minimize delta, legacy and merge mistakes over the years
This commit is contained in:
@@ -31,7 +31,7 @@ body:
|
||||
description: |
|
||||
Do you have any logs or screenshots that can be useful?
|
||||
Crash logs in text are preffered over screenshots.
|
||||
If you have logs in text form please upload them to [Gist](https://gist.github.com/) or PasteBin and upload the link.
|
||||
DO NOT POST THE FULL CRASH LOG IN THE ISSUE BODY. DO NOT UPLOAD TEXT FILES. USE [GITHUB GIST](https://gist.github.com/), PASTEBIN, OR ANY SIMILAR SERVICE INSTEAD.
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
# List of AUTHORS who contributed over time to the AzerothCore project
|
||||
|
||||
## Warning
|
||||
The code of AzerothCore is shipped as it is without any form of warranty,
|
||||
and - except for third party libraries licensed under the AGPL 3,
|
||||
which you can read from the file "LICENSE".
|
||||
|
||||
## Point of current development
|
||||
The project is currently hosted at https://www.azerothcore.org/ and developed under https://github.com/azerothcore
|
||||
|
||||
|
||||
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>
|
||||
#
|
||||
# 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) 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
|
||||
# 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) 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
|
||||
# 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();
|
||||
objects.clear();
|
||||
bounds = G3D::AABox::empty();
|
||||
// create space for the first node
|
||||
tree.push_back(3u << 30u); // dummy leaf
|
||||
tree.insert(tree.end(), 2, 0);
|
||||
@@ -116,6 +117,7 @@ public:
|
||||
delete[] dat.indices;
|
||||
}
|
||||
[[nodiscard]] uint32 primCount() const { return objects.size(); }
|
||||
G3D::AABox const& bound() const { return bounds; }
|
||||
|
||||
template<typename RayCallback>
|
||||
void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const
|
||||
|
||||
@@ -170,25 +170,6 @@ private:
|
||||
VMAP::ModelIgnoreFlags _ignoreFlags;
|
||||
};
|
||||
|
||||
struct DynamicTreeAreaInfoCallback
|
||||
{
|
||||
DynamicTreeAreaInfoCallback(uint32 phaseMask) : _phaseMask(phaseMask) { }
|
||||
|
||||
void operator()(G3D::Vector3 const& p, GameObjectModel const& obj)
|
||||
{
|
||||
obj.IntersectPoint(p, _areaInfo, _phaseMask);
|
||||
}
|
||||
|
||||
VMAP::AreaInfo const& GetAreaInfo() const
|
||||
{
|
||||
return _areaInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _phaseMask;
|
||||
VMAP::AreaInfo _areaInfo;
|
||||
};
|
||||
|
||||
struct DynamicTreeLocationInfoCallback
|
||||
{
|
||||
DynamicTreeLocationInfoCallback(uint32 phaseMask)
|
||||
@@ -308,24 +289,7 @@ float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist,
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicMapTree::GetAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
|
||||
{
|
||||
G3D::Vector3 v(x, y, z + 0.5f);
|
||||
DynamicTreeAreaInfoCallback intersectionCallBack(phasemask);
|
||||
impl->intersectPoint(v, intersectionCallBack);
|
||||
if (intersectionCallBack.GetAreaInfo().result)
|
||||
{
|
||||
flags = intersectionCallBack.GetAreaInfo().flags;
|
||||
adtId = intersectionCallBack.GetAreaInfo().adtId;
|
||||
rootId = intersectionCallBack.GetAreaInfo().rootId;
|
||||
groupId = intersectionCallBack.GetAreaInfo().groupId;
|
||||
z = intersectionCallBack.GetAreaInfo().ground_Z;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const
|
||||
bool DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional<uint8> reqLiquidType, VMAP::AreaAndLiquidData& data) const
|
||||
{
|
||||
G3D::Vector3 v(x, y, z + 0.5f);
|
||||
DynamicTreeLocationInfoCallback intersectionCallBack(phasemask);
|
||||
@@ -335,13 +299,16 @@ void DynamicMapTree::GetAreaAndLiquidData(float x, float y, float z, uint32 phas
|
||||
data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
|
||||
uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType();
|
||||
float liquidLevel;
|
||||
if (!reqLiquidType || (dynamic_cast<VMAP::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))
|
||||
data.liquidInfo.emplace(liquidType, liquidLevel);
|
||||
|
||||
data.areaInfo.emplace(0,
|
||||
data.areaInfo.emplace(intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
|
||||
0,
|
||||
intersectionCallBack.GetLocationInfo().rootId,
|
||||
intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
|
||||
intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags());
|
||||
intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags(),
|
||||
0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define _DYNTREE_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "Optional.h"
|
||||
|
||||
namespace G3D
|
||||
{
|
||||
@@ -47,8 +48,7 @@ public:
|
||||
|
||||
bool GetIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const G3D::Vector3& endPos, float& maxDist) const;
|
||||
|
||||
bool GetAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
|
||||
void GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const;
|
||||
bool GetAreaAndLiquidData(float x, float y, float z, uint32 phasemask, Optional<uint8> reqLiquidType, VMAP::AreaAndLiquidData& data) const;
|
||||
|
||||
bool GetObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1,
|
||||
const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos,
|
||||
|
||||
@@ -52,20 +52,23 @@ namespace VMAP
|
||||
{
|
||||
struct AreaInfo
|
||||
{
|
||||
AreaInfo(int32 _adtId, int32 _rootId, int32 _groupId, uint32 _flags)
|
||||
: adtId(_adtId), rootId(_rootId), groupId(_groupId), mogpFlags(_flags) { }
|
||||
int32 const adtId;
|
||||
int32 const rootId;
|
||||
int32 const groupId;
|
||||
uint32 const mogpFlags;
|
||||
AreaInfo() = default;
|
||||
AreaInfo(int32 _groupId, int32 _adtId, int32 _rootId, uint32 _mogpFlags, uint32 _uniqueId)
|
||||
: groupId(_groupId), adtId(_adtId), rootId(_rootId), mogpFlags(_mogpFlags), uniqueId(_uniqueId) { }
|
||||
int32 groupId = 0;
|
||||
int32 adtId = 0;
|
||||
int32 rootId = 0;
|
||||
uint32 mogpFlags = 0;
|
||||
uint32 uniqueId = 0;
|
||||
};
|
||||
|
||||
struct LiquidInfo
|
||||
{
|
||||
LiquidInfo() = default;
|
||||
LiquidInfo(uint32 _type, float _level)
|
||||
: type(_type), level(_level) {}
|
||||
uint32 const type;
|
||||
float const level;
|
||||
uint32 type = 0;
|
||||
float level = 0.0f;
|
||||
};
|
||||
|
||||
float floorZ = VMAP_INVALID_HEIGHT;
|
||||
@@ -120,14 +123,12 @@ namespace VMAP
|
||||
[[nodiscard]] bool isMapLoadingEnabled() const { return (iEnableLineOfSightCalc || iEnableHeightCalc ); }
|
||||
|
||||
[[nodiscard]] virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0;
|
||||
|
||||
/**
|
||||
Query world model area info.
|
||||
\param z gets adjusted to the ground height for which this are info is valid
|
||||
*/
|
||||
virtual bool GetAreaInfo(uint32 pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0;
|
||||
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const = 0;
|
||||
// get both area + liquid data in a single vmap lookup
|
||||
virtual void GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const = 0;
|
||||
virtual bool GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -138,8 +138,7 @@ namespace MMAP
|
||||
uint32 packedGridPos = packTileID(x, y);
|
||||
if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
|
||||
{
|
||||
// Peiru: Commented out for now because Playerbots system uses this method to load or check loaded maps and will spam logs
|
||||
// LOG_ERROR("maps", "MMAP:loadMap: Asked to load already loaded navmesh tile. {:03}{:02}{:02}.mmtile", mapId, x, y);
|
||||
LOG_ERROR("maps", "MMAP:loadMap: Asked to load already loaded navmesh tile. {:03}{:02}{:02}.mmtile", mapId, x, y);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -253,70 +253,8 @@ namespace VMAP
|
||||
return VMAP_INVALID_HEIGHT_VALUE;
|
||||
}
|
||||
|
||||
bool VMapMgr2::GetAreaInfo(uint32 mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
|
||||
bool VMapMgr2::GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<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);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
@@ -325,16 +263,22 @@ namespace VMAP
|
||||
if (instanceTree->second->GetLocationInfo(pos, info))
|
||||
{
|
||||
data.floorZ = info.ground_Z;
|
||||
uint32 liquidType = info.hitModel->GetLiquidType();
|
||||
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
|
||||
{
|
||||
uint32 liquidType = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
|
||||
float liquidLevel;
|
||||
if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & reqLiquidType))
|
||||
if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & *reqLiquidType))
|
||||
if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel))
|
||||
data.liquidInfo.emplace(liquidType, liquidLevel);
|
||||
}
|
||||
|
||||
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
|
||||
data.areaInfo.emplace(info.hitInstance->adtId, info.rootId, info.hitModel->GetWmoID(), info.hitModel->GetMogpFlags());
|
||||
data.areaInfo.emplace(info.hitModel->GetWmoID(), info.hitInstance->adtId, info.rootId, info.hitModel->GetMogpFlags(), info.hitInstance->ID);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
WorldModel* VMapMgr2::acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags/* Only used when creating the model */)
|
||||
|
||||
@@ -115,9 +115,7 @@ namespace VMAP
|
||||
|
||||
bool processCommand(char* /*command*/) override { return false; } // for debug and extensions
|
||||
|
||||
bool GetAreaInfo(uint32 pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override;
|
||||
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type, uint32& mogpFlags) const override;
|
||||
void GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const override;
|
||||
bool GetAreaAndLiquidData(uint32 mapId, float x, float y, float z, Optional<uint8> reqLiquidType, AreaAndLiquidData& data) const override;
|
||||
|
||||
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags);
|
||||
void releaseModelInstance(const std::string& filename);
|
||||
|
||||
@@ -51,22 +51,6 @@ namespace VMAP
|
||||
bool hit;
|
||||
};
|
||||
|
||||
class AreaInfoCallback
|
||||
{
|
||||
public:
|
||||
AreaInfoCallback(ModelInstance* val): prims(val) {}
|
||||
void operator()(const Vector3& point, uint32 entry)
|
||||
{
|
||||
#if defined(VMAP_DEBUG)
|
||||
LOG_DEBUG("maps", "AreaInfoCallback: trying to intersect '{}'", prims[entry].name);
|
||||
#endif
|
||||
prims[entry].intersectPoint(point, aInfo);
|
||||
}
|
||||
|
||||
ModelInstance* prims;
|
||||
AreaInfo aInfo;
|
||||
};
|
||||
|
||||
class LocationInfoCallback
|
||||
{
|
||||
public:
|
||||
@@ -99,22 +83,6 @@ namespace VMAP
|
||||
return tilefilename.str();
|
||||
}
|
||||
|
||||
bool StaticMapTree::GetAreaInfo(Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
|
||||
{
|
||||
AreaInfoCallback intersectionCallBack(iTreeValues);
|
||||
iTree.intersectPoint(pos, intersectionCallBack);
|
||||
if (intersectionCallBack.aInfo.result)
|
||||
{
|
||||
flags = intersectionCallBack.aInfo.flags;
|
||||
adtId = intersectionCallBack.aInfo.adtId;
|
||||
rootId = intersectionCallBack.aInfo.rootId;
|
||||
groupId = intersectionCallBack.aInfo.groupId;
|
||||
pos.z = intersectionCallBack.aInfo.ground_Z;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StaticMapTree::GetLocationInfo(const Vector3& pos, LocationInfo& info) const
|
||||
{
|
||||
LocationInfoCallback intersectionCallBack(iTreeValues, info);
|
||||
|
||||
@@ -30,6 +30,12 @@ namespace VMAP
|
||||
enum class ModelIgnoreFlags : uint32;
|
||||
enum class LoadResult : uint8;
|
||||
|
||||
struct GroupLocationInfo
|
||||
{
|
||||
const GroupModel* hitModel = nullptr;
|
||||
int32 rootId = -1;
|
||||
};
|
||||
|
||||
struct LocationInfo
|
||||
{
|
||||
LocationInfo(): ground_Z(-G3D::inf()) { }
|
||||
@@ -73,7 +79,6 @@ namespace VMAP
|
||||
[[nodiscard]] bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2, ModelIgnoreFlags ignoreFlags) const;
|
||||
bool GetObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
|
||||
[[nodiscard]] float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const;
|
||||
bool GetAreaInfo(G3D::Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
|
||||
bool GetLocationInfo(const G3D::Vector3& pos, LocationInfo& info) const;
|
||||
|
||||
bool InitMap(const std::string& fname, VMapMgr2* vm);
|
||||
|
||||
@@ -203,27 +203,6 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
|
||||
return hit;
|
||||
}
|
||||
|
||||
void GameObjectModel::IntersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const
|
||||
{
|
||||
if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject())
|
||||
return;
|
||||
|
||||
if (!iBound.contains(point))
|
||||
return;
|
||||
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (iModel->IntersectPoint(pModel, zDirModel, zDist, info))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
if (info.ground_Z < world_Z)
|
||||
info.ground_Z = world_Z;
|
||||
}
|
||||
}
|
||||
|
||||
bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const
|
||||
{
|
||||
if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject())
|
||||
@@ -236,7 +215,9 @@ bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationI
|
||||
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
|
||||
|
||||
VMAP::GroupLocationInfo groupInfo;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
|
||||
@@ -70,7 +70,6 @@ public:
|
||||
[[nodiscard]] bool IsMapObject() const { return isWmo; }
|
||||
|
||||
bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
||||
void IntersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const;
|
||||
bool GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const;
|
||||
bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const;
|
||||
|
||||
|
||||
@@ -63,44 +63,6 @@ namespace VMAP
|
||||
return hit;
|
||||
}
|
||||
|
||||
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo& info) const
|
||||
{
|
||||
if (!iModel)
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
std::cout << "<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
|
||||
{
|
||||
if (!iModel)
|
||||
@@ -124,7 +86,9 @@ namespace VMAP
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
|
||||
|
||||
GroupLocationInfo groupInfo;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, groupInfo))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
// Transform back to world space. Note that:
|
||||
@@ -133,6 +97,8 @@ namespace VMAP
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
|
||||
{
|
||||
info.rootId = groupInfo.rootId;
|
||||
info.hitModel = groupInfo.hitModel;
|
||||
info.ground_Z = world_Z;
|
||||
info.hitInstance = this;
|
||||
return true;
|
||||
|
||||
@@ -66,7 +66,6 @@ namespace VMAP
|
||||
ModelInstance(const ModelSpawn& spawn, WorldModel* model);
|
||||
void setUnloaded() { iModel = nullptr; }
|
||||
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit, ModelIgnoreFlags ignoreFlags) const;
|
||||
void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const;
|
||||
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const;
|
||||
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const;
|
||||
WorldModel* getWorldModel() { return iModel; }
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#include "ModelIgnoreFlags.h"
|
||||
#include "ModelInstance.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include <array>
|
||||
|
||||
using G3D::Vector3;
|
||||
using G3D::Ray;
|
||||
|
||||
template<> struct BoundsTrait<VMAP::GroupModel>
|
||||
{
|
||||
@@ -451,21 +451,46 @@ namespace VMAP
|
||||
return callback.hit;
|
||||
}
|
||||
|
||||
bool GroupModel::IsInsideObject(const Vector3& pos, const Vector3& down, float& z_dist) const
|
||||
inline bool IsInsideOrAboveBound(G3D::AABox const& bounds, const G3D::Point3& point)
|
||||
{
|
||||
if (triangles.empty() || !iBound.contains(pos))
|
||||
{
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
Vector3 rPos = pos - 0.1f * down;
|
||||
float dist = G3D::inf();
|
||||
G3D::Ray ray(rPos, down);
|
||||
bool hit = IntersectRay(ray, dist, false);
|
||||
if (hit)
|
||||
|
||||
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)
|
||||
{
|
||||
float dist = G3D::finf();
|
||||
if (IntersectRay(ray, dist, false))
|
||||
{
|
||||
z_dist = dist - 0.1f;
|
||||
return INSIDE;
|
||||
}
|
||||
return hit;
|
||||
if (meshTree.bound().contains(ray.origin()))
|
||||
return MAYBE_INSIDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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 OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const
|
||||
@@ -541,76 +566,58 @@ namespace VMAP
|
||||
class WModelAreaCallback
|
||||
{
|
||||
public:
|
||||
WModelAreaCallback(const std::vector<GroupModel>& vals, const Vector3& down):
|
||||
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { }
|
||||
std::vector<GroupModel>::const_iterator prims;
|
||||
std::vector<GroupModel>::const_iterator hit;
|
||||
float minVol;
|
||||
float zDist;
|
||||
Vector3 zVec;
|
||||
void operator()(const Vector3& point, uint32 entry)
|
||||
WModelAreaCallback(std::vector<GroupModel> const& vals) :
|
||||
prims(vals), hit() { }
|
||||
std::vector<GroupModel> const& prims;
|
||||
std::array<GroupModel const*, 3> hit;
|
||||
bool operator()(G3D::Ray const& ray, uint32 entry, float& distance, bool /*stopAtFirstHit*/)
|
||||
{
|
||||
float group_Z;
|
||||
//float pVol = prims[entry].GetBound().volume();
|
||||
//if (pVol < minVol)
|
||||
//{
|
||||
/* if (prims[entry].iBound.contains(point)) */
|
||||
if (prims[entry].IsInsideObject(point, zVec, group_Z))
|
||||
if (GroupModel::InsideResult result = prims[entry].IsInsideObject(ray, group_Z); result != GroupModel::OUT_OF_BOUNDS)
|
||||
{
|
||||
//minVol = pVol;
|
||||
//hit = prims + entry;
|
||||
if (group_Z < zDist)
|
||||
if (result != GroupModel::MAYBE_INSIDE)
|
||||
{
|
||||
zDist = group_Z;
|
||||
hit = prims + entry;
|
||||
if (group_Z < distance)
|
||||
{
|
||||
distance = group_Z;
|
||||
hit[result] = &prims[entry];
|
||||
return true;
|
||||
}
|
||||
#ifdef VMAP_DEBUG
|
||||
const GroupModel& gm = prims[entry];
|
||||
printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
|
||||
gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
|
||||
gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
|
||||
#endif
|
||||
}
|
||||
//}
|
||||
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
|
||||
else
|
||||
hit[result] = &prims[entry];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
bool WorldModel::IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const
|
||||
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const
|
||||
{
|
||||
if (groupModels.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WModelAreaCallback callback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
if (callback.hit != groupModels.end())
|
||||
WModelAreaCallback callback(groupModels);
|
||||
G3D::Ray r(p - down * 0.1f, down);
|
||||
float zDist = groupTree.bound().extent().length();
|
||||
groupTree.intersectRay(r, callback, zDist, false);
|
||||
if (callback.hit[GroupModel::INSIDE])
|
||||
{
|
||||
info.rootId = RootWMOID;
|
||||
info.groupId = callback.hit->GetWmoID();
|
||||
info.flags = callback.hit->GetMogpFlags();
|
||||
info.result = true;
|
||||
dist = callback.zDist;
|
||||
info.hitModel = callback.hit[GroupModel::INSIDE];
|
||||
dist = zDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const
|
||||
{
|
||||
if (groupModels.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WModelAreaCallback callback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
if (callback.hit != groupModels.end())
|
||||
// some group models don't have any floor to intersect with
|
||||
// so we should attempt to intersect with a model part below the group `p` is in (stored in GroupModel::ABOVE)
|
||||
// then find back where we originated from (GroupModel::MAYBE_INSIDE)
|
||||
if (callback.hit[GroupModel::MAYBE_INSIDE] && callback.hit[GroupModel::ABOVE])
|
||||
{
|
||||
info.rootId = RootWMOID;
|
||||
info.hitModel = &(*callback.hit);
|
||||
dist = callback.zDist;
|
||||
info.hitModel = callback.hit[GroupModel::MAYBE_INSIDE];
|
||||
dist = zDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace VMAP
|
||||
class TreeNode;
|
||||
struct AreaInfo;
|
||||
struct LocationInfo;
|
||||
struct GroupLocationInfo;
|
||||
enum class ModelIgnoreFlags : uint32;
|
||||
|
||||
class MeshTriangle
|
||||
@@ -81,12 +82,14 @@ namespace VMAP
|
||||
void setMeshData(std::vector<G3D::Vector3>& vert, std::vector<MeshTriangle>& tri);
|
||||
void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = nullptr; }
|
||||
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const;
|
||||
bool IsInsideObject(const G3D::Vector3& pos, const G3D::Vector3& down, float& z_dist) const;
|
||||
enum InsideResult { INSIDE = 0, MAYBE_INSIDE = 1, ABOVE = 2, OUT_OF_BOUNDS = -1 };
|
||||
InsideResult IsInsideObject(G3D::Ray const& ray, float& z_dist) const;
|
||||
bool GetLiquidLevel(const G3D::Vector3& pos, float& liqHeight) const;
|
||||
[[nodiscard]] uint32 GetLiquidType() const;
|
||||
bool writeToFile(FILE* wf);
|
||||
bool readFromFile(FILE* rf);
|
||||
[[nodiscard]] const G3D::AABox& GetBound() const { return iBound; }
|
||||
[[nodiscard]] G3D::AABox const& GetBound() const { return iBound; }
|
||||
[[nodiscard]] G3D::AABox const& GetMeshTreeBound() const { return meshTree.bound(); }
|
||||
[[nodiscard]] uint32 GetMogpFlags() const { return iMogpFlags; }
|
||||
[[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; }
|
||||
void GetMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid);
|
||||
@@ -109,8 +112,7 @@ namespace VMAP
|
||||
void setGroupModels(std::vector<GroupModel>& models);
|
||||
void setRootWmoID(uint32 id) { RootWMOID = id; }
|
||||
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) const;
|
||||
bool IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const;
|
||||
bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const;
|
||||
bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, GroupLocationInfo& info) const;
|
||||
bool writeFile(const std::string& filename);
|
||||
bool readFile(const std::string& filename);
|
||||
void GetGroupModels(std::vector<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
|
||||
* 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_
|
||||
|
||||
@@ -97,32 +97,6 @@ public:
|
||||
return _eventMap.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current internal time as uint32 milliseconds
|
||||
*
|
||||
* was removed in core https://github.com/azerothcore/azerothcore-wotlk/pull/23121,
|
||||
* but still required atm for mod-playerbot.
|
||||
*/
|
||||
uint32 GetTimer() const
|
||||
{
|
||||
return static_cast<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
|
||||
* @brief Sets the phase of the map (absolute).
|
||||
|
||||
@@ -120,7 +120,7 @@ class EventProcessor
|
||||
[[nodiscard]] uint64 CalculateQueueTime(uint64 delay) const;
|
||||
|
||||
void CancelEventGroup(uint8 group);
|
||||
bool HaveEventList() const { return !m_events.empty(); }
|
||||
bool HasEvents() const { return !m_events.empty(); }
|
||||
|
||||
protected:
|
||||
uint64 m_time{0};
|
||||
|
||||
@@ -347,7 +347,6 @@ inline wchar_t wcharToLower(wchar_t wchar)
|
||||
|
||||
void wstrToUpper(std::wstring& str);
|
||||
void wstrToLower(std::wstring& str);
|
||||
void strToLower(std::string& str);
|
||||
|
||||
std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension);
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() cons
|
||||
// data/sql
|
||||
for (auto const& itr : moduleList)
|
||||
{
|
||||
std::string path = _sourceDirectory->generic_string() + "/modules/" + itr + "/data/sql/" + _dbModuleName; // modules/mod-name/sql/world
|
||||
std::string path = _sourceDirectory->generic_string() + "/modules/" + itr + "/data/sql/" + _dbModuleName; // modules/mod-name/data/sql/db-world
|
||||
|
||||
Path const p(path);
|
||||
if (!is_directory(p))
|
||||
|
||||
@@ -83,29 +83,19 @@ WorldObject* CreatureAI::GetSummoner() const
|
||||
inline bool IsValidCombatTarget(Creature* source, Player* target)
|
||||
{
|
||||
if (target->IsGameMaster())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source->IsInWorld() || !target->IsInWorld())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source->IsAlive() || !target->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source->InSamePhase(target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source->HasUnitState(UNIT_STATE_IN_FLIGHT) || target->HasUnitState(UNIT_STATE_IN_FLIGHT))
|
||||
{
|
||||
if (source->IsInFlight() || target->IsInFlight())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -950,6 +950,9 @@ bool SmartAIMgr::CheckUnusedTargetParams(SmartScriptHolder const& e)
|
||||
case SMART_TARGET_VEHICLE_PASSENGER: return sizeof(SmartTarget::vehicle);
|
||||
// case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: return sizeof(SmartTarget::goClosest);
|
||||
case SMART_TARGET_PLAYER_WITH_AURA: return sizeof(SmartTarget::playerWithAura);
|
||||
case SMART_TARGET_RANDOM_POINT: return sizeof(SmartTarget::randomPoint);
|
||||
case SMART_TARGET_SUMMONED_CREATURES: return sizeof(SmartTarget::summonedCreatures);
|
||||
case SMART_TARGET_INSTANCE_STORAGE: return sizeof(SmartTarget::instanceStorage);
|
||||
default:
|
||||
LOG_WARN("sql.sql", "SmartAIMgr: entryorguid {} source_type {} id {} action_type {} is using a target {} with no unused params specified in SmartAIMgr::CheckUnusedTargetParams(), please report this.",
|
||||
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.GetTargetType());
|
||||
|
||||
@@ -1826,6 +1826,15 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
|
||||
// someone on this realm has already completed that achievement
|
||||
if (sAchievementMgr->IsRealmCompleted(achievement))
|
||||
return false;
|
||||
|
||||
// A character may only have 1 race-specific 'Realm First!' achievement
|
||||
// prevent clever use of the race/faction change service to obtain multiple 'Realm First!' achievements
|
||||
constexpr std::array<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)
|
||||
|
||||
@@ -33,17 +33,6 @@ class WorldObject;
|
||||
|
||||
struct GameTele;
|
||||
|
||||
enum PlayerChatTag
|
||||
{
|
||||
CHAT_TAG_NONE = 0x00,
|
||||
CHAT_TAG_AFK = 0x01,
|
||||
CHAT_TAG_DND = 0x02,
|
||||
CHAT_TAG_GM = 0x04,
|
||||
CHAT_TAG_COM = 0x08, // Commentator
|
||||
CHAT_TAG_DEV = 0x10, // Developer
|
||||
};
|
||||
typedef uint32 ChatTagFlags;
|
||||
|
||||
class AC_GAME_API ChatHandler
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -92,27 +92,13 @@ private:
|
||||
};
|
||||
ThreatMgr* iThreatMgr;
|
||||
public:
|
||||
ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iFValue(0.f), iThreatMgr(nullptr)
|
||||
{
|
||||
iHostileReference = nullptr;
|
||||
}
|
||||
ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = nullptr; }
|
||||
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iFValue(0.f), iThreatMgr(nullptr)
|
||||
{
|
||||
iHostileReference = pHostileReference;
|
||||
}
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; }
|
||||
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr)
|
||||
{
|
||||
iHostileReference = pHostileReference;
|
||||
iFValue = pValue;
|
||||
}
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; iFValue = pValue; }
|
||||
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr)
|
||||
{
|
||||
iHostileReference = pHostileReference;
|
||||
iBValue = pValue;
|
||||
}
|
||||
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatMgr(nullptr) { iHostileReference = pHostileReference; iBValue = pValue; }
|
||||
|
||||
[[nodiscard]] int32 getIValue() const { return iIValue; }
|
||||
|
||||
|
||||
@@ -1373,8 +1373,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
m_spawnId = sObjectMgr->GenerateCreatureSpawnId();
|
||||
|
||||
CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId);
|
||||
data.spawnId = m_spawnId;
|
||||
|
||||
data.spawnId = m_spawnId; // mod_playerbots
|
||||
uint32 displayId = GetNativeDisplayId();
|
||||
uint32 npcflag = GetNpcFlags();
|
||||
uint32 unit_flags = GetUnitFlags();
|
||||
@@ -3498,7 +3497,7 @@ bool Creature::IsMovementPreventedByCasting() const
|
||||
void Creature::SetCannotReachTarget(ObjectGuid const& cannotReach)
|
||||
{
|
||||
if (cannotReach == m_cannotReachTarget)
|
||||
{
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> EquipmentInfo
|
||||
struct CreatureData
|
||||
{
|
||||
CreatureData() = default;
|
||||
ObjectGuid::LowType spawnId{0};
|
||||
ObjectGuid::LowType spawnId{ 0 }; // mod_playerbots
|
||||
uint32 id1{0}; // entry in creature_template
|
||||
uint32 id2{0}; // entry in creature_template
|
||||
uint32 id3{0}; // entry in creature_template
|
||||
|
||||
@@ -3294,9 +3294,7 @@ void Player::learnSpell(uint32 spellId, bool temporary /*= false*/, bool learnFr
|
||||
// Xinef: don't allow to learn active spell once more
|
||||
if (HasActiveSpell(spellId))
|
||||
{
|
||||
#ifndef MOD_PLAYERBOTS
|
||||
LOG_DEBUG("entities.player", "Player ({}) tries to learn already active spell: {}", GetGUID().ToString(), spellId);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4332,28 +4330,6 @@ void Player::DeleteOldRecoveryItems(uint32 keepDays)
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SetMovement(PlayerMovementType pType)
|
||||
{
|
||||
WorldPacket data;
|
||||
const PackedGuid& guid = GetPackGUID();
|
||||
switch (pType)
|
||||
{
|
||||
case MOVE_WATER_WALK:
|
||||
data.Initialize(SMSG_MOVE_WATER_WALK, guid.size() + 4);
|
||||
break;
|
||||
case MOVE_LAND_WALK:
|
||||
data.Initialize(SMSG_MOVE_LAND_WALK, guid.size() + 4);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("entities.player", "Player::SetMovement: Unsupported move type ({}), data not sent to client.", pType);
|
||||
return;
|
||||
}
|
||||
data << guid;
|
||||
data << GetSession()->GetOrderCounter(); // movement counter
|
||||
SendDirectMessage(&data);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
/* Preconditions:
|
||||
- a resurrectable corpse must not be loaded for the player (only bones)
|
||||
- the player must be in world
|
||||
@@ -4389,7 +4365,6 @@ void Player::BuildPlayerRepop()
|
||||
}
|
||||
GetMap()->AddToMap(corpse);
|
||||
SetHealth(1); // convert player body to ghost
|
||||
SetMovement(MOVE_WATER_WALK);
|
||||
SetWaterWalking(true);
|
||||
|
||||
if (!IsImmobilizedState())
|
||||
@@ -4430,7 +4405,6 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
||||
SetDynamicFlag(UNIT_DYNFLAG_REFER_A_FRIEND);
|
||||
|
||||
setDeathState(DeathState::Alive);
|
||||
SetMovement(MOVE_LAND_WALK);
|
||||
SendMoveRoot(false);
|
||||
SetWaterWalking(false);
|
||||
m_deathTimer = 0;
|
||||
@@ -9390,11 +9364,7 @@ void Player::Say(std::string_view text, Language language, WorldObject const* /*
|
||||
{
|
||||
std::string _text(text);
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_SAY, language, _text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text);
|
||||
@@ -9416,11 +9386,7 @@ void Player::Yell(std::string_view text, Language language, WorldObject const* /
|
||||
std::string _text(text);
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_YELL, language, _text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text);
|
||||
@@ -9442,11 +9408,7 @@ void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/,
|
||||
std::string _text(text);
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
|
||||
@@ -9475,11 +9437,7 @@ void Player::Whisper(std::string_view text, Language language, Player* target, b
|
||||
std::string _text(text);
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(this, CHAT_MSG_WHISPER, language, _text, target))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, language, this, this, _text);
|
||||
@@ -11686,7 +11644,7 @@ void Player::SendInitialPacketsAfterAddToMap()
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
if (HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
if (HasAuraType(SPELL_AURA_WATER_WALK) || HasAura(8326))
|
||||
{
|
||||
uint32 const counter = GetSession()->GetOrderCounter();
|
||||
setCompoundState << uint8(2 + GetPackGUID().size() + 4);
|
||||
@@ -12096,18 +12054,6 @@ void Player::GetAurasForTarget(Unit* target, bool force /*= false*/)
|
||||
if (!target || (!force && target->GetVisibleAuras()->empty())) // speedup things
|
||||
return;
|
||||
|
||||
/*! Blizz sends certain movement packets sometimes even before CreateObject
|
||||
These movement packets are usually found in SMSG_COMPRESSED_MOVES
|
||||
*/
|
||||
if (target->HasFeatherFallAura())
|
||||
target->SendMovementFeatherFall(this);
|
||||
|
||||
if (target->HasWaterWalkAura())
|
||||
target->SendMovementWaterWalking(this);
|
||||
|
||||
if (target->HasHoverAura())
|
||||
target->SendMovementHover(this);
|
||||
|
||||
WorldPacket data(SMSG_AURA_UPDATE_ALL);
|
||||
data<< target->GetPackGUID();
|
||||
|
||||
|
||||
@@ -827,6 +827,16 @@ enum EnviromentalDamage
|
||||
DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss
|
||||
};
|
||||
|
||||
enum PlayerChatTag
|
||||
{
|
||||
CHAT_TAG_NONE = 0x00,
|
||||
CHAT_TAG_AFK = 0x01,
|
||||
CHAT_TAG_DND = 0x02,
|
||||
CHAT_TAG_GM = 0x04,
|
||||
CHAT_TAG_COM = 0x08, // Commentator tag. Do not exist in clean client
|
||||
CHAT_TAG_DEV = 0x10,
|
||||
};
|
||||
|
||||
enum PlayedTimeIndex
|
||||
{
|
||||
PLAYED_TIME_TOTAL = 0,
|
||||
|
||||
@@ -1463,6 +1463,9 @@ void Player::UpdatePvPState()
|
||||
|
||||
if (pvpInfo.IsHostile) // in hostile area
|
||||
{
|
||||
if (IsInFlight()) // on taxi
|
||||
return;
|
||||
|
||||
if (!IsPvP() || pvpInfo.EndTimer != 0)
|
||||
UpdatePvP(true, true);
|
||||
}
|
||||
|
||||
@@ -1864,7 +1864,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
||||
|
||||
auto canTakeMeleeDamage = [&]()
|
||||
{
|
||||
return victim->IsAlive() && !victim->HasUnitState(UNIT_STATE_IN_FLIGHT) && (!victim->IsCreature() || !victim->ToCreature()->IsEvadingAttacks());
|
||||
return victim->IsAlive() && !victim->IsInFlight() && (!victim->IsCreature() || !victim->ToCreature()->IsEvadingAttacks());
|
||||
};
|
||||
|
||||
if (!canTakeMeleeDamage())
|
||||
@@ -1956,10 +1956,11 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
||||
Probability = 0.65f * victim->GetLevel() + 0.5f;
|
||||
|
||||
uint32 VictimDefense = victim->GetDefenseSkillValue();
|
||||
uint32 VictimAuraDefense = -victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE) * 25;
|
||||
uint32 AttackerMeleeSkill = GetUnitMeleeSkill();
|
||||
|
||||
// xinef: fix daze mechanics
|
||||
Probability -= ((float)VictimDefense - AttackerMeleeSkill) * 0.1428f;
|
||||
Probability -= ((float)VictimDefense + (float)VictimAuraDefense - AttackerMeleeSkill) * 0.1428f;
|
||||
|
||||
if (Probability > 40.0f)
|
||||
Probability = 40.0f;
|
||||
@@ -18429,10 +18430,8 @@ void Unit::SetControlled(bool apply, UnitState state, Unit* source /*= nullptr*/
|
||||
|
||||
void Unit::SetStunned(bool apply)
|
||||
{
|
||||
if (HasUnitState(UNIT_STATE_IN_FLIGHT))
|
||||
{
|
||||
if (IsInFlight())
|
||||
return;
|
||||
}
|
||||
|
||||
if (apply)
|
||||
{
|
||||
@@ -21520,18 +21519,3 @@ Player const* Unit::GetClientControlling() const
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Unit::SetCannotReachTargetUnit(bool cannotReach, bool isChase)
|
||||
{
|
||||
if (cannotReach == m_cannotReachTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_cannotReachTarget = cannotReach;
|
||||
}
|
||||
|
||||
bool Unit::CanNotReachTarget() const
|
||||
{
|
||||
return m_cannotReachTarget;
|
||||
}
|
||||
|
||||
@@ -2051,8 +2051,6 @@ public:
|
||||
// Debug
|
||||
void OutDebugInfo() const;
|
||||
std::string GetDebugInfo() const override;
|
||||
void SetCannotReachTargetUnit(bool target, bool isChase);
|
||||
[[nodiscard]] bool CanNotReachTarget() const;
|
||||
|
||||
bool m_cannotReachTarget;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ enum VehicleFlags
|
||||
VEHICLE_FLAG_CUSTOM_PITCH = 0x00000040, // If set use pitchMin and pitchMax from DBC, otherwise pitchMin = -pi/2, pitchMax = pi/2
|
||||
VEHICLE_FLAG_ADJUST_AIM_ANGLE = 0x00000400, // Lua_IsVehicleAimAngleAdjustable
|
||||
VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800, // Lua_IsVehicleAimPowerAdjustable
|
||||
VEHICLE_FLAG_FIXED_POSITION = 0x00200000 // Used for cannons, when they should be rooted
|
||||
VEHICLE_FLAG_FIXED_POSITION = 0x00200000 // Used for cannons, when they should be rooted (mod_playerbots, not sure this is still valid since its only used my playerbot)
|
||||
};
|
||||
|
||||
enum VehicleSpells
|
||||
|
||||
@@ -527,9 +527,11 @@ float GridTerrainData::getLiquidLevel(float x, float y) const
|
||||
}
|
||||
|
||||
// Get water state on map
|
||||
LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float collisionHeight, uint8 ReqLiquidType) const
|
||||
LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float collisionHeight, Optional<uint8> ReqLiquidType) const
|
||||
{
|
||||
LiquidData liquidData;
|
||||
liquidData.Status = LIQUID_MAP_NO_WATER;
|
||||
|
||||
if (!_loadedLiquidData)
|
||||
return liquidData;
|
||||
|
||||
@@ -575,7 +577,7 @@ LiquidData const GridTerrainData::GetLiquidData(float x, float y, float z, float
|
||||
}
|
||||
|
||||
// Check req liquid type mask
|
||||
if (type != 0 && (!ReqLiquidType || (ReqLiquidType & type) != 0))
|
||||
if (type != 0 && (!ReqLiquidType || (*ReqLiquidType & type) != 0))
|
||||
{
|
||||
// Check water level:
|
||||
// Check water height map
|
||||
|
||||
@@ -186,7 +186,7 @@ struct LoadedHoleData
|
||||
HolesType holes;
|
||||
};
|
||||
|
||||
enum LiquidStatus
|
||||
enum LiquidStatus : uint32
|
||||
{
|
||||
LIQUID_MAP_NO_WATER = 0x00000000,
|
||||
LIQUID_MAP_ABOVE_WATER = 0x00000001,
|
||||
@@ -249,7 +249,7 @@ public:
|
||||
inline float getHeight(float x, float y) const { return (this->*_gridGetHeight)(x, y); }
|
||||
float getMinHeight(float x, float y) const;
|
||||
float getLiquidLevel(float x, float y) const;
|
||||
LiquidData const GetLiquidData(float x, float y, float z, float collisionHeight, uint8 ReqLiquidType) const;
|
||||
LiquidData const GetLiquidData(float x, float y, float z, float collisionHeight, Optional<uint8> ReqLiquidType) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -262,6 +262,7 @@ public:
|
||||
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag);
|
||||
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag);
|
||||
|
||||
//mod_playerbots
|
||||
ObjectGuid const GetTargetIcon(uint8 id) const { return m_targetIcons[id]; }
|
||||
|
||||
Difficulty GetDifficulty(bool isRaid) const;
|
||||
|
||||
@@ -135,7 +135,8 @@ void Guild::SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode
|
||||
template <typename Entry>
|
||||
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))
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Entry> template <typename... Ts>
|
||||
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) :
|
||||
m_guildId(guildId), m_guid(guid), m_timestamp(GameTime::GetGameTime().count()) { }
|
||||
m_guildId(guildId), m_guid(guid), m_timestamp(GameTime::GetGameTime().count()) {
|
||||
}
|
||||
|
||||
// EventLogEntry
|
||||
void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const
|
||||
@@ -185,12 +187,12 @@ void Guild::EventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) const
|
||||
|
||||
uint8 index = 0;
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_EVENTLOG);
|
||||
stmt->SetData( index, m_guildId);
|
||||
stmt->SetData(index, m_guildId);
|
||||
stmt->SetData(++index, m_guid);
|
||||
stmt->SetData (++index, uint8(m_eventType));
|
||||
stmt->SetData(++index, uint8(m_eventType));
|
||||
stmt->SetData(++index, m_playerGuid1.GetCounter());
|
||||
stmt->SetData(++index, m_playerGuid2.GetCounter());
|
||||
stmt->SetData (++index, m_newRank);
|
||||
stmt->SetData(++index, m_newRank);
|
||||
stmt->SetData(++index, m_timestamp);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
@@ -215,21 +217,21 @@ void Guild::BankEventLogEntry::SaveToDB(CharacterDatabaseTransaction trans) cons
|
||||
uint8 index = 0;
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_EVENTLOG);
|
||||
stmt->SetData( index, m_guildId);
|
||||
stmt->SetData(index, m_guildId);
|
||||
stmt->SetData(++index, m_guid);
|
||||
stmt->SetData (++index, m_bankTabId);
|
||||
stmt->SetData(++index, m_bankTabId);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
|
||||
index = 0;
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_EVENTLOG);
|
||||
stmt->SetData( index, m_guildId);
|
||||
stmt->SetData(index, m_guildId);
|
||||
stmt->SetData(++index, m_guid);
|
||||
stmt->SetData (++index, m_bankTabId);
|
||||
stmt->SetData (++index, uint8(m_eventType));
|
||||
stmt->SetData(++index, m_bankTabId);
|
||||
stmt->SetData(++index, uint8(m_eventType));
|
||||
stmt->SetData(++index, m_playerGuid.GetCounter());
|
||||
stmt->SetData(++index, m_itemOrMoney);
|
||||
stmt->SetData(++index, m_itemStackCount);
|
||||
stmt->SetData (++index, m_destTabId);
|
||||
stmt->SetData(++index, m_destTabId);
|
||||
stmt->SetData(++index, m_timestamp);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
}
|
||||
@@ -276,7 +278,7 @@ void Guild::RankInfo::SaveToDB(CharacterDatabaseTransaction trans) const
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_RANK);
|
||||
stmt->SetData(0, m_guildId);
|
||||
stmt->SetData (1, m_rankId);
|
||||
stmt->SetData(1, m_rankId);
|
||||
stmt->SetData(2, m_name);
|
||||
stmt->SetData(3, m_rights);
|
||||
stmt->SetData(4, m_bankMoneyPerDay);
|
||||
@@ -317,7 +319,7 @@ void Guild::RankInfo::SetName(std::string_view name)
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_NAME);
|
||||
stmt->SetData(0, m_name);
|
||||
stmt->SetData (1, m_rankId);
|
||||
stmt->SetData(1, m_rankId);
|
||||
stmt->SetData(2, m_guildId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
@@ -334,7 +336,7 @@ void Guild::RankInfo::SetRights(uint32 rights)
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_RIGHTS);
|
||||
stmt->SetData(0, m_rights);
|
||||
stmt->SetData (1, m_rankId);
|
||||
stmt->SetData(1, m_rankId);
|
||||
stmt->SetData(2, m_guildId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
@@ -351,7 +353,7 @@ void Guild::RankInfo::SetBankMoneyPerDay(uint32 money)
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY);
|
||||
stmt->SetData(0, money);
|
||||
stmt->SetData (1, m_rankId);
|
||||
stmt->SetData(1, m_rankId);
|
||||
stmt->SetData(2, m_guildId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
@@ -368,9 +370,9 @@ void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAnd
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_RIGHT);
|
||||
stmt->SetData(0, m_guildId);
|
||||
stmt->SetData (1, guildBR.GetTabId());
|
||||
stmt->SetData (2, m_rankId);
|
||||
stmt->SetData (3, guildBR.GetRights());
|
||||
stmt->SetData(1, guildBR.GetTabId());
|
||||
stmt->SetData(2, m_rankId);
|
||||
stmt->SetData(3, guildBR.GetRights());
|
||||
stmt->SetData(4, guildBR.GetSlots());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
@@ -409,8 +411,8 @@ bool Guild::BankTab::LoadItemFromDB(Field* fields)
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM);
|
||||
stmt->SetData(0, m_guildId);
|
||||
stmt->SetData (1, m_tabId);
|
||||
stmt->SetData (2, slotId);
|
||||
stmt->SetData(1, m_tabId);
|
||||
stmt->SetData(2, slotId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
delete pItem;
|
||||
@@ -448,7 +450,7 @@ void Guild::BankTab::SetInfo(std::string_view name, std::string_view icon)
|
||||
stmt->SetData(0, m_name);
|
||||
stmt->SetData(1, m_icon);
|
||||
stmt->SetData(2, m_guildId);
|
||||
stmt->SetData (3, m_tabId);
|
||||
stmt->SetData(3, m_tabId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
@@ -463,7 +465,7 @@ void Guild::BankTab::SetText(std::string_view text)
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_BANK_TAB_TEXT);
|
||||
stmt->SetData(0, m_text);
|
||||
stmt->SetData(1, m_guildId);
|
||||
stmt->SetData (2, m_tabId);
|
||||
stmt->SetData(2, m_tabId);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
|
||||
@@ -478,16 +480,16 @@ bool Guild::BankTab::SetItem(CharacterDatabaseTransaction trans, uint8 slotId, I
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_ITEM);
|
||||
stmt->SetData(0, m_guildId);
|
||||
stmt->SetData (1, m_tabId);
|
||||
stmt->SetData (2, slotId);
|
||||
stmt->SetData(1, m_tabId);
|
||||
stmt->SetData(2, slotId);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
|
||||
if (item)
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_ITEM);
|
||||
stmt->SetData(0, m_guildId);
|
||||
stmt->SetData (1, m_tabId);
|
||||
stmt->SetData (2, slotId);
|
||||
stmt->SetData(1, m_tabId);
|
||||
stmt->SetData(2, slotId);
|
||||
stmt->SetData(3, item->GetGUID().GetCounter());
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
|
||||
@@ -574,7 +576,7 @@ void Guild::Member::ChangeRank(uint8 newRank)
|
||||
player->SetRank(newRank);
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_MEMBER_RANK);
|
||||
stmt->SetData (0, newRank);
|
||||
stmt->SetData(0, newRank);
|
||||
stmt->SetData(1, m_guid.GetCounter());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
@@ -589,7 +591,7 @@ void Guild::Member::SaveToDB(CharacterDatabaseTransaction trans) const
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_MEMBER);
|
||||
stmt->SetData(0, m_guildId);
|
||||
stmt->SetData(1, m_guid.GetCounter());
|
||||
stmt->SetData (2, m_rankId);
|
||||
stmt->SetData(2, m_rankId);
|
||||
stmt->SetData(3, m_publicNote);
|
||||
stmt->SetData(4, m_officerNote);
|
||||
CharacterDatabase.ExecuteOrAppend(trans, stmt);
|
||||
@@ -1031,7 +1033,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
|
||||
}
|
||||
|
||||
// Guild
|
||||
Guild::Guild():
|
||||
Guild::Guild() :
|
||||
m_id(0),
|
||||
m_createdDate(0),
|
||||
m_accountsNumber(0),
|
||||
@@ -1075,7 +1077,7 @@ bool Guild::Create(Player* pLeader, std::string_view name)
|
||||
|
||||
uint8 index = 0;
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD);
|
||||
stmt->SetData( index, m_id);
|
||||
stmt->SetData(index, m_id);
|
||||
stmt->SetData(++index, m_name);
|
||||
stmt->SetData(++index, m_leaderGuid.GetCounter());
|
||||
stmt->SetData(++index, m_info);
|
||||
@@ -2427,12 +2429,12 @@ void Guild::_CreateNewBankTab()
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_TAB);
|
||||
stmt->SetData(0, m_id);
|
||||
stmt->SetData (1, tabId);
|
||||
stmt->SetData(1, tabId);
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_TAB);
|
||||
stmt->SetData(0, m_id);
|
||||
stmt->SetData (1, tabId);
|
||||
stmt->SetData(1, tabId);
|
||||
trans->Append(stmt);
|
||||
|
||||
++tabId;
|
||||
@@ -2873,7 +2875,7 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid,
|
||||
LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: {}", guildEvent);
|
||||
}
|
||||
|
||||
void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds *slots /*= nullptr*/) const
|
||||
void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds* slots /*= nullptr*/) const
|
||||
{
|
||||
if (!sScriptMgr->CanGuildSendBankList(this, session, tabId, sendAllSlots))
|
||||
return;
|
||||
|
||||
@@ -239,7 +239,8 @@ class EmblemInfo
|
||||
{
|
||||
public:
|
||||
EmblemInfo(uint32 /*style*/ = 0, uint32 /*color*/ = 0, uint32 /*borderStyle*/ = 0, uint32 /*borderColor*/ = 0, uint32 /*backgroundColor*/ = 0) :
|
||||
m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) { }
|
||||
m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) {
|
||||
}
|
||||
|
||||
void LoadFromDB(Field* fields);
|
||||
void SaveToDB(uint32 guildId) const;
|
||||
@@ -263,9 +264,9 @@ private:
|
||||
class GuildBankRightsAndSlots
|
||||
{
|
||||
public:
|
||||
GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) { }
|
||||
GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), rights(0), slots(0) { }
|
||||
GuildBankRightsAndSlots(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) { }
|
||||
GuildBankRightsAndSlots() : tabId(TAB_UNDEFINED), rights(0), slots(0) {}
|
||||
GuildBankRightsAndSlots(uint8 _tabId) : tabId(_tabId), rights(0), slots(0) {}
|
||||
GuildBankRightsAndSlots(uint8 _tabId, uint8 _rights, uint32 _slots) : tabId(_tabId), rights(_rights), slots(_slots) {}
|
||||
|
||||
void SetGuildMasterValues()
|
||||
{
|
||||
@@ -296,7 +297,7 @@ public: // pussywizard: public class Member
|
||||
class Member
|
||||
{
|
||||
public:
|
||||
Member(uint32 guildId, ObjectGuid guid, uint8 rankId):
|
||||
Member(uint32 guildId, ObjectGuid guid, uint8 rankId) :
|
||||
m_guildId(guildId),
|
||||
m_guid(guid),
|
||||
m_zoneId(0),
|
||||
@@ -404,8 +405,8 @@ private:
|
||||
{
|
||||
public:
|
||||
LogEntry(uint32 guildId, ObjectGuid::LowType guid);
|
||||
LogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) { }
|
||||
virtual ~LogEntry() { }
|
||||
LogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) {}
|
||||
virtual ~LogEntry() {}
|
||||
|
||||
ObjectGuid::LowType GetGUID() const { return m_guid; }
|
||||
uint64 GetTimestamp() const { return m_timestamp; }
|
||||
@@ -423,12 +424,14 @@ private:
|
||||
{
|
||||
public:
|
||||
EventLogEntry(uint32 guildId, ObjectGuid::LowType guid, GuildEventLogTypes eventType, ObjectGuid playerGuid1, ObjectGuid playerGuid2, uint8 newRank) :
|
||||
LogEntry(guildId, guid), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { }
|
||||
LogEntry(guildId, guid), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) {
|
||||
}
|
||||
|
||||
EventLogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp, GuildEventLogTypes eventType, ObjectGuid playerGuid1, ObjectGuid playerGuid2, uint8 newRank) :
|
||||
LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { }
|
||||
LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) {
|
||||
}
|
||||
|
||||
~EventLogEntry() override { }
|
||||
~EventLogEntry() override {}
|
||||
|
||||
void SaveToDB(CharacterDatabaseTransaction trans) const override;
|
||||
void WritePacket(WorldPackets::Guild::GuildEventLogQueryResults& packet) const;
|
||||
@@ -459,13 +462,15 @@ private:
|
||||
|
||||
BankEventLogEntry(uint32 guildId, ObjectGuid::LowType guid, GuildBankEventLogTypes eventType, uint8 tabId, ObjectGuid playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
|
||||
LogEntry(guildId, guid), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid),
|
||||
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { }
|
||||
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) {
|
||||
}
|
||||
|
||||
BankEventLogEntry(uint32 guildId, ObjectGuid::LowType guid, time_t timestamp, uint8 tabId, GuildBankEventLogTypes eventType, ObjectGuid playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
|
||||
LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid),
|
||||
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { }
|
||||
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) {
|
||||
}
|
||||
|
||||
~BankEventLogEntry() override { }
|
||||
~BankEventLogEntry() override {}
|
||||
|
||||
void SaveToDB(CharacterDatabaseTransaction trans) const override;
|
||||
void WritePacket(WorldPackets::Guild::GuildBankLogQueryResults& packet) const;
|
||||
@@ -510,11 +515,12 @@ private:
|
||||
class RankInfo
|
||||
{
|
||||
public:
|
||||
RankInfo(): m_guildId(0), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { }
|
||||
RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { }
|
||||
RankInfo() : m_guildId(0), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) {}
|
||||
RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) {}
|
||||
RankInfo(uint32 guildId, uint8 rankId, std::string_view name, uint32 rights, uint32 money) :
|
||||
m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights),
|
||||
m_bankMoneyPerDay(rankId != GR_GUILDMASTER ? money : GUILD_WITHDRAW_MONEY_UNLIMITED) { }
|
||||
m_bankMoneyPerDay(rankId != GR_GUILDMASTER ? money : GUILD_WITHDRAW_MONEY_UNLIMITED) {
|
||||
}
|
||||
|
||||
void LoadFromDB(Field* fields);
|
||||
void SaveToDB(CharacterDatabaseTransaction trans) const;
|
||||
@@ -591,8 +597,9 @@ private:
|
||||
{
|
||||
public:
|
||||
MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : m_pGuild(guild), m_pPlayer(player),
|
||||
m_container(container), m_slotId(slotId), m_pItem(nullptr), m_pClonedItem(nullptr) { }
|
||||
virtual ~MoveItemData() { }
|
||||
m_container(container), m_slotId(slotId), m_pItem(nullptr), m_pClonedItem(nullptr) {
|
||||
}
|
||||
virtual ~MoveItemData() {}
|
||||
|
||||
virtual bool IsBank() const = 0;
|
||||
// Initializes item pointer. Returns true, if item exists, false otherwise.
|
||||
@@ -638,7 +645,8 @@ private:
|
||||
{
|
||||
public:
|
||||
PlayerMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) :
|
||||
MoveItemData(guild, player, container, slotId) { }
|
||||
MoveItemData(guild, player, container, slotId) {
|
||||
}
|
||||
|
||||
bool IsBank() const override { return false; }
|
||||
bool InitItem() override;
|
||||
@@ -653,7 +661,8 @@ private:
|
||||
{
|
||||
public:
|
||||
BankMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) :
|
||||
MoveItemData(guild, player, container, slotId) { }
|
||||
MoveItemData(guild, player, container, slotId) {
|
||||
}
|
||||
|
||||
bool IsBank() const override { return true; }
|
||||
bool InitItem() override;
|
||||
|
||||
@@ -945,14 +945,13 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
|
||||
pCurrChar->CastSpell(pCurrChar, 20584, true, 0); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
|
||||
|
||||
pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
|
||||
pCurrChar->SetMovement(MOVE_WATER_WALK);
|
||||
}
|
||||
|
||||
// Set FFA PvP for non GM in non-rest mode
|
||||
if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
|
||||
if (!pCurrChar->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||
{
|
||||
sScriptMgr->OnPlayerFfaPvpStateUpdate(pCurrChar,true);
|
||||
sScriptMgr->OnPlayerFfaPvpStateUpdate(pCurrChar, true);
|
||||
pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,17 +335,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
msg.erase(end, msg.end());
|
||||
}
|
||||
|
||||
// Skip validation for playerbots module
|
||||
auto playerbotsHyperlink = msg.find("Hfound:") != std::string::npos;
|
||||
if (!playerbotsHyperlink)
|
||||
{
|
||||
// Validate hyperlinks
|
||||
if (!ValidateHyperlinksAndMaybeKick(msg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
@@ -439,11 +434,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg);
|
||||
@@ -457,18 +448,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
|
||||
{
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
|
||||
|
||||
guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -479,11 +462,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
|
||||
{
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, guild))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
|
||||
|
||||
guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
|
||||
}
|
||||
@@ -502,11 +481,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg);
|
||||
@@ -525,11 +500,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
|
||||
@@ -543,11 +514,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
||||
|
||||
// In battleground, raid warning is sent only to players in battleground - code is ok
|
||||
WorldPacket data;
|
||||
@@ -563,11 +530,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
|
||||
@@ -582,11 +545,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
return;
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(GetPlayer(), type, lang, msg, group))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
|
||||
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);
|
||||
@@ -609,11 +568,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
if (Channel* chn = cMgr->GetChannel(channel, sender))
|
||||
{
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg, chn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
|
||||
|
||||
chn->Say(sender->GetGUID(), msg.c_str(), lang);
|
||||
}
|
||||
@@ -642,12 +597,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(sender, type, lang, msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHAT_MSG_DND:
|
||||
@@ -670,11 +621,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
}
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanUseChat(sender, type, lang, msg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerChat(sender, type, lang, msg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -482,8 +482,6 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
|
||||
break;
|
||||
}
|
||||
|
||||
sScriptMgr->OnPlayerbotCheckPetitionAccount(_player, found);
|
||||
|
||||
if (found)
|
||||
{
|
||||
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
|
||||
|
||||
@@ -54,6 +54,10 @@ Map::~Map()
|
||||
{
|
||||
// UnloadAll must be called before deleting the map
|
||||
|
||||
// Kill all scheduled events without executing them, since the map and its objects are being destroyed.
|
||||
// This prevents events from running on invalid or deleted objects during map destruction.
|
||||
Events.KillAllEvents(false);
|
||||
|
||||
sScriptMgr->OnDestroyMap(this);
|
||||
|
||||
if (!m_scriptSchedule.empty())
|
||||
@@ -447,7 +451,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
||||
}
|
||||
}
|
||||
|
||||
_creatureRespawnScheduler.Update(t_diff);
|
||||
Events.Update(t_diff);
|
||||
|
||||
if (!t_diff)
|
||||
{
|
||||
@@ -1097,7 +1101,7 @@ float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, fl
|
||||
if (ground)
|
||||
*ground = ground_z;
|
||||
|
||||
LiquidData const& liquidData = const_cast<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)
|
||||
{
|
||||
case LIQUID_MAP_ABOVE_WATER:
|
||||
@@ -1198,27 +1202,18 @@ static inline bool IsInWMOInterior(uint32 mogpFlags)
|
||||
|
||||
bool Map::GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
|
||||
{
|
||||
float vmap_z = z;
|
||||
float dynamic_z = z;
|
||||
float check_z = z;
|
||||
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
||||
uint32 vflags;
|
||||
int32 vadtId;
|
||||
int32 vrootId;
|
||||
int32 vgroupId;
|
||||
uint32 dflags;
|
||||
int32 dadtId;
|
||||
int32 drootId;
|
||||
int32 dgroupId;
|
||||
|
||||
bool hasVmapAreaInfo = vmgr->GetAreaInfo(GetId(), x, y, vmap_z, vflags, vadtId, vrootId, vgroupId);
|
||||
bool hasDynamicAreaInfo = _dynamicTree.GetAreaInfo(x, y, dynamic_z, phaseMask, dflags, dadtId, drootId, dgroupId);
|
||||
auto useVmap = [&]() { check_z = vmap_z; flags = vflags; adtId = vadtId; rootId = vrootId; groupId = vgroupId; };
|
||||
auto useDyn = [&]() { check_z = dynamic_z; flags = dflags; adtId = dadtId; rootId = drootId; groupId = dgroupId; };
|
||||
VMAP::AreaAndLiquidData vdata;
|
||||
VMAP::AreaAndLiquidData ddata;
|
||||
|
||||
bool hasVmapAreaInfo = vmgr->GetAreaAndLiquidData(GetId(), x, y, z, {}, vdata) && vdata.areaInfo.has_value();
|
||||
bool hasDynamicAreaInfo = _dynamicTree.GetAreaAndLiquidData(x, y, z, phaseMask, {}, ddata) && ddata.areaInfo.has_value();
|
||||
auto useVmap = [&] { check_z = vdata.floorZ; groupId = vdata.areaInfo->groupId; adtId = vdata.areaInfo->adtId; rootId = vdata.areaInfo->rootId; flags = vdata.areaInfo->mogpFlags; };
|
||||
auto useDyn = [&] { check_z = ddata.floorZ; groupId = ddata.areaInfo->groupId; adtId = ddata.areaInfo->adtId; rootId = ddata.areaInfo->rootId; flags = ddata.areaInfo->mogpFlags; };
|
||||
if (hasVmapAreaInfo)
|
||||
{
|
||||
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
|
||||
if (hasDynamicAreaInfo && ddata.floorZ > vdata.floorZ)
|
||||
useDyn();
|
||||
else
|
||||
useVmap();
|
||||
@@ -1299,32 +1294,30 @@ void Map::GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, flo
|
||||
zoneid = area->zone;
|
||||
}
|
||||
|
||||
LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType)
|
||||
LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional<uint8> ReqLiquidType)
|
||||
{
|
||||
LiquidData liquidData;
|
||||
liquidData.Status = LIQUID_MAP_NO_WATER;
|
||||
|
||||
VMAP::IVMapMgr* vmgr = VMAP::VMapFactory::createOrGetVMapMgr();
|
||||
float liquid_level = INVALID_HEIGHT;
|
||||
float ground_level = INVALID_HEIGHT;
|
||||
uint32 liquid_type = 0;
|
||||
uint32 mogpFlags = 0;
|
||||
VMAP::AreaAndLiquidData vmapData;
|
||||
bool useGridLiquid = true;
|
||||
if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type, mogpFlags))
|
||||
if (vmgr->GetAreaAndLiquidData(GetId(), x, y, z, ReqLiquidType, vmapData) && vmapData.liquidInfo)
|
||||
{
|
||||
useGridLiquid = !IsInWMOInterior(mogpFlags);
|
||||
LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", liquid_level, ground_level, liquid_type);
|
||||
useGridLiquid = !vmapData.areaInfo || !IsInWMOInterior(vmapData.areaInfo->mogpFlags);
|
||||
LOG_DEBUG("maps", "GetLiquidStatus(): vmap liquid level: {} ground: {} type: {}", vmapData.liquidInfo->level, vmapData.floorZ, vmapData.liquidInfo->type);
|
||||
// Check water level and ground level
|
||||
if (liquid_level > ground_level && G3D::fuzzyGe(z, ground_level - GROUND_HEIGHT_TOLERANCE))
|
||||
if (vmapData.liquidInfo->level > vmapData.floorZ && G3D::fuzzyGe(z, vmapData.floorZ - GROUND_HEIGHT_TOLERANCE))
|
||||
{
|
||||
// hardcoded in client like this
|
||||
if (GetId() == MAP_OUTLAND && liquid_type == 2)
|
||||
liquid_type = 15;
|
||||
if (GetId() == MAP_OUTLAND && vmapData.liquidInfo->type == 2)
|
||||
vmapData.liquidInfo->type = 15;
|
||||
|
||||
uint32 liquidFlagType = 0;
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type))
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(vmapData.liquidInfo->type))
|
||||
liquidFlagType = liq->Type;
|
||||
|
||||
if (liquid_type && liquid_type < 21)
|
||||
if (vmapData.liquidInfo->type && vmapData.liquidInfo->type < 21)
|
||||
{
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseMask, x, y, z)))
|
||||
{
|
||||
@@ -1338,19 +1331,19 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
|
||||
|
||||
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid))
|
||||
{
|
||||
liquid_type = overrideLiquid;
|
||||
vmapData.liquidInfo->type = overrideLiquid;
|
||||
liquidFlagType = liq->Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
liquidData.Level = liquid_level;
|
||||
liquidData.DepthLevel = ground_level;
|
||||
liquidData.Entry = liquid_type;
|
||||
liquidData.Level = vmapData.liquidInfo->level;
|
||||
liquidData.DepthLevel = vmapData.floorZ;
|
||||
liquidData.Entry = vmapData.liquidInfo->type;
|
||||
liquidData.Flags = 1 << liquidFlagType;
|
||||
}
|
||||
|
||||
float delta = liquid_level - z;
|
||||
float delta = vmapData.liquidInfo->level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > collisionHeight)
|
||||
@@ -1369,7 +1362,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
|
||||
{
|
||||
LiquidData const& map_data = gmap->GetLiquidData(x, y, z, collisionHeight, ReqLiquidType);
|
||||
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
|
||||
if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > ground_level))
|
||||
if (map_data.Status != LIQUID_MAP_NO_WATER && (map_data.Level > vmapData.floorZ))
|
||||
{
|
||||
// hardcoded in client like this
|
||||
uint32 liquidEntry = map_data.Entry;
|
||||
@@ -1385,7 +1378,7 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
|
||||
return liquidData;
|
||||
}
|
||||
|
||||
void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType)
|
||||
void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<uint8> reqLiquidType)
|
||||
{
|
||||
GridTerrainData* gmap = GetGridTerrainData(x, y);
|
||||
|
||||
@@ -1600,7 +1593,7 @@ float Map::GetHeight(uint32 phasemask, float x, float y, float z, bool vmap/*=tr
|
||||
|
||||
bool Map::IsInWater(uint32 phaseMask, float x, float y, float pZ, float collisionHeight) const
|
||||
{
|
||||
LiquidData const& liquidData = const_cast<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;
|
||||
}
|
||||
|
||||
@@ -1729,12 +1722,6 @@ void Map::SendObjectUpdates()
|
||||
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
|
||||
for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
|
||||
{
|
||||
if (!sScriptMgr->OnPlayerbotCheckUpdatesToSend(iter->first))
|
||||
{
|
||||
iter->second.Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
iter->second.BuildPacket(packet);
|
||||
iter->first->SendDirectMessage(&packet);
|
||||
packet.clear(); // clean the string
|
||||
@@ -2764,13 +2751,13 @@ void Map::RemoveOldCorpses()
|
||||
|
||||
void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnTimer, Position pos)
|
||||
{
|
||||
_creatureRespawnScheduler.Schedule(respawnTimer, [this, creatureGuid, pos](TaskContext)
|
||||
Events.AddEventAtOffset([this, creatureGuid, pos]()
|
||||
{
|
||||
if (Creature* creature = GetCreature(creatureGuid))
|
||||
creature->Respawn();
|
||||
else
|
||||
SummonCreature(creatureGuid.GetEntry(), pos);
|
||||
});
|
||||
}, respawnTimer);
|
||||
}
|
||||
|
||||
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "DataMap.h"
|
||||
#include "Define.h"
|
||||
#include "DynamicTree.h"
|
||||
#include "EventProcessor.h"
|
||||
#include "GameObjectModel.h"
|
||||
#include "GridDefines.h"
|
||||
#include "GridRefMgr.h"
|
||||
@@ -33,7 +34,6 @@
|
||||
#include "PathGenerator.h"
|
||||
#include "Position.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "Timer.h"
|
||||
#include "GridTerrainData.h"
|
||||
#include <bitset>
|
||||
@@ -172,7 +172,7 @@ public:
|
||||
// currently unused for normal maps
|
||||
bool CanUnload(uint32 diff)
|
||||
{
|
||||
if (!m_unloadTimer)
|
||||
if (!m_unloadTimer || Events.HasEvents())
|
||||
return false;
|
||||
|
||||
if (m_unloadTimer <= diff)
|
||||
@@ -243,8 +243,8 @@ public:
|
||||
[[nodiscard]] float GetMinHeight(float x, float y) const;
|
||||
Transport* GetTransportForPos(uint32 phase, float x, float y, float z, WorldObject* worldobject = nullptr);
|
||||
|
||||
void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS);
|
||||
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, uint8 ReqLiquidType);
|
||||
void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<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]] uint32 GetAreaId(uint32 phaseMask, float x, float y, float z) const;
|
||||
@@ -430,7 +430,7 @@ public:
|
||||
void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone);
|
||||
[[nodiscard]] uint32 ApplyDynamicModeRespawnScaling(WorldObject const* obj, uint32 respawnDelay) const;
|
||||
|
||||
TaskScheduler _creatureRespawnScheduler;
|
||||
EventProcessor Events;
|
||||
|
||||
void ScheduleCreatureRespawn(ObjectGuid /*creatureGuid*/, Milliseconds /*respawnTimer*/, Position pos = Position());
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
|
||||
{
|
||||
bool buildShortcut = false;
|
||||
|
||||
auto liquidDataStart = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS);
|
||||
auto liquidDataEnd = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS);
|
||||
auto liquidDataStart = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.z, _source->GetCollisionHeight(), {});
|
||||
auto liquidDataEnd = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight(), {});
|
||||
|
||||
bool startUnderWaterEndInWater = liquidDataStart.Status == LIQUID_MAP_UNDER_WATER &&
|
||||
(liquidDataEnd.Status & MAP_LIQUID_STATUS_IN_CONTACT) != 0;
|
||||
@@ -698,7 +698,7 @@ void PathGenerator::UpdateFilter()
|
||||
|
||||
NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) const
|
||||
{
|
||||
LiquidData const& liquidData = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), x, y, z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS);
|
||||
LiquidData const& liquidData = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), x, y, z, _source->GetCollisionHeight(), {});
|
||||
if (liquidData.Status == LIQUID_MAP_NO_WATER)
|
||||
return NAV_GROUND;
|
||||
|
||||
|
||||
@@ -47,10 +47,6 @@ void PointMovementGenerator<T>::DoInitialize(T* unit)
|
||||
|
||||
i_recalculateSpeed = false;
|
||||
Movement::MoveSplineInit init(unit);
|
||||
/// Added by mod-playerbots
|
||||
if (_reverseOrientation)
|
||||
init.SetOrientationInversed();
|
||||
/// End added
|
||||
if (m_precomputedPath.size() > 2) // pussywizard: for charge
|
||||
init.MovebyPath(m_precomputedPath);
|
||||
else if (_generatePath)
|
||||
@@ -220,9 +216,14 @@ template <> void PointMovementGenerator<Creature>::MovementInform(Creature* unit
|
||||
if (Unit* summoner = unit->GetCharmerOrOwner())
|
||||
{
|
||||
if (UnitAI* AI = summoner->GetAI())
|
||||
{
|
||||
AI->SummonMovementInform(unit, POINT_MOTION_TYPE, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TempSummon* tempSummon = unit->ToTempSummon())
|
||||
if (Unit* summoner = tempSummon->GetSummonerUnit())
|
||||
if (UnitAI* AI = summoner->GetAI())
|
||||
AI->SummonMovementInform(unit, POINT_MOTION_TYPE, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -276,23 +276,15 @@ void WaypointMovementGenerator<Creature>::MovementInform(Creature* creature)
|
||||
if (Unit* owner = creature->GetCharmerOrOwner())
|
||||
{
|
||||
if (UnitAI* AI = owner->GetAI())
|
||||
{
|
||||
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TempSummon* tempSummon = creature->ToTempSummon())
|
||||
{
|
||||
if (Unit* owner = tempSummon->GetSummonerUnit())
|
||||
{
|
||||
if (UnitAI* AI = owner->GetAI())
|
||||
{
|
||||
AI->SummonMovementInform(creature, WAYPOINT_MOTION_TYPE, i_currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointMovementGenerator<Creature>::Pause(uint32 timer)
|
||||
@@ -418,6 +410,7 @@ void FlightPathMovementGenerator::DoFinalize(Player* player)
|
||||
player->m_taxi.ClearTaxiDestinations();
|
||||
player->Dismount();
|
||||
player->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
||||
player->UpdatePvPState(); // to account for cases such as flying into a PvP territory, as it does not flag on the way in
|
||||
|
||||
if (player->m_taxi.empty())
|
||||
{
|
||||
@@ -447,6 +440,9 @@ void FlightPathMovementGenerator::DoReset(Player* player)
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->pvpInfo.EndTimer)
|
||||
player->UpdatePvP(false, true); // PvP flag timer immediately ends when starting taxi
|
||||
|
||||
player->getHostileRefMgr().setOnlineOfflineState(false);
|
||||
player->AddUnitState(UNIT_STATE_IN_FLIGHT);
|
||||
player->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
|
||||
|
||||
@@ -169,36 +169,11 @@ void ScriptMgr::OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_DUEL_END, script->OnPlayerDuelEnd(winner, loser, type));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT, script->OnPlayerChat(player, type, lang, msg));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerBeforeSendChatMessage(Player* player, uint32& type, uint32& lang, std::string& msg)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_SEND_CHAT_MESSAGE, script->OnPlayerBeforeSendChatMessage(player, type, lang, msg));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_RECEIVER, script->OnPlayerChat(player, type, lang, msg, receiver));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_GROUP, script->OnPlayerChat(player, type, lang, msg, group));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_GUILD, script->OnPlayerChat(player, type, lang, msg, guild));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_CHAT_WITH_CHANNEL, script->OnPlayerChat(player, type, lang, msg, channel));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerEmote(Player* player, uint32 emote)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_EMOTE, script->OnPlayerEmote(player, emote));
|
||||
|
||||
@@ -306,18 +306,8 @@ public:
|
||||
virtual void OnPlayerDuelEnd(Player* /*winner*/, Player* /*loser*/, DuelCompleteType /*type*/) { }
|
||||
|
||||
// The following methods are called when a player sends a chat message.
|
||||
virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/) { }
|
||||
|
||||
virtual void OnPlayerBeforeSendChatMessage(Player* /*player*/, uint32& /*type*/, uint32& /*lang*/, std::string& /*msg*/) { }
|
||||
|
||||
virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Player* /*receiver*/) { }
|
||||
|
||||
virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Group* /*group*/) { }
|
||||
|
||||
virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Guild* /*guild*/) { }
|
||||
|
||||
virtual void OnPlayerChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Channel* /*channel*/) { }
|
||||
|
||||
// Both of the below are called on emote opcodes.
|
||||
virtual void OnPlayerEmote(Player* /*player*/, uint32 /*emote*/) { }
|
||||
|
||||
|
||||
@@ -340,12 +340,7 @@ public: /* PlayerScript */
|
||||
void OnPlayerDuelRequest(Player* target, Player* challenger);
|
||||
void OnPlayerDuelStart(Player* player1, Player* player2);
|
||||
void OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type);
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg);
|
||||
void OnPlayerBeforeSendChatMessage(Player* player, uint32& type, uint32& lang, std::string& msg);
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver);
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group);
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild);
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel);
|
||||
void OnPlayerEmote(Player* player, uint32 emote);
|
||||
void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid);
|
||||
void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck);
|
||||
|
||||
@@ -1377,7 +1377,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
|
||||
|
||||
float ground = m_caster->GetMapHeight(x, y, z, true);
|
||||
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
|
||||
LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), MAP_ALL_LIQUIDS);
|
||||
LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
|
||||
if (liquidData.Status)
|
||||
liquidLevel = liquidData.Level;
|
||||
|
||||
|
||||
@@ -156,13 +156,13 @@ public:
|
||||
if (enable)
|
||||
{
|
||||
handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK);
|
||||
handler->GetSession()->GetPlayer()->SetMovement(MOVE_WATER_WALK); // ON
|
||||
handler->GetSession()->GetPlayer()->SetWaterWalking(true); // ON
|
||||
handler->SendSysMessage("Waterwalking is ON. You can walk on water.");
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK);
|
||||
handler->GetSession()->GetPlayer()->SetMovement(MOVE_LAND_WALK); // OFF
|
||||
handler->GetSession()->GetPlayer()->SetWaterWalking(false); // OFF
|
||||
handler->SendSysMessage("Waterwalking is OFF. You can't walk on water.");
|
||||
}
|
||||
|
||||
|
||||
@@ -1949,7 +1949,7 @@ public:
|
||||
// the max level of the new profession.
|
||||
uint16 max = maxPureSkill ? *maxPureSkill : targetHasSkill ? target->GetPureMaxSkillValue(skillID) : uint16(level);
|
||||
|
||||
if (level < 0 || level > max || max < 0)
|
||||
if (level <= 0 || level > max || max <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,6 @@ public:
|
||||
{
|
||||
ObjectGuid::LowType guid = sObjectMgr->GenerateCreatureSpawnId();
|
||||
CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);
|
||||
data.spawnId = guid;
|
||||
data.id1 = id;
|
||||
data.phaseMask = chr->GetPhaseMaskForSpawn();
|
||||
data.posX = chr->GetTransOffsetX();
|
||||
|
||||
@@ -2019,11 +2019,14 @@ class spell_gen_animal_blood : public AuraScript
|
||||
{
|
||||
// Remove all auras with spell id 46221, except the one currently being applied
|
||||
while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, ObjectGuid::Empty, ObjectGuid::Empty, 0, GetAura()))
|
||||
GetUnitOwner()->RemoveOwnedAura(aur);
|
||||
GetUnitOwner()->RemoveOwnedAura(aur, AURA_REMOVE_BY_EXPIRE);
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
|
||||
return;
|
||||
|
||||
if (Unit* owner = GetUnitOwner())
|
||||
if (owner->IsInWater())
|
||||
owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true);
|
||||
@@ -2044,7 +2047,7 @@ class spell_spawn_blood_pool : public SpellScript
|
||||
void SetDest(SpellDestination &dest)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
LiquidData liquidStatus = caster->GetMap()->GetLiquidData(caster->GetPhaseMask(), caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), caster->GetCollisionHeight(), MAP_ALL_LIQUIDS);
|
||||
LiquidData liquidStatus = caster->GetMap()->GetLiquidData(caster->GetPhaseMask(), caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), caster->GetCollisionHeight(), {});
|
||||
|
||||
float level = liquidStatus.Level > INVALID_HEIGHT ? liquidStatus.Level : caster->GetPositionZ();
|
||||
Position pos = Position(caster->GetPositionX(), caster->GetPositionY(), level, caster->GetOrientation());
|
||||
|
||||
@@ -170,7 +170,7 @@ public:
|
||||
{
|
||||
QuestStatus QLR = player->GetQuestStatus(QUEST_LAST_RITES);
|
||||
QuestStatus QBT = player->GetQuestStatus(QUEST_BREAKING_THROUGH);
|
||||
if (!(QLR == QUEST_STATUS_INCOMPLETE || QLR == QUEST_STATUS_COMPLETE ||
|
||||
if (!(QLR == QUEST_STATUS_INCOMPLETE || QLR == QUEST_STATUS_COMPLETE || QLR == QUEST_STATUS_REWARDED ||
|
||||
QBT == QUEST_STATUS_INCOMPLETE || QBT == QUEST_STATUS_COMPLETE))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -27,16 +27,16 @@ public:
|
||||
ChatLogScript() :
|
||||
PlayerScript("ChatLogScript",
|
||||
{
|
||||
PLAYERHOOK_ON_CHAT,
|
||||
PLAYERHOOK_ON_CHAT_WITH_GROUP,
|
||||
PLAYERHOOK_ON_CHAT_WITH_GUILD,
|
||||
PLAYERHOOK_ON_CHAT_WITH_CHANNEL,
|
||||
PLAYERHOOK_ON_CHAT_WITH_RECEIVER
|
||||
PLAYERHOOK_CAN_PLAYER_USE_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_GROUP_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_GUILD_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_CHANNEL_CHAT,
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg) override
|
||||
bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg) override
|
||||
{
|
||||
std::string logType = "";
|
||||
std::string chatType = "";
|
||||
@@ -56,14 +56,16 @@ public:
|
||||
chatType = "yells";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_INFO(logType, "Player {} {} (language {}): {}",
|
||||
player->GetName(), chatType, lang, msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnPlayerChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) override
|
||||
bool OnPlayerCanUseChat(Player* player, uint32 /*type*/, uint32 lang, std::string& msg, Player* receiver) override
|
||||
{
|
||||
//! NOTE:
|
||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||
@@ -72,9 +74,11 @@ public:
|
||||
|
||||
LOG_INFO(logType + msgType, "Player {} {} {}: {}",
|
||||
player->GetName(), msgType, receiver ? receiver->GetName() : "<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:
|
||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||
@@ -97,7 +101,7 @@ public:
|
||||
msgType = "bg";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string role = (type == CHAT_MSG_PARTY_LEADER || type == CHAT_MSG_RAID_LEADER || type == CHAT_MSG_BATTLEGROUND_LEADER) ? "Leader player" : "Player";
|
||||
@@ -106,9 +110,11 @@ public:
|
||||
|
||||
LOG_INFO(logType + msgType, "{} {} {} {} with leader {}: {}",
|
||||
role, player->GetName(), action, msgType, targetGroup, msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override
|
||||
bool OnPlayerCanUseChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild) override
|
||||
{
|
||||
//! NOTE:
|
||||
//! LANG_ADDON can only be sent by client in "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"
|
||||
@@ -124,14 +130,16 @@ public:
|
||||
msgType = "guild.officer";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_INFO(logType + msgType, "Player {} tells {} \"{}\": {}",
|
||||
player->GetName(), msgType, guild ? guild->GetName() : "<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 &&
|
||||
(channel->HasFlag(CHANNEL_FLAG_TRADE) ||
|
||||
@@ -152,6 +160,8 @@ public:
|
||||
LOG_INFO("chat.channel." + channelName, "Player {} tells channel {}: {}",
|
||||
player->GetName(), channelName, msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user