mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-25 22:46:25 +00:00
[HOT FIX] MS build issues regarding folder / command lenght usage or rc.exe (#2038)
This commit is contained in:
233
src/Ai/Base/Value/GrindTargetValue.cpp
Normal file
233
src/Ai/Base/Value/GrindTargetValue.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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 "GrindTargetValue.h"
|
||||
|
||||
#include "NewRpgInfo.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
Unit* GrindTargetValue::Calculate()
|
||||
{
|
||||
uint32 memberCount = 1;
|
||||
Group* group = bot->GetGroup();
|
||||
if (group)
|
||||
memberCount = group->GetMembersCount();
|
||||
|
||||
Unit* target = nullptr;
|
||||
uint32 assistCount = 0;
|
||||
while (!target && assistCount < memberCount)
|
||||
{
|
||||
target = FindTargetForGrinding(assistCount++);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
Unit* GrindTargetValue::FindTargetForGrinding(uint32 assistCount)
|
||||
{
|
||||
uint32 memberCount = 1;
|
||||
Group* group = bot->GetGroup();
|
||||
Player* master = GetMaster();
|
||||
|
||||
if (master && (master == bot || master->GetMapId() != bot->GetMapId() || master->IsBeingTeleported() ||
|
||||
!GET_PLAYERBOT_AI(master)))
|
||||
master = nullptr;
|
||||
|
||||
GuidVector attackers = context->GetValue<GuidVector>("attackers")->Get();
|
||||
for (ObjectGuid const guid : attackers)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
if (!unit || !unit->IsAlive())
|
||||
continue;
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
GuidVector targets = *context->GetValue<GuidVector>("possible targets");
|
||||
if (targets.empty())
|
||||
return nullptr;
|
||||
|
||||
float distance = 0;
|
||||
Unit* result = nullptr;
|
||||
std::unordered_map<uint32, bool> needForQuestMap;
|
||||
|
||||
for (ObjectGuid const guid : targets)
|
||||
{
|
||||
Unit* unit = botAI->GetUnit(guid);
|
||||
|
||||
if (!unit)
|
||||
continue;
|
||||
|
||||
auto& rep = bot->ToPlayer()->GetReputationMgr();
|
||||
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 (!bot->isHonorOrXPTarget(unit))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (abs(bot->GetPositionZ() - unit->GetPositionZ()) > INTERACTION_DISTANCE)
|
||||
continue;
|
||||
|
||||
if (!bot->InBattleground() && GetTargetingPlayerCount(unit) > assistCount)
|
||||
continue;
|
||||
|
||||
// if (!bot->InBattleground() && master && master->GetDistance(unit) >= sPlayerbotAIConfig->grindDistance &&
|
||||
// !sRandomPlayerbotMgr->IsRandomBot(bot)) continue;
|
||||
|
||||
// Bots in bot-groups no have a more limited range to look for grind target
|
||||
if (!bot->InBattleground() && master && botAI->HasStrategy("follow", BotState::BOT_STATE_NON_COMBAT) &&
|
||||
sServerFacade->GetDistance2d(master, unit) > sPlayerbotAIConfig->lootDistance)
|
||||
{
|
||||
if (botAI->HasStrategy("debug grind", BotState::BOT_STATE_NON_COMBAT))
|
||||
botAI->TellMaster(chat->FormatWorldobject(unit) + " ignored (far from master).");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bot->InBattleground() && (int)unit->GetLevel() - (int)bot->GetLevel() > 4 && !unit->GetGUID().IsPlayer())
|
||||
continue;
|
||||
|
||||
if (Creature* creature = unit->ToCreature())
|
||||
if (CreatureTemplate const* CreatureTemplate = creature->GetCreatureTemplate())
|
||||
if (CreatureTemplate->rank > CREATURE_ELITE_NORMAL && !AI_VALUE(bool, "can fight elite"))
|
||||
continue;
|
||||
|
||||
if (!bot->IsWithinLOSInMap(unit))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool inactiveGrindStatus = botAI->rpgInfo.status != RPG_WANDER_RANDOM && botAI->rpgInfo.status != RPG_IDLE;
|
||||
|
||||
float aggroRange = 30.0f;
|
||||
if (unit->ToCreature())
|
||||
aggroRange = std::min(30.0f, unit->ToCreature()->GetAggroRange(bot) + 10.0f);
|
||||
bool outOfAggro = unit->ToCreature() && bot->GetDistance(unit) > aggroRange;
|
||||
if (inactiveGrindStatus && outOfAggro)
|
||||
{
|
||||
if (needForQuestMap.find(unit->GetEntry()) == needForQuestMap.end())
|
||||
needForQuestMap[unit->GetEntry()] = needForQuest(unit);
|
||||
|
||||
if (!needForQuestMap[unit->GetEntry()])
|
||||
continue;
|
||||
}
|
||||
|
||||
if (group)
|
||||
{
|
||||
Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
|
||||
for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
|
||||
{
|
||||
Player* member = ObjectAccessor::FindPlayer(itr->guid);
|
||||
if (!member || !member->IsAlive())
|
||||
continue;
|
||||
|
||||
float d = member->GetDistance(unit);
|
||||
if (!result || d < distance)
|
||||
{
|
||||
distance = d;
|
||||
result = unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float newdistance = bot->GetDistance(unit);
|
||||
if (!result || (newdistance < distance))
|
||||
{
|
||||
distance = newdistance;
|
||||
result = unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GrindTargetValue::needForQuest(Unit* target)
|
||||
{
|
||||
QuestStatusMap& questMap = bot->getQuestStatusMap();
|
||||
for (auto& quest : questMap)
|
||||
{
|
||||
Quest const* questTemplate = sObjectMgr->GetQuestTemplate(quest.first);
|
||||
if (!questTemplate)
|
||||
continue;
|
||||
|
||||
uint32 questId = questTemplate->GetQuestId();
|
||||
if (!questId)
|
||||
continue;
|
||||
|
||||
QuestStatus status = bot->GetQuestStatus(questId);
|
||||
|
||||
if (status == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
const QuestStatusData* questStatus = &bot->getQuestStatusMap()[questId];
|
||||
|
||||
if (questTemplate->GetQuestLevel() > bot->GetLevel() + 5)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < QUEST_OBJECTIVES_COUNT; j++)
|
||||
{
|
||||
int32 entry = questTemplate->RequiredNpcOrGo[j];
|
||||
|
||||
if (entry && entry > 0)
|
||||
{
|
||||
int required = questTemplate->RequiredNpcOrGoCount[j];
|
||||
int available = questStatus->CreatureOrGOCount[j];
|
||||
|
||||
if (required && available < required && target->GetEntry() == entry)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CreatureTemplate const* data = sObjectMgr->GetCreatureTemplate(target->GetEntry()))
|
||||
{
|
||||
if (uint32 lootId = data->lootid)
|
||||
{
|
||||
if (LootTemplates_Creature.HaveQuestLootForPlayer(lootId, bot))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GrindTargetValue::GetTargetingPlayerCount(Unit* unit)
|
||||
{
|
||||
Group* group = bot->GetGroup();
|
||||
if (!group)
|
||||
return 0;
|
||||
|
||||
uint32 count = 0;
|
||||
Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
|
||||
for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
|
||||
{
|
||||
Player* member = ObjectAccessor::FindPlayer(itr->guid);
|
||||
if (!member || !member->IsAlive() || member == bot)
|
||||
continue;
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(member);
|
||||
if ((botAI && *botAI->GetAiObjectContext()->GetValue<Unit*>("current target") == unit) ||
|
||||
(!botAI && member->GetTarget() == unit->GetGUID()))
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
Reference in New Issue
Block a user