mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-22 04:56:22 +00:00
Bot should be more consistent at doing quest +several fixes
This commit is contained in:
@@ -6,54 +6,62 @@
|
||||
#include "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
void AcceptAllQuestsAction::ProcessQuest(Quest const* quest, Object* questGiver)
|
||||
bool AcceptAllQuestsAction::ProcessQuest(Quest const* quest, Object* questGiver)
|
||||
{
|
||||
AcceptQuest(quest, questGiver->GetGUID());
|
||||
if (!AcceptQuest(quest, questGiver->GetGUID())) return false;
|
||||
|
||||
auto text_quest = ChatHelper::FormatQuest(quest);
|
||||
bot->PlayDistanceSound(620);
|
||||
|
||||
if (botAI->HasStrategy("debug quest", BotState::BOT_STATE_NON_COMBAT) || botAI->HasStrategy("debug rpg", BotState::BOT_STATE_COMBAT))
|
||||
{
|
||||
bot->Say("Quest [ " + text_quest + " ] accepted", LANG_UNIVERSAL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AcceptQuestAction::Execute(Event event)
|
||||
{
|
||||
Player* master = GetMaster();
|
||||
if (!master)
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
if (!requester)
|
||||
return false;
|
||||
|
||||
Player* bot = botAI->GetBot();
|
||||
ObjectGuid guid;
|
||||
uint64_t guid;
|
||||
uint32 quest = 0;
|
||||
|
||||
std::string const text = event.getParam();
|
||||
PlayerbotChatHandler ch(master);
|
||||
PlayerbotChatHandler ch(requester);
|
||||
quest = ch.extractQuestId(text);
|
||||
|
||||
bool hasAccept = false;
|
||||
|
||||
if (event.getPacket().empty())
|
||||
{
|
||||
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
|
||||
for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++)
|
||||
for (auto i = npcs.begin(); i != npcs.end(); i++)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(*i);
|
||||
if (unit && quest && unit->hasQuest(quest))
|
||||
{
|
||||
guid = unit->GetGUID();
|
||||
guid = unit->GetGUID().GetRawValue();
|
||||
break;
|
||||
}
|
||||
|
||||
if (unit && text == "*" && bot->GetDistance(unit) <= INTERACTION_DISTANCE)
|
||||
QuestAction::ProcessQuests(unit);
|
||||
if (unit && text == "*" && sqrt(bot->GetDistance(unit)) <= INTERACTION_DISTANCE)
|
||||
hasAccept |= QuestAction::ProcessQuests(unit);
|
||||
}
|
||||
|
||||
GuidVector gos = AI_VALUE(GuidVector, "nearest game objects");
|
||||
for (GuidVector::iterator i = gos.begin(); i != gos.end(); i++)
|
||||
GuidVector gos = AI_VALUE(GuidVector, "nearest game objects no los");
|
||||
for (auto i = gos.begin(); i != gos.end(); i++)
|
||||
{
|
||||
GameObject* go = botAI->GetGameObject(*i);
|
||||
if (go && quest && go->hasQuest(quest))
|
||||
{
|
||||
guid = go->GetGUID();
|
||||
guid = go->GetGUID().GetRawValue();
|
||||
break;
|
||||
}
|
||||
|
||||
if (go && text == "*" && bot->GetDistance(go) <= INTERACTION_DISTANCE)
|
||||
QuestAction::ProcessQuests(go);
|
||||
if (go && text == "*" && sqrt(bot->GetDistance(go)) <= INTERACTION_DISTANCE)
|
||||
hasAccept |= QuestAction::ProcessQuests(go);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -70,7 +78,17 @@ bool AcceptQuestAction::Execute(Event event)
|
||||
if (!qInfo)
|
||||
return false;
|
||||
|
||||
return AcceptQuest(qInfo, guid);
|
||||
hasAccept |= AcceptQuest(qInfo, ObjectGuid(guid));
|
||||
|
||||
if (hasAccept)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "AcceptQuestAction {" << qInfo->GetTitle() << "} - {" << std::to_string(qInfo->GetQuestId()) << "}";
|
||||
LOG_INFO("playerbots", "{}", ss.str().c_str());
|
||||
botAI->TellMaster(ss.str());
|
||||
}
|
||||
|
||||
return hasAccept;
|
||||
}
|
||||
|
||||
bool AcceptQuestShareAction::Execute(Event event)
|
||||
@@ -112,7 +130,7 @@ bool AcceptQuestShareAction::Execute(Event event)
|
||||
bot->SetDivider(ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
if (bot->CanAddQuest( qInfo, false))
|
||||
if (bot->CanAddQuest(qInfo, false))
|
||||
{
|
||||
bot->AddQuest(qInfo, master);
|
||||
|
||||
@@ -125,7 +143,7 @@ bool AcceptQuestShareAction::Execute(Event event)
|
||||
|
||||
if (qInfo->GetSrcSpell() > 0)
|
||||
{
|
||||
bot->CastSpell( bot, qInfo->GetSrcSpell(), true);
|
||||
bot->CastSpell(bot, qInfo->GetSrcSpell(), true);
|
||||
}
|
||||
|
||||
botAI->TellMaster("Quest accepted");
|
||||
@@ -134,3 +152,41 @@ bool AcceptQuestShareAction::Execute(Event event)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfirmQuestAction::Execute(Event event)
|
||||
{
|
||||
Player* bot = botAI->GetBot();
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
|
||||
WorldPacket& p = event.getPacket();
|
||||
p.rpos(0);
|
||||
uint32 quest;
|
||||
p >> quest;
|
||||
Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest);
|
||||
|
||||
quest = qInfo->GetQuestId();
|
||||
if (!bot->CanTakeQuest(qInfo, false))
|
||||
{
|
||||
// can't take quest
|
||||
botAI->TellError("quest_cant_take");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot->CanAddQuest(qInfo, false))
|
||||
{
|
||||
bot->AddQuest(qInfo, requester);
|
||||
|
||||
if (bot->CanCompleteQuest(quest))
|
||||
bot->CompleteQuest(quest);
|
||||
|
||||
if (qInfo->GetSrcSpell() > 0)
|
||||
{
|
||||
bot->CastSpell(bot, qInfo->GetSrcSpell(), true);
|
||||
}
|
||||
|
||||
botAI->TellMaster("quest_accept");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class AcceptAllQuestsAction : public QuestAction
|
||||
AcceptAllQuestsAction(PlayerbotAI* botAI, std::string const name = "accept all quests") : QuestAction(botAI, name) { }
|
||||
|
||||
protected:
|
||||
void ProcessQuest(Quest const* quest, Object* questGiver) override;
|
||||
bool ProcessQuest(Quest const* quest, Object* questGiver) override;
|
||||
};
|
||||
|
||||
class AcceptQuestAction : public AcceptAllQuestsAction
|
||||
@@ -34,4 +34,10 @@ class AcceptQuestShareAction : public Action
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class ConfirmQuestAction : public Action {
|
||||
public:
|
||||
ConfirmQuestAction(PlayerbotAI* ai) : Action(ai, "confirm quest") {}
|
||||
bool Execute(Event event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,10 +30,10 @@ bool AutoLearnSpellAction::Execute(Event event)
|
||||
|
||||
void AutoLearnSpellAction::LearnSpells(std::ostringstream* out)
|
||||
{
|
||||
if (sPlayerbotAIConfig->autoLearnTrainerSpells && sRandomPlayerbotMgr->IsRandomBot(bot))// || (!botAI->GetMaster() && sRandomPlayerbotMgr->IsRandomBot(bot)))
|
||||
if (sPlayerbotAIConfig->autoLearnTrainerSpells)
|
||||
LearnTrainerSpells(out);
|
||||
|
||||
if (sPlayerbotAIConfig->autoLearnQuestSpells && sRandomPlayerbotMgr->IsRandomBot(bot))// || (!botAI->GetMaster() && sRandomPlayerbotMgr->IsRandomBot(bot)))
|
||||
if (sPlayerbotAIConfig->autoLearnQuestSpells)
|
||||
LearnQuestSpells(out);
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotGuildTalk)
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include "GuildCreateActions.h"
|
||||
#include "PossibleRpgTargetsValue.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RpgSubActions.h"
|
||||
#include "Util.h"
|
||||
#include "ServerFacade.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
@@ -50,42 +53,77 @@ float ChooseRpgTargetAction::getMaxRelevance(GuidPosition guidP)
|
||||
GuidPosition currentRpgTarget = AI_VALUE(GuidPosition, "rpg target");
|
||||
SET_AI_VALUE(GuidPosition, "rpg target", guidP);
|
||||
|
||||
Strategy* rpgStrategy = botAI->GetAiObjectContext()->GetStrategy("rpg");
|
||||
Strategy* rpgStrategy;
|
||||
|
||||
std::vector<TriggerNode*> triggerNodes;
|
||||
rpgStrategy->InitTriggers(triggerNodes);
|
||||
|
||||
float maxRelevance = 0.0f;
|
||||
|
||||
for (auto& triggerNode : triggerNodes)
|
||||
for (auto& strategy : botAI->GetAiObjectContext()->GetSupportedStrategies())
|
||||
{
|
||||
Trigger* trigger = context->GetTrigger(triggerNode->getName());
|
||||
if (trigger)
|
||||
if (strategy.find("rpg") == std::string::npos)
|
||||
continue;
|
||||
|
||||
if (!botAI->HasStrategy(strategy, BotState::BOT_STATE_NON_COMBAT))
|
||||
continue;
|
||||
|
||||
rpgStrategy = botAI->GetAiObjectContext()->GetStrategy(strategy);
|
||||
|
||||
rpgStrategy->InitTriggers(triggerNodes);
|
||||
|
||||
for (auto triggerNode : triggerNodes)
|
||||
{
|
||||
triggerNode->setTrigger(trigger);
|
||||
Trigger* trigger = context->GetTrigger(triggerNode->getName());
|
||||
|
||||
if (triggerNode->getFirstRelevance() < maxRelevance || triggerNode->getFirstRelevance() > 2.0f)
|
||||
continue;
|
||||
if (trigger)
|
||||
{
|
||||
triggerNode->setTrigger(trigger);
|
||||
|
||||
trigger = triggerNode->getTrigger();
|
||||
if (!trigger->IsActive())
|
||||
continue;
|
||||
if (triggerNode->getFirstRelevance() < maxRelevance || triggerNode->getFirstRelevance() > 2.0f)
|
||||
continue;
|
||||
|
||||
maxRelevance = triggerNode->getFirstRelevance();
|
||||
Trigger* trigger = triggerNode->getTrigger();
|
||||
|
||||
if (!trigger->IsActive())
|
||||
continue;
|
||||
|
||||
NextAction** nextActions = triggerNode->getHandlers();
|
||||
|
||||
bool isRpg = false;
|
||||
|
||||
for (int32 i = 0; i < NextAction::size(nextActions); i++)
|
||||
{
|
||||
NextAction* nextAction = nextActions[i];
|
||||
|
||||
Action* action = botAI->GetAiObjectContext()->GetAction(nextAction->getName());
|
||||
|
||||
if (dynamic_cast<RpgEnabled*>(action))
|
||||
isRpg = true;
|
||||
}
|
||||
NextAction::destroy(nextActions);
|
||||
|
||||
if (isRpg)
|
||||
{
|
||||
maxRelevance = triggerNode->getFirstRelevance();
|
||||
rgpActionReason[guidP] = triggerNode->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto trigger : triggerNodes)
|
||||
{
|
||||
delete trigger;
|
||||
}
|
||||
|
||||
triggerNodes.clear();
|
||||
}
|
||||
|
||||
SET_AI_VALUE(GuidPosition, "rpg target", currentRpgTarget);
|
||||
|
||||
for (std::vector<TriggerNode*>::iterator i = triggerNodes.begin(); i != triggerNodes.end(); i++)
|
||||
{
|
||||
TriggerNode* trigger = *i;
|
||||
delete trigger;
|
||||
}
|
||||
if (!maxRelevance)
|
||||
return 0.0;
|
||||
|
||||
triggerNodes.clear();
|
||||
|
||||
return (maxRelevance - 1.0) * 1000.0f;
|
||||
return floor((maxRelevance - 1.0) * 1000.0f);
|
||||
}
|
||||
|
||||
bool ChooseRpgTargetAction::Execute(Event event)
|
||||
@@ -117,7 +155,7 @@ bool ChooseRpgTargetAction::Execute(Event event)
|
||||
|
||||
if (urand(0, 9))
|
||||
{
|
||||
for (auto target : ignoreList)
|
||||
for (auto target : ignoreList)
|
||||
targets.erase(target);
|
||||
}
|
||||
|
||||
@@ -188,7 +226,7 @@ bool ChooseRpgTargetAction::Execute(Event event)
|
||||
|
||||
if (targets.empty())
|
||||
{
|
||||
LOG_DEBUG("playerbots", "{} can't choose RPG target: all {} are not available", bot->GetName().c_str(), possibleTargets.size());
|
||||
LOG_DEBUG("playerbots", "{} can't choose RPG target: all {} targets are not available", bot->GetName().c_str(), possibleTargets.size());
|
||||
RESET_AI_VALUE(GuidSet&, "ignore rpg target");
|
||||
RESET_AI_VALUE(GuidPosition, "rpg target");
|
||||
return false;
|
||||
@@ -241,17 +279,20 @@ bool ChooseRpgTargetAction::isUseful()
|
||||
if (!botAI->AllowActivity(RPG_ACTIVITY))
|
||||
return false;
|
||||
|
||||
if (AI_VALUE(GuidPosition, "rpg target"))
|
||||
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
|
||||
|
||||
if (guidP && guidP.distance(bot) < sPlayerbotAIConfig->reactDistance * 2)
|
||||
return false;
|
||||
|
||||
TravelTarget* travelTarget = AI_VALUE(TravelTarget*, "travel target");
|
||||
|
||||
if (travelTarget->isTraveling() && isFollowValid(bot, *travelTarget->getPosition()))
|
||||
return false;
|
||||
//if (travelTarget->isTraveling() && AI_VALUE2(bool, "can free move to", *travelTarget->getPosition()))
|
||||
//return false;
|
||||
|
||||
if (AI_VALUE(GuidVector, "possible rpg targets").empty())
|
||||
return false;
|
||||
|
||||
//Not stay, not guard, not combat, not trading and group ready.
|
||||
if (!AI_VALUE(bool, "can move around"))
|
||||
return false;
|
||||
|
||||
@@ -310,7 +351,7 @@ bool ChooseRpgTargetAction::isFollowValid(Player* bot, WorldPosition pos)
|
||||
return true;
|
||||
|
||||
if (distance < formation->GetMaxDistance())
|
||||
return true;
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ class ChooseRpgTargetAction : public Action
|
||||
private:
|
||||
float getMaxRelevance(GuidPosition guidP);
|
||||
bool HasSameTarget(ObjectGuid guid, uint32 max, GuidVector const& nearGuids);
|
||||
|
||||
std::unordered_map <ObjectGuid, std::string> rgpActionReason;
|
||||
};
|
||||
|
||||
class ClearRpgTargetAction : public ChooseRpgTargetAction
|
||||
|
||||
@@ -9,16 +9,24 @@
|
||||
|
||||
bool ChooseTravelTargetAction::Execute(Event event)
|
||||
{
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
|
||||
//Get the current travel target. This target is no longer active.
|
||||
TravelTarget* oldTarget = context->GetValue<TravelTarget*>("travel target")->Get();
|
||||
|
||||
//Select a new target to travel to.
|
||||
//Select a new target to travel to.
|
||||
TravelTarget newTarget = TravelTarget(botAI);
|
||||
getNewTarget(&newTarget, oldTarget);
|
||||
|
||||
if (!oldTarget) return false;
|
||||
|
||||
if (!oldTarget->isForced() || oldTarget->getStatus() == TravelStatus::TRAVEL_STATUS_EXPIRED)
|
||||
getNewTarget(&newTarget, oldTarget);
|
||||
else
|
||||
newTarget.copyTarget(oldTarget);
|
||||
|
||||
//If the new target is not active we failed.
|
||||
if (!newTarget.isActive())
|
||||
return false;
|
||||
if (!newTarget.isActive() && !newTarget.isForced())
|
||||
return false;
|
||||
|
||||
setNewTarget(&newTarget, oldTarget);
|
||||
|
||||
@@ -36,6 +44,11 @@ void ChooseTravelTargetAction::getNewTarget(TravelTarget* newTarget, TravelTarge
|
||||
|
||||
foundTarget = SetGroupTarget(newTarget); //Join groups members
|
||||
|
||||
//Do quests (start, do, end)
|
||||
if (!foundTarget && urand(1, 100) > 5) //95% chance
|
||||
{
|
||||
foundTarget = SetQuestTarget(newTarget, false); //Do any nearby
|
||||
}
|
||||
//Enpty bags/repair
|
||||
if (!foundTarget && urand(1, 100) > 10) //90% chance
|
||||
if (AI_VALUE2(bool, "group or", "should sell,can sell,following party,near leader") || AI_VALUE2(bool, "group or", "should repair,can repair,following party,near leader"))
|
||||
@@ -53,9 +66,11 @@ void ChooseTravelTargetAction::getNewTarget(TravelTarget* newTarget, TravelTarge
|
||||
|
||||
if (!foundTarget)
|
||||
foundTarget = SetQuestTarget(newTarget); //Do low level quests
|
||||
} else if (urand(1, 100) > 50) {
|
||||
}
|
||||
else if (urand(1, 100) > 50) {
|
||||
foundTarget = SetGrindTarget(newTarget); //Go grind mobs for money
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
foundTarget = SetNewQuestTarget(newTarget); //Find a low level quest to do
|
||||
}
|
||||
}
|
||||
@@ -703,7 +718,7 @@ bool ChooseTravelTargetAction::SetNullTarget(TravelTarget* target)
|
||||
std::vector<std::string> split(std::string const s, char delim);
|
||||
char* strstri(char const* haystack, char const* needle);
|
||||
|
||||
TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::string const name)
|
||||
TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::string const name, bool zones, bool npcs, bool quests, bool mobs, bool bosses)
|
||||
{
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
|
||||
@@ -711,32 +726,54 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
||||
|
||||
std::vector<TravelDestination*> dests;
|
||||
|
||||
//Zones
|
||||
for (auto& d : sTravelMgr->getExploreTravelDestinations(bot, true, true))
|
||||
//Quests
|
||||
if (quests)
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
for (auto& d : sTravelMgr->getQuestTravelDestinations(bot, 0, true, true))
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
//Zones
|
||||
if (zones)
|
||||
{
|
||||
for (auto& d : sTravelMgr->getExploreTravelDestinations(bot, true, true))
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
//Npcs
|
||||
for (auto& d : sTravelMgr->getRpgTravelDestinations(bot, true, true))
|
||||
if (npcs)
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
for (auto& d : sTravelMgr->getRpgTravelDestinations(bot, true, true))
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
//Mobs
|
||||
for (auto& d : sTravelMgr->getGrindTravelDestinations(bot, true, true))
|
||||
if (mobs)
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
for (auto& d : sTravelMgr->getGrindTravelDestinations(bot, true, true, 5000.0f))
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
//Bosses
|
||||
for (auto& d : sTravelMgr->getBossTravelDestinations(bot, true, true))
|
||||
if (bosses)
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
for (auto& d : sTravelMgr->getBossTravelDestinations(bot, true, true))
|
||||
{
|
||||
if (strstri(d->getTitle().c_str(), name.c_str()))
|
||||
dests.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
WorldPosition botPos(bot);
|
||||
@@ -745,9 +782,9 @@ TravelDestination* ChooseTravelTargetAction::FindDestination(Player* bot, std::s
|
||||
return nullptr;
|
||||
|
||||
TravelDestination* dest = *std::min_element(dests.begin(), dests.end(), [botPos](TravelDestination* i, TravelDestination* j)
|
||||
{
|
||||
return i->distanceTo(const_cast<WorldPosition*>(&botPos)) < j->distanceTo(const_cast<WorldPosition*>(&botPos));
|
||||
});
|
||||
{
|
||||
return i->distanceTo(const_cast<WorldPosition*>(&botPos)) < j->distanceTo(const_cast<WorldPosition*>(&botPos));
|
||||
});
|
||||
|
||||
return dest;
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ class ChooseTravelTargetAction : public MovementAction
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
|
||||
static TravelDestination* FindDestination(Player* bot, std::string const name);
|
||||
static TravelDestination* FindDestination(Player* bot, std::string const name, bool zones = true, bool npcs = true, bool quests = true, bool mobs = true, bool bosses = true);
|
||||
|
||||
protected:
|
||||
void getNewTarget(TravelTarget* newTarget, TravelTarget* oldTarget);
|
||||
|
||||
@@ -101,10 +101,8 @@ void CleanQuestLogAction::DropQuestType(uint8& numQuest, uint8 wantNum, bool isG
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
if (quest->GetRequiredClasses() && (quest->GetRewSpellCast() || quest->GetRewSpell())) //Do not drop class specific quests that learn spells.
|
||||
continue;
|
||||
|
||||
if (quest->GetRequiredClasses() && (quest->GetRewSpellCast() || quest->GetRewSpell())) // Do not drop class specific quests that learn spells.
|
||||
// Do not drop class quest, may be not rewarding gold but important spells
|
||||
if (quest->GetRequiredClasses())
|
||||
continue;
|
||||
|
||||
if (wantNum == 100)
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "MovementActions.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
class TravelDestination;
|
||||
class WorldPosition;
|
||||
|
||||
class GoAction : public MovementAction
|
||||
{
|
||||
|
||||
@@ -14,8 +14,10 @@ void QueryQuestAction::TellObjective(std::string const name, uint32 available, u
|
||||
|
||||
bool QueryQuestAction::Execute(Event event)
|
||||
{
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
Player* bot = botAI->GetBot();
|
||||
WorldPosition botPos(bot);
|
||||
WorldPosition* ptr_botpos = &botPos;
|
||||
std::string text = event.getParam();
|
||||
bool travel = false;
|
||||
|
||||
@@ -28,7 +30,22 @@ bool QueryQuestAction::Execute(Event event)
|
||||
PlayerbotChatHandler ch(bot);
|
||||
uint32 questId = ch.extractQuestId(text);
|
||||
if (!questId)
|
||||
return false;
|
||||
{
|
||||
for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
|
||||
{
|
||||
uint32 logQuest = bot->GetQuestSlotQuestId(slot);
|
||||
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(logQuest);
|
||||
if (!quest)
|
||||
continue;
|
||||
|
||||
if (text.find(quest->GetTitle()) != std::string::npos)
|
||||
{
|
||||
questId = quest->GetQuestId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint16 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
|
||||
{
|
||||
@@ -55,10 +72,7 @@ bool QueryQuestAction::Execute(Event event)
|
||||
uint32 limit = 0;
|
||||
std::vector<TravelDestination*> allDestinations = sTravelMgr->getQuestTravelDestinations(bot, questId, true, true, -1);
|
||||
|
||||
std::sort(allDestinations.begin(), allDestinations.end(), [botPos](TravelDestination* i, TravelDestination* j)
|
||||
{
|
||||
return i->distanceTo(const_cast<WorldPosition*>(&botPos)) < j->distanceTo(const_cast<WorldPosition*>(&botPos));
|
||||
});
|
||||
std::sort(allDestinations.begin(), allDestinations.end(), [ptr_botpos](TravelDestination* i, TravelDestination* j) {return i->distanceTo(ptr_botpos) < j->distanceTo(ptr_botpos); });
|
||||
|
||||
for (auto dest : allDestinations)
|
||||
{
|
||||
@@ -71,24 +85,18 @@ bool QueryQuestAction::Execute(Event event)
|
||||
uint32 apoints = dest->getPoints().size();
|
||||
|
||||
|
||||
out << round(dest->distanceTo(const_cast<WorldPosition*>(&botPos)));
|
||||
out << " to " << dest->getTitle();
|
||||
out << " " << apoints;
|
||||
out << round(dest->distanceTo(&botPos));
|
||||
|
||||
out << " to " << dest->getTitle();
|
||||
|
||||
out << " " << apoints;
|
||||
if (apoints < tpoints)
|
||||
out << "/" << tpoints;
|
||||
|
||||
out << " points.";
|
||||
|
||||
if (!dest->isActive(bot))
|
||||
out << " not active";
|
||||
|
||||
if (dest->isFull(bot))
|
||||
out << " crowded";
|
||||
|
||||
if (dest->isFull(bot))
|
||||
out << " crowded";
|
||||
|
||||
botAI->TellMaster(out);
|
||||
|
||||
limit++;
|
||||
|
||||
@@ -7,27 +7,48 @@
|
||||
#include "ChatHelper.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ServerFacade.h"
|
||||
|
||||
bool QuestAction::Execute(Event event)
|
||||
{
|
||||
ObjectGuid guid = event.getObject();
|
||||
|
||||
Player* master = GetMaster();
|
||||
if (!master)
|
||||
{
|
||||
if (!guid)
|
||||
guid = bot->GetTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!guid)
|
||||
guid = master->GetTarget();
|
||||
}
|
||||
|
||||
if (!guid)
|
||||
return false;
|
||||
{
|
||||
if (!master)
|
||||
{
|
||||
guid = bot->GetTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
guid = master->GetTarget();
|
||||
}
|
||||
}
|
||||
|
||||
return ProcessQuests(guid);
|
||||
if (guid)
|
||||
{
|
||||
return ProcessQuests(guid);
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
|
||||
for (const auto npc : npcs)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(npc);
|
||||
if (unit && bot->GetDistance(unit) <= INTERACTION_DISTANCE)
|
||||
result |= ProcessQuests(unit);
|
||||
}
|
||||
std::list<ObjectGuid> gos = AI_VALUE(std::list<ObjectGuid>, "nearest game objects");
|
||||
for (const auto go : gos)
|
||||
{
|
||||
GameObject* gameobj = botAI->GetGameObject(go);
|
||||
if (gameobj && bot->GetDistance(gameobj) <= INTERACTION_DISTANCE)
|
||||
result |= ProcessQuests(gameobj);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QuestAction::CompleteQuest(Player* player, uint32 entry)
|
||||
@@ -67,7 +88,15 @@ bool QuestAction::CompleteQuest(Player* player, uint32 entry)
|
||||
int32 creature = pQuest->RequiredNpcOrGo[i];
|
||||
uint32 creaturecount = pQuest->RequiredNpcOrGoCount[i];
|
||||
|
||||
if (creature > 0)
|
||||
// TODO check if we need a REQSPELL condition, this methods and sql entry dosent seem implemented ?
|
||||
/*if (uint32 spell_id = pQuest->GetReqSpell[i])
|
||||
{
|
||||
for (uint16 z = 0; z < creaturecount; ++z)
|
||||
{
|
||||
player->CastedCreatureOrGO(creature, ObjectGuid(), spell_id);
|
||||
}
|
||||
}*/
|
||||
/*else*/ if (creature > 0)
|
||||
{
|
||||
if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature))
|
||||
for (uint16 z = 0; z < creaturecount; ++z)
|
||||
@@ -127,6 +156,8 @@ bool QuestAction::ProcessQuests(WorldObject* questGiver)
|
||||
|
||||
if (bot->GetDistance(questGiver) > INTERACTION_DISTANCE && !sPlayerbotAIConfig->syncQuestWithPlayer)
|
||||
{
|
||||
//if (botAI->HasStrategy("debug", BotState::BOT_STATE_COMBAT) || botAI->HasStrategy("debug", BotState::BOT_STATE_NON_COMBAT))
|
||||
|
||||
botAI->TellError("Cannot talk to quest giver");
|
||||
return false;
|
||||
}
|
||||
@@ -160,16 +191,16 @@ bool QuestAction::AcceptQuest(Quest const* quest, ObjectGuid questGiver)
|
||||
|
||||
if (bot->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
|
||||
out << "Already completed";
|
||||
else if (! bot->CanTakeQuest(quest, false))
|
||||
else if (!bot->CanTakeQuest(quest, false))
|
||||
{
|
||||
if (! bot->SatisfyQuestStatus(quest, false))
|
||||
if (!bot->SatisfyQuestStatus(quest, false))
|
||||
out << "Already on";
|
||||
else
|
||||
out << "Can't take";
|
||||
}
|
||||
else if (! bot->SatisfyQuestLog(false))
|
||||
else if (!bot->SatisfyQuestLog(false))
|
||||
out << "Quest log is full";
|
||||
else if (! bot->CanAddQuest(quest, false))
|
||||
else if (!bot->CanAddQuest(quest, false))
|
||||
out << "Bags are full";
|
||||
else
|
||||
{
|
||||
@@ -179,7 +210,7 @@ bool QuestAction::AcceptQuest(Quest const* quest, ObjectGuid questGiver)
|
||||
p.rpos(0);
|
||||
bot->GetSession()->HandleQuestgiverAcceptQuestOpcode(p);
|
||||
|
||||
if (bot->GetQuestStatus(questId ) == QUEST_STATUS_NONE && sPlayerbotAIConfig->syncQuestWithPlayer)
|
||||
if (bot->GetQuestStatus(questId) == QUEST_STATUS_NONE && sPlayerbotAIConfig->syncQuestWithPlayer)
|
||||
{
|
||||
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*bot, questGiver, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM);
|
||||
bot->AddQuest(quest, pObject);
|
||||
@@ -196,10 +227,11 @@ bool QuestAction::AcceptQuest(Quest const* quest, ObjectGuid questGiver)
|
||||
|
||||
out << " " << chat->FormatQuest(quest);
|
||||
botAI->TellMaster(out);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestObjectiveCompletedAction::Execute(Event event)
|
||||
bool QuestUpdateCompleteAction::Execute(Event event)
|
||||
{
|
||||
WorldPacket p(event.getPacket());
|
||||
p.rpos(0);
|
||||
@@ -208,17 +240,84 @@ bool QuestObjectiveCompletedAction::Execute(Event event)
|
||||
ObjectGuid guid;
|
||||
p >> questId >> entry >> available >> required >> guid;
|
||||
|
||||
if (entry & 0x80000000)
|
||||
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (qInfo)
|
||||
{
|
||||
entry &= 0x7FFFFFFF;
|
||||
if (GameObjectTemplate const* info = sObjectMgr->GetGameObjectTemplate(entry))
|
||||
botAI->TellMaster(chat->FormatQuestObjective(info->name, available, required));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CreatureTemplate const* info = sObjectMgr->GetCreatureTemplate(entry))
|
||||
botAI->TellMaster(chat->FormatQuestObjective(info->Name, available, required));
|
||||
if (botAI->HasStrategy("debug quest", BotState::BOT_STATE_NON_COMBAT) || botAI->HasStrategy("debug rpg", BotState::BOT_STATE_COMBAT))
|
||||
{
|
||||
bot->Say("Quest [ " + ChatHelper::FormatQuest(qInfo) + " ] completed", LANG_UNIVERSAL);
|
||||
}
|
||||
botAI->TellMasterNoFacing("Quest completed " + ChatHelper::FormatQuest(qInfo));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* For creature or gameobject
|
||||
*/
|
||||
bool QuestUpdateAddKillAction::Execute(Event event)
|
||||
{
|
||||
WorldPacket p(event.getPacket());
|
||||
p.rpos(0);
|
||||
|
||||
uint32 entry, questId, available, required;
|
||||
ObjectGuid guid;
|
||||
p >> questId >> entry >> available >> required >> guid;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Update progression kill questid {" << std::to_string(questId) << "} {" << std::to_string(available) << "} / {" << std::to_string(required) << "}";
|
||||
botAI->TellMasterNoFacing(ss.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestUpdateAddItemAction::Execute(Event event)
|
||||
{
|
||||
WorldPacket p(event.getPacket());
|
||||
p.rpos(0);
|
||||
|
||||
uint32 itemId, count;
|
||||
p >> itemId >> count;
|
||||
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
auto const* itemPrototype = sObjectMgr->GetItemTemplate(itemId);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Update progression itemid {" << std::to_string(itemId) << "} count: {" << std::to_string(count) << "}";
|
||||
botAI->TellMasterNoFacing(ss.str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestUpdateFailedAction::Execute(Event event)
|
||||
{
|
||||
//opcode SMSG_QUESTUPDATE_FAILED is never sent...(yet?)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestUpdateFailedTimerAction::Execute(Event event)
|
||||
{
|
||||
WorldPacket p(event.getPacket());
|
||||
p.rpos(0);
|
||||
|
||||
uint32 questId;
|
||||
p >> questId;
|
||||
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
|
||||
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
|
||||
|
||||
if (qInfo)
|
||||
{
|
||||
botAI->TellMaster("Failed timer for " + botAI->GetChatHelper()->FormatQuest(qInfo) +", abandoning");
|
||||
}
|
||||
else
|
||||
{
|
||||
botAI->TellMaster("Failed timer for " + std::to_string(questId));
|
||||
}
|
||||
|
||||
//drop quest
|
||||
bot->AbandonQuest(questId);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "Action.h"
|
||||
#include "Object.h"
|
||||
#include "QuestDef.h"
|
||||
|
||||
class ObjectGuid;
|
||||
class Quest;
|
||||
@@ -17,25 +18,52 @@ class Object;
|
||||
|
||||
class QuestAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name) { }
|
||||
public:
|
||||
QuestAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name) { }
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool Execute(Event event) override;
|
||||
|
||||
protected:
|
||||
bool CompleteQuest(Player* player, uint32 entry);
|
||||
virtual void ProcessQuest(Quest const* quest, Object* questGiver) = 0;
|
||||
bool AcceptQuest(Quest const* quest, ObjectGuid questGiver);
|
||||
bool ProcessQuests(ObjectGuid questGiver);
|
||||
bool ProcessQuests(WorldObject* questGiver);
|
||||
protected:
|
||||
bool CompleteQuest(Player* player, uint32 entry);
|
||||
virtual bool ProcessQuest(Quest const* quest, Object* questGiver) = 0;
|
||||
bool AcceptQuest(Quest const* quest, ObjectGuid questGiver);
|
||||
bool ProcessQuests(ObjectGuid questGiver);
|
||||
bool ProcessQuests(WorldObject* questGiver);
|
||||
};
|
||||
|
||||
class QuestObjectiveCompletedAction : public Action
|
||||
class QuestUpdateCompleteAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestObjectiveCompletedAction(PlayerbotAI* botAI) : Action(botAI, "quest objective completed") { }
|
||||
public:
|
||||
QuestUpdateCompleteAction(PlayerbotAI* ai) : Action(ai, "quest update complete") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
bool Execute(Event event) override;
|
||||
class QuestUpdateAddKillAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestUpdateAddKillAction(PlayerbotAI* ai) : Action(ai, "quest update add kill") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class QuestUpdateAddItemAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestUpdateAddItemAction(PlayerbotAI* ai) : Action(ai, "quest update add item") {}
|
||||
bool Execute(Event event) override;;
|
||||
};
|
||||
|
||||
class QuestUpdateFailedAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestUpdateFailedAction(PlayerbotAI* ai) : Action(ai, "quest update failed") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class QuestUpdateFailedTimerAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestUpdateFailedTimerAction(PlayerbotAI* ai) : Action(ai, "quest update failed timer") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "QuestConfirmAcceptAction.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
bool QuestConfirmAcceptAction::Execute(Event event)
|
||||
{
|
||||
WorldPacket packet(event.getPacket());
|
||||
uint32 questId;
|
||||
packet >> questId;
|
||||
|
||||
WorldPacket sendPacket(CMSG_QUEST_CONFIRM_ACCEPT);
|
||||
sendPacket << questId;
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (!quest || !bot->CanAddQuest(quest, true)) {
|
||||
return false;
|
||||
}
|
||||
std::ostringstream out;
|
||||
out << "Quest: " << chat->FormatQuest(quest) << " confirm accept";
|
||||
botAI->TellMaster(out);
|
||||
bot->GetSession()->HandleQuestConfirmAccept(sendPacket);
|
||||
return true;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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_QUESTCONFIRMACCEPTACTION_H
|
||||
#define _PLAYERBOT_QUESTCONFIRMACCEPTACTION_H
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "QuestAction.h"
|
||||
#include "Player.h"
|
||||
|
||||
class ObjectGuid;
|
||||
class Quest;
|
||||
class Player;
|
||||
class PlayerbotAI;
|
||||
class WorldObject;
|
||||
|
||||
class QuestConfirmAcceptAction : public Action
|
||||
{
|
||||
public:
|
||||
QuestConfirmAcceptAction(PlayerbotAI* botAI) : Action(botAI, "quest confirm accept") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Formations.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "RpgSubActions.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
@@ -45,65 +46,109 @@ bool RpgAction::isUseful()
|
||||
|
||||
bool RpgAction::SetNextRpgAction()
|
||||
{
|
||||
Strategy* rpgStrategy = botAI->GetAiObjectContext()->GetStrategy("rpg");
|
||||
|
||||
Strategy* rpgStrategy;
|
||||
std::vector<Action*> actions;
|
||||
std::vector<uint32> relevances;
|
||||
std::vector<TriggerNode*> triggerNodes;
|
||||
rpgStrategy->InitTriggers(triggerNodes);
|
||||
|
||||
for (auto& triggerNode : triggerNodes)
|
||||
|
||||
for (auto& strategy : botAI->GetAiObjectContext()->GetSupportedStrategies())
|
||||
{
|
||||
Trigger* trigger = context->GetTrigger(triggerNode->getName());
|
||||
if (trigger)
|
||||
if (strategy.find("rpg") == std::string::npos)
|
||||
continue;
|
||||
|
||||
rpgStrategy = botAI->GetAiObjectContext()->GetStrategy(strategy);
|
||||
|
||||
rpgStrategy->InitTriggers(triggerNodes);
|
||||
|
||||
for (auto& triggerNode : triggerNodes)
|
||||
{
|
||||
triggerNode->setTrigger(trigger);
|
||||
Trigger* trigger = context->GetTrigger(triggerNode->getName());
|
||||
|
||||
NextAction** nextActions = triggerNode->getHandlers();
|
||||
|
||||
trigger = triggerNode->getTrigger();
|
||||
|
||||
bool isChecked = false;
|
||||
for (int32 i = 0; i < NextAction::size(nextActions); i++)
|
||||
if (trigger)
|
||||
{
|
||||
NextAction* nextAction = nextActions[i];
|
||||
|
||||
if (nextAction->getRelevance() > 2.0f)
|
||||
continue;
|
||||
triggerNode->setTrigger(trigger);
|
||||
|
||||
if (!isChecked && !trigger->IsActive())
|
||||
break;
|
||||
NextAction** nextActions = triggerNode->getHandlers();
|
||||
|
||||
isChecked = true;
|
||||
Trigger* trigger = triggerNode->getTrigger();
|
||||
|
||||
Action* action = botAI->GetAiObjectContext()->GetAction(nextAction->getName());
|
||||
bool isChecked = false;
|
||||
|
||||
if (!action->isPossible() || !action->isUseful())
|
||||
continue;
|
||||
for (int32 i = 0; i < NextAction::size(nextActions); i++)
|
||||
{
|
||||
NextAction* nextAction = nextActions[i];
|
||||
|
||||
actions.push_back(action);
|
||||
relevances.push_back((nextAction->getRelevance() - 1) * 1000);
|
||||
if (nextAction->getRelevance() > 2.0f)
|
||||
continue;
|
||||
|
||||
if (!isChecked && !trigger->IsActive())
|
||||
break;
|
||||
|
||||
isChecked = true;
|
||||
|
||||
Action* action = botAI->GetAiObjectContext()->GetAction(nextAction->getName());
|
||||
if (!dynamic_cast<RpgEnabled*>(action) || !action->isPossible() || !action->isUseful())
|
||||
continue;
|
||||
|
||||
actions.push_back(action);
|
||||
relevances.push_back((nextAction->getRelevance() - 1) * 1000);
|
||||
}
|
||||
NextAction::destroy(nextActions);
|
||||
}
|
||||
|
||||
NextAction::destroy(nextActions);
|
||||
}
|
||||
|
||||
for (const auto i : triggerNodes)
|
||||
{
|
||||
delete i;
|
||||
}
|
||||
triggerNodes.clear();
|
||||
}
|
||||
|
||||
if (actions.empty())
|
||||
return false;
|
||||
|
||||
if (botAI->HasStrategy("debug rpg", BotState::BOT_STATE_NON_COMBAT))
|
||||
{
|
||||
std::vector<std::pair<Action*, uint32>> sortedActions;
|
||||
|
||||
for (int i = 0; i < actions.size(); i++)
|
||||
sortedActions.push_back(std::make_pair(actions[i], relevances[i]));
|
||||
|
||||
std::sort(sortedActions.begin(), sortedActions.end(), [](std::pair<Action*, uint32>i, std::pair<Action*, uint32> j) {return i.second > j.second; });
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "------" << chat->FormatWorldobject(AI_VALUE(GuidPosition, "rpg target").GetWorldObject()) << "------";
|
||||
bot->Say(ss.str(), LANG_UNIVERSAL);
|
||||
botAI->TellMasterNoFacing(ss.str());
|
||||
|
||||
for (auto action : sortedActions)
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
||||
out << " " << action.first->getName() << " " << action.second;
|
||||
|
||||
botAI->TellMasterNoFacing(out);
|
||||
}
|
||||
}
|
||||
|
||||
std::mt19937 gen(time(0));
|
||||
|
||||
sTravelMgr->weighted_shuffle(actions.begin(), actions.end(), relevances.begin(), relevances.end(), gen);
|
||||
|
||||
Action* action = actions.front();
|
||||
|
||||
for (std::vector<TriggerNode*>::iterator i = triggerNodes.begin(); i != triggerNodes.end(); i++)
|
||||
if ((botAI->HasStrategy("debug", BotState::BOT_STATE_NON_COMBAT) || botAI->HasStrategy("debug rpg", BotState::BOT_STATE_NON_COMBAT)))
|
||||
{
|
||||
TriggerNode* trigger = *i;
|
||||
delete trigger;
|
||||
}
|
||||
std::ostringstream out;
|
||||
out << "do: ";
|
||||
out << chat->FormatWorldobject(AI_VALUE(GuidPosition, "rpg target").GetWorldObject());
|
||||
|
||||
triggerNodes.clear();
|
||||
out << " " << action->getName();
|
||||
|
||||
botAI->TellMasterNoFacing(out);
|
||||
}
|
||||
|
||||
SET_AI_VALUE(std::string, "next rpg action", action->getName());
|
||||
|
||||
|
||||
@@ -13,28 +13,28 @@ class Unit;
|
||||
|
||||
class RpgAction : public MovementAction
|
||||
{
|
||||
public:
|
||||
RpgAction(PlayerbotAI* botAI, std::string const name = "rpg") : MovementAction(botAI, name) { }
|
||||
public:
|
||||
RpgAction(PlayerbotAI* botAI, std::string const name = "rpg") : MovementAction(botAI, name) { }
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
|
||||
protected:
|
||||
virtual bool SetNextRpgAction();
|
||||
protected:
|
||||
virtual bool SetNextRpgAction();
|
||||
|
||||
typedef void (RpgAction::*RpgElement)(ObjectGuid guid);
|
||||
typedef void (RpgAction::* RpgElement)(ObjectGuid guid);
|
||||
|
||||
bool AddIgnore(ObjectGuid guid);
|
||||
bool RemIgnore(ObjectGuid guid);
|
||||
bool HasIgnore(ObjectGuid guid);
|
||||
bool AddIgnore(ObjectGuid guid);
|
||||
bool RemIgnore(ObjectGuid guid);
|
||||
bool HasIgnore(ObjectGuid guid);
|
||||
};
|
||||
|
||||
class CRpgAction : public RpgAction
|
||||
{
|
||||
public:
|
||||
CRpgAction(PlayerbotAI* botAI) : RpgAction(botAI, "crpg") { }
|
||||
public:
|
||||
CRpgAction(PlayerbotAI* botAI) : RpgAction(botAI, "crpg") { }
|
||||
|
||||
bool isUseful() override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
#include "QuestDef.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
void TalkToQuestGiverAction::ProcessQuest(Quest const* quest, Object* questGiver)
|
||||
bool TalkToQuestGiverAction::ProcessQuest(Quest const* quest, Object* questGiver)
|
||||
{
|
||||
bool isCompleted = false;
|
||||
std::ostringstream out;
|
||||
out << "Quest ";
|
||||
|
||||
@@ -26,7 +27,7 @@ void TalkToQuestGiverAction::ProcessQuest(Quest const* quest, Object* questGiver
|
||||
{
|
||||
QuestStatus masterStatus = master->GetQuestStatus(quest->GetQuestId());
|
||||
if (masterStatus == QUEST_STATUS_INCOMPLETE || masterStatus == QUEST_STATUS_FAILED)
|
||||
CompleteQuest(master, quest->GetQuestId());
|
||||
isCompleted |= CompleteQuest(master, quest->GetQuestId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,39 +35,42 @@ void TalkToQuestGiverAction::ProcessQuest(Quest const* quest, Object* questGiver
|
||||
{
|
||||
if (master && master->GetQuestStatus(quest->GetQuestId()) == QUEST_STATUS_COMPLETE && (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_FAILED))
|
||||
{
|
||||
CompleteQuest(bot, quest->GetQuestId());
|
||||
isCompleted |= CompleteQuest(bot, quest->GetQuestId());
|
||||
status = bot->GetQuestStatus(quest->GetQuestId());
|
||||
}
|
||||
}
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case QUEST_STATUS_COMPLETE:
|
||||
TurnInQuest(quest, questGiver, out);
|
||||
break;
|
||||
case QUEST_STATUS_INCOMPLETE:
|
||||
out << "|cffff0000Incompleted|r";
|
||||
break;
|
||||
case QUEST_STATUS_NONE:
|
||||
out << "|cff00ff00Available|r";
|
||||
break;
|
||||
case QUEST_STATUS_FAILED:
|
||||
out << "|cffff0000Failed|r";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QUEST_STATUS_COMPLETE:
|
||||
isCompleted |= TurnInQuest(quest, questGiver, out);
|
||||
break;
|
||||
case QUEST_STATUS_INCOMPLETE:
|
||||
out << "|cffff0000Incompleted|r";
|
||||
break;
|
||||
case QUEST_STATUS_NONE:
|
||||
AcceptQuest(quest, questGiver->GetGUID());
|
||||
out << "|cff00ff00Available|r";
|
||||
break;
|
||||
case QUEST_STATUS_FAILED:
|
||||
out << "|cffff0000Failed|r";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out << ": " << chat->FormatQuest(quest);
|
||||
botAI->TellMaster(out);
|
||||
|
||||
return isCompleted;
|
||||
}
|
||||
|
||||
void TalkToQuestGiverAction::TurnInQuest(Quest const* quest, Object* questGiver, std::ostringstream& out)
|
||||
bool TalkToQuestGiverAction::TurnInQuest(Quest const* quest, Object* questGiver, std::ostringstream& out)
|
||||
{
|
||||
uint32 questID = quest->GetQuestId();
|
||||
|
||||
if (bot->GetQuestRewardStatus(questID))
|
||||
return;
|
||||
return false;
|
||||
|
||||
bot->PlayDistanceSound(621);
|
||||
|
||||
@@ -78,6 +82,8 @@ void TalkToQuestGiverAction::TurnInQuest(Quest const* quest, Object* questGiver,
|
||||
{
|
||||
RewardMultipleItem(quest, questGiver, out);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TalkToQuestGiverAction::RewardNoItem(Quest const* quest, Object* questGiver, std::ostringstream& out)
|
||||
@@ -244,26 +250,26 @@ bool TurnInQueryQuestAction::Execute(Event event)
|
||||
out << "Quest ";
|
||||
switch (status)
|
||||
{
|
||||
case QUEST_STATUS_COMPLETE:
|
||||
TurnInQuest(quest, object, out);
|
||||
break;
|
||||
case QUEST_STATUS_INCOMPLETE:
|
||||
out << "|cffff0000Incompleted|r";
|
||||
break;
|
||||
case QUEST_STATUS_NONE:
|
||||
out << "|cff00ff00Available|r";
|
||||
break;
|
||||
case QUEST_STATUS_FAILED:
|
||||
out << "|cffff0000Failed|r";
|
||||
break;
|
||||
case QUEST_STATUS_REWARDED:
|
||||
out << "|cffff0000Rewarded|r";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QUEST_STATUS_COMPLETE:
|
||||
TurnInQuest(quest, object, out);
|
||||
break;
|
||||
case QUEST_STATUS_INCOMPLETE:
|
||||
out << "|cffff0000Incompleted|r";
|
||||
break;
|
||||
case QUEST_STATUS_NONE:
|
||||
out << "|cff00ff00Available|r";
|
||||
break;
|
||||
case QUEST_STATUS_FAILED:
|
||||
out << "|cffff0000Failed|r";
|
||||
break;
|
||||
case QUEST_STATUS_REWARDED:
|
||||
out << "|cffff0000Rewarded|r";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out << ": " << chat->FormatQuest(quest);
|
||||
botAI->TellMaster(out);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,25 +13,25 @@ class WorldObject;
|
||||
|
||||
class TalkToQuestGiverAction : public QuestAction
|
||||
{
|
||||
public:
|
||||
TalkToQuestGiverAction(PlayerbotAI* botAI, std::string name = "talk to quest giver") : QuestAction(botAI, name) { }
|
||||
public:
|
||||
TalkToQuestGiverAction(PlayerbotAI* botAI, std::string name = "talk to quest giver") : QuestAction(botAI, name) { }
|
||||
|
||||
protected:
|
||||
void ProcessQuest(Quest const* quest, Object* questGiver) override;
|
||||
void TurnInQuest(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
protected:
|
||||
bool ProcessQuest(Quest const* quest, Object* questGiver) override;
|
||||
bool TurnInQuest(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
|
||||
private:
|
||||
void RewardNoItem(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
void RewardSingleItem(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
std::set<uint32> BestRewards(Quest const* quest);
|
||||
void RewardMultipleItem(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
void AskToSelectReward(Quest const* quest, std::ostringstream& out, bool forEquip);
|
||||
private:
|
||||
void RewardNoItem(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
void RewardSingleItem(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
std::set<uint32> BestRewards(Quest const* quest);
|
||||
void RewardMultipleItem(Quest const* quest, Object* questGiver, std::ostringstream& out);
|
||||
void AskToSelectReward(Quest const* quest, std::ostringstream& out, bool forEquip);
|
||||
};
|
||||
|
||||
class TurnInQueryQuestAction : public TalkToQuestGiverAction
|
||||
{
|
||||
public:
|
||||
TurnInQueryQuestAction(PlayerbotAI* botAI) : TalkToQuestGiverAction(botAI, "turn in query quest") {}
|
||||
bool Execute(Event event) override;
|
||||
public:
|
||||
TurnInQueryQuestAction(PlayerbotAI* botAI) : TalkToQuestGiverAction(botAI, "turn in query quest") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -463,13 +463,10 @@ bool UseRandomQuestItem::Execute(Event event)
|
||||
ObjectGuid goTarget;
|
||||
|
||||
std::vector<Item*> questItems = AI_VALUE2(std::vector<Item*>, "inventory items", "quest");
|
||||
|
||||
Item* item = nullptr;
|
||||
uint32 delay = 0;
|
||||
|
||||
if (questItems.empty())
|
||||
return false;
|
||||
|
||||
Item* item = nullptr;
|
||||
for (uint8 i = 0; i < 5; i++)
|
||||
{
|
||||
auto itr = questItems.begin();
|
||||
@@ -477,7 +474,6 @@ bool UseRandomQuestItem::Execute(Event event)
|
||||
Item* questItem = *itr;
|
||||
|
||||
ItemTemplate const* proto = questItem->GetTemplate();
|
||||
|
||||
if (proto->StartQuest)
|
||||
{
|
||||
Quest const* qInfo = sObjectMgr->GetQuestTemplate(proto->StartQuest);
|
||||
@@ -488,61 +484,14 @@ bool UseRandomQuestItem::Execute(Event event)
|
||||
}
|
||||
}
|
||||
|
||||
uint32 spellId = proto->Spells[0].SpellId;
|
||||
if (spellId)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
|
||||
GuidVector npcs = AI_VALUE(GuidVector, ("nearest npcs"));
|
||||
for (auto& npc : npcs)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(npc);
|
||||
if (botAI->CanCastSpell(spellId, unit, false))
|
||||
{
|
||||
item = questItem;
|
||||
unitTarget = unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GuidVector gos = AI_VALUE(GuidVector, ("nearest game objects"));
|
||||
for (auto& go : gos)
|
||||
{
|
||||
GameObject* gameObject = botAI->GetGameObject(go);
|
||||
GameObjectTemplate const* goInfo = gameObject->GetGOInfo();
|
||||
if (!goInfo->GetLockId())
|
||||
continue;
|
||||
|
||||
LockEntry const* lock = sLockStore.LookupEntry(goInfo->GetLockId());
|
||||
for (uint8 i = 0; i < MAX_LOCK_CASE; ++i)
|
||||
{
|
||||
if (!lock->Type[i])
|
||||
continue;
|
||||
if (lock->Type[i] != LOCK_KEY_ITEM)
|
||||
continue;
|
||||
|
||||
if (lock->Index[i] == proto->ItemId)
|
||||
{
|
||||
item = questItem;
|
||||
goTarget = go;
|
||||
unitTarget = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
if (!goTarget && !unitTarget)
|
||||
return false;
|
||||
|
||||
bool used = UseItem(item, goTarget, nullptr, unitTarget);
|
||||
|
||||
if (used)
|
||||
botAI->SetNextCheckDelay(delay);
|
||||
botAI->SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "QuestAction.h"
|
||||
#include "PassLeadershipToMasterAction.h"
|
||||
#include "PetitionSignAction.h"
|
||||
#include "QuestConfirmAcceptAction.h"
|
||||
#include "ReadyCheckAction.h"
|
||||
#include "RememberTaxiAction.h"
|
||||
#include "ReviveFromCorpseAction.h"
|
||||
@@ -37,116 +36,131 @@
|
||||
#include "TradeStatusAction.h"
|
||||
#include "UseMeetingStoneAction.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "QuestConfirmAcceptAction.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class WorldPacketActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
WorldPacketActionContext()
|
||||
{
|
||||
creators["accept invitation"] = &WorldPacketActionContext::accept_invitation;
|
||||
creators["give leader in dungeon"] = &WorldPacketActionContext::give_leader_in_dungeon;
|
||||
creators["leader"] = &WorldPacketActionContext::pass_leadership_to_master;
|
||||
creators["tell not enough money"] = &WorldPacketActionContext::tell_not_enough_money;
|
||||
creators["tell not enough reputation"] = &WorldPacketActionContext::tell_not_enough_reputation;
|
||||
creators["tell cannot equip"] = &WorldPacketActionContext::tell_cannot_equip;
|
||||
creators["talk to quest giver"] = &WorldPacketActionContext::turn_in_quest;
|
||||
creators["accept quest"] = &WorldPacketActionContext::accept_quest;
|
||||
creators["accept all quests"] = &WorldPacketActionContext::accept_all_quests;
|
||||
creators["accept quest share"] = &WorldPacketActionContext::accept_quest_share;
|
||||
creators["loot roll"] = &WorldPacketActionContext::loot_roll;
|
||||
creators["master loot roll"] = &WorldPacketActionContext::master_loot_roll;
|
||||
creators["revive from corpse"] = &WorldPacketActionContext::revive_from_corpse;
|
||||
creators["find corpse"] = &WorldPacketActionContext::find_corpse;
|
||||
creators["auto release"] = &WorldPacketActionContext::auto_release;
|
||||
creators["accept resurrect"] = &WorldPacketActionContext::accept_resurrect;
|
||||
creators["use meeting stone"] = &WorldPacketActionContext::use_meeting_stone;
|
||||
creators["area trigger"] = &WorldPacketActionContext::area_trigger;
|
||||
creators["reach area trigger"] = &WorldPacketActionContext::reach_area_trigger;
|
||||
creators["check mount state"] = &WorldPacketActionContext::check_mount_state;
|
||||
creators["remember taxi"] = &WorldPacketActionContext::remember_taxi;
|
||||
creators["accept trade"] = &WorldPacketActionContext::accept_trade;
|
||||
creators["store loot"] = &WorldPacketActionContext::store_loot;
|
||||
creators["quest objective completed"] = &WorldPacketActionContext::quest_objective_completed;
|
||||
creators["party command"] = &WorldPacketActionContext::party_command;
|
||||
creators["tell cast failed"] = &WorldPacketActionContext::tell_cast_failed;
|
||||
creators["accept duel"] = &WorldPacketActionContext::accept_duel;
|
||||
creators["ready check"] = &WorldPacketActionContext::ready_check;
|
||||
creators["ready check finished"] = &WorldPacketActionContext::ready_check_finished;
|
||||
creators["uninvite"] = &WorldPacketActionContext::uninvite;
|
||||
creators["security check"] = &WorldPacketActionContext::security_check;
|
||||
creators["guild accept"] = &WorldPacketActionContext::guild_accept;
|
||||
creators["inventory change failure"] = &WorldPacketActionContext::inventory_change_failure;
|
||||
creators["bg status check"] = &WorldPacketActionContext::bg_status_check;
|
||||
creators["bg strategy check"] = &WorldPacketActionContext::bg_strategy_check;
|
||||
creators["bg status"] = &WorldPacketActionContext::bg_status;
|
||||
creators["bg join"] = &WorldPacketActionContext::bg_join;
|
||||
creators["bg leave"] = &WorldPacketActionContext::bg_leave;
|
||||
creators["arena tactics"] = &WorldPacketActionContext::arena_tactics;
|
||||
creators["petition sign"] = &WorldPacketActionContext::petition_sign;
|
||||
creators["lfg join"] = &WorldPacketActionContext::lfg_join;
|
||||
creators["lfg accept"] = &WorldPacketActionContext::lfg_accept;
|
||||
creators["lfg role check"] = &WorldPacketActionContext::lfg_role_check;
|
||||
creators["lfg leave"] = &WorldPacketActionContext::lfg_leave;
|
||||
creators["lfg teleport"] = &WorldPacketActionContext::lfg_teleport;
|
||||
creators["see spell"] = &WorldPacketActionContext::see_spell;
|
||||
creators["arena team accept"] = &WorldPacketActionContext::arena_team_accept;
|
||||
creators["turn in query quest"] = &WorldPacketActionContext::turn_in_query_quest;
|
||||
creators["quest confirm accept"] = &WorldPacketActionContext::quest_confirm_accept;
|
||||
}
|
||||
public:
|
||||
WorldPacketActionContext()
|
||||
{
|
||||
creators["accept invitation"] = &WorldPacketActionContext::accept_invitation;
|
||||
creators["give leader in dungeon"] = &WorldPacketActionContext::give_leader_in_dungeon;
|
||||
creators["leader"] = &WorldPacketActionContext::pass_leadership_to_master;
|
||||
creators["tell not enough money"] = &WorldPacketActionContext::tell_not_enough_money;
|
||||
creators["tell not enough reputation"] = &WorldPacketActionContext::tell_not_enough_reputation;
|
||||
creators["tell cannot equip"] = &WorldPacketActionContext::tell_cannot_equip;
|
||||
creators["loot roll"] = &WorldPacketActionContext::loot_roll;
|
||||
creators["master loot roll"] = &WorldPacketActionContext::master_loot_roll;
|
||||
creators["revive from corpse"] = &WorldPacketActionContext::revive_from_corpse;
|
||||
creators["find corpse"] = &WorldPacketActionContext::find_corpse;
|
||||
creators["auto release"] = &WorldPacketActionContext::auto_release;
|
||||
creators["accept resurrect"] = &WorldPacketActionContext::accept_resurrect;
|
||||
creators["use meeting stone"] = &WorldPacketActionContext::use_meeting_stone;
|
||||
creators["area trigger"] = &WorldPacketActionContext::area_trigger;
|
||||
creators["reach area trigger"] = &WorldPacketActionContext::reach_area_trigger;
|
||||
creators["check mount state"] = &WorldPacketActionContext::check_mount_state;
|
||||
creators["remember taxi"] = &WorldPacketActionContext::remember_taxi;
|
||||
creators["accept trade"] = &WorldPacketActionContext::accept_trade;
|
||||
creators["store loot"] = &WorldPacketActionContext::store_loot;
|
||||
|
||||
private:
|
||||
static Action* inventory_change_failure(PlayerbotAI* botAI) { return new InventoryChangeFailureAction(botAI); }
|
||||
static Action* guild_accept(PlayerbotAI* botAI) { return new GuildAcceptAction(botAI); }
|
||||
static Action* security_check(PlayerbotAI* botAI) { return new SecurityCheckAction(botAI); }
|
||||
static Action* uninvite(PlayerbotAI* botAI) { return new UninviteAction(botAI); }
|
||||
static Action* ready_check_finished(PlayerbotAI* botAI) { return new FinishReadyCheckAction(botAI); }
|
||||
static Action* ready_check(PlayerbotAI* botAI) { return new ReadyCheckAction(botAI); }
|
||||
static Action* accept_duel(PlayerbotAI* botAI) { return new AcceptDuelAction(botAI); }
|
||||
static Action* tell_cast_failed(PlayerbotAI* botAI) { return new TellCastFailedAction(botAI); }
|
||||
static Action* party_command(PlayerbotAI* botAI) { return new PartyCommandAction(botAI); }
|
||||
static Action* quest_objective_completed(PlayerbotAI* botAI) { return new QuestObjectiveCompletedAction(botAI); }
|
||||
static Action* store_loot(PlayerbotAI* botAI) { return new StoreLootAction(botAI); }
|
||||
static Action* accept_trade(PlayerbotAI* botAI) { return new TradeStatusAction(botAI); }
|
||||
static Action* remember_taxi(PlayerbotAI* botAI) { return new RememberTaxiAction(botAI); }
|
||||
static Action* check_mount_state(PlayerbotAI* botAI) { return new CheckMountStateAction(botAI); }
|
||||
static Action* area_trigger(PlayerbotAI* botAI) { return new AreaTriggerAction(botAI); }
|
||||
static Action* reach_area_trigger(PlayerbotAI* botAI) { return new ReachAreaTriggerAction(botAI); }
|
||||
static Action* use_meeting_stone(PlayerbotAI* botAI) { return new UseMeetingStoneAction(botAI); }
|
||||
static Action* accept_resurrect(PlayerbotAI* botAI) { return new AcceptResurrectAction(botAI); }
|
||||
static Action* find_corpse(PlayerbotAI* botAI) { return new FindCorpseAction(botAI); }
|
||||
static Action* auto_release(PlayerbotAI* botAI) { return new AutoReleaseSpiritAction(botAI); }
|
||||
static Action* revive_from_corpse(PlayerbotAI* botAI) { return new ReviveFromCorpseAction(botAI); }
|
||||
static Action* accept_invitation(PlayerbotAI* botAI) { return new AcceptInvitationAction(botAI); }
|
||||
static Action* give_leader_in_dungeon(PlayerbotAI* botAI) { return new GiveLeaderAction(botAI, "I don't know this dungeon, lead the way!"); }
|
||||
static Action* pass_leadership_to_master(PlayerbotAI* botAI) { return new PassLeadershipToMasterAction(botAI); }
|
||||
static Action* tell_not_enough_money(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough money"); }
|
||||
static Action* tell_not_enough_reputation(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough reputation"); }
|
||||
static Action* tell_cannot_equip(PlayerbotAI* botAI) { return new InventoryChangeFailureAction(botAI); }
|
||||
static Action* turn_in_quest(PlayerbotAI* botAI) { return new TalkToQuestGiverAction(botAI); }
|
||||
static Action* accept_quest(PlayerbotAI* botAI) { return new AcceptQuestAction(botAI); }
|
||||
static Action* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsAction(botAI); }
|
||||
static Action* accept_quest_share(PlayerbotAI* botAI) { return new AcceptQuestShareAction(botAI); }
|
||||
static Action* loot_roll(PlayerbotAI* botAI) { return new LootRollAction(botAI); }
|
||||
static Action* master_loot_roll(PlayerbotAI* botAI) { return new MasterLootRollAction(botAI); }
|
||||
static Action* bg_join(PlayerbotAI* botAI) { return new BGJoinAction(botAI); }
|
||||
static Action* bg_leave(PlayerbotAI* botAI) { return new BGLeaveAction(botAI); }
|
||||
static Action* bg_status(PlayerbotAI* botAI) { return new BGStatusAction(botAI); }
|
||||
static Action* bg_status_check(PlayerbotAI* botAI) { return new BGStatusCheckAction(botAI); }
|
||||
static Action* bg_strategy_check(PlayerbotAI* botAI) { return new BGStrategyCheckAction(botAI); }
|
||||
static Action* arena_tactics(PlayerbotAI* botAI) { return new ArenaTactics(botAI); }
|
||||
static Action* petition_sign(PlayerbotAI* botAI) { return new PetitionSignAction(botAI); }
|
||||
static Action* lfg_teleport(PlayerbotAI* botAI) { return new LfgTeleportAction(botAI); }
|
||||
static Action* lfg_leave(PlayerbotAI* botAI) { return new LfgLeaveAction(botAI); }
|
||||
static Action* lfg_accept(PlayerbotAI* botAI) { return new LfgAcceptAction(botAI); }
|
||||
static Action* lfg_role_check(PlayerbotAI* botAI) { return new LfgRoleCheckAction(botAI); }
|
||||
static Action* lfg_join(PlayerbotAI* botAI) { return new LfgJoinAction(botAI); }
|
||||
static Action* see_spell(PlayerbotAI* botAI) { return new SeeSpellAction(botAI); }
|
||||
static Action* arena_team_accept(PlayerbotAI* botAI) { return new ArenaTeamAcceptAction(botAI); }
|
||||
static Action* turn_in_query_quest(PlayerbotAI* botAI) { return new TurnInQueryQuestAction(botAI); }
|
||||
static Action* quest_confirm_accept(PlayerbotAI* botAI) { return new QuestConfirmAcceptAction(botAI); }
|
||||
// quest
|
||||
creators["talk to quest giver"] = &WorldPacketActionContext::turn_in_quest;
|
||||
creators["accept quest"] = &WorldPacketActionContext::accept_quest;
|
||||
creators["confirm quest"] = &WorldPacketActionContext::confirm_quest;
|
||||
creators["accept all quests"] = &WorldPacketActionContext::accept_all_quests;
|
||||
creators["accept quest share"] = &WorldPacketActionContext::accept_quest_share;
|
||||
creators["quest update add kill"] = &WorldPacketActionContext::quest_update_add_kill;
|
||||
creators["quest update add item"] = &WorldPacketActionContext::quest_update_add_item;
|
||||
creators["quest update failed"] = &WorldPacketActionContext::quest_update_failed;
|
||||
creators["quest update failed timer"] = &WorldPacketActionContext::quest_update_failed_timer;
|
||||
creators["quest update complete"] = &WorldPacketActionContext::quest_update_complete;
|
||||
|
||||
creators["party command"] = &WorldPacketActionContext::party_command;
|
||||
creators["tell cast failed"] = &WorldPacketActionContext::tell_cast_failed;
|
||||
creators["accept duel"] = &WorldPacketActionContext::accept_duel;
|
||||
creators["ready check"] = &WorldPacketActionContext::ready_check;
|
||||
creators["ready check finished"] = &WorldPacketActionContext::ready_check_finished;
|
||||
creators["uninvite"] = &WorldPacketActionContext::uninvite;
|
||||
creators["security check"] = &WorldPacketActionContext::security_check;
|
||||
creators["guild accept"] = &WorldPacketActionContext::guild_accept;
|
||||
creators["inventory change failure"] = &WorldPacketActionContext::inventory_change_failure;
|
||||
creators["bg status check"] = &WorldPacketActionContext::bg_status_check;
|
||||
creators["bg strategy check"] = &WorldPacketActionContext::bg_strategy_check;
|
||||
creators["bg status"] = &WorldPacketActionContext::bg_status;
|
||||
creators["bg join"] = &WorldPacketActionContext::bg_join;
|
||||
creators["bg leave"] = &WorldPacketActionContext::bg_leave;
|
||||
creators["arena tactics"] = &WorldPacketActionContext::arena_tactics;
|
||||
creators["petition sign"] = &WorldPacketActionContext::petition_sign;
|
||||
creators["lfg join"] = &WorldPacketActionContext::lfg_join;
|
||||
creators["lfg accept"] = &WorldPacketActionContext::lfg_accept;
|
||||
creators["lfg role check"] = &WorldPacketActionContext::lfg_role_check;
|
||||
creators["lfg leave"] = &WorldPacketActionContext::lfg_leave;
|
||||
creators["lfg teleport"] = &WorldPacketActionContext::lfg_teleport;
|
||||
creators["see spell"] = &WorldPacketActionContext::see_spell;
|
||||
creators["arena team accept"] = &WorldPacketActionContext::arena_team_accept;
|
||||
}
|
||||
|
||||
private:
|
||||
static Action* inventory_change_failure(PlayerbotAI* botAI) { return new InventoryChangeFailureAction(botAI); }
|
||||
static Action* guild_accept(PlayerbotAI* botAI) { return new GuildAcceptAction(botAI); }
|
||||
static Action* security_check(PlayerbotAI* botAI) { return new SecurityCheckAction(botAI); }
|
||||
static Action* uninvite(PlayerbotAI* botAI) { return new UninviteAction(botAI); }
|
||||
static Action* ready_check_finished(PlayerbotAI* botAI) { return new FinishReadyCheckAction(botAI); }
|
||||
static Action* ready_check(PlayerbotAI* botAI) { return new ReadyCheckAction(botAI); }
|
||||
static Action* accept_duel(PlayerbotAI* botAI) { return new AcceptDuelAction(botAI); }
|
||||
static Action* tell_cast_failed(PlayerbotAI* botAI) { return new TellCastFailedAction(botAI); }
|
||||
static Action* party_command(PlayerbotAI* botAI) { return new PartyCommandAction(botAI); }
|
||||
static Action* store_loot(PlayerbotAI* botAI) { return new StoreLootAction(botAI); }
|
||||
static Action* accept_trade(PlayerbotAI* botAI) { return new TradeStatusAction(botAI); }
|
||||
static Action* remember_taxi(PlayerbotAI* botAI) { return new RememberTaxiAction(botAI); }
|
||||
static Action* check_mount_state(PlayerbotAI* botAI) { return new CheckMountStateAction(botAI); }
|
||||
static Action* area_trigger(PlayerbotAI* botAI) { return new AreaTriggerAction(botAI); }
|
||||
static Action* reach_area_trigger(PlayerbotAI* botAI) { return new ReachAreaTriggerAction(botAI); }
|
||||
static Action* use_meeting_stone(PlayerbotAI* botAI) { return new UseMeetingStoneAction(botAI); }
|
||||
static Action* accept_resurrect(PlayerbotAI* botAI) { return new AcceptResurrectAction(botAI); }
|
||||
static Action* find_corpse(PlayerbotAI* botAI) { return new FindCorpseAction(botAI); }
|
||||
static Action* auto_release(PlayerbotAI* botAI) { return new AutoReleaseSpiritAction(botAI); }
|
||||
static Action* revive_from_corpse(PlayerbotAI* botAI) { return new ReviveFromCorpseAction(botAI); }
|
||||
static Action* accept_invitation(PlayerbotAI* botAI) { return new AcceptInvitationAction(botAI); }
|
||||
static Action* give_leader_in_dungeon(PlayerbotAI* botAI) { return new GiveLeaderAction(botAI, "I don't know this dungeon, lead the way!"); }
|
||||
static Action* pass_leadership_to_master(PlayerbotAI* botAI) { return new PassLeadershipToMasterAction(botAI); }
|
||||
static Action* tell_not_enough_money(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough money"); }
|
||||
static Action* tell_not_enough_reputation(PlayerbotAI* botAI) { return new TellMasterAction(botAI, "Not enough reputation"); }
|
||||
static Action* tell_cannot_equip(PlayerbotAI* botAI) { return new InventoryChangeFailureAction(botAI); }
|
||||
|
||||
// quest
|
||||
static Action* quest_update_add_kill(PlayerbotAI* ai) { return new QuestUpdateAddKillAction(ai); }
|
||||
static Action* quest_update_add_item(PlayerbotAI* ai) { return new QuestUpdateAddItemAction(ai); }
|
||||
static Action* quest_update_failed(PlayerbotAI* ai) { return new QuestUpdateFailedAction(ai); }
|
||||
static Action* quest_update_failed_timer(PlayerbotAI* ai) { return new QuestUpdateFailedTimerAction(ai); }
|
||||
static Action* quest_update_complete(PlayerbotAI* botAI) { return new QuestUpdateCompleteAction(botAI); }
|
||||
|
||||
static Action* turn_in_quest(PlayerbotAI* botAI) { return new TalkToQuestGiverAction(botAI); }
|
||||
static Action* accept_quest(PlayerbotAI* botAI) { return new AcceptQuestAction(botAI); }
|
||||
static Action* confirm_quest(PlayerbotAI* ai) { return new ConfirmQuestAction(ai); }
|
||||
static Action* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsAction(botAI); }
|
||||
static Action* accept_quest_share(PlayerbotAI* botAI) { return new AcceptQuestShareAction(botAI); }
|
||||
//static Action* turn_in_query_quest(PlayerbotAI* botAI) { return new TurnInQueryQuestAction(botAI); }
|
||||
//static Action* quest_confirm_accept(PlayerbotAI* botAI) { return new QuestConfirmAcceptAction(botAI); }
|
||||
|
||||
|
||||
static Action* loot_roll(PlayerbotAI* botAI) { return new LootRollAction(botAI); }
|
||||
static Action* master_loot_roll(PlayerbotAI* botAI) { return new MasterLootRollAction(botAI); }
|
||||
static Action* bg_join(PlayerbotAI* botAI) { return new BGJoinAction(botAI); }
|
||||
static Action* bg_leave(PlayerbotAI* botAI) { return new BGLeaveAction(botAI); }
|
||||
static Action* bg_status(PlayerbotAI* botAI) { return new BGStatusAction(botAI); }
|
||||
static Action* bg_status_check(PlayerbotAI* botAI) { return new BGStatusCheckAction(botAI); }
|
||||
static Action* bg_strategy_check(PlayerbotAI* botAI) { return new BGStrategyCheckAction(botAI); }
|
||||
static Action* arena_tactics(PlayerbotAI* botAI) { return new ArenaTactics(botAI); }
|
||||
static Action* petition_sign(PlayerbotAI* botAI) { return new PetitionSignAction(botAI); }
|
||||
static Action* lfg_teleport(PlayerbotAI* botAI) { return new LfgTeleportAction(botAI); }
|
||||
static Action* lfg_leave(PlayerbotAI* botAI) { return new LfgLeaveAction(botAI); }
|
||||
static Action* lfg_accept(PlayerbotAI* botAI) { return new LfgAcceptAction(botAI); }
|
||||
static Action* lfg_role_check(PlayerbotAI* botAI) { return new LfgRoleCheckAction(botAI); }
|
||||
static Action* lfg_join(PlayerbotAI* botAI) { return new LfgJoinAction(botAI); }
|
||||
static Action* see_spell(PlayerbotAI* botAI) { return new SeeSpellAction(botAI); }
|
||||
static Action* arena_team_accept(PlayerbotAI* botAI) { return new ArenaTeamAcceptAction(botAI); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user