mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-13 09:07:19 +00:00
* Revert "[Large server fix] #1537 Serialize playerBots/botLoading with a mutex and use snapshot-based loops to fix concurrency crashes (#1540)" This reverts commit3fff58df1a. * Revert "[Fix] teleport to invalid map or invalid coordinates (x , y , z 200000, o ) given when teleporting player (g UI d full type player low , name , map , x , y , z , o ) (#1538)" This reverts commitca2e2ef0db. * Revert "Fix: prevent MoveSplineInitArgs::Validate velocity asserts (velocity > 0.01f) for bots, pets, and charmed units (#1534)" This reverts commit4e3ac609bd. * Revert "[Fix issue #1527] : startup crash in tank target selection — add TOCTOU & null-safety guards (#1532)" This reverts commitc6b0424c29. * Revert "[Fix issue #1528] Close small window where the “in a BG/arena” state can change between the check (InBattleground() / InArena()) and grabbing the pointer (GetBattleground()), which leads to a null dereference. (#1530)" This reverts commit2e0a161623. * Revert "Harden playerbot logout & packet dispatch; add null-safety in chat hooks and RPG checks (#1529)" This reverts commite4ea8e2694. * Revert "Dont wait to travel when in combat. (#1524)" This reverts commitddfa919154. * Revert "nullptr fix (#1523)" This reverts commit380312ffd2. * Revert "Playerbots/LFG: fix false not eligible & dungeon 0/type 0, add clear diagnostics (#1521)" This reverts commit872e417613. * Revert "nullptr exception (#1520)" This reverts commit3d28a81508. * Revert "Removed bot freezing at startup and system message, not relevant anymore (#1519)" This reverts commitbcd6f5bc06.
178 lines
4.9 KiB
C++
178 lines
4.9 KiB
C++
/*
|
|
* 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.
|
|
*/
|
|
|
|
#include "TargetValue.h"
|
|
|
|
#include "LastMovementValue.h"
|
|
#include "ObjectGuid.h"
|
|
#include "Playerbots.h"
|
|
#include "RtiTargetValue.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "ThreatMgr.h"
|
|
|
|
Unit* FindTargetStrategy::GetResult() { return result; }
|
|
|
|
Unit* TargetValue::FindTarget(FindTargetStrategy* strategy)
|
|
{
|
|
GuidVector attackers = botAI->GetAiObjectContext()->GetValue<GuidVector>("attackers")->Get();
|
|
for (ObjectGuid const guid : attackers)
|
|
{
|
|
Unit* unit = botAI->GetUnit(guid);
|
|
if (!unit)
|
|
continue;
|
|
|
|
ThreatMgr& ThreatMgr = unit->GetThreatMgr();
|
|
strategy->CheckAttacker(unit, &ThreatMgr);
|
|
}
|
|
|
|
return strategy->GetResult();
|
|
}
|
|
|
|
bool FindNonCcTargetStrategy::IsCcTarget(Unit* attacker)
|
|
{
|
|
if (Group* group = botAI->GetBot()->GetGroup())
|
|
{
|
|
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;
|
|
|
|
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(member))
|
|
{
|
|
if (botAI->GetAiObjectContext()->GetValue<Unit*>("rti cc target")->Get() == attacker)
|
|
return true;
|
|
|
|
std::string const rti = botAI->GetAiObjectContext()->GetValue<std::string>("rti cc")->Get();
|
|
int32 index = RtiTargetValue::GetRtiIndex(rti);
|
|
if (index != -1)
|
|
{
|
|
if (ObjectGuid guid = group->GetTargetIcon(index))
|
|
if (attacker->GetGUID() == guid)
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ObjectGuid guid = group->GetTargetIcon(4))
|
|
if (attacker->GetGUID() == guid)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FindTargetStrategy::GetPlayerCount(Unit* creature, uint32* tankCount, uint32* dpsCount)
|
|
{
|
|
Player* bot = botAI->GetBot();
|
|
if (tankCountCache.find(creature) != tankCountCache.end())
|
|
{
|
|
*tankCount = tankCountCache[creature];
|
|
*dpsCount = dpsCountCache[creature];
|
|
return;
|
|
}
|
|
|
|
*tankCount = 0;
|
|
*dpsCount = 0;
|
|
|
|
Unit::AttackerSet attackers(creature->getAttackers());
|
|
for (Unit* attacker : attackers)
|
|
{
|
|
if (!attacker || !attacker->IsAlive() || attacker == bot)
|
|
continue;
|
|
|
|
Player* player = attacker->ToPlayer();
|
|
if (!player)
|
|
continue;
|
|
|
|
if (botAI->IsTank(player))
|
|
++(*tankCount);
|
|
else
|
|
++(*dpsCount);
|
|
}
|
|
|
|
tankCountCache[creature] = *tankCount;
|
|
dpsCountCache[creature] = *dpsCount;
|
|
}
|
|
|
|
bool FindTargetStrategy::IsHighPriority(Unit* attacker)
|
|
{
|
|
if (Group* group = botAI->GetBot()->GetGroup())
|
|
{
|
|
ObjectGuid guid = group->GetTargetIcon(7);
|
|
if (guid && attacker->GetGUID() == guid)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
GuidVector prioritizedTargets = botAI->GetAiObjectContext()->GetValue<GuidVector>("prioritized targets")->Get();
|
|
for (ObjectGuid targetGuid : prioritizedTargets)
|
|
{
|
|
if (targetGuid && attacker->GetGUID() == targetGuid)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
WorldPosition LastLongMoveValue::Calculate()
|
|
{
|
|
LastMovement& lastMove = *context->GetValue<LastMovement&>("last movement");
|
|
if (lastMove.lastPath.empty())
|
|
return WorldPosition();
|
|
|
|
return lastMove.lastPath.getBack();
|
|
}
|
|
|
|
WorldPosition HomeBindValue::Calculate()
|
|
{
|
|
return WorldPosition(bot->m_homebindMapId, bot->m_homebindX, bot->m_homebindY, bot->m_homebindZ, 0.f);
|
|
}
|
|
|
|
Unit* FindTargetValue::Calculate()
|
|
{
|
|
if (qualifier == "")
|
|
{
|
|
return nullptr;
|
|
}
|
|
Group* group = bot->GetGroup();
|
|
if (!group)
|
|
{
|
|
return nullptr;
|
|
}
|
|
HostileReference* ref = bot->getHostileRefMgr().getFirst();
|
|
while (ref)
|
|
{
|
|
ThreatMgr* threatManager = ref->GetSource();
|
|
Unit* unit = threatManager->GetOwner();
|
|
std::wstring wnamepart;
|
|
Utf8toWStr(unit->GetName(), wnamepart);
|
|
wstrToLower(wnamepart);
|
|
if (!qualifier.empty() && qualifier.length() == wnamepart.length() && Utf8FitTo(qualifier, wnamepart))
|
|
{
|
|
return unit;
|
|
}
|
|
ref = ref->next();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void FindBossTargetStrategy::CheckAttacker(Unit* attacker, ThreatMgr* threatManager)
|
|
{
|
|
UnitAI* unitAI = attacker->GetAI();
|
|
BossAI* bossAI = dynamic_cast<BossAI*>(unitAI);
|
|
if (bossAI)
|
|
{
|
|
result = attacker;
|
|
}
|
|
}
|
|
|
|
Unit* BossTargetValue::Calculate()
|
|
{
|
|
FindBossTargetStrategy strategy(botAI);
|
|
return FindTarget(&strategy);
|
|
} |