From 0a0ba0a53f75c6178780e9e46e0d8b7ae394e993 Mon Sep 17 00:00:00 2001 From: bash Date: Thu, 8 Jan 2026 00:50:49 +0100 Subject: [PATCH] minimize delta, legacy and merge mistakes over the years --- .github/ISSUE_TEMPLATE/bb_crash_issues.yml | 2 +- AUTHORS | 5 - apps/docker/Dockerfile | 2 +- conf/dist/config.cmake | 2 +- deps/recastnavigation/Detour/CMakeLists.txt | 2 +- deps/recastnavigation/Recast/CMakeLists.txt | 2 +- .../pendings/changes_1647137971165231200.md | 7 - .../Collision/BoundingIntervalHierarchy.h | 2 + src/common/Collision/DynamicTree.cpp | 49 +- src/common/Collision/DynamicTree.h | 4 +- src/common/Collision/Management/IVMapMgr.h | 25 +- src/common/Collision/Management/MMapMgr.cpp | 3 +- src/common/Collision/Management/VMapMgr2.cpp | 82 +-- src/common/Collision/Management/VMapMgr2.h | 4 +- src/common/Collision/Maps/MapTree.cpp | 32 -- src/common/Collision/Maps/MapTree.h | 7 +- .../Collision/Models/GameObjectModel.cpp | 25 +- src/common/Collision/Models/GameObjectModel.h | 1 - src/common/Collision/Models/ModelInstance.cpp | 44 +- src/common/Collision/Models/ModelInstance.h | 1 - src/common/Collision/Models/WorldModel.cpp | 125 +++-- src/common/Collision/Models/WorldModel.h | 10 +- src/common/Utilities/CircularBuffer.h | 2 +- src/common/Utilities/DataMap.h | 2 +- src/common/Utilities/EventMap.h | 26 - src/common/Utilities/EventProcessor.h | 2 +- src/common/Utilities/Util.h | 1 - src/server/database/Updater/UpdateFetcher.cpp | 2 +- src/server/game/AI/CreatureAI.cpp | 12 +- .../game/AI/SmartScripts/SmartScriptMgr.cpp | 3 + .../game/Achievements/AchievementMgr.cpp | 9 + src/server/game/Chat/Chat.h | 11 - src/server/game/Combat/UnitEvents.h | 22 +- .../game/Entities/Creature/Creature.cpp | 5 +- .../game/Entities/Creature/CreatureData.h | 2 +- src/server/game/Entities/Player/Player.cpp | 56 +- src/server/game/Entities/Player/Player.h | 12 +- .../game/Entities/Player/PlayerUpdates.cpp | 3 + src/server/game/Entities/Unit/Unit.cpp | 24 +- src/server/game/Entities/Unit/Unit.h | 2 - .../game/Entities/Vehicle/VehicleDefines.h | 2 +- src/server/game/Grids/GridTerrainData.cpp | 6 +- src/server/game/Grids/GridTerrainData.h | 4 +- src/server/game/Groups/Group.h | 1 + src/server/game/Guilds/Guild.cpp | 428 +++++++-------- src/server/game/Guilds/Guild.h | 319 +++++------ src/server/game/Handlers/CharacterHandler.cpp | 517 +++++++++--------- src/server/game/Handlers/ChatHandler.cpp | 59 +- src/server/game/Handlers/PetitionsHandler.cpp | 2 - src/server/game/Maps/Map.cpp | 81 ++- src/server/game/Maps/Map.h | 10 +- .../MovementGenerators/PathGenerator.cpp | 6 +- .../PointMovementGenerator.cpp | 13 +- .../WaypointMovementGenerator.cpp | 12 +- .../Scripting/ScriptDefines/PlayerScript.cpp | 25 - .../Scripting/ScriptDefines/PlayerScript.h | 10 - src/server/game/Scripting/ScriptMgr.h | 5 - src/server/game/Spells/Spell.cpp | 2 +- src/server/scripts/Commands/cs_cheat.cpp | 4 +- src/server/scripts/Commands/cs_misc.cpp | 2 +- src/server/scripts/Commands/cs_npc.cpp | 1 - src/server/scripts/Spells/spell_generic.cpp | 7 +- .../scripts/World/areatrigger_scripts.cpp | 2 +- src/server/scripts/World/chat_log.cpp | 36 +- 64 files changed, 908 insertions(+), 1278 deletions(-) delete mode 100644 doc/changelog/pendings/changes_1647137971165231200.md diff --git a/.github/ISSUE_TEMPLATE/bb_crash_issues.yml b/.github/ISSUE_TEMPLATE/bb_crash_issues.yml index 43b07bf79..9e94e5bbc 100644 --- a/.github/ISSUE_TEMPLATE/bb_crash_issues.yml +++ b/.github/ISSUE_TEMPLATE/bb_crash_issues.yml @@ -31,7 +31,7 @@ body: description: | Do you have any logs or screenshots that can be useful? Crash logs in text are preffered over screenshots. - If you have logs in text form please upload them to [Gist](https://gist.github.com/) or PasteBin and upload the link. + DO NOT POST THE FULL CRASH LOG IN THE ISSUE BODY. DO NOT UPLOAD TEXT FILES. USE [GITHUB GIST](https://gist.github.com/), PASTEBIN, OR ANY SIMILAR SERVICE INSTEAD. validations: required: false - type: input diff --git a/AUTHORS b/AUTHORS index 63425cea7..c9155fdca 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,5 @@ # List of AUTHORS who contributed over time to the AzerothCore project -## Warning -The code of AzerothCore is shipped as it is without any form of warranty, -and - except for third party libraries licensed under the AGPL 3, -which you can read from the file "LICENSE". - ## Point of current development The project is currently hosted at https://www.azerothcore.org/ and developed under https://github.com/azerothcore diff --git a/apps/docker/Dockerfile b/apps/docker/Dockerfile index b96f11b6e..0fdee45ce 100644 --- a/apps/docker/Dockerfile +++ b/apps/docker/Dockerfile @@ -258,4 +258,4 @@ COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build \ /azerothcore/env/dist/bin/vmap4_assembler /azerothcore/env/dist/bin/vmap4_assembler COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build \ - /azerothcore/env/dist/bin/vmap4_extractor /azerothcore/env/dist/bin/vmap4_extractor \ No newline at end of file + /azerothcore/env/dist/bin/vmap4_extractor /azerothcore/env/dist/bin/vmap4_extractor diff --git a/conf/dist/config.cmake b/conf/dist/config.cmake index d1a32cf14..ce2e079f3 100644 --- a/conf/dist/config.cmake +++ b/conf/dist/config.cmake @@ -1,5 +1,5 @@ # -# Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE +# Copyright (C) 2016+ AzerothCore # Copyright (C) 2021+ WarheadCore # # This file is free software; as a special exception the author gives diff --git a/deps/recastnavigation/Detour/CMakeLists.txt b/deps/recastnavigation/Detour/CMakeLists.txt index e658bef15..e1294b0e0 100644 --- a/deps/recastnavigation/Detour/CMakeLists.txt +++ b/deps/recastnavigation/Detour/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2008-2016 TrinityCore -# Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE +# Copyright (C) 2016+ AzerothCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/deps/recastnavigation/Recast/CMakeLists.txt b/deps/recastnavigation/Recast/CMakeLists.txt index ab1641bad..c54d570c3 100644 --- a/deps/recastnavigation/Recast/CMakeLists.txt +++ b/deps/recastnavigation/Recast/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2008-2016 TrinityCore -# Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE +# Copyright (C) 2016+ AzerothCore # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without diff --git a/doc/changelog/pendings/changes_1647137971165231200.md b/doc/changelog/pendings/changes_1647137971165231200.md deleted file mode 100644 index 86f51b9af..000000000 --- a/doc/changelog/pendings/changes_1647137971165231200.md +++ /dev/null @@ -1,7 +0,0 @@ -### Added - -- New hook for OnQuestComputeXP(). The intended use is to change the XP values for certain quests programmatically. The hook is triggered after XP calculation and before rewarding XP or gold to the player. - -### How to upgrade - -- No special changes needed. The new hook is available for use and should not interfere with any existing hooks or logic. diff --git a/src/common/Collision/BoundingIntervalHierarchy.h b/src/common/Collision/BoundingIntervalHierarchy.h index d9fcc17b5..84aa01139 100644 --- a/src/common/Collision/BoundingIntervalHierarchy.h +++ b/src/common/Collision/BoundingIntervalHierarchy.h @@ -70,6 +70,7 @@ private: { tree.clear(); objects.clear(); + bounds = G3D::AABox::empty(); // create space for the first node tree.push_back(3u << 30u); // dummy leaf tree.insert(tree.end(), 2, 0); @@ -116,6 +117,7 @@ public: delete[] dat.indices; } [[nodiscard]] uint32 primCount() const { return objects.size(); } + G3D::AABox const& bound() const { return bounds; } template void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp index 08ccac79d..0025bf998 100644 --- a/src/common/Collision/DynamicTree.cpp +++ b/src/common/Collision/DynamicTree.cpp @@ -170,25 +170,6 @@ private: VMAP::ModelIgnoreFlags _ignoreFlags; }; -struct DynamicTreeAreaInfoCallback -{ - DynamicTreeAreaInfoCallback(uint32 phaseMask) : _phaseMask(phaseMask) { } - - void operator()(G3D::Vector3 const& p, GameObjectModel const& obj) - { - obj.IntersectPoint(p, _areaInfo, _phaseMask); - } - - VMAP::AreaInfo const& GetAreaInfo() const - { - return _areaInfo; - } - -private: - uint32 _phaseMask; - VMAP::AreaInfo _areaInfo; -}; - struct DynamicTreeLocationInfoCallback { DynamicTreeLocationInfoCallback(uint32 phaseMask) @@ -308,24 +289,7 @@ float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, } } -bool DynamicMapTree::GetAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const -{ - G3D::Vector3 v(x, y, z + 0.5f); - DynamicTreeAreaInfoCallback intersectionCallBack(phasemask); - impl->intersectPoint(v, intersectionCallBack); - if (intersectionCallBack.GetAreaInfo().result) - { - flags = intersectionCallBack.GetAreaInfo().flags; - adtId = intersectionCallBack.GetAreaInfo().adtId; - rootId = intersectionCallBack.GetAreaInfo().rootId; - groupId = intersectionCallBack.GetAreaInfo().groupId; - z = intersectionCallBack.GetAreaInfo().ground_Z; - return true; - } - return false; -} - -void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const +bool DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional reqLiquidType, VMAP::AreaAndLiquidData& data) const { G3D::Vector3 v(x, y, z + 0.5f); DynamicTreeLocationInfoCallback intersectionCallBack(phasemask); @@ -335,13 +299,16 @@ void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phas data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z; uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType(); float liquidLevel; - if (!reqLiquidType || (dynamic_cast(VMAP::VMapFactory::createOrGetVMapMgr())->GetLiquidFlagsPtr(liquidType) & reqLiquidType)) + if (!reqLiquidType || (dynamic_cast(VMAP::VMapFactory::createOrGetVMapMgr())->GetLiquidFlagsPtr(liquidType) & *reqLiquidType)) if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), liquidLevel)) data.liquidInfo.emplace(liquidType, liquidLevel); - data.areaInfo.emplace(0, + data.areaInfo.emplace(intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(), + 0, intersectionCallBack.GetLocationInfo().rootId, - intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(), - intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags()); + intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags(), + 0); + return true; } + return false; } diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h index 62bd7a85d..e2ddca550 100644 --- a/src/common/Collision/DynamicTree.h +++ b/src/common/Collision/DynamicTree.h @@ -19,6 +19,7 @@ #define _DYNTREE_H #include "Define.h" +#include "Optional.h" namespace G3D { @@ -47,8 +48,7 @@ public: bool GetIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const G3D::Vector3& endPos, float& maxDist) const; - bool GetAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const; - void GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const; + bool GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional reqLiquidType, VMAP::AreaAndLiquidData& data) const; bool GetObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1, const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos, diff --git a/src/common/Collision/Management/IVMapMgr.h b/src/common/Collision/Management/IVMapMgr.h index f99c957c3..410743f76 100644 --- a/src/common/Collision/Management/IVMapMgr.h +++ b/src/common/Collision/Management/IVMapMgr.h @@ -52,20 +52,23 @@ namespace VMAP { struct AreaInfo { - AreaInfo(int32 _adtId, int32 _rootId, int32 _groupId, uint32 _flags) - : adtId(_adtId), rootId(_rootId), groupId(_groupId), mogpFlags(_flags) { } - int32 const adtId; - int32 const rootId; - int32 const groupId; - uint32 const mogpFlags; + AreaInfo() = default; + AreaInfo(int32 _groupId, int32 _adtId, int32 _rootId, uint32 _mogpFlags, uint32 _uniqueId) + : groupId(_groupId), adtId(_adtId), rootId(_rootId), mogpFlags(_mogpFlags), uniqueId(_uniqueId) { } + int32 groupId = 0; + int32 adtId = 0; + int32 rootId = 0; + uint32 mogpFlags = 0; + uint32 uniqueId = 0; }; struct LiquidInfo { + LiquidInfo() = default; LiquidInfo(uint32 _type, float _level) : type(_type), level(_level) {} - uint32 const type; - float const level; + uint32 type = 0; + float level = 0.0f; }; float floorZ = VMAP_INVALID_HEIGHT; @@ -120,14 +123,12 @@ namespace VMAP [[nodiscard]] bool isMapLoadingEnabled() const { return (iEnableLineOfSightCalc || iEnableHeightCalc ); } [[nodiscard]] virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0; + /** Query world model area info. \param z gets adjusted to the ground height for which this are info is valid */ - virtual bool GetAreaInfo(uint32 pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0; - virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const = 0; - // get both area + liquid data in a single vmap lookup - virtual void GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const = 0; + virtual bool GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional reqLiquidType, AreaAndLiquidData& data) const = 0; }; } diff --git a/src/common/Collision/Management/MMapMgr.cpp b/src/common/Collision/Management/MMapMgr.cpp index 77db7fbbc..d3c450097 100644 --- a/src/common/Collision/Management/MMapMgr.cpp +++ b/src/common/Collision/Management/MMapMgr.cpp @@ -138,8 +138,7 @@ namespace MMAP uint32 packedGridPos = packTileID(x, y); if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end()) { - // Peiru: Commented out for now because Playerbots system uses this method to load or check loaded maps and will spam logs -// LOG_ERROR("maps", "MMAP:loadMap: Asked to load already loaded navmesh tile. {:03}{:02}{:02}.mmtile", mapId, x, y); + LOG_ERROR("maps", "MMAP:loadMap: Asked to load already loaded navmesh tile. {:03}{:02}{:02}.mmtile", mapId, x, y); return false; } diff --git a/src/common/Collision/Management/VMapMgr2.cpp b/src/common/Collision/Management/VMapMgr2.cpp index 46df0b330..7639c9c6b 100644 --- a/src/common/Collision/Management/VMapMgr2.cpp +++ b/src/common/Collision/Management/VMapMgr2.cpp @@ -253,70 +253,8 @@ namespace VMAP return VMAP_INVALID_HEIGHT_VALUE; } - bool VMapMgr2::GetAreaInfo(uint32 mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const + bool VMapMgr2::GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional reqLiquidType, AreaAndLiquidData& data) const { -#if defined(ENABLE_VMAP_CHECKS) - if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) -#endif - { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); - if (instanceTree != iInstanceMapTrees.end()) - { - Vector3 pos = convertPositionToInternalRep(x, y, z); - bool result = instanceTree->second->GetAreaInfo(pos, flags, adtId, rootId, groupId); - // z is not touched by convertPositionToInternalRep(), so just copy - z = pos.z; - return result; - } - } - - return false; - } - - bool VMapMgr2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const - { -#if defined(ENABLE_VMAP_CHECKS) - if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) -#endif - { - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); - if (instanceTree != iInstanceMapTrees.end()) - { - LocationInfo info; - Vector3 pos = convertPositionToInternalRep(x, y, z); - if (instanceTree->second->GetLocationInfo(pos, info)) - { - floor = info.ground_Z; - ASSERT(floor < std::numeric_limits::max()); - type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc - mogpFlags = info.hitModel->GetMogpFlags(); - if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType)) - { - return false; - } - if (info.hitInstance->GetLiquidLevel(pos, info, level)) - { - return true; - } - } - } - } - - return false; - } - - void VMapMgr2::GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const - { - if (IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) - { - data.floorZ = z; - int32 adtId, rootId, groupId; - uint32 flags; - if (GetAreaInfo(mapId, x, y, data.floorZ, flags, adtId, rootId, groupId)) - data.areaInfo.emplace(adtId, rootId, groupId, flags); - return; - } - InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { @@ -325,16 +263,22 @@ namespace VMAP if (instanceTree->second->GetLocationInfo(pos, info)) { data.floorZ = info.ground_Z; - uint32 liquidType = info.hitModel->GetLiquidType(); - float liquidLevel; - if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & reqLiquidType)) - if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel)) - data.liquidInfo.emplace(liquidType, liquidLevel); + if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) + { + uint32 liquidType = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc + float liquidLevel; + if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & *reqLiquidType)) + if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel)) + data.liquidInfo.emplace(liquidType, liquidLevel); + } if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) - data.areaInfo.emplace(info.hitInstance->adtId, info.rootId, info.hitModel->GetWmoID(), info.hitModel->GetMogpFlags()); + data.areaInfo.emplace(info.hitModel->GetWmoID(), info.hitInstance->adtId, info.rootId, info.hitModel->GetMogpFlags(), info.hitInstance->ID); + return true; } } + + return false; } WorldModel* VMapMgr2::acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags/* Only used when creating the model */) diff --git a/src/common/Collision/Management/VMapMgr2.h b/src/common/Collision/Management/VMapMgr2.h index 8eb7ff823..5fc4106d2 100644 --- a/src/common/Collision/Management/VMapMgr2.h +++ b/src/common/Collision/Management/VMapMgr2.h @@ -115,9 +115,7 @@ namespace VMAP bool processCommand(char* /*command*/) override { return false; } // for debug and extensions - bool GetAreaInfo(uint32 pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override; - bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const override; - void GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const override; + bool GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional reqLiquidType, AreaAndLiquidData& data) const override; WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags); void releaseModelInstance(const std::string& filename); diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp index 66c711c9c..bb9577d4e 100644 --- a/src/common/Collision/Maps/MapTree.cpp +++ b/src/common/Collision/Maps/MapTree.cpp @@ -51,22 +51,6 @@ namespace VMAP bool hit; }; - class AreaInfoCallback - { - public: - AreaInfoCallback(ModelInstance* val): prims(val) {} - void operator()(const Vector3& point, uint32 entry) - { -#if defined(VMAP_DEBUG) - LOG_DEBUG("maps", "AreaInfoCallback: trying to intersect '{}'", prims[entry].name); -#endif - prims[entry].intersectPoint(point, aInfo); - } - - ModelInstance* prims; - AreaInfo aInfo; - }; - class LocationInfoCallback { public: @@ -99,22 +83,6 @@ namespace VMAP return tilefilename.str(); } - bool StaticMapTree::GetAreaInfo(Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const - { - AreaInfoCallback intersectionCallBack(iTreeValues); - iTree.intersectPoint(pos, intersectionCallBack); - if (intersectionCallBack.aInfo.result) - { - flags = intersectionCallBack.aInfo.flags; - adtId = intersectionCallBack.aInfo.adtId; - rootId = intersectionCallBack.aInfo.rootId; - groupId = intersectionCallBack.aInfo.groupId; - pos.z = intersectionCallBack.aInfo.ground_Z; - return true; - } - return false; - } - bool StaticMapTree::GetLocationInfo(const Vector3& pos, LocationInfo& info) const { LocationInfoCallback intersectionCallBack(iTreeValues, info); diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h index 1a5db5693..09e426e3f 100644 --- a/src/common/Collision/Maps/MapTree.h +++ b/src/common/Collision/Maps/MapTree.h @@ -30,6 +30,12 @@ namespace VMAP enum class ModelIgnoreFlags : uint32; enum class LoadResult : uint8; + struct GroupLocationInfo + { + const GroupModel* hitModel = nullptr; + int32 rootId = -1; + }; + struct LocationInfo { LocationInfo(): ground_Z(-G3D::inf()) { } @@ -73,7 +79,6 @@ namespace VMAP [[nodiscard]] bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2, ModelIgnoreFlags ignoreFlags) const; bool GetObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const; [[nodiscard]] float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const; - bool GetAreaInfo(G3D::Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const; bool GetLocationInfo(const G3D::Vector3& pos, LocationInfo& info) const; bool InitMap(const std::string& fname, VMapMgr2* vm); diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index dacca121d..eebc7e62d 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -203,27 +203,6 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto return hit; } -void GameObjectModel::IntersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const -{ - if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject()) - return; - - if (!iBound.contains(point)) - return; - - // child bounds are defined in object space: - Vector3 pModel = iInvRot * (point - iPos) * iInvScale; - Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); - float zDist; - if (iModel->IntersectPoint(pModel, zDirModel, zDist, info)) - { - Vector3 modelGround = pModel + zDist * zDirModel; - float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; - if (info.ground_Z < world_Z) - info.ground_Z = world_Z; - } -} - bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const { if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject()) @@ -236,7 +215,9 @@ bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationI Vector3 pModel = iInvRot * (point - iPos) * iInvScale; Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); float zDist; - if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info)) + + VMAP::GroupLocationInfo groupInfo; + if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo)) { Vector3 modelGround = pModel + zDist * zDirModel; float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index 204d114e2..5938a5c1d 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -70,7 +70,6 @@ public: [[nodiscard]] bool IsMapObject() const { return isWmo; } bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask, VMAP::ModelIgnoreFlags ignoreFlags) const; - void IntersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const; bool GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const; bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const; diff --git a/src/common/Collision/Models/ModelInstance.cpp b/src/common/Collision/Models/ModelInstance.cpp index deba465d6..c5b6fbfdb 100644 --- a/src/common/Collision/Models/ModelInstance.cpp +++ b/src/common/Collision/Models/ModelInstance.cpp @@ -63,44 +63,6 @@ namespace VMAP return hit; } - void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo& info) const - { - if (!iModel) - { -#ifdef VMAP_DEBUG - std::cout << "\n"; -#endif - return; - } - - // M2 files don't contain area info, only WMO files - if (flags & MOD_M2) - { - return; - } - if (!iBound.contains(p)) - { - return; - } - // child bounds are defined in object space: - Vector3 pModel = iInvRot * (p - iPos) * iInvScale; - Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); - float zDist; - if (iModel->IntersectPoint(pModel, zDirModel, zDist, info)) - { - Vector3 modelGround = pModel + zDist * zDirModel; - // Transform back to world space. Note that: - // Mat * vec == vec * Mat.transpose() - // and for rotation matrices: Mat.inverse() == Mat.transpose() - float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; - if (info.ground_Z < world_Z) - { - info.ground_Z = world_Z; - info.adtId = adtId; - } - } - } - bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const { if (!iModel) @@ -124,7 +86,9 @@ namespace VMAP Vector3 pModel = iInvRot * (p - iPos) * iInvScale; Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f); float zDist; - if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info)) + + GroupLocationInfo groupInfo; + if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo)) { Vector3 modelGround = pModel + zDist * zDirModel; // Transform back to world space. Note that: @@ -133,6 +97,8 @@ namespace VMAP float world_Z = ((modelGround * iInvRot) * iScale + iPos).z; if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection? { + info.rootId = groupInfo.rootId; + info.hitModel = groupInfo.hitModel; info.ground_Z = world_Z; info.hitInstance = this; return true; diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h index 8cadb4197..3476a514d 100644 --- a/src/common/Collision/Models/ModelInstance.h +++ b/src/common/Collision/Models/ModelInstance.h @@ -66,7 +66,6 @@ namespace VMAP ModelInstance(const ModelSpawn& spawn, WorldModel* model); void setUnloaded() { iModel = nullptr; } bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit, ModelIgnoreFlags ignoreFlags) const; - void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const; bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const; bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const; WorldModel* getWorldModel() { return iModel; } diff --git a/src/common/Collision/Models/WorldModel.cpp b/src/common/Collision/Models/WorldModel.cpp index 0c29124a7..53bd55a2d 100644 --- a/src/common/Collision/Models/WorldModel.cpp +++ b/src/common/Collision/Models/WorldModel.cpp @@ -20,9 +20,9 @@ #include "ModelIgnoreFlags.h" #include "ModelInstance.h" #include "VMapDefinitions.h" +#include using G3D::Vector3; -using G3D::Ray; template<> struct BoundsTrait { @@ -451,21 +451,46 @@ namespace VMAP return callback.hit; } - bool GroupModel::IsInsideObject(const Vector3& pos, const Vector3& down, float& z_dist) const + inline bool IsInsideOrAboveBound(G3D::AABox const& bounds, const G3D::Point3& point) { - if (triangles.empty() || !iBound.contains(pos)) + return point.x >= bounds.low().x + && point.y >= bounds.low().y + && point.z >= bounds.low().z + && point.x <= bounds.high().x + && point.y <= bounds.high().y; + } + + GroupModel::InsideResult GroupModel::IsInsideObject(G3D::Ray const& ray, float& z_dist) const + { + if (triangles.empty() || !IsInsideOrAboveBound(iBound, ray.origin())) + return OUT_OF_BOUNDS; + + if (meshTree.bound().high().z >= ray.origin().z) { - return false; + float dist = G3D::finf(); + if (IntersectRay(ray, dist, false)) + { + z_dist = dist - 0.1f; + return INSIDE; + } + if (meshTree.bound().contains(ray.origin())) + return MAYBE_INSIDE; } - Vector3 rPos = pos - 0.1f * down; - float dist = G3D::inf(); - G3D::Ray ray(rPos, down); - bool hit = IntersectRay(ray, dist, false); - if (hit) + else { - z_dist = dist - 0.1f; + // some group models don't have any floor to intersect with + // so we should attempt to intersect with a model part below this group + // then find back where we originated from (in WorldModel::GetLocationInfo) + float dist = G3D::finf(); + float delta = ray.origin().z - meshTree.bound().high().z; + if (IntersectRay(ray.bumpedRay(delta), dist, false)) + { + z_dist = dist - 0.1f + delta; + return ABOVE; + } } - return hit; + + return OUT_OF_BOUNDS; } bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const @@ -541,76 +566,58 @@ namespace VMAP class WModelAreaCallback { public: - WModelAreaCallback(const std::vector& vals, const Vector3& down): - prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { } - std::vector::const_iterator prims; - std::vector::const_iterator hit; - float minVol; - float zDist; - Vector3 zVec; - void operator()(const Vector3& point, uint32 entry) + WModelAreaCallback(std::vector const& vals) : + prims(vals), hit() { } + std::vector const& prims; + std::array hit; + bool operator()(G3D::Ray const& ray, uint32 entry, float& distance, bool /*stopAtFirstHit*/) { float group_Z; - //float pVol = prims[entry].GetBound().volume(); - //if (pVol < minVol) - //{ - /* if (prims[entry].iBound.contains(point)) */ - if (prims[entry].IsInsideObject(point, zVec, group_Z)) + if (GroupModel::InsideResult result = prims[entry].IsInsideObject(ray, group_Z); result != GroupModel::OUT_OF_BOUNDS) { - //minVol = pVol; - //hit = prims + entry; - if (group_Z < zDist) + if (result != GroupModel::MAYBE_INSIDE) { - zDist = group_Z; - hit = prims + entry; + if (group_Z < distance) + { + distance = group_Z; + hit[result] = &prims[entry]; + return true; + } } -#ifdef VMAP_DEBUG - const GroupModel& gm = prims[entry]; - printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(), - gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z, - gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z); -#endif + else + hit[result] = &prims[entry]; } - //} - //std::cout << "trying to intersect '" << prims[entry].name << "'\n"; + return false; } }; - bool WorldModel::IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const + bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const { if (groupModels.empty()) { return false; } - WModelAreaCallback callback(groupModels, down); - groupTree.intersectPoint(p, callback); - if (callback.hit != groupModels.end()) + WModelAreaCallback callback(groupModels); + G3D::Ray r(p - down * 0.1f, down); + float zDist = groupTree.bound().extent().length(); + groupTree.intersectRay(r, callback, zDist, false); + if (callback.hit[GroupModel::INSIDE]) { info.rootId = RootWMOID; - info.groupId = callback.hit->GetWmoID(); - info.flags = callback.hit->GetMogpFlags(); - info.result = true; - dist = callback.zDist; + info.hitModel = callback.hit[GroupModel::INSIDE]; + dist = zDist; return true; } - return false; - } - bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const - { - if (groupModels.empty()) - { - return false; - } - - WModelAreaCallback callback(groupModels, down); - groupTree.intersectPoint(p, callback); - if (callback.hit != groupModels.end()) + // some group models don't have any floor to intersect with + // so we should attempt to intersect with a model part below the group `p` is in (stored in GroupModel::ABOVE) + // then find back where we originated from (GroupModel::MAYBE_INSIDE) + if (callback.hit[GroupModel::MAYBE_INSIDE] && callback.hit[GroupModel::ABOVE]) { info.rootId = RootWMOID; - info.hitModel = &(*callback.hit); - dist = callback.zDist; + info.hitModel = callback.hit[GroupModel::MAYBE_INSIDE]; + dist = zDist; return true; } return false; diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h index 9febf86e7..2d5d8126b 100644 --- a/src/common/Collision/Models/WorldModel.h +++ b/src/common/Collision/Models/WorldModel.h @@ -29,6 +29,7 @@ namespace VMAP class TreeNode; struct AreaInfo; struct LocationInfo; + struct GroupLocationInfo; enum class ModelIgnoreFlags : uint32; class MeshTriangle @@ -81,12 +82,14 @@ namespace VMAP void setMeshData(std::vector& vert, std::vector& tri); void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = nullptr; } bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const; - bool IsInsideObject(const G3D::Vector3& pos, const G3D::Vector3& down, float& z_dist) const; + enum InsideResult { INSIDE = 0, MAYBE_INSIDE = 1, ABOVE = 2, OUT_OF_BOUNDS = -1 }; + InsideResult IsInsideObject(G3D::Ray const& ray, float& z_dist) const; bool GetLiquidLevel(const G3D::Vector3& pos, float& liqHeight) const; [[nodiscard]] uint32 GetLiquidType() const; bool writeToFile(FILE* wf); bool readFromFile(FILE* rf); - [[nodiscard]] const G3D::AABox& GetBound() const { return iBound; } + [[nodiscard]] G3D::AABox const& GetBound() const { return iBound; } + [[nodiscard]] G3D::AABox const& GetMeshTreeBound() const { return meshTree.bound(); } [[nodiscard]] uint32 GetMogpFlags() const { return iMogpFlags; } [[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; } void GetMeshData(std::vector& outVertices, std::vector& outTriangles, WmoLiquid*& liquid); @@ -109,8 +112,7 @@ namespace VMAP void setGroupModels(std::vector& models); void setRootWmoID(uint32 id) { RootWMOID = id; } bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) const; - bool IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const; - bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const; + bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const; bool writeFile(const std::string& filename); bool readFile(const std::string& filename); void GetGroupModels(std::vector& outGroupModels); diff --git a/src/common/Utilities/CircularBuffer.h b/src/common/Utilities/CircularBuffer.h index 4c23099c9..55681c87b 100644 --- a/src/common/Utilities/CircularBuffer.h +++ b/src/common/Utilities/CircularBuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE +# Copyright (C) 2016+ AzerothCore * * This file was based on * https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/ diff --git a/src/common/Utilities/DataMap.h b/src/common/Utilities/DataMap.h index 170539a67..31910f945 100644 --- a/src/common/Utilities/DataMap.h +++ b/src/common/Utilities/DataMap.h @@ -1,5 +1,5 @@ /* - * Originally written by Rochet2 - Copyright (C) 2018+ AzerothCore , released under GNU AGPL v3 license: http://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + * Originally written by Rochet2 - Copyright (C) 2018+ AzerothCore */ #ifndef _DATA_MAP_H_ diff --git a/src/common/Utilities/EventMap.h b/src/common/Utilities/EventMap.h index b89d4e3f7..a382910b8 100644 --- a/src/common/Utilities/EventMap.h +++ b/src/common/Utilities/EventMap.h @@ -97,32 +97,6 @@ public: return _eventMap.empty(); } - /** - * @return Current internal time as uint32 milliseconds - * - * was removed in core https://github.com/azerothcore/azerothcore-wotlk/pull/23121, - * but still required atm for mod-playerbot. - */ - uint32 GetTimer() const - { - return static_cast(duration_cast(_time.time_since_epoch()).count()); - } - - /** - * @return Time of found even - * - * was removed in core https://github.com/azerothcore/azerothcore-wotlk/pull/23121, - * but still required atm for mod-playerbot. - */ - uint32 GetNextEventTime(uint16 eventId) const - { - auto timeUntil = GetTimeUntilEvent(eventId); - if (timeUntil == Milliseconds::max()) - return 0; - - return GetTimer() + static_cast(timeUntil.count()); - } - /** * @name SetPhase * @brief Sets the phase of the map (absolute). diff --git a/src/common/Utilities/EventProcessor.h b/src/common/Utilities/EventProcessor.h index dc8779957..644c2b643 100644 --- a/src/common/Utilities/EventProcessor.h +++ b/src/common/Utilities/EventProcessor.h @@ -120,7 +120,7 @@ class EventProcessor [[nodiscard]] uint64 CalculateQueueTime(uint64 delay) const; void CancelEventGroup(uint8 group); - bool HaveEventList() const { return !m_events.empty(); } + bool HasEvents() const { return !m_events.empty(); } protected: uint64 m_time{0}; diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h index a7669fa16..3976d4e76 100644 --- a/src/common/Utilities/Util.h +++ b/src/common/Utilities/Util.h @@ -347,7 +347,6 @@ inline wchar_t wcharToLower(wchar_t wchar) void wstrToUpper(std::wstring& str); void wstrToLower(std::wstring& str); -void strToLower(std::string& str); std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension); diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp index 46e5dafe8..b3a7eaa86 100644 --- a/src/server/database/Updater/UpdateFetcher.cpp +++ b/src/server/database/Updater/UpdateFetcher.cpp @@ -162,7 +162,7 @@ UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() cons // data/sql for (auto const& itr : moduleList) { - std::string path = _sourceDirectory->generic_string() + "/modules/" + itr + "/data/sql/" + _dbModuleName; // modules/mod-name/sql/world + std::string path = _sourceDirectory->generic_string() + "/modules/" + itr + "/data/sql/" + _dbModuleName; // modules/mod-name/data/sql/db-world Path const p(path); if (!is_directory(p)) diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 8d0804f3b..f21e93230 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -83,29 +83,19 @@ WorldObject* CreatureAI::GetSummoner() const inline bool IsValidCombatTarget(Creature* source, Player* target) { if (target->IsGameMaster()) - { return false; - } if (!source->IsInWorld() || !target->IsInWorld()) - { return false; - } if (!source->IsAlive() || !target->IsAlive()) - { return false; - } if (!source->InSamePhase(target)) - { return false; - } - if (source->HasUnitState(UNIT_STATE_IN_FLIGHT) || target->HasUnitState(UNIT_STATE_IN_FLIGHT)) - { + if (source->IsInFlight() || target->IsInFlight()) return false; - } return true; } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index b1b6c65bd..aef961781 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -950,6 +950,9 @@ bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e) case SMART_TARGET_VEHICLE_PASSENGER: return sizeof(SmartTarget::vehicle); // case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: return sizeof(SmartTarget::goClosest); case SMART_TARGET_PLAYER_WITH_AURA: return sizeof(SmartTarget::playerWithAura); + case SMART_TARGET_RANDOM_POINT: return sizeof(SmartTarget::randomPoint); + case SMART_TARGET_SUMMONED_CREATURES: return sizeof(SmartTarget::summonedCreatures); + case SMART_TARGET_INSTANCE_STORAGE: return sizeof(SmartTarget::instanceStorage); default: LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using a target {} with no unused params specified in SmartAIMgr::CheckUnusedTargetParams(), please report this.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType()); diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 1e615b6d5..2451aac3d 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1826,6 +1826,15 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve // someone on this realm has already completed that achievement if (sAchievementMgr->IsRealmCompleted(achievement)) return false; + + // A character may only have 1 race-specific 'Realm First!' achievement + // prevent clever use of the race/faction change service to obtain multiple 'Realm First!' achievements + constexpr std::array raceSpecificRealmFirstAchievements { 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413 }; + bool isRaceSpecific = std::ranges::find(raceSpecificRealmFirstAchievements, achievement->ID) != std::ranges::end(raceSpecificRealmFirstAchievements); + if (isRaceSpecific) + for (uint32 raceAchievementId : raceSpecificRealmFirstAchievements) + if (raceAchievementId != achievement->ID && HasAchieved(raceAchievementId)) + return false; } // pussywizard: progress will be deleted after getting the achievement (optimization) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index adddbd6d1..ce733b3a5 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -33,17 +33,6 @@ class WorldObject; struct GameTele; -enum PlayerChatTag -{ - CHAT_TAG_NONE = 0x00, - CHAT_TAG_AFK = 0x01, - CHAT_TAG_DND = 0x02, - CHAT_TAG_GM = 0x04, - CHAT_TAG_COM = 0x08, // Commentator - CHAT_TAG_DEV = 0x10, // Developer -}; -typedef uint32 ChatTagFlags; - class AC_GAME_API ChatHandler { public: diff --git a/src/server/game/Combat/UnitEvents.h b/src/server/game/Combat/UnitEvents.h index db1408089..da2c1a965 100644 --- a/src/server/game/Combat/UnitEvents.h +++ b/src/server/game/Combat/UnitEvents.h @@ -92,27 +92,13 @@ private: }; ThreatMgr* iThreatMgr; public: - ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iFValue(0.f), iThreatMgr(nullptr) - { - iHostileReference = nullptr; - } + ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = nullptr; } - ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iFValue(0.f), iThreatMgr(nullptr) - { - iHostileReference = pHostileReference; - } + ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; } - ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) - { - iHostileReference = pHostileReference; - iFValue = pValue; - } + ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; iFValue = pValue; } - ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) - { - iHostileReference = pHostileReference; - iBValue = pValue; - } + ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; iBValue = pValue; } [[nodiscard]] int32 getIValue() const { return iIValue; } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index bd98a2570..23077fe9b 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1373,8 +1373,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) m_spawnId = sObjectMgr->GenerateCreatureSpawnId(); CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId); - data.spawnId = m_spawnId; - + data.spawnId = m_spawnId; // mod_playerbots uint32 displayId = GetNativeDisplayId(); uint32 npcflag = GetNpcFlags(); uint32 unit_flags = GetUnitFlags(); @@ -3498,7 +3497,7 @@ bool Creature::IsMovementPreventedByCasting() const void Creature::SetCannotReachTarget(ObjectGuid const& cannotReach) { if (cannotReach == m_cannotReachTarget) -{ + { return; } diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index 92e1c4bb2..e1022f122 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -365,7 +365,7 @@ typedef std::unordered_map EquipmentInfo struct CreatureData { CreatureData() = default; - ObjectGuid::LowType spawnId{0}; + ObjectGuid::LowType spawnId{ 0 }; // mod_playerbots uint32 id1{0}; // entry in creature_template uint32 id2{0}; // entry in creature_template uint32 id3{0}; // entry in creature_template diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 26ecd4dc4..17268ca43 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3294,9 +3294,7 @@ void Player::learnSpell(uint32 spellId, bool temporary /*= false*/, bool learnFr // Xinef: don't allow to learn active spell once more if (HasActiveSpell(spellId)) { -#ifndef MOD_PLAYERBOTS LOG_DEBUG("entities.player", "Player ({}) tries to learn already active spell: {}", GetGUID().ToString(), spellId); -#endif return; } @@ -4332,28 +4330,6 @@ void Player::DeleteOldRecoveryItems(uint32 keepDays) } } -void Player::SetMovement(PlayerMovementType pType) -{ - WorldPacket data; - const PackedGuid& guid = GetPackGUID(); - switch (pType) - { - case MOVE_WATER_WALK: - data.Initialize(SMSG_MOVE_WATER_WALK, guid.size() + 4); - break; - case MOVE_LAND_WALK: - data.Initialize(SMSG_MOVE_LAND_WALK, guid.size() + 4); - break; - default: - LOG_ERROR("entities.player", "Player::SetMovement: Unsupported move type ({}), data not sent to client.", pType); - return; - } - data << guid; - data << GetSession()->GetOrderCounter(); // movement counter - SendDirectMessage(&data); - GetSession()->IncrementOrderCounter(); -} - /* Preconditions: - a resurrectable corpse must not be loaded for the player (only bones) - the player must be in world @@ -4389,7 +4365,6 @@ void Player::BuildPlayerRepop() } GetMap()->AddToMap(corpse); SetHealth(1); // convert player body to ghost - SetMovement(MOVE_WATER_WALK); SetWaterWalking(true); if (!IsImmobilizedState()) @@ -4430,7 +4405,6 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) SetDynamicFlag(UNIT_DYNFLAG_REFER_A_FRIEND); setDeathState(DeathState::Alive); - SetMovement(MOVE_LAND_WALK); SendMoveRoot(false); SetWaterWalking(false); m_deathTimer = 0; @@ -9390,11 +9364,7 @@ void Player::Say(std::string_view text, Language language, WorldObject const* /* { std::string _text(text); if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_SAY, language, _text)) - { return; - } - - sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text); @@ -9416,11 +9386,7 @@ void Player::Yell(std::string_view text, Language language, WorldObject const* / std::string _text(text); if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_YELL, language, _text)) - { return; - } - - sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text); @@ -9442,11 +9408,7 @@ void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/, std::string _text(text); if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text)) - { return; - } - - sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); @@ -9475,11 +9437,7 @@ void Player::Whisper(std::string_view text, Language language, Player* target, b std::string _text(text); if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_WHISPER, language, _text, target)) - { return; - } - - sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, language, this, this, _text); @@ -11686,7 +11644,7 @@ void Player::SendInitialPacketsAfterAddToMap() GetSession()->IncrementOrderCounter(); } - if (HasAuraType(SPELL_AURA_WATER_WALK)) + if (HasAuraType(SPELL_AURA_WATER_WALK) || HasAura(8326)) { uint32 const counter = GetSession()->GetOrderCounter(); setCompoundState << uint8(2 + GetPackGUID().size() + 4); @@ -12096,18 +12054,6 @@ void Player::GetAurasForTarget(Unit* target, bool force /*= false*/) if (!target || (!force && target->GetVisibleAuras()->empty())) // speedup things return; - /*! Blizz sends certain movement packets sometimes even before CreateObject - These movement packets are usually found in SMSG_COMPRESSED_MOVES - */ - if (target->HasFeatherFallAura()) - target->SendMovementFeatherFall(this); - - if (target->HasWaterWalkAura()) - target->SendMovementWaterWalking(this); - - if (target->HasHoverAura()) - target->SendMovementHover(this); - WorldPacket data(SMSG_AURA_UPDATE_ALL); data<< target->GetPackGUID(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 399ad652a..3befdbc0c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -656,7 +656,7 @@ enum PlayerSlots #define INVENTORY_SLOT_BAG_0 255 -enum EquipmentSlots : uint32 // 19 slots +enum EquipmentSlots : uint32 // 19 slots { EQUIPMENT_SLOT_START = 0, EQUIPMENT_SLOT_HEAD = 0, @@ -827,6 +827,16 @@ enum EnviromentalDamage DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss }; +enum PlayerChatTag +{ + CHAT_TAG_NONE = 0x00, + CHAT_TAG_AFK = 0x01, + CHAT_TAG_DND = 0x02, + CHAT_TAG_GM = 0x04, + CHAT_TAG_COM = 0x08, // Commentator tag. Do not exist in clean client + CHAT_TAG_DEV = 0x10, +}; + enum PlayedTimeIndex { PLAYED_TIME_TOTAL = 0, diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 669bd3bc3..96910f4eb 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1463,6 +1463,9 @@ void Player::UpdatePvPState() if (pvpInfo.IsHostile) // in hostile area { + if (IsInFlight()) // on taxi + return; + if (!IsPvP() || pvpInfo.EndTimer != 0) UpdatePvP(true, true); } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b67a2ecd3..9168e8dd2 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1864,7 +1864,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) auto canTakeMeleeDamage = [&]() { - return victim->IsAlive() && !victim->HasUnitState(UNIT_STATE_IN_FLIGHT) && (!victim->IsCreature() || !victim->ToCreature()->IsEvadingAttacks()); + return victim->IsAlive() && !victim->IsInFlight() && (!victim->IsCreature() || !victim->ToCreature()->IsEvadingAttacks()); }; if (!canTakeMeleeDamage()) @@ -1956,10 +1956,11 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) Probability = 0.65f * victim->GetLevel() + 0.5f; uint32 VictimDefense = victim->GetDefenseSkillValue(); + uint32 VictimAuraDefense = -victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE) * 25; uint32 AttackerMeleeSkill = GetUnitMeleeSkill(); // xinef: fix daze mechanics - Probability -= ((float)VictimDefense - AttackerMeleeSkill) * 0.1428f; + Probability -= ((float)VictimDefense + (float)VictimAuraDefense - AttackerMeleeSkill) * 0.1428f; if (Probability > 40.0f) Probability = 40.0f; @@ -18429,10 +18430,8 @@ void Unit::SetControlled(bool apply, UnitState state, Unit* source /*= nullptr*/ void Unit::SetStunned(bool apply) { - if (HasUnitState(UNIT_STATE_IN_FLIGHT)) - { + if (IsInFlight()) return; - } if (apply) { @@ -21520,18 +21519,3 @@ Player const* Unit::GetClientControlling() const } return nullptr; } - -void Unit::SetCannotReachTargetUnit(bool cannotReach, bool isChase) -{ - if (cannotReach == m_cannotReachTarget) - { - return; - } - - m_cannotReachTarget = cannotReach; -} - -bool Unit::CanNotReachTarget() const -{ - return m_cannotReachTarget; -} diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index a7e8aba76..7313a7562 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2051,8 +2051,6 @@ public: // Debug void OutDebugInfo() const; std::string GetDebugInfo() const override; - void SetCannotReachTargetUnit(bool target, bool isChase); - [[nodiscard]] bool CanNotReachTarget() const; bool m_cannotReachTarget; diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index 8b30a81d1..86822d05e 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -45,7 +45,7 @@ enum VehicleFlags VEHICLE_FLAG_CUSTOM_PITCH = 0x00000040, // If set use pitchMin and pitchMax from DBC, otherwise pitchMin = -pi/2, pitchMax = pi/2 VEHICLE_FLAG_ADJUST_AIM_ANGLE = 0x00000400, // Lua_IsVehicleAimAngleAdjustable VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800, // Lua_IsVehicleAimPowerAdjustable - VEHICLE_FLAG_FIXED_POSITION = 0x00200000 // Used for cannons, when they should be rooted + VEHICLE_FLAG_FIXED_POSITION = 0x00200000 // Used for cannons, when they should be rooted (mod_playerbots, not sure this is still valid since its only used my playerbot) }; enum VehicleSpells diff --git a/src/server/game/Grids/GridTerrainData.cpp b/src/server/game/Grids/GridTerrainData.cpp index e2439dc2e..ab4a1c286 100644 --- a/src/server/game/Grids/GridTerrainData.cpp +++ b/src/server/game/Grids/GridTerrainData.cpp @@ -527,9 +527,11 @@ float GridTerrainData::getLiquidLevel(float x, float y) const } // Get water state on map -LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float collisionHeight, uint8 ReqLiquidType) const +LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float collisionHeight, Optional ReqLiquidType) const { LiquidData liquidData; + liquidData.Status = LIQUID_MAP_NO_WATER; + if (!_loadedLiquidData) return liquidData; @@ -575,7 +577,7 @@ LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float } // Check req liquid type mask - if (type != 0 && (!ReqLiquidType || (ReqLiquidType & type) != 0)) + if (type != 0 && (!ReqLiquidType || (*ReqLiquidType & type) != 0)) { // Check water level: // Check water height map diff --git a/src/server/game/Grids/GridTerrainData.h b/src/server/game/Grids/GridTerrainData.h index 082e42282..18324d574 100644 --- a/src/server/game/Grids/GridTerrainData.h +++ b/src/server/game/Grids/GridTerrainData.h @@ -186,7 +186,7 @@ struct LoadedHoleData HolesType holes; }; -enum LiquidStatus +enum LiquidStatus : uint32 { LIQUID_MAP_NO_WATER = 0x00000000, LIQUID_MAP_ABOVE_WATER = 0x00000001, @@ -249,7 +249,7 @@ public: inline float getHeight(float x, float y) const { return (this->*_gridGetHeight)(x, y); } float getMinHeight(float x, float y) const; float getLiquidLevel(float x, float y) const; - LiquidData const GetLiquidData(float x, float y, float z, float collisionHeight, uint8 ReqLiquidType) const; + LiquidData const GetLiquidData(float x, float y, float z, float collisionHeight, Optional ReqLiquidType) const; }; #endif diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index c208fc0ab..b9cdb1e35 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -262,6 +262,7 @@ public: void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag); void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag); + //mod_playerbots ObjectGuid const GetTargetIcon(uint8 id) const { return m_targetIcons[id]; } Difficulty GetDifficulty(bool isRaid) const; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index cc31bfca6..86b3cc832 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -44,48 +44,48 @@ std::string _GetGuildEventString(GuildEvents event) { switch (event) { - case GE_PROMOTION: - return "Member promotion"; - case GE_DEMOTION: - return "Member demotion"; - case GE_MOTD: - return "Guild MOTD"; - case GE_JOINED: - return "Member joined"; - case GE_LEFT: - return "Member left"; - case GE_REMOVED: - return "Member removed"; - case GE_LEADER_IS: - return "Leader is"; - case GE_LEADER_CHANGED: - return "Leader changed"; - case GE_DISBANDED: - return "Guild disbanded"; - case GE_TABARDCHANGE: - return "Tabard change"; - case GE_RANK_UPDATED: - return "Rank updated"; - case GE_RANK_DELETED: - return "Rank deleted"; - case GE_SIGNED_ON: - return "Member signed on"; - case GE_SIGNED_OFF: - return "Member signed off"; - case GE_GUILDBANKBAGSLOTS_CHANGED: - return "Bank bag slots changed"; - case GE_BANK_TAB_PURCHASED: - return "Bank tab purchased"; - case GE_BANK_TAB_UPDATED: - return "Bank tab updated"; - case GE_BANK_MONEY_SET: - return "Bank money set"; - case GE_BANK_TAB_AND_MONEY_UPDATED: - return "Bank and money updated"; - case GE_BANK_TEXT_CHANGED: - return "Bank tab text changed"; - default: - break; + case GE_PROMOTION: + return "Member promotion"; + case GE_DEMOTION: + return "Member demotion"; + case GE_MOTD: + return "Guild MOTD"; + case GE_JOINED: + return "Member joined"; + case GE_LEFT: + return "Member left"; + case GE_REMOVED: + return "Member removed"; + case GE_LEADER_IS: + return "Leader is"; + case GE_LEADER_CHANGED: + return "Leader changed"; + case GE_DISBANDED: + return "Guild disbanded"; + case GE_TABARDCHANGE: + return "Tabard change"; + case GE_RANK_UPDATED: + return "Rank updated"; + case GE_RANK_DELETED: + return "Rank deleted"; + case GE_SIGNED_ON: + return "Member signed on"; + case GE_SIGNED_OFF: + return "Member signed off"; + case GE_GUILDBANKBAGSLOTS_CHANGED: + return "Bank bag slots changed"; + case GE_BANK_TAB_PURCHASED: + return "Bank tab purchased"; + case GE_BANK_TAB_UPDATED: + return "Bank tab updated"; + case GE_BANK_MONEY_SET: + return "Bank money set"; + case GE_BANK_TAB_AND_MONEY_UPDATED: + return "Bank and money updated"; + case GE_BANK_TEXT_CHANGED: + return "Bank tab text changed"; + default: + break; } return ""; } @@ -94,20 +94,20 @@ inline uint32 _GetGuildBankTabPrice(uint8 tabId) { switch (tabId) { - case 0: - return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_0); - case 1: - return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_1); - case 2: - return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_2); - case 3: - return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_3); - case 4: - return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_4); - case 5: - return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_5); - default: - return 0; + case 0: + return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_0); + case 1: + return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_1); + case 2: + return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_2); + case 3: + return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_3); + case 4: + return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_4); + case 5: + return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_5); + default: + return 0; } } @@ -134,8 +134,9 @@ void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode // LogHolder template Guild::LogHolder::LogHolder() - : m_maxRecords(sWorld->getIntConfig(std::is_same_v ? CONFIG_GUILD_BANK_EVENT_LOG_COUNT : CONFIG_GUILD_EVENT_LOG_COUNT)), m_nextGUID(uint32(GUILD_EVENT_LOG_GUID_UNDEFINED)) -{ } + : m_maxRecords(sWorld->getIntConfig(std::is_same_v ? CONFIG_GUILD_BANK_EVENT_LOG_COUNT : CONFIG_GUILD_EVENT_LOG_COUNT)), m_nextGUID(uint32(GUILD_EVENT_LOG_GUID_UNDEFINED)) +{ +} template template void Guild::LogHolder::LoadEvent(Ts&&... args) @@ -173,7 +174,8 @@ inline uint32 Guild::LogHolder::GetNextGUID() } Guild::LogEntry::LogEntry(uint32 guildId, ObjectGuid::LowType guid) : - m_guildId(guildId), m_guid(guid), m_timestamp(GameTime::GetGameTime().count()) { } + m_guildId(guildId), m_guid(guid), m_timestamp(GameTime::GetGameTime().count()) { +} // EventLogEntry void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const @@ -185,12 +187,12 @@ void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_EVENTLOG); - stmt->SetData( index, m_guildId); + stmt->SetData(index, m_guildId); stmt->SetData(++index, m_guid); - stmt->SetData (++index, uint8(m_eventType)); + stmt->SetData(++index, uint8(m_eventType)); stmt->SetData(++index, m_playerGuid1.GetCounter()); stmt->SetData(++index, m_playerGuid2.GetCounter()); - stmt->SetData (++index, m_newRank); + stmt->SetData(++index, m_newRank); stmt->SetData(++index, m_timestamp); CharacterDatabase.ExecuteOrAppend(trans, stmt); } @@ -215,21 +217,21 @@ void Guild::BankEventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) cons uint8 index = 0; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_EVENTLOG); - stmt->SetData( index, m_guildId); + stmt->SetData(index, m_guildId); stmt->SetData(++index, m_guid); - stmt->SetData (++index, m_bankTabId); + stmt->SetData(++index, m_bankTabId); CharacterDatabase.ExecuteOrAppend(trans, stmt); index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_EVENTLOG); - stmt->SetData( index, m_guildId); + stmt->SetData(index, m_guildId); stmt->SetData(++index, m_guid); - stmt->SetData (++index, m_bankTabId); - stmt->SetData (++index, uint8(m_eventType)); + stmt->SetData(++index, m_bankTabId); + stmt->SetData(++index, uint8(m_eventType)); stmt->SetData(++index, m_playerGuid.GetCounter()); stmt->SetData(++index, m_itemOrMoney); stmt->SetData(++index, m_itemStackCount); - stmt->SetData (++index, m_destTabId); + stmt->SetData(++index, m_destTabId); stmt->SetData(++index, m_timestamp); CharacterDatabase.ExecuteOrAppend(trans, stmt); } @@ -243,19 +245,19 @@ void Guild::BankEventLogEntry::WritePacket(WorldPackets::Guild::GuildBankLogQuer switch (m_eventType) { - case GUILD_BANK_LOG_DEPOSIT_ITEM: - case GUILD_BANK_LOG_WITHDRAW_ITEM: - bankLogEntry.ItemID = int32(m_itemOrMoney); - bankLogEntry.Count = int32(m_itemStackCount); - break; - case GUILD_BANK_LOG_MOVE_ITEM: - case GUILD_BANK_LOG_MOVE_ITEM2: - bankLogEntry.ItemID = int32(m_itemOrMoney); - bankLogEntry.Count = int32(m_itemStackCount); - bankLogEntry.OtherTab = int8(m_destTabId); - break; - default: - bankLogEntry.Money = uint32(m_itemOrMoney); + case GUILD_BANK_LOG_DEPOSIT_ITEM: + case GUILD_BANK_LOG_WITHDRAW_ITEM: + bankLogEntry.ItemID = int32(m_itemOrMoney); + bankLogEntry.Count = int32(m_itemStackCount); + break; + case GUILD_BANK_LOG_MOVE_ITEM: + case GUILD_BANK_LOG_MOVE_ITEM2: + bankLogEntry.ItemID = int32(m_itemOrMoney); + bankLogEntry.Count = int32(m_itemStackCount); + bankLogEntry.OtherTab = int8(m_destTabId); + break; + default: + bankLogEntry.Money = uint32(m_itemOrMoney); } packet.Entry.push_back(bankLogEntry); @@ -264,10 +266,10 @@ void Guild::BankEventLogEntry::WritePacket(WorldPackets::Guild::GuildBankLogQuer // RankInfo void Guild::RankInfo::LoadFromDB(Field* fields) { - m_rankId = fields[1].Get(); - m_name = fields[2].Get(); - m_rights = fields[3].Get(); - m_bankMoneyPerDay = fields[4].Get(); + m_rankId = fields[1].Get(); + m_name = fields[2].Get(); + m_rights = fields[3].Get(); + m_bankMoneyPerDay = fields[4].Get(); if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights m_rights |= GR_RIGHT_ALL; } @@ -276,7 +278,7 @@ void Guild::RankInfo::SaveToDB(CharacterDatabaseTransaction trans) const { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_RANK); stmt->SetData(0, m_guildId); - stmt->SetData (1, m_rankId); + stmt->SetData(1, m_rankId); stmt->SetData(2, m_name); stmt->SetData(3, m_rights); stmt->SetData(4, m_bankMoneyPerDay); @@ -317,7 +319,7 @@ void Guild::RankInfo::SetName(std::string_view name) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_NAME); stmt->SetData(0, m_name); - stmt->SetData (1, m_rankId); + stmt->SetData(1, m_rankId); stmt->SetData(2, m_guildId); CharacterDatabase.Execute(stmt); } @@ -334,7 +336,7 @@ void Guild::RankInfo::SetRights(uint32 rights) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_RIGHTS); stmt->SetData(0, m_rights); - stmt->SetData (1, m_rankId); + stmt->SetData(1, m_rankId); stmt->SetData(2, m_guildId); CharacterDatabase.Execute(stmt); } @@ -351,7 +353,7 @@ void Guild::RankInfo::SetBankMoneyPerDay(uint32 money) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY); stmt->SetData(0, money); - stmt->SetData (1, m_rankId); + stmt->SetData(1, m_rankId); stmt->SetData(2, m_guildId); CharacterDatabase.Execute(stmt); } @@ -368,9 +370,9 @@ void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAnd { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT); stmt->SetData(0, m_guildId); - stmt->SetData (1, guildBR.GetTabId()); - stmt->SetData (2, m_rankId); - stmt->SetData (3, guildBR.GetRights()); + stmt->SetData(1, guildBR.GetTabId()); + stmt->SetData(2, m_rankId); + stmt->SetData(3, guildBR.GetRights()); stmt->SetData(4, guildBR.GetSlots()); CharacterDatabase.Execute(stmt); } @@ -409,8 +411,8 @@ bool Guild::BankTab::LoadItemFromDB(Field* fields) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM); stmt->SetData(0, m_guildId); - stmt->SetData (1, m_tabId); - stmt->SetData (2, slotId); + stmt->SetData(1, m_tabId); + stmt->SetData(2, slotId); CharacterDatabase.Execute(stmt); delete pItem; @@ -448,7 +450,7 @@ void Guild::BankTab::SetInfo(std::string_view name, std::string_view icon) stmt->SetData(0, m_name); stmt->SetData(1, m_icon); stmt->SetData(2, m_guildId); - stmt->SetData (3, m_tabId); + stmt->SetData(3, m_tabId); CharacterDatabase.Execute(stmt); } @@ -463,7 +465,7 @@ void Guild::BankTab::SetText(std::string_view text) CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_BANK_TAB_TEXT); stmt->SetData(0, m_text); stmt->SetData(1, m_guildId); - stmt->SetData (2, m_tabId); + stmt->SetData(2, m_tabId); CharacterDatabase.Execute(stmt); } @@ -478,16 +480,16 @@ bool Guild::BankTab::SetItem(CharacterDatabaseTransaction trans, uint8 slotId, I CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_ITEM); stmt->SetData(0, m_guildId); - stmt->SetData (1, m_tabId); - stmt->SetData (2, slotId); + stmt->SetData(1, m_tabId); + stmt->SetData(2, slotId); CharacterDatabase.ExecuteOrAppend(trans, stmt); if (item) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_ITEM); stmt->SetData(0, m_guildId); - stmt->SetData (1, m_tabId); - stmt->SetData (2, slotId); + stmt->SetData(1, m_tabId); + stmt->SetData(2, slotId); stmt->SetData(3, item->GetGUID().GetCounter()); CharacterDatabase.ExecuteOrAppend(trans, stmt); @@ -508,7 +510,7 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const if (session) { LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [{}]: Tabid: {}, Text: {}" - , session->GetPlayerInfo(), m_tabId, m_text); + , session->GetPlayerInfo(), m_tabId, m_text); session->SendPacket(textQuery.Write()); } else @@ -521,21 +523,21 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const // Member void Guild::Member::SetStats(Player* player) { - m_name = player->GetName(); - m_level = player->GetLevel(); - m_class = player->getClass(); - m_gender = player->getGender(); - m_zoneId = player->GetZoneId(); + m_name = player->GetName(); + m_level = player->GetLevel(); + m_class = player->getClass(); + m_gender = player->getGender(); + m_zoneId = player->GetZoneId(); m_accountId = player->GetSession()->GetAccountId(); } void Guild::Member::SetStats(std::string_view name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId) { - m_name = name; - m_level = level; - m_class = _class; - m_gender = gender; - m_zoneId = zoneId; + m_name = name; + m_level = level; + m_class = _class; + m_gender = gender; + m_zoneId = zoneId; m_accountId = accountId; } @@ -574,7 +576,7 @@ void Guild::Member::ChangeRank(uint8 newRank) player->SetRank(newRank); CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_RANK); - stmt->SetData (0, newRank); + stmt->SetData(0, newRank); stmt->SetData(1, m_guid.GetCounter()); CharacterDatabase.Execute(stmt); } @@ -589,7 +591,7 @@ void Guild::Member::SaveToDB(CharacterDatabaseTransaction trans) const CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER); stmt->SetData(0, m_guildId); stmt->SetData(1, m_guid.GetCounter()); - stmt->SetData (2, m_rankId); + stmt->SetData(2, m_rankId); stmt->SetData(3, m_publicNote); stmt->SetData(4, m_officerNote); CharacterDatabase.ExecuteOrAppend(trans, stmt); @@ -600,18 +602,18 @@ void Guild::Member::SaveToDB(CharacterDatabaseTransaction trans) const // In this case member has to be removed from guild. bool Guild::Member::LoadFromDB(Field* fields) { - m_publicNote = fields[3].Get(); + m_publicNote = fields[3].Get(); m_officerNote = fields[4].Get(); for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS; ++i) m_bankWithdraw[i] = fields[5 + i].Get(); SetStats(fields[12].Get(), - fields[13].Get(), // characters.level - fields[14].Get(), // characters.class - fields[15].Get(), // characters.gender - fields[16].Get(), // characters.zone - fields[17].Get()); // characters.account + fields[13].Get(), // characters.level + fields[14].Get(), // characters.class + fields[15].Get(), // characters.gender + fields[16].Get(), // characters.zone + fields[17].Get()); // characters.account m_logoutTime = fields[18].Get(); // characters.logout_time if (!CheckStats()) @@ -691,11 +693,11 @@ void EmblemInfo::ReadPacket(WorldPackets::Guild::SaveGuildEmblem& packet) void EmblemInfo::LoadFromDB(Field* fields) { - m_style = fields[3].Get(); - m_color = fields[4].Get(); - m_borderStyle = fields[5].Get(); - m_borderColor = fields[6].Get(); - m_backgroundColor = fields[7].Get(); + m_style = fields[3].Get(); + m_color = fields[4].Get(); + m_borderStyle = fields[5].Get(); + m_borderColor = fields[6].Get(); + m_backgroundColor = fields[7].Get(); } void EmblemInfo::SaveToDB(uint32 guildId) const @@ -747,8 +749,8 @@ void Guild::MoveItemData::LogAction(MoveItemData* pFrom) const ASSERT(pFrom->GetItem()); sScriptMgr->OnGuildItemMove(m_pGuild, m_pPlayer, pFrom->GetItem(), - pFrom->IsBank(), pFrom->GetContainer(), pFrom->GetSlotId(), - IsBank(), GetContainer(), GetSlotId()); + pFrom->IsBank(), pFrom->GetContainer(), pFrom->GetSlotId(), + IsBank(), GetContainer(), GetSlotId()); } inline void Guild::MoveItemData::CopySlots(SlotIds& ids) const @@ -808,7 +810,7 @@ void Guild::PlayerMoveItemData::LogBankEvent(CharacterDatabaseTransaction trans, ASSERT(pFrom); // Bank -> Char m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUID(), - pFrom->GetItem()->GetEntry(), count); + pFrom->GetItem()->GetEntry(), count); } inline InventoryResult Guild::PlayerMoveItemData::CanStore(Item* pItem, bool swap) @@ -881,7 +883,7 @@ Item* Guild::BankMoveItemData::StoreItem(CharacterDatabaseTransaction trans, Ite ++itr; LOG_DEBUG("guild", "GUILD STORAGE: StoreItem tab = {}, slot = {}, item = {}, count = {}", - m_container, m_slotId, pItem->GetEntry(), pItem->GetCount()); + m_container, m_slotId, pItem->GetEntry(), pItem->GetCount()); pLastItem = _StoreItem(trans, pTab, pItem, pos, itr != m_vec.end()); } return pLastItem; @@ -893,11 +895,11 @@ void Guild::BankMoveItemData::LogBankEvent(CharacterDatabaseTransaction trans, M if (pFrom->IsBank()) // Bank -> Bank m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUID(), - pFrom->GetItem()->GetEntry(), count, m_container); + pFrom->GetItem()->GetEntry(), count, m_container); else // Char -> Bank m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, m_container, m_pPlayer->GetGUID(), - pFrom->GetItem()->GetEntry(), count); + pFrom->GetItem()->GetEntry(), count); } void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const @@ -984,7 +986,7 @@ void Guild::BankMoveItemData::CanStoreItemInTab(Item* pItem, uint8 skipSlotId, b InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap) { LOG_DEBUG("guild", "GUILD STORAGE: CanStore() tab = {}, slot = {}, item = {}, count = {}", - m_container, m_slotId, pItem->GetEntry(), pItem->GetCount()); + m_container, m_slotId, pItem->GetEntry(), pItem->GetCount()); uint32 count = pItem->GetCount(); // Soulbound items cannot be moved if (pItem->IsSoulBound()) @@ -1031,7 +1033,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap) } // Guild -Guild::Guild(): +Guild::Guild() : m_id(0), m_createdDate(0), m_accountsNumber(0), @@ -1065,7 +1067,7 @@ bool Guild::Create(Player* pLeader, std::string_view name) m_createdDate = GameTime::GetGameTime().count(); LOG_DEBUG("guild", "GUILD: creating guild [{}] for leader {} ({})", - m_name, pLeader->GetName(), m_leaderGuid.ToString()); + m_name, pLeader->GetName(), m_leaderGuid.ToString()); CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); @@ -1075,7 +1077,7 @@ bool Guild::Create(Player* pLeader, std::string_view name) uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD); - stmt->SetData( index, m_id); + stmt->SetData(index, m_id); stmt->SetData(++index, m_name); stmt->SetData(++index, m_leaderGuid.GetCounter()); stmt->SetData(++index, m_info); @@ -1161,15 +1163,15 @@ void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value) { switch (dataid) { - case GUILD_MEMBER_DATA_ZONEID: - member->SetZoneID(value); - break; - case GUILD_MEMBER_DATA_LEVEL: - member->SetLevel(value); - break; - default: - LOG_ERROR("guild", "Guild::UpdateMemberData: Called with incorrect DATAID {} (value {})", dataid, value); - return; + case GUILD_MEMBER_DATA_ZONEID: + member->SetZoneID(value); + break; + case GUILD_MEMBER_DATA_LEVEL: + member->SetLevel(value); + break; + default: + LOG_ERROR("guild", "Guild::UpdateMemberData: Called with incorrect DATAID {} (value {})", dataid, value); + return; } //HandleRoster(); } @@ -1207,7 +1209,7 @@ void Guild::HandleRoster(WorldSession* session) roster.RankData.reserve(m_ranks.size()); for (RankInfo const& rank : m_ranks) { - WorldPackets::Guild::GuildRankData& rankData = roster.RankData.emplace_back(); + WorldPackets::Guild::GuildRankData& rankData = roster.RankData.emplace_back(); rankData.Flags = rank.GetRights(); rankData.WithdrawGoldLimit = rank.GetBankMoneyPerDay(); @@ -1362,7 +1364,7 @@ void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string if (!tab) { LOG_ERROR("guild", "Guild::HandleSetBankTabInfo: Player {} trying to change bank tab info from unexisting tab {}.", - session->GetPlayerInfo(), tabId); + session->GetPlayerInfo(), tabId); return; } @@ -1931,14 +1933,14 @@ void Guild::SendLoginInfo(WorldSession* session) // Loading methods bool Guild::LoadFromDB(Field* fields) { - m_id = fields[0].Get(); - m_name = fields[1].Get(); - m_leaderGuid = ObjectGuid::Create(fields[2].Get()); + m_id = fields[0].Get(); + m_name = fields[1].Get(); + m_leaderGuid = ObjectGuid::Create(fields[2].Get()); m_emblemInfo.LoadFromDB(fields); - m_info = fields[8].Get(); - m_motd = fields[9].Get(); - m_createdDate = time_t(fields[10].Get()); - m_bankMoney = fields[11].Get(); + m_info = fields[8].Get(); + m_motd = fields[9].Get(); + m_createdDate = time_t(fields[10].Get()); + m_bankMoney = fields[11].Get(); uint8 purchasedTabs = uint8(fields[12].Get()); if (purchasedTabs > GUILD_BANK_MAX_TABS) @@ -1997,13 +1999,13 @@ bool Guild::LoadEventLogFromDB(Field* fields) if (m_eventLog.CanInsert()) { m_eventLog.LoadEvent( - m_id, // guild id - fields[1].Get(), // guid - time_t(fields[6].Get()), // timestamp - GuildEventLogTypes(fields[2].Get()), // event type - ObjectGuid::Create(fields[3].Get()), // player guid 1 - ObjectGuid::Create(fields[4].Get()), // player guid 2 - fields[5].Get()); // rank + m_id, // guild id + fields[1].Get(), // guid + time_t(fields[6].Get()), // timestamp + GuildEventLogTypes(fields[2].Get()), // event type + ObjectGuid::Create(fields[3].Get()), // player guid 1 + ObjectGuid::Create(fields[4].Get()), // player guid 2 + fields[5].Get()); // rank return true; } return false; @@ -2035,15 +2037,15 @@ bool Guild::LoadBankEventLogFromDB(Field* fields) return false; } bankLog.LoadEvent( - m_id, // guild id - guid, // guid - time_t(fields[8].Get()), // timestamp - dbTabId, // tab id - eventType, // event type - ObjectGuid::Create(fields[4].Get()), // player guid - fields[5].Get(), // item or money - fields[6].Get(), // itam stack count - fields[7].Get()); // dest tab id + m_id, // guild id + guid, // guid + time_t(fields[8].Get()), // timestamp + dbTabId, // tab id + eventType, // event type + ObjectGuid::Create(fields[4].Get()), // player guid + fields[5].Get(), // item or money + fields[6].Get(), // itam stack count + fields[7].Get()); // dest tab id } } return true; @@ -2064,7 +2066,7 @@ bool Guild::LoadBankItemFromDB(Field* fields) if (tabId >= _GetPurchasedTabsSize()) { LOG_ERROR("guild", "Invalid tab for item (GUID: {}, id: #{}) in guild bank, skipped.", - fields[14].Get(), fields[15].Get()); + fields[14].Get(), fields[15].Get()); return false; } return m_bankTabs[tabId].LoadItemFromDB(fields); @@ -2383,7 +2385,7 @@ bool Guild::ChangeMemberRank(ObjectGuid guid, uint8 newRank) void Guild::SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount) { if (tabId >= _GetPurchasedTabsSize() || slotId >= GUILD_BANK_MAX_SLOTS || - destTabId >= _GetPurchasedTabsSize() || destSlotId >= GUILD_BANK_MAX_SLOTS) + destTabId >= _GetPurchasedTabsSize() || destSlotId >= GUILD_BANK_MAX_SLOTS) return; if (tabId == destTabId && slotId == destSlotId) @@ -2427,12 +2429,12 @@ void Guild::_CreateNewBankTab() CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB); stmt->SetData(0, m_id); - stmt->SetData (1, tabId); + stmt->SetData(1, tabId); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_TAB); stmt->SetData(0, m_id); - stmt->SetData (1, tabId); + stmt->SetData(1, tabId); trans->Append(stmt); ++tabId; @@ -2452,10 +2454,10 @@ void Guild::_CreateDefaultGuildRanks(LocaleConstant loc) stmt->SetData(0, m_id); CharacterDatabase.Execute(stmt); - _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_MASTER, loc), GR_RIGHT_ALL); - _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_OFFICER, loc), GR_RIGHT_ALL); - _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_VETERAN, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); - _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_MEMBER, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); + _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_MASTER, loc), GR_RIGHT_ALL); + _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_OFFICER, loc), GR_RIGHT_ALL); + _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_VETERAN, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); + _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_MEMBER, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); _CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_INITIATE, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); } @@ -2626,7 +2628,7 @@ inline void Guild::_UpdateMemberWithdrawSlots(CharacterDatabaseTransaction trans { uint8 rankId = member->GetRankId(); if (rankId != GR_GUILDMASTER - && member->GetBankWithdrawValue(tabId) < _GetRankBankTabSlotsPerDay(rankId, tabId)) + && member->GetBankWithdrawValue(tabId) < _GetRankBankTabSlotsPerDay(rankId, tabId)) member->UpdateBankWithdrawValue(trans, tabId, 1); } } @@ -2850,7 +2852,7 @@ void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const } void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, - Optional param1 /*= {}*/, Optional param2 /*= {}*/, Optional param3 /*= {}*/) const + Optional param1 /*= {}*/, Optional param2 /*= {}*/, Optional param3 /*= {}*/) const { WorldPackets::Guild::GuildEvent event; event.Type = guildEvent; @@ -2873,7 +2875,7 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: {}", guildEvent); } -void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds *slots /*= nullptr*/) const +void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds* slots /*= nullptr*/) const { if (!sScriptMgr->CanGuildSendBankList(this, session, tabId, sendAllSlots)) return; @@ -2899,47 +2901,47 @@ void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= if (BankTab const* tab = GetBankTab(tabId)) { auto fillItems = [&](auto begin, auto end, bool skipEmpty) - { - for (auto itr = begin; itr != end; ++itr) { - if (Item* tabItem = tab->GetItem(*itr)) + for (auto itr = begin; itr != end; ++itr) { - WorldPackets::Guild::GuildBankItemInfo itemInfo; - - itemInfo.Slot = *itr; - itemInfo.ItemID = tabItem->GetEntry(); - itemInfo.Count = int32(tabItem->GetCount()); - itemInfo.Charges = int32(std::abs(tabItem->GetSpellCharges())); - itemInfo.EnchantmentID = int32(tabItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); - itemInfo.Flags = tabItem->GetInt32Value(ITEM_FIELD_FLAGS); - itemInfo.RandomPropertiesID = tabItem->GetItemRandomPropertyId(); - itemInfo.RandomPropertiesSeed = int32(tabItem->GetItemSuffixFactor()); - - for (uint32 socketSlot = 0; socketSlot < MAX_GEM_SOCKETS; ++socketSlot) + if (Item* tabItem = tab->GetItem(*itr)) { - if (uint32 enchId = tabItem->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + socketSlot))) + WorldPackets::Guild::GuildBankItemInfo itemInfo; + + itemInfo.Slot = *itr; + itemInfo.ItemID = tabItem->GetEntry(); + itemInfo.Count = int32(tabItem->GetCount()); + itemInfo.Charges = int32(std::abs(tabItem->GetSpellCharges())); + itemInfo.EnchantmentID = int32(tabItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); + itemInfo.Flags = tabItem->GetInt32Value(ITEM_FIELD_FLAGS); + itemInfo.RandomPropertiesID = tabItem->GetItemRandomPropertyId(); + itemInfo.RandomPropertiesSeed = int32(tabItem->GetItemSuffixFactor()); + + for (uint32 socketSlot = 0; socketSlot < MAX_GEM_SOCKETS; ++socketSlot) { - WorldPackets::Guild::GuildBankSocketEnchant gem; - gem.SocketIndex = socketSlot; - gem.SocketEnchantID = int32(enchId); - itemInfo.SocketEnchant.push_back(gem); + if (uint32 enchId = tabItem->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + socketSlot))) + { + WorldPackets::Guild::GuildBankSocketEnchant gem; + gem.SocketIndex = socketSlot; + gem.SocketEnchantID = int32(enchId); + itemInfo.SocketEnchant.push_back(gem); + } } + + packet.ItemInfo.push_back(itemInfo); } + else if (!skipEmpty) + { + WorldPackets::Guild::GuildBankItemInfo itemInfo; - packet.ItemInfo.push_back(itemInfo); + itemInfo.Slot = *itr; + itemInfo.ItemID = 0; + + packet.ItemInfo.push_back(itemInfo); + } } - else if (!skipEmpty) - { - WorldPackets::Guild::GuildBankItemInfo itemInfo; - itemInfo.Slot = *itr; - itemInfo.ItemID = 0; - - packet.ItemInfo.push_back(itemInfo); - } - } - - }; + }; if (sendAllSlots) fillItems(boost::make_counting_iterator(uint8(0)), boost::make_counting_iterator(uint8(GUILD_BANK_MAX_SLOTS)), true); @@ -2954,7 +2956,7 @@ void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= session->SendPacket(packet.Write()); LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [{}]: TabId: {}, FullSlots: {}, slots: {}", - session->GetPlayerInfo(), tabId, sendAllSlots, packet.WithdrawalsRemaining); + session->GetPlayerInfo(), tabId, sendAllSlots, packet.WithdrawalsRemaining); } else { @@ -2974,7 +2976,7 @@ void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= packet.SetWithdrawalsRemaining(_GetMemberRemainingSlots(member, tabId)); player->SendDirectMessage(packet.GetRawPacket()); LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [{}]: TabId: {}, FullSlots: {}, slots: {}" - , player->GetName(), tabId, sendAllSlots, packet.WithdrawalsRemaining); + , player->GetName(), tabId, sendAllSlots, packet.WithdrawalsRemaining); } } } diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 3e0d88522..ceb935e86 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -39,16 +39,16 @@ namespace WorldPackets enum GuildMisc { - GUILD_BANK_MAX_TABS = 6, // send by client for money log also - GUILD_BANK_MAX_SLOTS = 98, - GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB - GUILD_RANKS_MIN_COUNT = 5, - GUILD_RANKS_MAX_COUNT = 10, - GUILD_RANK_NONE = 0xFF, - GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF, - GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF, - GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF, - TAB_UNDEFINED = 0xFF, + GUILD_BANK_MAX_TABS = 6, // send by client for money log also + GUILD_BANK_MAX_SLOTS = 98, + GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB + GUILD_RANKS_MIN_COUNT = 5, + GUILD_RANKS_MAX_COUNT = 10, + GUILD_RANK_NONE = 0xFF, + GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF, + GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF, + GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF, + TAB_UNDEFINED = 0xFF, }; constexpr uint64 GUILD_BANK_MONEY_LIMIT = UI64LIT(0x7FFFFFFFFFFFF); @@ -62,176 +62,176 @@ enum GuildMemberData enum GuildDefaultRanks { // These ranks can be modified, but they cannot be deleted - GR_GUILDMASTER = 0, - GR_OFFICER = 1, - GR_VETERAN = 2, - GR_MEMBER = 3, - GR_INITIATE = 4 - // When promoting member server does: rank-- - // When demoting member server does: rank++ + GR_GUILDMASTER = 0, + GR_OFFICER = 1, + GR_VETERAN = 2, + GR_MEMBER = 3, + GR_INITIATE = 4 + // When promoting member server does: rank-- + // When demoting member server does: rank++ }; enum GuildRankRights { - GR_RIGHT_EMPTY = 0x00000040, - GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001, - GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002, - GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004, - GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008, - GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010, - GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020, - GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080, - GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100, - GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000, - GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000, - GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000, - GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000, - GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000, - GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity - GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair - GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold - GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk - GR_RIGHT_ALL = 0x001DF1FF + GR_RIGHT_EMPTY = 0x00000040, + GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001, + GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002, + GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004, + GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008, + GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010, + GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020, + GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080, + GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100, + GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000, + GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000, + GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000, + GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000, + GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000, + GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity + GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair + GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold + GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk + GR_RIGHT_ALL = 0x001DF1FF }; enum GuildCommandType { - GUILD_COMMAND_CREATE = 0, - GUILD_COMMAND_INVITE = 1, - GUILD_COMMAND_QUIT = 3, - GUILD_COMMAND_ROSTER = 5, - GUILD_COMMAND_PROMOTE = 6, - GUILD_COMMAND_DEMOTE = 7, - GUILD_COMMAND_REMOVE = 8, - GUILD_COMMAND_CHANGE_LEADER = 10, - GUILD_COMMAND_EDIT_MOTD = 11, - GUILD_COMMAND_GUILD_CHAT = 13, - GUILD_COMMAND_FOUNDER = 14, - GUILD_COMMAND_CHANGE_RANK = 16, - GUILD_COMMAND_PUBLIC_NOTE = 19, - GUILD_COMMAND_VIEW_TAB = 21, - GUILD_COMMAND_MOVE_ITEM = 22, - GUILD_COMMAND_REPAIR = 25, + GUILD_COMMAND_CREATE = 0, + GUILD_COMMAND_INVITE = 1, + GUILD_COMMAND_QUIT = 3, + GUILD_COMMAND_ROSTER = 5, + GUILD_COMMAND_PROMOTE = 6, + GUILD_COMMAND_DEMOTE = 7, + GUILD_COMMAND_REMOVE = 8, + GUILD_COMMAND_CHANGE_LEADER = 10, + GUILD_COMMAND_EDIT_MOTD = 11, + GUILD_COMMAND_GUILD_CHAT = 13, + GUILD_COMMAND_FOUNDER = 14, + GUILD_COMMAND_CHANGE_RANK = 16, + GUILD_COMMAND_PUBLIC_NOTE = 19, + GUILD_COMMAND_VIEW_TAB = 21, + GUILD_COMMAND_MOVE_ITEM = 22, + GUILD_COMMAND_REPAIR = 25, }; enum GuildCommandError { - ERR_GUILD_COMMAND_SUCCESS = 0, - ERR_GUILD_INTERNAL = 1, - ERR_ALREADY_IN_GUILD = 2, - ERR_ALREADY_IN_GUILD_S = 3, - ERR_INVITED_TO_GUILD = 4, - ERR_ALREADY_INVITED_TO_GUILD_S = 5, - ERR_GUILD_NAME_INVALID = 6, - ERR_GUILD_NAME_EXISTS_S = 7, - ERR_GUILD_LEADER_LEAVE = 8, - ERR_GUILD_PERMISSIONS = 8, - ERR_GUILD_PLAYER_NOT_IN_GUILD = 9, - ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 10, - ERR_GUILD_PLAYER_NOT_FOUND_S = 11, - ERR_GUILD_NOT_ALLIED = 12, - ERR_GUILD_RANK_TOO_HIGH_S = 13, - ERR_GUILD_RANK_TOO_LOW_S = 14, - ERR_GUILD_RANKS_LOCKED = 17, - ERR_GUILD_RANK_IN_USE = 18, - ERR_GUILD_IGNORING_YOU_S = 19, - ERR_GUILD_UNK1 = 20, // Forces roster update - ERR_GUILD_WITHDRAW_LIMIT = 25, - ERR_GUILD_NOT_ENOUGH_MONEY = 26, - ERR_GUILD_BANK_FULL = 28, - ERR_GUILD_ITEM_NOT_FOUND = 29, + ERR_GUILD_COMMAND_SUCCESS = 0, + ERR_GUILD_INTERNAL = 1, + ERR_ALREADY_IN_GUILD = 2, + ERR_ALREADY_IN_GUILD_S = 3, + ERR_INVITED_TO_GUILD = 4, + ERR_ALREADY_INVITED_TO_GUILD_S = 5, + ERR_GUILD_NAME_INVALID = 6, + ERR_GUILD_NAME_EXISTS_S = 7, + ERR_GUILD_LEADER_LEAVE = 8, + ERR_GUILD_PERMISSIONS = 8, + ERR_GUILD_PLAYER_NOT_IN_GUILD = 9, + ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 10, + ERR_GUILD_PLAYER_NOT_FOUND_S = 11, + ERR_GUILD_NOT_ALLIED = 12, + ERR_GUILD_RANK_TOO_HIGH_S = 13, + ERR_GUILD_RANK_TOO_LOW_S = 14, + ERR_GUILD_RANKS_LOCKED = 17, + ERR_GUILD_RANK_IN_USE = 18, + ERR_GUILD_IGNORING_YOU_S = 19, + ERR_GUILD_UNK1 = 20, // Forces roster update + ERR_GUILD_WITHDRAW_LIMIT = 25, + ERR_GUILD_NOT_ENOUGH_MONEY = 26, + ERR_GUILD_BANK_FULL = 28, + ERR_GUILD_ITEM_NOT_FOUND = 29, }; enum GuildEvents { - GE_PROMOTION = 0, - GE_DEMOTION = 1, - GE_MOTD = 2, - GE_JOINED = 3, - GE_LEFT = 4, - GE_REMOVED = 5, - GE_LEADER_IS = 6, - GE_LEADER_CHANGED = 7, - GE_DISBANDED = 8, - GE_TABARDCHANGE = 9, - GE_RANK_UPDATED = 10, - GE_RANK_DELETED = 11, - GE_SIGNED_ON = 12, - GE_SIGNED_OFF = 13, - GE_GUILDBANKBAGSLOTS_CHANGED = 14, /// @todo: Sent when items are moved in gbank - all players with bank open will send tab query - GE_BANK_TAB_PURCHASED = 15, - GE_BANK_TAB_UPDATED = 16, - GE_BANK_MONEY_SET = 17, - GE_BANK_TAB_AND_MONEY_UPDATED = 18, - GE_BANK_TEXT_CHANGED = 19, + GE_PROMOTION = 0, + GE_DEMOTION = 1, + GE_MOTD = 2, + GE_JOINED = 3, + GE_LEFT = 4, + GE_REMOVED = 5, + GE_LEADER_IS = 6, + GE_LEADER_CHANGED = 7, + GE_DISBANDED = 8, + GE_TABARDCHANGE = 9, + GE_RANK_UPDATED = 10, + GE_RANK_DELETED = 11, + GE_SIGNED_ON = 12, + GE_SIGNED_OFF = 13, + GE_GUILDBANKBAGSLOTS_CHANGED = 14, /// @todo: Sent when items are moved in gbank - all players with bank open will send tab query + GE_BANK_TAB_PURCHASED = 15, + GE_BANK_TAB_UPDATED = 16, + GE_BANK_MONEY_SET = 17, + GE_BANK_TAB_AND_MONEY_UPDATED = 18, + GE_BANK_TEXT_CHANGED = 19, }; enum PetitionTurns { - PETITION_TURN_OK = 0, - PETITION_TURN_ALREADY_IN_GUILD = 2, - PETITION_TURN_NEED_MORE_SIGNATURES = 4 + PETITION_TURN_OK = 0, + PETITION_TURN_ALREADY_IN_GUILD = 2, + PETITION_TURN_NEED_MORE_SIGNATURES = 4 }; enum PetitionSigns { - PETITION_SIGN_OK = 0, - PETITION_SIGN_ALREADY_SIGNED = 1, - PETITION_SIGN_ALREADY_IN_GUILD = 2, - PETITION_SIGN_CANT_SIGN_OWN = 3, - PETITION_SIGN_NOT_SERVER = 4 + PETITION_SIGN_OK = 0, + PETITION_SIGN_ALREADY_SIGNED = 1, + PETITION_SIGN_ALREADY_IN_GUILD = 2, + PETITION_SIGN_CANT_SIGN_OWN = 3, + PETITION_SIGN_NOT_SERVER = 4 }; enum GuildBankRights { - GUILD_BANK_RIGHT_VIEW_TAB = 0x01, - GUILD_BANK_RIGHT_PUT_ITEM = 0x02, - GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, + GUILD_BANK_RIGHT_VIEW_TAB = 0x01, + GUILD_BANK_RIGHT_PUT_ITEM = 0x02, + GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, - GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, - GUILD_BANK_RIGHT_FULL = 0xFF + GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, + GUILD_BANK_RIGHT_FULL = 0xFF }; enum GuildBankEventLogTypes { - GUILD_BANK_LOG_DEPOSIT_ITEM = 1, - GUILD_BANK_LOG_WITHDRAW_ITEM = 2, - GUILD_BANK_LOG_MOVE_ITEM = 3, - GUILD_BANK_LOG_DEPOSIT_MONEY = 4, - GUILD_BANK_LOG_WITHDRAW_MONEY = 5, - GUILD_BANK_LOG_REPAIR_MONEY = 6, - GUILD_BANK_LOG_MOVE_ITEM2 = 7, - GUILD_BANK_LOG_UNK1 = 8, - GUILD_BANK_LOG_BUY_SLOT = 9 + GUILD_BANK_LOG_DEPOSIT_ITEM = 1, + GUILD_BANK_LOG_WITHDRAW_ITEM = 2, + GUILD_BANK_LOG_MOVE_ITEM = 3, + GUILD_BANK_LOG_DEPOSIT_MONEY = 4, + GUILD_BANK_LOG_WITHDRAW_MONEY = 5, + GUILD_BANK_LOG_REPAIR_MONEY = 6, + GUILD_BANK_LOG_MOVE_ITEM2 = 7, + GUILD_BANK_LOG_UNK1 = 8, + GUILD_BANK_LOG_BUY_SLOT = 9 }; enum GuildEventLogTypes { - GUILD_EVENT_LOG_INVITE_PLAYER = 1, - GUILD_EVENT_LOG_JOIN_GUILD = 2, - GUILD_EVENT_LOG_PROMOTE_PLAYER = 3, - GUILD_EVENT_LOG_DEMOTE_PLAYER = 4, - GUILD_EVENT_LOG_UNINVITE_PLAYER = 5, - GUILD_EVENT_LOG_LEAVE_GUILD = 6 + GUILD_EVENT_LOG_INVITE_PLAYER = 1, + GUILD_EVENT_LOG_JOIN_GUILD = 2, + GUILD_EVENT_LOG_PROMOTE_PLAYER = 3, + GUILD_EVENT_LOG_DEMOTE_PLAYER = 4, + GUILD_EVENT_LOG_UNINVITE_PLAYER = 5, + GUILD_EVENT_LOG_LEAVE_GUILD = 6 }; enum GuildEmblemError { - ERR_GUILDEMBLEM_SUCCESS = 0, + ERR_GUILDEMBLEM_SUCCESS = 0, ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1, - ERR_GUILDEMBLEM_NOGUILD = 2, - ERR_GUILDEMBLEM_NOTGUILDMASTER = 3, - ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4, - ERR_GUILDEMBLEM_INVALIDVENDOR = 5 + ERR_GUILDEMBLEM_NOGUILD = 2, + ERR_GUILDEMBLEM_NOTGUILDMASTER = 3, + ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4, + ERR_GUILDEMBLEM_INVALIDVENDOR = 5 }; enum GuildMemberFlags { - GUILDMEMBER_STATUS_NONE = 0x0000, - GUILDMEMBER_STATUS_ONLINE = 0x0001, - GUILDMEMBER_STATUS_AFK = 0x0002, - GUILDMEMBER_STATUS_DND = 0x0004, - GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app + GUILDMEMBER_STATUS_NONE = 0x0000, + GUILDMEMBER_STATUS_ONLINE = 0x0001, + GUILDMEMBER_STATUS_AFK = 0x0002, + GUILDMEMBER_STATUS_DND = 0x0004, + GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app }; // Emblem info @@ -239,7 +239,8 @@ class EmblemInfo { public: EmblemInfo(uint32 /*style*/ = 0, uint32 /*color*/ = 0, uint32 /*borderStyle*/ = 0, uint32 /*borderColor*/ = 0, uint32 /*backgroundColor*/ = 0) : - m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) { } + m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) { + } void LoadFromDB(Field* fields); void SaveToDB(uint32 guildId) const; @@ -263,9 +264,9 @@ private: class GuildBankRightsAndSlots { public: - GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) { } - GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), rights(0), slots(0) { } - GuildBankRightsAndSlots(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) { } + GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) {} + GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), rights(0), slots(0) {} + GuildBankRightsAndSlots(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) {} void SetGuildMasterValues() { @@ -296,7 +297,7 @@ public: // pussywizard: public class Member class Member { public: - Member(uint32 guildId, ObjectGuid guid, uint8 rankId): + Member(uint32 guildId, ObjectGuid guid, uint8 rankId) : m_guildId(guildId), m_guid(guid), m_zoneId(0), @@ -404,8 +405,8 @@ private: { public: LogEntry(uint32 guildId, ObjectGuid::LowType guid); - LogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) { } - virtual ~LogEntry() { } + LogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) {} + virtual ~LogEntry() {} ObjectGuid::LowType GetGUID() const { return m_guid; } uint64 GetTimestamp() const { return m_timestamp; } @@ -423,12 +424,14 @@ private: { public: EventLogEntry(uint32 guildId, ObjectGuid::LowType guid, GuildEventLogTypes eventType, ObjectGuid playerGuid1, ObjectGuid playerGuid2, uint8 newRank) : - LogEntry(guildId, guid), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { } + LogEntry(guildId, guid), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { + } EventLogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp, GuildEventLogTypes eventType, ObjectGuid playerGuid1, ObjectGuid playerGuid2, uint8 newRank) : - LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { } + LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { + } - ~EventLogEntry() override { } + ~EventLogEntry() override {} void SaveToDB(CharacterDatabaseTransaction trans) const override; void WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const; @@ -459,13 +462,15 @@ private: BankEventLogEntry(uint32 guildId, ObjectGuid::LowType guid, GuildBankEventLogTypes eventType, uint8 tabId, ObjectGuid playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) : LogEntry(guildId, guid), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid), - m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { } + m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { + } BankEventLogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp, uint8 tabId, GuildBankEventLogTypes eventType, ObjectGuid playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) : LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid), - m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { } + m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { + } - ~BankEventLogEntry() override { } + ~BankEventLogEntry() override {} void SaveToDB(CharacterDatabaseTransaction trans) const override; void WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const; @@ -510,11 +515,12 @@ private: class RankInfo { public: - RankInfo(): m_guildId(0), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } - RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } + RankInfo() : m_guildId(0), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) {} + RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) {} RankInfo(uint32 guildId, uint8 rankId, std::string_view name, uint32 rights, uint32 money) : m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights), - m_bankMoneyPerDay(rankId != GR_GUILDMASTER ? money : GUILD_WITHDRAW_MONEY_UNLIMITED) { } + m_bankMoneyPerDay(rankId != GR_GUILDMASTER ? money : GUILD_WITHDRAW_MONEY_UNLIMITED) { + } void LoadFromDB(Field* fields); void SaveToDB(CharacterDatabaseTransaction trans) const; @@ -573,7 +579,7 @@ private: std::string const& GetIcon() const { return m_icon; } std::string const& GetText() const { return m_text; } - inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : nullptr; } + inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : nullptr; } bool SetItem(CharacterDatabaseTransaction trans, uint8 slotId, Item* pItem); private: @@ -591,8 +597,9 @@ private: { public: MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : m_pGuild(guild), m_pPlayer(player), - m_container(container), m_slotId(slotId), m_pItem(nullptr), m_pClonedItem(nullptr) { } - virtual ~MoveItemData() { } + m_container(container), m_slotId(slotId), m_pItem(nullptr), m_pClonedItem(nullptr) { + } + virtual ~MoveItemData() {} virtual bool IsBank() const = 0; // Initializes item pointer. Returns true, if item exists, false otherwise. @@ -638,7 +645,8 @@ private: { public: PlayerMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : - MoveItemData(guild, player, container, slotId) { } + MoveItemData(guild, player, container, slotId) { + } bool IsBank() const override { return false; } bool InitItem() override; @@ -653,7 +661,8 @@ private: { public: BankMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : - MoveItemData(guild, player, container, slotId) { } + MoveItemData(guild, player, container, slotId) { + } bool IsBank() const override { return true; } bool InitItem() override; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 31a5b5181..97c8815d9 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -264,15 +264,15 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) std::shared_ptr createInfo = std::make_shared(); recvData >> createInfo->Name - >> createInfo->Race - >> createInfo->Class - >> createInfo->Gender - >> createInfo->Skin - >> createInfo->Face - >> createInfo->HairStyle - >> createInfo->HairColor - >> createInfo->FacialHair - >> createInfo->OutfitId; + >> createInfo->Race + >> createInfo->Class + >> createInfo->Gender + >> createInfo->Skin + >> createInfo->Face + >> createInfo->HairStyle + >> createInfo->HairColor + >> createInfo->FacialHair + >> createInfo->OutfitId; if (AccountMgr::IsPlayerAccount(GetSecurity())) { @@ -371,233 +371,233 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData) stmt->SetData(0, createInfo->Name); _queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt) - .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result) - { - if (result) - { - SendCharCreate(CHAR_CREATE_NAME_IN_USE); - return; - } - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SUM_REALM_CHARACTERS); - stmt->SetData(0, GetAccountId()); - queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt)); - }) - .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result) - { - uint64 acctCharCount = 0; - if (result) - { - Field* fields = result->Fetch(); - acctCharCount = uint64(fields[0].Get()); - } - - if (acctCharCount >= static_cast(sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT))) - { - SendCharCreate(CHAR_CREATE_ACCOUNT_LIMIT); - return; - } - - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS); - stmt->SetData(0, GetAccountId()); - queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt)); - }) - .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result) - { - if (result) - { - Field* fields = result->Fetch(); - createInfo->CharCount = uint8(fields[0].Get()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max - - if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM)) + .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result) { - SendCharCreate(CHAR_CREATE_SERVER_LIMIT); - return; - } - } - - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); - uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); - - std::function finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result) - { - if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class)) - { - SendCharCreate(CHAR_CREATE_DISABLED); - return; - } - bool haveSameRace = false; - uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); - bool hasHeroicReqLevel = (heroicReqLevel == 0); - bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); - uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); - bool checkDeathKnightReqs = AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT; - - if (result) - { - TeamId teamId = Player::TeamIdForRace(createInfo->Race); - uint32 freeDeathKnightSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); - - Field* field = result->Fetch(); - uint8 accRace = field[1].Get(); - - if (checkDeathKnightReqs) + if (result) { - uint8 accClass = field[2].Get(); - if (accClass == CLASS_DEATH_KNIGHT) - { - if (freeDeathKnightSlots > 0) - --freeDeathKnightSlots; - - if (freeDeathKnightSlots == 0) - { - SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT); - return; - } - } - - if (!hasHeroicReqLevel) - { - uint8 accLevel = field[0].Get(); - if (accLevel >= heroicReqLevel) - hasHeroicReqLevel = true; - } + SendCharCreate(CHAR_CREATE_NAME_IN_USE); + return; } - // need to check team only for first character - /// @todo what to if account already has characters of both races? - if (!allowTwoSideAccounts) + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SUM_REALM_CHARACTERS); + stmt->SetData(0, GetAccountId()); + queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt)); + }) + .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result) + { + uint64 acctCharCount = 0; + if (result) { - uint32 accTeam = 0; - if (accRace > 0) - accTeam = Player::TeamIdForRace(accRace); + Field* fields = result->Fetch(); + acctCharCount = uint64(fields[0].Get()); + } - if (accTeam != teamId) + if (acctCharCount >= static_cast(sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT))) + { + SendCharCreate(CHAR_CREATE_ACCOUNT_LIMIT); + return; + } + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SUM_CHARS); + stmt->SetData(0, GetAccountId()); + queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt)); + }) + .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result) + { + if (result) + { + Field* fields = result->Fetch(); + createInfo->CharCount = uint8(fields[0].Get()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max + + if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM)) { - SendCharCreate(CHAR_CREATE_PVP_TEAMS_VIOLATION); + SendCharCreate(CHAR_CREATE_SERVER_LIMIT); return; } } - // search same race for cinematic or same class if need - /// @todo check if cinematic already shown? (already logged in?; cinematic field) - while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT) - { - if (!result->NextRow()) - break; + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); + uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); - field = result->Fetch(); - accRace = field[1].Get(); - - if (!haveSameRace) - haveSameRace = createInfo->Race == accRace; - - if (checkDeathKnightReqs) + std::function finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result) { - uint8 acc_class = field[2].Get(); - if (acc_class == CLASS_DEATH_KNIGHT) + if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class)) { - if (freeDeathKnightSlots > 0) - --freeDeathKnightSlots; + SendCharCreate(CHAR_CREATE_DISABLED); + return; + } + bool haveSameRace = false; + uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER); + bool hasHeroicReqLevel = (heroicReqLevel == 0); + bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity()); + uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS); + bool checkDeathKnightReqs = AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT; - if (freeDeathKnightSlots == 0) + if (result) + { + TeamId teamId = Player::TeamIdForRace(createInfo->Race); + uint32 freeDeathKnightSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); + + Field* field = result->Fetch(); + uint8 accRace = field[1].Get(); + + if (checkDeathKnightReqs) { - SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT); - return; + uint8 accClass = field[2].Get(); + if (accClass == CLASS_DEATH_KNIGHT) + { + if (freeDeathKnightSlots > 0) + --freeDeathKnightSlots; + + if (freeDeathKnightSlots == 0) + { + SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT); + return; + } + } + + if (!hasHeroicReqLevel) + { + uint8 accLevel = field[0].Get(); + if (accLevel >= heroicReqLevel) + hasHeroicReqLevel = true; + } + } + + // need to check team only for first character + /// @todo what to if account already has characters of both races? + if (!allowTwoSideAccounts) + { + uint32 accTeam = 0; + if (accRace > 0) + accTeam = Player::TeamIdForRace(accRace); + + if (accTeam != teamId) + { + SendCharCreate(CHAR_CREATE_PVP_TEAMS_VIOLATION); + return; + } + } + + // search same race for cinematic or same class if need + /// @todo check if cinematic already shown? (already logged in?; cinematic field) + while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT) + { + if (!result->NextRow()) + break; + + field = result->Fetch(); + accRace = field[1].Get(); + + if (!haveSameRace) + haveSameRace = createInfo->Race == accRace; + + if (checkDeathKnightReqs) + { + uint8 acc_class = field[2].Get(); + if (acc_class == CLASS_DEATH_KNIGHT) + { + if (freeDeathKnightSlots > 0) + --freeDeathKnightSlots; + + if (freeDeathKnightSlots == 0) + { + SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT); + return; + } + } + + if (!hasHeroicReqLevel) + { + uint8 acc_level = field[0].Get(); + if (acc_level >= heroicReqLevel) + hasHeroicReqLevel = true; + } + } } } - if (!hasHeroicReqLevel) + if (checkDeathKnightReqs && !hasHeroicReqLevel) { - uint8 acc_level = field[0].Get(); - if (acc_level >= heroicReqLevel) - hasHeroicReqLevel = true; + SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT); + return; } - } - } - } - if (checkDeathKnightReqs && !hasHeroicReqLevel) - { - SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT); - return; - } + // Check name uniqueness in the same step as saving to database + if (sCharacterCache->GetCharacterGuidByName(createInfo->Name)) + { + SendCharCreate(CHAR_CREATE_NAME_IN_USE); + return; + } - // Check name uniqueness in the same step as saving to database - if (sCharacterCache->GetCharacterGuidByName(createInfo->Name)) - { - SendCharCreate(CHAR_CREATE_NAME_IN_USE); - return; - } + std::shared_ptr newChar(new Player(this), [](Player* ptr) + { + // Only when player is created correctly do clean + if (ptr->HasAtLoginFlag(AT_LOGIN_FIRST)) + { + ptr->CleanupsBeforeDelete(); + } + delete ptr; + }); - std::shared_ptr newChar(new Player(this), [](Player* ptr) - { - // Only when player is created correctly do clean - if (ptr->HasAtLoginFlag(AT_LOGIN_FIRST)) + newChar->GetMotionMaster()->Initialize(); + if (!newChar->Create(sObjectMgr->GetGenerator().Generate(), createInfo.get())) + { + // Player not create (race/class/etc problem?) + SendCharCreate(CHAR_CREATE_ERROR); + return; + } + + if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2) + newChar->setCinematic(1); // not show intro + + newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login + + CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction(); + LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); + + // Player created, save it now + newChar->SaveToDB(characterTransaction, true, false); + createInfo->CharCount++; + + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); + stmt->SetData(0, GetAccountId()); + stmt->SetData(1, realm.Id.Realm); + trans->Append(stmt); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_REALM_CHARACTERS); + stmt->SetData(0, createInfo->CharCount); + stmt->SetData(1, GetAccountId()); + stmt->SetData(2, realm.Id.Realm); + trans->Append(stmt); + + LoginDatabase.CommitTransaction(trans); + + AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(characterTransaction)).AfterComplete([this, newChar = std::move(newChar)](bool success) + { + if (success) + { + LOG_INFO("entities.player.character", "Account: {} (IP: {}) Create Character: {} {}", GetAccountId(), GetRemoteAddress(), newChar->GetName(), newChar->GetGUID().ToString()); + sScriptMgr->OnPlayerCreate(newChar.get()); + sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->getGender(), newChar->getRace(), newChar->getClass(), newChar->GetLevel()); + SendCharCreate(CHAR_CREATE_SUCCESS); + } + else + SendCharCreate(CHAR_CREATE_ERROR); + }); + }; + + if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT) { - ptr->CleanupsBeforeDelete(); + finalizeCharacterCreation(PreparedQueryResult(nullptr)); + return; } - delete ptr; - }); - newChar->GetMotionMaster()->Initialize(); - if (!newChar->Create(sObjectMgr->GetGenerator().Generate(), createInfo.get())) - { - // Player not create (race/class/etc problem?) - SendCharCreate(CHAR_CREATE_ERROR); - return; - } - - if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2) - newChar->setCinematic(1); // not show intro - - newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login - - CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction(); - LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction(); - - // Player created, save it now - newChar->SaveToDB(characterTransaction, true, false); - createInfo->CharCount++; - - LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); - stmt->SetData(0, GetAccountId()); - stmt->SetData(1, realm.Id.Realm); - trans->Append(stmt); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_REALM_CHARACTERS); - stmt->SetData(0, createInfo->CharCount); - stmt->SetData(1, GetAccountId()); - stmt->SetData(2, realm.Id.Realm); - trans->Append(stmt); - - LoginDatabase.CommitTransaction(trans); - - AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(characterTransaction)).AfterComplete([this, newChar = std::move(newChar)](bool success) - { - if (success) - { - LOG_INFO("entities.player.character", "Account: {} (IP: {}) Create Character: {} {}", GetAccountId(), GetRemoteAddress(), newChar->GetName(), newChar->GetGUID().ToString()); - sScriptMgr->OnPlayerCreate(newChar.get()); - sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->getGender(), newChar->getRace(), newChar->getClass(), newChar->GetLevel()); - SendCharCreate(CHAR_CREATE_SUCCESS); - } - else - SendCharCreate(CHAR_CREATE_ERROR); - }); - }; - - if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT) - { - finalizeCharacterCreation(PreparedQueryResult(nullptr)); - return; - } - - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO); - stmt->SetData(0, GetAccountId()); - stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1); - queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt)); - })); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO); + stmt->SetData(0, GetAccountId()); + stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1); + queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt)); + })); } void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData) @@ -775,9 +775,9 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) m_playerLoading = true; AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) - { - HandlePlayerLoginFromDB(static_cast(holder)); - }); + { + HandlePlayerLoginFromDB(static_cast(holder)); + }); } void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) @@ -945,14 +945,13 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) pCurrChar->CastSpell(pCurrChar, 20584, true, 0); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) - pCurrChar->SetMovement(MOVE_WATER_WALK); } // Set FFA PvP for non GM in non-rest mode if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING)) if (!pCurrChar->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) { - sScriptMgr->OnPlayerFfaPvpStateUpdate(pCurrChar,true); + sScriptMgr->OnPlayerFfaPvpStateUpdate(pCurrChar, true); pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); } @@ -979,10 +978,10 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) { // If we process the check while players are loading they won't be notified of the changes. pCurrChar->m_Events.AddEventAtOffset([pCurrChar] - { - pCurrChar->RemoveAtLoginFlag(AT_LOGIN_CHECK_ACHIEVS, true); - pCurrChar->CheckAllAchievementCriteria(); - }, 1s); + { + pCurrChar->RemoveAtLoginFlag(AT_LOGIN_CHECK_ACHIEVS, true); + pCurrChar->CheckAllAchievementCriteria(); + }, 1s); } bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST); @@ -1009,25 +1008,25 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) ReputationMgr& repMgr = pCurrChar->GetReputationMgr(); auto SendFullReputation = [&repMgr](std::initializer_list factionsList) - { - for (auto const& itr : factionsList) { - repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false); - } - }; + for (auto const& itr : factionsList) + { + repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false); + } + }; SendFullReputation({ 942, 935, 936, 1011, 970, 967, 989, 932, 934, 1038, 1077, 1106, 1104, 1090, 1098, 1156, 1073, 1105, 1119, 1091 }); switch (pCurrChar->GetFaction()) { - case ALLIANCE: - SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 }); - break; - case HORDE: - SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 }); - break; - default: - break; + case ALLIANCE: + SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 }); + break; + case HORDE: + SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 }); + break; + default: + break; } repMgr.SendStates(); @@ -1046,7 +1045,7 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder) std::string IP_str = GetRemoteAddress(); LOG_INFO("entities.player", "Account: {} (IP: {}) Login Character:[{}] ({}) Level: {}", - GetAccountId(), IP_str, pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), pCurrChar->GetLevel()); + GetAccountId(), IP_str, pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), pCurrChar->GetLevel()); if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); @@ -1341,7 +1340,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData) std::shared_ptr renameInfo = std::make_shared(); recvData >> renameInfo->Guid - >> renameInfo->Name; + >> renameInfo->Name; // prevent character rename to invalid name if (!normalizePlayerName(renameInfo->Name)) @@ -1638,12 +1637,12 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData) } recvData >> customizeInfo->Name - >> customizeInfo->Gender - >> customizeInfo->Skin - >> customizeInfo->HairColor - >> customizeInfo->HairStyle - >> customizeInfo->FacialHair - >> customizeInfo->Face; + >> customizeInfo->Gender + >> customizeInfo->Skin + >> customizeInfo->HairColor + >> customizeInfo->HairStyle + >> customizeInfo->FacialHair + >> customizeInfo->Face; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO); stmt->SetData(0, customizeInfo->Guid.GetCounter()); @@ -1775,10 +1774,10 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData) EquipmentSet eqSet; - eqSet.Guid = setGuid; - eqSet.Name = name; - eqSet.IconName = iconName; - eqSet.state = EQUIPMENT_SET_NEW; + eqSet.Guid = setGuid; + eqSet.Name = name; + eqSet.IconName = iconName; + eqSet.state = EQUIPMENT_SET_NEW; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { @@ -1933,13 +1932,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } recvData >> factionChangeInfo->Name - >> factionChangeInfo->Gender - >> factionChangeInfo->Skin - >> factionChangeInfo->HairColor - >> factionChangeInfo->HairStyle - >> factionChangeInfo->FacialHair - >> factionChangeInfo->Face - >> factionChangeInfo->Race; + >> factionChangeInfo->Gender + >> factionChangeInfo->Skin + >> factionChangeInfo->HairColor + >> factionChangeInfo->HairStyle + >> factionChangeInfo->FacialHair + >> factionChangeInfo->Face + >> factionChangeInfo->Race; // pussywizard: if (ObjectAccessor::FindConnectedPlayer(factionChangeInfo->Guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(factionChangeInfo->Guid.GetCounter())) @@ -2217,16 +2216,16 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptrOnPlayerCanUseChat(GetPlayer(), type, lang, msg, group)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg); @@ -457,18 +448,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } - else - { - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg); - } } } break; @@ -479,11 +462,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } @@ -502,11 +481,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg); @@ -525,11 +500,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg); @@ -543,11 +514,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) return; if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); // In battleground, raid warning is sent only to players in battleground - code is ok WorldPacket data; @@ -563,11 +530,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) return; if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg); @@ -582,11 +545,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) return; if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group)) - { return; - } - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg); @@ -609,11 +568,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (Channel* chn = cMgr->GetChannel(channel, sender)) { if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg, chn)) - { return; - } - - sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); chn->Say(sender->GetGUID(), msg.c_str(), lang); } @@ -642,11 +597,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg)) - { return; - } - - sScriptMgr->OnPlayerChat(sender, type, lang, msg); } break; } @@ -670,11 +621,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg)) - { return; - } - - sScriptMgr->OnPlayerChat(sender, type, lang, msg); break; } diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 464a9e06c..7ce587015 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -482,8 +482,6 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) break; } - sScriptMgr->OnPlayerbotCheckPetitionAccount(_player, found); - if (found) { WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4)); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 452e540a7..0ea47ff8a 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -54,6 +54,10 @@ Map::~Map() { // UnloadAll must be called before deleting the map + // Kill all scheduled events without executing them, since the map and its objects are being destroyed. + // This prevents events from running on invalid or deleted objects during map destruction. + Events.KillAllEvents(false); + sScriptMgr->OnDestroyMap(this); if (!m_scriptSchedule.empty()) @@ -447,7 +451,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) } } - _creatureRespawnScheduler.Update(t_diff); + Events.Update(t_diff); if (!t_diff) { @@ -1097,7 +1101,7 @@ float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, fl if (ground) *ground = ground_z; - LiquidData const& liquidData = const_cast(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, MAP_ALL_LIQUIDS); + LiquidData const& liquidData = const_cast(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, {}); switch (liquidData.Status) { case LIQUID_MAP_ABOVE_WATER: @@ -1198,27 +1202,18 @@ static inline bool IsInWMOInterior(uint32 mogpFlags) bool Map::GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const { - float vmap_z = z; - float dynamic_z = z; float check_z = z; VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr(); - uint32 vflags; - int32 vadtId; - int32 vrootId; - int32 vgroupId; - uint32 dflags; - int32 dadtId; - int32 drootId; - int32 dgroupId; - - bool hasVmapAreaInfo = vmgr->GetAreaInfo(GetId(), x, y, vmap_z, vflags, vadtId, vrootId, vgroupId); - bool hasDynamicAreaInfo = _dynamicTree.GetAreaInfo(x, y, dynamic_z, phaseMask, dflags, dadtId, drootId, dgroupId); - auto useVmap = [&]() { check_z = vmap_z; flags = vflags; adtId = vadtId; rootId = vrootId; groupId = vgroupId; }; - auto useDyn = [&]() { check_z = dynamic_z; flags = dflags; adtId = dadtId; rootId = drootId; groupId = dgroupId; }; + VMAP::AreaAndLiquidData vdata; + VMAP::AreaAndLiquidData ddata; + bool hasVmapAreaInfo = vmgr->GetAreaAndLiquidData(GetId(), x, y, z, {}, vdata) && vdata.areaInfo.has_value(); + bool hasDynamicAreaInfo = _dynamicTree.GetAreaAndLiquidData(x, y, z, phaseMask, {}, ddata) && ddata.areaInfo.has_value(); + auto useVmap = [&] { check_z = vdata.floorZ; groupId = vdata.areaInfo->groupId; adtId = vdata.areaInfo->adtId; rootId = vdata.areaInfo->rootId; flags = vdata.areaInfo->mogpFlags; }; + auto useDyn = [&] { check_z = ddata.floorZ; groupId = ddata.areaInfo->groupId; adtId = ddata.areaInfo->adtId; rootId = ddata.areaInfo->rootId; flags = ddata.areaInfo->mogpFlags; }; if (hasVmapAreaInfo) { - if (hasDynamicAreaInfo && dynamic_z > vmap_z) + if (hasDynamicAreaInfo && ddata.floorZ > vdata.floorZ) useDyn(); else useVmap(); @@ -1299,32 +1294,30 @@ void Map::GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, flo zoneid = area->zone; } -LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType) +LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional ReqLiquidType) { LiquidData liquidData; + liquidData.Status = LIQUID_MAP_NO_WATER; VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr(); - float liquid_level = INVALID_HEIGHT; - float ground_level = INVALID_HEIGHT; - uint32 liquid_type = 0; - uint32 mogpFlags = 0; + VMAP::AreaAndLiquidData vmapData; bool useGridLiquid = true; - if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type, mogpFlags)) + if (vmgr->GetAreaAndLiquidData(GetId(), x, y, z, ReqLiquidType, vmapData) && vmapData.liquidInfo) { - useGridLiquid = !IsInWMOInterior(mogpFlags); - LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", liquid_level, ground_level, liquid_type); + useGridLiquid = !vmapData.areaInfo || !IsInWMOInterior(vmapData.areaInfo->mogpFlags); + LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", vmapData.liquidInfo->level, vmapData.floorZ, vmapData.liquidInfo->type); // Check water level and ground level - if (liquid_level > ground_level && G3D::fuzzyGe(z, ground_level - GROUND_HEIGHT_TOLERANCE)) + if (vmapData.liquidInfo->level > vmapData.floorZ && G3D::fuzzyGe(z, vmapData.floorZ - GROUND_HEIGHT_TOLERANCE)) { // hardcoded in client like this - if (GetId() == MAP_OUTLAND && liquid_type == 2) - liquid_type = 15; + if (GetId() == MAP_OUTLAND && vmapData.liquidInfo->type == 2) + vmapData.liquidInfo->type = 15; uint32 liquidFlagType = 0; - if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type)) + if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(vmapData.liquidInfo->type)) liquidFlagType = liq->Type; - if (liquid_type && liquid_type < 21) + if (vmapData.liquidInfo->type && vmapData.liquidInfo->type < 21) { if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseMask, x, y, z))) { @@ -1338,19 +1331,19 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid)) { - liquid_type = overrideLiquid; + vmapData.liquidInfo->type = overrideLiquid; liquidFlagType = liq->Type; } } } - liquidData.Level = liquid_level; - liquidData.DepthLevel = ground_level; - liquidData.Entry = liquid_type; + liquidData.Level = vmapData.liquidInfo->level; + liquidData.DepthLevel = vmapData.floorZ; + liquidData.Entry = vmapData.liquidInfo->type; liquidData.Flags = 1 << liquidFlagType; } - float delta = liquid_level - z; + float delta = vmapData.liquidInfo->level - z; // Get position delta if (delta > collisionHeight) @@ -1369,7 +1362,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, { LiquidData const& map_data = gmap->GetLiquidData(x, y, z, collisionHeight, ReqLiquidType); // Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER: - if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > ground_level)) + if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > vmapData.floorZ)) { // hardcoded in client like this uint32 liquidEntry = map_data.Entry; @@ -1385,7 +1378,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, return liquidData; } -void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType) +void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional reqLiquidType) { GridTerrainData* gmap = GetGridTerrainData(x, y); @@ -1600,7 +1593,7 @@ float Map::GetHeight(uint32 phasemask, float x, float y, float z, bool vmap/*=tr bool Map::IsInWater(uint32 phaseMask, float x, float y, float pZ, float collisionHeight) const { - LiquidData const& liquidData = const_cast(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, MAP_ALL_LIQUIDS); + LiquidData const& liquidData = const_cast(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, {}); return (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING) != 0; } @@ -1729,12 +1722,6 @@ void Map::SendObjectUpdates() WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) { - if (!sScriptMgr->OnPlayerbotCheckUpdatesToSend(iter->first)) - { - iter->second.Clear(); - continue; - } - iter->second.BuildPacket(packet); iter->first->SendDirectMessage(&packet); packet.clear(); // clean the string @@ -2764,13 +2751,13 @@ void Map::RemoveOldCorpses() void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnTimer, Position pos) { - _creatureRespawnScheduler.Schedule(respawnTimer, [this, creatureGuid, pos](TaskContext) + Events.AddEventAtOffset([this, creatureGuid, pos]() { if (Creature* creature = GetCreature(creatureGuid)) creature->Respawn(); else SummonCreature(creatureGuid.GetEntry(), pos); - }); + }, respawnTimer); } /// Send a packet to all players (or players selected team) in the zone (except self if mentioned) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 96f9cc32b..21226c54a 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -23,6 +23,7 @@ #include "DataMap.h" #include "Define.h" #include "DynamicTree.h" +#include "EventProcessor.h" #include "GameObjectModel.h" #include "GridDefines.h" #include "GridRefMgr.h" @@ -33,7 +34,6 @@ #include "PathGenerator.h" #include "Position.h" #include "SharedDefines.h" -#include "TaskScheduler.h" #include "Timer.h" #include "GridTerrainData.h" #include @@ -172,7 +172,7 @@ public: // currently unused for normal maps bool CanUnload(uint32 diff) { - if (!m_unloadTimer) + if (!m_unloadTimer || Events.HasEvents()) return false; if (m_unloadTimer <= diff) @@ -243,8 +243,8 @@ public: [[nodiscard]] float GetMinHeight(float x, float y) const; Transport* GetTransportForPos(uint32 phase, float x, float y, float z, WorldObject* worldobject = nullptr); - void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS); - LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType); + void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional reqLiquidType = {}); + LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional ReqLiquidType); [[nodiscard]] bool GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const; [[nodiscard]] uint32 GetAreaId(uint32 phaseMask, float x, float y, float z) const; @@ -430,7 +430,7 @@ public: void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone); [[nodiscard]] uint32 ApplyDynamicModeRespawnScaling(WorldObject const* obj, uint32 respawnDelay) const; - TaskScheduler _creatureRespawnScheduler; + EventProcessor Events; void ScheduleCreatureRespawn(ObjectGuid /*creatureGuid*/, Milliseconds /*respawnTimer*/, Position pos = Position()); diff --git a/src/server/game/Movement/MovementGenerators/PathGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathGenerator.cpp index 4d606f461..5ddbc2c45 100644 --- a/src/server/game/Movement/MovementGenerators/PathGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathGenerator.cpp @@ -211,8 +211,8 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con { bool buildShortcut = false; - auto liquidDataStart = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS); - auto liquidDataEnd = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS); + auto liquidDataStart = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.z, _source->GetCollisionHeight(), {}); + auto liquidDataEnd = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight(), {}); bool startUnderWaterEndInWater = liquidDataStart.Status == LIQUID_MAP_UNDER_WATER && (liquidDataEnd.Status & MAP_LIQUID_STATUS_IN_CONTACT) != 0; @@ -698,7 +698,7 @@ void PathGenerator::UpdateFilter() NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) const { - LiquidData const& liquidData = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), x, y, z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS); + LiquidData const& liquidData = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), x, y, z, _source->GetCollisionHeight(), {}); if (liquidData.Status == LIQUID_MAP_NO_WATER) return NAV_GROUND; diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 526c92730..66ba79be5 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -47,10 +47,6 @@ void PointMovementGenerator::DoInitialize(T* unit) i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); - /// Added by mod-playerbots - if (_reverseOrientation) - init.SetOrientationInversed(); - /// End added if (m_precomputedPath.size() > 2) // pussywizard: for charge init.MovebyPath(m_precomputedPath); else if (_generatePath) @@ -220,9 +216,14 @@ template <> void PointMovementGenerator::MovementInform(Creature* unit if (Unit* summoner = unit->GetCharmerOrOwner()) { if (UnitAI* AI = summoner->GetAI()) - { AI->SummonMovementInform(unit, POINT_MOTION_TYPE, id); - } + } + else + { + if (TempSummon* tempSummon = unit->ToTempSummon()) + if (Unit* summoner = tempSummon->GetSummonerUnit()) + if (UnitAI* AI = summoner->GetAI()) + AI->SummonMovementInform(unit, POINT_MOTION_TYPE, id); } } diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 0239f1a72..7c13fb982 100644 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -276,22 +276,14 @@ void WaypointMovementGenerator::MovementInform(Creature* creature) if (Unit* owner = creature->GetCharmerOrOwner()) { if (UnitAI* AI = owner->GetAI()) - { AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode); - } } else { if (TempSummon* tempSummon = creature->ToTempSummon()) - { if (Unit* owner = tempSummon->GetSummonerUnit()) - { if (UnitAI* AI = owner->GetAI()) - { AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode); - } - } - } } } @@ -418,6 +410,7 @@ void FlightPathMovementGenerator::DoFinalize(Player* player) player->m_taxi.ClearTaxiDestinations(); player->Dismount(); player->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); + player->UpdatePvPState(); // to account for cases such as flying into a PvP territory, as it does not flag on the way in if (player->m_taxi.empty()) { @@ -447,6 +440,9 @@ void FlightPathMovementGenerator::DoReset(Player* player) return; } + if (player->pvpInfo.EndTimer) + player->UpdatePvP(false, true); // PvP flag timer immediately ends when starting taxi + player->getHostileRefMgr().setOnlineOfflineState(false); player->AddUnitState(UNIT_STATE_IN_FLIGHT); player->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp index 3c7f4dd4f..c2afb5804 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.cpp @@ -169,36 +169,11 @@ void ScriptMgr::OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_DUEL_END, script->OnPlayerDuelEnd(winner, loser, type)); } -void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg) -{ - CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT, script->OnPlayerChat(player, type, lang, msg)); -} - void ScriptMgr::OnPlayerBeforeSendChatMessage(Player* player, uint32& type, uint32& lang, std::string& msg) { CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_SEND_CHAT_MESSAGE, script->OnPlayerBeforeSendChatMessage(player, type, lang, msg)); } -void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver) -{ - CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_RECEIVER, script->OnPlayerChat(player, type, lang, msg, receiver)); -} - -void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) -{ - CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_GROUP, script->OnPlayerChat(player, type, lang, msg, group)); -} - -void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) -{ - CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_GUILD, script->OnPlayerChat(player, type, lang, msg, guild)); -} - -void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel) -{ - CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_CHANNEL, script->OnPlayerChat(player, type, lang, msg, channel)); -} - void ScriptMgr::OnPlayerEmote(Player* player, uint32 emote) { CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_EMOTE, script->OnPlayerEmote(player, emote)); diff --git a/src/server/game/Scripting/ScriptDefines/PlayerScript.h b/src/server/game/Scripting/ScriptDefines/PlayerScript.h index 71d6ffcca..8177dea2c 100644 --- a/src/server/game/Scripting/ScriptDefines/PlayerScript.h +++ b/src/server/game/Scripting/ScriptDefines/PlayerScript.h @@ -306,18 +306,8 @@ public: virtual void OnPlayerDuelEnd(Player* /*winner*/, Player* /*loser*/, DuelCompleteType /*type*/) { } // The following methods are called when a player sends a chat message. - virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/) { } - virtual void OnPlayerBeforeSendChatMessage(Player* /*player*/, uint32& /*type*/, uint32& /*lang*/, std::string& /*msg*/) { } - virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Player* /*receiver*/) { } - - virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Group* /*group*/) { } - - virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Guild* /*guild*/) { } - - virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Channel* /*channel*/) { } - // Both of the below are called on emote opcodes. virtual void OnPlayerEmote(Player* /*player*/, uint32 /*emote*/) { } diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 392d7d5fc..e1d535007 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -340,12 +340,7 @@ public: /* PlayerScript */ void OnPlayerDuelRequest(Player* target, Player* challenger); void OnPlayerDuelStart(Player* player1, Player* player2); void OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type); - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg); void OnPlayerBeforeSendChatMessage(Player* player, uint32& type, uint32& lang, std::string& msg); - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver); - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group); - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild); - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel); void OnPlayerEmote(Player* player, uint32 emote); void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid); void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 2d7a658d1..608b9614b 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1377,7 +1377,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici float ground = m_caster->GetMapHeight(x, y, z, true); float liquidLevel = VMAP_INVALID_HEIGHT_VALUE; - LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), MAP_ALL_LIQUIDS); + LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {}); if (liquidData.Status) liquidLevel = liquidData.Level; diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp index bbfedeceb..84d22411e 100644 --- a/src/server/scripts/Commands/cs_cheat.cpp +++ b/src/server/scripts/Commands/cs_cheat.cpp @@ -156,13 +156,13 @@ public: if (enable) { handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK); - handler->GetSession()->GetPlayer()->SetMovement(MOVE_WATER_WALK); // ON + handler->GetSession()->GetPlayer()->SetWaterWalking(true); // ON handler->SendSysMessage("Waterwalking is ON. You can walk on water."); } else { handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK); - handler->GetSession()->GetPlayer()->SetMovement(MOVE_LAND_WALK); // OFF + handler->GetSession()->GetPlayer()->SetWaterWalking(false); // OFF handler->SendSysMessage("Waterwalking is OFF. You can't walk on water."); } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 4a6deb50f..80201c969 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1949,7 +1949,7 @@ public: // the max level of the new profession. uint16 max = maxPureSkill ? *maxPureSkill : targetHasSkill ? target->GetPureMaxSkillValue(skillID) : uint16(level); - if (level < 0 || level > max || max < 0) + if (level <= 0 || level > max || max <= 0) { return false; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index e0adab854..66c50537e 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -219,7 +219,6 @@ public: { ObjectGuid::LowType guid = sObjectMgr->GenerateCreatureSpawnId(); CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid); - data.spawnId = guid; data.id1 = id; data.phaseMask = chr->GetPhaseMaskForSpawn(); data.posX = chr->GetTransOffsetX(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index df4e3a016..f5ff6e968 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -2019,11 +2019,14 @@ class spell_gen_animal_blood : public AuraScript { // Remove all auras with spell id 46221, except the one currently being applied while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, ObjectGuid::Empty, ObjectGuid::Empty, 0, GetAura())) - GetUnitOwner()->RemoveOwnedAura(aur); + GetUnitOwner()->RemoveOwnedAura(aur, AURA_REMOVE_BY_EXPIRE); } void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { + if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) + return; + if (Unit* owner = GetUnitOwner()) if (owner->IsInWater()) owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true); @@ -2044,7 +2047,7 @@ class spell_spawn_blood_pool : public SpellScript void SetDest(SpellDestination &dest) { Unit* caster = GetCaster(); - LiquidData liquidStatus = caster->GetMap()->GetLiquidData(caster->GetPhaseMask(), caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), caster->GetCollisionHeight(), MAP_ALL_LIQUIDS); + LiquidData liquidStatus = caster->GetMap()->GetLiquidData(caster->GetPhaseMask(), caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), caster->GetCollisionHeight(), {}); float level = liquidStatus.Level > INVALID_HEIGHT ? liquidStatus.Level : caster->GetPositionZ(); Position pos = Position(caster->GetPositionX(), caster->GetPositionY(), level, caster->GetOrientation()); diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp index 8f7f403e0..d031d4465 100644 --- a/src/server/scripts/World/areatrigger_scripts.cpp +++ b/src/server/scripts/World/areatrigger_scripts.cpp @@ -170,7 +170,7 @@ public: { QuestStatus QLR = player->GetQuestStatus(QUEST_LAST_RITES); QuestStatus QBT = player->GetQuestStatus(QUEST_BREAKING_THROUGH); - if (!(QLR == QUEST_STATUS_INCOMPLETE || QLR == QUEST_STATUS_COMPLETE || + if (!(QLR == QUEST_STATUS_INCOMPLETE || QLR == QUEST_STATUS_COMPLETE || QLR == QUEST_STATUS_REWARDED || QBT == QUEST_STATUS_INCOMPLETE || QBT == QUEST_STATUS_COMPLETE)) return false; diff --git a/src/server/scripts/World/chat_log.cpp b/src/server/scripts/World/chat_log.cpp index a1af849c9..3feb0c528 100644 --- a/src/server/scripts/World/chat_log.cpp +++ b/src/server/scripts/World/chat_log.cpp @@ -27,16 +27,16 @@ public: ChatLogScript() : PlayerScript("ChatLogScript", { - PLAYERHOOK_ON_CHAT, - PLAYERHOOK_ON_CHAT_WITH_GROUP, - PLAYERHOOK_ON_CHAT_WITH_GUILD, - PLAYERHOOK_ON_CHAT_WITH_CHANNEL, - PLAYERHOOK_ON_CHAT_WITH_RECEIVER + PLAYERHOOK_CAN_PLAYER_USE_CHAT, + PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT, + PLAYERHOOK_CAN_PLAYER_USE_GROUP_CHAT, + PLAYERHOOK_CAN_PLAYER_USE_GUILD_CHAT, + PLAYERHOOK_CAN_PLAYER_USE_CHANNEL_CHAT, }) { } - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg) override + bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg) override { std::string logType = ""; std::string chatType = ""; @@ -56,14 +56,16 @@ public: chatType = "yells"; break; default: - return; + return true; } LOG_INFO(logType, "Player {} {} (language {}): {}", player->GetName(), chatType, lang, msg); + + return true; } - void OnPlayerChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) override + bool OnPlayerCanUseChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) override { //! NOTE: //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER" @@ -72,9 +74,11 @@ public: LOG_INFO(logType + msgType, "Player {} {} {}: {}", player->GetName(), msgType, receiver ? receiver->GetName() : "", msg); + + return true; } - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) override + bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group) override { //! NOTE: //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER" @@ -97,7 +101,7 @@ public: msgType = "bg"; break; default: - return; + return true; } std::string role = (type == CHAT_MSG_PARTY_LEADER || type == CHAT_MSG_RAID_LEADER || type == CHAT_MSG_BATTLEGROUND_LEADER) ? "Leader player" : "Player"; @@ -106,9 +110,11 @@ public: LOG_INFO(logType + msgType, "{} {} {} {} with leader {}: {}", role, player->GetName(), action, msgType, targetGroup, msg); + + return true; } - void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override + bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override { //! NOTE: //! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER" @@ -124,14 +130,16 @@ public: msgType = "guild.officer"; break; default: - return; + return true; } LOG_INFO(logType + msgType, "Player {} tells {} \"{}\": {}", player->GetName(), msgType, guild ? guild->GetName() : "", msg); + + return true; } - void OnPlayerChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) override + bool OnPlayerCanUseChat(Player* player, uint32 /*type*/, uint32 /*lang*/, std::string& msg, Channel* channel) override { bool isSystem = channel && (channel->HasFlag(CHANNEL_FLAG_TRADE) || @@ -152,6 +160,8 @@ public: LOG_INFO("chat.channel." + channelName, "Player {} tells channel {}: {}", player->GetName(), channelName, msg); } + + return true; } };