minimize delta, legacy and merge mistakes over the years

This commit is contained in:
bash
2026-01-08 00:50:49 +01:00
parent ae2af138e2
commit 0a0ba0a53f
64 changed files with 908 additions and 1278 deletions
+1 -1
View File
@@ -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
-5
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+8 -41
View File
@@ -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;
}
+2 -2
View File
@@ -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,
+13 -12
View File
@@ -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;
};
}
+1 -2
View File
@@ -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;
}
+10 -66
View File
@@ -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 */)
+1 -3
View File
@@ -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);
-32
View File
@@ -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);
+6 -1
View File
@@ -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;
+5 -39
View File
@@ -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; }
+66 -59
View File
@@ -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;
+6 -4
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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_
-26
View File
@@ -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).
+1 -1
View File
@@ -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};
-1
View File
@@ -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))
+1 -11
View File
@@ -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)
-11
View File
@@ -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:
+4 -18
View File
@@ -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
+1 -55
View File
@@ -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();
+10
View File
@@ -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);
}
+4 -20
View File
@@ -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;
}
-2
View File
@@ -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
+4 -2
View File
@@ -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
+2 -2
View File
@@ -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
+1
View File
@@ -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;
+35 -33
View File
@@ -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;
+29 -20
View File
@@ -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);
}
-53
View File
@@ -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));
+34 -47
View File
@@ -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)
+5 -5
View File
@@ -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*/) { }
-5
View File
@@ -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);
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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.");
}
+1 -1
View File
@@ -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;
}
-1
View File
@@ -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();
+5 -2
View File
@@ -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;
+23 -13
View File
@@ -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;
}
};