mod-playerbots/src/Ai/World/Rpg/Strategy/NewRpgStrategy.cpp

138 lines
3.5 KiB
C++

/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "NewRpgStrategy.h"
#include "Action.h"
#include "NewRpgInfo.h"
#include "Player.h"
#include "PlayerbotAI.h"
static bool IsGatherObjectiveForDoQuest(NewRpgInfo::DoQuest const* data)
{
if (!data || !data->quest)
return false;
Quest const* q = data->quest;
int32 obj = data->objectiveIdx;
if (obj < QUEST_OBJECTIVES_COUNT)
{
int32 entry = q->RequiredNpcOrGo[obj];
if (entry < 0) // GO objective
return true;
if (entry == 0 && obj < QUEST_ITEM_OBJECTIVES_COUNT && q->RequiredItemId[obj])
return true;
}
else if (obj < QUEST_OBJECTIVES_COUNT + QUEST_ITEM_OBJECTIVES_COUNT)
{
return true;
}
// source-item quest: need to find the right target to use it on
if (q->GetSrcItemId())
return true;
return false;
}
float NewRpgDoQuestMultiplier::GetValue(Action* action)
{
if (!action || action->getName() != "attack anything")
return 1.0f;
NewRpgInfo& info = botAI->rpgInfo;
if (info.GetStatus() != RPG_DO_QUEST)
return 1.0f;
auto* data = std::get_if<NewRpgInfo::DoQuest>(&info.data);
if (!data)
return 1.0f;
// heading back to turn in, don't get sidetracked
if (data->questId && bot->GetQuestStatus(data->questId) == QUEST_STATUS_COMPLETE)
return 0.15f;
// at POI: gather stays low so mobs don't pull us off the cluster;
// kill runs full so attack-anything drives behavior
if (data->lastReachPOI)
return IsGatherObjectiveForDoQuest(data) ? 0.30f : 1.0f;
// traveling
return 0.20f;
}
NewRpgStrategy::NewRpgStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
std::vector<NextAction> NewRpgStrategy::getDefaultActions()
{
// must outrank grind
return {
NextAction("new rpg status update", 11.0f)
};
}
void NewRpgStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(
new TriggerNode(
"go grind status",
{
NextAction("new rpg go grind", 3.0f)
}
)
);
triggers.push_back(
new TriggerNode(
"go camp status",
{
NextAction("new rpg go camp", 3.0f)
}
)
);
triggers.push_back(
new TriggerNode(
"wander random status",
{
NextAction("new rpg wander random", 3.0f)
}
)
);
triggers.push_back(
new TriggerNode(
"wander npc status",
{
NextAction("new rpg wander npc", 3.0f)
}
)
);
triggers.push_back(
new TriggerNode(
"do quest status",
{
// 4.5: above attack-anything (4.0), below loot (5.0+)
NextAction("new rpg do quest", 4.5f)
}
)
);
triggers.push_back(
new TriggerNode(
"travel flight status",
{
NextAction("new rpg travel flight", 3.0f)
}
)
);
triggers.push_back(
new TriggerNode(
"outdoor pvp status",
{
NextAction("new rpg outdoor pvp", 3.0f)
}
)
);
}
void NewRpgStrategy::InitMultipliers(std::vector<Multiplier*>& multipliers)
{
multipliers.push_back(new NewRpgDoQuestMultiplier(botAI));
}