mod-playerbots/src/Ai/Base/Value/NearestNpcsValue.cpp
bashermens 3d467ce3bb
Added some additional defense checks around isHostile and unit/target (#2056)
Needs second pair of eyes, they appear in crash logs here and there. Its
merely a patch on a open wound.

----
As in aslong there multithreads in mapupdate, which we need for decent
performance and core calls are not done correctly due various reasons.
These type of issues remain.

Although i am planning to experiment a little with threadsafe execution
of our strategies vs performance.

The most effective thing we could do is check every single action and
check its stateless and where it does effect the state or read the state
of a core object its done in the safest way. flags, worldthread where
possible and/ot simply taking into account the state might be invalid.
2026-01-24 20:41:12 +01:00

77 lines
2.4 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 "NearestNpcsValue.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Playerbots.h"
#include "Vehicle.h"
void NearestNpcsValue::FindUnits(std::list<Unit*>& targets)
{
Acore::AnyUnitInObjectRangeCheck u_check(bot, range);
Acore::UnitListSearcher<Acore::AnyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
Cell::VisitObjects(bot, searcher, range);
}
bool NearestNpcsValue::AcceptUnit(Unit* unit) { return !unit->IsPlayer(); }
void NearestHostileNpcsValue::FindUnits(std::list<Unit*>& targets)
{
Acore::AnyUnitInObjectRangeCheck u_check(bot, range);
Acore::UnitListSearcher<Acore::AnyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
Cell::VisitObjects(bot, searcher, range);
}
bool NearestHostileNpcsValue::AcceptUnit(Unit* unit)
{
if (!unit || !unit->IsInWorld() || unit->IsDuringRemoveFromWorld())
return false;
if (unit->IsPlayer())
return false;
return unit->IsHostileTo(bot);
}
void NearestVehiclesValue::FindUnits(std::list<Unit*>& targets)
{
Acore::AnyUnitInObjectRangeCheck u_check(bot, range);
Acore::UnitListSearcher<Acore::AnyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
Cell::VisitObjects(bot, searcher, range);
}
bool NearestVehiclesValue::AcceptUnit(Unit* unit)
{
if (!unit || !unit->IsVehicle() || !unit->IsAlive())
return false;
Vehicle* veh = unit->GetVehicleKit();
if (!veh || !veh->GetAvailableSeatCount())
return false;
return true;
}
void NearestTriggersValue::FindUnits(std::list<Unit*>& targets)
{
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(bot, bot, range);
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
Cell::VisitObjects(bot, searcher, range);
}
bool NearestTriggersValue::AcceptUnit(Unit* unit) { return !unit->IsPlayer(); }
void NearestTotemsValue::FindUnits(std::list<Unit*>& targets)
{
Acore::AnyUnitInObjectRangeCheck u_check(bot, range);
Acore::UnitListSearcher<Acore::AnyUnitInObjectRangeCheck> searcher(bot, targets, u_check);
Cell::VisitObjects(bot, searcher, range);
}
bool NearestTotemsValue::AcceptUnit(Unit* unit) { return unit->IsTotem(); }