/* * Copyright (C) 2016+ AzerothCore , 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 "AggressiveTargetValue.h" #include "Playerbots.h" #include "ServerFacade.h" #include "SharedDefines.h" Unit* AggressiveTargetValue::Calculate() { Player* master = GetMaster(); if (master && (master == bot || master->GetMapId() != bot->GetMapId() || master->IsBeingTeleported() || !GET_PLAYERBOT_AI(master))) master = nullptr; GuidVector targets = AI_VALUE(GuidVector, "possible targets"); if (targets.empty()) return nullptr; float aggroRange = sPlayerbotAIConfig.aggroDistance; float distance = 0; Unit* result = nullptr; for (ObjectGuid const guid : targets) { Unit* unit = botAI->GetUnit(guid); if (!unit || !unit->IsAlive()) continue; if (!unit->IsInWorld() || unit->IsDuringRemoveFromWorld()) continue; if (unit->ToCreature() && !unit->ToCreature()->GetCreatureTemplate()->lootid && bot->GetReactionTo(unit) >= REP_NEUTRAL) continue; if (!bot->IsHostileTo(unit) && unit->GetNpcFlags() != UNIT_NPC_FLAG_NONE) continue; if (abs(bot->GetPositionZ() - unit->GetPositionZ()) > INTERACTION_DISTANCE) continue; if (!bot->InBattleground() && master && botAI->HasStrategy("follow", BotState::BOT_STATE_NON_COMBAT) && ServerFacade::instance().GetDistance2d(master, unit) > aggroRange) continue; if (!bot->IsWithinLOSInMap(unit)) continue; if (bot->GetDistance(unit) > aggroRange) continue; float newdistance = bot->GetDistance(unit); if (!result || (newdistance < distance)) { distance = newdistance; result = unit; } } return result; }