Skip to content

Commit

Permalink
-Loot fix: Bots no longer ignore loot while inside an instance when t…
Browse files Browse the repository at this point in the history
…here is another instance running for the same map.

-Internal: Added instanceId to various creature/map lookup functions to prevent using the wrong instance.
  • Loading branch information
mostlikely4r committed Sep 10, 2024
1 parent 52de27a commit 9706409
Show file tree
Hide file tree
Showing 27 changed files with 183 additions and 171 deletions.
8 changes: 4 additions & 4 deletions playerbot/ChatHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,8 +846,8 @@ std::string ChatHelper::formatWorldPosition(const WorldPosition& pos)
out << pos.getX() << "," << pos.getY() << "," << pos.getZ();
if (pos.getO())
out << " facing " << formatAngle(pos.getO());
if (pos.getMap())
out << " in " << pos.getMap()->GetMapName();
if (pos.getMap(pos.getFirstInstanceId()))
out << " in " << pos.getMap(pos.getFirstInstanceId())->GetMapName();
else
out << " map:" << pos.getMapId();

Expand All @@ -858,8 +858,8 @@ std::string ChatHelper::formatWorldPosition(const WorldPosition& pos)
std::string ChatHelper::formatGuidPosition(const GuidPosition& guidP)
{
std::ostringstream out;
if (guidP.GetWorldObject())
out << guidP.GetWorldObject()->GetName();
if (guidP.GetWorldObject(guidP.getFirstInstanceId()))
out << guidP.GetWorldObject(guidP.getFirstInstanceId())->GetName();
else if (guidP.GetCreatureTemplate())
out << guidP.GetCreatureTemplate()->Name;
else if (guidP.GetGameObjectInfo())
Expand Down
3 changes: 1 addition & 2 deletions playerbot/FleeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ void FleeManager::calculatePossibleDestinations(std::list<FleePoint*> &points)

bot->UpdateAllowedPositionZ(x, y, z);

Map* map = startPosition.getMap();
const TerrainInfo* terrain = map->GetTerrain();
const TerrainInfo* terrain = startPosition.getTerrain();
if (terrain && terrain->IsInWater(x, y, z))
continue;

Expand Down
36 changes: 21 additions & 15 deletions playerbot/GuidPosition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,37 @@ std::string GuidPosition::to_string() const
return b.str();
}

Creature* GuidPosition::GetCreature() const
Creature* GuidPosition::GetCreature(uint32 instanceId) const
{
if (!*this)
return nullptr;

return getMap()->GetAnyTypeCreature(*this);
if (!getMap(instanceId))
return nullptr;

return getMap(instanceId)->GetAnyTypeCreature(*this);
}

Unit* GuidPosition::GetUnit() const
Unit* GuidPosition::GetUnit(uint32 instanceId) const
{
if (!*this)
return nullptr;

if (IsPlayer())
return sObjectAccessor.FindPlayer(*this);

return GetCreature();
return GetCreature(instanceId);
}

GameObject* GuidPosition::GetGameObject() const
GameObject* GuidPosition::GetGameObject(uint32 instanceId) const
{
if (!*this)
return nullptr;

return getMap()->GetGameObject(*this);
if (!getMap(instanceId))
return nullptr;

return getMap(instanceId)->GetGameObject(*this);
}

Player* GuidPosition::GetPlayer() const
Expand All @@ -82,12 +88,12 @@ const FactionTemplateEntry* GuidPosition::GetFactionTemplateEntry() const
return nullptr;
}

const ReputationRank GuidPosition::GetReactionTo(const GuidPosition& other)
const ReputationRank GuidPosition::GetReactionTo(const GuidPosition& other, uint32 instanceId)
{
if(other.IsUnit() && other.GetUnit())
if (other.GetUnit()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
if(other.IsUnit() && other.GetUnit(instanceId))
if (other.GetUnit(instanceId)->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
{
if (const Player* unitPlayer = other.GetUnit()->GetControllingPlayer())
if (const Player* unitPlayer = other.GetUnit(instanceId)->GetControllingPlayer())
{
if (unitPlayer->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP) && GetFactionTemplateEntry()->IsContestedGuardFaction())
return REP_HOSTILE;
Expand Down Expand Up @@ -119,18 +125,18 @@ const ReputationRank GuidPosition::GetReactionTo(const GuidPosition& other)
return PlayerbotAI::GetFactionReaction(GetFactionTemplateEntry(), other.GetFactionTemplateEntry());
}

bool GuidPosition::isDead()
bool GuidPosition::isDead(uint32 instanceId)
{
if (!getMap())
if (!getMap(instanceId))
return false;

if (!getMap()->IsLoaded(getX(), getY()))
if (!getMap(instanceId)->IsLoaded(getX(), getY()))
return false;

if (IsUnit() && GetUnit() && GetUnit()->IsInWorld() && GetUnit()->IsAlive())
if (IsUnit() && GetUnit(instanceId) && GetUnit(instanceId)->IsInWorld() && GetUnit(instanceId)->IsAlive())
return false;

if (IsGameObject() && GetGameObject() && GetGameObject()->IsInWorld())
if (IsGameObject() && GetGameObject(instanceId) && GetGameObject(instanceId)->IsInWorld())
return false;

return true;
Expand Down
25 changes: 15 additions & 10 deletions playerbot/GuidPosition.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace ai
public:
GuidPosition() : ObjectGuid(), WorldPosition() {}
GuidPosition(ObjectGuid guid, WorldPosition pos) : ObjectGuid(guid), WorldPosition(pos) {};
GuidPosition(ObjectGuid guid, const uint32 mapId) : ObjectGuid(guid) { WorldPosition::set(guid, mapId); }
GuidPosition(ObjectGuid guid, const uint32 mapId, const uint32 instanceId) : ObjectGuid(guid) { WorldPosition::set(guid, mapId, instanceId); }
GuidPosition(ObjectGuid guid, const WorldObject* wo) : ObjectGuid(guid), WorldPosition(wo) {}
GuidPosition(uint64 const& guid, WorldPosition const& pos) : ObjectGuid(guid), WorldPosition(pos) {};
//template<class T>
//GuidPosition(ObjectGuid guid, T) : ObjectGuid(guid) {WorldPosition::set(WorldPosition(T))};
Expand All @@ -25,23 +26,27 @@ namespace ai

GameObjectInfo const* GetGameObjectInfo() const { return IsGameObject() ? sObjectMgr.GetGameObjectInfo(GetEntry()) : nullptr; };

WorldObject* GetWorldObject() const { return getMap() ? getMap()->GetWorldObject(*this) : nullptr;}
Creature* GetCreature() const;
Unit* GetUnit() const;
GameObject* GetGameObject() const;
WorldObject* GetWorldObject(uint32 m_instanceId) const { return getMap(m_instanceId) ? getMap(m_instanceId)->GetWorldObject(*this) : nullptr;}
Creature* GetCreature(uint32 instanceId) const;
Unit* GetUnit(uint32 instanceId) const;
GameObject* GetGameObject(uint32 instanceId) const;
Player* GetPlayer() const;

void updatePosition() {WorldObject* wo = GetWorldObject(); if (wo) WorldPosition::set(wo); }
void updatePosition(uint32 m_instanceId) {WorldObject* wo = GetWorldObject(m_instanceId); if (wo) WorldPosition::set(wo); }

bool HasNpcFlag(NPCFlags flag) { return IsCreature() && GetCreatureTemplate()->NpcFlags & flag; }
bool isGoType(GameobjectTypes type) { return IsGameObject() && GetGameObjectInfo()->type == type; }

const FactionTemplateEntry* GetFactionTemplateEntry() const;
const ReputationRank GetReactionTo(const GuidPosition& other);
bool IsFriendlyTo(const GuidPosition& other) { return (GetFactionTemplateEntry() && other.GetFactionTemplateEntry()) ? (GetReactionTo(other) > REP_NEUTRAL) : false; }
bool IsHostileTo(const GuidPosition& other) { return (GetFactionTemplateEntry() && other.GetFactionTemplateEntry()) ? (GetReactionTo(other) < REP_NEUTRAL) : false; }
const ReputationRank GetReactionTo(const GuidPosition& other, uint32 instanceId);
bool IsFriendlyTo(const GuidPosition& other, const uint32 instanceId) { return (GetFactionTemplateEntry() && other.GetFactionTemplateEntry()) ? (GetReactionTo(other, instanceId) > REP_NEUTRAL) : false; }
bool IsHostileTo(const GuidPosition& other, const uint32 instanceId) { return (GetFactionTemplateEntry() && other.GetFactionTemplateEntry()) ? (GetReactionTo(other, instanceId) < REP_NEUTRAL) : false; }

bool isDead(); //For loaded grids check if the unit/object is unloaded/dead.
const ReputationRank GetReactionTo(WorldObject* object) { return GetReactionTo(GuidPosition(object), object->GetInstanceId()); }
bool IsFriendlyTo(WorldObject* object) { return IsFriendlyTo(GuidPosition(object), object->GetInstanceId()); }
bool IsHostileTo(WorldObject* object) { return IsHostileTo(GuidPosition(object), object->GetInstanceId()); }

bool isDead(uint32 instanceId); //For loaded grids check if the unit/object is unloaded/dead.

uint16 IsPartOfAPool();
uint16 GetGameEventId();
Expand Down
32 changes: 17 additions & 15 deletions playerbot/RandomPlayerbotMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,28 +762,30 @@ void RandomPlayerbotMgr::DelayedFacingFix()
return;

for (auto& fMap : facingFix) {
for (auto obj : fMap.second) {
if (time(0) - obj.second > 5)
{
if (!obj.first.IsCreature())
continue;
for (auto& fInstance : fMap.second) {
for (auto obj : fInstance.second) {
if (time(0) - obj.second > 5)
{
if (!obj.first.IsCreature())
continue;

GuidPosition guidP(obj.first, WorldPosition(fMap.first, 0, 0, 0));
GuidPosition guidP(obj.first, WorldPosition(fMap.first, 0, 0, 0));

Creature* unit = guidP.GetCreature();
Creature* unit = guidP.GetCreature(fInstance.first);

if (!unit)
continue;
if (!unit)
continue;

CreatureData* data = guidP.GetCreatureData();
CreatureData* data = guidP.GetCreatureData();

if (!data)
continue;
if (!data)
continue;

if (unit->GetOrientation() == data->orientation)
continue;
if (unit->GetOrientation() == data->orientation)
continue;

unit->SetFacingTo(data->orientation);
unit->SetFacingTo(data->orientation);
}
}
}
facingFix[fMap.first].clear();
Expand Down
4 changes: 2 additions & 2 deletions playerbot/RandomPlayerbotMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class RandomPlayerbotMgr : public PlayerbotHolder

void PrintTeleportCache();

void AddFacingFix(uint32 mapId, ObjectGuid guid) { facingFix[mapId].push_back(std::make_pair(guid,time(0))); }
void AddFacingFix(uint32 mapId, uint32 instanceId, ObjectGuid guid) { facingFix[mapId][instanceId].push_back(std::make_pair(guid,time(0))); }

bool arenaTeamsDeleted, guildsDeleted = false;

Expand Down Expand Up @@ -205,7 +205,7 @@ class RandomPlayerbotMgr : public PlayerbotHolder
float GetMetricDelta(botPerformanceMetric& metric) const;

bool showLoginWarning;
std::unordered_map<uint32, std::vector<std::pair<ObjectGuid, time_t>>> facingFix;
std::unordered_map<uint32, std::unordered_map<uint32, std::vector<std::pair<ObjectGuid, time_t>>>> facingFix;
};

#define sRandomPlayerbotMgr RandomPlayerbotMgr::instance()
Expand Down
4 changes: 2 additions & 2 deletions playerbot/TravelMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ bool GrindTravelDestination::isActive(Player* bot)
if (cInfo->Rank > CREATURE_ELITE_NORMAL && !AI_VALUE(bool, "can fight elite"))
return false;

return GuidPosition(bot).IsHostileTo(GuidPosition(HIGHGUID_UNIT, entry));
return GuidPosition(bot).IsHostileTo(GuidPosition(HIGHGUID_UNIT, entry), bot->GetInstanceId());
}

std::string GrindTravelDestination::getTitle() {
Expand Down Expand Up @@ -417,7 +417,7 @@ bool BossTravelDestination::isActive(Player* bot)
if ((int32)cInfo->MaxLevel > bot->GetLevel() + 3)
return false;

if (!GuidPosition(bot).IsHostileTo(GuidPosition(HIGHGUID_UNIT, entry)))
if (!GuidPosition(bot).IsHostileTo(GuidPosition(HIGHGUID_UNIT, entry), bot->GetInstanceId()))
return false;

if (bot->GetGroup())
Expand Down
6 changes: 3 additions & 3 deletions playerbot/TravelNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ float TravelNodePath::getCost(Unit* unit, uint32 cGold)
AreaTrigger const* at = sObjectMgr.GetAreaTrigger(pathObject);
if (atEntry && at && atEntry->mapid == bot->GetMapId())
{
Map* map = WorldPosition(atEntry->mapid, atEntry->box_x, atEntry->box_y, atEntry->box_z).getMap();
Map* map = WorldPosition(atEntry->mapid, atEntry->box_x, atEntry->box_y, atEntry->box_z).getMap(bot->GetInstanceId());
if (map)
if (at && at->conditionId && !sObjectMgr.IsConditionSatisfied(at->conditionId, bot, map, nullptr, CONDITION_FROM_AREATRIGGER_TELEPORT))
return -1;
Expand Down Expand Up @@ -303,7 +303,7 @@ TravelNodePath* TravelNode::buildPath(TravelNode* endNode, Unit* bot, bool postP
if (isTransport() && path.size() > 1)
{
WorldPosition secondPos = *std::next(path.begin()); //This is to prevent bots from jumping in the water from a transport. Need to remove this when transports are properly handled.
if (secondPos.getMap() && secondPos.getTerrain() && secondPos.isInWater())
if (secondPos.getTerrain() && secondPos.isInWater())
canPath = false;
}

Expand Down Expand Up @@ -2147,7 +2147,7 @@ void TravelNodeMap::generateTransportNodes()
else if(data->displayId == 3031)
exitPos.setZ(exitPos.getZ() - 17.0f);

if (exitPos.ClosestCorrectPoint(20.0f, 10.0f))
if (exitPos.ClosestCorrectPoint(20.0f, 10.0f,0))
{
TravelNode* exitNode = sTravelNodeMap.addNode(exitPos, data->name + std::string(" dock"), true, true);

Expand Down
22 changes: 11 additions & 11 deletions playerbot/WorldPosition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,19 @@ void WorldPosition::rem()
#endif
}

WorldPosition::WorldPosition(const uint32 mapId, const GuidPosition& guidP)
WorldPosition::WorldPosition(const uint32 mapId, const GuidPosition& guidP, uint32 instanceId)
{
if (guidP.mapid !=0 || guidP.coord_x != 0 || guidP.coord_y != 0 || guidP.coord_z !=0) {
set(WorldPosition(guidP.mapid, guidP.coord_x, guidP.coord_y, guidP.coord_z, guidP.orientation));
return;
}

set(ObjectGuid(guidP), guidP.mapid);
set(ObjectGuid(guidP), guidP.mapid, instanceId);

add();
}

void WorldPosition::set(const ObjectGuid& guid, const uint32 mapId)
void WorldPosition::set(const ObjectGuid& guid, const uint32 mapId, const uint32 instanceId)
{
switch (guid.GetHigh())
{
Expand All @@ -223,7 +223,7 @@ void WorldPosition::set(const ObjectGuid& guid, const uint32 mapId)
case HIGHGUID_UNIT:
{
setMapId(mapId);
Creature* creature = getMap()->GetAnyTypeCreature(guid);
Creature* creature = getMap(instanceId)->GetAnyTypeCreature(guid);
if (creature)
{
set(creature);
Expand Down Expand Up @@ -580,14 +580,14 @@ bool WorldPosition::hasFaction(const Team team) const
std::set<GenericTransport*> WorldPosition::getTransports(uint32 entry)
{
std::set<GenericTransport*> transports;
for (auto transport : getMap()->GetTransports()) //Boats&Zeppelins.
for (auto transport : getMap(getFirstInstanceId())->GetTransports()) //Boats&Zeppelins.
if (!entry || transport->GetEntry() == entry)
transports.insert(transport);

if (transports.empty() || !entry) //Elevators&rams
{
for (auto gopair : getGameObjectsNear(0.0f, entry))
if (GameObject* go = getMap()->GetGameObject(gopair->first))
if (GameObject* go = getMap(getFirstInstanceId())->GetGameObject(gopair->first))
if (GenericTransport* transport = dynamic_cast<GenericTransport*>(go))
transports.insert(transport);
}
Expand Down Expand Up @@ -961,10 +961,10 @@ std::vector<WorldPosition> WorldPosition::getPathFromPath(const std::vector<Worl
return fullPath;
}

bool WorldPosition::ClosestCorrectPoint(float maxRange, float maxHeight)
bool WorldPosition::ClosestCorrectPoint(float maxRange, float maxHeight, uint32 instanceId)
{
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
dtNavMeshQuery const* query = mmap->GetNavMeshQuery(getMapId(), getInstanceId());
dtNavMeshQuery const* query = mmap->GetNavMeshQuery(getMapId(), instanceId);

float curPoint[VERTEX_SIZE] = {coord_y, coord_z, coord_x };
float extend[VERTEX_SIZE] = { maxRange, maxHeight, maxRange };
Expand Down Expand Up @@ -995,9 +995,9 @@ bool WorldPosition::ClosestCorrectPoint(float maxRange, float maxHeight)
bool WorldPosition::GetReachableRandomPointOnGround(const Player* bot, const float radius, const bool randomRange)
{
#ifndef MANGOSBOT_TWO
return getMap()->GetReachableRandomPointOnGround(coord_x, coord_y, coord_z, radius, randomRange);
return getMap(bot->GetInstanceId())->GetReachableRandomPointOnGround(coord_x, coord_y, coord_z, radius, randomRange);
#else
return getMap()->GetReachableRandomPointOnGround(bot->GetPhaseMask(), coord_x, coord_y, coord_z, radius, randomRange);
return getMap(bot->GetInstanceId())->GetReachableRandomPointOnGround(bot->GetPhaseMask(), coord_x, coord_y, coord_z, radius, randomRange);
#endif
}

Expand Down Expand Up @@ -1029,7 +1029,7 @@ uint32 WorldPosition::getUnitsAggro(const std::list<ObjectGuid>& units, const Pl
uint32 count = 0;
for (auto guid : units)
{
Unit* unit = GuidPosition(guid,bot->GetMapId()).GetUnit();
Unit* unit = GuidPosition(guid,bot).GetUnit(bot->GetInstanceId());

if (!unit) continue;

Expand Down
Loading

0 comments on commit 9706409

Please sign in to comment.