mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-16 10:20:27 +00:00
Refactor instance suggestions
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
#include "SayAction.h"
|
||||
#include "StayActions.h"
|
||||
#include "SuggestWhatToDoAction.h"
|
||||
#include "SuggestDungeonAction.h"
|
||||
#include "TravelAction.h"
|
||||
#include "XpGainAction.h"
|
||||
#include "VehicleActions.h"
|
||||
@@ -117,6 +118,7 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
creators["emote"] = &ActionContext::emote;
|
||||
creators["talk"] = &ActionContext::talk;
|
||||
creators["suggest what to do"] = &ActionContext::suggest_what_to_do;
|
||||
creators["suggest dungeon"] = &ActionContext::suggest_dungeon;
|
||||
creators["suggest trade"] = &ActionContext::suggest_trade;
|
||||
creators["return"] = &ActionContext::_return;
|
||||
creators["move to loot"] = &ActionContext::move_to_loot;
|
||||
@@ -264,6 +266,7 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
static Action* emote(PlayerbotAI* botAI) { return new EmoteAction(botAI); }
|
||||
static Action* talk(PlayerbotAI* botAI) { return new TalkAction(botAI); }
|
||||
static Action* suggest_what_to_do(PlayerbotAI* botAI) { return new SuggestWhatToDoAction(botAI); }
|
||||
static Action* suggest_dungeon(PlayerbotAI* botAI) { return new SuggestDungeonAction(botAI); }
|
||||
static Action* suggest_trade(PlayerbotAI* botAI) { return new SuggestTradeAction(botAI); }
|
||||
static Action* attack_anything(PlayerbotAI* botAI) { return new AttackAnythingAction(botAI); }
|
||||
static Action* attack_least_hp_target(PlayerbotAI* botAI) { return new AttackLeastHpTargetAction(botAI); }
|
||||
|
||||
95
src/strategy/actions/SuggestDungeonAction.cpp
Normal file
95
src/strategy/actions/SuggestDungeonAction.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#include "SuggestDungeonAction.h"
|
||||
#include "AiFactory.h"
|
||||
#include "Player.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
|
||||
DungeonSuggestions SuggestDungeonAction::m_dungeonSuggestions;
|
||||
|
||||
SuggestDungeonAction::SuggestDungeonAction(PlayerbotAI* botAI) :
|
||||
SuggestWhatToDoAction(botAI, "suggest instance")
|
||||
{
|
||||
if (m_dungeonSuggestions.empty())
|
||||
{
|
||||
m_dungeonSuggestions = sPlayerbotDungeonSuggestionMgr->GetDungeonSuggestions();
|
||||
}
|
||||
}
|
||||
|
||||
bool SuggestDungeonAction::Execute(Event event)
|
||||
{
|
||||
bool const isRealPlayer = !sRandomPlayerbotMgr->IsRandomBot(bot);
|
||||
bool const isInGroup = bot->GetGroup();
|
||||
bool const isInInstance = bot->GetInstanceId();
|
||||
if (isRealPlayer || isInGroup || isInInstance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DungeonSuggestions const dungeonSuggestions = GetDungeonSuggestionsEligibleFor(bot);
|
||||
if (dungeonSuggestions.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 const randomDungeonIndex = urand(0, dungeonSuggestions.size() - 1);
|
||||
DungeonSuggestion const* dungeonSuggestion = &dungeonSuggestions[randomDungeonIndex];
|
||||
PlaceholderMap const placeholders = MapPlaceholders(bot, dungeonSuggestion);
|
||||
std::string playerbotsTextKey = PlayerbotsTextKeyByMapKey(placeholders);
|
||||
std::string message = sPlayerbotTextMgr->Format(playerbotsTextKey, placeholders);
|
||||
bool isRandomlyLowerCase = sPlayerbotAIConfig->suggestDungeonsInLowerCaseRandomly
|
||||
? urand(0, 1)
|
||||
: false;
|
||||
spam(message, 1, isRandomlyLowerCase);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DungeonSuggestions const SuggestDungeonAction::GetDungeonSuggestionsEligibleFor(Player* bot)
|
||||
{
|
||||
DungeonSuggestions dungeonSuggestionsEligibleFor;
|
||||
for (DungeonSuggestions::const_iterator i = m_dungeonSuggestions.begin();
|
||||
i != m_dungeonSuggestions.end(); ++i)
|
||||
{
|
||||
uint8 const level = bot->getLevel();
|
||||
bool const isEligible = level >= i->min_level && level <= i->max_level;
|
||||
if (isEligible)
|
||||
{
|
||||
dungeonSuggestionsEligibleFor.push_back(*i);
|
||||
}
|
||||
}
|
||||
|
||||
return dungeonSuggestionsEligibleFor;
|
||||
}
|
||||
|
||||
PlaceholderMap SuggestDungeonAction::MapPlaceholders(
|
||||
Player* bot,
|
||||
DungeonSuggestion const* dungeonSuggestion
|
||||
)
|
||||
{
|
||||
PlaceholderMap placeholders;
|
||||
bool const isRandomlyMappingRole = urand(0, 1);
|
||||
if (isRandomlyMappingRole)
|
||||
{
|
||||
PlaceholderHelper::MapRole(placeholders, bot);
|
||||
}
|
||||
PlaceholderHelper::MapDungeon(placeholders, dungeonSuggestion, bot);
|
||||
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
std::string SuggestDungeonAction::PlayerbotsTextKeyByMapKey(PlaceholderMap const& placeholders)
|
||||
{
|
||||
bool const isRoleMapped = placeholders.find("%role") != placeholders.end();
|
||||
std::string playerbotsTextKey = "suggest_dungeon";
|
||||
if (isRoleMapped)
|
||||
{
|
||||
playerbotsTextKey = "suggest_dungeon_role";
|
||||
}
|
||||
|
||||
return playerbotsTextKey;
|
||||
}
|
||||
33
src/strategy/actions/SuggestDungeonAction.h
Normal file
33
src/strategy/actions/SuggestDungeonAction.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_SUGGESTINSTANCEACTION_H
|
||||
#define _PLAYERBOT_SUGGESTINSTANCEACTION_H
|
||||
|
||||
#include "SuggestWhatToDoAction.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
#include "PlaceholderHelper.h"
|
||||
|
||||
typedef std::vector<DungeonSuggestion> DungeonSuggestions;
|
||||
|
||||
class SuggestDungeonAction : public SuggestWhatToDoAction
|
||||
{
|
||||
public:
|
||||
SuggestDungeonAction(PlayerbotAI* botAI);
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override { return true; }
|
||||
|
||||
private:
|
||||
static DungeonSuggestions m_dungeonSuggestions;
|
||||
|
||||
DungeonSuggestions const GetDungeonSuggestionsEligibleFor(Player* bot);
|
||||
PlaceholderMap MapPlaceholders(
|
||||
Player* bot,
|
||||
DungeonSuggestion const* dungeonSuggestion
|
||||
);
|
||||
std::string PlayerbotsTextKeyByMapKey(PlaceholderMap const& placeholders);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -11,12 +11,10 @@
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
|
||||
std::map<std::string, uint8> SuggestWhatToDoAction::instances;
|
||||
std::map<std::string, uint8> SuggestWhatToDoAction::factions;
|
||||
|
||||
SuggestWhatToDoAction::SuggestWhatToDoAction(PlayerbotAI* botAI, std::string const name) : InventoryAction(botAI, name)
|
||||
{
|
||||
suggestions.push_back(&SuggestWhatToDoAction::instance);
|
||||
suggestions.push_back(&SuggestWhatToDoAction::specificQuest);
|
||||
suggestions.push_back(&SuggestWhatToDoAction::grindReputation);
|
||||
suggestions.push_back(&SuggestWhatToDoAction::something);
|
||||
@@ -37,74 +35,6 @@ bool SuggestWhatToDoAction::Execute(Event event)
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::instance()
|
||||
{
|
||||
if (instances.empty())
|
||||
{
|
||||
instances["Ragefire Chasm"] = 15;
|
||||
instances["Deadmines"] = 18;
|
||||
instances["Wailing Caverns"] = 18;
|
||||
instances["Shadowfang Keep"] = 25;
|
||||
instances["Blackfathom Deeps"] = 20;
|
||||
instances["Stockade"] = 20;
|
||||
instances["Gnomeregan"] = 35;
|
||||
instances["Razorfen Kraul"] = 35;
|
||||
instances["Maraudon"] = 50;
|
||||
instances["Scarlet Monastery"] = 40;
|
||||
instances["Uldaman"] = 45;
|
||||
instances["Dire Maul"] = 58;
|
||||
instances["Scholomance"] = 59;
|
||||
instances["Razorfen Downs"] = 40;
|
||||
instances["Stratholme"] = 59;
|
||||
instances["Zul'Farrak"] = 45;
|
||||
instances["Blackrock Depths"] = 55;
|
||||
instances["Temple of Atal'Hakkar"] = 55;
|
||||
instances["Lower Blackrock Spire"] = 57;
|
||||
|
||||
instances["Hellfire Citadel"] = 65;
|
||||
instances["Coilfang Reservoir"] = 65;
|
||||
instances["Auchindoun"] = 65;
|
||||
instances["Cavens of Time"] = 68;
|
||||
instances["Tempest Keep"] = 69;
|
||||
instances["Magister's Terrace"] = 70;
|
||||
|
||||
instances["Utgarde Keep"] = 75;
|
||||
instances["The Nexus"] = 75;
|
||||
instances["Ahn'kahet: The Old Kingdom"] = 75;
|
||||
instances["Azjol-Nerub"] = 75;
|
||||
instances["Drak'Tharon Keep"] = 75;
|
||||
instances["Violet Hold"] = 80;
|
||||
instances["Gundrak"] = 77;
|
||||
instances["Halls of Stone"] = 77;
|
||||
instances["Halls of Lightning"] = 77;
|
||||
instances["Oculus"] = 77;
|
||||
instances["Utgarde Pinnacle"] = 77;
|
||||
instances["Trial of the Champion"] = 80;
|
||||
instances["Forge of Souls"] = 80;
|
||||
instances["Pit of Saron"] = 80;
|
||||
instances["Halls of Reflection"] = 80;
|
||||
}
|
||||
|
||||
std::vector<std::string> allowedInstances;
|
||||
for (std::map<std::string, uint8>::iterator i = instances.begin(); i != instances.end(); ++i)
|
||||
{
|
||||
if (bot->getLevel() >= i->second)
|
||||
allowedInstances.push_back(i->first);
|
||||
}
|
||||
|
||||
if (allowedInstances.empty())
|
||||
return;
|
||||
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||
|
||||
std::ostringstream itemout;
|
||||
itemout << "|c00b000b0" << allowedInstances[urand(0, allowedInstances.size() - 1)] << "|r";
|
||||
placeholders["%instance"] = itemout.str();
|
||||
|
||||
spam(sPlayerbotTextMgr->Format("suggest_instance", placeholders));
|
||||
}
|
||||
|
||||
std::vector<uint32> SuggestWhatToDoAction::GetIncompletedQuests()
|
||||
{
|
||||
std::vector<uint32> result;
|
||||
@@ -226,7 +156,11 @@ void SuggestWhatToDoAction::something()
|
||||
spam(sPlayerbotTextMgr->Format("suggest_something", placeholders));
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::spam(std::string const msg, uint32 channelId)
|
||||
void SuggestWhatToDoAction::spam(
|
||||
std::string msg,
|
||||
uint32 channelId,
|
||||
bool const isLowerCase
|
||||
)
|
||||
{
|
||||
std::set<std::string> said;
|
||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
||||
@@ -248,6 +182,10 @@ void SuggestWhatToDoAction::spam(std::string const msg, uint32 channelId)
|
||||
if (Channel* chn = cMgr->GetJoinChannel(channelName, channel->ChannelID))
|
||||
{
|
||||
chn->JoinChannel(bot, "");
|
||||
if (isLowerCase)
|
||||
{
|
||||
strToLower(msg);
|
||||
}
|
||||
chn->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,14 @@ class SuggestWhatToDoAction : public InventoryAction
|
||||
protected:
|
||||
typedef void (SuggestWhatToDoAction::*Suggestion)();
|
||||
std::vector<Suggestion> suggestions;
|
||||
void instance();
|
||||
void specificQuest();
|
||||
void grindReputation();
|
||||
void something();
|
||||
void spam(std::string const msg, uint32 channelId = 1);
|
||||
void spam(
|
||||
std::string msg,
|
||||
uint32 channelId = 1,
|
||||
bool const isLowerCase = false
|
||||
);
|
||||
|
||||
std::vector<uint32> GetIncompletedQuests();
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ void EmoteStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("suggest what to do", 1.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("suggest trade", 1.0f), nullptr)));
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotSuggestDungeons)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("random", NextAction::array(0, new NextAction("suggest dungeon", 1.0f), nullptr)));
|
||||
}
|
||||
|
||||
if (sPlayerbotAIConfig->enableGreet)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("new player nearby", NextAction::array(0, new NextAction("greet", 1.0f), nullptr)));
|
||||
|
||||
Reference in New Issue
Block a user