minimize delta, legacy and merge mistakes over the years
This commit is contained in:
@@ -31,7 +31,7 @@ body:
|
|||||||
description: |
|
description: |
|
||||||
Do you have any logs or screenshots that can be useful?
|
Do you have any logs or screenshots that can be useful?
|
||||||
Crash logs in text are preffered over screenshots.
|
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:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
- type: input
|
- type: input
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
# List of AUTHORS who contributed over time to the AzerothCore project
|
# 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
|
## Point of current development
|
||||||
The project is currently hosted at https://www.azerothcore.org/ and developed under https://github.com/azerothcore
|
The project is currently hosted at https://www.azerothcore.org/ and developed under https://github.com/azerothcore
|
||||||
|
|
||||||
|
|||||||
@@ -258,4 +258,4 @@ COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build \
|
|||||||
/azerothcore/env/dist/bin/vmap4_assembler /azerothcore/env/dist/bin/vmap4_assembler
|
/azerothcore/env/dist/bin/vmap4_assembler /azerothcore/env/dist/bin/vmap4_assembler
|
||||||
|
|
||||||
COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build \
|
COPY --chown=$DOCKER_USER:$DOCKER_USER --from=build \
|
||||||
/azerothcore/env/dist/bin/vmap4_extractor /azerothcore/env/dist/bin/vmap4_extractor
|
/azerothcore/env/dist/bin/vmap4_extractor /azerothcore/env/dist/bin/vmap4_extractor
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
|
||||||
# Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
# Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||||
#
|
#
|
||||||
# This file is free software; as a special exception the author gives
|
# This file is free software; as a special exception the author gives
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||||
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
|
||||||
#
|
#
|
||||||
# This file is free software; as a special exception the author gives
|
# This file is free software; as a special exception the author gives
|
||||||
# unlimited permission to copy and/or distribute it, with or without
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||||
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
|
||||||
#
|
#
|
||||||
# This file is free software; as a special exception the author gives
|
# This file is free software; as a special exception the author gives
|
||||||
# unlimited permission to copy and/or distribute it, with or without
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -70,6 +70,7 @@ private:
|
|||||||
{
|
{
|
||||||
tree.clear();
|
tree.clear();
|
||||||
objects.clear();
|
objects.clear();
|
||||||
|
bounds = G3D::AABox::empty();
|
||||||
// create space for the first node
|
// create space for the first node
|
||||||
tree.push_back(3u << 30u); // dummy leaf
|
tree.push_back(3u << 30u); // dummy leaf
|
||||||
tree.insert(tree.end(), 2, 0);
|
tree.insert(tree.end(), 2, 0);
|
||||||
@@ -116,6 +117,7 @@ public:
|
|||||||
delete[] dat.indices;
|
delete[] dat.indices;
|
||||||
}
|
}
|
||||||
[[nodiscard]] uint32 primCount() const { return objects.size(); }
|
[[nodiscard]] uint32 primCount() const { return objects.size(); }
|
||||||
|
G3D::AABox const& bound() const { return bounds; }
|
||||||
|
|
||||||
template<typename RayCallback>
|
template<typename RayCallback>
|
||||||
void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const
|
void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const
|
||||||
|
|||||||
@@ -170,25 +170,6 @@ private:
|
|||||||
VMAP::ModelIgnoreFlags _ignoreFlags;
|
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
|
struct DynamicTreeLocationInfoCallback
|
||||||
{
|
{
|
||||||
DynamicTreeLocationInfoCallback(uint32 phaseMask)
|
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
|
bool DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional<uint8> reqLiquidType, VMAP::AreaAndLiquidData& data) 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
|
|
||||||
{
|
{
|
||||||
G3D::Vector3 v(x, y, z + 0.5f);
|
G3D::Vector3 v(x, y, z + 0.5f);
|
||||||
DynamicTreeLocationInfoCallback intersectionCallBack(phasemask);
|
DynamicTreeLocationInfoCallback intersectionCallBack(phasemask);
|
||||||
@@ -335,13 +299,16 @@ void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phas
|
|||||||
data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
|
data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
|
||||||
uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType();
|
uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType();
|
||||||
float liquidLevel;
|
float liquidLevel;
|
||||||
if (!reqLiquidType || (dynamic_cast<VMAP::VMapMgr2*>(VMAP::VMapFactory::createOrGetVMapMgr())->GetLiquidFlagsPtr(liquidType) & reqLiquidType))
|
if (!reqLiquidType || (dynamic_cast<VMAP::VMapMgr2*>(VMAP::VMapFactory::createOrGetVMapMgr())->GetLiquidFlagsPtr(liquidType) & *reqLiquidType))
|
||||||
if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), liquidLevel))
|
if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), liquidLevel))
|
||||||
data.liquidInfo.emplace(liquidType, liquidLevel);
|
data.liquidInfo.emplace(liquidType, liquidLevel);
|
||||||
|
|
||||||
data.areaInfo.emplace(0,
|
data.areaInfo.emplace(intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
|
||||||
|
0,
|
||||||
intersectionCallBack.GetLocationInfo().rootId,
|
intersectionCallBack.GetLocationInfo().rootId,
|
||||||
intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
|
intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags(),
|
||||||
intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags());
|
0);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#define _DYNTREE_H
|
#define _DYNTREE_H
|
||||||
|
|
||||||
#include "Define.h"
|
#include "Define.h"
|
||||||
|
#include "Optional.h"
|
||||||
|
|
||||||
namespace G3D
|
namespace G3D
|
||||||
{
|
{
|
||||||
@@ -47,8 +48,7 @@ public:
|
|||||||
|
|
||||||
bool GetIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const G3D::Vector3& endPos, float& maxDist) const;
|
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;
|
bool GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional<uint8> reqLiquidType, VMAP::AreaAndLiquidData& data) const;
|
||||||
void GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const;
|
|
||||||
|
|
||||||
bool GetObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1,
|
bool GetObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1,
|
||||||
const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos,
|
const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos,
|
||||||
|
|||||||
@@ -52,20 +52,23 @@ namespace VMAP
|
|||||||
{
|
{
|
||||||
struct AreaInfo
|
struct AreaInfo
|
||||||
{
|
{
|
||||||
AreaInfo(int32 _adtId, int32 _rootId, int32 _groupId, uint32 _flags)
|
AreaInfo() = default;
|
||||||
: adtId(_adtId), rootId(_rootId), groupId(_groupId), mogpFlags(_flags) { }
|
AreaInfo(int32 _groupId, int32 _adtId, int32 _rootId, uint32 _mogpFlags, uint32 _uniqueId)
|
||||||
int32 const adtId;
|
: groupId(_groupId), adtId(_adtId), rootId(_rootId), mogpFlags(_mogpFlags), uniqueId(_uniqueId) { }
|
||||||
int32 const rootId;
|
int32 groupId = 0;
|
||||||
int32 const groupId;
|
int32 adtId = 0;
|
||||||
uint32 const mogpFlags;
|
int32 rootId = 0;
|
||||||
|
uint32 mogpFlags = 0;
|
||||||
|
uint32 uniqueId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LiquidInfo
|
struct LiquidInfo
|
||||||
{
|
{
|
||||||
|
LiquidInfo() = default;
|
||||||
LiquidInfo(uint32 _type, float _level)
|
LiquidInfo(uint32 _type, float _level)
|
||||||
: type(_type), level(_level) {}
|
: type(_type), level(_level) {}
|
||||||
uint32 const type;
|
uint32 type = 0;
|
||||||
float const level;
|
float level = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
float floorZ = VMAP_INVALID_HEIGHT;
|
float floorZ = VMAP_INVALID_HEIGHT;
|
||||||
@@ -120,14 +123,12 @@ namespace VMAP
|
|||||||
[[nodiscard]] bool isMapLoadingEnabled() const { return (iEnableLineOfSightCalc || iEnableHeightCalc ); }
|
[[nodiscard]] bool isMapLoadingEnabled() const { return (iEnableLineOfSightCalc || iEnableHeightCalc ); }
|
||||||
|
|
||||||
[[nodiscard]] virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0;
|
[[nodiscard]] virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Query world model area info.
|
Query world model area info.
|
||||||
\param z gets adjusted to the ground height for which this are info is valid
|
\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 GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) 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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,8 +138,7 @@ namespace MMAP
|
|||||||
uint32 packedGridPos = packTileID(x, y);
|
uint32 packedGridPos = packTileID(x, y);
|
||||||
if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -253,70 +253,8 @@ namespace VMAP
|
|||||||
return VMAP_INVALID_HEIGHT_VALUE;
|
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<uint8> 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<float>::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);
|
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||||
if (instanceTree != iInstanceMapTrees.end())
|
if (instanceTree != iInstanceMapTrees.end())
|
||||||
{
|
{
|
||||||
@@ -325,16 +263,22 @@ namespace VMAP
|
|||||||
if (instanceTree->second->GetLocationInfo(pos, info))
|
if (instanceTree->second->GetLocationInfo(pos, info))
|
||||||
{
|
{
|
||||||
data.floorZ = info.ground_Z;
|
data.floorZ = info.ground_Z;
|
||||||
uint32 liquidType = info.hitModel->GetLiquidType();
|
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
|
||||||
float liquidLevel;
|
{
|
||||||
if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & reqLiquidType))
|
uint32 liquidType = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
|
||||||
if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel))
|
float liquidLevel;
|
||||||
data.liquidInfo.emplace(liquidType, liquidLevel);
|
if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & *reqLiquidType))
|
||||||
|
if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel))
|
||||||
|
data.liquidInfo.emplace(liquidType, liquidLevel);
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
|
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 */)
|
WorldModel* VMapMgr2::acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags/* Only used when creating the model */)
|
||||||
|
|||||||
@@ -115,9 +115,7 @@ namespace VMAP
|
|||||||
|
|
||||||
bool processCommand(char* /*command*/) override { return false; } // for debug and extensions
|
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 GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) 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;
|
|
||||||
|
|
||||||
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags);
|
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags);
|
||||||
void releaseModelInstance(const std::string& filename);
|
void releaseModelInstance(const std::string& filename);
|
||||||
|
|||||||
@@ -51,22 +51,6 @@ namespace VMAP
|
|||||||
bool hit;
|
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
|
class LocationInfoCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -99,22 +83,6 @@ namespace VMAP
|
|||||||
return tilefilename.str();
|
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
|
bool StaticMapTree::GetLocationInfo(const Vector3& pos, LocationInfo& info) const
|
||||||
{
|
{
|
||||||
LocationInfoCallback intersectionCallBack(iTreeValues, info);
|
LocationInfoCallback intersectionCallBack(iTreeValues, info);
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ namespace VMAP
|
|||||||
enum class ModelIgnoreFlags : uint32;
|
enum class ModelIgnoreFlags : uint32;
|
||||||
enum class LoadResult : uint8;
|
enum class LoadResult : uint8;
|
||||||
|
|
||||||
|
struct GroupLocationInfo
|
||||||
|
{
|
||||||
|
const GroupModel* hitModel = nullptr;
|
||||||
|
int32 rootId = -1;
|
||||||
|
};
|
||||||
|
|
||||||
struct LocationInfo
|
struct LocationInfo
|
||||||
{
|
{
|
||||||
LocationInfo(): ground_Z(-G3D::inf()) { }
|
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;
|
[[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;
|
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;
|
[[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 GetLocationInfo(const G3D::Vector3& pos, LocationInfo& info) const;
|
||||||
|
|
||||||
bool InitMap(const std::string& fname, VMapMgr2* vm);
|
bool InitMap(const std::string& fname, VMapMgr2* vm);
|
||||||
|
|||||||
@@ -203,27 +203,6 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
|
|||||||
return hit;
|
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
|
bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const
|
||||||
{
|
{
|
||||||
if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject())
|
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 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||||
float zDist;
|
float zDist;
|
||||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
|
|
||||||
|
VMAP::GroupLocationInfo groupInfo;
|
||||||
|
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo))
|
||||||
{
|
{
|
||||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ public:
|
|||||||
[[nodiscard]] bool IsMapObject() const { return isWmo; }
|
[[nodiscard]] bool IsMapObject() const { return isWmo; }
|
||||||
|
|
||||||
bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
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 GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const;
|
||||||
bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const;
|
bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const;
|
||||||
|
|
||||||
|
|||||||
@@ -63,44 +63,6 @@ namespace VMAP
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo& info) const
|
|
||||||
{
|
|
||||||
if (!iModel)
|
|
||||||
{
|
|
||||||
#ifdef VMAP_DEBUG
|
|
||||||
std::cout << "<object not loaded>\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
|
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const
|
||||||
{
|
{
|
||||||
if (!iModel)
|
if (!iModel)
|
||||||
@@ -124,7 +86,9 @@ namespace VMAP
|
|||||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||||
float zDist;
|
float zDist;
|
||||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
|
|
||||||
|
GroupLocationInfo groupInfo;
|
||||||
|
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo))
|
||||||
{
|
{
|
||||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||||
// Transform back to world space. Note that:
|
// Transform back to world space. Note that:
|
||||||
@@ -133,6 +97,8 @@ namespace VMAP
|
|||||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||||
if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
|
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.ground_Z = world_Z;
|
||||||
info.hitInstance = this;
|
info.hitInstance = this;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ namespace VMAP
|
|||||||
ModelInstance(const ModelSpawn& spawn, WorldModel* model);
|
ModelInstance(const ModelSpawn& spawn, WorldModel* model);
|
||||||
void setUnloaded() { iModel = nullptr; }
|
void setUnloaded() { iModel = nullptr; }
|
||||||
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit, ModelIgnoreFlags ignoreFlags) const;
|
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 GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const;
|
||||||
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const;
|
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const;
|
||||||
WorldModel* getWorldModel() { return iModel; }
|
WorldModel* getWorldModel() { return iModel; }
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
#include "ModelIgnoreFlags.h"
|
#include "ModelIgnoreFlags.h"
|
||||||
#include "ModelInstance.h"
|
#include "ModelInstance.h"
|
||||||
#include "VMapDefinitions.h"
|
#include "VMapDefinitions.h"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
using G3D::Vector3;
|
using G3D::Vector3;
|
||||||
using G3D::Ray;
|
|
||||||
|
|
||||||
template<> struct BoundsTrait<VMAP::GroupModel>
|
template<> struct BoundsTrait<VMAP::GroupModel>
|
||||||
{
|
{
|
||||||
@@ -451,21 +451,46 @@ namespace VMAP
|
|||||||
return callback.hit;
|
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;
|
else
|
||||||
float dist = G3D::inf();
|
|
||||||
G3D::Ray ray(rPos, down);
|
|
||||||
bool hit = IntersectRay(ray, dist, false);
|
|
||||||
if (hit)
|
|
||||||
{
|
{
|
||||||
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
|
bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const
|
||||||
@@ -541,76 +566,58 @@ namespace VMAP
|
|||||||
class WModelAreaCallback
|
class WModelAreaCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WModelAreaCallback(const std::vector<GroupModel>& vals, const Vector3& down):
|
WModelAreaCallback(std::vector<GroupModel> const& vals) :
|
||||||
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { }
|
prims(vals), hit() { }
|
||||||
std::vector<GroupModel>::const_iterator prims;
|
std::vector<GroupModel> const& prims;
|
||||||
std::vector<GroupModel>::const_iterator hit;
|
std::array<GroupModel const*, 3> hit;
|
||||||
float minVol;
|
bool operator()(G3D::Ray const& ray, uint32 entry, float& distance, bool /*stopAtFirstHit*/)
|
||||||
float zDist;
|
|
||||||
Vector3 zVec;
|
|
||||||
void operator()(const Vector3& point, uint32 entry)
|
|
||||||
{
|
{
|
||||||
float group_Z;
|
float group_Z;
|
||||||
//float pVol = prims[entry].GetBound().volume();
|
if (GroupModel::InsideResult result = prims[entry].IsInsideObject(ray, group_Z); result != GroupModel::OUT_OF_BOUNDS)
|
||||||
//if (pVol < minVol)
|
|
||||||
//{
|
|
||||||
/* if (prims[entry].iBound.contains(point)) */
|
|
||||||
if (prims[entry].IsInsideObject(point, zVec, group_Z))
|
|
||||||
{
|
{
|
||||||
//minVol = pVol;
|
if (result != GroupModel::MAYBE_INSIDE)
|
||||||
//hit = prims + entry;
|
|
||||||
if (group_Z < zDist)
|
|
||||||
{
|
{
|
||||||
zDist = group_Z;
|
if (group_Z < distance)
|
||||||
hit = prims + entry;
|
{
|
||||||
|
distance = group_Z;
|
||||||
|
hit[result] = &prims[entry];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef VMAP_DEBUG
|
else
|
||||||
const GroupModel& gm = prims[entry];
|
hit[result] = &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
|
|
||||||
}
|
}
|
||||||
//}
|
return false;
|
||||||
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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())
|
if (groupModels.empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WModelAreaCallback callback(groupModels, down);
|
WModelAreaCallback callback(groupModels);
|
||||||
groupTree.intersectPoint(p, callback);
|
G3D::Ray r(p - down * 0.1f, down);
|
||||||
if (callback.hit != groupModels.end())
|
float zDist = groupTree.bound().extent().length();
|
||||||
|
groupTree.intersectRay(r, callback, zDist, false);
|
||||||
|
if (callback.hit[GroupModel::INSIDE])
|
||||||
{
|
{
|
||||||
info.rootId = RootWMOID;
|
info.rootId = RootWMOID;
|
||||||
info.groupId = callback.hit->GetWmoID();
|
info.hitModel = callback.hit[GroupModel::INSIDE];
|
||||||
info.flags = callback.hit->GetMogpFlags();
|
dist = zDist;
|
||||||
info.result = true;
|
|
||||||
dist = callback.zDist;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const
|
// 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)
|
||||||
if (groupModels.empty())
|
// then find back where we originated from (GroupModel::MAYBE_INSIDE)
|
||||||
{
|
if (callback.hit[GroupModel::MAYBE_INSIDE] && callback.hit[GroupModel::ABOVE])
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WModelAreaCallback callback(groupModels, down);
|
|
||||||
groupTree.intersectPoint(p, callback);
|
|
||||||
if (callback.hit != groupModels.end())
|
|
||||||
{
|
{
|
||||||
info.rootId = RootWMOID;
|
info.rootId = RootWMOID;
|
||||||
info.hitModel = &(*callback.hit);
|
info.hitModel = callback.hit[GroupModel::MAYBE_INSIDE];
|
||||||
dist = callback.zDist;
|
dist = zDist;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace VMAP
|
|||||||
class TreeNode;
|
class TreeNode;
|
||||||
struct AreaInfo;
|
struct AreaInfo;
|
||||||
struct LocationInfo;
|
struct LocationInfo;
|
||||||
|
struct GroupLocationInfo;
|
||||||
enum class ModelIgnoreFlags : uint32;
|
enum class ModelIgnoreFlags : uint32;
|
||||||
|
|
||||||
class MeshTriangle
|
class MeshTriangle
|
||||||
@@ -81,12 +82,14 @@ namespace VMAP
|
|||||||
void setMeshData(std::vector<G3D::Vector3>& vert, std::vector<MeshTriangle>& tri);
|
void setMeshData(std::vector<G3D::Vector3>& vert, std::vector<MeshTriangle>& tri);
|
||||||
void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = nullptr; }
|
void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = nullptr; }
|
||||||
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const;
|
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;
|
bool GetLiquidLevel(const G3D::Vector3& pos, float& liqHeight) const;
|
||||||
[[nodiscard]] uint32 GetLiquidType() const;
|
[[nodiscard]] uint32 GetLiquidType() const;
|
||||||
bool writeToFile(FILE* wf);
|
bool writeToFile(FILE* wf);
|
||||||
bool readFromFile(FILE* rf);
|
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 GetMogpFlags() const { return iMogpFlags; }
|
||||||
[[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; }
|
[[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; }
|
||||||
void GetMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid);
|
void GetMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid);
|
||||||
@@ -109,8 +112,7 @@ namespace VMAP
|
|||||||
void setGroupModels(std::vector<GroupModel>& models);
|
void setGroupModels(std::vector<GroupModel>& models);
|
||||||
void setRootWmoID(uint32 id) { RootWMOID = id; }
|
void setRootWmoID(uint32 id) { RootWMOID = id; }
|
||||||
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) const;
|
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, GroupLocationInfo& info) const;
|
||||||
bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const;
|
|
||||||
bool writeFile(const std::string& filename);
|
bool writeFile(const std::string& filename);
|
||||||
bool readFile(const std::string& filename);
|
bool readFile(const std::string& filename);
|
||||||
void GetGroupModels(std::vector<GroupModel>& outGroupModels);
|
void GetGroupModels(std::vector<GroupModel>& outGroupModels);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
|
||||||
*
|
*
|
||||||
* This file was based on
|
* This file was based on
|
||||||
* https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/
|
* https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Originally written by Rochet2 - Copyright (C) 2018+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: http://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
* Originally written by Rochet2 - Copyright (C) 2018+ AzerothCore <www.azerothcore.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DATA_MAP_H_
|
#ifndef _DATA_MAP_H_
|
||||||
|
|||||||
@@ -97,32 +97,6 @@ public:
|
|||||||
return _eventMap.empty();
|
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<uint32>(duration_cast<Milliseconds>(_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<uint32>(timeUntil.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name SetPhase
|
* @name SetPhase
|
||||||
* @brief Sets the phase of the map (absolute).
|
* @brief Sets the phase of the map (absolute).
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class EventProcessor
|
|||||||
[[nodiscard]] uint64 CalculateQueueTime(uint64 delay) const;
|
[[nodiscard]] uint64 CalculateQueueTime(uint64 delay) const;
|
||||||
|
|
||||||
void CancelEventGroup(uint8 group);
|
void CancelEventGroup(uint8 group);
|
||||||
bool HaveEventList() const { return !m_events.empty(); }
|
bool HasEvents() const { return !m_events.empty(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint64 m_time{0};
|
uint64 m_time{0};
|
||||||
|
|||||||
@@ -347,7 +347,6 @@ inline wchar_t wcharToLower(wchar_t wchar)
|
|||||||
|
|
||||||
void wstrToUpper(std::wstring& str);
|
void wstrToUpper(std::wstring& str);
|
||||||
void wstrToLower(std::wstring& str);
|
void wstrToLower(std::wstring& str);
|
||||||
void strToLower(std::string& str);
|
|
||||||
|
|
||||||
std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
|
std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() cons
|
|||||||
// data/sql
|
// data/sql
|
||||||
for (auto const& itr : moduleList)
|
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);
|
Path const p(path);
|
||||||
if (!is_directory(p))
|
if (!is_directory(p))
|
||||||
|
|||||||
@@ -83,29 +83,19 @@ WorldObject* CreatureAI::GetSummoner() const
|
|||||||
inline bool IsValidCombatTarget(Creature* source, Player* target)
|
inline bool IsValidCombatTarget(Creature* source, Player* target)
|
||||||
{
|
{
|
||||||
if (target->IsGameMaster())
|
if (target->IsGameMaster())
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!source->IsInWorld() || !target->IsInWorld())
|
if (!source->IsInWorld() || !target->IsInWorld())
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!source->IsAlive() || !target->IsAlive())
|
if (!source->IsAlive() || !target->IsAlive())
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!source->InSamePhase(target))
|
if (!source->InSamePhase(target))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (source->HasUnitState(UNIT_STATE_IN_FLIGHT) || target->HasUnitState(UNIT_STATE_IN_FLIGHT))
|
if (source->IsInFlight() || target->IsInFlight())
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -950,6 +950,9 @@ bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e)
|
|||||||
case SMART_TARGET_VEHICLE_PASSENGER: return sizeof(SmartTarget::vehicle);
|
case SMART_TARGET_VEHICLE_PASSENGER: return sizeof(SmartTarget::vehicle);
|
||||||
// case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: return sizeof(SmartTarget::goClosest);
|
// case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: return sizeof(SmartTarget::goClosest);
|
||||||
case SMART_TARGET_PLAYER_WITH_AURA: return sizeof(SmartTarget::playerWithAura);
|
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:
|
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.",
|
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());
|
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
|
||||||
|
|||||||
@@ -1826,6 +1826,15 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
|||||||
// someone on this realm has already completed that achievement
|
// someone on this realm has already completed that achievement
|
||||||
if (sAchievementMgr->IsRealmCompleted(achievement))
|
if (sAchievementMgr->IsRealmCompleted(achievement))
|
||||||
return false;
|
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<uint32, 9> 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)
|
// pussywizard: progress will be deleted after getting the achievement (optimization)
|
||||||
|
|||||||
@@ -33,17 +33,6 @@ class WorldObject;
|
|||||||
|
|
||||||
struct GameTele;
|
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
|
class AC_GAME_API ChatHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -92,27 +92,13 @@ private:
|
|||||||
};
|
};
|
||||||
ThreatMgr* iThreatMgr;
|
ThreatMgr* iThreatMgr;
|
||||||
public:
|
public:
|
||||||
ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iFValue(0.f), iThreatMgr(nullptr)
|
ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = nullptr; }
|
||||||
{
|
|
||||||
iHostileReference = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iFValue(0.f), iThreatMgr(nullptr)
|
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; }
|
||||||
{
|
|
||||||
iHostileReference = pHostileReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr)
|
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; iFValue = pValue; }
|
||||||
{
|
|
||||||
iHostileReference = pHostileReference;
|
|
||||||
iFValue = pValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr)
|
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; iBValue = pValue; }
|
||||||
{
|
|
||||||
iHostileReference = pHostileReference;
|
|
||||||
iBValue = pValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] int32 getIValue() const { return iIValue; }
|
[[nodiscard]] int32 getIValue() const { return iIValue; }
|
||||||
|
|
||||||
|
|||||||
@@ -1373,8 +1373,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
|||||||
m_spawnId = sObjectMgr->GenerateCreatureSpawnId();
|
m_spawnId = sObjectMgr->GenerateCreatureSpawnId();
|
||||||
|
|
||||||
CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId);
|
CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId);
|
||||||
data.spawnId = m_spawnId;
|
data.spawnId = m_spawnId; // mod_playerbots
|
||||||
|
|
||||||
uint32 displayId = GetNativeDisplayId();
|
uint32 displayId = GetNativeDisplayId();
|
||||||
uint32 npcflag = GetNpcFlags();
|
uint32 npcflag = GetNpcFlags();
|
||||||
uint32 unit_flags = GetUnitFlags();
|
uint32 unit_flags = GetUnitFlags();
|
||||||
@@ -3498,7 +3497,7 @@ bool Creature::IsMovementPreventedByCasting() const
|
|||||||
void Creature::SetCannotReachTarget(ObjectGuid const& cannotReach)
|
void Creature::SetCannotReachTarget(ObjectGuid const& cannotReach)
|
||||||
{
|
{
|
||||||
if (cannotReach == m_cannotReachTarget)
|
if (cannotReach == m_cannotReachTarget)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> EquipmentInfo
|
|||||||
struct CreatureData
|
struct CreatureData
|
||||||
{
|
{
|
||||||
CreatureData() = default;
|
CreatureData() = default;
|
||||||
ObjectGuid::LowType spawnId{0};
|
ObjectGuid::LowType spawnId{ 0 }; // mod_playerbots
|
||||||
uint32 id1{0}; // entry in creature_template
|
uint32 id1{0}; // entry in creature_template
|
||||||
uint32 id2{0}; // entry in creature_template
|
uint32 id2{0}; // entry in creature_template
|
||||||
uint32 id3{0}; // entry in creature_template
|
uint32 id3{0}; // entry in creature_template
|
||||||
|
|||||||
@@ -3294,9 +3294,7 @@ void Player::learnSpell(uint32 spellId, bool temporary /*= false*/, bool learnFr
|
|||||||
// Xinef: don't allow to learn active spell once more
|
// Xinef: don't allow to learn active spell once more
|
||||||
if (HasActiveSpell(spellId))
|
if (HasActiveSpell(spellId))
|
||||||
{
|
{
|
||||||
#ifndef MOD_PLAYERBOTS
|
|
||||||
LOG_DEBUG("entities.player", "Player ({}) tries to learn already active spell: {}", GetGUID().ToString(), spellId);
|
LOG_DEBUG("entities.player", "Player ({}) tries to learn already active spell: {}", GetGUID().ToString(), spellId);
|
||||||
#endif
|
|
||||||
return;
|
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:
|
/* Preconditions:
|
||||||
- a resurrectable corpse must not be loaded for the player (only bones)
|
- a resurrectable corpse must not be loaded for the player (only bones)
|
||||||
- the player must be in world
|
- the player must be in world
|
||||||
@@ -4389,7 +4365,6 @@ void Player::BuildPlayerRepop()
|
|||||||
}
|
}
|
||||||
GetMap()->AddToMap(corpse);
|
GetMap()->AddToMap(corpse);
|
||||||
SetHealth(1); // convert player body to ghost
|
SetHealth(1); // convert player body to ghost
|
||||||
SetMovement(MOVE_WATER_WALK);
|
|
||||||
SetWaterWalking(true);
|
SetWaterWalking(true);
|
||||||
|
|
||||||
if (!IsImmobilizedState())
|
if (!IsImmobilizedState())
|
||||||
@@ -4430,7 +4405,6 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
|||||||
SetDynamicFlag(UNIT_DYNFLAG_REFER_A_FRIEND);
|
SetDynamicFlag(UNIT_DYNFLAG_REFER_A_FRIEND);
|
||||||
|
|
||||||
setDeathState(DeathState::Alive);
|
setDeathState(DeathState::Alive);
|
||||||
SetMovement(MOVE_LAND_WALK);
|
|
||||||
SendMoveRoot(false);
|
SendMoveRoot(false);
|
||||||
SetWaterWalking(false);
|
SetWaterWalking(false);
|
||||||
m_deathTimer = 0;
|
m_deathTimer = 0;
|
||||||
@@ -9390,11 +9364,7 @@ void Player::Say(std::string_view text, Language language, WorldObject const* /*
|
|||||||
{
|
{
|
||||||
std::string _text(text);
|
std::string _text(text);
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_SAY, language, _text))
|
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_SAY, language, _text))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text);
|
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);
|
std::string _text(text);
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_YELL, language, _text))
|
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_YELL, language, _text))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text);
|
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);
|
std::string _text(text);
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text))
|
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
|
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);
|
std::string _text(text);
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_WHISPER, language, _text, target))
|
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_WHISPER, language, _text, target))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, language, this, this, _text);
|
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, language, this, this, _text);
|
||||||
@@ -11686,7 +11644,7 @@ void Player::SendInitialPacketsAfterAddToMap()
|
|||||||
GetSession()->IncrementOrderCounter();
|
GetSession()->IncrementOrderCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasAuraType(SPELL_AURA_WATER_WALK))
|
if (HasAuraType(SPELL_AURA_WATER_WALK) || HasAura(8326))
|
||||||
{
|
{
|
||||||
uint32 const counter = GetSession()->GetOrderCounter();
|
uint32 const counter = GetSession()->GetOrderCounter();
|
||||||
setCompoundState << uint8(2 + GetPackGUID().size() + 4);
|
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
|
if (!target || (!force && target->GetVisibleAuras()->empty())) // speedup things
|
||||||
return;
|
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);
|
WorldPacket data(SMSG_AURA_UPDATE_ALL);
|
||||||
data<< target->GetPackGUID();
|
data<< target->GetPackGUID();
|
||||||
|
|
||||||
|
|||||||
@@ -656,7 +656,7 @@ enum PlayerSlots
|
|||||||
|
|
||||||
#define INVENTORY_SLOT_BAG_0 255
|
#define INVENTORY_SLOT_BAG_0 255
|
||||||
|
|
||||||
enum EquipmentSlots : uint32 // 19 slots
|
enum EquipmentSlots : uint32 // 19 slots
|
||||||
{
|
{
|
||||||
EQUIPMENT_SLOT_START = 0,
|
EQUIPMENT_SLOT_START = 0,
|
||||||
EQUIPMENT_SLOT_HEAD = 0,
|
EQUIPMENT_SLOT_HEAD = 0,
|
||||||
@@ -827,6 +827,16 @@ enum EnviromentalDamage
|
|||||||
DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss
|
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
|
enum PlayedTimeIndex
|
||||||
{
|
{
|
||||||
PLAYED_TIME_TOTAL = 0,
|
PLAYED_TIME_TOTAL = 0,
|
||||||
|
|||||||
@@ -1463,6 +1463,9 @@ void Player::UpdatePvPState()
|
|||||||
|
|
||||||
if (pvpInfo.IsHostile) // in hostile area
|
if (pvpInfo.IsHostile) // in hostile area
|
||||||
{
|
{
|
||||||
|
if (IsInFlight()) // on taxi
|
||||||
|
return;
|
||||||
|
|
||||||
if (!IsPvP() || pvpInfo.EndTimer != 0)
|
if (!IsPvP() || pvpInfo.EndTimer != 0)
|
||||||
UpdatePvP(true, true);
|
UpdatePvP(true, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1864,7 +1864,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
|||||||
|
|
||||||
auto canTakeMeleeDamage = [&]()
|
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())
|
if (!canTakeMeleeDamage())
|
||||||
@@ -1956,10 +1956,11 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
|||||||
Probability = 0.65f * victim->GetLevel() + 0.5f;
|
Probability = 0.65f * victim->GetLevel() + 0.5f;
|
||||||
|
|
||||||
uint32 VictimDefense = victim->GetDefenseSkillValue();
|
uint32 VictimDefense = victim->GetDefenseSkillValue();
|
||||||
|
uint32 VictimAuraDefense = -victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE) * 25;
|
||||||
uint32 AttackerMeleeSkill = GetUnitMeleeSkill();
|
uint32 AttackerMeleeSkill = GetUnitMeleeSkill();
|
||||||
|
|
||||||
// xinef: fix daze mechanics
|
// xinef: fix daze mechanics
|
||||||
Probability -= ((float)VictimDefense - AttackerMeleeSkill) * 0.1428f;
|
Probability -= ((float)VictimDefense + (float)VictimAuraDefense - AttackerMeleeSkill) * 0.1428f;
|
||||||
|
|
||||||
if (Probability > 40.0f)
|
if (Probability > 40.0f)
|
||||||
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)
|
void Unit::SetStunned(bool apply)
|
||||||
{
|
{
|
||||||
if (HasUnitState(UNIT_STATE_IN_FLIGHT))
|
if (IsInFlight())
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
@@ -21520,18 +21519,3 @@ Player const* Unit::GetClientControlling() const
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::SetCannotReachTargetUnit(bool cannotReach, bool isChase)
|
|
||||||
{
|
|
||||||
if (cannotReach == m_cannotReachTarget)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_cannotReachTarget = cannotReach;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Unit::CanNotReachTarget() const
|
|
||||||
{
|
|
||||||
return m_cannotReachTarget;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2051,8 +2051,6 @@ public:
|
|||||||
// Debug
|
// Debug
|
||||||
void OutDebugInfo() const;
|
void OutDebugInfo() const;
|
||||||
std::string GetDebugInfo() const override;
|
std::string GetDebugInfo() const override;
|
||||||
void SetCannotReachTargetUnit(bool target, bool isChase);
|
|
||||||
[[nodiscard]] bool CanNotReachTarget() const;
|
|
||||||
|
|
||||||
bool m_cannotReachTarget;
|
bool m_cannotReachTarget;
|
||||||
|
|
||||||
|
|||||||
@@ -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_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_ANGLE = 0x00000400, // Lua_IsVehicleAimAngleAdjustable
|
||||||
VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800, // Lua_IsVehicleAimPowerAdjustable
|
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
|
enum VehicleSpells
|
||||||
|
|||||||
@@ -527,9 +527,11 @@ float GridTerrainData::getLiquidLevel(float x, float y) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get water state on map
|
// 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<uint8> ReqLiquidType) const
|
||||||
{
|
{
|
||||||
LiquidData liquidData;
|
LiquidData liquidData;
|
||||||
|
liquidData.Status = LIQUID_MAP_NO_WATER;
|
||||||
|
|
||||||
if (!_loadedLiquidData)
|
if (!_loadedLiquidData)
|
||||||
return liquidData;
|
return liquidData;
|
||||||
|
|
||||||
@@ -575,7 +577,7 @@ LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check req liquid type mask
|
// Check req liquid type mask
|
||||||
if (type != 0 && (!ReqLiquidType || (ReqLiquidType & type) != 0))
|
if (type != 0 && (!ReqLiquidType || (*ReqLiquidType & type) != 0))
|
||||||
{
|
{
|
||||||
// Check water level:
|
// Check water level:
|
||||||
// Check water height map
|
// Check water height map
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ struct LoadedHoleData
|
|||||||
HolesType holes;
|
HolesType holes;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LiquidStatus
|
enum LiquidStatus : uint32
|
||||||
{
|
{
|
||||||
LIQUID_MAP_NO_WATER = 0x00000000,
|
LIQUID_MAP_NO_WATER = 0x00000000,
|
||||||
LIQUID_MAP_ABOVE_WATER = 0x00000001,
|
LIQUID_MAP_ABOVE_WATER = 0x00000001,
|
||||||
@@ -249,7 +249,7 @@ public:
|
|||||||
inline float getHeight(float x, float y) const { return (this->*_gridGetHeight)(x, y); }
|
inline float getHeight(float x, float y) const { return (this->*_gridGetHeight)(x, y); }
|
||||||
float getMinHeight(float x, float y) const;
|
float getMinHeight(float x, float y) const;
|
||||||
float getLiquidLevel(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<uint8> ReqLiquidType) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ public:
|
|||||||
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag);
|
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag);
|
||||||
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag);
|
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag);
|
||||||
|
|
||||||
|
//mod_playerbots
|
||||||
ObjectGuid const GetTargetIcon(uint8 id) const { return m_targetIcons[id]; }
|
ObjectGuid const GetTargetIcon(uint8 id) const { return m_targetIcons[id]; }
|
||||||
|
|
||||||
Difficulty GetDifficulty(bool isRaid) const;
|
Difficulty GetDifficulty(bool isRaid) const;
|
||||||
|
|||||||
+215
-213
@@ -44,48 +44,48 @@ std::string _GetGuildEventString(GuildEvents event)
|
|||||||
{
|
{
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case GE_PROMOTION:
|
case GE_PROMOTION:
|
||||||
return "Member promotion";
|
return "Member promotion";
|
||||||
case GE_DEMOTION:
|
case GE_DEMOTION:
|
||||||
return "Member demotion";
|
return "Member demotion";
|
||||||
case GE_MOTD:
|
case GE_MOTD:
|
||||||
return "Guild MOTD";
|
return "Guild MOTD";
|
||||||
case GE_JOINED:
|
case GE_JOINED:
|
||||||
return "Member joined";
|
return "Member joined";
|
||||||
case GE_LEFT:
|
case GE_LEFT:
|
||||||
return "Member left";
|
return "Member left";
|
||||||
case GE_REMOVED:
|
case GE_REMOVED:
|
||||||
return "Member removed";
|
return "Member removed";
|
||||||
case GE_LEADER_IS:
|
case GE_LEADER_IS:
|
||||||
return "Leader is";
|
return "Leader is";
|
||||||
case GE_LEADER_CHANGED:
|
case GE_LEADER_CHANGED:
|
||||||
return "Leader changed";
|
return "Leader changed";
|
||||||
case GE_DISBANDED:
|
case GE_DISBANDED:
|
||||||
return "Guild disbanded";
|
return "Guild disbanded";
|
||||||
case GE_TABARDCHANGE:
|
case GE_TABARDCHANGE:
|
||||||
return "Tabard change";
|
return "Tabard change";
|
||||||
case GE_RANK_UPDATED:
|
case GE_RANK_UPDATED:
|
||||||
return "Rank updated";
|
return "Rank updated";
|
||||||
case GE_RANK_DELETED:
|
case GE_RANK_DELETED:
|
||||||
return "Rank deleted";
|
return "Rank deleted";
|
||||||
case GE_SIGNED_ON:
|
case GE_SIGNED_ON:
|
||||||
return "Member signed on";
|
return "Member signed on";
|
||||||
case GE_SIGNED_OFF:
|
case GE_SIGNED_OFF:
|
||||||
return "Member signed off";
|
return "Member signed off";
|
||||||
case GE_GUILDBANKBAGSLOTS_CHANGED:
|
case GE_GUILDBANKBAGSLOTS_CHANGED:
|
||||||
return "Bank bag slots changed";
|
return "Bank bag slots changed";
|
||||||
case GE_BANK_TAB_PURCHASED:
|
case GE_BANK_TAB_PURCHASED:
|
||||||
return "Bank tab purchased";
|
return "Bank tab purchased";
|
||||||
case GE_BANK_TAB_UPDATED:
|
case GE_BANK_TAB_UPDATED:
|
||||||
return "Bank tab updated";
|
return "Bank tab updated";
|
||||||
case GE_BANK_MONEY_SET:
|
case GE_BANK_MONEY_SET:
|
||||||
return "Bank money set";
|
return "Bank money set";
|
||||||
case GE_BANK_TAB_AND_MONEY_UPDATED:
|
case GE_BANK_TAB_AND_MONEY_UPDATED:
|
||||||
return "Bank and money updated";
|
return "Bank and money updated";
|
||||||
case GE_BANK_TEXT_CHANGED:
|
case GE_BANK_TEXT_CHANGED:
|
||||||
return "Bank tab text changed";
|
return "Bank tab text changed";
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return "<None>";
|
return "<None>";
|
||||||
}
|
}
|
||||||
@@ -94,20 +94,20 @@ inline uint32 _GetGuildBankTabPrice(uint8 tabId)
|
|||||||
{
|
{
|
||||||
switch (tabId)
|
switch (tabId)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_0);
|
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_0);
|
||||||
case 1:
|
case 1:
|
||||||
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_1);
|
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_1);
|
||||||
case 2:
|
case 2:
|
||||||
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_2);
|
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_2);
|
||||||
case 3:
|
case 3:
|
||||||
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_3);
|
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_3);
|
||||||
case 4:
|
case 4:
|
||||||
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_4);
|
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_4);
|
||||||
case 5:
|
case 5:
|
||||||
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_5);
|
return sWorld->getIntConfig(CONFIG_GUILD_BANK_TAB_COST_5);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +134,9 @@ void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode
|
|||||||
// LogHolder
|
// LogHolder
|
||||||
template <typename Entry>
|
template <typename Entry>
|
||||||
Guild::LogHolder<Entry>::LogHolder()
|
Guild::LogHolder<Entry>::LogHolder()
|
||||||
: m_maxRecords(sWorld->getIntConfig(std::is_same_v<Entry, BankEventLogEntry> ? 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<Entry, BankEventLogEntry> ? CONFIG_GUILD_BANK_EVENT_LOG_COUNT : CONFIG_GUILD_EVENT_LOG_COUNT)), m_nextGUID(uint32(GUILD_EVENT_LOG_GUID_UNDEFINED))
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Entry> template <typename... Ts>
|
template <typename Entry> template <typename... Ts>
|
||||||
void Guild::LogHolder<Entry>::LoadEvent(Ts&&... args)
|
void Guild::LogHolder<Entry>::LoadEvent(Ts&&... args)
|
||||||
@@ -173,7 +174,8 @@ inline uint32 Guild::LogHolder<Entry>::GetNextGUID()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Guild::LogEntry::LogEntry(uint32 guildId, ObjectGuid::LowType guid) :
|
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
|
// EventLogEntry
|
||||||
void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const
|
void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const
|
||||||
@@ -185,12 +187,12 @@ void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const
|
|||||||
|
|
||||||
uint8 index = 0;
|
uint8 index = 0;
|
||||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_EVENTLOG);
|
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, m_guid);
|
||||||
stmt->SetData (++index, uint8(m_eventType));
|
stmt->SetData(++index, uint8(m_eventType));
|
||||||
stmt->SetData(++index, m_playerGuid1.GetCounter());
|
stmt->SetData(++index, m_playerGuid1.GetCounter());
|
||||||
stmt->SetData(++index, m_playerGuid2.GetCounter());
|
stmt->SetData(++index, m_playerGuid2.GetCounter());
|
||||||
stmt->SetData (++index, m_newRank);
|
stmt->SetData(++index, m_newRank);
|
||||||
stmt->SetData(++index, m_timestamp);
|
stmt->SetData(++index, m_timestamp);
|
||||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||||
}
|
}
|
||||||
@@ -215,21 +217,21 @@ void Guild::BankEventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) cons
|
|||||||
uint8 index = 0;
|
uint8 index = 0;
|
||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_EVENTLOG);
|
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_guid);
|
||||||
stmt->SetData (++index, m_bankTabId);
|
stmt->SetData(++index, m_bankTabId);
|
||||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_EVENTLOG);
|
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_guid);
|
||||||
stmt->SetData (++index, m_bankTabId);
|
stmt->SetData(++index, m_bankTabId);
|
||||||
stmt->SetData (++index, uint8(m_eventType));
|
stmt->SetData(++index, uint8(m_eventType));
|
||||||
stmt->SetData(++index, m_playerGuid.GetCounter());
|
stmt->SetData(++index, m_playerGuid.GetCounter());
|
||||||
stmt->SetData(++index, m_itemOrMoney);
|
stmt->SetData(++index, m_itemOrMoney);
|
||||||
stmt->SetData(++index, m_itemStackCount);
|
stmt->SetData(++index, m_itemStackCount);
|
||||||
stmt->SetData (++index, m_destTabId);
|
stmt->SetData(++index, m_destTabId);
|
||||||
stmt->SetData(++index, m_timestamp);
|
stmt->SetData(++index, m_timestamp);
|
||||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||||
}
|
}
|
||||||
@@ -243,19 +245,19 @@ void Guild::BankEventLogEntry::WritePacket(WorldPackets::Guild::GuildBankLogQuer
|
|||||||
|
|
||||||
switch (m_eventType)
|
switch (m_eventType)
|
||||||
{
|
{
|
||||||
case GUILD_BANK_LOG_DEPOSIT_ITEM:
|
case GUILD_BANK_LOG_DEPOSIT_ITEM:
|
||||||
case GUILD_BANK_LOG_WITHDRAW_ITEM:
|
case GUILD_BANK_LOG_WITHDRAW_ITEM:
|
||||||
bankLogEntry.ItemID = int32(m_itemOrMoney);
|
bankLogEntry.ItemID = int32(m_itemOrMoney);
|
||||||
bankLogEntry.Count = int32(m_itemStackCount);
|
bankLogEntry.Count = int32(m_itemStackCount);
|
||||||
break;
|
break;
|
||||||
case GUILD_BANK_LOG_MOVE_ITEM:
|
case GUILD_BANK_LOG_MOVE_ITEM:
|
||||||
case GUILD_BANK_LOG_MOVE_ITEM2:
|
case GUILD_BANK_LOG_MOVE_ITEM2:
|
||||||
bankLogEntry.ItemID = int32(m_itemOrMoney);
|
bankLogEntry.ItemID = int32(m_itemOrMoney);
|
||||||
bankLogEntry.Count = int32(m_itemStackCount);
|
bankLogEntry.Count = int32(m_itemStackCount);
|
||||||
bankLogEntry.OtherTab = int8(m_destTabId);
|
bankLogEntry.OtherTab = int8(m_destTabId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bankLogEntry.Money = uint32(m_itemOrMoney);
|
bankLogEntry.Money = uint32(m_itemOrMoney);
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.Entry.push_back(bankLogEntry);
|
packet.Entry.push_back(bankLogEntry);
|
||||||
@@ -264,10 +266,10 @@ void Guild::BankEventLogEntry::WritePacket(WorldPackets::Guild::GuildBankLogQuer
|
|||||||
// RankInfo
|
// RankInfo
|
||||||
void Guild::RankInfo::LoadFromDB(Field* fields)
|
void Guild::RankInfo::LoadFromDB(Field* fields)
|
||||||
{
|
{
|
||||||
m_rankId = fields[1].Get<uint8>();
|
m_rankId = fields[1].Get<uint8>();
|
||||||
m_name = fields[2].Get<std::string>();
|
m_name = fields[2].Get<std::string>();
|
||||||
m_rights = fields[3].Get<uint32>();
|
m_rights = fields[3].Get<uint32>();
|
||||||
m_bankMoneyPerDay = fields[4].Get<uint32>();
|
m_bankMoneyPerDay = fields[4].Get<uint32>();
|
||||||
if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights
|
if (m_rankId == GR_GUILDMASTER) // Prevent loss of leader rights
|
||||||
m_rights |= GR_RIGHT_ALL;
|
m_rights |= GR_RIGHT_ALL;
|
||||||
}
|
}
|
||||||
@@ -276,7 +278,7 @@ void Guild::RankInfo::SaveToDB(CharacterDatabaseTransaction trans) const
|
|||||||
{
|
{
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_RANK);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_RANK);
|
||||||
stmt->SetData(0, m_guildId);
|
stmt->SetData(0, m_guildId);
|
||||||
stmt->SetData (1, m_rankId);
|
stmt->SetData(1, m_rankId);
|
||||||
stmt->SetData(2, m_name);
|
stmt->SetData(2, m_name);
|
||||||
stmt->SetData(3, m_rights);
|
stmt->SetData(3, m_rights);
|
||||||
stmt->SetData(4, m_bankMoneyPerDay);
|
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);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_NAME);
|
||||||
stmt->SetData(0, m_name);
|
stmt->SetData(0, m_name);
|
||||||
stmt->SetData (1, m_rankId);
|
stmt->SetData(1, m_rankId);
|
||||||
stmt->SetData(2, m_guildId);
|
stmt->SetData(2, m_guildId);
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
}
|
}
|
||||||
@@ -334,7 +336,7 @@ void Guild::RankInfo::SetRights(uint32 rights)
|
|||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_RIGHTS);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_RIGHTS);
|
||||||
stmt->SetData(0, m_rights);
|
stmt->SetData(0, m_rights);
|
||||||
stmt->SetData (1, m_rankId);
|
stmt->SetData(1, m_rankId);
|
||||||
stmt->SetData(2, m_guildId);
|
stmt->SetData(2, m_guildId);
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
}
|
}
|
||||||
@@ -351,7 +353,7 @@ void Guild::RankInfo::SetBankMoneyPerDay(uint32 money)
|
|||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY);
|
||||||
stmt->SetData(0, money);
|
stmt->SetData(0, money);
|
||||||
stmt->SetData (1, m_rankId);
|
stmt->SetData(1, m_rankId);
|
||||||
stmt->SetData(2, m_guildId);
|
stmt->SetData(2, m_guildId);
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
}
|
}
|
||||||
@@ -368,9 +370,9 @@ void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAnd
|
|||||||
{
|
{
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT);
|
||||||
stmt->SetData(0, m_guildId);
|
stmt->SetData(0, m_guildId);
|
||||||
stmt->SetData (1, guildBR.GetTabId());
|
stmt->SetData(1, guildBR.GetTabId());
|
||||||
stmt->SetData (2, m_rankId);
|
stmt->SetData(2, m_rankId);
|
||||||
stmt->SetData (3, guildBR.GetRights());
|
stmt->SetData(3, guildBR.GetRights());
|
||||||
stmt->SetData(4, guildBR.GetSlots());
|
stmt->SetData(4, guildBR.GetSlots());
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
}
|
}
|
||||||
@@ -409,8 +411,8 @@ bool Guild::BankTab::LoadItemFromDB(Field* fields)
|
|||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM);
|
||||||
stmt->SetData(0, m_guildId);
|
stmt->SetData(0, m_guildId);
|
||||||
stmt->SetData (1, m_tabId);
|
stmt->SetData(1, m_tabId);
|
||||||
stmt->SetData (2, slotId);
|
stmt->SetData(2, slotId);
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
|
|
||||||
delete pItem;
|
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(0, m_name);
|
||||||
stmt->SetData(1, m_icon);
|
stmt->SetData(1, m_icon);
|
||||||
stmt->SetData(2, m_guildId);
|
stmt->SetData(2, m_guildId);
|
||||||
stmt->SetData (3, m_tabId);
|
stmt->SetData(3, m_tabId);
|
||||||
CharacterDatabase.Execute(stmt);
|
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);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_BANK_TAB_TEXT);
|
||||||
stmt->SetData(0, m_text);
|
stmt->SetData(0, m_text);
|
||||||
stmt->SetData(1, m_guildId);
|
stmt->SetData(1, m_guildId);
|
||||||
stmt->SetData (2, m_tabId);
|
stmt->SetData(2, m_tabId);
|
||||||
CharacterDatabase.Execute(stmt);
|
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);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_ITEM);
|
||||||
stmt->SetData(0, m_guildId);
|
stmt->SetData(0, m_guildId);
|
||||||
stmt->SetData (1, m_tabId);
|
stmt->SetData(1, m_tabId);
|
||||||
stmt->SetData (2, slotId);
|
stmt->SetData(2, slotId);
|
||||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||||
|
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_ITEM);
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_ITEM);
|
||||||
stmt->SetData(0, m_guildId);
|
stmt->SetData(0, m_guildId);
|
||||||
stmt->SetData (1, m_tabId);
|
stmt->SetData(1, m_tabId);
|
||||||
stmt->SetData (2, slotId);
|
stmt->SetData(2, slotId);
|
||||||
stmt->SetData(3, item->GetGUID().GetCounter());
|
stmt->SetData(3, item->GetGUID().GetCounter());
|
||||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||||
|
|
||||||
@@ -508,7 +510,7 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const
|
|||||||
if (session)
|
if (session)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [{}]: Tabid: {}, Text: {}"
|
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());
|
session->SendPacket(textQuery.Write());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -521,21 +523,21 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const
|
|||||||
// Member
|
// Member
|
||||||
void Guild::Member::SetStats(Player* player)
|
void Guild::Member::SetStats(Player* player)
|
||||||
{
|
{
|
||||||
m_name = player->GetName();
|
m_name = player->GetName();
|
||||||
m_level = player->GetLevel();
|
m_level = player->GetLevel();
|
||||||
m_class = player->getClass();
|
m_class = player->getClass();
|
||||||
m_gender = player->getGender();
|
m_gender = player->getGender();
|
||||||
m_zoneId = player->GetZoneId();
|
m_zoneId = player->GetZoneId();
|
||||||
m_accountId = player->GetSession()->GetAccountId();
|
m_accountId = player->GetSession()->GetAccountId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guild::Member::SetStats(std::string_view name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId)
|
void Guild::Member::SetStats(std::string_view name, uint8 level, uint8 _class, uint8 gender, uint32 zoneId, uint32 accountId)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
m_level = level;
|
m_level = level;
|
||||||
m_class = _class;
|
m_class = _class;
|
||||||
m_gender = gender;
|
m_gender = gender;
|
||||||
m_zoneId = zoneId;
|
m_zoneId = zoneId;
|
||||||
m_accountId = accountId;
|
m_accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +576,7 @@ void Guild::Member::ChangeRank(uint8 newRank)
|
|||||||
player->SetRank(newRank);
|
player->SetRank(newRank);
|
||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_RANK);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_RANK);
|
||||||
stmt->SetData (0, newRank);
|
stmt->SetData(0, newRank);
|
||||||
stmt->SetData(1, m_guid.GetCounter());
|
stmt->SetData(1, m_guid.GetCounter());
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
}
|
}
|
||||||
@@ -589,7 +591,7 @@ void Guild::Member::SaveToDB(CharacterDatabaseTransaction trans) const
|
|||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER);
|
||||||
stmt->SetData(0, m_guildId);
|
stmt->SetData(0, m_guildId);
|
||||||
stmt->SetData(1, m_guid.GetCounter());
|
stmt->SetData(1, m_guid.GetCounter());
|
||||||
stmt->SetData (2, m_rankId);
|
stmt->SetData(2, m_rankId);
|
||||||
stmt->SetData(3, m_publicNote);
|
stmt->SetData(3, m_publicNote);
|
||||||
stmt->SetData(4, m_officerNote);
|
stmt->SetData(4, m_officerNote);
|
||||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
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.
|
// In this case member has to be removed from guild.
|
||||||
bool Guild::Member::LoadFromDB(Field* fields)
|
bool Guild::Member::LoadFromDB(Field* fields)
|
||||||
{
|
{
|
||||||
m_publicNote = fields[3].Get<std::string>();
|
m_publicNote = fields[3].Get<std::string>();
|
||||||
m_officerNote = fields[4].Get<std::string>();
|
m_officerNote = fields[4].Get<std::string>();
|
||||||
|
|
||||||
for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS; ++i)
|
for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS; ++i)
|
||||||
m_bankWithdraw[i] = fields[5 + i].Get<uint32>();
|
m_bankWithdraw[i] = fields[5 + i].Get<uint32>();
|
||||||
|
|
||||||
SetStats(fields[12].Get<std::string>(),
|
SetStats(fields[12].Get<std::string>(),
|
||||||
fields[13].Get<uint8>(), // characters.level
|
fields[13].Get<uint8>(), // characters.level
|
||||||
fields[14].Get<uint8>(), // characters.class
|
fields[14].Get<uint8>(), // characters.class
|
||||||
fields[15].Get<uint8>(), // characters.gender
|
fields[15].Get<uint8>(), // characters.gender
|
||||||
fields[16].Get<uint16>(), // characters.zone
|
fields[16].Get<uint16>(), // characters.zone
|
||||||
fields[17].Get<uint32>()); // characters.account
|
fields[17].Get<uint32>()); // characters.account
|
||||||
m_logoutTime = fields[18].Get<uint32>(); // characters.logout_time
|
m_logoutTime = fields[18].Get<uint32>(); // characters.logout_time
|
||||||
|
|
||||||
if (!CheckStats())
|
if (!CheckStats())
|
||||||
@@ -691,11 +693,11 @@ void EmblemInfo::ReadPacket(WorldPackets::Guild::SaveGuildEmblem& packet)
|
|||||||
|
|
||||||
void EmblemInfo::LoadFromDB(Field* fields)
|
void EmblemInfo::LoadFromDB(Field* fields)
|
||||||
{
|
{
|
||||||
m_style = fields[3].Get<uint8>();
|
m_style = fields[3].Get<uint8>();
|
||||||
m_color = fields[4].Get<uint8>();
|
m_color = fields[4].Get<uint8>();
|
||||||
m_borderStyle = fields[5].Get<uint8>();
|
m_borderStyle = fields[5].Get<uint8>();
|
||||||
m_borderColor = fields[6].Get<uint8>();
|
m_borderColor = fields[6].Get<uint8>();
|
||||||
m_backgroundColor = fields[7].Get<uint8>();
|
m_backgroundColor = fields[7].Get<uint8>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmblemInfo::SaveToDB(uint32 guildId) const
|
void EmblemInfo::SaveToDB(uint32 guildId) const
|
||||||
@@ -747,8 +749,8 @@ void Guild::MoveItemData::LogAction(MoveItemData* pFrom) const
|
|||||||
ASSERT(pFrom->GetItem());
|
ASSERT(pFrom->GetItem());
|
||||||
|
|
||||||
sScriptMgr->OnGuildItemMove(m_pGuild, m_pPlayer, pFrom->GetItem(),
|
sScriptMgr->OnGuildItemMove(m_pGuild, m_pPlayer, pFrom->GetItem(),
|
||||||
pFrom->IsBank(), pFrom->GetContainer(), pFrom->GetSlotId(),
|
pFrom->IsBank(), pFrom->GetContainer(), pFrom->GetSlotId(),
|
||||||
IsBank(), GetContainer(), GetSlotId());
|
IsBank(), GetContainer(), GetSlotId());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Guild::MoveItemData::CopySlots(SlotIds& ids) const
|
inline void Guild::MoveItemData::CopySlots(SlotIds& ids) const
|
||||||
@@ -808,7 +810,7 @@ void Guild::PlayerMoveItemData::LogBankEvent(CharacterDatabaseTransaction trans,
|
|||||||
ASSERT(pFrom);
|
ASSERT(pFrom);
|
||||||
// Bank -> Char
|
// Bank -> Char
|
||||||
m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUID(),
|
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)
|
inline InventoryResult Guild::PlayerMoveItemData::CanStore(Item* pItem, bool swap)
|
||||||
@@ -881,7 +883,7 @@ Item* Guild::BankMoveItemData::StoreItem(CharacterDatabaseTransaction trans, Ite
|
|||||||
++itr;
|
++itr;
|
||||||
|
|
||||||
LOG_DEBUG("guild", "GUILD STORAGE: StoreItem tab = {}, slot = {}, item = {}, count = {}",
|
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());
|
pLastItem = _StoreItem(trans, pTab, pItem, pos, itr != m_vec.end());
|
||||||
}
|
}
|
||||||
return pLastItem;
|
return pLastItem;
|
||||||
@@ -893,11 +895,11 @@ void Guild::BankMoveItemData::LogBankEvent(CharacterDatabaseTransaction trans, M
|
|||||||
if (pFrom->IsBank())
|
if (pFrom->IsBank())
|
||||||
// Bank -> Bank
|
// Bank -> Bank
|
||||||
m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUID(),
|
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
|
else
|
||||||
// Char -> Bank
|
// Char -> Bank
|
||||||
m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, m_container, m_pPlayer->GetGUID(),
|
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
|
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)
|
InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("guild", "GUILD STORAGE: CanStore() tab = {}, slot = {}, item = {}, count = {}",
|
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();
|
uint32 count = pItem->GetCount();
|
||||||
// Soulbound items cannot be moved
|
// Soulbound items cannot be moved
|
||||||
if (pItem->IsSoulBound())
|
if (pItem->IsSoulBound())
|
||||||
@@ -1031,7 +1033,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Guild
|
// Guild
|
||||||
Guild::Guild():
|
Guild::Guild() :
|
||||||
m_id(0),
|
m_id(0),
|
||||||
m_createdDate(0),
|
m_createdDate(0),
|
||||||
m_accountsNumber(0),
|
m_accountsNumber(0),
|
||||||
@@ -1065,7 +1067,7 @@ bool Guild::Create(Player* pLeader, std::string_view name)
|
|||||||
m_createdDate = GameTime::GetGameTime().count();
|
m_createdDate = GameTime::GetGameTime().count();
|
||||||
|
|
||||||
LOG_DEBUG("guild", "GUILD: creating guild [{}] for leader {} ({})",
|
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();
|
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||||
|
|
||||||
@@ -1075,7 +1077,7 @@ bool Guild::Create(Player* pLeader, std::string_view name)
|
|||||||
|
|
||||||
uint8 index = 0;
|
uint8 index = 0;
|
||||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD);
|
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_name);
|
||||||
stmt->SetData(++index, m_leaderGuid.GetCounter());
|
stmt->SetData(++index, m_leaderGuid.GetCounter());
|
||||||
stmt->SetData(++index, m_info);
|
stmt->SetData(++index, m_info);
|
||||||
@@ -1161,15 +1163,15 @@ void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value)
|
|||||||
{
|
{
|
||||||
switch (dataid)
|
switch (dataid)
|
||||||
{
|
{
|
||||||
case GUILD_MEMBER_DATA_ZONEID:
|
case GUILD_MEMBER_DATA_ZONEID:
|
||||||
member->SetZoneID(value);
|
member->SetZoneID(value);
|
||||||
break;
|
break;
|
||||||
case GUILD_MEMBER_DATA_LEVEL:
|
case GUILD_MEMBER_DATA_LEVEL:
|
||||||
member->SetLevel(value);
|
member->SetLevel(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("guild", "Guild::UpdateMemberData: Called with incorrect DATAID {} (value {})", dataid, value);
|
LOG_ERROR("guild", "Guild::UpdateMemberData: Called with incorrect DATAID {} (value {})", dataid, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//HandleRoster();
|
//HandleRoster();
|
||||||
}
|
}
|
||||||
@@ -1207,7 +1209,7 @@ void Guild::HandleRoster(WorldSession* session)
|
|||||||
roster.RankData.reserve(m_ranks.size());
|
roster.RankData.reserve(m_ranks.size());
|
||||||
for (RankInfo const& rank : m_ranks)
|
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.Flags = rank.GetRights();
|
||||||
rankData.WithdrawGoldLimit = rank.GetBankMoneyPerDay();
|
rankData.WithdrawGoldLimit = rank.GetBankMoneyPerDay();
|
||||||
@@ -1362,7 +1364,7 @@ void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string
|
|||||||
if (!tab)
|
if (!tab)
|
||||||
{
|
{
|
||||||
LOG_ERROR("guild", "Guild::HandleSetBankTabInfo: Player {} trying to change bank tab info from unexisting tab {}.",
|
LOG_ERROR("guild", "Guild::HandleSetBankTabInfo: Player {} trying to change bank tab info from unexisting tab {}.",
|
||||||
session->GetPlayerInfo(), tabId);
|
session->GetPlayerInfo(), tabId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1931,14 +1933,14 @@ void Guild::SendLoginInfo(WorldSession* session)
|
|||||||
// Loading methods
|
// Loading methods
|
||||||
bool Guild::LoadFromDB(Field* fields)
|
bool Guild::LoadFromDB(Field* fields)
|
||||||
{
|
{
|
||||||
m_id = fields[0].Get<uint32>();
|
m_id = fields[0].Get<uint32>();
|
||||||
m_name = fields[1].Get<std::string>();
|
m_name = fields[1].Get<std::string>();
|
||||||
m_leaderGuid = ObjectGuid::Create<HighGuid::Player>(fields[2].Get<uint32>());
|
m_leaderGuid = ObjectGuid::Create<HighGuid::Player>(fields[2].Get<uint32>());
|
||||||
m_emblemInfo.LoadFromDB(fields);
|
m_emblemInfo.LoadFromDB(fields);
|
||||||
m_info = fields[8].Get<std::string>();
|
m_info = fields[8].Get<std::string>();
|
||||||
m_motd = fields[9].Get<std::string>();
|
m_motd = fields[9].Get<std::string>();
|
||||||
m_createdDate = time_t(fields[10].Get<uint32>());
|
m_createdDate = time_t(fields[10].Get<uint32>());
|
||||||
m_bankMoney = fields[11].Get<uint64>();
|
m_bankMoney = fields[11].Get<uint64>();
|
||||||
|
|
||||||
uint8 purchasedTabs = uint8(fields[12].Get<uint64>());
|
uint8 purchasedTabs = uint8(fields[12].Get<uint64>());
|
||||||
if (purchasedTabs > GUILD_BANK_MAX_TABS)
|
if (purchasedTabs > GUILD_BANK_MAX_TABS)
|
||||||
@@ -1997,13 +1999,13 @@ bool Guild::LoadEventLogFromDB(Field* fields)
|
|||||||
if (m_eventLog.CanInsert())
|
if (m_eventLog.CanInsert())
|
||||||
{
|
{
|
||||||
m_eventLog.LoadEvent(
|
m_eventLog.LoadEvent(
|
||||||
m_id, // guild id
|
m_id, // guild id
|
||||||
fields[1].Get<uint32>(), // guid
|
fields[1].Get<uint32>(), // guid
|
||||||
time_t(fields[6].Get<uint32>()), // timestamp
|
time_t(fields[6].Get<uint32>()), // timestamp
|
||||||
GuildEventLogTypes(fields[2].Get<uint8>()), // event type
|
GuildEventLogTypes(fields[2].Get<uint8>()), // event type
|
||||||
ObjectGuid::Create<HighGuid::Player>(fields[3].Get<uint32>()), // player guid 1
|
ObjectGuid::Create<HighGuid::Player>(fields[3].Get<uint32>()), // player guid 1
|
||||||
ObjectGuid::Create<HighGuid::Player>(fields[4].Get<uint32>()), // player guid 2
|
ObjectGuid::Create<HighGuid::Player>(fields[4].Get<uint32>()), // player guid 2
|
||||||
fields[5].Get<uint8>()); // rank
|
fields[5].Get<uint8>()); // rank
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -2035,15 +2037,15 @@ bool Guild::LoadBankEventLogFromDB(Field* fields)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bankLog.LoadEvent(
|
bankLog.LoadEvent(
|
||||||
m_id, // guild id
|
m_id, // guild id
|
||||||
guid, // guid
|
guid, // guid
|
||||||
time_t(fields[8].Get<uint32>()), // timestamp
|
time_t(fields[8].Get<uint32>()), // timestamp
|
||||||
dbTabId, // tab id
|
dbTabId, // tab id
|
||||||
eventType, // event type
|
eventType, // event type
|
||||||
ObjectGuid::Create<HighGuid::Player>(fields[4].Get<uint32>()), // player guid
|
ObjectGuid::Create<HighGuid::Player>(fields[4].Get<uint32>()), // player guid
|
||||||
fields[5].Get<uint32>(), // item or money
|
fields[5].Get<uint32>(), // item or money
|
||||||
fields[6].Get<uint16>(), // itam stack count
|
fields[6].Get<uint16>(), // itam stack count
|
||||||
fields[7].Get<uint8>()); // dest tab id
|
fields[7].Get<uint8>()); // dest tab id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -2064,7 +2066,7 @@ bool Guild::LoadBankItemFromDB(Field* fields)
|
|||||||
if (tabId >= _GetPurchasedTabsSize())
|
if (tabId >= _GetPurchasedTabsSize())
|
||||||
{
|
{
|
||||||
LOG_ERROR("guild", "Invalid tab for item (GUID: {}, id: #{}) in guild bank, skipped.",
|
LOG_ERROR("guild", "Invalid tab for item (GUID: {}, id: #{}) in guild bank, skipped.",
|
||||||
fields[14].Get<uint32>(), fields[15].Get<uint32>());
|
fields[14].Get<uint32>(), fields[15].Get<uint32>());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return m_bankTabs[tabId].LoadItemFromDB(fields);
|
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)
|
void Guild::SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
|
||||||
{
|
{
|
||||||
if (tabId >= _GetPurchasedTabsSize() || slotId >= GUILD_BANK_MAX_SLOTS ||
|
if (tabId >= _GetPurchasedTabsSize() || slotId >= GUILD_BANK_MAX_SLOTS ||
|
||||||
destTabId >= _GetPurchasedTabsSize() || destSlotId >= GUILD_BANK_MAX_SLOTS)
|
destTabId >= _GetPurchasedTabsSize() || destSlotId >= GUILD_BANK_MAX_SLOTS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (tabId == destTabId && slotId == destSlotId)
|
if (tabId == destTabId && slotId == destSlotId)
|
||||||
@@ -2427,12 +2429,12 @@ void Guild::_CreateNewBankTab()
|
|||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB);
|
||||||
stmt->SetData(0, m_id);
|
stmt->SetData(0, m_id);
|
||||||
stmt->SetData (1, tabId);
|
stmt->SetData(1, tabId);
|
||||||
trans->Append(stmt);
|
trans->Append(stmt);
|
||||||
|
|
||||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_TAB);
|
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_TAB);
|
||||||
stmt->SetData(0, m_id);
|
stmt->SetData(0, m_id);
|
||||||
stmt->SetData (1, tabId);
|
stmt->SetData(1, tabId);
|
||||||
trans->Append(stmt);
|
trans->Append(stmt);
|
||||||
|
|
||||||
++tabId;
|
++tabId;
|
||||||
@@ -2452,10 +2454,10 @@ void Guild::_CreateDefaultGuildRanks(LocaleConstant loc)
|
|||||||
stmt->SetData(0, m_id);
|
stmt->SetData(0, m_id);
|
||||||
CharacterDatabase.Execute(stmt);
|
CharacterDatabase.Execute(stmt);
|
||||||
|
|
||||||
_CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_MASTER, loc), GR_RIGHT_ALL);
|
_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_OFFICER, loc), GR_RIGHT_ALL);
|
||||||
_CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_VETERAN, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
_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_MEMBER, loc), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK);
|
||||||
_CreateRank(sObjectMgr->GetAcoreString(LANG_GUILD_INITIATE, 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();
|
uint8 rankId = member->GetRankId();
|
||||||
if (rankId != GR_GUILDMASTER
|
if (rankId != GR_GUILDMASTER
|
||||||
&& member->GetBankWithdrawValue(tabId) < _GetRankBankTabSlotsPerDay(rankId, tabId))
|
&& member->GetBankWithdrawValue(tabId) < _GetRankBankTabSlotsPerDay(rankId, tabId))
|
||||||
member->UpdateBankWithdrawValue(trans, tabId, 1);
|
member->UpdateBankWithdrawValue(trans, tabId, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2850,7 +2852,7 @@ void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid,
|
void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid,
|
||||||
Optional<std::string_view> param1 /*= {}*/, Optional<std::string_view> param2 /*= {}*/, Optional<std::string_view> param3 /*= {}*/) const
|
Optional<std::string_view> param1 /*= {}*/, Optional<std::string_view> param2 /*= {}*/, Optional<std::string_view> param3 /*= {}*/) const
|
||||||
{
|
{
|
||||||
WorldPackets::Guild::GuildEvent event;
|
WorldPackets::Guild::GuildEvent event;
|
||||||
event.Type = guildEvent;
|
event.Type = guildEvent;
|
||||||
@@ -2873,7 +2875,7 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid,
|
|||||||
LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: {}", guildEvent);
|
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))
|
if (!sScriptMgr->CanGuildSendBankList(this, session, tabId, sendAllSlots))
|
||||||
return;
|
return;
|
||||||
@@ -2899,47 +2901,47 @@ void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*=
|
|||||||
if (BankTab const* tab = GetBankTab(tabId))
|
if (BankTab const* tab = GetBankTab(tabId))
|
||||||
{
|
{
|
||||||
auto fillItems = [&](auto begin, auto end, bool skipEmpty)
|
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;
|
if (Item* tabItem = tab->GetItem(*itr))
|
||||||
|
|
||||||
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 (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;
|
if (uint32 enchId = tabItem->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + socketSlot)))
|
||||||
gem.SocketIndex = socketSlot;
|
{
|
||||||
gem.SocketEnchantID = int32(enchId);
|
WorldPackets::Guild::GuildBankSocketEnchant gem;
|
||||||
itemInfo.SocketEnchant.push_back(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)
|
if (sendAllSlots)
|
||||||
fillItems(boost::make_counting_iterator(uint8(0)), boost::make_counting_iterator(uint8(GUILD_BANK_MAX_SLOTS)), true);
|
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());
|
session->SendPacket(packet.Write());
|
||||||
LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [{}]: TabId: {}, FullSlots: {}, slots: {}",
|
LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [{}]: TabId: {}, FullSlots: {}, slots: {}",
|
||||||
session->GetPlayerInfo(), tabId, sendAllSlots, packet.WithdrawalsRemaining);
|
session->GetPlayerInfo(), tabId, sendAllSlots, packet.WithdrawalsRemaining);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2974,7 +2976,7 @@ void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*=
|
|||||||
packet.SetWithdrawalsRemaining(_GetMemberRemainingSlots(member, tabId));
|
packet.SetWithdrawalsRemaining(_GetMemberRemainingSlots(member, tabId));
|
||||||
player->SendDirectMessage(packet.GetRawPacket());
|
player->SendDirectMessage(packet.GetRawPacket());
|
||||||
LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [{}]: TabId: {}, FullSlots: {}, slots: {}"
|
LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [{}]: TabId: {}, FullSlots: {}, slots: {}"
|
||||||
, player->GetName(), tabId, sendAllSlots, packet.WithdrawalsRemaining);
|
, player->GetName(), tabId, sendAllSlots, packet.WithdrawalsRemaining);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+164
-155
@@ -39,16 +39,16 @@ namespace WorldPackets
|
|||||||
|
|
||||||
enum GuildMisc
|
enum GuildMisc
|
||||||
{
|
{
|
||||||
GUILD_BANK_MAX_TABS = 6, // send by client for money log also
|
GUILD_BANK_MAX_TABS = 6, // send by client for money log also
|
||||||
GUILD_BANK_MAX_SLOTS = 98,
|
GUILD_BANK_MAX_SLOTS = 98,
|
||||||
GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB
|
GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB
|
||||||
GUILD_RANKS_MIN_COUNT = 5,
|
GUILD_RANKS_MIN_COUNT = 5,
|
||||||
GUILD_RANKS_MAX_COUNT = 10,
|
GUILD_RANKS_MAX_COUNT = 10,
|
||||||
GUILD_RANK_NONE = 0xFF,
|
GUILD_RANK_NONE = 0xFF,
|
||||||
GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF,
|
GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF,
|
||||||
GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF,
|
GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF,
|
||||||
GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF,
|
GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF,
|
||||||
TAB_UNDEFINED = 0xFF,
|
TAB_UNDEFINED = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint64 GUILD_BANK_MONEY_LIMIT = UI64LIT(0x7FFFFFFFFFFFF);
|
constexpr uint64 GUILD_BANK_MONEY_LIMIT = UI64LIT(0x7FFFFFFFFFFFF);
|
||||||
@@ -62,176 +62,176 @@ enum GuildMemberData
|
|||||||
enum GuildDefaultRanks
|
enum GuildDefaultRanks
|
||||||
{
|
{
|
||||||
// These ranks can be modified, but they cannot be deleted
|
// These ranks can be modified, but they cannot be deleted
|
||||||
GR_GUILDMASTER = 0,
|
GR_GUILDMASTER = 0,
|
||||||
GR_OFFICER = 1,
|
GR_OFFICER = 1,
|
||||||
GR_VETERAN = 2,
|
GR_VETERAN = 2,
|
||||||
GR_MEMBER = 3,
|
GR_MEMBER = 3,
|
||||||
GR_INITIATE = 4
|
GR_INITIATE = 4
|
||||||
// When promoting member server does: rank--
|
// When promoting member server does: rank--
|
||||||
// When demoting member server does: rank++
|
// When demoting member server does: rank++
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildRankRights
|
enum GuildRankRights
|
||||||
{
|
{
|
||||||
GR_RIGHT_EMPTY = 0x00000040,
|
GR_RIGHT_EMPTY = 0x00000040,
|
||||||
GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001,
|
GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001,
|
||||||
GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002,
|
GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002,
|
||||||
GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004,
|
GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004,
|
||||||
GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008,
|
GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008,
|
||||||
GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010,
|
GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010,
|
||||||
GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020,
|
GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020,
|
||||||
GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080,
|
GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080,
|
||||||
GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100,
|
GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100,
|
||||||
GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000,
|
GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000,
|
||||||
GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000,
|
GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000,
|
||||||
GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000,
|
GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000,
|
||||||
GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000,
|
GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000,
|
||||||
GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000,
|
GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000,
|
||||||
GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity
|
GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity
|
||||||
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
|
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
|
||||||
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
|
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
|
||||||
GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
|
GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
|
||||||
GR_RIGHT_ALL = 0x001DF1FF
|
GR_RIGHT_ALL = 0x001DF1FF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildCommandType
|
enum GuildCommandType
|
||||||
{
|
{
|
||||||
GUILD_COMMAND_CREATE = 0,
|
GUILD_COMMAND_CREATE = 0,
|
||||||
GUILD_COMMAND_INVITE = 1,
|
GUILD_COMMAND_INVITE = 1,
|
||||||
GUILD_COMMAND_QUIT = 3,
|
GUILD_COMMAND_QUIT = 3,
|
||||||
GUILD_COMMAND_ROSTER = 5,
|
GUILD_COMMAND_ROSTER = 5,
|
||||||
GUILD_COMMAND_PROMOTE = 6,
|
GUILD_COMMAND_PROMOTE = 6,
|
||||||
GUILD_COMMAND_DEMOTE = 7,
|
GUILD_COMMAND_DEMOTE = 7,
|
||||||
GUILD_COMMAND_REMOVE = 8,
|
GUILD_COMMAND_REMOVE = 8,
|
||||||
GUILD_COMMAND_CHANGE_LEADER = 10,
|
GUILD_COMMAND_CHANGE_LEADER = 10,
|
||||||
GUILD_COMMAND_EDIT_MOTD = 11,
|
GUILD_COMMAND_EDIT_MOTD = 11,
|
||||||
GUILD_COMMAND_GUILD_CHAT = 13,
|
GUILD_COMMAND_GUILD_CHAT = 13,
|
||||||
GUILD_COMMAND_FOUNDER = 14,
|
GUILD_COMMAND_FOUNDER = 14,
|
||||||
GUILD_COMMAND_CHANGE_RANK = 16,
|
GUILD_COMMAND_CHANGE_RANK = 16,
|
||||||
GUILD_COMMAND_PUBLIC_NOTE = 19,
|
GUILD_COMMAND_PUBLIC_NOTE = 19,
|
||||||
GUILD_COMMAND_VIEW_TAB = 21,
|
GUILD_COMMAND_VIEW_TAB = 21,
|
||||||
GUILD_COMMAND_MOVE_ITEM = 22,
|
GUILD_COMMAND_MOVE_ITEM = 22,
|
||||||
GUILD_COMMAND_REPAIR = 25,
|
GUILD_COMMAND_REPAIR = 25,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildCommandError
|
enum GuildCommandError
|
||||||
{
|
{
|
||||||
ERR_GUILD_COMMAND_SUCCESS = 0,
|
ERR_GUILD_COMMAND_SUCCESS = 0,
|
||||||
ERR_GUILD_INTERNAL = 1,
|
ERR_GUILD_INTERNAL = 1,
|
||||||
ERR_ALREADY_IN_GUILD = 2,
|
ERR_ALREADY_IN_GUILD = 2,
|
||||||
ERR_ALREADY_IN_GUILD_S = 3,
|
ERR_ALREADY_IN_GUILD_S = 3,
|
||||||
ERR_INVITED_TO_GUILD = 4,
|
ERR_INVITED_TO_GUILD = 4,
|
||||||
ERR_ALREADY_INVITED_TO_GUILD_S = 5,
|
ERR_ALREADY_INVITED_TO_GUILD_S = 5,
|
||||||
ERR_GUILD_NAME_INVALID = 6,
|
ERR_GUILD_NAME_INVALID = 6,
|
||||||
ERR_GUILD_NAME_EXISTS_S = 7,
|
ERR_GUILD_NAME_EXISTS_S = 7,
|
||||||
ERR_GUILD_LEADER_LEAVE = 8,
|
ERR_GUILD_LEADER_LEAVE = 8,
|
||||||
ERR_GUILD_PERMISSIONS = 8,
|
ERR_GUILD_PERMISSIONS = 8,
|
||||||
ERR_GUILD_PLAYER_NOT_IN_GUILD = 9,
|
ERR_GUILD_PLAYER_NOT_IN_GUILD = 9,
|
||||||
ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 10,
|
ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 10,
|
||||||
ERR_GUILD_PLAYER_NOT_FOUND_S = 11,
|
ERR_GUILD_PLAYER_NOT_FOUND_S = 11,
|
||||||
ERR_GUILD_NOT_ALLIED = 12,
|
ERR_GUILD_NOT_ALLIED = 12,
|
||||||
ERR_GUILD_RANK_TOO_HIGH_S = 13,
|
ERR_GUILD_RANK_TOO_HIGH_S = 13,
|
||||||
ERR_GUILD_RANK_TOO_LOW_S = 14,
|
ERR_GUILD_RANK_TOO_LOW_S = 14,
|
||||||
ERR_GUILD_RANKS_LOCKED = 17,
|
ERR_GUILD_RANKS_LOCKED = 17,
|
||||||
ERR_GUILD_RANK_IN_USE = 18,
|
ERR_GUILD_RANK_IN_USE = 18,
|
||||||
ERR_GUILD_IGNORING_YOU_S = 19,
|
ERR_GUILD_IGNORING_YOU_S = 19,
|
||||||
ERR_GUILD_UNK1 = 20, // Forces roster update
|
ERR_GUILD_UNK1 = 20, // Forces roster update
|
||||||
ERR_GUILD_WITHDRAW_LIMIT = 25,
|
ERR_GUILD_WITHDRAW_LIMIT = 25,
|
||||||
ERR_GUILD_NOT_ENOUGH_MONEY = 26,
|
ERR_GUILD_NOT_ENOUGH_MONEY = 26,
|
||||||
ERR_GUILD_BANK_FULL = 28,
|
ERR_GUILD_BANK_FULL = 28,
|
||||||
ERR_GUILD_ITEM_NOT_FOUND = 29,
|
ERR_GUILD_ITEM_NOT_FOUND = 29,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildEvents
|
enum GuildEvents
|
||||||
{
|
{
|
||||||
GE_PROMOTION = 0,
|
GE_PROMOTION = 0,
|
||||||
GE_DEMOTION = 1,
|
GE_DEMOTION = 1,
|
||||||
GE_MOTD = 2,
|
GE_MOTD = 2,
|
||||||
GE_JOINED = 3,
|
GE_JOINED = 3,
|
||||||
GE_LEFT = 4,
|
GE_LEFT = 4,
|
||||||
GE_REMOVED = 5,
|
GE_REMOVED = 5,
|
||||||
GE_LEADER_IS = 6,
|
GE_LEADER_IS = 6,
|
||||||
GE_LEADER_CHANGED = 7,
|
GE_LEADER_CHANGED = 7,
|
||||||
GE_DISBANDED = 8,
|
GE_DISBANDED = 8,
|
||||||
GE_TABARDCHANGE = 9,
|
GE_TABARDCHANGE = 9,
|
||||||
GE_RANK_UPDATED = 10,
|
GE_RANK_UPDATED = 10,
|
||||||
GE_RANK_DELETED = 11,
|
GE_RANK_DELETED = 11,
|
||||||
GE_SIGNED_ON = 12,
|
GE_SIGNED_ON = 12,
|
||||||
GE_SIGNED_OFF = 13,
|
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_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_PURCHASED = 15,
|
||||||
GE_BANK_TAB_UPDATED = 16,
|
GE_BANK_TAB_UPDATED = 16,
|
||||||
GE_BANK_MONEY_SET = 17,
|
GE_BANK_MONEY_SET = 17,
|
||||||
GE_BANK_TAB_AND_MONEY_UPDATED = 18,
|
GE_BANK_TAB_AND_MONEY_UPDATED = 18,
|
||||||
GE_BANK_TEXT_CHANGED = 19,
|
GE_BANK_TEXT_CHANGED = 19,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PetitionTurns
|
enum PetitionTurns
|
||||||
{
|
{
|
||||||
PETITION_TURN_OK = 0,
|
PETITION_TURN_OK = 0,
|
||||||
PETITION_TURN_ALREADY_IN_GUILD = 2,
|
PETITION_TURN_ALREADY_IN_GUILD = 2,
|
||||||
PETITION_TURN_NEED_MORE_SIGNATURES = 4
|
PETITION_TURN_NEED_MORE_SIGNATURES = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PetitionSigns
|
enum PetitionSigns
|
||||||
{
|
{
|
||||||
PETITION_SIGN_OK = 0,
|
PETITION_SIGN_OK = 0,
|
||||||
PETITION_SIGN_ALREADY_SIGNED = 1,
|
PETITION_SIGN_ALREADY_SIGNED = 1,
|
||||||
PETITION_SIGN_ALREADY_IN_GUILD = 2,
|
PETITION_SIGN_ALREADY_IN_GUILD = 2,
|
||||||
PETITION_SIGN_CANT_SIGN_OWN = 3,
|
PETITION_SIGN_CANT_SIGN_OWN = 3,
|
||||||
PETITION_SIGN_NOT_SERVER = 4
|
PETITION_SIGN_NOT_SERVER = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildBankRights
|
enum GuildBankRights
|
||||||
{
|
{
|
||||||
GUILD_BANK_RIGHT_VIEW_TAB = 0x01,
|
GUILD_BANK_RIGHT_VIEW_TAB = 0x01,
|
||||||
GUILD_BANK_RIGHT_PUT_ITEM = 0x02,
|
GUILD_BANK_RIGHT_PUT_ITEM = 0x02,
|
||||||
GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04,
|
GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04,
|
||||||
|
|
||||||
GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM,
|
GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM,
|
||||||
GUILD_BANK_RIGHT_FULL = 0xFF
|
GUILD_BANK_RIGHT_FULL = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildBankEventLogTypes
|
enum GuildBankEventLogTypes
|
||||||
{
|
{
|
||||||
GUILD_BANK_LOG_DEPOSIT_ITEM = 1,
|
GUILD_BANK_LOG_DEPOSIT_ITEM = 1,
|
||||||
GUILD_BANK_LOG_WITHDRAW_ITEM = 2,
|
GUILD_BANK_LOG_WITHDRAW_ITEM = 2,
|
||||||
GUILD_BANK_LOG_MOVE_ITEM = 3,
|
GUILD_BANK_LOG_MOVE_ITEM = 3,
|
||||||
GUILD_BANK_LOG_DEPOSIT_MONEY = 4,
|
GUILD_BANK_LOG_DEPOSIT_MONEY = 4,
|
||||||
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
|
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
|
||||||
GUILD_BANK_LOG_REPAIR_MONEY = 6,
|
GUILD_BANK_LOG_REPAIR_MONEY = 6,
|
||||||
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
|
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
|
||||||
GUILD_BANK_LOG_UNK1 = 8,
|
GUILD_BANK_LOG_UNK1 = 8,
|
||||||
GUILD_BANK_LOG_BUY_SLOT = 9
|
GUILD_BANK_LOG_BUY_SLOT = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildEventLogTypes
|
enum GuildEventLogTypes
|
||||||
{
|
{
|
||||||
GUILD_EVENT_LOG_INVITE_PLAYER = 1,
|
GUILD_EVENT_LOG_INVITE_PLAYER = 1,
|
||||||
GUILD_EVENT_LOG_JOIN_GUILD = 2,
|
GUILD_EVENT_LOG_JOIN_GUILD = 2,
|
||||||
GUILD_EVENT_LOG_PROMOTE_PLAYER = 3,
|
GUILD_EVENT_LOG_PROMOTE_PLAYER = 3,
|
||||||
GUILD_EVENT_LOG_DEMOTE_PLAYER = 4,
|
GUILD_EVENT_LOG_DEMOTE_PLAYER = 4,
|
||||||
GUILD_EVENT_LOG_UNINVITE_PLAYER = 5,
|
GUILD_EVENT_LOG_UNINVITE_PLAYER = 5,
|
||||||
GUILD_EVENT_LOG_LEAVE_GUILD = 6
|
GUILD_EVENT_LOG_LEAVE_GUILD = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildEmblemError
|
enum GuildEmblemError
|
||||||
{
|
{
|
||||||
ERR_GUILDEMBLEM_SUCCESS = 0,
|
ERR_GUILDEMBLEM_SUCCESS = 0,
|
||||||
ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1,
|
ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1,
|
||||||
ERR_GUILDEMBLEM_NOGUILD = 2,
|
ERR_GUILDEMBLEM_NOGUILD = 2,
|
||||||
ERR_GUILDEMBLEM_NOTGUILDMASTER = 3,
|
ERR_GUILDEMBLEM_NOTGUILDMASTER = 3,
|
||||||
ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4,
|
ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4,
|
||||||
ERR_GUILDEMBLEM_INVALIDVENDOR = 5
|
ERR_GUILDEMBLEM_INVALIDVENDOR = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GuildMemberFlags
|
enum GuildMemberFlags
|
||||||
{
|
{
|
||||||
GUILDMEMBER_STATUS_NONE = 0x0000,
|
GUILDMEMBER_STATUS_NONE = 0x0000,
|
||||||
GUILDMEMBER_STATUS_ONLINE = 0x0001,
|
GUILDMEMBER_STATUS_ONLINE = 0x0001,
|
||||||
GUILDMEMBER_STATUS_AFK = 0x0002,
|
GUILDMEMBER_STATUS_AFK = 0x0002,
|
||||||
GUILDMEMBER_STATUS_DND = 0x0004,
|
GUILDMEMBER_STATUS_DND = 0x0004,
|
||||||
GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app
|
GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app
|
||||||
};
|
};
|
||||||
|
|
||||||
// Emblem info
|
// Emblem info
|
||||||
@@ -239,7 +239,8 @@ class EmblemInfo
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EmblemInfo(uint32 /*style*/ = 0, uint32 /*color*/ = 0, uint32 /*borderStyle*/ = 0, uint32 /*borderColor*/ = 0, uint32 /*backgroundColor*/ = 0) :
|
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 LoadFromDB(Field* fields);
|
||||||
void SaveToDB(uint32 guildId) const;
|
void SaveToDB(uint32 guildId) const;
|
||||||
@@ -263,9 +264,9 @@ private:
|
|||||||
class GuildBankRightsAndSlots
|
class GuildBankRightsAndSlots
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) { }
|
GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) {}
|
||||||
GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), 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(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) {}
|
||||||
|
|
||||||
void SetGuildMasterValues()
|
void SetGuildMasterValues()
|
||||||
{
|
{
|
||||||
@@ -296,7 +297,7 @@ public: // pussywizard: public class Member
|
|||||||
class Member
|
class Member
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Member(uint32 guildId, ObjectGuid guid, uint8 rankId):
|
Member(uint32 guildId, ObjectGuid guid, uint8 rankId) :
|
||||||
m_guildId(guildId),
|
m_guildId(guildId),
|
||||||
m_guid(guid),
|
m_guid(guid),
|
||||||
m_zoneId(0),
|
m_zoneId(0),
|
||||||
@@ -404,8 +405,8 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LogEntry(uint32 guildId, ObjectGuid::LowType guid);
|
LogEntry(uint32 guildId, ObjectGuid::LowType guid);
|
||||||
LogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) { }
|
LogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) {}
|
||||||
virtual ~LogEntry() { }
|
virtual ~LogEntry() {}
|
||||||
|
|
||||||
ObjectGuid::LowType GetGUID() const { return m_guid; }
|
ObjectGuid::LowType GetGUID() const { return m_guid; }
|
||||||
uint64 GetTimestamp() const { return m_timestamp; }
|
uint64 GetTimestamp() const { return m_timestamp; }
|
||||||
@@ -423,12 +424,14 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EventLogEntry(uint32 guildId, ObjectGuid::LowType guid, GuildEventLogTypes eventType, ObjectGuid playerGuid1, ObjectGuid playerGuid2, uint8 newRank) :
|
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) :
|
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 SaveToDB(CharacterDatabaseTransaction trans) const override;
|
||||||
void WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const;
|
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) :
|
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),
|
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) :
|
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),
|
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 SaveToDB(CharacterDatabaseTransaction trans) const override;
|
||||||
void WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const;
|
void WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const;
|
||||||
@@ -510,11 +515,12 @@ private:
|
|||||||
class RankInfo
|
class RankInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RankInfo(): m_guildId(0), 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) : 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) :
|
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_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 LoadFromDB(Field* fields);
|
||||||
void SaveToDB(CharacterDatabaseTransaction trans) const;
|
void SaveToDB(CharacterDatabaseTransaction trans) const;
|
||||||
@@ -573,7 +579,7 @@ private:
|
|||||||
std::string const& GetIcon() const { return m_icon; }
|
std::string const& GetIcon() const { return m_icon; }
|
||||||
std::string const& GetText() const { return m_text; }
|
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);
|
bool SetItem(CharacterDatabaseTransaction trans, uint8 slotId, Item* pItem);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -591,8 +597,9 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : m_pGuild(guild), m_pPlayer(player),
|
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) { }
|
m_container(container), m_slotId(slotId), m_pItem(nullptr), m_pClonedItem(nullptr) {
|
||||||
virtual ~MoveItemData() { }
|
}
|
||||||
|
virtual ~MoveItemData() {}
|
||||||
|
|
||||||
virtual bool IsBank() const = 0;
|
virtual bool IsBank() const = 0;
|
||||||
// Initializes item pointer. Returns true, if item exists, false otherwise.
|
// Initializes item pointer. Returns true, if item exists, false otherwise.
|
||||||
@@ -638,7 +645,8 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayerMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) :
|
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 IsBank() const override { return false; }
|
||||||
bool InitItem() override;
|
bool InitItem() override;
|
||||||
@@ -653,7 +661,8 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BankMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) :
|
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 IsBank() const override { return true; }
|
||||||
bool InitItem() override;
|
bool InitItem() override;
|
||||||
|
|||||||
@@ -264,15 +264,15 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
|||||||
std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
|
std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
|
||||||
|
|
||||||
recvData >> createInfo->Name
|
recvData >> createInfo->Name
|
||||||
>> createInfo->Race
|
>> createInfo->Race
|
||||||
>> createInfo->Class
|
>> createInfo->Class
|
||||||
>> createInfo->Gender
|
>> createInfo->Gender
|
||||||
>> createInfo->Skin
|
>> createInfo->Skin
|
||||||
>> createInfo->Face
|
>> createInfo->Face
|
||||||
>> createInfo->HairStyle
|
>> createInfo->HairStyle
|
||||||
>> createInfo->HairColor
|
>> createInfo->HairColor
|
||||||
>> createInfo->FacialHair
|
>> createInfo->FacialHair
|
||||||
>> createInfo->OutfitId;
|
>> createInfo->OutfitId;
|
||||||
|
|
||||||
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
if (AccountMgr::IsPlayerAccount(GetSecurity()))
|
||||||
{
|
{
|
||||||
@@ -371,233 +371,233 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
|||||||
stmt->SetData(0, createInfo->Name);
|
stmt->SetData(0, createInfo->Name);
|
||||||
|
|
||||||
_queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt)
|
_queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt)
|
||||||
.WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
|
.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<double>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (acctCharCount >= static_cast<uint64>(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<uint64>()); // 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_SERVER_LIMIT);
|
if (result)
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
|
|
||||||
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
|
|
||||||
|
|
||||||
std::function<void(PreparedQueryResult)> 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<uint8>();
|
|
||||||
|
|
||||||
if (checkDeathKnightReqs)
|
|
||||||
{
|
{
|
||||||
uint8 accClass = field[2].Get<uint8>();
|
SendCharCreate(CHAR_CREATE_NAME_IN_USE);
|
||||||
if (accClass == CLASS_DEATH_KNIGHT)
|
return;
|
||||||
{
|
|
||||||
if (freeDeathKnightSlots > 0)
|
|
||||||
--freeDeathKnightSlots;
|
|
||||||
|
|
||||||
if (freeDeathKnightSlots == 0)
|
|
||||||
{
|
|
||||||
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasHeroicReqLevel)
|
|
||||||
{
|
|
||||||
uint8 accLevel = field[0].Get<uint8>();
|
|
||||||
if (accLevel >= heroicReqLevel)
|
|
||||||
hasHeroicReqLevel = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to check team only for first character
|
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_SUM_REALM_CHARACTERS);
|
||||||
/// @todo what to if account already has characters of both races?
|
stmt->SetData(0, GetAccountId());
|
||||||
if (!allowTwoSideAccounts)
|
queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
|
||||||
|
})
|
||||||
|
.WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
|
||||||
|
{
|
||||||
|
uint64 acctCharCount = 0;
|
||||||
|
if (result)
|
||||||
{
|
{
|
||||||
uint32 accTeam = 0;
|
Field* fields = result->Fetch();
|
||||||
if (accRace > 0)
|
acctCharCount = uint64(fields[0].Get<double>());
|
||||||
accTeam = Player::TeamIdForRace(accRace);
|
}
|
||||||
|
|
||||||
if (accTeam != teamId)
|
if (acctCharCount >= static_cast<uint64>(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<uint64>()); // 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// search same race for cinematic or same class if need
|
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
|
||||||
/// @todo check if cinematic already shown? (already logged in?; cinematic field)
|
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
|
||||||
while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT)
|
|
||||||
{
|
|
||||||
if (!result->NextRow())
|
|
||||||
break;
|
|
||||||
|
|
||||||
field = result->Fetch();
|
std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
|
||||||
accRace = field[1].Get<uint8>();
|
|
||||||
|
|
||||||
if (!haveSameRace)
|
|
||||||
haveSameRace = createInfo->Race == accRace;
|
|
||||||
|
|
||||||
if (checkDeathKnightReqs)
|
|
||||||
{
|
{
|
||||||
uint8 acc_class = field[2].Get<uint8>();
|
if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class))
|
||||||
if (acc_class == CLASS_DEATH_KNIGHT)
|
|
||||||
{
|
{
|
||||||
if (freeDeathKnightSlots > 0)
|
SendCharCreate(CHAR_CREATE_DISABLED);
|
||||||
--freeDeathKnightSlots;
|
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<uint8>();
|
||||||
|
|
||||||
|
if (checkDeathKnightReqs)
|
||||||
{
|
{
|
||||||
SendCharCreate(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
|
uint8 accClass = field[2].Get<uint8>();
|
||||||
return;
|
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<uint8>();
|
||||||
|
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<uint8>();
|
||||||
|
|
||||||
|
if (!haveSameRace)
|
||||||
|
haveSameRace = createInfo->Race == accRace;
|
||||||
|
|
||||||
|
if (checkDeathKnightReqs)
|
||||||
|
{
|
||||||
|
uint8 acc_class = field[2].Get<uint8>();
|
||||||
|
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<uint8>();
|
||||||
|
if (acc_level >= heroicReqLevel)
|
||||||
|
hasHeroicReqLevel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasHeroicReqLevel)
|
if (checkDeathKnightReqs && !hasHeroicReqLevel)
|
||||||
{
|
{
|
||||||
uint8 acc_level = field[0].Get<uint8>();
|
SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
|
||||||
if (acc_level >= heroicReqLevel)
|
return;
|
||||||
hasHeroicReqLevel = true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkDeathKnightReqs && !hasHeroicReqLevel)
|
// Check name uniqueness in the same step as saving to database
|
||||||
{
|
if (sCharacterCache->GetCharacterGuidByName(createInfo->Name))
|
||||||
SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
|
{
|
||||||
return;
|
SendCharCreate(CHAR_CREATE_NAME_IN_USE);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check name uniqueness in the same step as saving to database
|
std::shared_ptr<Player> newChar(new Player(this), [](Player* ptr)
|
||||||
if (sCharacterCache->GetCharacterGuidByName(createInfo->Name))
|
{
|
||||||
{
|
// Only when player is created correctly do clean
|
||||||
SendCharCreate(CHAR_CREATE_NAME_IN_USE);
|
if (ptr->HasAtLoginFlag(AT_LOGIN_FIRST))
|
||||||
return;
|
{
|
||||||
}
|
ptr->CleanupsBeforeDelete();
|
||||||
|
}
|
||||||
|
delete ptr;
|
||||||
|
});
|
||||||
|
|
||||||
std::shared_ptr<Player> newChar(new Player(this), [](Player* ptr)
|
newChar->GetMotionMaster()->Initialize();
|
||||||
{
|
if (!newChar->Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
|
||||||
// Only when player is created correctly do clean
|
{
|
||||||
if (ptr->HasAtLoginFlag(AT_LOGIN_FIRST))
|
// 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();
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO);
|
||||||
if (!newChar->Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
|
stmt->SetData(0, GetAccountId());
|
||||||
{
|
stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
|
||||||
// Player not create (race/class/etc problem?)
|
queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
|
||||||
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));
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
|
void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
|
||||||
@@ -775,9 +775,9 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
|
|||||||
|
|
||||||
m_playerLoading = true;
|
m_playerLoading = true;
|
||||||
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
|
AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
|
||||||
{
|
{
|
||||||
HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
|
HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& 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, 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->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
|
// Set FFA PvP for non GM in non-rest mode
|
||||||
if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
|
if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
|
||||||
if (!pCurrChar->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
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);
|
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.
|
// If we process the check while players are loading they won't be notified of the changes.
|
||||||
pCurrChar->m_Events.AddEventAtOffset([pCurrChar]
|
pCurrChar->m_Events.AddEventAtOffset([pCurrChar]
|
||||||
{
|
{
|
||||||
pCurrChar->RemoveAtLoginFlag(AT_LOGIN_CHECK_ACHIEVS, true);
|
pCurrChar->RemoveAtLoginFlag(AT_LOGIN_CHECK_ACHIEVS, true);
|
||||||
pCurrChar->CheckAllAchievementCriteria();
|
pCurrChar->CheckAllAchievementCriteria();
|
||||||
}, 1s);
|
}, 1s);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
|
bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
|
||||||
@@ -1009,25 +1008,25 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
|
|||||||
ReputationMgr& repMgr = pCurrChar->GetReputationMgr();
|
ReputationMgr& repMgr = pCurrChar->GetReputationMgr();
|
||||||
|
|
||||||
auto SendFullReputation = [&repMgr](std::initializer_list<uint32> factionsList)
|
auto SendFullReputation = [&repMgr](std::initializer_list<uint32> 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 });
|
SendFullReputation({ 942, 935, 936, 1011, 970, 967, 989, 932, 934, 1038, 1077, 1106, 1104, 1090, 1098, 1156, 1073, 1105, 1119, 1091 });
|
||||||
|
|
||||||
switch (pCurrChar->GetFaction())
|
switch (pCurrChar->GetFaction())
|
||||||
{
|
{
|
||||||
case ALLIANCE:
|
case ALLIANCE:
|
||||||
SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 });
|
SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 });
|
||||||
break;
|
break;
|
||||||
case HORDE:
|
case HORDE:
|
||||||
SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 });
|
SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 });
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
repMgr.SendStates();
|
repMgr.SendStates();
|
||||||
@@ -1046,7 +1045,7 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
|
|||||||
|
|
||||||
std::string IP_str = GetRemoteAddress();
|
std::string IP_str = GetRemoteAddress();
|
||||||
LOG_INFO("entities.player", "Account: {} (IP: {}) Login Character:[{}] ({}) Level: {}",
|
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))
|
if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
|
||||||
pCurrChar->SetStandState(UNIT_STAND_STATE_STAND);
|
pCurrChar->SetStandState(UNIT_STAND_STATE_STAND);
|
||||||
@@ -1341,7 +1340,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData)
|
|||||||
std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
|
std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
|
||||||
|
|
||||||
recvData >> renameInfo->Guid
|
recvData >> renameInfo->Guid
|
||||||
>> renameInfo->Name;
|
>> renameInfo->Name;
|
||||||
|
|
||||||
// prevent character rename to invalid name
|
// prevent character rename to invalid name
|
||||||
if (!normalizePlayerName(renameInfo->Name))
|
if (!normalizePlayerName(renameInfo->Name))
|
||||||
@@ -1638,12 +1637,12 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
recvData >> customizeInfo->Name
|
recvData >> customizeInfo->Name
|
||||||
>> customizeInfo->Gender
|
>> customizeInfo->Gender
|
||||||
>> customizeInfo->Skin
|
>> customizeInfo->Skin
|
||||||
>> customizeInfo->HairColor
|
>> customizeInfo->HairColor
|
||||||
>> customizeInfo->HairStyle
|
>> customizeInfo->HairStyle
|
||||||
>> customizeInfo->FacialHair
|
>> customizeInfo->FacialHair
|
||||||
>> customizeInfo->Face;
|
>> customizeInfo->Face;
|
||||||
|
|
||||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO);
|
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO);
|
||||||
stmt->SetData(0, customizeInfo->Guid.GetCounter());
|
stmt->SetData(0, customizeInfo->Guid.GetCounter());
|
||||||
@@ -1775,10 +1774,10 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData)
|
|||||||
|
|
||||||
EquipmentSet eqSet;
|
EquipmentSet eqSet;
|
||||||
|
|
||||||
eqSet.Guid = setGuid;
|
eqSet.Guid = setGuid;
|
||||||
eqSet.Name = name;
|
eqSet.Name = name;
|
||||||
eqSet.IconName = iconName;
|
eqSet.IconName = iconName;
|
||||||
eqSet.state = EQUIPMENT_SET_NEW;
|
eqSet.state = EQUIPMENT_SET_NEW;
|
||||||
|
|
||||||
for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
|
||||||
{
|
{
|
||||||
@@ -1933,13 +1932,13 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
recvData >> factionChangeInfo->Name
|
recvData >> factionChangeInfo->Name
|
||||||
>> factionChangeInfo->Gender
|
>> factionChangeInfo->Gender
|
||||||
>> factionChangeInfo->Skin
|
>> factionChangeInfo->Skin
|
||||||
>> factionChangeInfo->HairColor
|
>> factionChangeInfo->HairColor
|
||||||
>> factionChangeInfo->HairStyle
|
>> factionChangeInfo->HairStyle
|
||||||
>> factionChangeInfo->FacialHair
|
>> factionChangeInfo->FacialHair
|
||||||
>> factionChangeInfo->Face
|
>> factionChangeInfo->Face
|
||||||
>> factionChangeInfo->Race;
|
>> factionChangeInfo->Race;
|
||||||
|
|
||||||
// pussywizard:
|
// pussywizard:
|
||||||
if (ObjectAccessor::FindConnectedPlayer(factionChangeInfo->Guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(factionChangeInfo->Guid.GetCounter()))
|
if (ObjectAccessor::FindConnectedPlayer(factionChangeInfo->Guid) || sWorldSessionMgr->FindOfflineSessionForCharacterGUID(factionChangeInfo->Guid.GetCounter()))
|
||||||
@@ -2217,16 +2216,16 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
|
|||||||
for (auto const& itr : sTaxiPathSetBySource)
|
for (auto const& itr : sTaxiPathSetBySource)
|
||||||
{
|
{
|
||||||
auto FillTaxiMask = [&](uint8 field, uint32 mask)
|
auto FillTaxiMask = [&](uint8 field, uint32 mask)
|
||||||
{
|
|
||||||
if (playerClass == CLASS_DEATH_KNIGHT)
|
|
||||||
{
|
{
|
||||||
newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
|
if (playerClass == CLASS_DEATH_KNIGHT)
|
||||||
}
|
{
|
||||||
else
|
newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
|
||||||
{
|
}
|
||||||
newTaxiMask[field] |= mask;
|
else
|
||||||
}
|
{
|
||||||
};
|
newTaxiMask[field] |= mask;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
uint32 nodeId = itr.first;
|
uint32 nodeId = itr.first;
|
||||||
uint8 field = (uint8)((nodeId - 1) / 32);
|
uint8 field = (uint8)((nodeId - 1) / 32);
|
||||||
|
|||||||
@@ -335,15 +335,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
msg.erase(end, msg.end());
|
msg.erase(end, msg.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip validation for playerbots module
|
// Validate hyperlinks
|
||||||
auto playerbotsHyperlink = msg.find("Hfound:") != std::string::npos;
|
if (!ValidateHyperlinksAndMaybeKick(msg))
|
||||||
if (!playerbotsHyperlink)
|
|
||||||
{
|
{
|
||||||
// Validate hyperlinks
|
return;
|
||||||
if (!ValidateHyperlinksAndMaybeKick(msg))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,11 +434,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg);
|
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 (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
|
||||||
{
|
{
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
|
|
||||||
|
|
||||||
guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -479,11 +462,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
|
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
|
||||||
{
|
{
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
|
|
||||||
|
|
||||||
guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
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))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg);
|
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))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
|
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
|
||||||
@@ -543,11 +514,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
||||||
|
|
||||||
// In battleground, raid warning is sent only to players in battleground - code is ok
|
// In battleground, raid warning is sent only to players in battleground - code is ok
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
@@ -563,11 +530,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
|
ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
|
||||||
@@ -582,11 +545,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
|
||||||
|
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);
|
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 (Channel* chn = cMgr->GetChannel(channel, sender))
|
||||||
{
|
{
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg, chn))
|
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg, chn))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
|
|
||||||
|
|
||||||
chn->Say(sender->GetGUID(), msg.c_str(), lang);
|
chn->Say(sender->GetGUID(), msg.c_str(), lang);
|
||||||
}
|
}
|
||||||
@@ -642,11 +597,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
|
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(sender, type, lang, msg);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -670,11 +621,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
|
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
sScriptMgr->OnPlayerChat(sender, type, lang, msg);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,8 +482,6 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sScriptMgr->OnPlayerbotCheckPetitionAccount(_player, found);
|
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
|
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ Map::~Map()
|
|||||||
{
|
{
|
||||||
// UnloadAll must be called before deleting the 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);
|
sScriptMgr->OnDestroyMap(this);
|
||||||
|
|
||||||
if (!m_scriptSchedule.empty())
|
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)
|
if (!t_diff)
|
||||||
{
|
{
|
||||||
@@ -1097,7 +1101,7 @@ float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, fl
|
|||||||
if (ground)
|
if (ground)
|
||||||
*ground = ground_z;
|
*ground = ground_z;
|
||||||
|
|
||||||
LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, MAP_ALL_LIQUIDS);
|
LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phasemask, x, y, ground_z, collisionHeight, {});
|
||||||
switch (liquidData.Status)
|
switch (liquidData.Status)
|
||||||
{
|
{
|
||||||
case LIQUID_MAP_ABOVE_WATER:
|
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
|
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;
|
float check_z = z;
|
||||||
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
||||||
uint32 vflags;
|
VMAP::AreaAndLiquidData vdata;
|
||||||
int32 vadtId;
|
VMAP::AreaAndLiquidData ddata;
|
||||||
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; };
|
|
||||||
|
|
||||||
|
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 (hasVmapAreaInfo)
|
||||||
{
|
{
|
||||||
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
|
if (hasDynamicAreaInfo && ddata.floorZ > vdata.floorZ)
|
||||||
useDyn();
|
useDyn();
|
||||||
else
|
else
|
||||||
useVmap();
|
useVmap();
|
||||||
@@ -1299,32 +1294,30 @@ void Map::GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, flo
|
|||||||
zoneid = area->zone;
|
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<uint8> ReqLiquidType)
|
||||||
{
|
{
|
||||||
LiquidData liquidData;
|
LiquidData liquidData;
|
||||||
|
liquidData.Status = LIQUID_MAP_NO_WATER;
|
||||||
|
|
||||||
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
||||||
float liquid_level = INVALID_HEIGHT;
|
VMAP::AreaAndLiquidData vmapData;
|
||||||
float ground_level = INVALID_HEIGHT;
|
|
||||||
uint32 liquid_type = 0;
|
|
||||||
uint32 mogpFlags = 0;
|
|
||||||
bool useGridLiquid = true;
|
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);
|
useGridLiquid = !vmapData.areaInfo || !IsInWMOInterior(vmapData.areaInfo->mogpFlags);
|
||||||
LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", liquid_level, ground_level, liquid_type);
|
LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", vmapData.liquidInfo->level, vmapData.floorZ, vmapData.liquidInfo->type);
|
||||||
// Check water level and ground level
|
// 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
|
// hardcoded in client like this
|
||||||
if (GetId() == MAP_OUTLAND && liquid_type == 2)
|
if (GetId() == MAP_OUTLAND && vmapData.liquidInfo->type == 2)
|
||||||
liquid_type = 15;
|
vmapData.liquidInfo->type = 15;
|
||||||
|
|
||||||
uint32 liquidFlagType = 0;
|
uint32 liquidFlagType = 0;
|
||||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
|
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(vmapData.liquidInfo->type))
|
||||||
liquidFlagType = liq->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)))
|
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))
|
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||||
{
|
{
|
||||||
liquid_type = overrideLiquid;
|
vmapData.liquidInfo->type = overrideLiquid;
|
||||||
liquidFlagType = liq->Type;
|
liquidFlagType = liq->Type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
liquidData.Level = liquid_level;
|
liquidData.Level = vmapData.liquidInfo->level;
|
||||||
liquidData.DepthLevel = ground_level;
|
liquidData.DepthLevel = vmapData.floorZ;
|
||||||
liquidData.Entry = liquid_type;
|
liquidData.Entry = vmapData.liquidInfo->type;
|
||||||
liquidData.Flags = 1 << liquidFlagType;
|
liquidData.Flags = 1 << liquidFlagType;
|
||||||
}
|
}
|
||||||
|
|
||||||
float delta = liquid_level - z;
|
float delta = vmapData.liquidInfo->level - z;
|
||||||
|
|
||||||
// Get position delta
|
// Get position delta
|
||||||
if (delta > collisionHeight)
|
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);
|
LiquidData const& map_data = gmap->GetLiquidData(x, y, z, collisionHeight, ReqLiquidType);
|
||||||
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
|
// 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
|
// hardcoded in client like this
|
||||||
uint32 liquidEntry = map_data.Entry;
|
uint32 liquidEntry = map_data.Entry;
|
||||||
@@ -1385,7 +1378,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
|
|||||||
return liquidData;
|
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<uint8> reqLiquidType)
|
||||||
{
|
{
|
||||||
GridTerrainData* gmap = GetGridTerrainData(x, y);
|
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
|
bool Map::IsInWater(uint32 phaseMask, float x, float y, float pZ, float collisionHeight) const
|
||||||
{
|
{
|
||||||
LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, MAP_ALL_LIQUIDS);
|
LiquidData const& liquidData = const_cast<Map*>(this)->GetLiquidData(phaseMask, x, y, pZ, collisionHeight, {});
|
||||||
return (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING) != 0;
|
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
|
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)
|
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->second.BuildPacket(packet);
|
||||||
iter->first->SendDirectMessage(&packet);
|
iter->first->SendDirectMessage(&packet);
|
||||||
packet.clear(); // clean the string
|
packet.clear(); // clean the string
|
||||||
@@ -2764,13 +2751,13 @@ void Map::RemoveOldCorpses()
|
|||||||
|
|
||||||
void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnTimer, Position pos)
|
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))
|
if (Creature* creature = GetCreature(creatureGuid))
|
||||||
creature->Respawn();
|
creature->Respawn();
|
||||||
else
|
else
|
||||||
SummonCreature(creatureGuid.GetEntry(), pos);
|
SummonCreature(creatureGuid.GetEntry(), pos);
|
||||||
});
|
}, respawnTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
|
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "DataMap.h"
|
#include "DataMap.h"
|
||||||
#include "Define.h"
|
#include "Define.h"
|
||||||
#include "DynamicTree.h"
|
#include "DynamicTree.h"
|
||||||
|
#include "EventProcessor.h"
|
||||||
#include "GameObjectModel.h"
|
#include "GameObjectModel.h"
|
||||||
#include "GridDefines.h"
|
#include "GridDefines.h"
|
||||||
#include "GridRefMgr.h"
|
#include "GridRefMgr.h"
|
||||||
@@ -33,7 +34,6 @@
|
|||||||
#include "PathGenerator.h"
|
#include "PathGenerator.h"
|
||||||
#include "Position.h"
|
#include "Position.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "TaskScheduler.h"
|
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "GridTerrainData.h"
|
#include "GridTerrainData.h"
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
@@ -172,7 +172,7 @@ public:
|
|||||||
// currently unused for normal maps
|
// currently unused for normal maps
|
||||||
bool CanUnload(uint32 diff)
|
bool CanUnload(uint32 diff)
|
||||||
{
|
{
|
||||||
if (!m_unloadTimer)
|
if (!m_unloadTimer || Events.HasEvents())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_unloadTimer <= diff)
|
if (m_unloadTimer <= diff)
|
||||||
@@ -243,8 +243,8 @@ public:
|
|||||||
[[nodiscard]] float GetMinHeight(float x, float y) const;
|
[[nodiscard]] float GetMinHeight(float x, float y) const;
|
||||||
Transport* GetTransportForPos(uint32 phase, float x, float y, float z, WorldObject* worldobject = nullptr);
|
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);
|
void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<uint8> reqLiquidType = {});
|
||||||
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType);
|
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional<uint8> ReqLiquidType);
|
||||||
|
|
||||||
[[nodiscard]] bool GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
|
[[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;
|
[[nodiscard]] uint32 GetAreaId(uint32 phaseMask, float x, float y, float z) const;
|
||||||
@@ -430,7 +430,7 @@ public:
|
|||||||
void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone);
|
void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone);
|
||||||
[[nodiscard]] uint32 ApplyDynamicModeRespawnScaling(WorldObject const* obj, uint32 respawnDelay) const;
|
[[nodiscard]] uint32 ApplyDynamicModeRespawnScaling(WorldObject const* obj, uint32 respawnDelay) const;
|
||||||
|
|
||||||
TaskScheduler _creatureRespawnScheduler;
|
EventProcessor Events;
|
||||||
|
|
||||||
void ScheduleCreatureRespawn(ObjectGuid /*creatureGuid*/, Milliseconds /*respawnTimer*/, Position pos = Position());
|
void ScheduleCreatureRespawn(ObjectGuid /*creatureGuid*/, Milliseconds /*respawnTimer*/, Position pos = Position());
|
||||||
|
|
||||||
|
|||||||
@@ -211,8 +211,8 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
|||||||
{
|
{
|
||||||
bool buildShortcut = false;
|
bool buildShortcut = false;
|
||||||
|
|
||||||
auto liquidDataStart = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.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(), MAP_ALL_LIQUIDS);
|
auto liquidDataEnd = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight(), {});
|
||||||
|
|
||||||
bool startUnderWaterEndInWater = liquidDataStart.Status == LIQUID_MAP_UNDER_WATER &&
|
bool startUnderWaterEndInWater = liquidDataStart.Status == LIQUID_MAP_UNDER_WATER &&
|
||||||
(liquidDataEnd.Status & MAP_LIQUID_STATUS_IN_CONTACT) != 0;
|
(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
|
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)
|
if (liquidData.Status == LIQUID_MAP_NO_WATER)
|
||||||
return NAV_GROUND;
|
return NAV_GROUND;
|
||||||
|
|
||||||
|
|||||||
@@ -47,10 +47,6 @@ void PointMovementGenerator<T>::DoInitialize(T* unit)
|
|||||||
|
|
||||||
i_recalculateSpeed = false;
|
i_recalculateSpeed = false;
|
||||||
Movement::MoveSplineInit init(unit);
|
Movement::MoveSplineInit init(unit);
|
||||||
/// Added by mod-playerbots
|
|
||||||
if (_reverseOrientation)
|
|
||||||
init.SetOrientationInversed();
|
|
||||||
/// End added
|
|
||||||
if (m_precomputedPath.size() > 2) // pussywizard: for charge
|
if (m_precomputedPath.size() > 2) // pussywizard: for charge
|
||||||
init.MovebyPath(m_precomputedPath);
|
init.MovebyPath(m_precomputedPath);
|
||||||
else if (_generatePath)
|
else if (_generatePath)
|
||||||
@@ -220,9 +216,14 @@ template <> void PointMovementGenerator<Creature>::MovementInform(Creature* unit
|
|||||||
if (Unit* summoner = unit->GetCharmerOrOwner())
|
if (Unit* summoner = unit->GetCharmerOrOwner())
|
||||||
{
|
{
|
||||||
if (UnitAI* AI = summoner->GetAI())
|
if (UnitAI* AI = summoner->GetAI())
|
||||||
{
|
|
||||||
AI->SummonMovementInform(unit, POINT_MOTION_TYPE, id);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -276,22 +276,14 @@ void WaypointMovementGenerator<Creature>::MovementInform(Creature* creature)
|
|||||||
if (Unit* owner = creature->GetCharmerOrOwner())
|
if (Unit* owner = creature->GetCharmerOrOwner())
|
||||||
{
|
{
|
||||||
if (UnitAI* AI = owner->GetAI())
|
if (UnitAI* AI = owner->GetAI())
|
||||||
{
|
|
||||||
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
|
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (TempSummon* tempSummon = creature->ToTempSummon())
|
if (TempSummon* tempSummon = creature->ToTempSummon())
|
||||||
{
|
|
||||||
if (Unit* owner = tempSummon->GetSummonerUnit())
|
if (Unit* owner = tempSummon->GetSummonerUnit())
|
||||||
{
|
|
||||||
if (UnitAI* AI = owner->GetAI())
|
if (UnitAI* AI = owner->GetAI())
|
||||||
{
|
|
||||||
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
|
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,6 +410,7 @@ void FlightPathMovementGenerator::DoFinalize(Player* player)
|
|||||||
player->m_taxi.ClearTaxiDestinations();
|
player->m_taxi.ClearTaxiDestinations();
|
||||||
player->Dismount();
|
player->Dismount();
|
||||||
player->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
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())
|
if (player->m_taxi.empty())
|
||||||
{
|
{
|
||||||
@@ -447,6 +440,9 @@ void FlightPathMovementGenerator::DoReset(Player* player)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->pvpInfo.EndTimer)
|
||||||
|
player->UpdatePvP(false, true); // PvP flag timer immediately ends when starting taxi
|
||||||
|
|
||||||
player->getHostileRefMgr().setOnlineOfflineState(false);
|
player->getHostileRefMgr().setOnlineOfflineState(false);
|
||||||
player->AddUnitState(UNIT_STATE_IN_FLIGHT);
|
player->AddUnitState(UNIT_STATE_IN_FLIGHT);
|
||||||
player->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
player->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
||||||
|
|||||||
@@ -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));
|
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)
|
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));
|
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)
|
void ScriptMgr::OnPlayerEmote(Player* player, uint32 emote)
|
||||||
{
|
{
|
||||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_EMOTE, script->OnPlayerEmote(player, emote));
|
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_EMOTE, script->OnPlayerEmote(player, emote));
|
||||||
|
|||||||
@@ -306,18 +306,8 @@ public:
|
|||||||
virtual void OnPlayerDuelEnd(Player* /*winner*/, Player* /*loser*/, DuelCompleteType /*type*/) { }
|
virtual void OnPlayerDuelEnd(Player* /*winner*/, Player* /*loser*/, DuelCompleteType /*type*/) { }
|
||||||
|
|
||||||
// The following methods are called when a player sends a chat message.
|
// 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 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.
|
// Both of the below are called on emote opcodes.
|
||||||
virtual void OnPlayerEmote(Player* /*player*/, uint32 /*emote*/) { }
|
virtual void OnPlayerEmote(Player* /*player*/, uint32 /*emote*/) { }
|
||||||
|
|
||||||
|
|||||||
@@ -340,12 +340,7 @@ public: /* PlayerScript */
|
|||||||
void OnPlayerDuelRequest(Player* target, Player* challenger);
|
void OnPlayerDuelRequest(Player* target, Player* challenger);
|
||||||
void OnPlayerDuelStart(Player* player1, Player* player2);
|
void OnPlayerDuelStart(Player* player1, Player* player2);
|
||||||
void OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type);
|
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 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 OnPlayerEmote(Player* player, uint32 emote);
|
||||||
void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid);
|
void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid);
|
||||||
void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck);
|
void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck);
|
||||||
|
|||||||
@@ -1377,7 +1377,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
|
|||||||
|
|
||||||
float ground = m_caster->GetMapHeight(x, y, z, true);
|
float ground = m_caster->GetMapHeight(x, y, z, true);
|
||||||
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
|
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)
|
if (liquidData.Status)
|
||||||
liquidLevel = liquidData.Level;
|
liquidLevel = liquidData.Level;
|
||||||
|
|
||||||
|
|||||||
@@ -156,13 +156,13 @@ public:
|
|||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK);
|
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.");
|
handler->SendSysMessage("Waterwalking is ON. You can walk on water.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK);
|
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.");
|
handler->SendSysMessage("Waterwalking is OFF. You can't walk on water.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1949,7 +1949,7 @@ public:
|
|||||||
// the max level of the new profession.
|
// the max level of the new profession.
|
||||||
uint16 max = maxPureSkill ? *maxPureSkill : targetHasSkill ? target->GetPureMaxSkillValue(skillID) : uint16(level);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,7 +219,6 @@ public:
|
|||||||
{
|
{
|
||||||
ObjectGuid::LowType guid = sObjectMgr->GenerateCreatureSpawnId();
|
ObjectGuid::LowType guid = sObjectMgr->GenerateCreatureSpawnId();
|
||||||
CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);
|
CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);
|
||||||
data.spawnId = guid;
|
|
||||||
data.id1 = id;
|
data.id1 = id;
|
||||||
data.phaseMask = chr->GetPhaseMaskForSpawn();
|
data.phaseMask = chr->GetPhaseMaskForSpawn();
|
||||||
data.posX = chr->GetTransOffsetX();
|
data.posX = chr->GetTransOffsetX();
|
||||||
|
|||||||
@@ -2019,11 +2019,14 @@ class spell_gen_animal_blood : public AuraScript
|
|||||||
{
|
{
|
||||||
// Remove all auras with spell id 46221, except the one currently being applied
|
// 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()))
|
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*/)
|
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
{
|
{
|
||||||
|
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Unit* owner = GetUnitOwner())
|
if (Unit* owner = GetUnitOwner())
|
||||||
if (owner->IsInWater())
|
if (owner->IsInWater())
|
||||||
owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true);
|
owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true);
|
||||||
@@ -2044,7 +2047,7 @@ class spell_spawn_blood_pool : public SpellScript
|
|||||||
void SetDest(SpellDestination &dest)
|
void SetDest(SpellDestination &dest)
|
||||||
{
|
{
|
||||||
Unit* caster = GetCaster();
|
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();
|
float level = liquidStatus.Level > INVALID_HEIGHT ? liquidStatus.Level : caster->GetPositionZ();
|
||||||
Position pos = Position(caster->GetPositionX(), caster->GetPositionY(), level, caster->GetOrientation());
|
Position pos = Position(caster->GetPositionX(), caster->GetPositionY(), level, caster->GetOrientation());
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public:
|
|||||||
{
|
{
|
||||||
QuestStatus QLR = player->GetQuestStatus(QUEST_LAST_RITES);
|
QuestStatus QLR = player->GetQuestStatus(QUEST_LAST_RITES);
|
||||||
QuestStatus QBT = player->GetQuestStatus(QUEST_BREAKING_THROUGH);
|
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))
|
QBT == QUEST_STATUS_INCOMPLETE || QBT == QUEST_STATUS_COMPLETE))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ public:
|
|||||||
ChatLogScript() :
|
ChatLogScript() :
|
||||||
PlayerScript("ChatLogScript",
|
PlayerScript("ChatLogScript",
|
||||||
{
|
{
|
||||||
PLAYERHOOK_ON_CHAT,
|
PLAYERHOOK_CAN_PLAYER_USE_CHAT,
|
||||||
PLAYERHOOK_ON_CHAT_WITH_GROUP,
|
PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT,
|
||||||
PLAYERHOOK_ON_CHAT_WITH_GUILD,
|
PLAYERHOOK_CAN_PLAYER_USE_GROUP_CHAT,
|
||||||
PLAYERHOOK_ON_CHAT_WITH_CHANNEL,
|
PLAYERHOOK_CAN_PLAYER_USE_GUILD_CHAT,
|
||||||
PLAYERHOOK_ON_CHAT_WITH_RECEIVER
|
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 logType = "";
|
||||||
std::string chatType = "";
|
std::string chatType = "";
|
||||||
@@ -56,14 +56,16 @@ public:
|
|||||||
chatType = "yells";
|
chatType = "yells";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(logType, "Player {} {} (language {}): {}",
|
LOG_INFO(logType, "Player {} {} (language {}): {}",
|
||||||
player->GetName(), chatType, lang, msg);
|
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:
|
//! NOTE:
|
||||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||||
@@ -72,9 +74,11 @@ public:
|
|||||||
|
|
||||||
LOG_INFO(logType + msgType, "Player {} {} {}: {}",
|
LOG_INFO(logType + msgType, "Player {} {} {}: {}",
|
||||||
player->GetName(), msgType, receiver ? receiver->GetName() : "<unknown>", msg);
|
player->GetName(), msgType, receiver ? receiver->GetName() : "<unknown>", 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:
|
//! NOTE:
|
||||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||||
@@ -97,7 +101,7 @@ public:
|
|||||||
msgType = "bg";
|
msgType = "bg";
|
||||||
break;
|
break;
|
||||||
default:
|
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";
|
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 {}: {}",
|
LOG_INFO(logType + msgType, "{} {} {} {} with leader {}: {}",
|
||||||
role, player->GetName(), action, msgType, targetGroup, msg);
|
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:
|
//! NOTE:
|
||||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||||
@@ -124,14 +130,16 @@ public:
|
|||||||
msgType = "guild.officer";
|
msgType = "guild.officer";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(logType + msgType, "Player {} tells {} \"{}\": {}",
|
LOG_INFO(logType + msgType, "Player {} tells {} \"{}\": {}",
|
||||||
player->GetName(), msgType, guild ? guild->GetName() : "<unknown>", msg);
|
player->GetName(), msgType, guild ? guild->GetName() : "<unknown>", 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 &&
|
bool isSystem = channel &&
|
||||||
(channel->HasFlag(CHANNEL_FLAG_TRADE) ||
|
(channel->HasFlag(CHANNEL_FLAG_TRADE) ||
|
||||||
@@ -152,6 +160,8 @@ public:
|
|||||||
LOG_INFO("chat.channel." + channelName, "Player {} tells channel {}: {}",
|
LOG_INFO("chat.channel." + channelName, "Player {} tells channel {}: {}",
|
||||||
player->GetName(), channelName, msg);
|
player->GetName(), channelName, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user