mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-02-07 20:51:09 +00:00
Merge remote-tracking branch 'upstream/master' into karazhan
This commit is contained in:
@@ -159,6 +159,9 @@ AiPlayerbot.RandomBotGuildNearby = 0
|
|||||||
# Number of guilds created by randombots
|
# Number of guilds created by randombots
|
||||||
AiPlayerbot.RandomBotGuildCount = 20
|
AiPlayerbot.RandomBotGuildCount = 20
|
||||||
|
|
||||||
|
# Maximum number of members in randombot guilds (minimum is hardcoded to 10)
|
||||||
|
AiPlayerbot.RandomBotGuildSizeMax = 15
|
||||||
|
|
||||||
# Delete all randombot guilds if set to 1
|
# Delete all randombot guilds if set to 1
|
||||||
AiPlayerbot.DeleteRandomBotGuilds = 0
|
AiPlayerbot.DeleteRandomBotGuilds = 0
|
||||||
|
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
|||||||
{
|
{
|
||||||
engine->addStrategiesNoInit("dps", "shadow debuff", "shadow aoe", nullptr);
|
engine->addStrategiesNoInit("dps", "shadow debuff", "shadow aoe", nullptr);
|
||||||
}
|
}
|
||||||
else if (tab == PRIEST_TAB_DISIPLINE)
|
else if (tab == PRIEST_TAB_DISCIPLINE)
|
||||||
{
|
{
|
||||||
engine->addStrategiesNoInit("heal", nullptr);
|
engine->addStrategiesNoInit("heal", nullptr);
|
||||||
}
|
}
|
||||||
@@ -607,7 +607,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
|||||||
nonCombatEngine->addStrategy("dps assist", false);
|
nonCombatEngine->addStrategy("dps assist", false);
|
||||||
break;
|
break;
|
||||||
case CLASS_WARLOCK:
|
case CLASS_WARLOCK:
|
||||||
if (tab == WARLOCK_TAB_AFFLICATION)
|
if (tab == WARLOCK_TAB_AFFLICTION)
|
||||||
{
|
{
|
||||||
nonCombatEngine->addStrategiesNoInit("felhunter", "spellstone", nullptr);
|
nonCombatEngine->addStrategiesNoInit("felhunter", "spellstone", nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2088,7 +2088,7 @@ bool PlayerbotAI::IsHeal(Player* player, bool bySpec)
|
|||||||
switch (player->getClass())
|
switch (player->getClass())
|
||||||
{
|
{
|
||||||
case CLASS_PRIEST:
|
case CLASS_PRIEST:
|
||||||
if (tab == PRIEST_TAB_DISIPLINE || tab == PRIEST_TAB_HOLY)
|
if (tab == PRIEST_TAB_DISCIPLINE || tab == PRIEST_TAB_HOLY)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ enum BotRoles : uint8
|
|||||||
|
|
||||||
enum HUNTER_TABS
|
enum HUNTER_TABS
|
||||||
{
|
{
|
||||||
HUNTER_TAB_BEASTMASTER,
|
HUNTER_TAB_BEASTMASTERY,
|
||||||
HUNTER_TAB_MARKSMANSHIP,
|
HUNTER_TAB_MARKSMANSHIP,
|
||||||
HUNTER_TAB_SURVIVAL,
|
HUNTER_TAB_SURVIVAL,
|
||||||
};
|
};
|
||||||
@@ -285,12 +285,12 @@ enum ROGUE_TABS
|
|||||||
{
|
{
|
||||||
ROGUE_TAB_ASSASSINATION,
|
ROGUE_TAB_ASSASSINATION,
|
||||||
ROGUE_TAB_COMBAT,
|
ROGUE_TAB_COMBAT,
|
||||||
ROGUE_TAB_SUBTLETY
|
ROGUE_TAB_SUBTLETY,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PRIEST_TABS
|
enum PRIEST_TABS
|
||||||
{
|
{
|
||||||
PRIEST_TAB_DISIPLINE,
|
PRIEST_TAB_DISCIPLINE,
|
||||||
PRIEST_TAB_HOLY,
|
PRIEST_TAB_HOLY,
|
||||||
PRIEST_TAB_SHADOW,
|
PRIEST_TAB_SHADOW,
|
||||||
};
|
};
|
||||||
@@ -332,7 +332,7 @@ enum PALADIN_TABS
|
|||||||
|
|
||||||
enum WARLOCK_TABS
|
enum WARLOCK_TABS
|
||||||
{
|
{
|
||||||
WARLOCK_TAB_AFFLICATION,
|
WARLOCK_TAB_AFFLICTION,
|
||||||
WARLOCK_TAB_DEMONOLOGY,
|
WARLOCK_TAB_DEMONOLOGY,
|
||||||
WARLOCK_TAB_DESTRUCTION,
|
WARLOCK_TAB_DESTRUCTION,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -509,6 +509,7 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
randomBotAccountCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAccountCount", 0);
|
randomBotAccountCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAccountCount", 0);
|
||||||
deleteRandomBotAccounts = sConfigMgr->GetOption<bool>("AiPlayerbot.DeleteRandomBotAccounts", false);
|
deleteRandomBotAccounts = sConfigMgr->GetOption<bool>("AiPlayerbot.DeleteRandomBotAccounts", false);
|
||||||
randomBotGuildCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotGuildCount", 20);
|
randomBotGuildCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotGuildCount", 20);
|
||||||
|
randomBotGuildSizeMax = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotGuildSizeMax", 15);
|
||||||
deleteRandomBotGuilds = sConfigMgr->GetOption<bool>("AiPlayerbot.DeleteRandomBotGuilds", false);
|
deleteRandomBotGuilds = sConfigMgr->GetOption<bool>("AiPlayerbot.DeleteRandomBotGuilds", false);
|
||||||
|
|
||||||
guildTaskEnabled = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableGuildTasks", true);
|
guildTaskEnabled = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableGuildTasks", true);
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ public:
|
|||||||
uint32 randomBotAccountCount;
|
uint32 randomBotAccountCount;
|
||||||
bool randomBotRandomPassword;
|
bool randomBotRandomPassword;
|
||||||
bool deleteRandomBotAccounts;
|
bool deleteRandomBotAccounts;
|
||||||
uint32 randomBotGuildCount;
|
uint32 randomBotGuildCount, randomBotGuildSizeMax;
|
||||||
bool deleteRandomBotGuilds;
|
bool deleteRandomBotGuilds;
|
||||||
std::vector<uint32> randomBotGuilds;
|
std::vector<uint32> randomBotGuilds;
|
||||||
std::vector<uint32> pvpProhibitedZoneIds;
|
std::vector<uint32> pvpProhibitedZoneIds;
|
||||||
|
|||||||
@@ -101,6 +101,22 @@ std::string PlayerbotTextMgr::GetBotText(std::string name, std::map<std::string,
|
|||||||
return botText;
|
return botText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PlayerbotTextMgr::GetBotTextOrDefault(std::string name, std::string defaultText,
|
||||||
|
std::map<std::string, std::string> placeholders)
|
||||||
|
{
|
||||||
|
std::string botText = GetBotText(name, placeholders);
|
||||||
|
if (botText.empty())
|
||||||
|
{
|
||||||
|
for (std::map<std::string, std::string>::iterator i = placeholders.begin(); i != placeholders.end(); ++i)
|
||||||
|
{
|
||||||
|
replaceAll(defaultText, i->first, i->second);
|
||||||
|
}
|
||||||
|
return defaultText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return botText;
|
||||||
|
}
|
||||||
|
|
||||||
// chat replies
|
// chat replies
|
||||||
|
|
||||||
std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::map<std::string, std::string> placeholders)
|
std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::map<std::string, std::string> placeholders)
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ public:
|
|||||||
std::string GetBotText(ChatReplyType replyType, std::string name);
|
std::string GetBotText(ChatReplyType replyType, std::string name);
|
||||||
bool GetBotText(std::string name, std::string& text);
|
bool GetBotText(std::string name, std::string& text);
|
||||||
bool GetBotText(std::string name, std::string& text, std::map<std::string, std::string> placeholders);
|
bool GetBotText(std::string name, std::string& text, std::map<std::string, std::string> placeholders);
|
||||||
|
std::string GetBotTextOrDefault(std::string name, std::string defaultText,
|
||||||
|
std::map<std::string, std::string> placeholders);
|
||||||
void LoadBotTexts();
|
void LoadBotTexts();
|
||||||
void LoadBotTextChance();
|
void LoadBotTextChance();
|
||||||
static void replaceAll(std::string& str, const std::string& from, const std::string& to);
|
static void replaceAll(std::string& str, const std::string& from, const std::string& to);
|
||||||
|
|||||||
@@ -3992,7 +3992,7 @@ void PlayerbotFactory::InitGuild()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (guild->GetMemberSize() < urand(10, 15))
|
if (guild->GetMemberSize() < urand(10, sPlayerbotAIConfig->randomBotGuildSizeMax))
|
||||||
guild->AddMember(bot->GetGUID(), urand(GR_OFFICER, GR_INITIATE));
|
guild->AddMember(bot->GetGUID(), urand(GR_OFFICER, GR_INITIATE));
|
||||||
|
|
||||||
// add guild tabard
|
// add guild tabard
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ void StatsWeightCalculator::GenerateBasicWeights(Player* player)
|
|||||||
stats_weights_[STATS_TYPE_MELEE_DPS] += 0.01f;
|
stats_weights_[STATS_TYPE_MELEE_DPS] += 0.01f;
|
||||||
stats_weights_[STATS_TYPE_RANGED_DPS] += 0.01f;
|
stats_weights_[STATS_TYPE_RANGED_DPS] += 0.01f;
|
||||||
|
|
||||||
if (cls == CLASS_HUNTER && (tab == HUNTER_TAB_BEASTMASTER || tab == HUNTER_TAB_SURVIVAL))
|
if (cls == CLASS_HUNTER && (tab == HUNTER_TAB_BEASTMASTERY || tab == HUNTER_TAB_SURVIVAL))
|
||||||
{
|
{
|
||||||
stats_weights_[STATS_TYPE_AGILITY] += 2.5f;
|
stats_weights_[STATS_TYPE_AGILITY] += 2.5f;
|
||||||
stats_weights_[STATS_TYPE_ATTACK_POWER] += 1.0f;
|
stats_weights_[STATS_TYPE_ATTACK_POWER] += 1.0f;
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ public:
|
|||||||
std::unordered_map<std::string, ObjectCreator> creators;
|
std::unordered_map<std::string, ObjectCreator> creators;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual ~NamedObjectFactory() = default;
|
||||||
|
|
||||||
virtual T* create(std::string name, PlayerbotAI* botAI)
|
virtual T* create(std::string name, PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
size_t found = name.find("::");
|
size_t found = name.find("::");
|
||||||
@@ -147,9 +149,7 @@ public:
|
|||||||
{
|
{
|
||||||
contexts.push_back(context);
|
contexts.push_back(context);
|
||||||
for (const auto& iter : context->creators)
|
for (const auto& iter : context->creators)
|
||||||
{
|
|
||||||
creators[iter.first] = iter.second;
|
creators[iter.first] = iter.second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,6 +208,7 @@ public:
|
|||||||
if (T* object = create(name, botAI))
|
if (T* object = create(name, botAI))
|
||||||
return created[name] = object;
|
return created[name] = object;
|
||||||
}
|
}
|
||||||
|
|
||||||
return created[name];
|
return created[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +237,6 @@ public:
|
|||||||
for (auto i = contexts.begin(); i != contexts.end(); i++)
|
for (auto i = contexts.begin(); i != contexts.end(); i++)
|
||||||
{
|
{
|
||||||
std::set<std::string> supported = (*i)->supports();
|
std::set<std::string> supported = (*i)->supports();
|
||||||
|
|
||||||
for (std::set<std::string>::const_iterator j = supported.begin(); j != supported.end(); ++j)
|
for (std::set<std::string>::const_iterator j = supported.begin(); j != supported.end(); ++j)
|
||||||
result.insert(*j);
|
result.insert(*j);
|
||||||
}
|
}
|
||||||
@@ -248,9 +248,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::set<std::string> result;
|
std::set<std::string> result;
|
||||||
for (typename std::unordered_map<std::string, T*>::const_iterator i = created.begin(); i != created.end(); i++)
|
for (typename std::unordered_map<std::string, T*>::const_iterator i = created.begin(); i != created.end(); i++)
|
||||||
{
|
|
||||||
result.insert(i->first);
|
result.insert(i->first);
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -297,15 +295,14 @@ public:
|
|||||||
{
|
{
|
||||||
factories.push_back(context);
|
factories.push_back(context);
|
||||||
for (const auto& iter : context->creators)
|
for (const auto& iter : context->creators)
|
||||||
{
|
|
||||||
creators[iter.first] = iter.second;
|
creators[iter.first] = iter.second;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T* GetContextObject(const std::string& name, PlayerbotAI* botAI)
|
T* GetContextObject(const std::string& name, PlayerbotAI* botAI)
|
||||||
{
|
{
|
||||||
if (T* object = create(name, botAI))
|
if (T* object = create(name, botAI))
|
||||||
return object;
|
return object;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -184,8 +184,8 @@ private:
|
|||||||
static Strategy* grind(PlayerbotAI* botAI) { return new GrindingStrategy(botAI); }
|
static Strategy* grind(PlayerbotAI* botAI) { return new GrindingStrategy(botAI); }
|
||||||
static Strategy* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeStrategy(botAI); }
|
static Strategy* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeStrategy(botAI); }
|
||||||
static Strategy* tank_face(PlayerbotAI* botAI) { return new TankFaceStrategy(botAI); }
|
static Strategy* tank_face(PlayerbotAI* botAI) { return new TankFaceStrategy(botAI); }
|
||||||
static Strategy* move_random(PlayerbotAI* ai) { return new MoveRandomStrategy(ai); }
|
static Strategy* move_random(PlayerbotAI* botAI) { return new MoveRandomStrategy(botAI); }
|
||||||
static Strategy* combat_formation(PlayerbotAI* ai) { return new CombatFormationStrategy(ai); }
|
static Strategy* combat_formation(PlayerbotAI* botAI) { return new CombatFormationStrategy(botAI); }
|
||||||
static Strategy* move_from_group(PlayerbotAI* botAI) { return new MoveFromGroupStrategy(botAI); }
|
static Strategy* move_from_group(PlayerbotAI* botAI) { return new MoveFromGroupStrategy(botAI); }
|
||||||
static Strategy* world_buff(PlayerbotAI* botAI) { return new WorldBuffStrategy(botAI); }
|
static Strategy* world_buff(PlayerbotAI* botAI) { return new WorldBuffStrategy(botAI); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -152,13 +152,9 @@ bool CheckMountStateAction::Execute(Event /*event*/)
|
|||||||
|
|
||||||
bool inBattleground = bot->InBattleground();
|
bool inBattleground = bot->InBattleground();
|
||||||
|
|
||||||
// If there is a master and bot not in BG
|
// If there is a master and bot not in BG, follow master's mount state regardless of group leader
|
||||||
if (master && !inBattleground)
|
if (master && !inBattleground)
|
||||||
{
|
{
|
||||||
Group* group = bot->GetGroup();
|
|
||||||
if (!group || group->GetLeaderGUID() != master->GetGUID())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ShouldFollowMasterMountState(master, noAttackers, shouldMount))
|
if (ShouldFollowMasterMountState(master, noAttackers, shouldMount))
|
||||||
return Mount();
|
return Mount();
|
||||||
|
|
||||||
|
|||||||
@@ -125,26 +125,15 @@ namespace ai::buff
|
|||||||
key = "rp_missing_reagent_generic";
|
key = "rp_missing_reagent_generic";
|
||||||
|
|
||||||
// Placeholders
|
// Placeholders
|
||||||
std::map<std::string, std::string> ph;
|
std::map<std::string, std::string> placeholders;
|
||||||
ph["%group_spell"] = groupName;
|
placeholders["%group_spell"] = groupName;
|
||||||
ph["%base_spell"] = baseName;
|
placeholders["%base_spell"] = baseName;
|
||||||
|
|
||||||
// Respecte ai_playerbot_texts_chance if present
|
std::string announceText = sPlayerbotTextMgr->GetBotTextOrDefault(key,
|
||||||
std::string rp;
|
"Out of components for %group_spell. Using %base_spell!", placeholders);
|
||||||
bool got = sPlayerbotTextMgr->GetBotText(key, rp, ph);
|
|
||||||
if (got && !rp.empty())
|
announce(announceText);
|
||||||
{
|
last = now;
|
||||||
announce(rp);
|
|
||||||
last = now;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Minimal Fallback
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Out of components for " << groupName << ". Using " << baseName << "!";
|
|
||||||
announce(oss.str());
|
|
||||||
last = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
class AutoShareQuestAction : public ShareQuestAction
|
class AutoShareQuestAction : public ShareQuestAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutoShareQuestAction(PlayerbotAI* ai) : ShareQuestAction(botAI, "auto share quest") {}
|
AutoShareQuestAction(PlayerbotAI* botAI) : ShareQuestAction(botAI, "auto share quest") {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public:
|
|||||||
class MoveRandomStrategy : public NonCombatStrategy
|
class MoveRandomStrategy : public NonCombatStrategy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MoveRandomStrategy(PlayerbotAI* ai) : NonCombatStrategy(botAI) {}
|
MoveRandomStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) {}
|
||||||
std::string const getName() override { return "move random"; }
|
std::string const getName() override { return "move random"; }
|
||||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class PullPowerSparkAction : public CastSpellAction
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PullPowerSparkAction(PlayerbotAI* botAI, std::string const name = "pull power spark")
|
PullPowerSparkAction(PlayerbotAI* botAI, std::string const name = "pull power spark")
|
||||||
: CastSpellAction(botAI, "death grip") {}
|
: CastSpellAction(botAI, name) {}
|
||||||
bool Execute(Event event) override;
|
bool Execute(Event event) override;
|
||||||
bool isPossible() override;
|
bool isPossible() override;
|
||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
|
|||||||
Reference in New Issue
Block a user