/* * Copyright (C) 2016+ AzerothCore , 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 "RpgAction.h" #include #include "BattlegroundMgr.h" #include "ChatHelper.h" #include "EmoteAction.h" #include "Event.h" #include "Formations.h" #include "Playerbots.h" #include "ServerFacade.h" #include "RpgSubActions.h" bool RpgAction::Execute(Event event) { GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target"); if (!guidP && botAI->GetMaster()) { if (WorldObject* target = ObjectAccessor::GetWorldObject(*bot, botAI->GetMaster()->GetTarget())) { guidP = GuidPosition(target); if (guidP) { RemIgnore(guidP); SET_AI_VALUE(GuidPosition, "rpg target", guidP); } } } if (bot->GetShapeshiftForm() > 0) bot->SetShapeshiftForm(FORM_NONE); if (!SetNextRpgAction()) RESET_AI_VALUE(GuidPosition, "rpg target"); return true; } bool RpgAction::isUseful() { return AI_VALUE(GuidPosition, "rpg target"); } bool RpgAction::SetNextRpgAction() { Strategy* rpgStrategy; std::vector actions; std::vector relevances; std::vector triggerNodes; for (auto& strategy : botAI->GetAiObjectContext()->GetSupportedStrategies()) { if (strategy.find("rpg") == std::string::npos) continue; rpgStrategy = botAI->GetAiObjectContext()->GetStrategy(strategy); rpgStrategy->InitTriggers(triggerNodes); for (auto& triggerNode : triggerNodes) { Trigger* trigger = context->GetTrigger(triggerNode->getName()); if (trigger) { triggerNode->setTrigger(trigger); NextAction** nextActions = triggerNode->getHandlers(); Trigger* trigger = triggerNode->getTrigger(); bool isChecked = false; for (int32 i = 0; i < NextAction::size(nextActions); i++) { NextAction* nextAction = nextActions[i]; if (nextAction->getRelevance() > 5.0f) continue; if (!isChecked && !trigger->IsActive()) break; isChecked = true; Action* action = botAI->GetAiObjectContext()->GetAction(nextAction->getName()); if (!dynamic_cast(action) || !action->isPossible() || !action->isUseful()) continue; actions.push_back(action); relevances.push_back((nextAction->getRelevance() - 1) * 500); } 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> 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::pairi, std::pair 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(); if ((botAI->HasStrategy("debug", BotState::BOT_STATE_NON_COMBAT) || botAI->HasStrategy("debug rpg", BotState::BOT_STATE_NON_COMBAT))) { std::ostringstream out; out << "do: "; out << chat->FormatWorldobject(AI_VALUE(GuidPosition, "rpg target").GetWorldObject()); out << " " << action->getName(); botAI->TellMasterNoFacing(out); } SET_AI_VALUE(std::string, "next rpg action", action->getName()); return true; } bool RpgAction::AddIgnore(ObjectGuid guid) { if (HasIgnore(guid)) { return false; } GuidSet& ignoreList = context->GetValue("ignore rpg target")->Get(); ignoreList.insert(guid); if (ignoreList.size() > 50) ignoreList.erase(ignoreList.begin()); context->GetValue("ignore rpg target")->Set(ignoreList); return true; } bool RpgAction::RemIgnore(ObjectGuid guid) { if (!HasIgnore(guid)) return false; GuidSet& ignoreList = context->GetValue("ignore rpg target")->Get(); ignoreList.erase(ignoreList.find(guid)); context->GetValue("ignore rpg target")->Set(ignoreList); return true; } bool RpgAction::HasIgnore(ObjectGuid guid) { GuidSet& ignoreList = context->GetValue("ignore rpg target")->Get(); if (ignoreList.empty()) return false; if (ignoreList.find(guid) == ignoreList.end()) return false; return true; } bool CRpgAction::isUseful() { RESET_AI_VALUE(GuidPosition, "rpg target"); return true; };