Compare commits

..

3 Commits

Author SHA1 Message Date
bashermens
b0dc63da67 Update windows_build.yml 2026-01-16 16:13:12 +01:00
bashermens
944940bd6f Update windows_build.yml 2026-01-16 16:06:37 +01:00
bashermens
9e0250b973 shorter build paths 2026-01-16 16:05:47 +01:00
1173 changed files with 2877 additions and 3490 deletions

View File

@@ -1,127 +0,0 @@
# Pull Request
Describe what this change does and why it is needed...
---
## Design Philosophy
We prioritize **stability, performance, and predictability** over behavioral realism.
Complex player-mimicking logic is intentionally limited due to its negative impact on scalability, maintainability, and
long-term robustness.
Excessive processing overhead can lead to server hiccups, increased CPU usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability, and significantly higher maintenance overhead.
Every additional branch of logic increases long-term responsibility. All decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having a measurable performance cost.
Principles:
- **Stability before intelligence**
A stable system is always preferred over a smarter one.
- **Performance is a shared resource**
Any increase in bot cost affects all players and all bots.
- **Simple logic scales better than smart logic**
Predictable behavior under load is more valuable than perfect decisions.
- **Complexity must justify itself**
If a feature cannot clearly explain its cost, it should not exist.
- **Defaults must be cheap**
Expensive behavior must always be optional and clearly communicated.
- **Bots should look reasonable, not perfect**
The goal is believable behavior, not human simulation.
Before submitting, confirm that this change aligns with those principles.
---
## Feature Evaluation
Please answer the following:
- Describe the **minimum logic** required to achieve the intended behavior?
- Describe the **cheapest implementation** that produces an acceptable result?
- Describe the **runtime cost** when this logic executes across many bots?
---
## How to Test the Changes
- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific configuration)
- Expected behavior and how to verify it
## Complexity & Impact
- Does this change add new decision branches?
- [ ] No
- [ ] Yes (**explain below**)
- Does this change increase per-bot or per-tick processing?
- [ ] No
- [ ] Yes (**describe and justify impact**)
- Could this logic scale poorly under load?
- [ ] No
- [ ] Yes (**explain why**)
---
## Defaults & Configuration
- Does this change modify default bot behavior?
- [ ] No
- [ ] Yes (**explain why**)
If this introduces more advanced or AI-heavy logic:
- [ ] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable
---
## AI Assistance
- Was AI assistance (e.g. ChatGPT or similar tools) used while working on this change?
- [ ] No
- [ ] Yes (**explain below**)
If yes, please specify:
- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted
AI assistance is allowed, but all submitted code must be fully understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB logic. We expect contributors to be honest
about what they do and do not understand.
---
## Final Checklist
- [ ] Stability is not compromised
- [ ] Performance impact is understood, tested, and acceptable
- [ ] Added logic complexity is justified and explained
- [ ] Documentation updated if needed
---
## Notes for Reviewers
Anything that significantly improves realism at the cost of stability or performance should be carefully discussed
before merging.

View File

@@ -3,9 +3,8 @@
##################################################
# Overview
# "Randombot": randomly generated bots that log in separately from players and populate the world. Randombots may automatically grind, quest, level up, and upgrade equipment and can be invited to groups and given commands.
# "AddClass bot": bots from the AddClassAccountPoolSize accounts. They are used for quickly adding a leveled and geared bot of any class to your party. They are recommended for a quick formation of a party.
# "Altbot": characters created on player accounts, which may be logged in by the player and invited to groups and given commands like randombots. They are best suited for long-progression playthroughs.
# "Randombot": randomly generated bots that log in separately from players and populate the world. Depending on settings, randombots may automatically grind, quest, and upgrade equipment and can be invited to groups and given commands.
# "Altbot": characters created on player accounts, which may be logged in by the player and invited to groups and given commands like randombots. Depending on settings, altbots can be limited to characters on the active player's account or in the active player's guild.
# Information about commands to control bots and set their strategies can be found on the wiki at https://github.com/mod-playerbots/mod-playerbots/wiki/Playerbot-Commands.
####################################################################################################
@@ -270,7 +269,7 @@ AiPlayerbot.UseFastFlyMountAtMinLevel = 70
AiPlayerbot.RandomBotShowHelmet = 1
AiPlayerbot.RandomBotShowCloak = 1
# Toggles whether altbots will automatically equip items in their inventory that are sufficient upgrades
# Randombots and altbots automatically equip any items in their inventory that are sufficient upgrades
# Default: 1 (enabled)
AiPlayerbot.AutoEquipUpgradeLoot = 1
@@ -544,8 +543,8 @@ AiPlayerbot.AutoGearQualityLimit = 3
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
# TBC
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 2(SSC, TK, ZA) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
# WotLK
# 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
# Wotlk
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
# Default: 0 (no limit)
@@ -670,7 +669,7 @@ AiPlayerbot.DisableDeathKnightLogin = 0
# Default: 0 (disabled)
AiPlayerbot.LimitTalentsExpansion = 0
# Configure randombot trading (0: Disabled, 1: Enabled, 2: Only Buy, 3: Only Sell)
# Configure randombots and addClass bot trading (0: Disabled, 1: Enabled, 2: Only Buy, 3: Only Sell)
# Default: 1 (enabled)
AiPlayerbot.EnableRandomBotTrading = 1
@@ -736,7 +735,7 @@ AiPlayerbot.RandomGearQualityLimit = 3
# TBC
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 2(SSC, TK, ZA) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
# WotLK
# Wotlk
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
# Default: 0 (no limit)
@@ -1624,7 +1623,7 @@ AiPlayerbot.PremadeSpecLink.9.1.60 = -003203301135112530135201051
AiPlayerbot.PremadeSpecLink.9.1.70 = -003203301135112530135201051-55
AiPlayerbot.PremadeSpecLink.9.1.80 = -003203301135112530135221351-55000005
AiPlayerbot.PremadeSpecName.9.2 = destro pve
AiPlayerbot.PremadeSpecGlyph.9.2 = 45785,43390,42454,43394,43393,45785
AiPlayerbot.PremadeSpecGlyph.9.2 = 45785,43390,50077,43394,43393,42454
AiPlayerbot.PremadeSpecLink.9.2.60 = --05203215200231051305031151
AiPlayerbot.PremadeSpecLink.9.2.80 = 23-0302-05203215220331051335231351
AiPlayerbot.PremadeSpecName.9.3 = affli pvp

View File

@@ -1,21 +0,0 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONACTIONCONTEXT_H
#define _PLAYERBOT_WOTLKDUNGEONACTIONCONTEXT_H
#include "UtgardeKeep/UtgardeKeepActionContext.h"
#include "Nexus/NexusActionContext.h"
#include "AzjolNerub/AzjolNerubActionContext.h"
#include "OldKingdom/OldKingdomActionContext.h"
#include "DraktharonKeep/DrakTharonKeepActionContext.h"
#include "VioletHold/VioletHoldActionContext.h"
#include "Gundrak/GundrakActionContext.h"
#include "HallsOfStone/HallsOfStoneActionContext.h"
#include "HallsOfLightning/HallsOfLightningActionContext.h"
#include "Oculus/OculusActionContext.h"
#include "UtgardePinnacle/UtgardePinnacleActionContext.h"
#include "CullingOfStratholme/CullingOfStratholmeActionContext.h"
#include "ForgeOfSouls/ForgeOfSoulsActionContext.h"
#include "PitOfSaron/PitOfSaronActionContext.h"
#include "TrialOfTheChampion/TrialOfTheChampionActionContext.h"
// #include "HallsOfReflection/HallsOfReflectionActionContext.h"
#endif

View File

@@ -1,21 +0,0 @@
#ifndef _PLAYERBOT_WOTLKDUNGEONTRIGGERCONTEXT_H
#define _PLAYERBOT_WOTLKDUNGEONTRIGGERCONTEXT_H
#include "UtgardeKeep/UtgardeKeepTriggerContext.h"
#include "Nexus/NexusTriggerContext.h"
#include "AzjolNerub/AzjolNerubTriggerContext.h"
#include "OldKingdom/OldKingdomTriggerContext.h"
#include "DraktharonKeep/DrakTharonKeepTriggerContext.h"
#include "VioletHold/VioletHoldTriggerContext.h"
#include "Gundrak/GundrakTriggerContext.h"
#include "HallsOfStone/HallsOfStoneTriggerContext.h"
#include "HallsOfLightning/HallsOfLightningTriggerContext.h"
#include "Oculus/OculusTriggerContext.h"
#include "UtgardePinnacle/UtgardePinnacleTriggerContext.h"
#include "CullingOfStratholme/CullingOfStratholmeTriggerContext.h"
#include "ForgeOfSouls/ForgeOfSoulsTriggerContext.h"
#include "PitOfSaron/PitOfSaronTriggerContext.h"
#include "TrialOfTheChampion/TrialOfTheChampionTriggerContext.h"
// #include "HallsOfReflection/HallsOfReflectionTriggerContext.h"
#endif

View File

@@ -281,7 +281,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (!player->InBattleground())
engine->addStrategiesNoInit("racials", "chat", "default", "cast time", "potions", "duel", "boost", nullptr);
if (sPlayerbotAIConfig.autoAvoidAoe && facade->HasRealPlayerMaster())
if (sPlayerbotAIConfig->autoAvoidAoe && facade->HasRealPlayerMaster())
engine->addStrategy("avoid aoe", false);
engine->addStrategy("formation", false);
@@ -399,13 +399,13 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
if (PlayerbotAI::IsHeal(player, true))
{
if (sPlayerbotAIConfig.autoSaveMana)
if (sPlayerbotAIConfig->autoSaveMana)
engine->addStrategy("save mana", false);
if (!sPlayerbotAIConfig.IsRestrictedHealerDPSMap(player->GetMapId()))
if (!sPlayerbotAIConfig->IsRestrictedHealerDPSMap(player->GetMapId()))
engine->addStrategy("healer dps", false);
}
if (facade->IsRealPlayer() || sRandomPlayerbotMgr.IsRandomBot(player))
if (facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player))
{
if (!player->GetGroup())
{
@@ -448,10 +448,10 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
}
}
}
if (sRandomPlayerbotMgr.IsRandomBot(player))
engine->ChangeStrategy(sPlayerbotAIConfig.randomBotCombatStrategies);
if (sRandomPlayerbotMgr->IsRandomBot(player))
engine->ChangeStrategy(sPlayerbotAIConfig->randomBotCombatStrategies);
else
engine->ChangeStrategy(sPlayerbotAIConfig.combatStrategies);
engine->ChangeStrategy(sPlayerbotAIConfig->combatStrategies);
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
@@ -586,10 +586,10 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
"gather", "duel", "pvp", "buff", "mount", "emote", nullptr);
}
if (sPlayerbotAIConfig.autoSaveMana && PlayerbotAI::IsHeal(player, true))
if (sPlayerbotAIConfig->autoSaveMana && PlayerbotAI::IsHeal(player, true))
nonCombatEngine->addStrategy("save mana", false);
if ((sRandomPlayerbotMgr.IsRandomBot(player)) && !player->InBattleground())
if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
{
Player* master = facade->GetMaster();
@@ -597,7 +597,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
if (!urand(0, 3))
nonCombatEngine->addStrategy("start duel", false);
if (sPlayerbotAIConfig.randomBotJoinLfg)
if (sPlayerbotAIConfig->randomBotJoinLfg)
nonCombatEngine->addStrategy("lfg", false);
if (!player->GetGroup() || player->GetGroup()->GetLeaderGUID() == player->GetGUID())
@@ -612,9 +612,9 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// nonCombatEngine->addStrategy("guild");
nonCombatEngine->addStrategy("grind", false);
if (sPlayerbotAIConfig.enableNewRpgStrategy)
if (sPlayerbotAIConfig->enableNewRpgStrategy)
nonCombatEngine->addStrategy("new rpg", false);
else if (sPlayerbotAIConfig.autoDoQuests)
else if (sPlayerbotAIConfig->autoDoQuests)
{
// nonCombatEngine->addStrategy("travel");
nonCombatEngine->addStrategy("rpg", false);
@@ -622,13 +622,13 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
else
nonCombatEngine->addStrategy("move random", false);
if (sPlayerbotAIConfig.randomBotJoinBG)
if (sPlayerbotAIConfig->randomBotJoinBG)
nonCombatEngine->addStrategy("bg", false);
// if (!master || GET_PLAYERBOT_AI(master))
// nonCombatEngine->addStrategy("maintenance");
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig.randomBotNonCombatStrategies);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies);
}
else
{
@@ -637,14 +637,14 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
if (master)
{
PlayerbotAI* masterBotAI = GET_PLAYERBOT_AI(master);
if (masterBotAI || sRandomPlayerbotMgr.IsRandomBot(player))
if (masterBotAI || sRandomPlayerbotMgr->IsRandomBot(player))
{
// nonCombatEngine->addStrategy("pvp", false);
// nonCombatEngine->addStrategy("collision");
// nonCombatEngine->addStrategy("group");
// nonCombatEngine->addStrategy("guild");
// if (sPlayerbotAIConfig.autoDoQuests)
// if (sPlayerbotAIConfig->autoDoQuests)
// {
// // nonCombatEngine->addStrategy("travel");
// nonCombatEngine->addStrategy("rpg");
@@ -657,19 +657,19 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
// if (masterBotAI)
// nonCombatEngine->addStrategy("maintenance");
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig.randomBotNonCombatStrategies);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies);
}
else
{
// nonCombatEngine->addStrategy("pvp", false);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig.nonCombatStrategies);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
}
}
}
}
}
else
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig.nonCombatStrategies);
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
@@ -726,7 +726,7 @@ void AiFactory::AddDefaultDeadStrategies(Player* player, PlayerbotAI* const faca
(void)facade; // unused and remove warning
deadEngine->addStrategiesNoInit("dead", "stay", "chat", "default", "follow", nullptr);
if (sRandomPlayerbotMgr.IsRandomBot(player) && !player->GetGroup())
if (sRandomPlayerbotMgr->IsRandomBot(player) && !player->GetGroup())
deadEngine->removeStrategy("follow", false);
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTCOMMANDSERVER_H
#define _PLAYERBOT_PLAYERBOTCOMMANDSERVER_H
class PlayerbotCommandServer
{
public:
static PlayerbotCommandServer& instance()
{
static PlayerbotCommandServer instance;
return instance;
}
void Start();
private:
PlayerbotCommandServer() = default;
~PlayerbotCommandServer() = default;
PlayerbotCommandServer(const PlayerbotCommandServer&) = delete;
PlayerbotCommandServer& operator=(const PlayerbotCommandServer&) = delete;
PlayerbotCommandServer(PlayerbotCommandServer&&) = delete;
PlayerbotCommandServer& operator=(PlayerbotCommandServer&&) = delete;
};
#endif

View File

@@ -28,29 +28,29 @@ bool BroadcastHelper::BroadcastTest(PlayerbotAI* ai, Player* /* bot */)
int32 rand = urand(0, 1);
if (rand == 1 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to trade, %rand1, %rand2, %rand3", placeholders), ChatChannelId::TRADE))
if (rand == 1 && ai->SayToChannel(BOT_TEXT2("Posted to trade, %rand1, %rand2, %rand3", placeholders), ChatChannelId::TRADE))
return true;
else if (ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to GuildRecruitment, %rand1, %rand2, %rand3", placeholders), ChatChannelId::GUILD_RECRUITMENT))
else if (ai->SayToChannel(BOT_TEXT2("Posted to GuildRecruitment, %rand1, %rand2, %rand3", placeholders), ChatChannelId::GUILD_RECRUITMENT))
return true;
return ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to trade, %rand1, %rand2, %rand3", placeholders), ChatChannelId::TRADE);
return ai->SayToChannel(BOT_TEXT2("Posted to trade, %rand1, %rand2, %rand3", placeholders), ChatChannelId::TRADE);
//int32 rand = urand(1, 8);
if (rand == 1 && ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("Posted to guild, %rand1, %rand2, %rand3", placeholders)))
if (rand == 1 && ai->SayToGuild(BOT_TEXT2("Posted to guild, %rand1, %rand2, %rand3", placeholders)))
return true;
else if (rand == 2 && ai->SayToWorld(PlayerbotTextMgr::instance().GetBotText("Posted to world, %rand1, %rand2, %rand3", placeholders)))
else if (rand == 2 && ai->SayToWorld(BOT_TEXT2("Posted to world, %rand1, %rand2, %rand3", placeholders)))
return true;
else if (rand == 3 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to general, %rand1, %rand2, %rand3", placeholders), ChatChannelId::GENERAL))
else if (rand == 3 && ai->SayToChannel(BOT_TEXT2("Posted to general, %rand1, %rand2, %rand3", placeholders), ChatChannelId::GENERAL))
return true;
else if (rand == 4 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to trade, %rand1, %rand2, %rand3", placeholders), ChatChannelId::TRADE))
else if (rand == 4 && ai->SayToChannel(BOT_TEXT2("Posted to trade, %rand1, %rand2, %rand3", placeholders), ChatChannelId::TRADE))
return true;
else if (rand == 5 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to LFG, %rand1, %rand2, %rand3", placeholders), ChatChannelId::LOOKING_FOR_GROUP))
else if (rand == 5 && ai->SayToChannel(BOT_TEXT2("Posted to LFG, %rand1, %rand2, %rand3", placeholders), ChatChannelId::LOOKING_FOR_GROUP))
return true;
else if (rand == 6 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to LocalDefense, %rand1, %rand2, %rand3", placeholders), ChatChannelId::LOCAL_DEFENSE))
else if (rand == 6 && ai->SayToChannel(BOT_TEXT2("Posted to LocalDefense, %rand1, %rand2, %rand3", placeholders), ChatChannelId::LOCAL_DEFENSE))
return true;
else if (rand == 7 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to WorldDefense, %rand1, %rand2, %rand3", placeholders), ChatChannelId::WORLD_DEFENSE))
else if (rand == 7 && ai->SayToChannel(BOT_TEXT2("Posted to WorldDefense, %rand1, %rand2, %rand3", placeholders), ChatChannelId::WORLD_DEFENSE))
return true;
else if (rand == 8 && ai->SayToChannel(PlayerbotTextMgr::instance().GetBotText("Posted to GuildRecruitment, %rand1, %rand2, %rand3", placeholders), ChatChannelId::GUILD_RECRUITMENT))
else if (rand == 8 && ai->SayToChannel(BOT_TEXT2("Posted to GuildRecruitment, %rand1, %rand2, %rand3", placeholders), ChatChannelId::GUILD_RECRUITMENT))
return true;
return false;
@@ -63,7 +63,7 @@ bool BroadcastHelper::BroadcastTest(PlayerbotAI* ai, Player* /* bot */)
*/
bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::string message, std::list<std::pair<ToChannel, uint32>> toChannels)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (message.empty())
{
@@ -74,14 +74,14 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
{
uint32 roll = urand(1, 100);
uint32 chance = pair.second;
uint32 broadcastRoll = urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue);
uint32 broadcastRoll = urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue);
switch (pair.first)
{
case TO_GUILD:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToGuildGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToGuildGlobalChance
&& ai->SayToGuild(message))
{
return true;
@@ -91,7 +91,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_WORLD:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToWorldGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToWorldGlobalChance
&& ai->SayToWorld(message))
{
return true;
@@ -101,7 +101,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_GENERAL:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToGeneralGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToGeneralGlobalChance
&& ai->SayToChannel(message, ChatChannelId::GENERAL))
{
return true;
@@ -111,7 +111,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_TRADE:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToTradeGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToTradeGlobalChance
&& ai->SayToChannel(message, ChatChannelId::TRADE))
{
return true;
@@ -121,7 +121,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_LOOKING_FOR_GROUP:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToLFGGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToLFGGlobalChance
&& ai->SayToChannel(message, ChatChannelId::LOOKING_FOR_GROUP))
{
return true;
@@ -131,7 +131,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_LOCAL_DEFENSE:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToLocalDefenseGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToLocalDefenseGlobalChance
&& ai->SayToChannel(message, ChatChannelId::LOCAL_DEFENSE))
{
return true;
@@ -141,7 +141,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_WORLD_DEFENSE:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToWorldDefenseGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToWorldDefenseGlobalChance
&& ai->SayToChannel(message, ChatChannelId::WORLD_DEFENSE))
{
return true;
@@ -151,7 +151,7 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
case TO_GUILD_RECRUITMENT:
{
if (roll <= chance
&& broadcastRoll <= sPlayerbotAIConfig.broadcastToGuildRecruitmentGlobalChance
&& broadcastRoll <= sPlayerbotAIConfig->broadcastToGuildRecruitmentGlobalChance
&& ai->SayToChannel(message, ChatChannelId::GUILD_RECRUITMENT))
{
return true;
@@ -168,14 +168,14 @@ bool BroadcastHelper::BroadcastToChannelWithGlobalChance(PlayerbotAI* ai, std::s
bool BroadcastHelper::BroadcastLootingItem(PlayerbotAI* ai, Player* bot, ItemTemplate const* proto)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
std::map<std::string, std::string> placeholders;
placeholders["%item_link"] = ai->GetChatHelper()->FormatItem(proto);
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
@@ -183,71 +183,71 @@ bool BroadcastHelper::BroadcastLootingItem(PlayerbotAI* ai, Player* bot, ItemTem
switch (proto->Quality)
{
case ITEM_QUALITY_POOR:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemPoor)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemPoor)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_poor", placeholders),
BOT_TEXT2("broadcast_looting_item_poor", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case ITEM_QUALITY_NORMAL:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemNormal)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemNormal)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_normal", placeholders),
BOT_TEXT2("broadcast_looting_item_normal", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case ITEM_QUALITY_UNCOMMON:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemUncommon)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemUncommon)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_uncommon", placeholders),
BOT_TEXT2("broadcast_looting_item_uncommon", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case ITEM_QUALITY_RARE:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemRare)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemRare)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_rare", placeholders),
BOT_TEXT2("broadcast_looting_item_rare", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case ITEM_QUALITY_EPIC:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemEpic)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemEpic)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_epic", placeholders),
BOT_TEXT2("broadcast_looting_item_epic", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case ITEM_QUALITY_LEGENDARY:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemLegendary)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemLegendary)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_legendary", placeholders),
BOT_TEXT2("broadcast_looting_item_legendary", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case ITEM_QUALITY_ARTIFACT:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLootingItemArtifact)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLootingItemArtifact)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_looting_item_artifact", placeholders),
BOT_TEXT2("broadcast_looting_item_artifact", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -261,23 +261,23 @@ bool BroadcastHelper::BroadcastLootingItem(PlayerbotAI* ai, Player* bot, ItemTem
bool BroadcastHelper::BroadcastQuestAccepted(PlayerbotAI* ai, Player* bot, const Quest* quest)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestAccepted)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestAccepted)
{
std::map<std::string, std::string> placeholders;
placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest);
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_accepted_generic", placeholders),
BOT_TEXT2("broadcast_quest_accepted_generic", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -287,13 +287,13 @@ bool BroadcastHelper::BroadcastQuestAccepted(PlayerbotAI* ai, Player* bot, const
bool BroadcastHelper::BroadcastQuestUpdateAddKill(PlayerbotAI* ai, Player* bot, Quest const* quest, uint32 availableCount, uint32 requiredCount, std::string obectiveName)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
std::map<std::string, std::string> placeholders;
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest);
placeholders["%quest_obj_name"] = obectiveName;
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
@@ -305,20 +305,20 @@ bool BroadcastHelper::BroadcastQuestUpdateAddKill(PlayerbotAI* ai, Player* bot,
placeholders["%quest_obj_full_formatted"] = ai->GetChatHelper()->FormatQuestObjective(obectiveName, availableCount, requiredCount);
if (availableCount < requiredCount
&& urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestUpdateObjectiveProgress)
&& urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestUpdateObjectiveProgress)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_update_add_kill_objective_progress", placeholders),
BOT_TEXT2("broadcast_quest_update_add_kill_objective_progress", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
else if (availableCount == requiredCount
&& urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestUpdateObjectiveCompleted)
&& urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestUpdateObjectiveCompleted)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_update_add_kill_objective_completed", placeholders),
BOT_TEXT2("broadcast_quest_update_add_kill_objective_completed", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -328,13 +328,13 @@ bool BroadcastHelper::BroadcastQuestUpdateAddKill(PlayerbotAI* ai, Player* bot,
bool BroadcastHelper::BroadcastQuestUpdateAddItem(PlayerbotAI* ai, Player* bot, Quest const* quest, uint32 availableCount, uint32 requiredCount, const ItemTemplate* proto)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
std::map<std::string, std::string> placeholders;
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest);
std::string itemLinkFormatted = ai->GetChatHelper()->FormatItem(proto);
placeholders["%item_link"] = itemLinkFormatted;
@@ -347,20 +347,20 @@ bool BroadcastHelper::BroadcastQuestUpdateAddItem(PlayerbotAI* ai, Player* bot,
placeholders["%quest_obj_full_formatted"] = ai->GetChatHelper()->FormatQuestObjective(itemLinkFormatted, availableCount, requiredCount);
if (availableCount < requiredCount
&& urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestUpdateObjectiveProgress)
&& urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestUpdateObjectiveProgress)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_update_add_item_objective_progress", placeholders),
BOT_TEXT2("broadcast_quest_update_add_item_objective_progress", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
else if (availableCount == requiredCount
&& urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestUpdateObjectiveCompleted)
&& urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestUpdateObjectiveCompleted)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_update_add_item_objective_completed", placeholders),
BOT_TEXT2("broadcast_quest_update_add_item_objective_completed", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -370,23 +370,23 @@ bool BroadcastHelper::BroadcastQuestUpdateAddItem(PlayerbotAI* ai, Player* bot,
bool BroadcastHelper::BroadcastQuestUpdateFailedTimer(PlayerbotAI* ai, Player* bot, Quest const* quest)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestUpdateFailedTimer)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestUpdateFailedTimer)
{
std::map<std::string, std::string> placeholders;
placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest);
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_update_failed_timer", placeholders),
BOT_TEXT2("broadcast_quest_update_failed_timer", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -396,23 +396,23 @@ bool BroadcastHelper::BroadcastQuestUpdateFailedTimer(PlayerbotAI* ai, Player* b
bool BroadcastHelper::BroadcastQuestUpdateComplete(PlayerbotAI* ai, Player* bot, Quest const* quest)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestUpdateComplete)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestUpdateComplete)
{
std::map<std::string, std::string> placeholders;
placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest);
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_update_complete", placeholders),
BOT_TEXT2("broadcast_quest_update_complete", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -422,23 +422,23 @@ bool BroadcastHelper::BroadcastQuestUpdateComplete(PlayerbotAI* ai, Player* bot,
bool BroadcastHelper::BroadcastQuestTurnedIn(PlayerbotAI* ai, Player* bot, Quest const* quest)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceQuestTurnedIn)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceQuestTurnedIn)
{
std::map<std::string, std::string> placeholders;
placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest);
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_quest_turned_in", placeholders),
BOT_TEXT2("broadcast_quest_turned_in", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -448,14 +448,14 @@ bool BroadcastHelper::BroadcastQuestTurnedIn(PlayerbotAI* ai, Player* bot, Quest
bool BroadcastHelper::BroadcastKill(PlayerbotAI* ai, Player* bot, Creature *creature)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
std::map<std::string, std::string> placeholders;
placeholders["%victim_name"] = creature->GetName();
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%victim_level"] = creature->GetLevel();
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
@@ -468,24 +468,24 @@ bool BroadcastHelper::BroadcastKill(PlayerbotAI* ai, Player* bot, Creature *crea
if (creature->IsPet())
{
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillPet)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillPet)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_pet", placeholders),
BOT_TEXT2("broadcast_killed_pet", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
}
else if (creature->IsPlayer())
{
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillPlayer)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillPlayer)
{
placeholders["%victim_class"] = ai->GetChatHelper()->FormatClass(creature->getClass());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_player", placeholders),
BOT_TEXT2("broadcast_killed_player", placeholders),
{ {TO_WORLD_DEFENSE, 50}, {TO_LOCAL_DEFENSE, 50}, {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -495,61 +495,61 @@ bool BroadcastHelper::BroadcastKill(PlayerbotAI* ai, Player* bot, Creature *crea
switch (creature->GetCreatureTemplate()->rank)
{
case CREATURE_ELITE_NORMAL:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillNormal)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillNormal)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_normal", placeholders),
BOT_TEXT2("broadcast_killed_normal", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case CREATURE_ELITE_ELITE:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillElite)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillElite)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_elite", placeholders),
BOT_TEXT2("broadcast_killed_elite", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case CREATURE_ELITE_RAREELITE:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillRareelite)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillRareelite)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_rareelite", placeholders),
BOT_TEXT2("broadcast_killed_rareelite", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case CREATURE_ELITE_WORLDBOSS:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillWorldboss)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillWorldboss)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_worldboss", placeholders),
BOT_TEXT2("broadcast_killed_worldboss", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case CREATURE_ELITE_RARE:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillRare)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillRare)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_rare", placeholders),
BOT_TEXT2("broadcast_killed_rare", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
break;
case CREATURE_UNKNOWN:
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceKillUnknown)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceKillUnknown)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_killed_unknown", placeholders),
BOT_TEXT2("broadcast_killed_unknown", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -564,43 +564,43 @@ bool BroadcastHelper::BroadcastKill(PlayerbotAI* ai, Player* bot, Creature *crea
bool BroadcastHelper::BroadcastLevelup(PlayerbotAI* ai, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
uint32 level = bot->GetLevel();
std::map<std::string, std::string> placeholders;
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(level);
if (level == sPlayerbotAIConfig.randomBotMaxLevel
&& urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLevelupMaxLevel)
if (level == sPlayerbotAIConfig->randomBotMaxLevel
&& urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLevelupMaxLevel)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_levelup_max_level", placeholders),
BOT_TEXT2("broadcast_levelup_max_level", placeholders),
{ {TO_GUILD, 30}, {TO_WORLD, 90}, {TO_GENERAL, 100} }
);
}
// It's divisible by 10
else if (level % 10 == 0
&& urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLevelupTenX)
&& urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLevelupTenX)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_levelup_10x", placeholders),
BOT_TEXT2("broadcast_levelup_10x", placeholders),
{ {TO_GUILD, 50}, {TO_WORLD, 90}, {TO_GENERAL, 100} }
);
}
else if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceLevelupGeneric)
else if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceLevelupGeneric)
{
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("broadcast_levelup_generic", placeholders),
BOT_TEXT2("broadcast_levelup_generic", placeholders),
{ {TO_GUILD, 90}, {TO_WORLD, 90}, {TO_GENERAL, 100} }
);
}
@@ -610,9 +610,9 @@ bool BroadcastHelper::BroadcastLevelup(PlayerbotAI* ai, Player* bot)
bool BroadcastHelper::BroadcastGuildMemberPromotion(PlayerbotAI* ai, Player* /* bot */, Player* player)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceGuildManagement)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceGuildManagement)
{
std::map<std::string, std::string> placeholders;
placeholders["%other_name"] = player->GetName();
@@ -620,7 +620,7 @@ bool BroadcastHelper::BroadcastGuildMemberPromotion(PlayerbotAI* ai, Player* /*
placeholders["%other_race"] = ai->GetChatHelper()->FormatRace(player->getRace());
placeholders["%other_level"] = std::to_string(player->GetLevel());
return ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("broadcast_guild_promotion", placeholders));
return ai->SayToGuild(BOT_TEXT2("broadcast_guild_promotion", placeholders));
}
return false;
@@ -628,7 +628,7 @@ bool BroadcastHelper::BroadcastGuildMemberPromotion(PlayerbotAI* ai, Player* /*
bool BroadcastHelper::BroadcastGuildMemberDemotion(PlayerbotAI* ai, Player* /* bot */, Player* player)
{
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceGuildManagement)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceGuildManagement)
{
std::map<std::string, std::string> placeholders;
placeholders["%other_name"] = player->GetName();
@@ -636,7 +636,7 @@ bool BroadcastHelper::BroadcastGuildMemberDemotion(PlayerbotAI* ai, Player* /* b
placeholders["%other_race"] = ai->GetChatHelper()->FormatRace(player->getRace());
placeholders["%other_level"] = std::to_string(player->GetLevel());
return ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("broadcast_guild_demotion", placeholders));
return ai->SayToGuild(BOT_TEXT2("broadcast_guild_demotion", placeholders));
}
return false;
@@ -644,25 +644,25 @@ bool BroadcastHelper::BroadcastGuildMemberDemotion(PlayerbotAI* ai, Player* /* b
bool BroadcastHelper::BroadcastGuildGroupOrRaidInvite(PlayerbotAI* ai, Player* /* bot */, Player* player, Group* group)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
std::map<std::string, std::string> placeholders;
placeholders["%name"] = player->GetName();
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
//TODO move texts to sql!
if (group && group->isRaidGroup())
{
if (urand(0, 3))
{
return ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("Hey anyone want to raid in %zone_name", placeholders));
return ai->SayToGuild(BOT_TEXT2("Hey anyone want to raid in %zone_name", placeholders));
}
else
{
return ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("Hey %name I'm raiding in %zone_name do you wan to join me?", placeholders));
return ai->SayToGuild(BOT_TEXT2("Hey %name I'm raiding in %zone_name do you wan to join me?", placeholders));
}
}
else
@@ -670,11 +670,11 @@ bool BroadcastHelper::BroadcastGuildGroupOrRaidInvite(PlayerbotAI* ai, Player* /
//(bot->GetTeam() == ALLIANCE ? LANG_COMMON : LANG_ORCISH)
if (urand(0, 3))
{
return ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("Hey anyone wanna group up in %zone_name?", placeholders));
return ai->SayToGuild(BOT_TEXT2("Hey anyone wanna group up in %zone_name?", placeholders));
}
else
{
return ai->SayToGuild(PlayerbotTextMgr::instance().GetBotText("Hey %name do you want join my group? I'm heading for %zone_name", placeholders));
return ai->SayToGuild(BOT_TEXT2("Hey %name do you want join my group? I'm heading for %zone_name", placeholders));
}
}
@@ -683,9 +683,9 @@ bool BroadcastHelper::BroadcastGuildGroupOrRaidInvite(PlayerbotAI* ai, Player* /
bool BroadcastHelper::BroadcastSuggestInstance(PlayerbotAI* ai, std::vector<std::string>& allowedInstances, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestInstance)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestInstance)
{
std::map<std::string, std::string> placeholders;
placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
@@ -701,7 +701,7 @@ bool BroadcastHelper::BroadcastSuggestInstance(PlayerbotAI* ai, std::vector<std:
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_instance", placeholders),
BOT_TEXT2("suggest_instance", placeholders),
{ {TO_LOOKING_FOR_GROUP, 50}, {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -711,9 +711,9 @@ bool BroadcastHelper::BroadcastSuggestInstance(PlayerbotAI* ai, std::vector<std:
bool BroadcastHelper::BroadcastSuggestQuest(PlayerbotAI* ai, std::vector<uint32>& quests, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestQuest)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestQuest)
{
int index = rand() % quests.size();
@@ -730,7 +730,7 @@ bool BroadcastHelper::BroadcastSuggestQuest(PlayerbotAI* ai, std::vector<uint32>
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_quest", placeholders),
BOT_TEXT2("suggest_quest", placeholders),
{ {TO_LOOKING_FOR_GROUP, 50}, {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -740,9 +740,9 @@ bool BroadcastHelper::BroadcastSuggestQuest(PlayerbotAI* ai, std::vector<uint32>
bool BroadcastHelper::BroadcastSuggestGrindMaterials(PlayerbotAI* ai, std::string item, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestGrindMaterials)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestGrindMaterials)
{
std::map<std::string, std::string> placeholders;
@@ -755,7 +755,7 @@ bool BroadcastHelper::BroadcastSuggestGrindMaterials(PlayerbotAI* ai, std::strin
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_trade", placeholders),
BOT_TEXT2("suggest_trade", placeholders),
{ {TO_TRADE, 50}, {TO_LOOKING_FOR_GROUP, 50}, {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -765,9 +765,9 @@ bool BroadcastHelper::BroadcastSuggestGrindMaterials(PlayerbotAI* ai, std::strin
bool BroadcastHelper::BroadcastSuggestGrindReputation(PlayerbotAI* ai, std::vector<std::string> levels, std::vector<std::string> allowedFactions, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestGrindReputation)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestGrindReputation)
{
std::map<std::string, std::string> placeholders;
@@ -787,7 +787,7 @@ bool BroadcastHelper::BroadcastSuggestGrindReputation(PlayerbotAI* ai, std::vect
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_faction", placeholders),
BOT_TEXT2("suggest_faction", placeholders),
{ {TO_LOOKING_FOR_GROUP, 50}, {TO_GUILD, 50}, {TO_WORLD, 50}, {TO_GENERAL, 100} }
);
}
@@ -797,9 +797,9 @@ bool BroadcastHelper::BroadcastSuggestGrindReputation(PlayerbotAI* ai, std::vect
bool BroadcastHelper::BroadcastSuggestSell(PlayerbotAI* ai, const ItemTemplate* proto, uint32 count, uint32 price, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestSell)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestSell)
{
std::map<std::string, std::string> placeholders;
@@ -814,7 +814,7 @@ bool BroadcastHelper::BroadcastSuggestSell(PlayerbotAI* ai, const ItemTemplate*
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_sell", placeholders),
BOT_TEXT2("suggest_sell", placeholders),
{ {TO_TRADE, 90}, {TO_GENERAL, 100} }
);
}
@@ -824,24 +824,24 @@ bool BroadcastHelper::BroadcastSuggestSell(PlayerbotAI* ai, const ItemTemplate*
bool BroadcastHelper::BroadcastSuggestSomething(PlayerbotAI* ai, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestSomething)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestSomething)
{
std::map<std::string, std::string> placeholders;
placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_something", placeholders),
BOT_TEXT2("suggest_something", placeholders),
{ {TO_GUILD, 10}, {TO_WORLD, 70}, {TO_GENERAL, 100} }
);
}
@@ -851,29 +851,29 @@ bool BroadcastHelper::BroadcastSuggestSomething(PlayerbotAI* ai, Player* bot)
bool BroadcastHelper::BroadcastSuggestSomethingToxic(PlayerbotAI* ai, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestSomethingToxic)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestSomethingToxic)
{
//items
std::vector<Item*> botItems = ai->GetInventoryAndEquippedItems();
std::map<std::string, std::string> placeholders;
placeholders["%random_inventory_item_link"] = botItems.size() > 0 ? ai->GetChatHelper()->FormatItem(botItems[rand() % botItems.size()]->GetTemplate()) : PlayerbotTextMgr::instance().GetBotText("string_empty_link");
placeholders["%random_inventory_item_link"] = botItems.size() > 0 ? ai->GetChatHelper()->FormatItem(botItems[rand() % botItems.size()]->GetTemplate()) : BOT_TEXT1("string_empty_link");
placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_something_toxic", placeholders),
BOT_TEXT2("suggest_something_toxic", placeholders),
{ {TO_GUILD, 10}, {TO_WORLD, 70}, {TO_GENERAL, 100} }
);
}
@@ -883,9 +883,9 @@ bool BroadcastHelper::BroadcastSuggestSomethingToxic(PlayerbotAI* ai, Player* bo
bool BroadcastHelper::BroadcastSuggestToxicLinks(PlayerbotAI* ai, Player* bot)
{
if (!sPlayerbotAIConfig.enableBroadcasts)
if (!sPlayerbotAIConfig->enableBroadcasts)
return false;
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestToxicLinks)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestToxicLinks)
{
//quests
std::vector<uint32> incompleteQuests;
@@ -908,8 +908,8 @@ bool BroadcastHelper::BroadcastSuggestToxicLinks(PlayerbotAI* ai, Player* bot)
std::map<std::string, std::string> placeholders;
placeholders["%random_inventory_item_link"] = botItems.size() > 0 ? ai->GetChatHelper()->FormatItem(botItems[rand() % botItems.size()]->GetTemplate()) : PlayerbotTextMgr::instance().GetBotText("string_empty_link");
placeholders["%prefix"] = sPlayerbotAIConfig.toxicLinksPrefix;
placeholders["%random_inventory_item_link"] = botItems.size() > 0 ? ai->GetChatHelper()->FormatItem(botItems[rand() % botItems.size()]->GetTemplate()) : BOT_TEXT1("string_empty_link");
placeholders["%prefix"] = sPlayerbotAIConfig->toxicLinksPrefix;
if (incompleteQuests.size() > 0)
{
@@ -924,15 +924,15 @@ bool BroadcastHelper::BroadcastSuggestToxicLinks(PlayerbotAI* ai, Player* bot)
placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
AreaTableEntry const* current_area = ai->GetCurrentArea();
AreaTableEntry const* current_zone = ai->GetCurrentZone();
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : PlayerbotTextMgr::instance().GetBotText("string_unknown_area");
placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area");
placeholders["%zone_name"] = current_zone ? ai->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass());
placeholders["%my_race"] = ai->GetChatHelper()->FormatRace(bot->getRace());
placeholders["%my_level"] = std::to_string(bot->GetLevel());
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("suggest_toxic_links", placeholders),
BOT_TEXT2("suggest_toxic_links", placeholders),
{ {TO_GUILD, 10}, {TO_WORLD, 70}, {TO_GENERAL, 100} }
);
}
@@ -942,7 +942,7 @@ bool BroadcastHelper::BroadcastSuggestToxicLinks(PlayerbotAI* ai, Player* bot)
bool BroadcastHelper::BroadcastSuggestThunderfury(PlayerbotAI* ai, Player* bot)
{
if (urand(1, sPlayerbotAIConfig.broadcastChanceMaxValue) <= sPlayerbotAIConfig.broadcastChanceSuggestThunderfury)
if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestThunderfury)
{
std::map<std::string, std::string> placeholders;
ItemTemplate const* thunderfuryProto = sObjectMgr->GetItemTemplate(19019);
@@ -950,7 +950,7 @@ bool BroadcastHelper::BroadcastSuggestThunderfury(PlayerbotAI* ai, Player* bot)
return BroadcastToChannelWithGlobalChance(
ai,
PlayerbotTextMgr::instance().GetBotText("thunderfury_spam", placeholders),
BOT_TEXT2("thunderfury_spam", placeholders),
{ {TO_WORLD, 70}, {TO_GENERAL, 100} }
);
}

View File

@@ -1,39 +0,0 @@
#include "FlightMasterCache.h"
void FlightMasterCache::AddHordeFlightMaster(uint32 entry, WorldPosition pos)
{
hordeFlightMasterCache[entry] = pos;
}
void FlightMasterCache::AddAllianceFlightMaster(uint32 entry, WorldPosition pos)
{
allianceFlightMasterCache[entry] = pos;
}
Creature* FlightMasterCache::GetNearestFlightMaster(Player* bot)
{
std::map<uint32, WorldPosition>& flightMasterCache =
(bot->GetTeamId() == TEAM_ALLIANCE) ? allianceFlightMasterCache : hordeFlightMasterCache;
Creature* nearestFlightMaster = nullptr;
float nearestDistance = std::numeric_limits<float>::max();
for (auto const& [entry, pos] : flightMasterCache)
{
if (pos.GetMapId() == bot->GetMapId())
{
float distance = bot->GetExactDist2dSq(pos);
if (distance < nearestDistance)
{
Creature* flightMaster = ObjectAccessor::GetSpawnedCreatureByDBGUID(bot->GetMapId(), entry);
if (flightMaster)
{
nearestDistance = distance;
nearestFlightMaster = flightMaster;
}
}
}
}
return nearestFlightMaster;
}

View File

@@ -1,36 +0,0 @@
#ifndef _PLAYERBOT_FLIGHTMASTER_H
#define _PLAYERBOT_FLIGHTMASTER_H
#include "Creature.h"
#include "Player.h"
#include "TravelMgr.h"
class FlightMasterCache
{
public:
static FlightMasterCache& Instance()
{
static FlightMasterCache instance;
return instance;
}
Creature* GetNearestFlightMaster(Player* bot);
void AddHordeFlightMaster(uint32 entry, WorldPosition pos);
void AddAllianceFlightMaster(uint32 entry, WorldPosition pos);
private:
FlightMasterCache() = default;
~FlightMasterCache() = default;
FlightMasterCache(const FlightMasterCache&) = delete;
FlightMasterCache& operator=(const FlightMasterCache&) = delete;
FlightMasterCache(FlightMasterCache&&) = delete;
FlightMasterCache& operator=(FlightMasterCache&&) = delete;
std::map<uint32, WorldPosition> allianceFlightMasterCache;
std::map<uint32, WorldPosition> hordeFlightMasterCache;
};
#endif

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTDUNGEONREPOSITORY_H
#define _PLAYERBOT_PLAYERBOTDUNGEONREPOSITORY_H
#include <vector>
#include <string>
#include "DBCEnums.h"
struct DungeonSuggestion
{
std::string name;
Difficulty difficulty;
uint8 min_level;
uint8 max_level;
std::string abbrevation;
std::string strategy;
};
// @TODO: Completely unused at this moment.
class PlayerbotDungeonRepository
{
public:
static PlayerbotDungeonRepository& instance()
{
static PlayerbotDungeonRepository instance;
return instance;
}
void LoadDungeonSuggestions();
std::vector<DungeonSuggestion> const GetDungeonSuggestions();
private:
PlayerbotDungeonRepository() = default;
~PlayerbotDungeonRepository() = default;
PlayerbotDungeonRepository(const PlayerbotDungeonRepository&) = delete;
PlayerbotDungeonRepository& operator=(const PlayerbotDungeonRepository&) = delete;
PlayerbotDungeonRepository(PlayerbotDungeonRepository&&) = delete;
PlayerbotDungeonRepository& operator=(PlayerbotDungeonRepository&&) = delete;
std::vector<DungeonSuggestion> m_dungeonSuggestions;
};
#endif

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTREPOSITORY_H
#define _PLAYERBOT_PLAYERBOTREPOSITORY_H
#include <cstdint>
#include <string>
#include <vector>
#include "PlayerbotAI.h"
class PlayerbotRepository
{
public:
static PlayerbotRepository& instance()
{
static PlayerbotRepository instance;
return instance;
}
void Save(PlayerbotAI* botAI);
void Load(PlayerbotAI* botAI);
void Reset(PlayerbotAI* botAI);
private:
PlayerbotRepository() = default;
~PlayerbotRepository() = default;
PlayerbotRepository(const PlayerbotRepository&) = delete;
PlayerbotRepository& operator=(const PlayerbotRepository&) = delete;
PlayerbotRepository(PlayerbotRepository&&) = delete;
PlayerbotRepository& operator=(PlayerbotRepository&&) = delete;
void SaveValue(uint32_t guid, std::string const key, std::string const value);
std::string const FormatStrategies(std::string const type, std::vector<std::string> strategies);
};
#endif

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTSPELLREPOSITORY_H
#define _PLAYERBOT_PLAYERBOTSPELLREPOSITORY_H
#include <cstdint>
#include "DBCStructure.h"
class PlayerbotSpellRepository
{
public:
static PlayerbotSpellRepository& Instance()
{
static PlayerbotSpellRepository instance;
return instance;
}
void Initialize();
SkillLineAbilityEntry const* GetSkillLine(uint32_t spellId) const;
bool IsItemBuyable(uint32_t itemId) const;
private:
PlayerbotSpellRepository() = default;
~PlayerbotSpellRepository() = default;
PlayerbotSpellRepository(const PlayerbotSpellRepository&) = delete;
PlayerbotSpellRepository& operator=(const PlayerbotSpellRepository&) = delete;
PlayerbotSpellRepository(PlayerbotSpellRepository&&) = delete;
PlayerbotSpellRepository& operator=(PlayerbotSpellRepository&&) = delete;
std::map<uint32_t, SkillLineAbilityEntry const*> skillSpells;
std::set<uint32_t> vendorItems;
};
#endif

View File

@@ -34,7 +34,7 @@ void FleeManager::calculateDistanceToCreatures(FleePoint* point)
if (!unit)
continue;
float d = ServerFacade::instance().GetDistance2d(unit, point->x, point->y);
float d = sServerFacade->GetDistance2d(unit, point->x, point->y);
point->sumDistance += d;
if (point->minDistance < 0 || point->minDistance > d)
point->minDistance = d;
@@ -81,11 +81,11 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*>& points)
enemyOri.push_back(ori);
}
float distIncrement = std::max(sPlayerbotAIConfig.followDistance,
(maxAllowedDistance - sPlayerbotAIConfig.tooCloseDistance) / 10.0f);
for (float dist = maxAllowedDistance; dist >= sPlayerbotAIConfig.tooCloseDistance; dist -= distIncrement)
float distIncrement = std::max(sPlayerbotAIConfig->followDistance,
(maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance) / 10.0f);
for (float dist = maxAllowedDistance; dist >= sPlayerbotAIConfig->tooCloseDistance; dist -= distIncrement)
{
float angleIncrement = std::max(M_PI / 20, M_PI / 4 / (1.0 + dist - sPlayerbotAIConfig.tooCloseDistance));
float angleIncrement = std::max(M_PI / 20, M_PI / 4 / (1.0 + dist - sPlayerbotAIConfig->tooCloseDistance));
for (float add = 0.0f; add < M_PI / 4 + angleIncrement; add += angleIncrement)
{
for (float angle = add; angle < add + 2 * static_cast<float>(M_PI) + angleIncrement;
@@ -97,8 +97,8 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*>& points)
float x = botPosX + cos(angle) * maxAllowedDistance, y = botPosY + sin(angle) * maxAllowedDistance,
z = botPosZ + CONTACT_DISTANCE;
if (forceMaxDistance &&
ServerFacade::instance().IsDistanceLessThan(ServerFacade::instance().GetDistance2d(bot, x, y),
maxAllowedDistance - sPlayerbotAIConfig.tooCloseDistance))
sServerFacade->IsDistanceLessThan(sServerFacade->GetDistance2d(bot, x, y),
maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance))
continue;
bot->UpdateAllowedPositionZ(x, y, z);
@@ -113,8 +113,8 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*>& points)
FleePoint* point = new FleePoint(botAI, x, y, z);
calculateDistanceToCreatures(point);
if (ServerFacade::instance().IsDistanceGreaterOrEqualThan(point->minDistance - start.minDistance,
sPlayerbotAIConfig.followDistance))
if (sServerFacade->IsDistanceGreaterOrEqualThan(point->minDistance - start.minDistance,
sPlayerbotAIConfig->followDistance))
points.push_back(point);
else
delete point;
@@ -189,8 +189,8 @@ bool FleeManager::isUseful()
creature->GetAttackDistance(bot) * creature->GetAttackDistance(bot))
return true;
// float d = ServerFacade::instance().GetDistance2d(unit, bot);
// if (ServerFacade::instance().IsDistanceLessThan(d, sPlayerbotAIConfig.aggroDistance)) return true;
// float d = sServerFacade->GetDistance2d(unit, bot);
// if (sServerFacade->IsDistanceLessThan(d, sPlayerbotAIConfig->aggroDistance)) return true;
}
return false;

View File

@@ -26,14 +26,14 @@ enum GuildTaskType
void GuildTaskMgr::Update(Player* player, Player* guildMaster)
{
if (!sPlayerbotAIConfig.guildTaskEnabled)
if (!sPlayerbotAIConfig->guildTaskEnabled)
return;
if (!GetTaskValue(0, 0, "advert_cleanup"))
{
CleanupAdverts();
RemoveDuplicatedAdverts();
SetTaskValue(0, 0, "advert_cleanup", 1, sPlayerbotAIConfig.guildTaskAdvertCleanupTime);
SetTaskValue(0, 0, "advert_cleanup", 1, sPlayerbotAIConfig->guildTaskAdvertCleanupTime);
}
PlayerbotAI* masterBotAI = GET_PLAYERBOT_AI(guildMaster);
@@ -69,8 +69,8 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
SetTaskValue(owner, guildId, "killTask", 0, 0);
SetTaskValue(owner, guildId, "killCount", 0, 0);
SetTaskValue(owner, guildId, "payment", 0, 0);
SetTaskValue(owner, guildId, "thanks", 1, 2 * sPlayerbotAIConfig.maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "reward", 1, 2 * sPlayerbotAIConfig.maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "thanks", 1, 2 * sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "reward", 1, 2 * sPlayerbotAIConfig->maxGuildTaskChangeTime);
uint32 task = CreateTask(player, guildId);
@@ -80,11 +80,11 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
player->GetName().c_str());
}
uint32 time = urand(sPlayerbotAIConfig.minGuildTaskChangeTime, sPlayerbotAIConfig.maxGuildTaskChangeTime);
uint32 time = urand(sPlayerbotAIConfig->minGuildTaskChangeTime, sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "activeTask", task, time);
SetTaskValue(owner, guildId, "advertisement", 1,
urand(sPlayerbotAIConfig.minGuildTaskAdvertisementTime,
sPlayerbotAIConfig.maxGuildTaskAdvertisementTime));
urand(sPlayerbotAIConfig->minGuildTaskAdvertisementTime,
sPlayerbotAIConfig->maxGuildTaskAdvertisementTime));
LOG_DEBUG("playerbots", "{} / {}: guild task {} is set for {} secs", guild->GetName().c_str(),
player->GetName().c_str(), task, time);
@@ -101,8 +101,8 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
if (SendAdvertisement(trans, owner, guildId))
{
SetTaskValue(owner, guildId, "advertisement", 1,
urand(sPlayerbotAIConfig.minGuildTaskAdvertisementTime,
sPlayerbotAIConfig.maxGuildTaskAdvertisementTime));
urand(sPlayerbotAIConfig->minGuildTaskAdvertisementTime,
sPlayerbotAIConfig->maxGuildTaskAdvertisementTime));
}
else
{
@@ -118,7 +118,7 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
if (SendThanks(trans, owner, guildId, GetTaskValue(owner, guildId, "payment")))
{
SetTaskValue(owner, guildId, "thanks", 1, 2 * sPlayerbotAIConfig.maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "thanks", 1, 2 * sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "payment", 0, 0);
}
else
@@ -135,7 +135,7 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
if (Reward(trans, owner, guildId))
{
SetTaskValue(owner, guildId, "reward", 1, 2 * sPlayerbotAIConfig.maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "reward", 1, 2 * sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "payment", 0, 0);
}
else
@@ -190,7 +190,7 @@ bool GuildTaskMgr::CreateItemTask(Player* player, uint32 guildId)
return false;
RandomItemBySkillGuildTaskPredicate predicate(player);
uint32 itemId = sRandomItemMgr.GetRandomItem(player->GetLevel() - 5, RANDOM_ITEM_GUILD_TASK, &predicate);
uint32 itemId = sRandomItemMgr->GetRandomItem(player->GetLevel() - 5, RANDOM_ITEM_GUILD_TASK, &predicate);
if (!itemId)
{
LOG_ERROR("playerbots", "{} / {}: no items avaible for item task",
@@ -204,9 +204,9 @@ bool GuildTaskMgr::CreateItemTask(Player* player, uint32 guildId)
player->GetName().c_str(), itemId, count);
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemCount", count,
sPlayerbotAIConfig.maxGuildTaskChangeTime);
sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemTask", itemId,
sPlayerbotAIConfig.maxGuildTaskChangeTime);
sPlayerbotAIConfig->maxGuildTaskChangeTime);
return true;
}
@@ -239,8 +239,8 @@ bool GuildTaskMgr::CreateKillTask(Player* player, uint32 guildId)
if (strstr(name.c_str(), "UNUSED"))
continue;
float dist = ServerFacade::instance().GetDistance2d(player, x, y);
if (dist > sPlayerbotAIConfig.guildTaskKillTaskDistance || player->GetMapId() != map)
float dist = sServerFacade->GetDistance2d(player, x, y);
if (dist > sPlayerbotAIConfig->guildTaskKillTaskDistance || player->GetMapId() != map)
continue;
if (find(ids.begin(), ids.end(), id) == ids.end())
@@ -262,7 +262,7 @@ bool GuildTaskMgr::CreateKillTask(Player* player, uint32 guildId)
player->GetName().c_str(), creatureId);
SetTaskValue(player->GetGUID().GetCounter(), guildId, "killTask", creatureId,
sPlayerbotAIConfig.maxGuildTaskChangeTime);
sPlayerbotAIConfig->maxGuildTaskChangeTime);
return true;
}
@@ -525,7 +525,7 @@ uint32 GuildTaskMgr::GetMaxItemTaskCount(uint32 itemId)
bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
{
if (!sPlayerbotAIConfig.guildTaskEnabled)
if (!sPlayerbotAIConfig->guildTaskEnabled)
{
return 0;
}
@@ -553,7 +553,7 @@ bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
std::map<uint32, uint32> GuildTaskMgr::GetTaskValues(uint32 owner, std::string const type,
[[maybe_unused]] uint32* validIn /* = nullptr */)
{
if (!sPlayerbotAIConfig.guildTaskEnabled)
if (!sPlayerbotAIConfig->guildTaskEnabled)
{
return std::map<uint32, uint32>();
}
@@ -586,7 +586,7 @@ 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 */)
{
if (!sPlayerbotAIConfig.guildTaskEnabled)
if (!sPlayerbotAIConfig->guildTaskEnabled)
{
return 0;
}
@@ -639,7 +639,7 @@ uint32 GuildTaskMgr::SetTaskValue(uint32 owner, uint32 guildId, std::string cons
bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* /* handler */, char const* args)
{
if (!sPlayerbotAIConfig.guildTaskEnabled)
if (!sPlayerbotAIConfig->guildTaskEnabled)
{
LOG_ERROR("playerbots", "Guild task system is currently disabled!");
return false;
@@ -703,8 +703,8 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* /* handler */, char const*
if (value == GUILD_TASK_TYPE_ITEM)
{
name << "ItemTask";
uint32 itemId = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "itemTask");
uint32 itemCount = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "itemCount");
uint32 itemId = sGuildTaskMgr->GetTaskValue(owner, guildId, "itemTask");
uint32 itemCount = sGuildTaskMgr->GetTaskValue(owner, guildId, "itemCount");
if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId))
{
@@ -735,7 +735,7 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* /* handler */, char const*
else if (value == GUILD_TASK_TYPE_KILL)
{
name << "KillTask";
uint32 creatureId = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "killTask");
uint32 creatureId = sGuildTaskMgr->GetTaskValue(owner, guildId, "killTask");
if (CreatureTemplate const* proto = sObjectMgr->GetCreatureTemplate(creatureId))
{
@@ -758,22 +758,22 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* /* handler */, char const*
continue;
uint32 advertValidIn = 0;
uint32 advert = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "advertisement", &advertValidIn);
uint32 advert = sGuildTaskMgr->GetTaskValue(owner, guildId, "advertisement", &advertValidIn);
if (advert && advertValidIn < validIn)
name << " advert in " << formatTime(advertValidIn);
uint32 thanksValidIn = 0;
uint32 thanks = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "thanks", &thanksValidIn);
uint32 thanks = sGuildTaskMgr->GetTaskValue(owner, guildId, "thanks", &thanksValidIn);
if (thanks && thanksValidIn < validIn)
name << " thanks in " << formatTime(thanksValidIn);
uint32 rewardValidIn = 0;
uint32 reward = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "reward", &rewardValidIn);
uint32 reward = sGuildTaskMgr->GetTaskValue(owner, guildId, "reward", &rewardValidIn);
if (reward && rewardValidIn < validIn)
name << " reward in " << formatTime(rewardValidIn);
uint32 paymentValidIn = 0;
uint32 payment = GuildTaskMgr::instance().GetTaskValue(owner, guildId, "payment", &paymentValidIn);
uint32 payment = sGuildTaskMgr->GetTaskValue(owner, guildId, "payment", &paymentValidIn);
if (payment && paymentValidIn < validIn)
name << " payment " << ChatHelper::formatMoney(payment) << " in " << formatTime(paymentValidIn);
@@ -788,8 +788,8 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* /* handler */, char const*
if (cmd == "cleanup")
{
GuildTaskMgr::instance().CleanupAdverts();
GuildTaskMgr::instance().RemoveDuplicatedAdverts();
sGuildTaskMgr->CleanupAdverts();
sGuildTaskMgr->RemoveDuplicatedAdverts();
return true;
}
@@ -840,10 +840,10 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* /* handler */, char const*
continue;
if (reward)
GuildTaskMgr::instance().Reward(trans, owner, guildId);
sGuildTaskMgr->Reward(trans, owner, guildId);
if (advert)
GuildTaskMgr::instance().SendAdvertisement(trans, owner, guildId);
sGuildTaskMgr->SendAdvertisement(trans, owner, guildId);
} while (result->NextRow());
CharacterDatabase.CommitTransaction(trans);
@@ -868,7 +868,7 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
if (!guild)
return false;
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
if (!sRandomPlayerbotMgr->IsRandomBot(bot))
return false;
LOG_DEBUG("playerbots", "{} / {}: checking guild task", guild->GetName().c_str(), ownerPlayer->GetName().c_str());
@@ -891,7 +891,7 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
return false;
}
uint32 rewardTime = urand(sPlayerbotAIConfig.minGuildTaskRewardTime, sPlayerbotAIConfig.maxGuildTaskRewardTime);
uint32 rewardTime = urand(sPlayerbotAIConfig->minGuildTaskRewardTime, sPlayerbotAIConfig->maxGuildTaskRewardTime);
if (byMail)
{
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
@@ -915,7 +915,7 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
{
LOG_DEBUG("playerbots", "{} / {}: guild task progress {}/{}", guild->GetName().c_str(),
ownerPlayer->GetName().c_str(), obtained, count);
SetTaskValue(owner, guildId, "itemCount", count - obtained, sPlayerbotAIConfig.maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "itemCount", count - obtained, sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "thanks", 1, rewardTime - 30);
SendCompletionMessage(ownerPlayer, "made a progress with");
}
@@ -961,7 +961,7 @@ bool GuildTaskMgr::Reward(CharacterDatabaseTransaction& trans, uint32 owner, uin
body << leader->GetName() << "\n";
rewardType = proto->Quality > ITEM_QUALITY_NORMAL ? RANDOM_ITEM_GUILD_TASK_REWARD_EQUIP_BLUE
: RANDOM_ITEM_GUILD_TASK_REWARD_EQUIP_GREEN;
itemId = sRandomItemMgr.GetRandomItem(player->GetLevel() - 5, rewardType);
itemId = sRandomItemMgr->GetRandomItem(player->GetLevel() - 5, rewardType);
}
else if (killTask)
{
@@ -977,7 +977,7 @@ bool GuildTaskMgr::Reward(CharacterDatabaseTransaction& trans, uint32 owner, uin
body << leader->GetName() << "\n";
rewardType = proto->rank == CREATURE_ELITE_RARE ? RANDOM_ITEM_GUILD_TASK_REWARD_TRADE
: RANDOM_ITEM_GUILD_TASK_REWARD_TRADE_RARE;
itemId = sRandomItemMgr.GetRandomItem(player->GetLevel(), rewardType);
itemId = sRandomItemMgr->GetRandomItem(player->GetLevel(), rewardType);
if (itemId)
{
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(itemId);
@@ -1086,7 +1086,7 @@ void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
LOG_DEBUG("playerbots", "{} / {}: guild task complete", guild->GetName().c_str(), player->GetName().c_str());
SetTaskValue(owner, guildId, "reward", 1,
urand(sPlayerbotAIConfig.minGuildTaskRewardTime, sPlayerbotAIConfig.maxGuildTaskRewardTime));
urand(sPlayerbotAIConfig->minGuildTaskRewardTime, sPlayerbotAIConfig->maxGuildTaskRewardTime));
SendCompletionMessage(player, "completed");
}
@@ -1094,7 +1094,7 @@ void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
void GuildTaskMgr::CleanupAdverts()
{
uint32 deliverTime = time(nullptr) - sPlayerbotAIConfig.minGuildTaskChangeTime;
uint32 deliverTime = time(nullptr) - sPlayerbotAIConfig->minGuildTaskChangeTime;
QueryResult result = CharacterDatabase.Query(
"SELECT id, receiver FROM mail WHERE subject LIKE 'Guild Task%%' AND deliver_time <= {}", deliverTime);
if (!result)
@@ -1200,7 +1200,7 @@ bool GuildTaskMgr::CheckTaskTransfer(std::string const text, Player* ownerPlayer
if (!guild)
return false;
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
if (!sRandomPlayerbotMgr->IsRandomBot(bot))
return false;
if (text.empty())

62
src/GuildTaskMgr.h Normal file
View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_GUILDTASKMGR_H
#define _PLAYERBOT_GUILDTASKMGR_H
#include <map>
#include "Common.h"
#include "Transaction.h"
class ChatHandler;
class Player;
class Unit;
class GuildTaskMgr
{
public:
GuildTaskMgr(){};
virtual ~GuildTaskMgr(){};
static GuildTaskMgr* instance()
{
static GuildTaskMgr instance;
return &instance;
}
void Update(Player* owner, Player* guildMaster);
static bool HandleConsoleCommand(ChatHandler* handler, char const* args);
bool IsGuildTaskItem(uint32 itemId, uint32 guildId);
bool CheckItemTask(uint32 itemId, uint32 obtained, Player* owner, Player* bot, bool byMail = false);
void CheckKillTask(Player* owner, Unit* victim);
void CheckKillTaskInternal(Player* owner, Unit* victim);
bool CheckTaskTransfer(std::string const text, Player* owner, Player* bot);
private:
std::map<uint32, uint32> GetTaskValues(uint32 owner, std::string const type, uint32* validIn = nullptr);
uint32 GetTaskValue(uint32 owner, uint32 guildId, std::string const type, uint32* validIn = nullptr);
uint32 SetTaskValue(uint32 owner, uint32 guildId, std::string const type, uint32 value, uint32 validIn);
uint32 CreateTask(Player* owner, uint32 guildId);
bool SendAdvertisement(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId);
bool SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner, uint32 guildId,
uint32 validIn);
bool SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32 creatureId, uint32 owner, uint32 guildId,
uint32 validIn);
bool SendThanks(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId, uint32 payment);
bool Reward(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId);
bool CreateItemTask(Player* owner, uint32 guildId);
bool CreateKillTask(Player* owner, uint32 guildId);
uint32 GetMaxItemTaskCount(uint32 itemId);
void CleanupAdverts();
void RemoveDuplicatedAdverts();
void DeleteMail(std::vector<uint32> buffer);
void SendCompletionMessage(Player* player, std::string const verb);
};
#define sGuildTaskMgr GuildTaskMgr::instance()
#endif

50
src/Helpers.cpp Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "Helpers.h"
char* strstri(char const* haystack, char const* needle)
{
if (!*needle)
{
return (char*)haystack;
}
for (; *haystack; ++haystack)
{
if (tolower(*haystack) == tolower(*needle))
{
char const *h = haystack, *n = needle;
for (; *h && *n; ++h, ++n)
{
if (tolower(*h) != tolower(*n))
{
break;
}
}
if (!*n)
{
return (char*)haystack;
}
}
}
return 0;
}
std::string& ltrim(std::string& s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
return s;
}
std::string& rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
return s;
}
std::string& trim(std::string& s) { return ltrim(rtrim(s)); }

55
src/Helpers.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_HELPERS_H
#define _PLAYERBOT_HELPERS_H
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cctype>
#include <functional>
#include <locale>
#include <map>
#include <sstream>
#include <vector>
#include "Common.h"
void split(std::vector<std::string>& dest, std::string const str, char const* delim)
{
char* pTempStr = strdup(str.c_str());
char* pWord = strtok(pTempStr, delim);
while (pWord != nullptr)
{
dest.push_back(pWord);
pWord = strtok(nullptr, delim);
}
free(pTempStr);
}
std::vector<std::string>& split(std::string const s, char delim, std::vector<std::string>& elems)
{
std::stringstream ss(s);
std::string item;
while (getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(std::string const s, char delim)
{
std::vector<std::string> elems;
return split(s, delim, elems);
}
#endif

39
src/LazyCalculatedValue.h Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_LAZYCALCULATEDVALUE_H
#define _PLAYERBOT_LAZYCALCULATEDVALUE_H
template <class TValue, class TOwner>
class LazyCalculatedValue
{
public:
typedef TValue (TOwner::*Calculator)();
public:
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) { Reset(); }
public:
TValue GetValue()
{
if (!calculated)
{
value = (owner->*calculator)();
calculated = true;
}
return value;
}
void Reset() { calculated = false; }
protected:
Calculator calculator;
TOwner* owner;
bool calculated;
TValue value;
};
#endif

View File

@@ -1,67 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_GUILDTASKMGR_H
#define _PLAYERBOT_GUILDTASKMGR_H
#include <map>
#include <vector>
#include <cstdint>
#include "DatabaseEnvFwd.h"
#include "Unit.h"
#include "Player.h"
#include "Chat.h"
class GuildTaskMgr
{
public:
static GuildTaskMgr& instance()
{
static GuildTaskMgr instance;
return instance;
}
void Update(Player* owner, Player* guildMaster);
static bool HandleConsoleCommand(ChatHandler* handler, char const* args);
bool IsGuildTaskItem(uint32_t itemId, uint32_t guildId);
bool CheckItemTask(uint32_t itemId, uint32_t obtained, Player* owner, Player* bot, bool byMail = false);
void CheckKillTask(Player* owner, Unit* victim);
void CheckKillTaskInternal(Player* owner, Unit* victim);
bool CheckTaskTransfer(std::string const text, Player* owner, Player* bot);
private:
GuildTaskMgr() = default;
~GuildTaskMgr() = default;
GuildTaskMgr(const GuildTaskMgr&) = delete;
GuildTaskMgr& operator=(const GuildTaskMgr&) = delete;
GuildTaskMgr(GuildTaskMgr&&) = delete;
GuildTaskMgr& operator=(GuildTaskMgr&&) = delete;
std::map<uint32_t, uint32_t> GetTaskValues(uint32_t owner, std::string const type, uint32_t* validIn = nullptr);
uint32_t GetTaskValue(uint32_t owner, uint32_t guildId, std::string const type, uint32_t* validIn = nullptr);
uint32_t SetTaskValue(uint32_t owner, uint32_t guildId, std::string const type, uint32_t value, uint32_t validIn);
uint32_t CreateTask(Player* owner, uint32_t guildId);
bool SendAdvertisement(CharacterDatabaseTransaction& trans, uint32_t owner, uint32_t guildId);
bool SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32_t itemId, uint32_t owner, uint32_t guildId,
uint32_t validIn);
bool SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32_t creatureId, uint32_t owner, uint32_t guildId,
uint32_t validIn);
bool SendThanks(CharacterDatabaseTransaction& trans, uint32_t owner, uint32_t guildId, uint32_t payment);
bool Reward(CharacterDatabaseTransaction& trans, uint32_t owner, uint32_t guildId);
bool CreateItemTask(Player* owner, uint32_t guildId);
bool CreateKillTask(Player* owner, uint32_t guildId);
uint32_t GetMaxItemTaskCount(uint32_t itemId);
void CleanupAdverts();
void RemoveDuplicatedAdverts();
void DeleteMail(std::vector<uint32_t> buffer);
void SendCompletionMessage(Player* player, std::string const verb);
};
#endif

View File

@@ -3,14 +3,14 @@
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "PerfMonitor.h"
#include "PerformanceMonitor.h"
#include "Playerbots.h"
PerfMonitorOperation* PerfMonitor::start(PerformanceMetric metric, std::string const name,
PerformanceMonitorOperation* PerformanceMonitor::start(PerformanceMetric metric, std::string const name,
PerformanceStack* stack)
{
if (!sPlayerbotAIConfig.perfMonEnabled)
if (!sPlayerbotAIConfig->perfMonEnabled)
return nullptr;
std::string stackName = name;
@@ -45,10 +45,10 @@ PerfMonitorOperation* PerfMonitor::start(PerformanceMetric metric, std::string c
data[metric][stackName] = pd;
}
return new PerfMonitorOperation(pd, name, stack);
return new PerformanceMonitorOperation(pd, name, stack);
}
void PerfMonitor::PrintStats(bool perTick, bool fullStack)
void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
{
if (data.empty())
return;
@@ -247,7 +247,7 @@ void PerfMonitor::PrintStats(bool perTick, bool fullStack)
}
}
void PerfMonitor::Reset()
void PerformanceMonitor::Reset()
{
for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*>>::iterator i = data.begin();
i != data.end(); ++i)
@@ -265,7 +265,7 @@ void PerfMonitor::Reset()
}
}
PerfMonitorOperation::PerfMonitorOperation(PerformanceData* data, std::string const name,
PerformanceMonitorOperation::PerformanceMonitorOperation(PerformanceData* data, std::string const name,
PerformanceStack* stack)
: data(data), name(name), stack(stack)
{
@@ -273,7 +273,7 @@ PerfMonitorOperation::PerfMonitorOperation(PerformanceData* data, std::string co
.time_since_epoch();
}
void PerfMonitorOperation::finish()
void PerformanceMonitorOperation::finish()
{
std::chrono::microseconds finished =
(std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()))

View File

@@ -11,16 +11,17 @@
#include <map>
#include <mutex>
#include <vector>
#include <cstdint>
#include "Common.h"
typedef std::vector<std::string> PerformanceStack;
struct PerformanceData
{
uint64_t minTime;
uint64_t maxTime;
uint64_t totalTime;
uint32_t count;
uint64 minTime;
uint64 maxTime;
uint64 totalTime;
uint32 count;
std::mutex lock;
};
@@ -33,10 +34,10 @@ enum PerformanceMetric
PERF_MON_TOTAL
};
class PerfMonitorOperation
class PerformanceMonitorOperation
{
public:
PerfMonitorOperation(PerformanceData* data, std::string const name, PerformanceStack* stack);
PerformanceMonitorOperation(PerformanceData* data, std::string const name, PerformanceStack* stack);
void finish();
private:
@@ -46,35 +47,28 @@ private:
std::chrono::microseconds started;
};
class PerfMonitor
class PerformanceMonitor
{
public:
static PerfMonitor& instance()
PerformanceMonitor(){};
virtual ~PerformanceMonitor(){};
static PerformanceMonitor* instance()
{
static PerfMonitor instance;
return instance;
static PerformanceMonitor instance;
return &instance;
}
PerfMonitorOperation* start(PerformanceMetric metric, std::string const name,
public:
PerformanceMonitorOperation* start(PerformanceMetric metric, std::string const name,
PerformanceStack* stack = nullptr);
void PrintStats(bool perTick = false, bool fullStack = false);
void Reset();
private:
PerfMonitor() = default;
virtual ~PerfMonitor() = default;
PerfMonitor(const PerfMonitor&) = delete;
PerfMonitor& operator=(const PerfMonitor&) = delete;
PerfMonitor(PerfMonitor&&) = delete;
PerfMonitor& operator=(PerfMonitor&&) = delete;
std::map<PerformanceMetric, std::map<std::string, PerformanceData*> > data;
std::mutex lock;
};
#define sPerfMonitor PerfMonitor::instance()
#define sPerformanceMonitor PerformanceMonitor::instance()
#endif

View File

@@ -10,7 +10,7 @@
#include "Common.h"
#include "Player.h"
#include "PlayerbotDungeonRepository.h"
#include "PlayerbotDungeonSuggestionMgr.h"
typedef std::map<std::string, std::string> PlaceholderMap;

File diff suppressed because it is too large Load Diff

View File

@@ -429,8 +429,8 @@ public:
static uint32 GetGroupTankNum(Player* player);
static bool IsAssistTank(Player* player);
static bool IsAssistTankOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
static bool IsAssistHealOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
static bool IsAssistRangedDpsOfIndex(Player* player, int index, bool ignoreDeadPlayers = false);
static bool IsHealAssistantOfIndex(Player* player, int index);
static bool IsRangedDpsAssistantOfIndex(Player* player, int index);
bool HasAggro(Unit* unit);
static int32 GetAssistTankIndex(Player* player);
int32 GetGroupSlotIndex(Player* player);
@@ -491,7 +491,7 @@ public:
void ImbueItem(Item* item);
void EnchantItemT(uint32 spellid, uint8 slot);
uint32 GetBuffedCount(Player* player, std::string const spellname);
int32 GetNearGroupMemberCount(float dis = sPlayerbotAIConfig.sightDistance);
int32 GetNearGroupMemberCount(float dis = sPlayerbotAIConfig->sightDistance);
virtual bool CanCastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr);
virtual bool CastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr);
@@ -545,9 +545,9 @@ public:
uint32 GetFixedBotNumer(uint32 maxNum = 100, float cyclePerMin = 1);
GrouperType GetGrouperType();
GuilderType GetGuilderType();
bool HasPlayerNearby(WorldPosition* pos, float range = sPlayerbotAIConfig.reactDistance);
bool HasPlayerNearby(float range = sPlayerbotAIConfig.reactDistance);
bool HasManyPlayersNearby(uint32 trigerrValue = 20, float range = sPlayerbotAIConfig.sightDistance);
bool HasPlayerNearby(WorldPosition* pos, float range = sPlayerbotAIConfig->reactDistance);
bool HasPlayerNearby(float range = sPlayerbotAIConfig->reactDistance);
bool HasManyPlayersNearby(uint32 trigerrValue = 20, float range = sPlayerbotAIConfig->sightDistance);
bool AllowActive(ActivityType activityType);
bool AllowActivity(ActivityType activityType = ALL_ACTIVITY, bool checkNow = false);
uint32 AutoScaleActivity(uint32 mod);
@@ -562,7 +562,7 @@ public:
bool HasCheat(BotCheatMask mask)
{
return ((uint32)mask & (uint32)cheatMask) != 0 ||
((uint32)mask & (uint32)sPlayerbotAIConfig.botCheatMask) != 0;
((uint32)mask & (uint32)sPlayerbotAIConfig->botCheatMask) != 0;
}
BotCheatMask GetCheat() { return cheatMask; }
void SetCheat(BotCheatMask mask) { cheatMask = mask; }

View File

@@ -14,7 +14,7 @@ void PlayerbotAIBase::UpdateAI(uint32 elapsed, bool minimal)
if (totalPmo)
totalPmo->finish();
totalPmo = sPerfMonitor.start(PERF_MON_TOTAL, "PlayerbotAIBase::FullTick");
totalPmo = sPerformanceMonitor->start(PERF_MON_TOTAL, "PlayerbotAIBase::FullTick");
if (nextAICheckDelay > elapsed)
nextAICheckDelay -= elapsed;
@@ -35,7 +35,7 @@ void PlayerbotAIBase::SetNextCheckDelay(uint32 const delay)
nextAICheckDelay = delay;
// if (nextAICheckDelay > sPlayerbotAIConfig.globalCoolDown)
// if (nextAICheckDelay > sPlayerbotAIConfig->globalCoolDown)
// LOG_DEBUG("playerbots", "std::set next check delay: {}", nextAICheckDelay);
}
@@ -43,7 +43,7 @@ void PlayerbotAIBase::IncreaseNextCheckDelay(uint32 delay)
{
nextAICheckDelay += delay;
// if (nextAICheckDelay > sPlayerbotAIConfig.globalCoolDown)
// if (nextAICheckDelay > sPlayerbotAIConfig->globalCoolDown)
// LOG_DEBUG("playerbots", "increase next check delay: {}", nextAICheckDelay);
}
@@ -55,6 +55,6 @@ void PlayerbotAIBase::YieldThread(uint32 delay)
nextAICheckDelay = delay;
}
bool PlayerbotAIBase::IsActive() { return nextAICheckDelay < sPlayerbotAIConfig.maxWaitForMove; }
bool PlayerbotAIBase::IsActive() { return nextAICheckDelay < sPlayerbotAIConfig->maxWaitForMove; }
bool PlayerbotAIBase::IsBotAI() const { return _isBotAI; }

View File

@@ -17,7 +17,7 @@ public:
bool CanUpdateAI();
void SetNextCheckDelay(uint32 const delay);
void IncreaseNextCheckDelay(uint32 delay);
void YieldThread(uint32 delay = sPlayerbotAIConfig.reactDelay);
void YieldThread(uint32 delay = sPlayerbotAIConfig->reactDelay);
virtual void UpdateAI(uint32 elapsed, bool minimal = false);
virtual void UpdateAIInternal(uint32 elapsed, bool minimal = false) = 0;
bool IsActive();
@@ -25,7 +25,7 @@ public:
protected:
uint32 nextAICheckDelay;
class PerfMonitorOperation* totalPmo = nullptr;
class PerformanceMonitorOperation* totalPmo = nullptr;
private:
bool _isBotAI;

View File

@@ -7,7 +7,7 @@
#include <iostream>
#include "Config.h"
#include "NewRpgInfo.h"
#include "PlayerbotDungeonRepository.h"
#include "PlayerbotDungeonSuggestionMgr.h"
#include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "PlayerbotGuildMgr.h"
@@ -660,25 +660,25 @@ bool PlayerbotAIConfig::Initialize()
}
// Assign account types after accounts are created
sRandomPlayerbotMgr.AssignAccountTypes();
sRandomPlayerbotMgr->AssignAccountTypes();
if (sPlayerbotAIConfig.enabled)
if (sPlayerbotAIConfig->enabled)
{
sRandomPlayerbotMgr.Init();
sRandomPlayerbotMgr->Init();
}
PlayerbotGuildMgr::instance().Init();
sRandomItemMgr.Init();
sRandomItemMgr.InitAfterAhBot();
PlayerbotTextMgr::instance().LoadBotTexts();
PlayerbotTextMgr::instance().LoadBotTextChance();
sPlayerbotGuildMgr->Init();
sRandomItemMgr->Init();
sRandomItemMgr->InitAfterAhBot();
sPlayerbotTextMgr->LoadBotTexts();
sPlayerbotTextMgr->LoadBotTextChance();
PlayerbotFactory::Init();
AiObjectContext::BuildAllSharedContexts();
if (sPlayerbotAIConfig.randomBotSuggestDungeons)
if (sPlayerbotAIConfig->randomBotSuggestDungeons)
{
PlayerbotDungeonRepository::instance().LoadDungeonSuggestions();
sPlayerbotDungeonSuggestionMgr->LoadDungeonSuggestions();
}
excludedHunterPetFamilies.clear();

View File

@@ -8,14 +8,11 @@
#include <mutex>
#include <unordered_map>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include "Common.h"
#include "DBCEnums.h"
#include "SharedDefines.h"
#include "Talentspec.h"
enum class BotCheatMask : uint32
{
@@ -65,11 +62,11 @@ enum NewRpgStatus : int
class PlayerbotAIConfig
{
public:
static PlayerbotAIConfig& instance()
PlayerbotAIConfig(){};
static PlayerbotAIConfig* instance()
{
static PlayerbotAIConfig instance;
return instance;
return &instance;
}
bool Initialize();
@@ -452,16 +449,6 @@ public:
bool IsRestrictedHealerDPSMap(uint32 mapId) const;
std::vector<uint32> excludedHunterPetFamilies;
private:
PlayerbotAIConfig() = default;
~PlayerbotAIConfig() = default;
PlayerbotAIConfig(const PlayerbotAIConfig&) = delete;
PlayerbotAIConfig& operator=(const PlayerbotAIConfig&) = delete;
PlayerbotAIConfig(PlayerbotAIConfig&&) = delete;
PlayerbotAIConfig& operator=(PlayerbotAIConfig&&) = delete;
};
#define sPlayerbotAIConfig PlayerbotAIConfig::instance()

View File

@@ -48,7 +48,7 @@ void session(socket_ptr sock)
std::string buffer, request;
while (ReadLine(sock, &buffer, &request))
{
std::string const response = sRandomPlayerbotMgr.HandleRemoteCommand(request) + "\n";
std::string const response = sRandomPlayerbotMgr->HandleRemoteCommand(request) + "\n";
boost::asio::write(*sock, boost::asio::buffer(response.c_str(), response.size()));
request = "";
}
@@ -72,19 +72,19 @@ void server(Acore::Asio::IoContext& io_service, short port)
void Run()
{
if (!sPlayerbotAIConfig.commandServerPort)
if (!sPlayerbotAIConfig->commandServerPort)
{
return;
}
std::ostringstream s;
s << "Starting Playerbots Command Server on port " << sPlayerbotAIConfig.commandServerPort;
s << "Starting Playerbots Command Server on port " << sPlayerbotAIConfig->commandServerPort;
LOG_INFO("playerbots", "{}", s.str().c_str());
try
{
Acore::Asio::IoContext io_service;
server(io_service, sPlayerbotAIConfig.commandServerPort);
server(io_service, sPlayerbotAIConfig->commandServerPort);
}
catch (std::exception& e)

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTCOMMANDSERVER_H
#define _PLAYERBOT_PLAYERBOTCOMMANDSERVER_H
class PlayerbotCommandServer
{
public:
PlayerbotCommandServer() {}
virtual ~PlayerbotCommandServer() {}
static PlayerbotCommandServer* instance()
{
static PlayerbotCommandServer instance;
return &instance;
}
void Start();
};
#define sPlayerbotCommandServer PlayerbotCommandServer::instance()
#endif

View File

@@ -3,13 +3,13 @@
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "PlayerbotRepository.h"
#include "PlayerbotDbStore.h"
#include <iostream>
#include "Playerbots.h"
void PlayerbotRepository::Load(PlayerbotAI* botAI)
void PlayerbotDbStore::Load(PlayerbotAI* botAI)
{
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
@@ -46,7 +46,7 @@ void PlayerbotRepository::Load(PlayerbotAI* botAI)
}
}
void PlayerbotRepository::Save(PlayerbotAI* botAI)
void PlayerbotDbStore::Save(PlayerbotAI* botAI)
{
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
@@ -68,7 +68,7 @@ void PlayerbotRepository::Save(PlayerbotAI* botAI)
SaveValue(guid, "dead", FormatStrategies("dead", botAI->GetStrategies(BOT_STATE_DEAD)));
}
std::string const PlayerbotRepository::FormatStrategies(std::string const type, std::vector<std::string> strategies)
std::string const PlayerbotDbStore::FormatStrategies(std::string const type, std::vector<std::string> strategies)
{
std::ostringstream out;
for (std::vector<std::string>::iterator i = strategies.begin(); i != strategies.end(); ++i)
@@ -78,7 +78,7 @@ std::string const PlayerbotRepository::FormatStrategies(std::string const type,
return res.substr(0, res.size() - 1);
}
void PlayerbotRepository::Reset(PlayerbotAI* botAI)
void PlayerbotDbStore::Reset(PlayerbotAI* botAI)
{
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
@@ -87,7 +87,7 @@ void PlayerbotRepository::Reset(PlayerbotAI* botAI)
PlayerbotsDatabase.Execute(stmt);
}
void PlayerbotRepository::SaveValue(uint32 guid, std::string const key, std::string const value)
void PlayerbotDbStore::SaveValue(uint32 guid, std::string const key, std::string const value)
{
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_INS_DB_STORE);
stmt->SetData(0, guid);

37
src/PlayerbotDbStore.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTDBSTORE_H
#define _PLAYERBOT_PLAYERBOTDBSTORE_H
#include <vector>
#include "Common.h"
class PlayerbotAI;
class PlayerbotDbStore
{
public:
PlayerbotDbStore() {}
virtual ~PlayerbotDbStore() {}
static PlayerbotDbStore* instance()
{
static PlayerbotDbStore instance;
return &instance;
}
void Save(PlayerbotAI* botAI);
void Load(PlayerbotAI* botAI);
void Reset(PlayerbotAI* botAI);
private:
void SaveValue(uint32 guid, std::string const key, std::string const value);
std::string const FormatStrategies(std::string const type, std::vector<std::string> strategies);
};
#define sPlayerbotDbStore PlayerbotDbStore::instance()
#endif

View File

@@ -3,22 +3,16 @@
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "Log.h"
#include "Timer.h"
#include "DatabaseEnv.h"
#include "Field.h"
#include "World.h"
// Required import due to poor implementation by AC
#include "QueryResult.h"
#include "PlayerbotDungeonSuggestionMgr.h"
#include "PlayerbotDungeonRepository.h"
#include "Playerbots.h"
std::vector<DungeonSuggestion> const PlayerbotDungeonRepository::GetDungeonSuggestions()
std::vector<DungeonSuggestion> const PlayerbotDungeonSuggestionMgr::GetDungeonSuggestions()
{
return m_dungeonSuggestions;
}
void PlayerbotDungeonRepository::LoadDungeonSuggestions()
void PlayerbotDungeonSuggestionMgr::LoadDungeonSuggestions()
{
LOG_INFO("server.loading", "Loading playerbots dungeon suggestions...");
uint32 oldMSTime = getMSTime();

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTDUNGEONSUGGESTIONMGR_H
#define _PLAYERBOT_PLAYERBOTDUNGEONSUGGESTIONMGR_H
#include <map>
#include <vector>
#include "Common.h"
#include "DBCEnums.h"
struct DungeonSuggestion
{
std::string name;
Difficulty difficulty;
uint8 min_level;
uint8 max_level;
std::string abbrevation;
std::string strategy;
};
class PlayerbotDungeonSuggestionMgr
{
public:
PlayerbotDungeonSuggestionMgr(){};
~PlayerbotDungeonSuggestionMgr(){};
static PlayerbotDungeonSuggestionMgr* instance()
{
static PlayerbotDungeonSuggestionMgr instance;
return &instance;
}
void LoadDungeonSuggestions();
std::vector<DungeonSuggestion> const GetDungeonSuggestions();
private:
std::vector<DungeonSuggestion> m_dungeonSuggestions;
};
#define sPlayerbotDungeonSuggestionMgr PlayerbotDungeonSuggestionMgr::instance()
#endif

View File

@@ -4,12 +4,15 @@
#include "DatabaseEnv.h"
#include "Guild.h"
#include "GuildMgr.h"
#include "RandomPlayerbotMgr.h"
#include "ScriptMgr.h"
PlayerbotGuildMgr::PlayerbotGuildMgr(){}
void PlayerbotGuildMgr::Init()
{
_guildCache.clear();
if (sPlayerbotAIConfig.deleteRandomBotGuilds)
if (sPlayerbotAIConfig->deleteRandomBotGuilds)
DeleteBotGuilds();
LoadGuildNames();
@@ -35,7 +38,7 @@ bool PlayerbotGuildMgr::CreateGuild(Player* player, std::string guildName)
entry.name = guildName;
entry.memberCount = 1;
entry.status = 1;
entry.maxMembers = sPlayerbotAIConfig.randomBotGuildSizeMax;
entry.maxMembers = sPlayerbotAIConfig->randomBotGuildSizeMax;
entry.faction = player->GetTeamId();
_guildCache[guild->GetId()] = entry;
@@ -110,7 +113,7 @@ std::string PlayerbotGuildMgr::AssignToGuild(Player* player)
}
);
if (count < sPlayerbotAIConfig.randomBotGuildCount)
if (count < sPlayerbotAIConfig->randomBotGuildCount)
{
for (auto& key : _shuffled_guild_keys)
{
@@ -211,7 +214,7 @@ void PlayerbotGuildMgr::ValidateGuildCache()
uint32 guildId = it->first;
GuildCache cache;
cache.name = it->second;
cache.maxMembers = sPlayerbotAIConfig.randomBotGuildSizeMax;
cache.maxMembers = sPlayerbotAIConfig->randomBotGuildSizeMax;
Guild* guild = sGuildMgr ->GetGuildById(guildId);
if (!guild)
@@ -221,7 +224,7 @@ void PlayerbotGuildMgr::ValidateGuildCache()
ObjectGuid leaderGuid = guild->GetLeaderGUID();
CharacterCacheEntry const* leaderEntry = sCharacterCache->GetCharacterCacheByGuid(leaderGuid);
uint32 leaderAccount = leaderEntry->AccountId;
cache.hasRealPlayer = !(sPlayerbotAIConfig.IsInRandomAccountList(leaderAccount));
cache.hasRealPlayer = !(sPlayerbotAIConfig->IsInRandomAccountList(leaderAccount));
cache.faction = Player::TeamIdForRace(leaderEntry->Race);
if (cache.memberCount == 0)
cache.status = 0; // empty
@@ -303,7 +306,7 @@ class BotGuildCacheWorldScript : public WorldScript
if (_validateTimer >= _validateInterval) // Validate every hour
{
_validateTimer = 0;
PlayerbotGuildMgr::instance().ValidateGuildCache();
sPlayerbotGuildMgr->ValidateGuildCache();
LOG_INFO("playerbots", "Scheduled guild cache validation");
}
}

View File

@@ -5,14 +5,15 @@
#include "Player.h"
#include "PlayerbotAI.h"
class PlayerbotAI;
class PlayerbotGuildMgr
{
public:
static PlayerbotGuildMgr& instance()
static PlayerbotGuildMgr* instance()
{
static PlayerbotGuildMgr instance;
return instance;
return &instance;
}
void Init();
@@ -28,15 +29,7 @@ public:
bool IsRealGuild(Player* bot);
private:
PlayerbotGuildMgr() = default;
~PlayerbotGuildMgr() = default;
PlayerbotGuildMgr(const PlayerbotGuildMgr&) = delete;
PlayerbotGuildMgr& operator=(const PlayerbotGuildMgr&) = delete;
PlayerbotGuildMgr(PlayerbotGuildMgr&&) = delete;
PlayerbotGuildMgr& operator=(PlayerbotGuildMgr&&) = delete;
PlayerbotGuildMgr();
std::unordered_map<std::string, bool> _guildNames;
struct GuildCache
@@ -54,4 +47,6 @@ private:
void PlayerBotsGuildValidationScript();
#define sPlayerbotGuildMgr PlayerbotGuildMgr::instance()
#endif

View File

@@ -26,7 +26,7 @@
#include "ObjectGuid.h"
#include "ObjectMgr.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotRepository.h"
#include "PlayerbotDbStore.h"
#include "PlayerbotFactory.h"
#include "PlayerbotOperations.h"
#include "PlayerbotSecurity.h"
@@ -102,11 +102,11 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
Player* masterPlayer = masterSession ? masterSession->GetPlayer() : nullptr;
bool isRndbot = !masterAccountId;
bool sameAccount = sPlayerbotAIConfig.allowAccountBots && accountId == masterAccountId;
bool sameAccount = sPlayerbotAIConfig->allowAccountBots && accountId == masterAccountId;
Guild* guild = masterPlayer ? sGuildMgr->GetGuildById(masterPlayer->GetGuildId()) : nullptr;
bool sameGuild = sPlayerbotAIConfig.allowGuildBots && guild && guild->GetMember(playerGuid);
bool addClassBot = sRandomPlayerbotMgr.IsAddclassBot(playerGuid.GetCounter());
bool linkedAccount = sPlayerbotAIConfig.allowTrustedAccountBots && IsAccountLinked(accountId, masterAccountId);
bool sameGuild = sPlayerbotAIConfig->allowGuildBots && guild && guild->GetMember(playerGuid);
bool addClassBot = sRandomPlayerbotMgr->IsAddclassBot(playerGuid.GetCounter());
bool linkedAccount = sPlayerbotAIConfig->allowTrustedAccountBots && IsAccountLinked(accountId, masterAccountId);
bool allowed = true;
std::ostringstream out;
@@ -126,10 +126,10 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
return;
}
uint32 count = mgr->GetPlayerbotsCount() + botLoading.size();
if (count >= sPlayerbotAIConfig.maxAddedBots)
if (count >= sPlayerbotAIConfig->maxAddedBots)
{
allowed = false;
out << "Failure: You have added too many bots (more than " << sPlayerbotAIConfig.maxAddedBots << ")";
out << "Failure: You have added too many bots (more than " << sPlayerbotAIConfig->maxAddedBots << ")";
}
}
if (!allowed)
@@ -156,6 +156,7 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
[](SQLQueryHolderBase const& queryHolder)
{
PlayerbotLoginQueryHolder const& holder = static_cast<PlayerbotLoginQueryHolder const&>(queryHolder);
PlayerbotHolder* mgr = sRandomPlayerbotMgr; // could be null
uint32 masterAccountId = holder.GetMasterAccountId();
if (masterAccountId)
@@ -163,25 +164,14 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
// verify and find current world session of master
WorldSession* masterSession = sWorldSessionMgr->FindSession(masterAccountId);
Player* masterPlayer = masterSession ? masterSession->GetPlayer() : nullptr;
if (masterPlayer)
{
PlayerbotHolder* mgr = PlayerbotsMgr::instance().GetPlayerbotMgr(masterPlayer);
mgr = GET_PLAYERBOT_MGR(masterPlayer);
}
if (mgr != nullptr)
{
if (mgr)
mgr->HandlePlayerBotLoginCallback(holder);
return;
}
else
PlayerbotHolder::botLoading.erase(holder.GetGuid());
return;
}
}
RandomPlayerbotMgr ::instance().HandlePlayerBotLoginCallback(holder);
});
}
@@ -226,9 +216,9 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
masterAccountId);
}
sRandomPlayerbotMgr.OnPlayerLogin(bot);
sRandomPlayerbotMgr->OnPlayerLogin(bot);
auto op = std::make_unique<OnBotLoginOperation>(bot->GetGUID(), masterAccountId);
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(op));
sPlayerbotWorldProcessor->QueueOperation(std::move(op));
PlayerbotHolder::botLoading.erase(holder.GetGuid());
}
@@ -322,8 +312,8 @@ void PlayerbotMgr::CancelLogout()
}
}
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr.GetPlayerBotsBegin();
it != sRandomPlayerbotMgr.GetPlayerBotsEnd(); ++it)
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{
Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@@ -351,7 +341,7 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
// Queue group cleanup operation for world thread
auto cleanupOp = std::make_unique<BotLogoutGroupCleanupOperation>(guid);
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(cleanupOp));
sPlayerbotWorldProcessor->QueueOperation(std::move(cleanupOp));
LOG_DEBUG("playerbots", "Bot {} logging out", bot->GetName().c_str());
bot->SaveToDB(false, false);
@@ -452,7 +442,7 @@ void PlayerbotHolder::DisablePlayerBot(ObjectGuid guid)
Group* group = bot->GetGroup();
if (group && !bot->InBattleground() && !bot->InBattlegroundQueue() && botAI->HasActivePlayerMaster())
{
PlayerbotRepository::instance().Save(botAI);
sPlayerbotDbStore->Save(botAI);
}
LOG_DEBUG("playerbots", "Bot {} logged out", bot->GetName().c_str());
@@ -498,7 +488,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
return;
}
PlayerbotsMgr::instance().AddPlayerbotData(bot, true);
sPlayerbotsMgr->AddPlayerbotData(bot, true);
playerBots[bot->GetGUID()] = bot;
OnBotLoginInternal(bot);
@@ -538,10 +528,10 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
// Don't disband alt groups when master goes away
// Controlled by config
if (sPlayerbotAIConfig.KeepAltsInGroup())
if (sPlayerbotAIConfig->KeepAltsInGroup())
{
uint32 account = sCharacterCache->GetCharacterAccountIdByGuid(member);
if (!sPlayerbotAIConfig.IsInRandomAccountList(account))
if (!sPlayerbotAIConfig->IsInRandomAccountList(account))
{
groupValid = true;
break;
@@ -562,9 +552,9 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
}
else
{
botAI->ResetStrategies(!sRandomPlayerbotMgr.IsRandomBot(bot));
botAI->ResetStrategies(!sRandomPlayerbotMgr->IsRandomBot(bot));
}
PlayerbotRepository::instance().Load(botAI);
sPlayerbotDbStore->Load(botAI);
if (master && !master->HasUnitState(UNIT_STATE_IN_FLIGHT))
{
@@ -590,52 +580,52 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
{
// Queue ConvertToRaid operation
auto convertOp = std::make_unique<GroupConvertToRaidOperation>(master->GetGUID());
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(convertOp));
sPlayerbotWorldProcessor->QueueOperation(std::move(convertOp));
}
if (mgroup->isRaidGroup())
{
// Queue AddMember operation
auto addOp = std::make_unique<GroupInviteOperation>(master->GetGUID(), bot->GetGUID());
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(addOp));
sPlayerbotWorldProcessor->QueueOperation(std::move(addOp));
}
}
else
{
// Queue AddMember operation
auto addOp = std::make_unique<GroupInviteOperation>(master->GetGUID(), bot->GetGUID());
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(addOp));
sPlayerbotWorldProcessor->QueueOperation(std::move(addOp));
}
}
else if (master && !group)
{
// Queue group creation and AddMember operation
auto inviteOp = std::make_unique<GroupInviteOperation>(master->GetGUID(), bot->GetGUID());
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(inviteOp));
sPlayerbotWorldProcessor->QueueOperation(std::move(inviteOp));
}
// if (master)
// {
// // bot->TeleportTo(master);
// }
uint32 accountId = bot->GetSession()->GetAccountId();
bool isRandomAccount = sPlayerbotAIConfig.IsInRandomAccountList(accountId);
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId);
if (isRandomAccount && sPlayerbotAIConfig.randomBotFixedLevel)
if (isRandomAccount && sPlayerbotAIConfig->randomBotFixedLevel)
{
bot->SetPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
}
else if (isRandomAccount && !sPlayerbotAIConfig.randomBotFixedLevel)
else if (isRandomAccount && !sPlayerbotAIConfig->randomBotFixedLevel)
{
bot->RemovePlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
}
bot->SaveToDB(false, false);
bool addClassBot = sRandomPlayerbotMgr.IsAccountType(accountId, 2);
bool addClassBot = sRandomPlayerbotMgr->IsAccountType(accountId, 2);
if (addClassBot && master && abs((int)master->GetLevel() - (int)bot->GetLevel()) > 3)
{
// PlayerbotFactory factory(bot, master->GetLevel());
// factory.Randomize(false);
uint32 mixedGearScore =
PlayerbotAI::GetMixedGearScore(master, true, false, 12) * sPlayerbotAIConfig.autoInitEquipLevelLimitRatio;
PlayerbotAI::GetMixedGearScore(master, true, false, 12) * sPlayerbotAIConfig->autoInitEquipLevelLimitRatio;
// work around: distinguish from 0 if no gear
if (mixedGearScore == 0)
mixedGearScore = 1;
@@ -644,7 +634,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
}
// bots join World chat if not solo oriented
if (bot->GetLevel() >= 10 && sRandomPlayerbotMgr.IsRandomBot(bot) && GET_PLAYERBOT_AI(bot) &&
if (bot->GetLevel() >= 10 && sRandomPlayerbotMgr->IsRandomBot(bot) && GET_PLAYERBOT_AI(bot) &&
GET_PLAYERBOT_AI(bot)->GetGrouperType() != GrouperType::SOLO)
{
// TODO make action/config
@@ -712,12 +702,12 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid,
bool admin, uint32 masterAccountId, uint32 masterGuildId)
{
if (!sPlayerbotAIConfig.enabled || guid.IsEmpty())
if (!sPlayerbotAIConfig->enabled || guid.IsEmpty())
return "bot system is disabled";
uint32 botAccount = sCharacterCache->GetCharacterAccountIdByGuid(guid);
//bool isRandomBot = sRandomPlayerbotMgr.IsRandomBot(guid.GetCounter()); //not used, line marked for removal.
//bool isRandomAccount = sPlayerbotAIConfig.IsInRandomAccountList(botAccount); //not used, shadowed, line marked for removal.
//bool isRandomBot = sRandomPlayerbotMgr->IsRandomBot(guid.GetCounter()); //not used, line marked for removal.
//bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(botAccount); //not used, shadowed, line marked for removal.
//bool isMasterAccount = (masterAccountId == botAccount); //not used, line marked for removal.
if (cmd == "add" || cmd == "addaccount" || cmd == "login")
@@ -732,8 +722,8 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
if (!accountId)
return "character not found";
if (!sPlayerbotAIConfig.allowAccountBots && accountId != masterAccountId &&
!(sPlayerbotAIConfig.allowTrustedAccountBots && IsAccountLinked(accountId, masterAccountId)))
if (!sPlayerbotAIConfig->allowAccountBots && accountId != masterAccountId &&
!(sPlayerbotAIConfig->allowTrustedAccountBots && IsAccountLinked(accountId, masterAccountId)))
{
return "you can only add bots from your own account or linked accounts";
}
@@ -758,12 +748,12 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
// {
Player* bot = GetPlayerBot(guid);
if (!bot)
bot = sRandomPlayerbotMgr.GetPlayerBot(guid);
bot = sRandomPlayerbotMgr->GetPlayerBot(guid);
if (!bot)
return "bot not found";
bool addClassBot = sRandomPlayerbotMgr.IsAddclassBot(guid.GetCounter());
bool addClassBot = sRandomPlayerbotMgr->IsAddclassBot(guid.GetCounter());
if (!addClassBot)
return "ERROR: You can not use this command on non-addclass bot.";
@@ -781,7 +771,7 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
{
if (Player* master = GET_PLAYERBOT_AI(bot)->GetMaster())
{
if (master->GetSession()->GetSecurity() <= SEC_PLAYER && sPlayerbotAIConfig.autoInitOnly &&
if (master->GetSession()->GetSecurity() <= SEC_PLAYER && sPlayerbotAIConfig->autoInitOnly &&
cmd != "init=auto")
{
return "The command is not allowed, use init=auto instead.";
@@ -828,7 +818,7 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
else if (cmd == "init=auto")
{
uint32 mixedGearScore = PlayerbotAI::GetMixedGearScore(master, true, false, 12) *
sPlayerbotAIConfig.autoInitEquipLevelLimitRatio;
sPlayerbotAIConfig->autoInitEquipLevelLimitRatio;
// work around: distinguish from 0 if no gear
if (mixedGearScore == 0)
mixedGearScore = 1;
@@ -868,7 +858,7 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
}
else if (cmd == "random")
{
sRandomPlayerbotMgr.Randomize(bot);
sRandomPlayerbotMgr->Randomize(bot);
return "ok";
}
else if (cmd == "quests")
@@ -896,7 +886,7 @@ static uint8 GetOfflinePlayerGender(ObjectGuid guid)
bool PlayerbotMgr::HandlePlayerbotMgrCommand(ChatHandler* handler, char const* args)
{
if (!sPlayerbotAIConfig.enabled)
if (!sPlayerbotAIConfig->enabled)
{
handler->PSendSysMessage("|cffff0000Playerbot system is currently disabled!");
return false;
@@ -1062,7 +1052,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
{
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
{
sPlayerbotAIConfig.Initialize();
sPlayerbotAIConfig->Initialize();
messages.push_back("Config reloaded.");
return messages;
}
@@ -1075,11 +1065,11 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
if (!strcmp(cmd, "tweak"))
{
sPlayerbotAIConfig.tweakValue = sPlayerbotAIConfig.tweakValue++;
if (sPlayerbotAIConfig.tweakValue > 2)
sPlayerbotAIConfig.tweakValue = 0;
sPlayerbotAIConfig->tweakValue = sPlayerbotAIConfig->tweakValue++;
if (sPlayerbotAIConfig->tweakValue > 2)
sPlayerbotAIConfig->tweakValue = 0;
messages.push_back("Set tweakvalue to " + std::to_string(sPlayerbotAIConfig.tweakValue));
messages.push_back("Set tweakvalue to " + std::to_string(sPlayerbotAIConfig->tweakValue));
return messages;
}
@@ -1090,14 +1080,14 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
messages.push_back("Disable player botAI");
delete GET_PLAYERBOT_AI(master);
}
else if (sPlayerbotAIConfig.selfBotLevel == 0)
else if (sPlayerbotAIConfig->selfBotLevel == 0)
messages.push_back("Self-bot is disabled");
else if (sPlayerbotAIConfig.selfBotLevel == 1 && master->GetSession()->GetSecurity() < SEC_GAMEMASTER)
else if (sPlayerbotAIConfig->selfBotLevel == 1 && master->GetSession()->GetSecurity() < SEC_GAMEMASTER)
messages.push_back("You do not have permission to enable player botAI");
else
{
messages.push_back("Enable player botAI");
PlayerbotsMgr::instance().AddPlayerbotData(master, true);
sPlayerbotsMgr->AddPlayerbotData(master, true);
GET_PLAYERBOT_AI(master)->SetMaster(master);
}
@@ -1112,7 +1102,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
if (!strcmp(cmd, "addclass"))
{
if (sPlayerbotAIConfig.addClassCommand == 0 && master->GetSession()->GetSecurity() < SEC_GAMEMASTER)
if (sPlayerbotAIConfig->addClassCommand == 0 && master->GetSession()->GetSecurity() < SEC_GAMEMASTER)
{
messages.push_back("You do not have permission to create bot by addclass command");
return messages;
@@ -1193,7 +1183,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
return messages;
}
uint8 teamId = master->GetTeamId(true);
const std::unordered_set<ObjectGuid> &guidCache = sRandomPlayerbotMgr.addclassCache[RandomPlayerbotMgr::GetTeamClassIdx(teamId == TEAM_ALLIANCE, claz)];
const std::unordered_set<ObjectGuid> &guidCache = sRandomPlayerbotMgr->addclassCache[RandomPlayerbotMgr::GetTeamClassIdx(teamId == TEAM_ALLIANCE, claz)];
for (const ObjectGuid &guid: guidCache)
{
// If the user requested a specific gender, skip any character that doesn't match.
@@ -1204,7 +1194,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
if (ObjectAccessor::FindConnectedPlayer(guid))
continue;
uint32 guildId = sCharacterCache->GetCharacterGuildIdByGuid(guid);
if (guildId && PlayerbotGuildMgr::instance().IsRealGuild(guildId))
if (guildId && sPlayerbotGuildMgr->IsRealGuild(guildId))
continue;
AddPlayerBot(guid, master->GetSession()->GetAccountId());
messages.push_back("Add class " + std::string(charname));
@@ -1434,7 +1424,7 @@ std::string const PlayerbotHolder::ListBots(Player* master)
for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
{
Player* member = ObjectAccessor::FindPlayer(itr->guid);
if (member && sRandomPlayerbotMgr.IsRandomBot(member))
if (member && sRandomPlayerbotMgr->IsRandomBot(member))
{
std::string const name = member->GetName();
@@ -1504,12 +1494,12 @@ PlayerbotMgr::PlayerbotMgr(Player* const master) : PlayerbotHolder(), master(mas
PlayerbotMgr::~PlayerbotMgr()
{
if (master)
PlayerbotsMgr::instance().RemovePlayerBotData(master->GetGUID(), false);
sPlayerbotsMgr->RemovePlayerBotData(master->GetGUID(), false);
}
void PlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/)
{
SetNextCheckDelay(sPlayerbotAIConfig.reactDelay);
SetNextCheckDelay(sPlayerbotAIConfig->reactDelay);
CheckTellErrors(elapsed);
}
@@ -1519,10 +1509,10 @@ void PlayerbotMgr::HandleCommand(uint32 type, std::string const text)
if (!master)
return;
if (text.find(sPlayerbotAIConfig.commandSeparator) != std::string::npos)
if (text.find(sPlayerbotAIConfig->commandSeparator) != std::string::npos)
{
std::vector<std::string> commands;
split(commands, text, sPlayerbotAIConfig.commandSeparator.c_str());
split(commands, text, sPlayerbotAIConfig->commandSeparator.c_str());
for (std::vector<std::string>::iterator i = commands.begin(); i != commands.end(); ++i)
{
HandleCommand(type, *i);
@@ -1539,8 +1529,8 @@ void PlayerbotMgr::HandleCommand(uint32 type, std::string const text)
botAI->HandleCommand(type, text, master);
}
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr.GetPlayerBotsBegin();
it != sRandomPlayerbotMgr.GetPlayerBotsEnd(); ++it)
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{
Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@@ -1561,8 +1551,8 @@ void PlayerbotMgr::HandleMasterIncomingPacket(WorldPacket const& packet)
botAI->HandleMasterIncomingPacket(packet);
}
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr.GetPlayerBotsBegin();
it != sRandomPlayerbotMgr.GetPlayerBotsEnd(); ++it)
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{
Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@@ -1597,8 +1587,8 @@ void PlayerbotMgr::HandleMasterOutgoingPacket(WorldPacket const& packet)
botAI->HandleMasterOutgoingPacket(packet);
}
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr.GetPlayerBotsBegin();
it != sRandomPlayerbotMgr.GetPlayerBotsEnd(); ++it)
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{
Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@@ -1615,8 +1605,8 @@ void PlayerbotMgr::SaveToDB()
bot->SaveToDB(false, false);
}
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr.GetPlayerBotsBegin();
it != sRandomPlayerbotMgr.GetPlayerBotsEnd(); ++it)
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{
Player* const bot = it->second;
if (GET_PLAYERBOT_AI(bot) && GET_PLAYERBOT_AI(bot)->GetMaster() == GetMaster())
@@ -1658,12 +1648,12 @@ void PlayerbotMgr::OnPlayerLogin(Player* player)
usedLocale = LOCALE_enUS; // fallback
// set locale priority for bot texts
PlayerbotTextMgr::instance().AddLocalePriority(usedLocale);
sPlayerbotTextMgr->AddLocalePriority(usedLocale);
if (sPlayerbotAIConfig.selfBotLevel > 2)
if (sPlayerbotAIConfig->selfBotLevel > 2)
HandlePlayerbotCommand("self", player);
if (!sPlayerbotAIConfig.botAutologin)
if (!sPlayerbotAIConfig->botAutologin)
return;
uint32 accountId = session->GetAccountId();
@@ -1703,7 +1693,7 @@ void PlayerbotMgr::TellError(std::string const botName, std::string const text)
void PlayerbotMgr::CheckTellErrors(uint32 elapsed)
{
time_t now = time(nullptr);
if ((now - lastErrorTell) < sPlayerbotAIConfig.errorDelay / 1000)
if ((now - lastErrorTell) < sPlayerbotAIConfig->errorDelay / 1000)
return;
lastErrorTell = now;
@@ -1787,7 +1777,7 @@ void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid, bool is_AI)
PlayerbotAI* PlayerbotsMgr::GetPlayerbotAI(Player* player)
{
if (!(sPlayerbotAIConfig.enabled) || !player)
if (!(sPlayerbotAIConfig->enabled) || !player)
{
return nullptr;
}
@@ -1807,7 +1797,7 @@ PlayerbotAI* PlayerbotsMgr::GetPlayerbotAI(Player* player)
PlayerbotMgr* PlayerbotsMgr::GetPlayerbotMgr(Player* player)
{
if (!(sPlayerbotAIConfig.enabled) || !player)
if (!(sPlayerbotAIConfig->enabled) || !player)
{
return nullptr;
}

View File

@@ -6,9 +6,12 @@
#ifndef _PLAYERBOT_PLAYERBOTMGR_H
#define _PLAYERBOT_PLAYERBOTMGR_H
#include "Common.h"
#include "ObjectGuid.h"
#include "Player.h"
#include "PlayerbotAIBase.h"
#include "QueryHolder.h"
#include "QueryResult.h"
class ChatHandler;
class PlayerbotAI;
@@ -98,10 +101,13 @@ private:
class PlayerbotsMgr
{
public:
static PlayerbotsMgr& instance()
PlayerbotsMgr() {}
~PlayerbotsMgr() {}
static PlayerbotsMgr* instance()
{
static PlayerbotsMgr instance;
return instance;
return &instance;
}
void AddPlayerbotData(Player* player, bool isBotAI);
@@ -111,15 +117,6 @@ public:
PlayerbotMgr* GetPlayerbotMgr(Player* player);
private:
PlayerbotsMgr() = default;
~PlayerbotsMgr() = default;
PlayerbotsMgr(const PlayerbotsMgr&) = delete;
PlayerbotsMgr& operator=(const PlayerbotsMgr&) = delete;
PlayerbotsMgr(PlayerbotsMgr&&) = delete;
PlayerbotsMgr& operator=(PlayerbotsMgr&&) = delete;
std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsAIMap;
std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsMgrMap;
};

View File

@@ -15,7 +15,7 @@
#include "Player.h"
#include "PlayerbotAI.h"
#include "PlayerbotMgr.h"
#include "PlayerbotRepository.h"
#include "PlayerbotDbStore.h"
#include "RandomPlayerbotMgr.h"
#include "WorldSession.h"
#include "WorldSessionMgr.h"
@@ -355,7 +355,7 @@ public:
if (!member || !newGroup->IsMember(memberGuid))
continue;
PlayerbotAI* memberBotAI = PlayerbotsMgr::instance().GetPlayerbotAI(member);
PlayerbotAI* memberBotAI = sPlayerbotsMgr->GetPlayerbotAI(member);
if (memberBotAI)
memberBotAI->Reset();
@@ -412,13 +412,13 @@ public:
if (!bot)
return false;
PlayerbotAI* botAI = PlayerbotsMgr::instance().GetPlayerbotAI(bot);
PlayerbotAI* botAI = sPlayerbotsMgr->GetPlayerbotAI(bot);
if (!botAI)
return false;
Group* group = bot->GetGroup();
if (group && !bot->InBattleground() && !bot->InBattlegroundQueue() && botAI->HasActivePlayerMaster())
PlayerbotRepository::instance().Save(botAI);
sPlayerbotDbStore->Save(botAI);
return true;
}
@@ -448,7 +448,7 @@ public:
bool Execute() override
{
sRandomPlayerbotMgr.AddPlayerBot(m_botGuid, m_masterAccountId);
sRandomPlayerbotMgr->AddPlayerBot(m_botGuid, m_masterAccountId);
return true;
}
@@ -483,13 +483,13 @@ public:
if (!bot)
return false;
PlayerbotHolder* holder = &RandomPlayerbotMgr::instance();
PlayerbotHolder* holder = sRandomPlayerbotMgr;
if (m_masterAccountId)
{
WorldSession* masterSession = sWorldSessionMgr->FindSession(m_masterAccountId);
Player* masterPlayer = masterSession ? masterSession->GetPlayer() : nullptr;
if (masterPlayer)
holder = PlayerbotsMgr::instance().GetPlayerbotMgr(masterPlayer);
holder = GET_PLAYERBOT_MGR(masterPlayer);
}
if (!holder)

View File

@@ -47,7 +47,7 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
return PLAYERBOT_SECURITY_DENY_ALL;
}
if (sPlayerbotAIConfig.IsInRandomAccountList(account))
if (sPlayerbotAIConfig->IsInRandomAccountList(account))
{
// (duplicate check in case of faction change)
if (botAI->IsOpposing(from))
@@ -72,7 +72,7 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
return PLAYERBOT_SECURITY_TALK;
}
if (sPlayerbotAIConfig.groupInvitationPermission <= 0)
if (sPlayerbotAIConfig->groupInvitationPermission <= 0)
{
if (reason)
*reason = PLAYERBOT_DENY_NONE;
@@ -80,7 +80,7 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
return PLAYERBOT_SECURITY_TALK;
}
if (sPlayerbotAIConfig.groupInvitationPermission <= 1)
if (sPlayerbotAIConfig->groupInvitationPermission <= 1)
{
int32 levelDiff = int32(bot->GetLevel()) - int32(from->GetLevel());
if (levelDiff > 5)
@@ -98,7 +98,7 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
int32 botGS = static_cast<int32>(botAI->GetEquipGearScore(bot));
int32 fromGS = static_cast<int32>(botAI->GetEquipGearScore(from));
if (sPlayerbotAIConfig.gearscorecheck && botGS && bot->GetLevel() > 15 && botGS > fromGS)
if (sPlayerbotAIConfig->gearscorecheck && botGS && bot->GetLevel() > 15 && botGS > fromGS)
{
uint32 diffPct = uint32(100 * (botGS - fromGS) / botGS);
uint32 reqPct = uint32(12 * sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) / from->GetLevel());
@@ -277,7 +277,7 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
ObjectGuid guid = from->GetGUID();
time_t lastSaid = whispers[guid][text];
if (!lastSaid || (time(nullptr) - lastSaid) >= sPlayerbotAIConfig.repeatDelay / 1000)
if (!lastSaid || (time(nullptr) - lastSaid) >= sPlayerbotAIConfig->repeatDelay / 1000)
{
whispers[guid][text] = time(nullptr);

View File

@@ -2,14 +2,12 @@
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "DatabaseEnv.h"
#include "WorldSessionMgr.h"
#include "Random.h"
// Required due to a poor implementation by AC
#include "QueryResult.h"
#include "PlayerbotTextMgr.h"
#include "Playerbots.h"
#include "WorldSessionMgr.h"
void PlayerbotTextMgr::replaceAll(std::string& str, const std::string& from, const std::string& to)
{
if (from.empty())

View File

@@ -11,6 +11,9 @@
#include "Common.h"
#define BOT_TEXT1(name) sPlayerbotTextMgr->GetBotText(name)
#define BOT_TEXT2(name, replace) sPlayerbotTextMgr->GetBotText(name, replace)
struct BotTextEntry
{
BotTextEntry(std::string name, std::map<uint32, std::string> text, uint32 say_type, uint32 reply_type)
@@ -60,11 +63,18 @@ enum ChatReplyType
class PlayerbotTextMgr
{
public:
static PlayerbotTextMgr& instance()
PlayerbotTextMgr()
{
for (uint8 i = 0; i < MAX_LOCALES; ++i)
{
botTextLocalePriority[i] = 0;
}
};
virtual ~PlayerbotTextMgr(){};
static PlayerbotTextMgr* instance()
{
static PlayerbotTextMgr instance;
return instance;
return &instance;
}
std::string GetBotText(std::string name, std::map<std::string, std::string> placeholders);
@@ -85,24 +95,11 @@ public:
void ResetLocalePriority();
private:
PlayerbotTextMgr()
{
for (uint8 i = 0; i < MAX_LOCALES; ++i)
{
botTextLocalePriority[i] = 0;
}
};
~PlayerbotTextMgr() = default;
PlayerbotTextMgr(const PlayerbotTextMgr&) = delete;
PlayerbotTextMgr& operator=(const PlayerbotTextMgr&) = delete;
PlayerbotTextMgr(PlayerbotTextMgr&&) = delete;
PlayerbotTextMgr& operator=(PlayerbotTextMgr&&) = delete;
std::map<std::string, std::vector<BotTextEntry>> botTexts;
std::map<std::string, uint32> botTextChance;
uint32 botTextLocalePriority[MAX_LOCALES];
};
#define sPlayerbotTextMgr PlayerbotTextMgr::instance()
#endif

View File

@@ -3,12 +3,27 @@
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include <algorithm>
#include "PlayerbotWorldThreadProcessor.h"
#include "Timer.h"
#include "Log.h"
#include "PlayerbotAIConfig.h"
#include <algorithm>
PlayerbotWorldThreadProcessor::PlayerbotWorldThreadProcessor()
: m_enabled(true), m_maxQueueSize(10000), m_batchSize(100), m_queueWarningThreshold(80),
m_timeSinceLastUpdate(0), m_updateInterval(50) // Process at least every 50ms
{
LOG_INFO("playerbots", "PlayerbotWorldThreadProcessor initialized");
}
PlayerbotWorldThreadProcessor::~PlayerbotWorldThreadProcessor() { ClearQueue(); }
PlayerbotWorldThreadProcessor* PlayerbotWorldThreadProcessor::instance()
{
static PlayerbotWorldThreadProcessor instance;
return &instance;
}
void PlayerbotWorldThreadProcessor::Update(uint32 diff)
{

View File

@@ -6,14 +6,13 @@
#ifndef _PLAYERBOT_WORLD_THREAD_PROCESSOR_H
#define _PLAYERBOT_WORLD_THREAD_PROCESSOR_H
#include "Common.h"
#include "PlayerbotOperation.h"
#include <memory>
#include <mutex>
#include <queue>
#include "Log.h"
#include "PlayerbotOperation.h"
/**
* @brief Processes thread-unsafe bot operations in the world thread
*
@@ -29,17 +28,15 @@
*
* Usage:
* auto op = std::make_unique<MyOperation>(botGuid, params);
* PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(op));
* sPlayerbotWorldProcessor->QueueOperation(std::move(op));
*/
class PlayerbotWorldThreadProcessor
{
public:
static PlayerbotWorldThreadProcessor& instance()
{
static PlayerbotWorldThreadProcessor instance;
PlayerbotWorldThreadProcessor();
~PlayerbotWorldThreadProcessor();
return instance;
}
static PlayerbotWorldThreadProcessor* instance();
/**
* @brief Update and process queued operations (called from world thread)
@@ -106,21 +103,6 @@ public:
bool IsEnabled() const { return m_enabled; }
private:
PlayerbotWorldThreadProcessor()
: m_enabled(true),
m_maxQueueSize(10000),
m_batchSize(100),
m_queueWarningThreshold(80),
m_timeSinceLastUpdate(0),
m_updateInterval(50) // Process at least every 50ms
{
LOG_INFO("playerbots", "PlayerbotWorldThreadProcessor initialized");
}
~PlayerbotWorldThreadProcessor()
{
this->ClearQueue();
}
/**
* @brief Process a single batch of operations
*
@@ -155,4 +137,6 @@ private:
uint32 m_updateInterval; // Minimum ms between updates
};
#define sPlayerbotWorldProcessor PlayerbotWorldThreadProcessor::instance()
#endif

View File

@@ -22,14 +22,15 @@
#include "DatabaseEnv.h"
#include "DatabaseLoader.h"
#include "GuildTaskMgr.h"
#include "Metric.h"
#include "PlayerScript.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotGuildMgr.h"
#include "PlayerbotSpellRepository.h"
#include "PlayerbotSpellCache.h"
#include "PlayerbotWorldThreadProcessor.h"
#include "RandomPlayerbotMgr.h"
#include "ScriptMgr.h"
#include "PlayerbotCommandScript.h"
#include "cs_playerbots.h"
#include "cmath"
#include "BattleGroundTactics.h"
@@ -97,24 +98,24 @@ public:
{
if (!player->GetSession()->IsBot())
{
PlayerbotsMgr::instance().AddPlayerbotData(player, false);
sRandomPlayerbotMgr.OnPlayerLogin(player);
sPlayerbotsMgr->AddPlayerbotData(player, false);
sRandomPlayerbotMgr->OnPlayerLogin(player);
// Before modifying the following messages, please make sure it does not violate the AGPLv3.0 license
// especially if you are distributing a repack or hosting a public server
// e.g. you can replace the URL with your own repository,
// but it should be publicly accessible and include all modifications you've made
if (sPlayerbotAIConfig.enabled)
if (sPlayerbotAIConfig->enabled)
{
ChatHandler(player->GetSession()).SendSysMessage(
"|cff00ff00This server runs with |cff00ccffmod-playerbots|r "
"|cffcccccchttps://github.com/mod-playerbots/mod-playerbots|r");
}
if (sPlayerbotAIConfig.enabled || sPlayerbotAIConfig.randomBotAutologin)
if (sPlayerbotAIConfig->enabled || sPlayerbotAIConfig->randomBotAutologin)
{
std::string roundedTime =
std::to_string(std::ceil((sPlayerbotAIConfig.maxRandomBots * 0.11 / 60) * 10) / 10.0);
std::to_string(std::ceil((sPlayerbotAIConfig->maxRandomBots * 0.11 / 60) * 10) / 10.0);
roundedTime = roundedTime.substr(0, roundedTime.find('.') + 2);
ChatHandler(player->GetSession()).SendSysMessage(
@@ -124,8 +125,7 @@ public:
}
}
bool OnPlayerBeforeTeleport(Player* /*player*/, uint32 /*mapid*/, float /*x*/, float /*y*/, float /*z*/,
float /*orientation*/, uint32 /*options*/, Unit* /*target*/) override
bool OnPlayerBeforeTeleport(Player* /*player*/, uint32 /*mapid*/, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) override
{
/* for now commmented out until proven its actually required
* havent seen any proof CleanVisibilityReferences() is needed
@@ -172,9 +172,7 @@ public:
void OnPlayerAfterUpdate(Player* player, uint32 diff) override
{
PlayerbotAI* const botAI = PlayerbotsMgr::instance().GetPlayerbotAI(player);
if (botAI != nullptr)
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))
{
botAI->UpdateAI(diff);
}
@@ -187,18 +185,10 @@ public:
bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Player* receiver) override
{
if (type != CHAT_MSG_WHISPER)
if (type == CHAT_MSG_WHISPER)
{
return true;
}
PlayerbotAI* const botAI = PlayerbotsMgr::instance().GetPlayerbotAI(receiver);
if (botAI == nullptr)
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(receiver))
{
return true;
}
botAI->HandleCommand(type, msg, player);
// hotfix; otherwise the server will crash when whispering logout
@@ -206,7 +196,8 @@ public:
// TODO: find the root cause and solve it. (does not happen in party chat)
if (msg == "logout")
return false;
}
}
return true;
}
@@ -214,77 +205,56 @@ public:
{
for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
{
Player* const member = itr->GetSource();
if (member == nullptr)
if (Player* member = itr->GetSource())
{
continue;
}
PlayerbotAI* const botAI = PlayerbotsMgr::instance().GetPlayerbotAI(member);
if (botAI == nullptr)
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(member))
{
continue;
}
botAI->HandleCommand(type, msg, player);
}
}
}
return true;
}
bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Guild* guild) override
{
if (type != CHAT_MSG_GUILD)
if (type == CHAT_MSG_GUILD)
{
return true;
}
PlayerbotMgr* playerbotMgr = PlayerbotsMgr::instance().GetPlayerbotMgr(player);
if (playerbotMgr == nullptr)
if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{
return true;
}
for (PlayerBotMap::const_iterator it = playerbotMgr->GetPlayerBotsBegin(); it != playerbotMgr->GetPlayerBotsEnd(); ++it)
for (PlayerBotMap::const_iterator it = playerbotMgr->GetPlayerBotsBegin();
it != playerbotMgr->GetPlayerBotsEnd(); ++it)
{
Player* const bot = it->second;
if (bot == nullptr)
if (Player* const bot = it->second)
{
continue;
}
if (bot->GetGuildId() != player->GetGuildId())
if (bot->GetGuildId() == player->GetGuildId())
{
continue;
GET_PLAYERBOT_AI(bot)->HandleCommand(type, msg, player);
}
}
}
}
PlayerbotsMgr::instance().GetPlayerbotAI(bot)->HandleCommand(type, msg, player);
}
return true;
}
bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 /*lang*/, std::string& msg, Channel* channel) override
{
PlayerbotMgr* const playerbotMgr = PlayerbotsMgr::instance().GetPlayerbotMgr(player);
if (playerbotMgr != nullptr && channel->GetFlags() & 0x18)
if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{
if (channel->GetFlags() & 0x18)
{
playerbotMgr->HandleCommand(type, msg);
}
}
sRandomPlayerbotMgr.HandleCommand(type, msg, player);
sRandomPlayerbotMgr->HandleCommand(type, msg, player);
return true;
}
bool OnPlayerBeforeAchievementComplete(Player* player, AchievementEntry const* achievement) override
{
if ((sRandomPlayerbotMgr.IsRandomBot(player) || sRandomPlayerbotMgr.IsAddclassBot(player)) &&
if ((sRandomPlayerbotMgr->IsRandomBot(player) || sRandomPlayerbotMgr->IsAddclassBot(player)) &&
(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)))
{
return false;
@@ -296,11 +266,11 @@ public:
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* /*victim*/, uint8 /*xpSource*/) override
{
// early return
if (sPlayerbotAIConfig.randomBotXPRate == 1.0 || !player)
if (sPlayerbotAIConfig->randomBotXPRate == 1.0 || !player)
return;
// no XP multiplier, when player is no bot.
if (!player->GetSession()->IsBot() || !sRandomPlayerbotMgr.IsRandomBot(player))
if (!player->GetSession()->IsBot() || !sRandomPlayerbotMgr->IsRandomBot(player))
return;
// no XP multiplier, when bot is in a group with a real player.
@@ -322,7 +292,7 @@ public:
}
// otherwise apply bot XP multiplier.
amount = static_cast<uint32>(std::round(static_cast<float>(amount) * sPlayerbotAIConfig.randomBotXPRate));
amount = static_cast<uint32>(std::round(static_cast<float>(amount) * sPlayerbotAIConfig->randomBotXPRate));
}
};
@@ -333,9 +303,7 @@ public:
void OnDestructPlayer(Player* player) override
{
PlayerbotAI* botAI = PlayerbotsMgr::instance().GetPlayerbotAI(player);
if (botAI != nullptr)
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))
{
delete botAI;
}
@@ -392,20 +360,20 @@ public:
LOG_INFO("server.loading", " ");
LOG_INFO("server.loading", "Load Playerbots Config...");
sPlayerbotAIConfig.Initialize();
sPlayerbotAIConfig->Initialize();
LOG_INFO("server.loading", ">> Loaded playerbots config in {} ms", GetMSTimeDiffToNow(oldMSTime));
LOG_INFO("server.loading", " ");
PlayerbotSpellRepository::Instance().Initialize();
sPlayerbotSpellCache->Initialize();
LOG_INFO("server.loading", "Playerbots World Thread Processor initialized");
}
void OnUpdate(uint32 diff) override
{
PlayerbotWorldThreadProcessor::instance().Update(diff);
sRandomPlayerbotMgr.UpdateAI(diff); // World thread only
sPlayerbotWorldProcessor->Update(diff);
sRandomPlayerbotMgr->UpdateAI(diff); // World thread only
}
};
@@ -417,12 +385,10 @@ public:
bool OnPlayerbotCheckLFGQueue(lfg::Lfg5Guids const& guidsList) override
{
bool nonBotFound = false;
for (ObjectGuid const& guid : guidsList.guids)
{
Player* player = ObjectAccessor::FindPlayer(guid);
if (guid.IsGroup() || (player && !PlayerbotsMgr::instance().GetPlayerbotAI(player)))
if (guid.IsGroup() || (player && !GET_PLAYERBOT_AI(player)))
{
nonBotFound = true;
break;
@@ -435,48 +401,32 @@ public:
void OnPlayerbotCheckKillTask(Player* player, Unit* victim) override
{
if (player)
GuildTaskMgr::instance().CheckKillTask(player, victim);
sGuildTaskMgr->CheckKillTask(player, victim);
}
void OnPlayerbotCheckPetitionAccount(Player* player, bool& found) override
{
if (!found)
{
return;
}
if (PlayerbotsMgr::instance().GetPlayerbotAI(player) != nullptr)
{
if (found && GET_PLAYERBOT_AI(player))
found = false;
}
}
bool OnPlayerbotCheckUpdatesToSend(Player* player) override
{
PlayerbotAI* botAI = PlayerbotsMgr::instance().GetPlayerbotAI(player);
if (botAI == nullptr)
{
return true;
}
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))
return botAI->IsRealPlayer();
return true;
}
void OnPlayerbotPacketSent(Player* player, WorldPacket const* packet) override
{
if (player == nullptr)
{
if (!player)
return;
}
PlayerbotAI* botAI = PlayerbotsMgr::instance().GetPlayerbotAI(player);
if (botAI != nullptr)
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))
{
botAI->HandleBotOutgoingPacket(*packet);
}
if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{
playerbotMgr->HandleMasterOutgoingPacket(*packet);
@@ -485,7 +435,7 @@ public:
void OnPlayerbotUpdate(uint32 diff) override
{
sRandomPlayerbotMgr.UpdateSessions(); // Per-bot updates only
sRandomPlayerbotMgr->UpdateSessions(); // Per-bot updates only
}
void OnPlayerbotUpdateSessions(Player* player) override
@@ -499,21 +449,20 @@ public:
{
if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{
PlayerbotAI* botAI = PlayerbotsMgr::instance().GetPlayerbotAI(player);
if (botAI == nullptr || botAI->IsRealPlayer())
PlayerbotAI* botAI = GET_PLAYERBOT_AI(player);
if (!botAI || botAI->IsRealPlayer())
{
playerbotMgr->LogoutAllBots();
}
}
sRandomPlayerbotMgr.OnPlayerLogout(player);
sRandomPlayerbotMgr->OnPlayerLogout(player);
}
void OnPlayerbotLogoutBots() override
{
LOG_INFO("playerbots", "Logging out all bots...");
sRandomPlayerbotMgr.LogoutAllBots();
sRandomPlayerbotMgr->LogoutAllBots();
}
};
@@ -566,6 +515,6 @@ void AddPlayerbotsScripts()
new PlayerbotsScript();
new PlayerBotsBGScript();
AddPlayerbotsSecureLoginScripts();
AddPlayerbotsCommandscripts();
AddSC_playerbots_commandscript();
PlayerBotsGuildValidationScript();
}

View File

@@ -27,8 +27,8 @@ int strcmpi(char const* s1, char const* s2);
#define CAST_ANGLE_IN_FRONT (2.f * static_cast<float>(M_PI) / 3.f)
#define EMOTE_ANGLE_IN_FRONT (2.f * static_cast<float>(M_PI) / 6.f)
#define GET_PLAYERBOT_AI(object) sPlayerbotsMgr.GetPlayerbotAI(object)
#define GET_PLAYERBOT_MGR(object) sPlayerbotsMgr.GetPlayerbotMgr(object)
#define GET_PLAYERBOT_AI(object) sPlayerbotsMgr->GetPlayerbotAI(object)
#define GET_PLAYERBOT_MGR(object) sPlayerbotsMgr->GetPlayerbotMgr(object)
#define AI_VALUE(type, name) context->GetValue<type>(name)->Get()
#define AI_VALUE2(type, name, param) context->GetValue<type>(name, param)->Get()
@@ -43,10 +43,10 @@ int strcmpi(char const* s1, char const* s2);
#define RESET_AI_VALUE(type, name) context->GetValue<type>(name)->Reset()
#define RESET_AI_VALUE2(type, name, param) context->GetValue<type>(name, param)->Reset()
#define PAI_VALUE(type, name) sPlayerbotsMgr.GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name)->Get()
#define PAI_VALUE(type, name) sPlayerbotsMgr->GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name)->Get()
#define PAI_VALUE2(type, name, param) \
sPlayerbotsMgr.GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name, param)->Get()
#define GAI_VALUE(type, name) sSharedValueContext.getGlobalValue<type>(name)->Get()
#define GAI_VALUE2(type, name, param) sSharedValueContext.getGlobalValue<type>(name, param)->Get()
sPlayerbotsMgr->GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name, param)->Get()
#define GAI_VALUE(type, name) sSharedValueContext->getGlobalValue<type>(name)->Get()
#define GAI_VALUE2(type, name, param) sSharedValueContext->getGlobalValue<type>(name, param)->Get()
#endif

View File

@@ -29,7 +29,6 @@ namespace
return;
PlayerbotAI* ai = GET_PLAYERBOT_AI(target);
if (!ai)
return;
@@ -42,7 +41,11 @@ namespace
}
}
sRandomPlayerbotMgr.LogoutPlayerBot(target->GetGUID());
if (sRandomPlayerbotMgr)
{
sRandomPlayerbotMgr->LogoutPlayerBot(target->GetGUID());
return;
}
}
}

View File

@@ -272,7 +272,7 @@ void RandomItemMgr::BuildRandomItemCache()
}
}
uint32 maxLevel = sPlayerbotAIConfig.randomBotMaxLevel;
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
@@ -2092,7 +2092,7 @@ uint32 RandomItemMgr::GetLiveStatWeight(Player* player, uint32 itemId)
void RandomItemMgr::BuildEquipCache()
{
uint32 maxLevel = sPlayerbotAIConfig.randomBotMaxLevel;
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
@@ -2415,7 +2415,7 @@ void RandomItemMgr::BuildPotionCache()
void RandomItemMgr::BuildFoodCache()
{
uint32 maxLevel = sPlayerbotAIConfig.randomBotMaxLevel;
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
@@ -2548,7 +2548,7 @@ uint32 RandomItemMgr::GetRandomFood(uint32 level, uint32 category)
void RandomItemMgr::BuildTradeCache()
{
uint32 maxLevel = sPlayerbotAIConfig.randomBotMaxLevel;
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);

View File

@@ -12,6 +12,7 @@
#include <vector>
#include "AiFactory.h"
#include "Common.h"
#include "ItemTemplate.h"
class ChatHandler;
@@ -134,11 +135,12 @@ typedef std::map<BotEquipKey, RandomItemList> BotEquipCache;
class RandomItemMgr
{
public:
static RandomItemMgr& instance()
RandomItemMgr();
virtual ~RandomItemMgr();
static RandomItemMgr* instance()
{
static RandomItemMgr instance;
return instance;
return &instance;
}
public:
@@ -189,17 +191,6 @@ private:
bool CheckItemStats(uint8 clazz, uint8 sp, uint8 ap, uint8 tank);
private:
// Implemented in RandomItemMgr.cpp
RandomItemMgr();
// Implemented in RandomItemMgr.cpp
~RandomItemMgr();
RandomItemMgr(const RandomItemMgr&) = delete;
RandomItemMgr& operator=(const RandomItemMgr&) = delete;
RandomItemMgr(RandomItemMgr&&) = delete;
RandomItemMgr& operator=(RandomItemMgr&&) = delete;
std::map<uint32, RandomItemCache> randomItemCache;
std::map<RandomItemType, RandomItemPredicate*> predicates;
BotEquipCache equipCache;

View File

@@ -317,14 +317,14 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount()
{
// Reset account types if features are disabled
// Reset is done here to precede needed accounts calculations
if (sPlayerbotAIConfig.maxRandomBots == 0 || sPlayerbotAIConfig.addClassAccountPoolSize == 0)
if (sPlayerbotAIConfig->maxRandomBots == 0 || sPlayerbotAIConfig->addClassAccountPoolSize == 0)
{
if (sPlayerbotAIConfig.maxRandomBots == 0)
if (sPlayerbotAIConfig->maxRandomBots == 0)
{
PlayerbotsDatabase.Execute("UPDATE playerbots_account_type SET account_type = 0 WHERE account_type = 1");
LOG_INFO("playerbots", "MaxRandomBots set to 0, any RNDbot accounts (type 1) will be unassigned (type 0)");
}
if (sPlayerbotAIConfig.addClassAccountPoolSize == 0)
if (sPlayerbotAIConfig->addClassAccountPoolSize == 0)
{
PlayerbotsDatabase.Execute("UPDATE playerbots_account_type SET account_type = 0 WHERE account_type = 2");
LOG_INFO("playerbots", "AddClassAccountPoolSize set to 0, any AddClass accounts (type 2) will be unassigned (type 0)");
@@ -334,8 +334,8 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount()
for (int waited = 0; waited < 1000; waited += 50)
{
QueryResult res = PlayerbotsDatabase.Query("SELECT COUNT(*) FROM playerbots_account_type WHERE account_type IN ({}, {})",
sPlayerbotAIConfig.maxRandomBots == 0 ? 1 : -1,
sPlayerbotAIConfig.addClassAccountPoolSize == 0 ? 2 : -1);
sPlayerbotAIConfig->maxRandomBots == 0 ? 1 : -1,
sPlayerbotAIConfig->addClassAccountPoolSize == 0 ? 2 : -1);
if (!res || res->Fetch()[0].Get<uint64>() == 0)
{
@@ -347,8 +347,8 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount()
}
// Checks if randomBotAccountCount is set, otherwise calculate it dynamically.
if (sPlayerbotAIConfig.randomBotAccountCount > 0)
return sPlayerbotAIConfig.randomBotAccountCount;
if (sPlayerbotAIConfig->randomBotAccountCount > 0)
return sPlayerbotAIConfig->randomBotAccountCount;
// Check existing account types
uint32 existingRndBotAccounts = 0;
@@ -374,17 +374,17 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount()
int divisor = CalculateAvailableCharsPerAccount();
// Calculate max bots
int maxBots = sPlayerbotAIConfig.maxRandomBots;
int maxBots = sPlayerbotAIConfig->maxRandomBots;
// Take periodic online - offline into account
if (sPlayerbotAIConfig.enablePeriodicOnlineOffline)
if (sPlayerbotAIConfig->enablePeriodicOnlineOffline)
{
maxBots *= sPlayerbotAIConfig.periodicOnlineOfflineRatio;
maxBots *= sPlayerbotAIConfig->periodicOnlineOfflineRatio;
}
// Calculate number of accounts needed for RNDbots
// Result is rounded up for maxBots not cleanly divisible by the divisor
uint32 neededRndBotAccounts = (maxBots + divisor - 1) / divisor;
uint32 neededAddClassAccounts = sPlayerbotAIConfig.addClassAccountPoolSize;
uint32 neededAddClassAccounts = sPlayerbotAIConfig->addClassAccountPoolSize;
// Start with existing total
uint32 existingTotal = existingRndBotAccounts + existingAddClassAccounts + existingUnassignedAccounts;
@@ -425,12 +425,12 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount()
uint32 RandomPlayerbotFactory::CalculateAvailableCharsPerAccount()
{
bool noDK = sPlayerbotAIConfig.disableDeathKnightLogin || sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING;
bool noDK = sPlayerbotAIConfig->disableDeathKnightLogin || sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING;
uint32 availableChars = noDK ? 9 : 10;
uint32 hordeRatio = sPlayerbotAIConfig.randomBotHordeRatio;
uint32 allianceRatio = sPlayerbotAIConfig.randomBotAllianceRatio;
uint32 hordeRatio = sPlayerbotAIConfig->randomBotHordeRatio;
uint32 allianceRatio = sPlayerbotAIConfig->randomBotAllianceRatio;
// horde : alliance = 50 : 50 -> 0%
// horde : alliance = 0 : 50 -> 50%
@@ -451,7 +451,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
{
/* multi-thread here is meaningless? since the async db operations */
if (sPlayerbotAIConfig.deleteRandomBotAccounts)
if (sPlayerbotAIConfig->deleteRandomBotAccounts)
{
std::vector<uint32> botAccounts;
std::vector<uint32> botFriends;
@@ -462,7 +462,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
for (uint32 accountNumber = 0; accountNumber < totalAccountCount; ++accountNumber)
{
std::ostringstream out;
out << sPlayerbotAIConfig.randomBotAccountPrefix << accountNumber;
out << sPlayerbotAIConfig->randomBotAccountPrefix << accountNumber;
std::string const accountName = out.str();
if (uint32 accountId = AccountMgr::GetId(accountName))
@@ -482,7 +482,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
// Delete all characters from bot accounts
CharacterDatabase.Execute("DELETE FROM characters WHERE account IN (SELECT id FROM " + loginDBName + ".account WHERE username LIKE '{}%%')",
sPlayerbotAIConfig.randomBotAccountPrefix.c_str());
sPlayerbotAIConfig->randomBotAccountPrefix.c_str());
// Wait for the characters to be deleted before proceeding to dependent deletes
while (CharacterDatabase.QueueSize())
@@ -496,7 +496,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
// Clean up orphaned entries in playerbots_db_store
PlayerbotsDatabase.Execute("DELETE FROM playerbots_db_store WHERE guid NOT IN (SELECT guid FROM " + characterDBName + ".characters WHERE account IN (SELECT id FROM " + loginDBName + ".account WHERE username NOT LIKE '{}%%'))",
sPlayerbotAIConfig.randomBotAccountPrefix.c_str());
sPlayerbotAIConfig->randomBotAccountPrefix.c_str());
// Clean up orphaned records in character-related tables
CharacterDatabase.Execute("DELETE FROM arena_team_member WHERE guid NOT IN (SELECT guid FROM characters)");
@@ -551,7 +551,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
// Finally, delete the bot accounts themselves
LOG_INFO("playerbots", "Deleting random bot accounts...");
QueryResult results = LoginDatabase.Query("SELECT id FROM account WHERE username LIKE '{}%%'",
sPlayerbotAIConfig.randomBotAccountPrefix.c_str());
sPlayerbotAIConfig->randomBotAccountPrefix.c_str());
int32 deletion_count = 0;
if (results)
{
@@ -601,7 +601,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
for (uint32 accountNumber = 0; accountNumber < totalAccountCount; ++accountNumber)
{
std::ostringstream out;
out << sPlayerbotAIConfig.randomBotAccountPrefix << accountNumber;
out << sPlayerbotAIConfig->randomBotAccountPrefix << accountNumber;
std::string const accountName = out.str();
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME);
@@ -613,7 +613,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
}
account_creation++;
std::string password = "";
if (sPlayerbotAIConfig.randomBotRandomPassword)
if (sPlayerbotAIConfig->randomBotRandomPassword)
{
for (int i = 0; i < 10; i++)
{
@@ -649,7 +649,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
for (uint32 accountNumber = 0; accountNumber < totalAccountCount; ++accountNumber)
{
std::ostringstream out;
out << sPlayerbotAIConfig.randomBotAccountPrefix << accountNumber;
out << sPlayerbotAIConfig->randomBotAccountPrefix << accountNumber;
std::string const accountName = out.str();
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME);
@@ -661,7 +661,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
Field* fields = result->Fetch();
uint32 accountId = fields[0].Get<uint32>();
sPlayerbotAIConfig.randomBotAccounts.push_back(accountId);
sPlayerbotAIConfig->randomBotAccounts.push_back(accountId);
uint32 count = AccountMgr::GetCharactersCount(accountId);
if (count >= 10)
@@ -746,13 +746,13 @@ void RandomPlayerbotFactory::CreateRandomBots()
for (WorldSession* session : sessionBots)
delete session;
for (uint32 accountId : sPlayerbotAIConfig.randomBotAccounts)
for (uint32 accountId : sPlayerbotAIConfig->randomBotAccounts)
{
totalRandomBotChars += AccountMgr::GetCharactersCount(accountId);
}
LOG_INFO("server.loading", ">> {} random bot accounts with {} characters available",
sPlayerbotAIConfig.randomBotAccounts.size(), totalRandomBotChars);
sPlayerbotAIConfig->randomBotAccounts.size(), totalRandomBotChars);
}
std::string const RandomPlayerbotFactory::CreateRandomGuildName()
@@ -811,7 +811,7 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
if (arenateam)
{
++arenaTeamNumber;
sPlayerbotAIConfig.randomBotArenaTeams.push_back(arenateam->GetId());
sPlayerbotAIConfig->randomBotArenaTeams.push_back(arenateam->GetId());
}
else
{
@@ -872,7 +872,7 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
// set random rating
arenateam->SetRatingForAll(
urand(sPlayerbotAIConfig.randomBotArenaTeamMinRating, sPlayerbotAIConfig.randomBotArenaTeamMaxRating));
urand(sPlayerbotAIConfig->randomBotArenaTeamMinRating, sPlayerbotAIConfig->randomBotArenaTeamMaxRating));
// set random emblem
uint32 backgroundColor = urand(0xFF000000, 0xFFFFFFFF);
@@ -891,7 +891,7 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
arenateam->SaveToDB();
sArenaTeamMgr->AddArenaTeam(arenateam);
sPlayerbotAIConfig.randomBotArenaTeams.push_back(arenateam->GetId());
sPlayerbotAIConfig->randomBotArenaTeams.push_back(arenateam->GetId());
}
LOG_DEBUG("playerbots", "{} random bot {}vs{} arena teams available", arenaTeamNumber, type, type);

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,6 @@
#include "ObjectGuid.h"
#include "PlayerbotMgr.h"
#include "GameTime.h"
#include "PlayerbotCommandServer.h"
struct BattlegroundInfo
{
@@ -44,7 +43,7 @@ struct BattlegroundInfo
};
class ChatHandler;
class PerfMonitorOperation;
class PerformanceMonitorOperation;
class WorldLocation;
struct CachedEvent
@@ -89,11 +88,12 @@ private:
class RandomPlayerbotMgr : public PlayerbotHolder
{
public:
static RandomPlayerbotMgr& instance()
RandomPlayerbotMgr();
virtual ~RandomPlayerbotMgr();
static RandomPlayerbotMgr* instance()
{
static RandomPlayerbotMgr instance;
return instance;
return &instance;
}
void LogPlayerLocation();
@@ -171,7 +171,8 @@ public:
std::map<uint8, std::vector<WorldLocation>> locsPerLevelCache;
std::map<uint8, std::vector<WorldLocation>> allianceStarterPerLevelCache;
std::map<uint8, std::vector<WorldLocation>> hordeStarterPerLevelCache;
std::vector<uint32> allianceFlightMasterCache;
std::vector<uint32> hordeFlightMasterCache;
struct LevelBracket {
uint32 low;
uint32 high;
@@ -192,43 +193,6 @@ protected:
void OnBotLoginInternal(Player* const bot) override;
private:
RandomPlayerbotMgr() : PlayerbotHolder(), processTicks(0)
{
this->playersLevel = sPlayerbotAIConfig.randombotStartingLevel;
if (sPlayerbotAIConfig.enabled || sPlayerbotAIConfig.randomBotAutologin)
{
PlayerbotCommandServer::instance().Start();
}
BattlegroundData.clear(); // Clear here and here only.
// Cleanup on server start: orphaned pet data that's often left behind by bot pets that no longer exist in the DB
CharacterDatabase.Execute("DELETE FROM pet_aura WHERE guid NOT IN (SELECT id FROM character_pet)");
CharacterDatabase.Execute("DELETE FROM pet_spell WHERE guid NOT IN (SELECT id FROM character_pet)");
CharacterDatabase.Execute("DELETE FROM pet_spell_cooldown WHERE guid NOT IN (SELECT id FROM character_pet)");
for (int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket)
{
for (int queueType = BATTLEGROUND_QUEUE_AV; queueType < MAX_BATTLEGROUND_QUEUE_TYPES; ++queueType)
{
this->BattlegroundData[queueType][bracket] = BattlegroundInfo();
}
}
this->BgCheckTimer = 0;
this->LfgCheckTimer = 0;
this->PlayersCheckTimer = 0;
}
~RandomPlayerbotMgr() = default;
RandomPlayerbotMgr(const RandomPlayerbotMgr&) = delete;
RandomPlayerbotMgr& operator=(const RandomPlayerbotMgr&) = delete;
RandomPlayerbotMgr(RandomPlayerbotMgr&&) = delete;
RandomPlayerbotMgr& operator=(RandomPlayerbotMgr&&) = delete;
// pid values are set in constructor
botPID pid = botPID(1, 50, -50, 0, 0, 0);
float activityMod = 0.25;

View File

@@ -1 +0,0 @@
void AddPlayerbotsCommandscripts();

View File

@@ -4,8 +4,8 @@
*/
#include "ServerFacade.h"
#include "Player.h"
#include "Playerbots.h"
#include "TargetedMovementGenerator.h"
float ServerFacade::GetDistance2d(Unit* unit, WorldObject* wo)
@@ -25,13 +25,13 @@ float ServerFacade::GetDistance2d(Unit* unit, float x, float y)
bool ServerFacade::IsDistanceLessThan(float dist1, float dist2)
{
// return dist1 - dist2 < sPlayerbotAIConfig.targetPosRecalcDistance;
// return dist1 - dist2 < sPlayerbotAIConfig->targetPosRecalcDistance;
return dist1 < dist2;
}
bool ServerFacade::IsDistanceGreaterThan(float dist1, float dist2)
{
// return dist1 - dist2 > sPlayerbotAIConfig.targetPosRecalcDistance;
// return dist1 - dist2 > sPlayerbotAIConfig->targetPosRecalcDistance;
return dist1 > dist2;
}
@@ -45,13 +45,11 @@ void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force)
return;
float angle = bot->GetAngle(wo);
// if (!force && bot->isMoving())
// bot->SetFacingTo(bot->GetAngle(wo));
// else
// {
bot->SetOrientation(angle);
if (!bot->IsRooted())
bot->SendMovementFlagUpdate();
// }
@@ -66,14 +64,16 @@ Unit* ServerFacade::GetChaseTarget(Unit* target)
{
return static_cast<ChaseMovementGenerator<Player> const*>(movementGen)->GetTarget();
}
else
{
return static_cast<ChaseMovementGenerator<Creature> const*>(movementGen)->GetTarget();
}
}
return nullptr;
}
void ServerFacade::SendPacket(Player *player, WorldPacket *packet)
{
player->GetSession()->SendPacket(packet);
return player->GetSession()->SendPacket(packet);
}

43
src/ServerFacade.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_SERVERFACADE_H
#define _PLAYERBOT_SERVERFACADE_H
#include "Common.h"
class Player;
class Unit;
class WorldObject;
class WorldPacket;
class ServerFacade
{
public:
ServerFacade(){};
virtual ~ServerFacade(){};
static ServerFacade* instance()
{
static ServerFacade instance;
return &instance;
}
public:
float GetDistance2d(Unit* unit, WorldObject* wo);
float GetDistance2d(Unit* unit, float x, float y);
bool IsDistanceLessThan(float dist1, float dist2);
bool IsDistanceGreaterThan(float dist1, float dist2);
bool IsDistanceGreaterOrEqualThan(float dist1, float dist2);
bool IsDistanceLessOrEqualThan(float dist1, float dist2);
void SetFacingTo(Player* bot, WorldObject* wo, bool force = false);
Unit* GetChaseTarget(Unit* target);
void SendPacket(Player *player, WorldPacket* packet);
};
#define sServerFacade ServerFacade::instance()
#endif

View File

@@ -8,18 +8,17 @@
#include <iomanip>
#include <numeric>
#include "Talentspec.h"
#include "CellImpl.h"
#include "ChatHelper.h"
#include "MMapFactory.h"
#include "MapMgr.h"
#include "PathGenerator.h"
#include "Playerbots.h"
#include "StrategyContext.h"
#include "TransportMgr.h"
#include "VMapFactory.h"
#include "VMapMgr2.h"
#include "Map.h"
#include "Corpse.h"
#include "CellImpl.h"
WorldPosition::WorldPosition(std::string const str)
{
@@ -247,7 +246,7 @@ float WorldPosition::distance(WorldPosition* center)
return relPoint(center).size();
// this -> mapTransfer | mapTransfer -> center
return TravelMgr::instance().mapTransDistance(*this, *center);
return sTravelMgr->mapTransDistance(*this, *center);
};
float WorldPosition::fDist(WorldPosition* center)
@@ -256,7 +255,7 @@ float WorldPosition::fDist(WorldPosition* center)
return sqrt(sqDistance2d(center));
// this -> mapTransfer | mapTransfer -> center
return TravelMgr::instance().fastMapTransDistance(*this, *center);
return sTravelMgr->fastMapTransDistance(*this, *center);
};
float mapTransfer::fDist(WorldPosition start, WorldPosition end)
@@ -429,7 +428,7 @@ void WorldPosition::printWKT(std::vector<WorldPosition> points, std::ostringstre
WorldPosition WorldPosition::getDisplayLocation()
{
WorldPosition pos = TravelNodeMap::instance().getMapOffset(getMapId());
WorldPosition pos = sTravelNodeMap->getMapOffset(getMapId());
return offset(const_cast<WorldPosition*>(&pos));
}
@@ -631,14 +630,14 @@ void WorldPosition::loadMapAndVMap(uint32 mapId, uint8 x, uint8 y)
if (isOverworld() && false || false)
{
if (!MMAP::MMapFactory::createOrGetMMapMgr()->loadMap(mapId, x, y))
if (sPlayerbotAIConfig.hasLog(fileName))
if (sPlayerbotAIConfig->hasLog(fileName))
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << "+00,\"mmap\", " << x << "," << y << "," << (TravelMgr::instance().isBadMmap(mapId, x, y) ? "0" : "1")
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00,\"mmap\", " << x << "," << y << "," << (sTravelMgr->isBadMmap(mapId, x, y) ? "0" : "1")
<< ",";
printWKT(fromGridCoord(GridCoord(x, y)), out, 1, true);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
}
else
@@ -646,7 +645,7 @@ void WorldPosition::loadMapAndVMap(uint32 mapId, uint8 x, uint8 y)
// This needs to be disabled or maps will not load.
// Needs more testing to check for impact on movement.
if (false)
if (!TravelMgr::instance().isBadVmap(mapId, x, y))
if (!sTravelMgr->isBadVmap(mapId, x, y))
{
// load VMAPs for current map/grid...
const MapEntry* i_mapEntry = sMapStore.LookupEntry(mapId);
@@ -663,40 +662,40 @@ void WorldPosition::loadMapAndVMap(uint32 mapId, uint8 x, uint8 y)
case VMAP::VMAP_LOAD_RESULT_ERROR:
// LOG_ERROR("playerbots", "Could not load VMAP name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{},
// y:{})", mapName, mapId, x, y, x, y);
TravelMgr::instance().addBadVmap(mapId, x, y);
sTravelMgr->addBadVmap(mapId, x, y);
break;
case VMAP::VMAP_LOAD_RESULT_IGNORED:
TravelMgr::instance().addBadVmap(mapId, x, y);
sTravelMgr->addBadVmap(mapId, x, y);
// LOG_INFO("playerbots", "Ignored VMAP name:{}, id:{}, x:{}, y:{} (vmap rep.: x:{}, y:{})",
// mapName, mapId, x, y, x, y);
break;
}
if (sPlayerbotAIConfig.hasLog(fileName))
if (sPlayerbotAIConfig->hasLog(fileName))
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << "+00,\"vmap\", " << x << "," << y << ", " << (TravelMgr::instance().isBadVmap(mapId, x, y) ? "0" : "1")
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00,\"vmap\", " << x << "," << y << ", " << (sTravelMgr->isBadVmap(mapId, x, y) ? "0" : "1")
<< ",";
printWKT(frommGridCoord(mGridCoord(x, y)), out, 1, true);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
}
if (!TravelMgr::instance().isBadMmap(mapId, x, y))
if (!sTravelMgr->isBadMmap(mapId, x, y))
{
// load navmesh
if (!MMAP::MMapFactory::createOrGetMMapMgr()->loadMap(mapId, x, y))
TravelMgr::instance().addBadMmap(mapId, x, y);
sTravelMgr->addBadMmap(mapId, x, y);
if (sPlayerbotAIConfig.hasLog(fileName))
if (sPlayerbotAIConfig->hasLog(fileName))
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << "+00,\"mmap\", " << x << "," << y << "," << (TravelMgr::instance().isBadMmap(mapId, x, y) ? "0" : "1")
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00,\"mmap\", " << x << "," << y << "," << (sTravelMgr->isBadMmap(mapId, x, y) ? "0" : "1")
<< ",";
printWKT(fromGridCoord(GridCoord(x, y)), out, 1, true);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
}
}
@@ -734,21 +733,21 @@ std::vector<WorldPosition> WorldPosition::getPathStepFrom(WorldPosition startPos
Movement::PointsArray points = path.GetPath();
PathType type = path.GetPathType();
if (sPlayerbotAIConfig.hasLog("pathfind_attempt_point.csv"))
if (sPlayerbotAIConfig->hasLog("pathfind_attempt_point.csv"))
{
std::ostringstream out;
out << std::fixed << std::setprecision(1);
printWKT({startPos, *this}, out);
sPlayerbotAIConfig.log("pathfind_attempt_point.csv", out.str().c_str());
sPlayerbotAIConfig->log("pathfind_attempt_point.csv", out.str().c_str());
}
if (sPlayerbotAIConfig.hasLog("pathfind_attempt.csv") && (type == PATHFIND_INCOMPLETE || type == PATHFIND_NORMAL))
if (sPlayerbotAIConfig->hasLog("pathfind_attempt.csv") && (type == PATHFIND_INCOMPLETE || type == PATHFIND_NORMAL))
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr() << "+00,";
out << sPlayerbotAIConfig->GetTimestampStr() << "+00,";
out << std::fixed << std::setprecision(1) << type << ",";
printWKT(fromPointsArray(points), out, 1);
sPlayerbotAIConfig.log("pathfind_attempt.csv", out.str().c_str());
sPlayerbotAIConfig->log("pathfind_attempt.csv", out.str().c_str());
}
if (type == PATHFIND_INCOMPLETE || type == PATHFIND_NORMAL)
@@ -797,7 +796,7 @@ std::vector<WorldPosition> WorldPosition::getPathFromPath(std::vector<WorldPosit
subPath = getPathStepFrom(currentPos, bot);
// If we could not find a path return what we have now.
if (subPath.empty() || currentPos.distance(&subPath.back()) < sPlayerbotAIConfig.targetPosRecalcDistance)
if (subPath.empty() || currentPos.distance(&subPath.back()) < sPlayerbotAIConfig->targetPosRecalcDistance)
break;
// Append the path excluding the start (this should be the same as the end of the startPath)
@@ -1072,7 +1071,7 @@ std::vector<WorldPosition*> TravelDestination::sortedPoints(WorldPosition* pos)
std::vector<WorldPosition*> TravelDestination::nextPoint(WorldPosition* pos, bool ignoreFull)
{
return TravelMgr::instance().getNextPoint(pos, ignoreFull ? points : getPoints());
return sTravelMgr->getNextPoint(pos, ignoreFull ? points : getPoints());
}
bool TravelDestination::isFull(bool ignoreFull)
@@ -1109,7 +1108,7 @@ bool QuestRelationTravelDestination::isActive(Player* bot)
if (!bot->GetMap()->GetEntry()->IsWorldMap() || !bot->CanTakeQuest(questTemplate, false))
return false;
//uint32 dialogStatus = TravelMgr::instance().getDialogStatus(bot, entry, questTemplate); //not used, shadowed by the next declaration, line marked for removal.
//uint32 dialogStatus = sTravelMgr->getDialogStatus(bot, entry, questTemplate); //not used, shadowed by the next declaration, line marked for removal.
if (AI_VALUE(bool, "can fight equal"))
{
@@ -1198,7 +1197,7 @@ bool QuestObjectiveTravelDestination::isActive(Player* bot)
if (questTemplate->GetType() == QUEST_TYPE_ELITE && !AI_VALUE(bool, "can fight elite"))
return false;
if (!TravelMgr::instance().getObjectiveStatus(bot, questTemplate, objective))
if (!sTravelMgr->getObjectiveStatus(bot, questTemplate, objective))
return false;
WorldPosition botPos(bot);
@@ -1436,8 +1435,8 @@ TravelTarget::~TravelTarget()
return;
releaseVisitors();
// TravelMgr::instance().botTargets.erase(std::remove(TravelMgr::instance().botTargets.begin(), TravelMgr::instance().botTargets.end(), this),
// TravelMgr::instance().botTargets.end());
// sTravelMgr->botTargets.erase(std::remove(sTravelMgr->botTargets.begin(), sTravelMgr->botTargets.end(), this),
// sTravelMgr->botTargets.end());
}
void TravelTarget::setTarget(TravelDestination* tDestination1, WorldPosition* wPosition1, bool groupCopy1)
@@ -1510,7 +1509,7 @@ void TravelTarget::setStatus(TravelStatus status)
statusTime = 1;
break;
case TRAVEL_STATUS_TRAVEL:
statusTime = getMaxTravelTime() * 2 + sPlayerbotAIConfig.maxWaitForMove;
statusTime = getMaxTravelTime() * 2 + sPlayerbotAIConfig->maxWaitForMove;
break;
case TRAVEL_STATUS_WORK:
statusTime = tDestination->getExpireDelay();
@@ -1579,7 +1578,7 @@ bool TravelTarget::isTraveling()
if (!botAI->HasStrategy("travel", BOT_STATE_NON_COMBAT))
{
setTarget(TravelMgr::instance().nullTravelDestination, TravelMgr::instance().nullWorldPosition, true);
setTarget(sTravelMgr->nullTravelDestination, sTravelMgr->nullWorldPosition, true);
return false;
}
@@ -1611,7 +1610,7 @@ bool TravelTarget::isWorking()
if (!botAI->HasStrategy("travel", BOT_STATE_NON_COMBAT))
{
setTarget(TravelMgr::instance().nullTravelDestination, TravelMgr::instance().nullWorldPosition, true);
setTarget(sTravelMgr->nullTravelDestination, sTravelMgr->nullWorldPosition, true);
return false;
}
@@ -1768,7 +1767,7 @@ void TravelMgr::logQuestError(uint32 errorNr, Quest* quest, uint32 objective, ui
void TravelMgr::LoadQuestTravelTable()
{
if (!TravelMgr::instance().quests.empty())
if (!sTravelMgr->quests.empty())
return;
// Clearing store (for reloading case)
@@ -1961,7 +1960,7 @@ void TravelMgr::LoadQuestTravelTable()
bool loadQuestData = true;
if (loadQuestData)
{
questGuidpMap questMap = SharedValueContext::instance().getGlobalValue<questGuidpMap>("quest guidp map")->Get();
questGuidpMap questMap = GAI_VALUE(questGuidpMap, "quest guidp map");
for (auto& q : questMap)
{
@@ -1983,7 +1982,7 @@ void TravelMgr::LoadQuestTravelTable()
if (flag & (uint32)QuestRelationFlag::questGiver)
{
loc = new QuestRelationTravelDestination(
questId, entry, 0, sPlayerbotAIConfig.tooCloseDistance, sPlayerbotAIConfig.sightDistance);
questId, entry, 0, sPlayerbotAIConfig->tooCloseDistance, sPlayerbotAIConfig->sightDistance);
loc->setExpireDelay(5 * 60 * 1000);
loc->setMaxVisitors(15, 0);
container->questGivers.push_back(loc);
@@ -1992,7 +1991,7 @@ void TravelMgr::LoadQuestTravelTable()
if (flag & (uint32)QuestRelationFlag::questTaker)
{
loc = new QuestRelationTravelDestination(
questId, entry, 1, sPlayerbotAIConfig.tooCloseDistance, sPlayerbotAIConfig.sightDistance);
questId, entry, 1, sPlayerbotAIConfig->tooCloseDistance, sPlayerbotAIConfig->sightDistance);
loc->setExpireDelay(5 * 60 * 1000);
loc->setMaxVisitors(15, 0);
container->questTakers.push_back(loc);
@@ -2011,8 +2010,8 @@ void TravelMgr::LoadQuestTravelTable()
objective = 3;
loc = new QuestObjectiveTravelDestination(questId, entry, objective,
sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance);
sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance);
loc->setExpireDelay(1 * 60 * 1000);
loc->setMaxVisitors(100, 1);
container->questObjectives.push_back(loc);
@@ -2061,8 +2060,8 @@ void TravelMgr::LoadQuestTravelTable()
int32 entry = r.type == 0 ? r.entry : r.entry * -1;
loc = new QuestRelationTravelDestination(r.questId, entry, r.role, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance); loc->setExpireDelay(5 * 60 * 1000); loc->setMaxVisitors(15, 0);
loc = new QuestRelationTravelDestination(r.questId, entry, r.role, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance); loc->setExpireDelay(5 * 60 * 1000); loc->setMaxVisitors(15, 0);
for (auto& u : units)
{
@@ -2099,8 +2098,8 @@ void TravelMgr::LoadQuestTravelTable()
uint32 reqEntry = quest->RequiredNpcOrGo[i];
loc = new QuestObjectiveTravelDestination(questId, reqEntry, i, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance); loc->setExpireDelay(1 * 60 * 1000); loc->setMaxVisitors(100, 1);
loc = new QuestObjectiveTravelDestination(questId, reqEntry, i, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance); loc->setExpireDelay(1 * 60 * 1000); loc->setMaxVisitors(100, 1);
for (auto& u : units)
{
@@ -2150,8 +2149,8 @@ void TravelMgr::LoadQuestTravelTable()
int32 entry = l.type == 0 ? l.entry : l.entry * -1;
loc = new QuestObjectiveTravelDestination(questId, entry, i, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance, l.item); loc->setExpireDelay(1 * 60 * 1000); loc->setMaxVisitors(100, 1);
loc = new QuestObjectiveTravelDestination(questId, entry, i, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance, l.item); loc->setExpireDelay(1 * 60 * 1000); loc->setMaxVisitors(100, 1);
for (auto& u : units)
{
@@ -2239,8 +2238,8 @@ void TravelMgr::LoadQuestTravelTable()
{
if ((cInfo->npcflag & *i) != 0)
{
rLoc = new RpgTravelDestination(u.entry, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance);
rLoc = new RpgTravelDestination(u.entry, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance);
rLoc->setExpireDelay(5 * 60 * 1000);
rLoc->setMaxVisitors(15, 0);
@@ -2252,8 +2251,8 @@ void TravelMgr::LoadQuestTravelTable()
if (cInfo->mingold > 0)
{
gLoc = new GrindTravelDestination(u.entry, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance);
gLoc = new GrindTravelDestination(u.entry, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance);
gLoc->setExpireDelay(5 * 60 * 1000);
gLoc->setMaxVisitors(100, 0);
@@ -2266,8 +2265,8 @@ void TravelMgr::LoadQuestTravelTable()
{
std::string const nodeName = cInfo->Name;
bLoc = new BossTravelDestination(u.entry, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance);
bLoc = new BossTravelDestination(u.entry, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance);
bLoc->setExpireDelay(5 * 60 * 1000);
bLoc->setMaxVisitors(0, 0);
@@ -2299,8 +2298,8 @@ void TravelMgr::LoadQuestTravelTable()
if (iloc == exploreLocs.end())
{
loc = new ExploreTravelDestination(area->ID, sPlayerbotAIConfig.tooCloseDistance,
sPlayerbotAIConfig.sightDistance);
loc = new ExploreTravelDestination(area->ID, sPlayerbotAIConfig->tooCloseDistance,
sPlayerbotAIConfig->sightDistance);
loc->setMaxVisitors(1000, 0);
loc->setCooldownDelay(1000);
loc->setExpireDelay(1000);
@@ -2316,23 +2315,23 @@ void TravelMgr::LoadQuestTravelTable()
}
// Clear these logs files
sPlayerbotAIConfig.openLog("zones.csv", "w");
sPlayerbotAIConfig.openLog("creatures.csv", "w");
sPlayerbotAIConfig.openLog("gos.csv", "w");
sPlayerbotAIConfig.openLog("bot_movement.csv", "w");
sPlayerbotAIConfig.openLog("bot_pathfinding.csv", "w");
sPlayerbotAIConfig.openLog("pathfind_attempt.csv", "w");
sPlayerbotAIConfig.openLog("pathfind_attempt_point.csv", "w");
sPlayerbotAIConfig.openLog("pathfind_result.csv", "w");
sPlayerbotAIConfig.openLog("load_map_grid.csv", "w");
sPlayerbotAIConfig.openLog("strategy.csv", "w");
sPlayerbotAIConfig->openLog("zones.csv", "w");
sPlayerbotAIConfig->openLog("creatures.csv", "w");
sPlayerbotAIConfig->openLog("gos.csv", "w");
sPlayerbotAIConfig->openLog("bot_movement.csv", "w");
sPlayerbotAIConfig->openLog("bot_pathfinding.csv", "w");
sPlayerbotAIConfig->openLog("pathfind_attempt.csv", "w");
sPlayerbotAIConfig->openLog("pathfind_attempt_point.csv", "w");
sPlayerbotAIConfig->openLog("pathfind_result.csv", "w");
sPlayerbotAIConfig->openLog("load_map_grid.csv", "w");
sPlayerbotAIConfig->openLog("strategy.csv", "w");
sPlayerbotAIConfig.openLog("unload_grid.csv", "w");
sPlayerbotAIConfig.openLog("unload_obj.csv", "w");
sPlayerbotAIConfig->openLog("unload_grid.csv", "w");
sPlayerbotAIConfig->openLog("unload_obj.csv", "w");
TravelNodeMap::instance().loadNodeStore();
sTravelNodeMap->loadNodeStore();
TravelNodeMap::instance().generateAll();
sTravelNodeMap->generateAll();
/*
bool fullNavPointReload = false;
@@ -2341,9 +2340,9 @@ void TravelMgr::LoadQuestTravelTable()
if (!fullNavPointReload && true)
TravelNodeStore::loadNodes();
//TravelNodeMap::instance().loadNodeStore();
//sTravelNodeMap->loadNodeStore();
for (auto node : TravelNodeMap::instance().getNodes())
for (auto node : sTravelNodeMap->getNodes())
{
node->setLinked(true);
}
@@ -2385,7 +2384,7 @@ void TravelMgr::LoadQuestTravelTable()
else
nodeName += " flightMaster";
TravelNodeMap::instance().addNode(&pos, nodeName, true, true);
sTravelNodeMap->addNode(&pos, nodeName, true, true);
break;
}
@@ -2415,8 +2414,8 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition startPos(startTaxiNode->map_id, startTaxiNode->x, startTaxiNode->y, startTaxiNode->z);
WorldPosition endPos(endTaxiNode->map_id, endTaxiNode->x, endTaxiNode->y, endTaxiNode->z);
TravelNode* startNode = TravelNodeMap::instance().getNode(&startPos, nullptr, 15.0f);
TravelNode* endNode = TravelNodeMap::instance().getNode(&endPos, nullptr, 15.0f);
TravelNode* startNode = sTravelNodeMap->getNode(&startPos, nullptr, 15.0f);
TravelNode* endNode = sTravelNodeMap->getNode(&endPos, nullptr, 15.0f);
if (!startNode || !endNode)
continue;
@@ -2449,7 +2448,7 @@ void TravelMgr::LoadQuestTravelTable()
if (cInfo->rank == 3 || (cInfo->rank == 1 && !pos.isOverworld() && u.c == 1))
{
std::string const nodeName = cInfo->Name;
TravelNodeMap::instance().addNode(&pos, nodeName, true, true);
sTravelNodeMap->addNode(&pos, nodeName, true, true);
}
}
@@ -2476,7 +2475,7 @@ void TravelMgr::LoadQuestTravelTable()
pos = WorldPosition(info->mapId, info->positionX, info->positionY, info->positionZ, info->orientation);
std::string const nodeName = startNames[i] + " start";
TravelNodeMap::instance().addNode(&pos, nodeName, true, true);
sTravelNodeMap->addNode(&pos, nodeName, true, true);
}
}
@@ -2531,7 +2530,7 @@ void TravelMgr::LoadQuestTravelTable()
if (pos.distance(&lPos) == 0)
{
TravelNode* node = TravelNodeMap::instance().addNode(&pos, data->name, true, true, true,
TravelNode* node = sTravelNodeMap->addNode(&pos, data->name, true, true, true,
iter.first);
if (!prevNode)
@@ -2567,7 +2566,7 @@ void TravelMgr::LoadQuestTravelTable()
if (pos.distance(&lPos) == 0)
{
TravelNode* node = TravelNodeMap::instance().addNode(&pos, data->name, true, true, true,
TravelNode* node = sTravelNodeMap->addNode(&pos, data->name, true, true, true,
iter.first); if (node != prevNode)
{
float totalTime = (p.second->TimeSeg - timeStart) / 1000.0f;
@@ -2606,7 +2605,7 @@ void TravelMgr::LoadQuestTravelTable()
if (p->delay > 0)
{
TravelNode* node = TravelNodeMap::instance().addNode(&pos, data->name, true, true, true, iter.first);
TravelNode* node = sTravelNodeMap->addNode(&pos, data->name, true, true, true, iter.first);
if (!prevNode)
{
@@ -2639,7 +2638,7 @@ void TravelMgr::LoadQuestTravelTable()
if (p->delay > 0)
{
TravelNode* node = TravelNodeMap::instance().getNode(&pos, nullptr, 5.0f);
TravelNode* node = sTravelNodeMap->getNode(&pos, nullptr, 5.0f);
if (node != prevNode)
{
TravelNodePath travelPath(0.1f, 0.0, (uint8) TravelNodePathType::transport, entry,
@@ -2668,13 +2667,13 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition pos = WorldPosition(points, WP_MEAN_CENTROID);
TravelNode* node = TravelNodeMap::instance().addNode(&pos, pos.getAreaName(), true, true, false);
TravelNode* node = sTravelNodeMap->addNode(&pos, pos.getAreaName(), true, true, false);
}
LOG_INFO("playerbots", ">> Loaded {} navigation points.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Loaded {} navigation points.", sTravelNodeMap->getNodes().size());
}
TravelNodeMap::instance().calcMapOffset();
sTravelNodeMap->calcMapOffset();
loadMapTransfers();
*/
@@ -2693,14 +2692,14 @@ void TravelMgr::LoadQuestTravelTable()
//PathGenerator
std::vector<WorldPosition> ppath;
uint32 cur = 0, max = TravelNodeMap::instance().getNodes().size();
uint32 cur = 0, max = sTravelNodeMap->getNodes().size();
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
if (!preloadReLinkFullyLinked && startNode->isLinked())
continue;
for (auto& endNode : TravelNodeMap::instance().getNodes())
for (auto& endNode : sTravelNodeMap->getNodes())
{
if (startNode == endNode)
continue;
@@ -2735,18 +2734,18 @@ void TravelMgr::LoadQuestTravelTable()
if (preloadSubPrint && (cur * 50) / max > ((cur - 1) * 50) / max)
{
TravelNodeMap::instance().printMap();
TravelNodeMap::instance().printNodeStore();
sTravelNodeMap->printMap();
sTravelNodeMap->printNodeStore();
}
}
if (!preloadSubPrint)
{
TravelNodeMap::instance().printNodeStore();
TravelNodeMap::instance().printMap();
sTravelNodeMap->printNodeStore();
sTravelNodeMap->printMap();
}
LOG_INFO("playerbots", ">> Loaded paths for {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Loaded paths for {} nodes.", sTravelNodeMap->getNodes().size());
}
bool removeLowLinkNodes = false || fullNavPointReload || storeNavPointReload;
@@ -2755,7 +2754,7 @@ void TravelMgr::LoadQuestTravelTable()
{
std::vector<TravelNode*> goodNodes;
std::vector<TravelNode*> remNodes;
for (auto& node : TravelNodeMap::instance().getNodes())
for (auto& node : sTravelNodeMap->getNodes())
{
if (!node->getPosition()->isOverworld())
continue;
@@ -2775,9 +2774,9 @@ void TravelMgr::LoadQuestTravelTable()
}
for (auto& node : remNodes)
TravelNodeMap::instance().removeNode(node);
sTravelNodeMap->removeNode(node);
LOG_INFO("playerbots", ">> Checked {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Checked {} nodes.", sTravelNodeMap->getNodes().size());
}
bool cleanUpNodeLinks = false || fullNavPointReload || storeNavPointReload;
@@ -2787,22 +2786,22 @@ void TravelMgr::LoadQuestTravelTable()
{
//Routes
uint32 cur = 0;
uint32 max = TravelNodeMap::instance().getNodes().size();
uint32 max = sTravelNodeMap->getNodes().size();
//Clean up node links
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
startNode->cropUselessLinks();
cur++;
if (cleanUpSubPrint && (cur * 10) / max > ((cur - 1) * 10) / max)
{
TravelNodeMap::instance().printMap();
TravelNodeMap::instance().printNodeStore();
sTravelNodeMap->printMap();
sTravelNodeMap->printNodeStore();
}
}
LOG_INFO("playerbots", ">> Cleaned paths for {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Cleaned paths for {} nodes.", sTravelNodeMap->getNodes().size());
}
bool reCalculateCost = false || fullNavPointReload || storeNavPointReload;
@@ -2810,7 +2809,7 @@ void TravelMgr::LoadQuestTravelTable()
if (reCalculateCost)
{
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
for (auto& path : *startNode->getLinks())
{
@@ -2826,14 +2825,14 @@ void TravelMgr::LoadQuestTravelTable()
}
}
LOG_INFO("playerbots", ">> Calculated pathcost for {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Calculated pathcost for {} nodes.", sTravelNodeMap->getNodes().size());
}
bool mirrorMissingPaths = true || fullNavPointReload || storeNavPointReload;
if (mirrorMissingPaths)
{
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
for (auto& path : *startNode->getLinks())
{
@@ -2856,16 +2855,16 @@ void TravelMgr::LoadQuestTravelTable()
}
}
LOG_INFO("playerbots", ">> Reversed missing paths for {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Reversed missing paths for {} nodes.", sTravelNodeMap->getNodes().size());
}
*/
TravelNodeMap::instance().printMap();
TravelNodeMap::instance().printNodeStore();
TravelNodeMap::instance().saveNodeStore();
sTravelNodeMap->printMap();
sTravelNodeMap->printNodeStore();
sTravelNodeMap->saveNodeStore();
// Creature/gos/zone export.
if (sPlayerbotAIConfig.hasLog("creatures.csv"))
if (sPlayerbotAIConfig->hasLog("creatures.csv"))
{
for (CreatureData const* cData : WorldPosition().getCreaturesNear())
{
@@ -2890,11 +2889,11 @@ void TravelMgr::LoadQuestTravelTable()
out << point.getAreaName() << ",";
out << std::fixed;
sPlayerbotAIConfig.log("creatures.csv", out.str().c_str());
sPlayerbotAIConfig->log("creatures.csv", out.str().c_str());
}
}
if (sPlayerbotAIConfig.hasLog("vmangoslines.csv"))
if (sPlayerbotAIConfig->hasLog("vmangoslines.csv"))
{
uint32 mapId = 0;
std::vector<WorldPosition> pos;
@@ -2925,7 +2924,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const ironforgeAreaSouthLimit[] = {
-7491.33f, 3093.740f, -7472.04f, -391.880f, -6366.68f, -730.100f, -6063.96f, -1411.76f,
@@ -2952,7 +2951,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const stormwindAreaNorthLimit[] = {
-8004.250f, 3714.110f, -8075.000f, -179.000f, -8638.000f, 169.0000f, -9044.000f, 35.00000f,
@@ -2980,7 +2979,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const stormwindAreaSouthLimit[] = {
-8725.3378910f, 3535.62402300f, -9525.6992190f, 910.13256800f, -9796.9531250f, 839.06958000f,
@@ -3011,7 +3010,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
mapId = 1;
@@ -3045,7 +3044,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const durotarSouthLimit[] = {
2755.0f, -3766.f, 2225.0f, -3596.f, 1762.0f, -3746.f, 1564.0f, -3943.f, 1184.0f, -3915.f, 737.00f,
@@ -3073,7 +3072,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const valleyoftrialsSouthLimit[] = {-324.f, -3869.f, -774.f, -3992.f, -965.f, -4290.f, -932.f,
-4349.f, -828.f, -4414.f, -661.f, -4541.f, -521.f, -4582.f};
@@ -3098,7 +3097,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const middleToSouthLimit[] = {
-2402.010000f, 4255.7000000f, -2475.933105f, 3199.5683590f, // Desolace
@@ -3130,7 +3129,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const orgrimmarSouthLimit[] = {
2132.5076f, -3912.2478f, 1944.4298f, -3855.2583f, 1735.6906f, -3834.2417f, 1654.3671f, -3380.9902f,
@@ -3158,7 +3157,7 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
static float const feralasThousandNeedlesSouthLimit[] = {
-6495.4995f, -4711.9810f, -6674.9995f, -4515.0019f, -6769.5717f, -4122.4272f, -6838.2651f, -3874.2792f,
@@ -3188,10 +3187,10 @@ void TravelMgr::LoadQuestTravelTable()
WorldPosition().printWKT(pos, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("vmangoslines.csv", out.str().c_str());
sPlayerbotAIConfig->log("vmangoslines.csv", out.str().c_str());
}
if (sPlayerbotAIConfig.hasLog("gos.csv"))
if (sPlayerbotAIConfig->hasLog("gos.csv"))
{
for (GameObjectData const* gData : WorldPosition().getGameObjectsNear())
{
@@ -3213,11 +3212,11 @@ void TravelMgr::LoadQuestTravelTable()
out << point.getAreaName() << ",";
out << std::fixed;
sPlayerbotAIConfig.log("gos.csv", out.str().c_str());
sPlayerbotAIConfig->log("gos.csv", out.str().c_str());
}
}
if (sPlayerbotAIConfig.hasLog("zones.csv"))
if (sPlayerbotAIConfig->hasLog("zones.csv"))
{
std::unordered_map<std::string, std::vector<WorldPosition>> zoneLocs;
@@ -3239,7 +3238,7 @@ void TravelMgr::LoadQuestTravelTable()
if (loc.second.empty())
continue;
if (!TravelNodeMap::instance().getMapOffset(loc.second.front().getMapId()) && loc.second.front().getMapId() != 0)
if (!sTravelNodeMap->getMapOffset(loc.second.front().getMapId()) && loc.second.front().getMapId() != 0)
continue;
std::vector<WorldPosition> points = loc.second;
@@ -3267,13 +3266,13 @@ void TravelMgr::LoadQuestTravelTable()
point.printWKT(points, out, 0);
sPlayerbotAIConfig.log("zones.csv", out.str().c_str());
sPlayerbotAIConfig->log("zones.csv", out.str().c_str());
}
}
bool printStrategyMap = false;
if (printStrategyMap && sPlayerbotAIConfig.hasLog("strategy.csv"))
if (printStrategyMap && sPlayerbotAIConfig->hasLog("strategy.csv"))
{
static std::map<uint8, std::string> classes;
static std::map<uint8, std::map<uint8, std::string>> specs;
@@ -3329,7 +3328,7 @@ void TravelMgr::LoadQuestTravelTable()
// Use randombot 0.
std::ostringstream cout;
cout << sPlayerbotAIConfig.randomBotAccountPrefix << 0;
cout << sPlayerbotAIConfig->randomBotAccountPrefix << 0;
std::string const accountName = cout.str();
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME);
@@ -3503,7 +3502,7 @@ void TravelMgr::LoadQuestTravelTable()
return false;
});
sPlayerbotAIConfig.log("strategy.csv", "relevance, action, trigger, strategy, classes");
sPlayerbotAIConfig->log("strategy.csv", "relevance, action, trigger, strategy, classes");
for (auto& actionkey : actionKeys)
{
@@ -3608,17 +3607,17 @@ void TravelMgr::LoadQuestTravelTable()
out << actionkey << "\n";
}
sPlayerbotAIConfig.log("strategy.csv", out.str().c_str());
sPlayerbotAIConfig->log("strategy.csv", out.str().c_str());
}
}
/*
sPlayerbotAIConfig.openLog(7, "w");
sPlayerbotAIConfig->openLog(7, "w");
//Zone area map REMOVE!
uint32 k = 0;
for (auto& node : TravelNodeMap::instance().getNodes())
for (auto& node : sTravelNodeMap->getNodes())
{
WorldPosition* pos = node->getPosition();
//map area
@@ -3643,7 +3642,7 @@ void TravelMgr::LoadQuestTravelTable()
std::ostringstream out;
out << std::fixed << area << "," << npos.getDisplayX() << "," << npos.getDisplayY();
sPlayerbotAIConfig.log(7, out.str().c_str());
sPlayerbotAIConfig->log(7, out.str().c_str());
}
}
k++;
@@ -3654,7 +3653,7 @@ void TravelMgr::LoadQuestTravelTable()
//Explore map output (REMOVE!)
sPlayerbotAIConfig.openLog(5, "w");
sPlayerbotAIConfig->openLog(5, "w");
for (auto i : exploreLocs)
{
for (auto j : i.second->getPoints())
@@ -3663,7 +3662,7 @@ void TravelMgr::LoadQuestTravelTable()
std::string const name = i.second->getTitle();
name.erase(remove(name.begin(), name.end(), '\"'), name.end());
out << std::fixed << std::setprecision(2) << name.c_str() << "," << i.first << "," << j->getDisplayX() <<
"," << j->getDisplayY() << "," << j->getX() << "," << j->getY() << "," << j->getZ(); sPlayerbotAIConfig.log(5,
"," << j->getDisplayY() << "," << j->getX() << "," << j->getY() << "," << j->getZ(); sPlayerbotAIConfig->log(5,
out.str().c_str());
}
}
@@ -3898,7 +3897,7 @@ bool TravelMgr::getObjectiveStatus(Player* bot, Quest const* pQuest, uint32 obje
if (bot->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE)
return false;
QuestStatusData* questStatus = TravelMgr::instance().getQuestStatus(bot, questId);
QuestStatusData* questStatus = sTravelMgr->getQuestStatus(bot, questId);
uint32 reqCount = pQuest->RequiredItemCount[objective];
uint32 hasCount = questStatus->ItemCount[objective];
@@ -4098,7 +4097,7 @@ void TravelMgr::setNullTravelTarget(Player* player)
TravelTarget* target = playerBotAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get();
if (target)
target->setTarget(TravelMgr::instance().nullTravelDestination, TravelMgr::instance().nullWorldPosition, true);
target->setTarget(sTravelMgr->nullTravelDestination, sTravelMgr->nullWorldPosition, true);
}
void TravelMgr::addMapTransfer(WorldPosition start, WorldPosition end, float portalDistance, bool makeShortcuts)
@@ -4147,7 +4146,7 @@ void TravelMgr::addMapTransfer(WorldPosition start, WorldPosition end, float por
void TravelMgr::loadMapTransfers()
{
for (auto& node : TravelNodeMap::instance().getNodes())
for (auto& node : sTravelNodeMap->getNodes())
{
for (auto& link : *node->getLinks())
{
@@ -4234,15 +4233,15 @@ void TravelMgr::printGrid(uint32 mapId, int x, int y, std::string const type)
{
std::string const fileName = "unload_grid.csv";
if (sPlayerbotAIConfig.hasLog(fileName))
if (sPlayerbotAIConfig->hasLog(fileName))
{
WorldPosition p = WorldPosition(mapId, 0, 0, 0, 0);
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00, " << 0 << 0 << x << "," << y << ", " << type << ",";
p.printWKT(p.fromGridCoord(GridCoord(x, y)), out, 1, true);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
}
@@ -4250,7 +4249,7 @@ void TravelMgr::printObj(WorldObject* obj, std::string const type)
{
std::string fileName = "unload_grid.csv";
if (sPlayerbotAIConfig.hasLog(fileName))
if (sPlayerbotAIConfig->hasLog(fileName))
{
WorldPosition p = WorldPosition(obj);
@@ -4262,40 +4261,40 @@ void TravelMgr::printObj(WorldObject* obj, std::string const type)
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00, " << obj->GetGUID().GetEntry() << "," << obj->GetGUID().GetCounter() << "," << cell.GridX()
<< "," << cell.GridY() << ", " << type << ",";
p.printWKT(vcell, out, 1, true);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00, " << obj->GetGUID().GetEntry() << "," << obj->GetGUID().GetCounter() << "," << cell.GridX()
<< "," << cell.GridY() << ", " << type << ",";
p.printWKT(vgrid, out, 1, true);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
}
fileName = "unload_obj.csv";
if (sPlayerbotAIConfig.hasLog(fileName))
if (sPlayerbotAIConfig->hasLog(fileName))
{
WorldPosition p = WorldPosition(obj);
Cell cell(obj->GetPositionX(), obj->GetPositionY());
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00, " << obj->GetGUID().GetEntry() << "," << obj->GetGUID().GetCounter() << "," << cell.GridX()
<< "," << cell.GridY() << ", " << type << ",";
p.printWKT({p}, out, 0);
sPlayerbotAIConfig.log(fileName, out.str().c_str());
sPlayerbotAIConfig->log(fileName, out.str().c_str());
}
}
}

View File

@@ -10,6 +10,7 @@
#include <random>
#include "AiObject.h"
#include "Corpse.h"
#include "CreatureData.h"
#include "GameObject.h"
#include "GridDefines.h"
@@ -297,11 +298,11 @@ public:
std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* bot) { return endPos.getPathFrom(*this, bot); }
bool isPathTo(std::vector<WorldPosition> path, float maxDistance = sPlayerbotAIConfig.targetPosRecalcDistance)
bool isPathTo(std::vector<WorldPosition> path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance)
{
return !path.empty() && distance(path.back()) < maxDistance;
};
bool cropPathTo(std::vector<WorldPosition>& path, float maxDistance = sPlayerbotAIConfig.targetPosRecalcDistance);
bool cropPathTo(std::vector<WorldPosition>& path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance);
bool canPathTo(WorldPosition endPos, Unit* bot) { return endPos.isPathTo(getPathTo(endPos, bot)); }
float getPathLength(std::vector<WorldPosition> points)
@@ -847,11 +848,12 @@ protected:
class TravelMgr
{
public:
static TravelMgr& instance()
TravelMgr(){};
static TravelMgr* instance()
{
static TravelMgr instance;
return instance;
return &instance;
}
void Clear();
@@ -920,6 +922,7 @@ public:
void printGrid(uint32 mapId, int x, int y, std::string const type);
void printObj(WorldObject* obj, std::string const type);
// protected:
void logQuestError(uint32 errorNr, Quest* quest, uint32 objective = 0, uint32 unitId = 0, uint32 itemId = 0);
std::vector<uint32> avoidLoaded;
@@ -936,16 +939,8 @@ public:
std::unordered_map<std::pair<uint32, uint32>, std::vector<mapTransfer>, boost::hash<std::pair<uint32, uint32>>>
mapTransfersMap;
private:
TravelMgr() = default;
~TravelMgr() = default;
TravelMgr(const TravelMgr&) = delete;
TravelMgr& operator=(const TravelMgr&) = delete;
TravelMgr(TravelMgr&&) = delete;
TravelMgr& operator=(TravelMgr&&) = delete;
};
#define sTravelMgr TravelMgr::instance()
#endif

View File

@@ -323,7 +323,7 @@ void TravelNode::removeLinkTo(TravelNode* node, bool removePaths)
else
{
// Remove all references to this node.
for (auto& node : TravelNodeMap::instance().getNodes())
for (auto& node : sTravelNodeMap->getNodes())
{
if (node->hasPathTo(this))
node->removeLinkTo(this, removePaths);
@@ -397,7 +397,7 @@ bool TravelNode::isUselessLink(TravelNode* farNode)
}
else
{
TravelNodeRoute route = TravelNodeMap::instance().getRoute(nearNode, farNode, nullptr);
TravelNodeRoute route = sTravelNodeMap->getRoute(nearNode, farNode, nullptr);
if (route.isEmpty())
continue;
@@ -432,7 +432,7 @@ bool TravelNode::cropUselessLinks()
this->removeLinkTo(farNode);
hasRemoved = true;
if (sPlayerbotAIConfig.hasLog("crop.csv"))
if (sPlayerbotAIConfig->hasLog("crop.csv"))
{
std::ostringstream out;
out << getName() << ",";
@@ -440,7 +440,7 @@ bool TravelNode::cropUselessLinks()
WorldPosition().printWKT({*getPosition(), *farNode->getPosition()}, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("crop.csv", out.str().c_str());
sPlayerbotAIConfig->log("crop.csv", out.str().c_str());
}
}
@@ -449,7 +449,7 @@ bool TravelNode::cropUselessLinks()
farNode->removeLinkTo(this);
hasRemoved = true;
if (sPlayerbotAIConfig.hasLog("crop.csv"))
if (sPlayerbotAIConfig->hasLog("crop.csv"))
{
std::ostringstream out;
out << getName() << ",";
@@ -457,7 +457,7 @@ bool TravelNode::cropUselessLinks()
WorldPosition().printWKT({*getPosition(), *farNode->getPosition()}, out, 1);
out << std::fixed;
sPlayerbotAIConfig.log("crop.csv", out.str().c_str());
sPlayerbotAIConfig->log("crop.csv", out.str().c_str());
}
}
}
@@ -496,7 +496,7 @@ bool TravelNode::cropUselessLinks()
}
else
{
TravelNodeRoute route = TravelNodeMap::instance().getRoute(firstNode, secondNode, false);
TravelNodeRoute route = sTravelNodeMap->getRoute(firstNode, secondNode, false);
if (route.isEmpty())
continue;
@@ -544,7 +544,7 @@ bool TravelNode::cropUselessLinks()
}
else
{
TravelNodeRoute route = TravelNodeMap::instance().getRoute(firstNode, secondNode, false);
TravelNodeRoute route = sTravelNodeMap->getRoute(firstNode, secondNode, false);
if (route.isEmpty())
continue;
@@ -579,7 +579,7 @@ bool TravelNode::isEqual(TravelNode* compareNode)
if (!compareNode->hasLinkTo(this))
return false;
for (auto& node : TravelNodeMap::instance().getNodes())
for (auto& node : sTravelNodeMap->getNodes())
{
if (node == this || node == compareNode)
continue;
@@ -611,11 +611,11 @@ void TravelNode::print([[maybe_unused]] bool printFailed)
out << (isImportant() ? 1 : 0) << ",";
out << mapSize;
sPlayerbotAIConfig.log("travelNodes.csv", out.str().c_str());
sPlayerbotAIConfig->log("travelNodes.csv", out.str().c_str());
std::vector<WorldPosition> ppath;
for (auto& endNode : TravelNodeMap::instance().getNodes())
for (auto& endNode : sTravelNodeMap->getNodes())
{
if (endNode == this)
continue;
@@ -665,7 +665,7 @@ void TravelNode::print([[maybe_unused]] bool printFailed)
out << std::to_string(path->getMaxLevelCreature()[1]) << ",";
out << std::to_string(path->getMaxLevelCreature()[2]);
sPlayerbotAIConfig.log("travelPaths.csv", out.str().c_str());
sPlayerbotAIConfig->log("travelPaths.csv", out.str().c_str());
}
}
}
@@ -695,8 +695,8 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
totalDist += p.point.sqDistance(std::prev(&p)->point);
if (curDist <
sPlayerbotAIConfig.tooCloseDistance *
sPlayerbotAIConfig.tooCloseDistance) // We are on the path. This is a good starting point
sPlayerbotAIConfig->tooCloseDistance *
sPlayerbotAIConfig->tooCloseDistance) // We are on the path. This is a good starting point
{
minDist = curDist;
totalDist = curDist;
@@ -731,11 +731,11 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
WorldPosition beginPos = newPath.begin()->point;
// The old path seems to be the best.
if (beginPos.distance(firstNode) < sPlayerbotAIConfig.tooCloseDistance)
if (beginPos.distance(firstNode) < sPlayerbotAIConfig->tooCloseDistance)
return false;
// We are (nearly) on the new path. Just follow the rest.
if (beginPos.distance(startPos) < sPlayerbotAIConfig.tooCloseDistance)
if (beginPos.distance(startPos) < sPlayerbotAIConfig->tooCloseDistance)
{
fullPath = newPath;
return true;
@@ -891,7 +891,7 @@ WorldPosition TravelPath::getNextPoint(WorldPosition startPos, float maxDist, Tr
}
// We have to move far for next point. Try to make a cropped path.
if (moveDist < sPlayerbotAIConfig.targetPosRecalcDistance && std::next(startP) != ed)
if (moveDist < sPlayerbotAIConfig->targetPosRecalcDistance && std::next(startP) != ed)
{
// std::vector<WorldPosition> path = startPos.getPathTo(std::next(startP)->point, nullptr);
// startP->point = startPos.lastInRange(path, -1, maxDist);
@@ -905,7 +905,7 @@ std::ostringstream const TravelPath::print()
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00,"
<< "1,";
out << std::fixed;
@@ -1031,7 +1031,7 @@ std::ostringstream const TravelNodeRoute::print()
{
std::ostringstream out;
out << sPlayerbotAIConfig.GetTimestampStr();
out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00"
<< ",0,"
<< "\"LINESTRING(";
@@ -1046,6 +1046,34 @@ std::ostringstream const TravelNodeRoute::print()
return out;
}
TravelNodeMap::TravelNodeMap(TravelNodeMap* baseMap)
{
TravelNode* newNode;
baseMap->m_nMapMtx.lock_shared();
for (auto& node : baseMap->getNodes())
{
newNode = new TravelNode(node);
m_nodes.push_back(newNode);
}
for (auto& node : baseMap->getNodes())
{
newNode = getNode(node);
for (auto& path : *node->getPaths())
{
TravelNode* endNode = getNode(path.first);
newNode->setPathTo(endNode, path.second);
}
}
baseMap->m_nMapMtx.unlock_shared();
}
TravelNode* TravelNodeMap::addNode(WorldPosition pos, std::string const preferedName, bool isImportant,
bool checkDuplicate, [[maybe_unused]] bool transport,
[[maybe_unused]] uint32 transportId)
@@ -1150,7 +1178,7 @@ TravelNode* TravelNodeMap::getNode(WorldPosition pos, [[maybe_unused]] std::vect
uint32 c = 0;
std::vector<TravelNode*> nodes = TravelNodeMap::instance().getNodes(pos, range);
std::vector<TravelNode*> nodes = sTravelNodeMap->getNodes(pos, range);
for (auto& node : nodes)
{
if (!bot || pos.canPathTo(*node->getPosition(), bot))
@@ -1205,14 +1233,14 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
{
AiObjectContext* context = botAI->GetAiObjectContext();
TravelNode* homeNode = TravelNodeMap::instance().getNode(AI_VALUE(WorldPosition, "home bind"), nullptr, 10.0f);
TravelNode* homeNode = sTravelNodeMap->getNode(AI_VALUE(WorldPosition, "home bind"), nullptr, 10.0f);
if (homeNode)
{
PortalNode* portNode = (PortalNode*)TravelNodeMap::instance().teleportNodes[bot->GetGUID()][8690];
PortalNode* portNode = (PortalNode*)sTravelNodeMap->teleportNodes[bot->GetGUID()][8690];
{
portNode = new PortalNode(start);
TravelNodeMap::instance().teleportNodes[bot->GetGUID()][8690] = portNode;
sTravelNodeMap->teleportNodes[bot->GetGUID()][8690] = portNode;
}
portNode->SetPortal(start, homeNode, 8690);
@@ -1342,7 +1370,7 @@ TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition en
WorldPosition startNodePosition = *startNode->getPosition();
WorldPosition endNodePosition = *endNode->getPosition();
float maxStartDistance = startNode->isTransport() ? 20.0f : sPlayerbotAIConfig.targetPosRecalcDistance;
float maxStartDistance = startNode->isTransport() ? 20.0f : sPlayerbotAIConfig->targetPosRecalcDistance;
TravelNodeRoute route = getRoute(startNode, endNode, bot);
@@ -1375,10 +1403,10 @@ TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition en
if (bot && !bot->HasSpellCooldown(8690))
{
startPath.clear();
TravelNode* botNode = TravelNodeMap::instance().teleportNodes[bot->GetGUID()][0];
TravelNode* botNode = sTravelNodeMap->teleportNodes[bot->GetGUID()][0];
{
botNode = new TravelNode(startPos, "Bot Pos", false);
TravelNodeMap::instance().teleportNodes[bot->GetGUID()][0] = botNode;
sTravelNodeMap->teleportNodes[bot->GetGUID()][0] = botNode;
}
botNode->setPoint(startPos);
@@ -1412,37 +1440,37 @@ TravelPath TravelNodeMap::getFullPath(WorldPosition startPos, WorldPosition endP
//[[Node pathfinding system]]
// We try to find nodes near the bot and near the end position that have a route between them.
// Then bot has to move towards/along the route.
TravelNodeMap::instance().m_nMapMtx.lock_shared();
sTravelNodeMap->m_nMapMtx.lock_shared();
// Find the route of nodes starting at a node closest to the start position and ending at a node closest to the
// endposition. Also returns longPath: The path from the start position to the first node in the route.
TravelNodeRoute route = TravelNodeMap::instance().getRoute(startPos, endPos, beginPath, bot);
TravelNodeRoute route = sTravelNodeMap->getRoute(startPos, endPos, beginPath, bot);
if (route.isEmpty())
return movePath;
if (sPlayerbotAIConfig.hasLog("bot_pathfinding.csv"))
if (sPlayerbotAIConfig->hasLog("bot_pathfinding.csv"))
{
if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
{
sPlayerbotAIConfig.openLog("bot_pathfinding.csv", "w");
sPlayerbotAIConfig.log("bot_pathfinding.csv", route.print().str().c_str());
sPlayerbotAIConfig->openLog("bot_pathfinding.csv", "w");
sPlayerbotAIConfig->log("bot_pathfinding.csv", route.print().str().c_str());
}
}
endPath = route.getNodes().back()->getPosition()->getPathTo(endPos, nullptr);
movePath = route.buildPath(beginPath, endPath);
if (sPlayerbotAIConfig.hasLog("bot_pathfinding.csv"))
if (sPlayerbotAIConfig->hasLog("bot_pathfinding.csv"))
{
if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
{
sPlayerbotAIConfig.openLog("bot_pathfinding.csv", "w");
sPlayerbotAIConfig.log("bot_pathfinding.csv", movePath.print().str().c_str());
sPlayerbotAIConfig->openLog("bot_pathfinding.csv", "w");
sPlayerbotAIConfig->log("bot_pathfinding.csv", movePath.print().str().c_str());
}
}
TravelNodeMap::instance().m_nMapMtx.unlock_shared();
sTravelNodeMap->m_nMapMtx.unlock_shared();
return movePath;
}
@@ -1483,7 +1511,7 @@ TravelNode* TravelNodeMap::addZoneLinkNode(TravelNode* startNode)
if (!getNode(pos, nullptr, 100.0f))
{
std::string const nodeName = zoneName + " to " + newZoneName;
return TravelNodeMap::instance().addNode(pos, nodeName, false, true);
return sTravelNodeMap->addNode(pos, nodeName, false, true);
}
zoneName = newZoneName;
@@ -1522,7 +1550,7 @@ TravelNode* TravelNodeMap::addRandomExtNode(TravelNode* startNode)
WorldPosition point = path[urand(0, path.size() - 1)];
if (!getNode(point, nullptr, 100.0f))
return TravelNodeMap::instance().addNode(point, startNode->getName(), false, true);
return sTravelNodeMap->addNode(point, startNode->getName(), false, true);
}
return nullptr;
@@ -1578,7 +1606,7 @@ void TravelNodeMap::manageNodes(Unit* bot, bool mapFull)
m_nMapMtx.unlock();
}
TravelNodeMap::instance().m_nMapMtx.lock_shared();
sTravelNodeMap->m_nMapMtx.lock_shared();
if (!rePrint && mapFull)
printMap();
@@ -1615,13 +1643,13 @@ void TravelNodeMap::generateNpcNodes()
else if (cInfo->npcflag & UNIT_NPC_FLAG_SPIRITGUIDE)
nodeName += " spiritguide";
/*TravelNode* node = */ TravelNodeMap::instance().addNode(guidP, nodeName, true, true); //node not used, fragment marked for removal.
/*TravelNode* node = */ sTravelNodeMap->addNode(guidP, nodeName, true, true); //node not used, fragment marked for removal.
}
else if (cInfo->rank == 3)
{
std::string const nodeName = cInfo->Name;
TravelNodeMap::instance().addNode(guidP, nodeName, true, true);
sTravelNodeMap->addNode(guidP, nodeName, true, true);
}
else if (cInfo->rank == 1 && !guidP.isOverworld())
{
@@ -1644,7 +1672,7 @@ void TravelNodeMap::generateNpcNodes()
std::string const nodeName = cInfo->Name;
TravelNodeMap::instance().addNode(guidP, nodeName, true, true);
sTravelNodeMap->addNode(guidP, nodeName, true, true);
}
}
@@ -1673,7 +1701,7 @@ void TravelNodeMap::generateStartNodes()
std::string const nodeName = startNames[i] + " start";
TravelNodeMap::instance().addNode(pos, nodeName, true, true);
sTravelNodeMap->addNode(pos, nodeName, true, true);
break;
}
@@ -1705,7 +1733,7 @@ void TravelNodeMap::generateAreaTriggerNodes()
else
nodeName = inPos.getAreaName(false) + " portal";
TravelNodeMap::instance().addNode(inPos, nodeName, true, true);
sTravelNodeMap->addNode(inPos, nodeName, true, true);
}
// Exit nodes
@@ -1731,11 +1759,11 @@ void TravelNodeMap::generateAreaTriggerNodes()
else
nodeName = inPos.getAreaName(false) + " portal";
//TravelNode* entryNode = TravelNodeMap::instance().getNode(outPos, nullptr, 20.0f); // Entry side, portal exit. //not used, line marked for removal.
//TravelNode* entryNode = sTravelNodeMap->getNode(outPos, nullptr, 20.0f); // Entry side, portal exit. //not used, line marked for removal.
TravelNode* outNode = TravelNodeMap::instance().addNode(outPos, nodeName, true, true); // Exit size, portal exit.
TravelNode* outNode = sTravelNodeMap->addNode(outPos, nodeName, true, true); // Exit size, portal exit.
TravelNode* inNode = TravelNodeMap::instance().getNode(inPos, nullptr, 5.0f); // Entry side, portal center.
TravelNode* inNode = sTravelNodeMap->getNode(inPos, nullptr, 5.0f); // Entry side, portal center.
// Portal link from area trigger to area trigger destination.
if (outNode && inNode)
@@ -1798,7 +1826,7 @@ void TravelNodeMap::generateTransportNodes()
if (pos.distance(&lPos) == 0)
{
TravelNode* node =
TravelNodeMap::instance().addNode(pos, data->name, true, true, true, itr.first);
sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first);
if (!prevNode)
{
@@ -1838,7 +1866,7 @@ void TravelNodeMap::generateTransportNodes()
if (pos.distance(&lPos) == 0)
{
TravelNode* node =
TravelNodeMap::instance().addNode(pos, data->name, true, true, true, itr.first);
sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first);
if (node != prevNode)
{
if (p.second->TimeSeg < timeStart)
@@ -1883,7 +1911,7 @@ void TravelNodeMap::generateTransportNodes()
if (p->delay > 0)
{
TravelNode* node = TravelNodeMap::instance().addNode(pos, data->name, true, true, true, itr.first);
TravelNode* node = sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first);
if (!prevNode)
{
@@ -1918,7 +1946,7 @@ void TravelNodeMap::generateTransportNodes()
if (p->delay > 0)
{
TravelNode* node = TravelNodeMap::instance().getNode(pos, nullptr, 5.0f);
TravelNode* node = sTravelNodeMap->getNode(pos, nullptr, 5.0f);
if (node != prevNode)
{
@@ -1940,7 +1968,7 @@ void TravelNodeMap::generateTransportNodes()
void TravelNodeMap::generateZoneMeanNodes()
{
// Zone means
for (auto& loc : TravelMgr::instance().exploreLocs)
for (auto& loc : sTravelMgr->exploreLocs)
{
std::vector<WorldPosition*> points;
@@ -1953,7 +1981,7 @@ void TravelNodeMap::generateZoneMeanNodes()
WorldPosition pos = WorldPosition(points, WP_MEAN_CENTROID);
/*TravelNode* node = */TravelNodeMap::instance().addNode(pos, pos.getAreaName(), true, true, false); //node not used, but addNode as side effect, fragment marked for removal.
/*TravelNode* node = */sTravelNodeMap->addNode(pos, pos.getAreaName(), true, true, false); //node not used, but addNode as side effect, fragment marked for removal.
}
}
@@ -1978,19 +2006,19 @@ void TravelNodeMap::generateWalkPaths()
std::map<uint32, bool> nodeMaps;
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
nodeMaps[startNode->getMapId()] = true;
}
for (auto& map : nodeMaps)
{
for (auto& startNode : TravelNodeMap::instance().getNodes(WorldPosition(map.first, 1, 1)))
for (auto& startNode : sTravelNodeMap->getNodes(WorldPosition(map.first, 1, 1)))
{
if (startNode->isLinked())
continue;
for (auto& endNode : TravelNodeMap::instance().getNodes(*startNode->getPosition(), 2000.0f))
for (auto& endNode : sTravelNodeMap->getNodes(*startNode->getPosition(), 2000.0f))
{
if (startNode == endNode)
continue;
@@ -2008,7 +2036,7 @@ void TravelNodeMap::generateWalkPaths()
}
}
LOG_INFO("playerbots", ">> Generated paths for {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Generated paths for {} nodes.", sTravelNodeMap->getNodes().size());
}
void TravelNodeMap::generateTaxiPaths()
@@ -2038,8 +2066,8 @@ void TravelNodeMap::generateTaxiPaths()
WorldPosition startPos(startTaxiNode->map_id, startTaxiNode->x, startTaxiNode->y, startTaxiNode->z);
WorldPosition endPos(endTaxiNode->map_id, endTaxiNode->x, endTaxiNode->y, endTaxiNode->z);
TravelNode* startNode = TravelNodeMap::instance().getNode(startPos, nullptr, 15.0f);
TravelNode* endNode = TravelNodeMap::instance().getNode(endPos, nullptr, 15.0f);
TravelNode* startNode = sTravelNodeMap->getNode(startPos, nullptr, 15.0f);
TravelNode* endNode = sTravelNodeMap->getNode(endPos, nullptr, 15.0f);
if (!startNode || !endNode)
continue;
@@ -2062,7 +2090,7 @@ void TravelNodeMap::removeLowNodes()
{
std::vector<TravelNode*> goodNodes;
std::vector<TravelNode*> remNodes;
for (auto& node : TravelNodeMap::instance().getNodes())
for (auto& node : sTravelNodeMap->getNodes())
{
if (!node->getPosition()->isOverworld())
continue;
@@ -2082,13 +2110,13 @@ void TravelNodeMap::removeLowNodes()
}
for (auto& node : remNodes)
TravelNodeMap::instance().removeNode(node);
sTravelNodeMap->removeNode(node);
}
void TravelNodeMap::removeUselessPaths()
{
// Clean up node links
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
for (auto& path : *startNode->getPaths())
if (path.second.getComplete() && startNode->hasLinkTo(path.first))
@@ -2099,7 +2127,7 @@ void TravelNodeMap::removeUselessPaths()
{
uint32 rem = 0;
// Clean up node links
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
if (startNode->cropUselessLinks())
rem++;
@@ -2118,7 +2146,7 @@ void TravelNodeMap::removeUselessPaths()
void TravelNodeMap::calculatePathCosts()
{
for (auto& startNode : TravelNodeMap::instance().getNodes())
for (auto& startNode : sTravelNodeMap->getNodes())
{
for (auto& path : *startNode->getLinks())
{
@@ -2134,7 +2162,7 @@ void TravelNodeMap::calculatePathCosts()
}
}
LOG_INFO("playerbots", ">> Calculated pathcost for {} nodes.", TravelNodeMap::instance().getNodes().size());
LOG_INFO("playerbots", ">> Calculated pathcost for {} nodes.", sTravelNodeMap->getNodes().size());
}
void TravelNodeMap::generatePaths()
@@ -2160,7 +2188,7 @@ void TravelNodeMap::generateAll()
calcMapOffset();
LOG_INFO("playerbots", "-Generating maptransfers");
TravelMgr::instance().loadMapTransfers();
sTravelMgr->loadMapTransfers();
if (hasToGen || hasToFullGen)
{
@@ -2173,14 +2201,14 @@ void TravelNodeMap::generateAll()
void TravelNodeMap::printMap()
{
if (!sPlayerbotAIConfig.hasLog("travelNodes.csv") && !sPlayerbotAIConfig.hasLog("travelPaths.csv"))
if (!sPlayerbotAIConfig->hasLog("travelNodes.csv") && !sPlayerbotAIConfig->hasLog("travelPaths.csv"))
return;
printf("\r [Qgis] \r\x3D");
fflush(stdout);
sPlayerbotAIConfig.openLog("travelNodes.csv", "w");
sPlayerbotAIConfig.openLog("travelPaths.csv", "w");
sPlayerbotAIConfig->openLog("travelNodes.csv", "w");
sPlayerbotAIConfig->openLog("travelPaths.csv", "w");
std::vector<TravelNode*> anodes = getNodes();
@@ -2196,26 +2224,26 @@ void TravelNodeMap::printNodeStore()
{
std::string const nodeStore = "TravelNodeStore.h";
if (!sPlayerbotAIConfig.hasLog(nodeStore))
if (!sPlayerbotAIConfig->hasLog(nodeStore))
return;
printf("\r [Map] \r\x3D");
fflush(stdout);
sPlayerbotAIConfig.openLog(nodeStore, "w");
sPlayerbotAIConfig->openLog(nodeStore, "w");
std::unordered_map<TravelNode*, uint32> saveNodes;
std::vector<TravelNode*> anodes = getNodes();
sPlayerbotAIConfig.log(nodeStore, "#pragma once");
sPlayerbotAIConfig.log(nodeStore, "#include \"TravelMgr.h\"");
sPlayerbotAIConfig.log(nodeStore, "class TravelNodeStore");
sPlayerbotAIConfig.log(nodeStore, " {");
sPlayerbotAIConfig.log(nodeStore, " public:");
sPlayerbotAIConfig.log(nodeStore, " static void loadNodes()");
sPlayerbotAIConfig.log(nodeStore, " {");
sPlayerbotAIConfig.log(nodeStore, " TravelNode** nodes = new TravelNode*[%zu];", anodes.size());
sPlayerbotAIConfig->log(nodeStore, "#pragma once");
sPlayerbotAIConfig->log(nodeStore, "#include \"TravelMgr.h\"");
sPlayerbotAIConfig->log(nodeStore, "class TravelNodeStore");
sPlayerbotAIConfig->log(nodeStore, " {");
sPlayerbotAIConfig->log(nodeStore, " public:");
sPlayerbotAIConfig->log(nodeStore, " static void loadNodes()");
sPlayerbotAIConfig->log(nodeStore, " {");
sPlayerbotAIConfig->log(nodeStore, " TravelNode** nodes = new TravelNode*[%zu];", anodes.size());
for (uint32 i = 0; i < anodes.size(); i++)
{
@@ -2238,7 +2266,7 @@ void TravelNodeMap::printNodeStore()
/*
out << std::fixed << std::setprecision(2) << " nodes[" << i << "] =
TravelNodeMap::instance().addNode(&WorldPosition(" << node->getMapId() << "," << node->getX() << "f," << node->getY()
sTravelNodeMap->addNode(&WorldPosition(" << node->getMapId() << "," << node->getX() << "f," << node->getY()
<< "f," << node->getZ() << "f,"<< node->getO() <<"f), \""
<< name << "\", " << (node->isImportant() ? "true" : "false") << ", true";
if (node->isTransport())
@@ -2246,7 +2274,7 @@ void TravelNodeMap::printNodeStore()
out << ");";
*/
sPlayerbotAIConfig.log(nodeStore, out.str().c_str());
sPlayerbotAIConfig->log(nodeStore, out.str().c_str());
saveNodes.insert(std::make_pair(node, i));
}
@@ -2269,12 +2297,12 @@ void TravelNodeMap::printNodeStore()
// out << std::fixed << std::setprecision(1) << " nodes[" << i << "]->setPathTo(nodes[" <<
// saveNodes.find(Link.first)->second << "],TravelNodePath("; out << Link.second->print() << "), true);";
sPlayerbotAIConfig.log(nodeStore, out.str().c_str());
sPlayerbotAIConfig->log(nodeStore, out.str().c_str());
}
}
sPlayerbotAIConfig.log(nodeStore, " }");
sPlayerbotAIConfig.log(nodeStore, "};");
sPlayerbotAIConfig->log(nodeStore, " }");
sPlayerbotAIConfig->log(nodeStore, "};");
printf("\r [Done] \r\x3D");
fflush(stdout);
@@ -2294,7 +2322,7 @@ void TravelNodeMap::saveNodeStore()
trans->Append(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_TRAVELNODE_PATH));
std::unordered_map<TravelNode*, uint32> saveNodes;
std::vector<TravelNode*> anodes = TravelNodeMap::instance().getNodes();
std::vector<TravelNode*> anodes = sTravelNodeMap->getNodes();
for (uint32 i = 0; i < anodes.size(); i++)
{

View File

@@ -477,11 +477,13 @@ public:
class TravelNodeMap
{
public:
static TravelNodeMap& instance()
TravelNodeMap(){};
TravelNodeMap(TravelNodeMap* baseMap);
static TravelNodeMap* instance()
{
static TravelNodeMap instance;
return instance;
return &instance;
}
TravelNode* addNode(WorldPosition pos, std::string const preferedName = "Travel Node", bool isImportant = false,
@@ -584,15 +586,6 @@ public:
std::unordered_map<ObjectGuid, std::unordered_map<uint32, TravelNode*>> teleportNodes;
private:
TravelNodeMap() = default;
~TravelNodeMap() = default;
TravelNodeMap(const TravelNodeMap&) = delete;
TravelNodeMap& operator=(const TravelNodeMap&) = delete;
TravelNodeMap(TravelNodeMap&&) = delete;
TravelNodeMap& operator=(TravelNodeMap&&) = delete;
std::vector<TravelNode*> m_nodes;
std::vector<std::pair<uint32, WorldPosition>> mapOffsets;

View File

@@ -1,114 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "Helpers.h"
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <string>
#include <vector>
/**
* Case-insensitive substring search.
*/
char* strstri(char const* haystack, char const* needle)
{
if (!*needle)
{
return (char*)haystack;
}
for (; *haystack; ++haystack)
{
if (tolower(*haystack) == tolower(*needle))
{
char const* h = haystack;
char const* n = needle;
for (; *h && *n; ++h, ++n)
{
if (tolower(*h) != tolower(*n))
{
break;
}
}
if (!*n)
{
return (char*)haystack;
}
}
}
return 0;
}
/**
* Trim whitespace from the left side of a string (in place).
*/
std::string& ltrim(std::string& s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
return s;
}
/**
* Trim whitespace from the right side of a string (in place).
*/
std::string& rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
return s;
}
/**
* Trim whitespace from both ends of a string (in place).
*/
std::string& trim(std::string& s) { return ltrim(rtrim(s)); }
/**
* Split a string using a C-string delimiter.
*/
void split(std::vector<std::string>& dest, std::string const str, char const* delim)
{
char* pTempStr = strdup(str.c_str());
char* pWord = strtok(pTempStr, delim);
while (pWord != nullptr)
{
dest.push_back(pWord);
pWord = strtok(nullptr, delim);
}
free(pTempStr);
}
/**
* Split a string using a single character delimiter.
*/
std::vector<std::string>& split(std::string const s, char delim, std::vector<std::string>& elems)
{
std::stringstream ss(s);
std::string item;
while (getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
/**
* Split a string using a single character delimiter.
*/
std::vector<std::string> split(std::string const s, char delim)
{
std::vector<std::string> elems;
return split(s, delim, elems);
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_HELPERS_H
#define _PLAYERBOT_HELPERS_H
#include <string>
#include <vector>
/**
* Case-insensitive substring search.
*
* @param haystack The string to search in
* @param needle The substring to search for
* @return Pointer to the first matching position in haystack, or nullptr if not found.
*/
char* strstri(char const* haystack, char const* needle);
/**
* Trim whitespace from the left side of a string (in place).
*
* @param s The string to trim
* @return Reference to the modified string
*/
std::string& ltrim(std::string& s);
/**
* Trim whitespace from the right side of a string (in place).
*
* @param s The string to trim
* @return Reference to the modified string
*/
std::string& rtrim(std::string& s);
/**
* Trim whitespace from both ends of a string (in place).
*
* @param s The string to trim
* @return Reference to the modified string
*/
std::string& trim(std::string& s);
/**
* Split a string using a C-string delimiter.
*
* @param dest Vector to store split tokens
* @param str String to split
* @param delim C-string delimiter
*/
void split(std::vector<std::string>& dest, std::string const str, char const* delim);
/**
* Split a string using a single character delimiter.
*
* @param s String to split
* @param delim Delimiter character
* @param elems Vector to store split tokens
* @return Reference to the vector containing tokens
*/
std::vector<std::string>& split(std::string const s, char delim, std::vector<std::string>& elems);
/**
* Split a string using a single character delimiter.
*
* @param s String to split
* @param delim Delimiter character
* @return Vector containing split tokens
*/
std::vector<std::string> split(std::string const s, char delim);
#endif

View File

@@ -1,74 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_LAZYCALCULATEDVALUE_H
#define _PLAYERBOT_LAZYCALCULATEDVALUE_H
/**
* @brief Lazy calculation helper.
*
* Stores a function pointer (calculator) and its owner instance, and
* calculates the value only when it is requested for the first time.
* The result is cached until Reset() is called.
*
* @tparam TValue Type of the calculated value.
* @tparam TOwner Type of the owner class containing the calculator function.
*/
template <class TValue, class TOwner>
class LazyCalculatedValue
{
public:
/**
* @brief Type of the calculator function.
*
* This is a pointer to a member function of TOwner returning TValue.
*/
typedef TValue (TOwner::*Calculator)();
public:
/**
* @brief Constructor.
*
* @param owner Pointer to the owner object.
* @param calculator Pointer to the member function used to calculate the value.
*/
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) { Reset(); }
public:
/**
* @brief Get the cached value or calculate it if needed.
*
* If the value has not been calculated yet, it calls the calculator
* on the owner and caches the result.
*
* @return TValue The calculated or cached value.
*/
TValue GetValue()
{
if (!calculated)
{
value = (owner->*calculator)();
calculated = true;
}
return value;
}
/**
* @brief Reset the cached state.
*
* After calling Reset(), the next call to GetValue() will recalculate
* the value again.
*/
void Reset() { calculated = false; }
protected:
Calculator calculator; ///< Pointer to calculator member function
TOwner* owner; ///< Owner instance
bool calculated; ///< Whether value has already been calculated
TValue value; ///< Cached value
};
#endif

View File

@@ -1,125 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_SERVERFACADE_H
#define _PLAYERBOT_SERVERFACADE_H
class Player;
class Unit;
class WorldObject;
class WorldPacket;
/**
* @brief Provides a simplified interface to server engine operations.
*
* ServerFacade acts as a wrapper around common server functions used by
* the Playerbot system. It centralizes utility methods for distance
* calculations, facing, chase target retrieval, and packet sending.
*/
class ServerFacade
{
public:
ServerFacade() {}
virtual ~ServerFacade() {}
/**
* @brief Get singleton instance.
*
* @return ServerFacade& Reference to the singleton instance.
*/
static ServerFacade& instance()
{
static ServerFacade instance;
return instance;
}
public:
/**
* @brief Get 2D distance between a unit and a world object.
*
* The result is rounded to one decimal place.
*
* @param unit Source unit.
* @param wo Target world object.
* @return float Distance in yards.
*/
float GetDistance2d(Unit* unit, WorldObject* wo);
/**
* @brief Get 2D distance between a unit and coordinates.
*
* The result is rounded to one decimal place.
*
* @param unit Source unit.
* @param x Target X coordinate.
* @param y Target Y coordinate.
* @return float Distance in yards.
*/
float GetDistance2d(Unit* unit, float x, float y);
/**
* @brief Compare two distances.
*
* @param dist1 First distance.
* @param dist2 Second distance.
* @return true if dist1 < dist2.
*/
bool IsDistanceLessThan(float dist1, float dist2);
/**
* @brief Compare two distances.
*
* @param dist1 First distance.
* @param dist2 Second distance.
* @return true if dist1 > dist2.
*/
bool IsDistanceGreaterThan(float dist1, float dist2);
/**
* @brief Compare two distances.
*
* @param dist1 First distance.
* @param dist2 Second distance.
* @return true if dist1 >= dist2.
*/
bool IsDistanceGreaterOrEqualThan(float dist1, float dist2);
/**
* @brief Compare two distances.
*
* @param dist1 First distance.
* @param dist2 Second distance.
* @return true if dist1 <= dist2.
*/
bool IsDistanceLessOrEqualThan(float dist1, float dist2);
/**
* @brief Set bot facing towards a world object.
*
* @param bot Player bot to rotate.
* @param wo Target world object.
* @param force If true, force facing even while moving.
*/
void SetFacingTo(Player* bot, WorldObject* wo, bool force = false);
/**
* @brief Get the current chase target of a unit.
*
* @param target Unit that is chasing.
* @return Unit* The chase target, or nullptr if not chasing.
*/
Unit* GetChaseTarget(Unit* target);
/**
* @brief Send a raw packet to a player.
*
* @param player Player to receive the packet.
* @param packet Packet to send.
*/
void SendPacket(Player* player, WorldPacket* packet);
};
#endif

View File

@@ -16,7 +16,7 @@
#include "BattleGroundTactics.h"
#include "Chat.h"
#include "GuildTaskMgr.h"
#include "PerfMonitor.h"
#include "PerformanceMonitor.h"
#include "PlayerbotMgr.h"
#include "RandomPlayerbotMgr.h"
#include "ScriptMgr.h"
@@ -76,33 +76,33 @@ public:
{
if (!strcmp(args, "reset"))
{
sPerfMonitor.Reset();
sPerformanceMonitor->Reset();
return true;
}
if (!strcmp(args, "tick"))
{
sPerfMonitor.PrintStats(true, false);
sPerformanceMonitor->PrintStats(true, false);
return true;
}
if (!strcmp(args, "stack"))
{
sPerfMonitor.PrintStats(false, true);
sPerformanceMonitor->PrintStats(false, true);
return true;
}
if (!strcmp(args, "toggle"))
{
sPlayerbotAIConfig.perfMonEnabled = !sPlayerbotAIConfig.perfMonEnabled;
if (sPlayerbotAIConfig.perfMonEnabled)
sPlayerbotAIConfig->perfMonEnabled = !sPlayerbotAIConfig->perfMonEnabled;
if (sPlayerbotAIConfig->perfMonEnabled)
LOG_INFO("playerbots", "Performance monitor enabled");
else
LOG_INFO("playerbots", "Performance monitor disabled");
return true;
}
sPerfMonitor.PrintStats();
sPerformanceMonitor->PrintStats();
return true;
}
@@ -122,7 +122,7 @@ public:
Player* player = handler->GetSession()->GetPlayer();
std::string key = args;
PlayerbotMgr* mgr = PlayerbotsMgr::instance().GetPlayerbotMgr(player);
PlayerbotMgr* mgr = sPlayerbotsMgr->GetPlayerbotMgr(player);
if (mgr)
{
mgr->HandleSetSecurityKeyCommand(player, key);
@@ -151,7 +151,7 @@ public:
Player* player = handler->GetSession()->GetPlayer();
PlayerbotMgr* mgr = PlayerbotsMgr::instance().GetPlayerbotMgr(player);
PlayerbotMgr* mgr = sPlayerbotsMgr->GetPlayerbotMgr(player);
if (mgr)
{
mgr->HandleLinkAccountCommand(player, accountName, key);
@@ -168,7 +168,7 @@ public:
{
Player* player = handler->GetSession()->GetPlayer();
PlayerbotMgr* mgr = PlayerbotsMgr::instance().GetPlayerbotMgr(player);
PlayerbotMgr* mgr = sPlayerbotsMgr->GetPlayerbotMgr(player);
if (mgr)
{
mgr->HandleViewLinkedAccountsCommand(player);
@@ -195,7 +195,7 @@ public:
Player* player = handler->GetSession()->GetPlayer();
PlayerbotMgr* mgr = PlayerbotsMgr::instance().GetPlayerbotMgr(player);
PlayerbotMgr* mgr = sPlayerbotsMgr->GetPlayerbotMgr(player);
if (mgr)
{
mgr->HandleUnlinkAccountCommand(player, accountName);
@@ -209,4 +209,4 @@ public:
}
};
void AddPlayerbotsCommandscripts() { new playerbots_commandscript(); }
void AddSC_playerbots_commandscript() { new playerbots_commandscript(); }

1
src/cs_playerbots.h Normal file
View File

@@ -0,0 +1 @@
void AddSC_playerbots_commandscript();

View File

@@ -1,17 +1,9 @@
#include "Log.h"
#include "DBCStores.h"
#include "DatabaseEnv.h"
#include "Field.h"
// Required due to poor implementation on AC side
#include "QueryResult.h"
#include "PlayerbotSpellCache.h"
#include "PlayerbotSpellRepository.h"
// caches the result set
void PlayerbotSpellRepository::Initialize()
void PlayerbotSpellCache::Initialize()
{
LOG_INFO("playerbots", "Playerbots: ListSpellsAction caches initialized");
LOG_INFO("playerbots",
"Playerbots: ListSpellsAction caches initialized");
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
{
if (SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j))
@@ -39,7 +31,7 @@ void PlayerbotSpellRepository::Initialize()
skillSpells.size(), vendorItems.size());
}
SkillLineAbilityEntry const* PlayerbotSpellRepository::GetSkillLine(uint32 spellId) const
SkillLineAbilityEntry const* PlayerbotSpellCache::GetSkillLine(uint32 spellId) const
{
auto itr = skillSpells.find(spellId);
if (itr != skillSpells.end())
@@ -47,7 +39,7 @@ SkillLineAbilityEntry const* PlayerbotSpellRepository::GetSkillLine(uint32 spell
return nullptr;
}
bool PlayerbotSpellRepository::IsItemBuyable(uint32 itemId) const
bool PlayerbotSpellCache::IsItemBuyable(uint32 itemId) const
{
return vendorItems.find(itemId) != vendorItems.end();
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#ifndef _PLAYERBOT_PLAYERBOTSPELLCACHE_H
#define _PLAYERBOT_PLAYERBOTSPELLCACHE_H
#include "Playerbots.h"
class PlayerbotSpellCache
{
public:
static PlayerbotSpellCache* Instance()
{
static PlayerbotSpellCache instance;
return &instance;
}
void Initialize(); // call once on startup
SkillLineAbilityEntry const* GetSkillLine(uint32 spellId) const;
bool IsItemBuyable(uint32 itemId) const;
private:
PlayerbotSpellCache() = default;
std::map<uint32, SkillLineAbilityEntry const*> skillSpells;
std::set<uint32> vendorItems;
};
#define sPlayerbotSpellCache PlayerbotSpellCache::Instance()
#endif

View File

@@ -24,12 +24,12 @@
#include "LootMgr.h"
#include "MapMgr.h"
#include "ObjectMgr.h"
#include "PerfMonitor.h"
#include "PerformanceMonitor.h"
#include "PetDefines.h"
#include "Player.h"
#include "PlayerbotAI.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotRepository.h"
#include "PlayerbotDbStore.h"
#include "PlayerbotGuildMgr.h"
#include "Playerbots.h"
#include "QuestDef.h"
@@ -68,18 +68,18 @@ PlayerbotFactory::PlayerbotFactory(Player* bot, uint32 level, uint32 itemQuality
botAI = GET_PLAYERBOT_AI(bot);
if (!this->itemQuality)
{
uint32 gs = sPlayerbotAIConfig.randomGearScoreLimit == 0
uint32 gs = sPlayerbotAIConfig->randomGearScoreLimit == 0
? 0
: PlayerbotFactory::CalcMixedGearScore(sPlayerbotAIConfig.randomGearScoreLimit,
sPlayerbotAIConfig.randomGearQualityLimit);
this->itemQuality = sPlayerbotAIConfig.randomGearQualityLimit;
: PlayerbotFactory::CalcMixedGearScore(sPlayerbotAIConfig->randomGearScoreLimit,
sPlayerbotAIConfig->randomGearQualityLimit);
this->itemQuality = sPlayerbotAIConfig->randomGearQualityLimit;
this->gearScoreLimit = gs;
}
}
void PlayerbotFactory::Init()
{
if (sPlayerbotAIConfig.randomBotPreQuests)
if (sPlayerbotAIConfig->randomBotPreQuests)
{
ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates();
for (ObjectMgr::QuestMap::const_iterator i = questTemplates.begin(); i != questTemplates.end(); ++i)
@@ -111,8 +111,8 @@ void PlayerbotFactory::Init()
}
}
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig.randomBotQuestIds.begin();
i != sPlayerbotAIConfig.randomBotQuestIds.end(); ++i)
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig->randomBotQuestIds.begin();
i != sPlayerbotAIConfig->randomBotQuestIds.end(); ++i)
{
uint32 questId = *i;
AddPrevQuests(questId, specialQuestIds);
@@ -190,7 +190,7 @@ void PlayerbotFactory::Init()
continue;
}
if (sRandomItemMgr.IsTestItem(gemId))
if (sRandomItemMgr->IsTestItem(gemId))
{
continue;
}
@@ -218,12 +218,12 @@ void PlayerbotFactory::Prepare()
{
bot->SetUInt32Value(PLAYER_XP, 0);
}
if (!sPlayerbotAIConfig.randomBotShowHelmet || !urand(0, 4))
if (!sPlayerbotAIConfig->randomBotShowHelmet || !urand(0, 4))
{
bot->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM);
}
if (!sPlayerbotAIConfig.randomBotShowCloak || !urand(0, 4))
if (!sPlayerbotAIConfig->randomBotShowCloak || !urand(0, 4))
{
bot->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK);
}
@@ -231,7 +231,7 @@ void PlayerbotFactory::Prepare()
void PlayerbotFactory::Randomize(bool incremental)
{
// if (sPlayerbotAIConfig.disableRandomLevels)
// if (sPlayerbotAIConfig->disableRandomLevels)
// {
// return;
// }
@@ -240,8 +240,8 @@ void PlayerbotFactory::Randomize(bool incremental)
// LOG_DEBUG("playerbots", "Preparing to {} randomize...", (incremental ? "incremental" : "full"));
Prepare();
LOG_DEBUG("playerbots", "Resetting player...");
PerfMonitorOperation* pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Reset");
if (!sPlayerbotAIConfig.equipmentPersistence || level < sPlayerbotAIConfig.equipmentPersistenceLevel)
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reset");
if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel)
{
bot->resetTalents(true);
}
@@ -250,7 +250,7 @@ void PlayerbotFactory::Randomize(bool incremental)
ClearSkills();
ClearSpells();
ResetQuests();
if (!sPlayerbotAIConfig.equipmentPersistence || level < sPlayerbotAIConfig.equipmentPersistenceLevel)
if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel)
{
ClearAllItems();
}
@@ -266,15 +266,15 @@ void PlayerbotFactory::Randomize(bool incremental)
if (pmo)
pmo->finish();
// pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Immersive");
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Immersive");
// LOG_INFO("playerbots", "Initializing immersive...");
// InitImmersive();
// if (pmo)
// pmo->finish();
if (sPlayerbotAIConfig.randomBotPreQuests)
if (sPlayerbotAIConfig->randomBotPreQuests)
{
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Quests");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Quests");
InitInstanceQuests();
InitAttunementQuests();
if (pmo)
@@ -282,157 +282,157 @@ void PlayerbotFactory::Randomize(bool incremental)
}
else
{
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Quests");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Quests");
InitAttunementQuests();
if (pmo)
pmo->finish();
}
LOG_DEBUG("playerbots", "Initializing skills (step 1)...");
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills1");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills1");
bot->LearnDefaultSkills();
InitSkills();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells1");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells1");
LOG_DEBUG("playerbots", "Initializing spells (step 1)...");
InitClassSpells();
InitAvailableSpells();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Talents");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Talents");
LOG_DEBUG("playerbots", "Initializing talents...");
if (!incremental || !sPlayerbotAIConfig.equipmentPersistence ||
bot->GetLevel() < sPlayerbotAIConfig.equipmentPersistenceLevel)
if (!incremental || !sPlayerbotAIConfig->equipmentPersistence ||
bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
{
InitTalentsTree();
}
sRandomPlayerbotMgr.SetValue(bot->GetGUID().GetCounter(), "specNo", 0);
sRandomPlayerbotMgr->SetValue(bot->GetGUID().GetCounter(), "specNo", 0);
if (botAI)
{
PlayerbotRepository::instance().Reset(botAI);
sPlayerbotDbStore->Reset(botAI);
// botAI->DoSpecificAction("auto talents");
botAI->ResetStrategies(false); // fix wrong stored strategy
}
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells2");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells2");
LOG_DEBUG("playerbots", "Initializing spells (step 2)...");
InitAvailableSpells();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Reputation");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reputation");
LOG_DEBUG("playerbots", "Initializing reputation...");
InitReputation();
if (pmo)
pmo->finish();
LOG_DEBUG("playerbots", "Initializing special spells...");
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells3");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Spells3");
InitSpecialSpells();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Mounts");
LOG_DEBUG("playerbots", "Initializing mounts...");
InitMounts();
// bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
// pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills2");
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Skills2");
// LOG_INFO("playerbots", "Initializing skills (step 2)...");
// UpdateTradeSkills();
// if (pmo)
// pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Equip");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Equip");
LOG_DEBUG("playerbots", "Initializing equipmemt...");
if (!incremental || !sPlayerbotAIConfig.equipmentPersistence ||
bot->GetLevel() < sPlayerbotAIConfig.equipmentPersistenceLevel)
if (!incremental || !sPlayerbotAIConfig->equipmentPersistence ||
bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
{
if (sPlayerbotAIConfig.incrementalGearInit || !incremental)
InitEquipment(incremental, incremental ? false : sPlayerbotAIConfig.twoRoundsGearInit);
if (sPlayerbotAIConfig->incrementalGearInit || !incremental)
InitEquipment(incremental, incremental ? false : sPlayerbotAIConfig->twoRoundsGearInit);
}
// bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
// if (bot->GetLevel() >= sPlayerbotAIConfig.minEnchantingBotLevel)
// if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel)
// {
// pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Enchant");
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Enchant");
// LOG_INFO("playerbots", "Initializing enchant templates...");
// LoadEnchantContainer();
// if (pmo)
// pmo->finish();
// }
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Bags");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Bags");
LOG_DEBUG("playerbots", "Initializing bags...");
InitBags();
// bot->SaveToDB(false, false);
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Ammo");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Ammo");
LOG_DEBUG("playerbots", "Initializing ammo...");
InitAmmo();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Food");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Food");
LOG_DEBUG("playerbots", "Initializing food...");
InitFood();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Potions");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Potions");
LOG_DEBUG("playerbots", "Initializing potions...");
InitPotions();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Reagents");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reagents");
LOG_DEBUG("playerbots", "Initializing reagents...");
InitReagents();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Keys");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Keys");
LOG_DEBUG("playerbots", "Initializing keys...");
InitKeyring();
if (pmo)
pmo->finish();
// pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_EqSets");
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_EqSets");
// LOG_DEBUG("playerbots", "Initializing second equipment set...");
// InitSecondEquipmentSet();
// if (pmo)
// pmo->finish();
if (bot->GetLevel() >= sPlayerbotAIConfig.minEnchantingBotLevel)
if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel)
{
ApplyEnchantAndGemsNew();
}
// {
// pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_EnchantTemplate");
// pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_EnchantTemplate");
// LOG_INFO("playerbots", "Initializing enchant templates...");
// ApplyEnchantTemplate();
// if (pmo)
// pmo->finish();
// }
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Inventory");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Inventory");
LOG_DEBUG("playerbots", "Initializing inventory...");
// InitInventory();
if (pmo)
pmo->finish();
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Consumable");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Consumable");
LOG_DEBUG("playerbots", "Initializing consumables...");
InitConsumables();
if (pmo)
@@ -442,9 +442,9 @@ void PlayerbotFactory::Randomize(bool incremental)
InitGlyphs();
// bot->SaveToDB(false, false);
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Guilds");
// bot->SaveToDB(false, false);
if (sPlayerbotAIConfig.randomBotGuildCount > 0)
if (sPlayerbotAIConfig->randomBotGuildCount > 0)
{
LOG_DEBUG("playerbots", "Initializing guilds...");
InitGuild();
@@ -455,7 +455,7 @@ void PlayerbotFactory::Randomize(bool incremental)
if (bot->GetLevel() >= 70)
{
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Arenas");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Arenas");
// LOG_INFO("playerbots", "Initializing arena teams...");
InitArenaTeam();
if (pmo)
@@ -470,7 +470,7 @@ void PlayerbotFactory::Randomize(bool incremental)
}
if (bot->GetLevel() >= 10)
{
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Pet");
LOG_DEBUG("playerbots", "Initializing pet...");
InitPet();
// bot->SaveToDB(false, false);
@@ -479,7 +479,7 @@ void PlayerbotFactory::Randomize(bool incremental)
pmo->finish();
}
pmo = sPerfMonitor.start(PERF_MON_RNDBOT, "PlayerbotFactory_Save");
pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Save");
LOG_DEBUG("playerbots", "Saving to DB...");
bot->SetMoney(urand(level * 100000, level * 5 * 100000));
bot->SetHealth(bot->GetMaxHealth());
@@ -493,7 +493,7 @@ void PlayerbotFactory::Randomize(bool incremental)
void PlayerbotFactory::Refresh()
{
// Prepare();
// if (!sPlayerbotAIConfig.equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig.equipmentPersistenceLevel)
// if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
// {
// InitEquipment(true);
// }
@@ -513,11 +513,11 @@ void PlayerbotFactory::Refresh()
InitSpecialSpells();
InitMounts();
InitKeyring();
if (!sPlayerbotAIConfig.equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig.equipmentPersistenceLevel)
if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel)
{
InitTalentsTree(true, true, true);
}
if (bot->GetLevel() >= sPlayerbotAIConfig.minEnchantingBotLevel)
if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel)
{
ApplyEnchantAndGemsNew();
}
@@ -746,7 +746,7 @@ void PlayerbotFactory::InitConsumables()
void PlayerbotFactory::InitPetTalents()
{
if (bot->GetLevel() <= 70 && sPlayerbotAIConfig.limitTalentsExpansion)
if (bot->GetLevel() <= 70 && sPlayerbotAIConfig->limitTalentsExpansion)
return;
Pet* pet = bot->GetPet();
@@ -794,7 +794,7 @@ void PlayerbotFactory::InitPetTalents()
}
std::vector<std::vector<uint32>> order =
sPlayerbotAIConfig.parsedHunterPetLinkOrder[pet_family->petTalentType][20];
sPlayerbotAIConfig->parsedHunterPetLinkOrder[pet_family->petTalentType][20];
uint32 maxTalentPoints = pet->GetMaxTalentPointsForLevel(pet->GetLevel());
if (order.empty())
@@ -842,16 +842,16 @@ void PlayerbotFactory::InitPetTalents()
uint32 spec = pet_family->petTalentType;
uint32 startPoints = pet->GetMaxTalentPointsForLevel(pet->GetLevel());
while (startPoints > 1 && startPoints < 20 &&
sPlayerbotAIConfig.parsedHunterPetLinkOrder[spec][startPoints].size() == 0)
sPlayerbotAIConfig->parsedHunterPetLinkOrder[spec][startPoints].size() == 0)
{
startPoints--;
}
for (uint32 points = startPoints; points <= 20; points++)
{
if (sPlayerbotAIConfig.parsedHunterPetLinkOrder[spec][points].size() == 0)
if (sPlayerbotAIConfig->parsedHunterPetLinkOrder[spec][points].size() == 0)
continue;
for (std::vector<uint32>& p : sPlayerbotAIConfig.parsedHunterPetLinkOrder[spec][points])
for (std::vector<uint32>& p : sPlayerbotAIConfig->parsedHunterPetLinkOrder[spec][points])
{
uint32 row = p[0], col = p[1], lvl = p[2];
uint32 talentID = 0;
@@ -924,17 +924,17 @@ void PlayerbotFactory::InitPet()
if (itr->second.minlevel > bot->GetLevel())
continue;
bool onlyWolf = sPlayerbotAIConfig.hunterWolfPet == 2 ||
(sPlayerbotAIConfig.hunterWolfPet == 1 &&
bool onlyWolf = sPlayerbotAIConfig->hunterWolfPet == 2 ||
(sPlayerbotAIConfig->hunterWolfPet == 1 &&
bot->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
// Wolf only (for higher dps)
if (onlyWolf && itr->second.family != CREATURE_FAMILY_WOLF)
continue;
// Exclude configured pet families
if (std::find(sPlayerbotAIConfig.excludedHunterPetFamilies.begin(),
sPlayerbotAIConfig.excludedHunterPetFamilies.end(),
itr->second.family) != sPlayerbotAIConfig.excludedHunterPetFamilies.end())
if (std::find(sPlayerbotAIConfig->excludedHunterPetFamilies.begin(),
sPlayerbotAIConfig->excludedHunterPetFamilies.end(),
itr->second.family) != sPlayerbotAIConfig->excludedHunterPetFamilies.end())
continue;
ids.push_back(itr->first);
@@ -1123,8 +1123,8 @@ void PlayerbotFactory::InitTalentsTree(bool increment /*false*/, bool use_templa
bool isCat = !bot->HasAura(16931);
if (!isCat && bot->GetLevel() == 20)
{
uint32 bearP = sPlayerbotAIConfig.randomClassSpecProb[cls][1];
uint32 catP = sPlayerbotAIConfig.randomClassSpecProb[cls][3];
uint32 bearP = sPlayerbotAIConfig->randomClassSpecProb[cls][1];
uint32 catP = sPlayerbotAIConfig->randomClassSpecProb[cls][3];
if (urand(1, bearP + catP) <= catP)
isCat = true;
}
@@ -1139,14 +1139,14 @@ void PlayerbotFactory::InitTalentsTree(bool increment /*false*/, bool use_templa
uint32 pointSum = 0;
for (int i = 0; i < MAX_SPECNO; i++)
{
pointSum += sPlayerbotAIConfig.randomClassSpecProb[cls][i];
pointSum += sPlayerbotAIConfig->randomClassSpecProb[cls][i];
}
uint32 point = urand(1, pointSum);
uint32 currentP = 0;
int i;
for (i = 0; i < MAX_SPECNO; i++)
{
currentP += sPlayerbotAIConfig.randomClassSpecProb[cls][i];
currentP += sPlayerbotAIConfig->randomClassSpecProb[cls][i];
if (point <= currentP)
{
specTab = i;
@@ -1204,17 +1204,17 @@ void PlayerbotFactory::InitTalentsBySpecNo(Player* bot, int specNo, bool reset)
spells_row[talentInfo->Row].push_back(talentInfo);
}
while (startLevel > 1 && startLevel < 80 &&
sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specNo][startLevel].size() == 0)
sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specNo][startLevel].size() == 0)
{
startLevel--;
}
for (int level = startLevel; level <= 80; level++)
{
if (sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specNo][level].size() == 0)
if (sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specNo][level].size() == 0)
{
continue;
}
for (std::vector<uint32>& p : sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specNo][level])
for (std::vector<uint32>& p : sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specNo][level])
{
uint32 tab = p[0], row = p[1], col = p[2], lvl = p[3];
uint32 talentID = -1;
@@ -1341,7 +1341,7 @@ private:
if (keep.find(id) != keep.end())
return false;
if (sPlayerbotAIConfig.IsInRandomQuestItemList(id))
if (sPlayerbotAIConfig->IsInRandomQuestItemList(id))
return true;
return false;
@@ -1603,7 +1603,7 @@ void Shuffle(std::vector<uint32>& items)
// bool noItem = false;
// uint32 quality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC);
// uint32 attempts = 10;
// if (urand(0, 100) < 100 * sPlayerbotAIConfig.randomGearLoweringChance && quality > ITEM_QUALITY_NORMAL)
// if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && quality > ITEM_QUALITY_NORMAL)
// {
// quality--;
// }
@@ -1614,11 +1614,11 @@ void Shuffle(std::vector<uint32>& items)
// uint32 itemInSlot = isUpgrade ? oldItem->GetTemplate()->ItemId : 0;
// uint32 maxLevel = sPlayerbotAIConfig.randomBotMaxLevel;
// uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
// if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
// maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
// uint32 minLevel = sPlayerbotAIConfig.randomBotMinLevel;
// uint32 minLevel = sPlayerbotAIConfig->randomBotMinLevel;
// if (minLevel < sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL))
// minLevel = sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL);
@@ -1627,7 +1627,7 @@ void Shuffle(std::vector<uint32>& items)
// {
// if (isUpgrade)
// {
// std::vector<uint32> ids = sRandomItemMgr.GetUpgradeList(bot, specName, slot, 0, itemInSlot);
// std::vector<uint32> ids = sRandomItemMgr->GetUpgradeList(bot, specName, slot, 0, itemInSlot);
// if (!ids.empty())
// Shuffle(ids);
@@ -1667,7 +1667,7 @@ void Shuffle(std::vector<uint32>& items)
// }
// else
// {
// std::vector<uint32> ids = sRandomItemMgr.GetUpgradeList(bot, specName, slot, quality, itemInSlot);
// std::vector<uint32> ids = sRandomItemMgr->GetUpgradeList(bot, specName, slot, quality, itemInSlot);
// if (!ids.empty())
// Shuffle(ids);
@@ -1706,7 +1706,7 @@ void Shuffle(std::vector<uint32>& items)
void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
{
if (incremental && !sPlayerbotAIConfig.incrementalGearInit)
if (incremental && !sPlayerbotAIConfig->incrementalGearInit)
return;
if (level < 5)
@@ -1786,7 +1786,7 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
int32 desiredQuality = itemQuality;
if (urand(0, 100) < 100 * sPlayerbotAIConfig.randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
{
desiredQuality--;
}
@@ -1797,7 +1797,7 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
{
for (InventoryType inventoryType : GetPossibleInventoryTypeListBySlot((EquipmentSlots)slot))
{
for (uint32 itemId : sRandomItemMgr.GetCachedEquipments(requiredLevel, inventoryType))
for (uint32 itemId : sRandomItemMgr->GetCachedEquipments(requiredLevel, inventoryType))
{
if (itemId == 46978) // shaman earth ring totem
{
@@ -1808,10 +1808,10 @@ void PlayerbotFactory::InitEquipment(bool incremental, bool second_chance)
continue;
// disable next expansion gear
if (sPlayerbotAIConfig.limitGearExpansion && bot->GetLevel() <= 60 && itemId >= 23728)
if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 60 && itemId >= 23728)
continue;
if (sPlayerbotAIConfig.limitGearExpansion && bot->GetLevel() <= 70 && itemId >= 35570 &&
if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 70 && itemId >= 35570 &&
itemId != 36737 && itemId != 37739 &&
itemId != 37740) // transition point from TBC -> WOTLK isn't as clear, and there are other
// wearable TBC items above 35570 but nothing of significance
@@ -2009,7 +2009,7 @@ bool PlayerbotFactory::IsDesiredReplacement(Item* item)
}
// if (!requiredLevel)
// {
// requiredLevel = sRandomItemMgr.GetMinLevelFromCache(proto->ItemId);
// requiredLevel = sRandomItemMgr->GetMinLevelFromCache(proto->ItemId);
// }
uint32 delta = 1 + (80 - bot->GetLevel()) / 10;
@@ -2039,7 +2039,7 @@ inline Item* StoreNewItemInInventorySlot(Player* player, uint32 newItemId, uint3
// std::map<uint32, std::vector<uint32>> items;
// uint32 desiredQuality = itemQuality;
// while (urand(0, 100) < 100 * sPlayerbotAIConfig.randomGearLoweringChance && desiredQuality >
// while (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality >
// ITEM_QUALITY_NORMAL)
// {
// desiredQuality--;
@@ -2061,9 +2061,9 @@ inline Item* StoreNewItemInInventorySlot(Player* player, uint32 newItemId, uint3
// //if (!CanEquipWeapon(proto))
// // continue;
// if (sRandomItemMgr.HasStatWeight(proto->ItemId))
// if (sRandomItemMgr->HasStatWeight(proto->ItemId))
// {
// if (!sRandomItemMgr.GetLiveStatWeight(bot, proto->ItemId))
// if (!sRandomItemMgr->GetLiveStatWeight(bot, proto->ItemId))
// continue;
// }
@@ -2096,9 +2096,9 @@ inline Item* StoreNewItemInInventorySlot(Player* player, uint32 newItemId, uint3
// //if (!CanEquipArmor(proto))
// // continue;
// if (sRandomItemMgr.HasStatWeight(proto->ItemId))
// if (sRandomItemMgr->HasStatWeight(proto->ItemId))
// {
// if (!sRandomItemMgr.GetLiveStatWeight(bot, proto->ItemId))
// if (!sRandomItemMgr->GetLiveStatWeight(bot, proto->ItemId))
// continue;
// }
@@ -2173,10 +2173,10 @@ void PlayerbotFactory::InitBags(bool destroyOld)
void PlayerbotFactory::EnchantItem(Item* item)
{
if (bot->GetLevel() < sPlayerbotAIConfig.minEnchantingBotLevel)
if (bot->GetLevel() < sPlayerbotAIConfig->minEnchantingBotLevel)
return;
if (urand(0, 100) < 100 * sPlayerbotAIConfig.randomGearLoweringChance)
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance)
return;
ItemTemplate const* proto = item->GetTemplate();
@@ -2279,8 +2279,8 @@ bool PlayerbotFactory::CanEquipUnseenItem(uint8 slot, uint16& dest, uint32 item)
void PlayerbotFactory::InitTradeSkills()
{
uint16 firstSkill = sRandomPlayerbotMgr.GetValue(bot, "firstSkill");
uint16 secondSkill = sRandomPlayerbotMgr.GetValue(bot, "secondSkill");
uint16 firstSkill = sRandomPlayerbotMgr->GetValue(bot, "firstSkill");
uint16 secondSkill = sRandomPlayerbotMgr->GetValue(bot, "secondSkill");
if (!firstSkill || !secondSkill)
{
std::vector<uint32> firstSkills;
@@ -2332,8 +2332,8 @@ void PlayerbotFactory::InitTradeSkills()
break;
}
sRandomPlayerbotMgr.SetValue(bot, "firstSkill", firstSkill);
sRandomPlayerbotMgr.SetValue(bot, "secondSkill", secondSkill);
sRandomPlayerbotMgr->SetValue(bot, "firstSkill", firstSkill);
sRandomPlayerbotMgr->SetValue(bot, "secondSkill", secondSkill);
}
SetRandomSkill(SKILL_FIRST_AID);
@@ -2359,13 +2359,13 @@ void PlayerbotFactory::InitSkills()
bot->UpdateSkillsForLevel();
bot->SetSkill(SKILL_RIDING, 0, 0, 0);
if (bot->GetLevel() >= sPlayerbotAIConfig.useGroundMountAtMinLevel)
if (bot->GetLevel() >= sPlayerbotAIConfig->useGroundMountAtMinLevel)
bot->learnSpell(33388);
if (bot->GetLevel() >= sPlayerbotAIConfig.useFastGroundMountAtMinLevel)
if (bot->GetLevel() >= sPlayerbotAIConfig->useFastGroundMountAtMinLevel)
bot->learnSpell(33391);
if (bot->GetLevel() >= sPlayerbotAIConfig.useFlyMountAtMinLevel)
if (bot->GetLevel() >= sPlayerbotAIConfig->useFlyMountAtMinLevel)
bot->learnSpell(34090);
if (bot->GetLevel() >= sPlayerbotAIConfig.useFastFlyMountAtMinLevel)
if (bot->GetLevel() >= sPlayerbotAIConfig->useFastFlyMountAtMinLevel)
bot->learnSpell(34091);
uint32 skillLevel = bot->GetLevel() < 40 ? 0 : 1;
@@ -2680,8 +2680,8 @@ void PlayerbotFactory::InitClassSpells()
void PlayerbotFactory::InitSpecialSpells()
{
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig.randomBotSpellIds.begin();
i != sPlayerbotAIConfig.randomBotSpellIds.end(); ++i)
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig->randomBotSpellIds.begin();
i != sPlayerbotAIConfig->randomBotSpellIds.end(); ++i)
{
uint32 spellId = *i;
bot->learnSpell(spellId);
@@ -2752,13 +2752,13 @@ void PlayerbotFactory::InitTalents(uint32 specNo)
void PlayerbotFactory::InitTalentsByTemplate(uint32 specTab)
{
// if (sPlayerbotAIConfig.parsedSpecLinkOrder[bot->getClass()][specNo][80].size() == 0)
// if (sPlayerbotAIConfig->parsedSpecLinkOrder[bot->getClass()][specNo][80].size() == 0)
// {
// return;
// }
uint32 cls = bot->getClass();
int startLevel = bot->GetLevel();
uint32 specIndex = sPlayerbotAIConfig.randomClassSpecIndex[cls][specTab];
uint32 specIndex = sPlayerbotAIConfig->randomClassSpecIndex[cls][specTab];
uint32 classMask = bot->getClassMask();
std::unordered_map<uint32, std::vector<TalentEntry const*>> spells_row;
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
@@ -2777,23 +2777,23 @@ void PlayerbotFactory::InitTalentsByTemplate(uint32 specTab)
spells_row[talentInfo->Row].push_back(talentInfo);
}
while (startLevel > 1 && startLevel < 80 &&
sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specIndex][startLevel].size() == 0)
sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specIndex][startLevel].size() == 0)
{
startLevel--;
}
for (int level = startLevel; level <= 80; level++)
{
if (sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specIndex][level].size() == 0)
if (sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specIndex][level].size() == 0)
{
continue;
}
for (std::vector<uint32>& p : sPlayerbotAIConfig.parsedSpecLinkOrder[cls][specIndex][level])
for (std::vector<uint32>& p : sPlayerbotAIConfig->parsedSpecLinkOrder[cls][specIndex][level])
{
uint32 tab = p[0], row = p[1], col = p[2], lvl = p[3];
if (sPlayerbotAIConfig.limitTalentsExpansion && bot->GetLevel() <= 60 && (row > 6 || (row == 6 && col != 1)))
if (sPlayerbotAIConfig->limitTalentsExpansion && bot->GetLevel() <= 60 && (row > 6 || (row == 6 && col != 1)))
continue;
if (sPlayerbotAIConfig.limitTalentsExpansion && bot->GetLevel() <= 70 && (row > 8 || (row == 8 && col != 1)))
if (sPlayerbotAIConfig->limitTalentsExpansion && bot->GetLevel() <= 70 && (row > 8 || (row == 8 && col != 1)))
continue;
uint32 talentID = 0;
@@ -2848,8 +2848,8 @@ void PlayerbotFactory::InitTalentsByTemplate(uint32 specTab)
ObjectGuid PlayerbotFactory::GetRandomBot()
{
GuidVector guids;
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig.randomBotAccounts.begin();
i != sPlayerbotAIConfig.randomBotAccounts.end(); i++)
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig->randomBotAccounts.begin();
i != sPlayerbotAIConfig->randomBotAccounts.end(); i++)
{
uint32 accountId = *i;
if (!AccountMgr::GetCharactersCount(accountId))
@@ -2981,7 +2981,7 @@ void PlayerbotFactory::InitAmmo()
if (!subClass)
return;
std::vector<uint32> ammoEntryList = sRandomItemMgr.GetAmmo(level, subClass);
std::vector<uint32> ammoEntryList = sRandomItemMgr->GetAmmo(level, subClass);
uint32 entry = 0;
for (uint32 tEntry : ammoEntryList)
{
@@ -2990,10 +2990,10 @@ void PlayerbotFactory::InitAmmo()
continue;
// disable next expansion ammo
if (sPlayerbotAIConfig.limitGearExpansion && bot->GetLevel() <= 60 && tEntry >= 23728)
if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 60 && tEntry >= 23728)
continue;
if (sPlayerbotAIConfig.limitGearExpansion && bot->GetLevel() <= 70 && tEntry >= 35570)
if (sPlayerbotAIConfig->limitGearExpansion && bot->GetLevel() <= 70 && tEntry >= 35570)
continue;
entry = tEntry;
@@ -3023,10 +3023,10 @@ uint32 PlayerbotFactory::CalcMixedGearScore(uint32 gs, uint32 quality)
void PlayerbotFactory::InitMounts()
{
uint32 firstmount = sPlayerbotAIConfig.useGroundMountAtMinLevel;
uint32 secondmount = sPlayerbotAIConfig.useFastGroundMountAtMinLevel;
uint32 thirdmount = sPlayerbotAIConfig.useFlyMountAtMinLevel;
uint32 fourthmount = sPlayerbotAIConfig.useFastFlyMountAtMinLevel;
uint32 firstmount = sPlayerbotAIConfig->useGroundMountAtMinLevel;
uint32 secondmount = sPlayerbotAIConfig->useFastGroundMountAtMinLevel;
uint32 thirdmount = sPlayerbotAIConfig->useFlyMountAtMinLevel;
uint32 fourthmount = sPlayerbotAIConfig->useFastFlyMountAtMinLevel;
if (bot->GetLevel() < firstmount)
return;
@@ -3165,7 +3165,7 @@ void PlayerbotFactory::InitPotions()
if (!visitor.GetResult().empty())
continue;
uint32 itemId = sRandomItemMgr.GetRandomPotion(level, effect);
uint32 itemId = sRandomItemMgr->GetRandomPotion(level, effect);
if (!itemId)
{
// LOG_INFO("playerbots", "No potions (type {}) available for bot {} ({} level)", effect,
@@ -3499,7 +3499,7 @@ void PlayerbotFactory::InitGlyphs(bool increment)
}
}
if (sPlayerbotAIConfig.limitTalentsExpansion && bot->GetLevel() <= 70)
if (sPlayerbotAIConfig->limitTalentsExpansion && bot->GetLevel() <= 70)
{
bot->SendTalentsInfoData(false);
return;
@@ -3722,10 +3722,10 @@ void PlayerbotFactory::InitGlyphs(bool increment)
// GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(slot);
// if (!gs)
// continue;
if (sPlayerbotAIConfig.parsedSpecGlyph[cls][tab].size() > slotIndex &&
sPlayerbotAIConfig.parsedSpecGlyph[cls][tab][slotIndex] != 0)
if (sPlayerbotAIConfig->parsedSpecGlyph[cls][tab].size() > slotIndex &&
sPlayerbotAIConfig->parsedSpecGlyph[cls][tab][slotIndex] != 0)
{
uint32 itemId = sPlayerbotAIConfig.parsedSpecGlyph[cls][tab][slotIndex];
uint32 itemId = sPlayerbotAIConfig->parsedSpecGlyph[cls][tab][slotIndex];
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
if (proto->Class != ITEM_CLASS_GLYPH)
continue;
@@ -3859,7 +3859,7 @@ Item* PlayerbotFactory::StoreItem(uint32 itemId, uint32 count)
void PlayerbotFactory::InitInventoryTrade()
{
uint32 itemId = sRandomItemMgr.GetRandomTrade(level);
uint32 itemId = sRandomItemMgr->GetRandomTrade(level);
if (!itemId)
{
LOG_ERROR("playerbots", "No trade items available for bot {} ({} level)", bot->GetName().c_str(),
@@ -3895,7 +3895,7 @@ void PlayerbotFactory::InitInventoryEquip()
std::vector<uint32> ids;
uint32 desiredQuality = itemQuality;
if (urand(0, 100) < 100 * sPlayerbotAIConfig.randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
{
desiredQuality--;
}
@@ -3949,21 +3949,21 @@ void PlayerbotFactory::InitGuild()
return;
}
std::string guildName = PlayerbotGuildMgr::instance().AssignToGuild(bot);
std::string guildName = sPlayerbotGuildMgr->AssignToGuild(bot);
if (guildName.empty())
return;
Guild* guild = sGuildMgr->GetGuildByName(guildName);
if (!guild)
{
if (!PlayerbotGuildMgr::instance().CreateGuild(bot, guildName))
if (!sPlayerbotGuildMgr->CreateGuild(bot, guildName))
LOG_ERROR("playerbots","Failed to create guild {} for bot {}", guildName, bot->GetName());
return;
}
else
{
if (guild->AddMember(bot->GetGUID(),urand(GR_OFFICER, GR_INITIATE)))
PlayerbotGuildMgr::instance().OnGuildUpdate(guild);
sPlayerbotGuildMgr->OnGuildUpdate(guild);
else
LOG_ERROR("playerbots","Bot {} failed to join guild {}.", bot->GetName(), guildName);
}
@@ -3985,7 +3985,7 @@ void PlayerbotFactory::InitImmersive()
std::ostringstream name;
name << "immersive_stat_" << i;
uint32 value = sRandomPlayerbotMgr.GetValue(owner, name.str());
uint32 value = sRandomPlayerbotMgr->GetValue(owner, name.str());
if (value)
initialized = true;
@@ -4058,7 +4058,7 @@ void PlayerbotFactory::InitImmersive()
std::ostringstream name;
name << "immersive_stat_" << i;
sRandomPlayerbotMgr.SetValue(owner, name.str(), percentMap[type]);
sRandomPlayerbotMgr->SetValue(owner, name.str(), percentMap[type]);
}
}
}
@@ -4066,15 +4066,15 @@ void PlayerbotFactory::InitImmersive()
void PlayerbotFactory::InitArenaTeam()
{
if (!sPlayerbotAIConfig.IsInRandomAccountList(bot->GetSession()->GetAccountId()))
if (!sPlayerbotAIConfig->IsInRandomAccountList(bot->GetSession()->GetAccountId()))
return;
// Currently the teams are only remade after a server restart and if deleteRandomBotArenaTeams = 1
// This is because randomBotArenaTeams is only empty on server restart.
// A manual reinitalization (.playerbots rndbot init) is also required after the teams have been deleted.
if (sPlayerbotAIConfig.randomBotArenaTeams.empty())
if (sPlayerbotAIConfig->randomBotArenaTeams.empty())
{
if (sPlayerbotAIConfig.deleteRandomBotArenaTeams)
if (sPlayerbotAIConfig->deleteRandomBotArenaTeams)
{
LOG_INFO("playerbots", "Deleting random bot arena teams...");
@@ -4099,14 +4099,14 @@ void PlayerbotFactory::InitArenaTeam()
LOG_INFO("playerbots", "Random bot arena teams deleted");
}
RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_2v2, sPlayerbotAIConfig.randomBotArenaTeam2v2Count);
RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_3v3, sPlayerbotAIConfig.randomBotArenaTeam3v3Count);
RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_5v5, sPlayerbotAIConfig.randomBotArenaTeam5v5Count);
RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_2v2, sPlayerbotAIConfig->randomBotArenaTeam2v2Count);
RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_3v3, sPlayerbotAIConfig->randomBotArenaTeam3v3Count);
RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_5v5, sPlayerbotAIConfig->randomBotArenaTeam5v5Count);
}
std::vector<uint32> arenateams;
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig.randomBotArenaTeams.begin();
i != sPlayerbotAIConfig.randomBotArenaTeams.end(); ++i)
for (std::vector<uint32>::iterator i = sPlayerbotAIConfig->randomBotArenaTeams.begin();
i != sPlayerbotAIConfig->randomBotArenaTeams.end(); ++i)
arenateams.push_back(*i);
if (arenateams.empty())
@@ -4300,7 +4300,7 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destroyOld)
if (!gemProperties)
continue;
if (sPlayerbotAIConfig.limitEnchantExpansion && bot->GetLevel() <= 70 && enchantGem >= 39900)
if (sPlayerbotAIConfig->limitEnchantExpansion && bot->GetLevel() <= 70 && enchantGem >= 39900)
continue;
uint32 requiredLevel = gemTemplate->ItemLevel;
@@ -4363,10 +4363,10 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destroyOld)
}
// disable next expansion enchantments
if (sPlayerbotAIConfig.limitEnchantExpansion && bot->GetLevel() <= 60 && enchantSpell >= 27899)
if (sPlayerbotAIConfig->limitEnchantExpansion && bot->GetLevel() <= 60 && enchantSpell >= 27899)
continue;
if (sPlayerbotAIConfig.limitEnchantExpansion && bot->GetLevel() <= 70 && enchantSpell >= 44483)
if (sPlayerbotAIConfig->limitEnchantExpansion && bot->GetLevel() <= 70 && enchantSpell >= 44483)
continue;
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)

View File

@@ -27,32 +27,32 @@
#include "WarriorAiObjectContext.h"
#include "WorldPacketActionContext.h"
#include "WorldPacketTriggerContext.h"
#include "Ai/Dungeon/DungeonStrategyContext.h"
#include "Ai/Dungeon/WotlkDungeonActionContext.h"
#include "Ai/Dungeon/WotlkDungeonTriggerContext.h"
#include "Ai/Raid/RaidStrategyContext.h"
#include "Ai/Raid/Aq20/RaidAq20ActionContext.h"
#include "Ai/Raid/Aq20/RaidAq20TriggerContext.h"
#include "Ai/Raid/MoltenCore/RaidMcActionContext.h"
#include "Ai/Raid/MoltenCore/RaidMcTriggerContext.h"
#include "Ai/Raid/BlackwingLair/RaidBwlActionContext.h"
#include "Ai/Raid/BlackwingLair/RaidBwlTriggerContext.h"
#include "Ai/Raid/Karazhan/RaidKarazhanActionContext.h"
#include "Ai/Raid/Karazhan/RaidKarazhanTriggerContext.h"
#include "Ai/Raid/Magtheridon/RaidMagtheridonActionContext.h"
#include "Ai/Raid/Magtheridon/RaidMagtheridonTriggerContext.h"
#include "Ai/Raid/GruulsLair/RaidGruulsLairActionContext.h"
#include "Ai/Raid/GruulsLair/RaidGruulsLairTriggerContext.h"
#include "Ai/Raid/EyeOfEternity/RaidEoEActionContext.h"
#include "Ai/Raid/EyeOfEternity/RaidEoETriggerContext.h"
#include "Ai/Raid/VaultOfArchavon/RaidVoAActionContext.h"
#include "Ai/Raid/VaultOfArchavon/RaidVoATriggerContext.h"
#include "Ai/Raid/ObsidianSanctum/RaidOsActionContext.h"
#include "Ai/Raid/ObsidianSanctum/RaidOsTriggerContext.h"
#include "Ai/Raid/Onyxia/RaidOnyxiaActionContext.h"
#include "Ai/Raid/Onyxia/RaidOnyxiaTriggerContext.h"
#include "Ai/Raid/Icecrown/RaidIccActionContext.h"
#include "Ai/Raid/Icecrown/RaidIccTriggerContext.h"
#include "dungeons/DungeonStrategyContext.h"
#include "dungeons/wotlk/WotlkDungeonActionContext.h"
#include "dungeons/wotlk/WotlkDungeonTriggerContext.h"
#include "raids/RaidStrategyContext.h"
#include "raids/aq20/RaidAq20ActionContext.h"
#include "raids/aq20/RaidAq20TriggerContext.h"
#include "raids/moltencore/RaidMcActionContext.h"
#include "raids/moltencore/RaidMcTriggerContext.h"
#include "raids/blackwinglair/RaidBwlActionContext.h"
#include "raids/blackwinglair/RaidBwlTriggerContext.h"
#include "raids/karazhan/RaidKarazhanActionContext.h"
#include "raids/karazhan/RaidKarazhanTriggerContext.h"
#include "raids/magtheridon/RaidMagtheridonActionContext.h"
#include "raids/magtheridon/RaidMagtheridonTriggerContext.h"
#include "raids/gruulslair/RaidGruulsLairActionContext.h"
#include "raids/gruulslair/RaidGruulsLairTriggerContext.h"
#include "raids/eyeofeternity/RaidEoEActionContext.h"
#include "raids/eyeofeternity/RaidEoETriggerContext.h"
#include "raids/vaultofarchavon/RaidVoAActionContext.h"
#include "raids/vaultofarchavon/RaidVoATriggerContext.h"
#include "raids/obsidiansanctum/RaidOsActionContext.h"
#include "raids/obsidiansanctum/RaidOsTriggerContext.h"
#include "raids/onyxia/RaidOnyxiaActionContext.h"
#include "raids/onyxia/RaidOnyxiaTriggerContext.h"
#include "raids/icecrown/RaidIccActionContext.h"
#include "raids/icecrown/RaidIccTriggerContext.h"
SharedNamedObjectContextList<Strategy> AiObjectContext::sharedStrategyContexts;
SharedNamedObjectContextList<Action> AiObjectContext::sharedActionContexts;

View File

@@ -7,7 +7,7 @@
#include "Action.h"
#include "Event.h"
#include "PerfMonitor.h"
#include "PerformanceMonitor.h"
#include "Playerbots.h"
#include "Queue.h"
#include "Strategy.h"
@@ -142,7 +142,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
{
LogAction("--- AI Tick ---");
if (sPlayerbotAIConfig.logValuesPerTick)
if (sPlayerbotAIConfig->logValuesPerTick)
LogValues();
bool actionExecuted = false;
@@ -154,7 +154,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
PushDefaultActions();
uint32 iterations = 0;
uint32 iterationsPerTick = queue.Size() * (minimal ? 2 : sPlayerbotAIConfig.iterationsPerTick);
uint32 iterationsPerTick = queue.Size() * (minimal ? 2 : sPlayerbotAIConfig->iterationsPerTick);
while (++iterations <= iterationsPerTick)
{
@@ -204,7 +204,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
}
}
PerfMonitorOperation* pmo = sPerfMonitor.start(PERF_MON_ACTION, action->getName(), &aiObjectContext->performanceStack);
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_ACTION, action->getName(), &aiObjectContext->performanceStack);
actionExecuted = ListenAndExecute(action, event);
if (pmo)
pmo->finish();
@@ -456,8 +456,8 @@ void Engine::ProcessTriggers(bool minimal)
if (minimal && node->getFirstRelevance() < 100)
continue;
PerfMonitorOperation* pmo =
sPerfMonitor.start(PERF_MON_TRIGGER, trigger->getName(), &aiObjectContext->performanceStack);
PerformanceMonitorOperation* pmo =
sPerformanceMonitor->start(PERF_MON_TRIGGER, trigger->getName(), &aiObjectContext->performanceStack);
Event event = trigger->Check();
if (pmo)
pmo->finish();
@@ -599,7 +599,7 @@ bool Engine::ListenAndExecute(Action* action, Event event)
void Engine::LogAction(char const* format, ...)
{
Player* bot = botAI->GetBot();
if (sPlayerbotAIConfig.logInGroupOnly && (!bot->GetGroup() || !botAI->HasRealPlayerMaster()) && !testMode)
if (sPlayerbotAIConfig->logInGroupOnly && (!bot->GetGroup() || !botAI->HasRealPlayerMaster()) && !testMode)
return;
char buf[1024];
@@ -661,7 +661,7 @@ void Engine::LogValues()
return;
Player* bot = botAI->GetBot();
if (sPlayerbotAIConfig.logInGroupOnly && (!bot->GetGroup() || !botAI->HasRealPlayerMaster()))
if (sPlayerbotAIConfig->logInGroupOnly && (!bot->GetGroup() || !botAI->HasRealPlayerMaster()))
return;
std::string const text = botAI->GetAiObjectContext()->FormatValues();

Some files were not shown because too many files have changed in this diff Show More