/* * Copyright (C) 2016+ AzerothCore , 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. */ #ifndef _PLAYERBOT_TRAVELMGR_H #define _PLAYERBOT_TRAVELMGR_H #include "AiObject.h" #include "CreatureData.h" #include "GameObject.h" #include "GridDefines.h" #include "PlayerbotAIConfig.h" #include #include class GuidPosition; class ObjectGuid; class Quest; class Player; class PlayerbotAI; struct QuestStatusData; namespace G3D { class Vector2; class Vector3; class Vector4; } //Constructor types for WorldPosition enum WorldPositionConst { WP_RANDOM = 0, WP_CENTROID = 1, WP_MEAN_CENTROID = 2, WP_CLOSEST = 3 }; enum TravelState { TRAVEL_STATE_IDLE = 0, TRAVEL_STATE_TRAVEL_PICK_UP_QUEST = 1, TRAVEL_STATE_WORK_PICK_UP_QUEST = 2, TRAVEL_STATE_TRAVEL_DO_QUEST = 3, TRAVEL_STATE_WORK_DO_QUEST = 4, TRAVEL_STATE_TRAVEL_HAND_IN_QUEST = 5, TRAVEL_STATE_WORK_HAND_IN_QUEST = 6, TRAVEL_STATE_TRAVEL_RPG = 7, TRAVEL_STATE_TRAVEL_EXPLORE = 8, MAX_TRAVEL_STATE }; enum TravelStatus { TRAVEL_STATUS_NONE = 0, TRAVEL_STATUS_PREPARE = 1, TRAVEL_STATUS_TRAVEL = 2, TRAVEL_STATUS_WORK = 3, TRAVEL_STATUS_COOLDOWN = 4, TRAVEL_STATUS_EXPIRED = 5, MAX_TRAVEL_STATUS }; class QuestTravelDestination; //A quest destination container for quick lookup of all destinations related to a quest. struct QuestContainer { std::vector questGivers; std::vector questTakers; std::vector questObjectives; }; typedef std::pair mGridCoord; //Extension of WorldLocation with distance functions. class WorldPosition : public WorldLocation { public: //Constructors WorldPosition() : WorldLocation() { }; WorldPosition(WorldLocation const& loc) : WorldLocation(loc) { } WorldPosition(WorldPosition const& pos) : WorldLocation(pos), visitors(pos.visitors) { } WorldPosition(std::string const str); WorldPosition(uint32 mapid, float x, float y, float z = 0.f, float orientation = 0.f) : WorldLocation(mapid, x, y, z, orientation) { } WorldPosition(uint32 mapId, const Position& pos); WorldPosition(WorldObject const* wo); WorldPosition(std::vector list, WorldPositionConst conType); WorldPosition(std::vector list, WorldPositionConst conType); WorldPosition(uint32 mapid, GridCoord grid); WorldPosition(uint32 mapid, CellCoord cell); WorldPosition(uint32 mapid, mGridCoord grid); //Setters void set(const WorldLocation& pos); void setMapId(uint32 id); void setX(float x); void setY(float y); void setZ(float z); void setO(float o); void addVisitor() { ++visitors; } void remVisitor() { --visitors; } //Getters operator bool() const; bool operator==(WorldPosition const& p1); bool operator!=(WorldPosition const& p1); WorldPosition& operator+=(WorldPosition const& p1); WorldPosition& operator-=(WorldPosition const& p1); uint32 getMapId(); float getX(); float getY(); float getZ(); float getO(); G3D::Vector3 getVector3(); std::string const print(); std::string const to_string(); void printWKT(std::vector points, std::ostringstream& out, uint32 dim = 0, bool loop = false); void printWKT(std::ostringstream& out) { printWKT({ *this }, out); } uint32 getVisitors() { return visitors; } bool isOverworld(); bool isInWater(); bool isUnderWater(); WorldPosition relPoint(WorldPosition* center); WorldPosition offset(WorldPosition* center); float size(); //Slow distance function using possible map transfers. float distance(WorldPosition* center); float distance(WorldPosition center) { return distance(¢er); } float fDist(WorldPosition* center); float fDist(WorldPosition center) { return fDist(¢er); } template std::pair closest(std::vector> list) { return *std::min_element(list.begin(), list.end(), [this](std::pair i, std::pair j) { return this->distance(i.second) < this->distance(j.second); }); } template std::pair closest(std::vector list) { return closest(GetPosList(list)); } //Returns the closest point from the list. WorldPosition* closest(std::vector list) { return *std::min_element(list.begin(), list.end(), [this](WorldPosition* i, WorldPosition* j) { return this->distance(i) < this->distance(j); }); } WorldPosition closest(std::vector list) { return *std::min_element(list.begin(), list.end(), [this](WorldPosition i, WorldPosition j) { return this->distance(i) < this->distance(j); }); } //Quick square distance in 2d plane. float sqDistance2d(WorldPosition center) { return (getX() - center.getX()) * (getX() - center.getX()) + (getY() - center.getY()) * (getY() - center.getY()); } //Quick square distance calculation without map check. Used for getting the minimum distant points. float sqDistance(WorldPosition center) { return (getX() - center.getX()) * (getX() - center.getX()) + (getY() - center.getY()) * (getY() - center.getY()) + (getZ() - center.getZ()) * (getZ() - center.getZ()); } float sqDistance2d(WorldPosition* center) { return (getX() - center->getX()) * (getX() - center->getX()) + (getY() - center->getY()) * (getY() - center->getY()); } float sqDistance(WorldPosition* center) { return (getX() - center->getX()) * (getX() - center->getX()) + (getY() - center->getY()) * (getY() - center->getY()) + (getZ() - center->getZ()) * (getZ() - center->getZ()); } //Returns the closest point of the list. Fast but only works for the same map. WorldPosition* closestSq(std::vector list) { return *std::min_element(list.begin(), list.end(), [this](WorldPosition* i, WorldPosition* j) { return this->sqDistance(i) < this->sqDistance(j); }); } WorldPosition closestSq(std::vector list) { return *std::min_element(list.begin(), list.end(), [this](WorldPosition i, WorldPosition j) { return this->sqDistance(i) < this->sqDistance(j); }); } float getAngleTo(WorldPosition endPos) { float ang = atan2(endPos.getY() - getY(), endPos.getX() - getX()); return (ang >= 0) ? ang : 2 * static_cast(M_PI) + ang; } float getAngleBetween(WorldPosition dir1, WorldPosition dir2) { return abs(getAngleTo(dir1) - getAngleTo(dir2)); } WorldPosition lastInRange(std::vector list, float minDist = -1.f, float maxDist = -1.f); WorldPosition firstOutRange(std::vector list, float minDist = -1.f, float maxDist = -1.f); float mSign(WorldPosition* p1, WorldPosition* p2) { return(getX() - p2->getX()) * (p1->getY() - p2->getY()) - (p1->getX() - p2->getX()) * (getY() - p2->getY()); } bool isInside(WorldPosition* p1, WorldPosition* p2, WorldPosition* p3); //Map functions. Player independent. MapEntry const* getMapEntry(); uint32 getInstanceId(); Map* getMap(); float getHeight(); // remove const - whipowill std::set getTransports(uint32 entry = 0); GridCoord getGridCoord() { return Acore::ComputeGridCoord(getX(), getY()); }; std::vector getGridCoord(WorldPosition secondPos); std::vector fromGridCoord(GridCoord GridCoord); CellCoord getCellCoord() { return Acore::ComputeCellCoord(getX(), getY()); } std::vector fromCellCoord(CellCoord cellCoord); std::vector gridFromCellCoord(CellCoord cellCoord); mGridCoord getmGridCoord() { return std::make_pair((int32)(CENTER_GRID_ID - getX() / SIZE_OF_GRIDS), (int32)(CENTER_GRID_ID - getY() / SIZE_OF_GRIDS)); } std::vector getmGridCoords(WorldPosition secondPos); std::vector frommGridCoord(mGridCoord GridCoord); void loadMapAndVMap(uint32 mapId, uint8 x, uint8 y); void loadMapAndVMap() { loadMapAndVMap(getMapId(), getmGridCoord().first, getmGridCoord().second); } void loadMapAndVMaps(WorldPosition secondPos); //Display functions WorldPosition getDisplayLocation(); float getDisplayX() { return getDisplayLocation().getY() * -1.0; } float getDisplayY() { return getDisplayLocation().getX(); } uint16 getAreaId(); AreaTableEntry const* getArea(); std::string const getAreaName(bool fullName = true, bool zoneName = false); std::vector fromPointsArray(std::vector path); //Pathfinding std::vector getPathStepFrom(WorldPosition startPos, Unit* bot); std::vector getPathFromPath(std::vector startPath, Unit* bot, uint8 maxAttempt = 40); std::vector getPathFrom(WorldPosition startPos, Unit* bot) { return getPathFromPath({ startPos }, bot); } std::vector getPathTo(WorldPosition endPos, Unit* bot) { return endPos.getPathFrom(*this, bot); } bool isPathTo(std::vector path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance) { return !path.empty() && distance(path.back()) < maxDistance; }; bool cropPathTo(std::vector& path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance); bool canPathTo(WorldPosition endPos, Unit* bot) { return endPos.isPathTo(getPathTo(endPos, bot)); } float getPathLength(std::vector points) { float dist = 0.f; for (auto& p : points) { if (&p == &points.front()) dist = 0.f; else dist += std::prev(&p, 1)->distance(p); } return dist; } bool GetReachableRandomPointOnGround(Player* bot, float radius, bool randomRange = true); uint32 getUnitsAggro(GuidVector& units, Player* bot); //Creatures std::vector getCreaturesNear(float radius = 0, uint32 entry = 0); //GameObjects std::vector getGameObjectsNear(float radius = 0, uint32 entry = 0); private: uint32 visitors = 0; }; inline ByteBuffer& operator<<(ByteBuffer& b, WorldPosition& guidP) { b << guidP.getMapId(); b << guidP.getX(); b << guidP.getY(); b << guidP.getZ(); b << guidP.getO(); b << guidP.getVisitors(); return b; } inline ByteBuffer& operator>>(ByteBuffer& b, [[maybe_unused]] WorldPosition& g) { uint32 mapid; float coord_x; float coord_y; float coord_z; float orientation; uint32 visitors = 0; b >> mapid; b >> coord_x; b >> coord_y; b >> coord_z; b >> orientation; b >> visitors; return b; } //Generic creature finder class FindPointCreatureData { public: FindPointCreatureData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0) { point = point1; radius = radius1; entry = entry1; } void operator()(CreatureData const& dataPair); std::vector GetResult() const { return data; }; private: WorldPosition point; float radius; uint32 entry; std::vector data; }; //Generic gameObject finder class FindPointGameObjectData { public: FindPointGameObjectData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0) { point = point1; radius = radius1; entry = entry1; } void operator()(GameObjectData const& dataPair); std::vector GetResult() const { return data; }; private: WorldPosition point; float radius; uint32 entry; std::vector data; }; class GuidPosition : public ObjectGuid, public WorldPosition { public: GuidPosition() : ObjectGuid(), WorldPosition(), loadedFromDB(false) { } GuidPosition(WorldObject* wo); GuidPosition(CreatureData const& creData); GuidPosition(GameObjectData const& goData); CreatureTemplate const* GetCreatureTemplate(); GameObjectTemplate const* GetGameObjectTemplate(); WorldObject* GetWorldObject(); Creature* GetCreature(); Unit* GetUnit(); GameObject* GetGameObject(); Player* GetPlayer(); bool HasNpcFlag(NPCFlags flag); bool isDead(); //For loaded grids check if the unit/object is unloaded/dead. operator bool() const { return !IsEmpty(); } bool operator==(ObjectGuid const& guid) const { return GetRawValue() == guid.GetRawValue(); } bool operator!=(ObjectGuid const& guid) const { return GetRawValue() != guid.GetRawValue(); } bool operator<(ObjectGuid const& guid) const { return GetRawValue() < guid.GetRawValue(); } private: bool loadedFromDB; }; template std::vector> GetPosList(std::vector oList) { std::vector> retList; for (auto& obj : oList) retList.push_back(std::make_pair(obj, WorldPosition(obj))); return std::move(retList); }; template std::vector> GetPosVector(std::vector oList) { std::vector> retList; for (auto& obj : oList) retList.push_back(make_pair(obj, WorldPosition(obj))); return std::move(retList); }; class mapTransfer { public: mapTransfer(WorldPosition pointFrom1, WorldPosition pointTo1, float portalLength1 = 0.1f) : pointFrom(pointFrom1), pointTo(pointTo1), portalLength(portalLength1) { } bool isFrom(WorldPosition point) { return point.getMapId() == pointFrom.getMapId(); } bool isTo(WorldPosition point) { return point.getMapId() == pointTo.getMapId(); } WorldPosition* getPointFrom() { return &pointFrom; } WorldPosition* getPointTo() { return &pointTo; } bool isUseful(WorldPosition point) { return isFrom(point) || isTo(point); } float distance(WorldPosition point) { return isUseful(point) ? (isFrom(point) ? point.distance(pointFrom) : point.distance(pointTo)) : 200000; } bool isUseful(WorldPosition start, WorldPosition end) { return isFrom(start) && isTo(end); } float distance(WorldPosition start, WorldPosition end) { return (isUseful(start, end) ? (start.distance(pointFrom) + portalLength + pointTo.distance(end)) : 200000); } float fDist(WorldPosition start, WorldPosition end); private: WorldPosition pointFrom; WorldPosition pointTo; float portalLength = 0.1f; }; //A destination for a bot to travel to and do something. class TravelDestination { public: TravelDestination() { } TravelDestination(float radiusMin1, float radiusMax1) { radiusMin = radiusMin1; radiusMax = radiusMax1; } TravelDestination(std::vector points1, float radiusMin1, float radiusMax1) { points = points1; radiusMin = radiusMin1; radiusMax = radiusMax1; } void addPoint(WorldPosition* pos) { points.push_back(pos); } void setExpireDelay(uint32 delay) { expireDelay = delay; } void setCooldownDelay(uint32 delay) { cooldownDelay = delay; } void setMaxVisitors(uint32 maxVisitors1 = 0, uint32 maxVisitorsPerPoint1 = 0) { maxVisitors = maxVisitors1; maxVisitorsPerPoint = maxVisitorsPerPoint1; } std::vector getPoints(bool ignoreFull = false); uint32 getExpireDelay() { return expireDelay; } uint32 getCooldownDelay() { return cooldownDelay; } void addVisitor() { ++visitors; } void remVisitor() { --visitors; } uint32 getVisitors() { return visitors; } virtual Quest const* GetQuestTemplate() { return nullptr; } virtual bool isActive([[maybe_unused]] Player* bot) { return false; } bool isFull(bool ignoreFull = false); virtual std::string const getName() { return "TravelDestination"; } virtual int32 getEntry() { return 0; } virtual std::string const getTitle() { return "generic travel destination"; } WorldPosition* nearestPoint(WorldPosition* pos); float distanceTo(WorldPosition* pos) { return nearestPoint(pos)->distance(pos); } bool onMap(WorldPosition* pos) { return nearestPoint(pos)->getMapId() == pos->getMapId(); } virtual bool isIn(WorldPosition* pos, float radius = 0.f) { return onMap(pos) && distanceTo(pos) <= (radius? radius : radiusMin); } virtual bool isOut(WorldPosition* pos, float radius = 0.f) { return !onMap(pos) || distanceTo(pos) > (radius? radius : radiusMax); } float getRadiusMin() { return radiusMin; } std::vector touchingPoints(WorldPosition* pos); std::vector sortedPoints(WorldPosition* pos); std::vector nextPoint(WorldPosition* pos, bool ignoreFull = true); protected: std::vector points; float radiusMin = 0; float radiusMax = 0; uint32 visitors = 0; uint32 maxVisitors = 0; uint32 maxVisitorsPerPoint = 0; uint32 expireDelay = 5 * 1000; uint32 cooldownDelay = 60 * 1000; }; //A travel target that is always inactive and jumps to cooldown. class NullTravelDestination : public TravelDestination { public: NullTravelDestination(uint32 cooldownDelay1 = 5 * 60 * 1000) : TravelDestination() { cooldownDelay = cooldownDelay1; }; Quest const* GetQuestTemplate() override { return nullptr; } bool isActive([[maybe_unused]] Player* bot) override { return false; } std::string const getName() override { return "NullTravelDestination"; } std::string const getTitle() override { return "no destination"; } bool isIn([[maybe_unused]] WorldPosition* pos, [[maybe_unused]] float radius = 0.f) override { return true; } bool isOut([[maybe_unused]] WorldPosition* pos, [[maybe_unused]] float radius = 0.f) override { return false; } }; //A travel target specifically related to a quest. class QuestTravelDestination : public TravelDestination { public: QuestTravelDestination(uint32 questId1, float radiusMin1, float radiusMax1); Quest const* GetQuestTemplate() override { return questTemplate; } bool isActive(Player* bot) override; std::string const getName() override { return "QuestTravelDestination"; } int32 getEntry() override { return 0; } std::string const getTitle() override; protected: uint32 questId; Quest const* questTemplate; }; //A quest giver or taker. class QuestRelationTravelDestination : public QuestTravelDestination { public: QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1, float radiusMax1) : QuestTravelDestination(quest_id1, radiusMin1, radiusMax1) { entry = entry1; relation = relation1; } bool isActive(Player* bot) override; std::string const getName() override { return "QuestRelationTravelDestination"; } int32 getEntry() override { return entry; } std::string const getTitle() override; virtual uint32 getRelation() { return relation; } private: uint32 relation; int32 entry; }; //A quest objective (creature/gameobject to grind/loot) class QuestObjectiveTravelDestination : public QuestTravelDestination { public: QuestObjectiveTravelDestination(uint32 quest_id1, uint32 entry1, uint32 objective1, float radiusMin1, float radiusMax1, uint32 itemId1 = 0) : QuestTravelDestination(quest_id1, radiusMin1, radiusMax1) { objective = objective1; entry = entry1; itemId = itemId1; } bool isCreature(); uint32 ReqCreature(); uint32 ReqGOId(); uint32 ReqCount(); bool isActive(Player* bot) override; std::string const getName() override { return "QuestObjectiveTravelDestination"; } int32 getEntry() override { return entry; } std::string const getTitle() override; private: uint32 objective; uint32 entry; uint32 itemId = 0; }; //A location with rpg target(s) based on race and level class RpgTravelDestination : public TravelDestination { public: RpgTravelDestination(uint32 entry1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1) { entry = entry1; } bool isActive(Player* bot) override; virtual CreatureTemplate const* GetCreatureTemplate(); std::string const getName() override { return "RpgTravelDestination"; } int32 getEntry() override { return 0; } std::string const getTitle() override; protected: uint32 entry; }; //A location with zone exploration target(s) class ExploreTravelDestination : public TravelDestination { public: ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1) { areaId = areaId1; } bool isActive(Player* bot) override; std::string const getName() override { return "ExploreTravelDestination"; } int32 getEntry() override { return 0; } std::string const getTitle() override { return title; }; virtual void setTitle(std::string newTitle) { title = newTitle; } virtual uint32 getAreaId() { return areaId; } protected: uint32 areaId; std::string title = ""; }; //A location with zone exploration target(s) class GrindTravelDestination : public TravelDestination { public: GrindTravelDestination(int32 entry1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1) { entry = entry1; } bool isActive(Player* bot) override; virtual CreatureTemplate const* GetCreatureTemplate(); std::string const getName() override { return "GrindTravelDestination"; } int32 getEntry() override { return entry; } std::string const getTitle() override; protected: int32 entry; }; //A location with a boss class BossTravelDestination : public TravelDestination { public: BossTravelDestination(int32 entry1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1) { entry = entry1; cooldownDelay = 1000; } bool isActive(Player* bot) override; CreatureTemplate const* getCreatureTemplate(); std::string const getName() override { return "BossTravelDestination"; } int32 getEntry() override { return entry; } std::string const getTitle() override; protected: int32 entry; }; //Current target and location for the bot to travel to. //The flow is as follows: //PREPARE (wait until no loot is near) //TRAVEL (move towards target until close enough) (rpg and grind is disabled) //WORK (grind/rpg until the target is no longer active) (rpg and grind is enabled on quest mobs) //COOLDOWN (wait some time free to do what the bot wants) //EXPIRE (if any of the above actions take too long pick a new target) class TravelTarget : AiObject { public: TravelTarget(PlayerbotAI* botAI) : AiObject(botAI), m_status(TRAVEL_STATUS_NONE), startTime(getMSTime()) { }; TravelTarget(PlayerbotAI* botAI, TravelDestination* tDestination1, WorldPosition* wPosition1) : AiObject(botAI), m_status(TRAVEL_STATUS_NONE), startTime(getMSTime()) { setTarget(tDestination1, wPosition1); } ~TravelTarget(); void setTarget(TravelDestination* tDestination1, WorldPosition* wPosition1, bool groupCopy1 = false); void setStatus(TravelStatus status); void setExpireIn(uint32 expireMs) { statusTime = getExpiredTime() + expireMs; } void incRetry(bool isMove) { if (isMove) ++moveRetryCount; else ++extendRetryCount; } void setRetry(bool isMove, uint32 newCount = 0) { if (isMove) moveRetryCount = newCount; else extendRetryCount = newCount; } void setForced(bool forced1) { forced = forced1; } void setRadius(float radius1) { radius = radius1; } void copyTarget(TravelTarget* target); void addVisitors(); void releaseVisitors(); float distance(Player* bot); WorldPosition* getPosition(); TravelDestination* getDestination(); uint32 getEntry() { if (!tDestination) return 0; return tDestination->getEntry(); } PlayerbotAI* getAi() { return botAI; } uint32 getExpiredTime() { return getMSTime() - startTime; } uint32 getTimeLeft() { return statusTime - getExpiredTime(); } uint32 getMaxTravelTime(); uint32 getRetryCount(bool isMove) { return isMove ? moveRetryCount: extendRetryCount; } bool isTraveling(); bool isActive(); bool isWorking(); bool isPreparing(); bool isMaxRetry(bool isMove) { return isMove ? (moveRetryCount > 5) : (extendRetryCount > 5); } TravelStatus getStatus() { return m_status; } TravelState getTravelState(); bool isGroupCopy() { return groupCopy; } bool isForced() { return forced; } protected: TravelStatus m_status; uint32 startTime; uint32 statusTime = 0; bool forced = false; float radius = 0.f; bool groupCopy = false; bool visitor = true; uint32 extendRetryCount = 0; uint32 moveRetryCount = 0; TravelDestination* tDestination = nullptr; WorldPosition* wPosition = nullptr; }; //General container for all travel destinations. class TravelMgr { public: TravelMgr() { }; static TravelMgr* instance() { static TravelMgr instance; return &instance; } void Clear(); void LoadQuestTravelTable(); template void weighted_shuffle(D first, D last, W first_weight, W last_weight, URBG&& g) { while (first != last && first_weight != last_weight) { std::discrete_distributiondd(first_weight, last_weight); auto i = dd(g); if (i) { std::swap(*first, *std::next(first, i)); std::swap(*first_weight, *std::next(first_weight, i)); } ++first; ++first_weight; } } std::vector getNextPoint(WorldPosition* center, std::vector points, uint32 amount = 1); std::vector getNextPoint(WorldPosition center, std::vector points, uint32 amount = 1); QuestStatusData* getQuestStatus(Player* bot, uint32 questId); bool getObjectiveStatus(Player* bot, Quest const* pQuest, uint32 objective); uint32 getDialogStatus(Player* pPlayer, int32 questgiver, Quest const* pQuest); std::vector getQuestTravelDestinations(Player* bot, int32 questId = -1, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 5000, bool ignoreObjectives = false); std::vector getRpgTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 5000); std::vector getExploreTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false); std::vector getGrindTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 5000); std::vector getBossTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 25000); void setNullTravelTarget(Player* player); void addMapTransfer(WorldPosition start, WorldPosition end, float portalDistance = 0.1f, bool makeShortcuts = true); void loadMapTransfers(); float mapTransDistance(WorldPosition start, WorldPosition end); float fastMapTransDistance(WorldPosition start, WorldPosition end); NullTravelDestination* nullTravelDestination = new NullTravelDestination(); WorldPosition* nullWorldPosition = new WorldPosition(); void addBadVmap(uint32 mapId, uint8 x, uint8 y) { badVmap.push_back(std::make_tuple(mapId, x, y)); } void addBadMmap(uint32 mapId, uint8 x, uint8 y) { badMmap.push_back(std::make_tuple(mapId, x, y)); } bool isBadVmap(uint32 mapId, uint8 x, uint8 y) { return std::find(badVmap.begin(), badVmap.end(), std::make_tuple(mapId, x, y)) != badVmap.end(); } bool isBadMmap(uint32 mapId, uint8 x, uint8 y) { return std::find(badMmap.begin(), badMmap.end(), std::make_tuple(mapId, x, y)) != badMmap.end(); } void printGrid(uint32 mapId, int x, int y, std::string const type); void printObj(WorldObject* obj, std::string const type); //protected: void logQuestError(uint32 errorNr, Quest* quest, uint32 objective = 0, uint32 unitId = 0, uint32 itemId = 0); std::vector avoidLoaded; std::vector questGivers; std::vector rpgNpcs; std::vector grindMobs; std::vector bossMobs; std::unordered_map exploreLocs; std::unordered_map quests; std::vector> badVmap, badMmap; std::unordered_map, std::vector, boost::hash>> mapTransfersMap; }; #define sTravelMgr TravelMgr::instance() #endif