diff options
Diffstat (limited to 'src')
172 files changed, 2442 insertions, 2019 deletions
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index 847b7bbd001..b71b94e3291 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -32,11 +32,41 @@ namespace MMAP // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost! } + void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds) + { + // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime + for (const uint32& mapId : mapIds) + loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)); + + thread_safe_environment = false; + } + + MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const + { + // return the iterator if found or end() if not found/NULL + MMapDataSet::const_iterator itr = loadedMMaps.find(mapId); + if (itr != loadedMMaps.cend() && !itr->second) + itr = loadedMMaps.cend(); + + return itr; + } + bool MMapManager::loadMapData(uint32 mapId) { // we already have this map loaded? - if (loadedMMaps.find(mapId) != loadedMMaps.end()) - return true; + MMapDataSet::iterator itr = loadedMMaps.find(mapId); + if (itr != loadedMMaps.end()) + { + if (itr->second) + return true; + } + else + { + if (thread_safe_environment) + itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first; + else + ASSERT(false, "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId); + } // load and init dtNavMesh - read parameters from file uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap")+1; @@ -79,7 +109,7 @@ namespace MMAP MMapData* mmap_data = new MMapData(mesh); mmap_data->mmapLoadedTiles.clear(); - loadedMMaps.insert(std::pair<uint32, MMapData*>(mapId, mmap_data)); + itr->second = mmap_data; return true; } @@ -165,21 +195,20 @@ namespace MMAP dtFree(data); return false; } - - return false; } bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) { // check if we have this map loaded - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, x, y); return false; } - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; // check if we have this tile loaded uint32 packedGridPos = packTileID(x, y); @@ -214,7 +243,8 @@ namespace MMAP bool MMapManager::unloadMap(uint32 mapId) { - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::iterator itr = loadedMMaps.find(mapId); + if (itr == loadedMMaps.end() || !itr->second) { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId); @@ -222,7 +252,7 @@ namespace MMAP } // unload all tiles from given map - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i) { uint32 x = (i->first >> 16); @@ -237,7 +267,7 @@ namespace MMAP } delete mmap; - loadedMMaps.erase(mapId); + itr->second = nullptr; TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId); return true; @@ -246,14 +276,15 @@ namespace MMAP bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId) { // check if we have this map loaded - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId); return false; } - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) { TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId); @@ -271,18 +302,20 @@ namespace MMAP dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId) { - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) return NULL; - return loadedMMaps[mapId]->navMesh; + return itr->second->navMesh; } dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) { - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) return NULL; - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) { // allocate mesh query diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h index ac01a3c5693..42292b76942 100644 --- a/src/server/collision/Management/MMapManager.h +++ b/src/server/collision/Management/MMapManager.h @@ -20,11 +20,12 @@ #define _MMAP_MANAGER_H #include "Define.h" -#include "DetourAlloc.h" #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" + #include <string> #include <unordered_map> +#include <vector> // move map related classes namespace MMAP @@ -60,9 +61,10 @@ namespace MMAP class MMapManager { public: - MMapManager() : loadedTiles(0) { } + MMapManager() : loadedTiles(0), thread_safe_environment(true) {} ~MMapManager(); + void InitializeThreadUnsafe(const std::vector<uint32>& mapIds); bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId); @@ -78,8 +80,10 @@ namespace MMAP bool loadMapData(uint32 mapId); uint32 packTileID(int32 x, int32 y); + MMapDataSet::const_iterator GetMMapData(uint32 mapId) const; MMapDataSet loadedMMaps; uint32 loadedTiles; + bool thread_safe_environment; }; } diff --git a/src/server/collision/Management/VMapFactory.cpp b/src/server/collision/Management/VMapFactory.cpp index e3e211268e0..4c2750a9e5c 100644 --- a/src/server/collision/Management/VMapFactory.cpp +++ b/src/server/collision/Management/VMapFactory.cpp @@ -27,7 +27,7 @@ namespace VMAP // just return the instance IVMapManager* VMapFactory::createOrGetVMapManager() { - if (gVMapManager == 0) + if (gVMapManager == nullptr) gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-) return gVMapManager; } diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index f9fcff96ad2..9594951196f 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -37,6 +37,7 @@ namespace VMAP { GetLiquidFlagsPtr = &GetLiquidFlagsDummy; IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy; + thread_safe_environment = true; } VMapManager2::~VMapManager2(void) @@ -51,6 +52,15 @@ namespace VMAP } } + void VMapManager2::InitializeThreadUnsafe(const std::vector<uint32>& mapIds) + { + // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime + for (const uint32& mapId : mapIds) + iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)); + + thread_safe_environment = false; + } + Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const { Vector3 pos; @@ -86,12 +96,31 @@ namespace VMAP return result; } + InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const + { + // return the iterator if found or end() if not found/NULL + InstanceTreeMap::const_iterator itr = iInstanceMapTrees.find(mapId); + if (itr != iInstanceMapTrees.cend() && !itr->second) + itr = iInstanceMapTrees.cend(); + + return itr; + } + // load one tile (internal use only) - bool VMapManager2::_loadMap(unsigned int mapId, const std::string& basePath, uint32 tileX, uint32 tileY) + bool VMapManager2::_loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree == iInstanceMapTrees.end()) { + if (thread_safe_environment) + instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)).first; + else + ASSERT(false, "Invalid mapId %u tile [%u, %u] passed to VMapManager2 after startup in thread unsafe environment", + mapId, tileX, tileY); + } + + if (!instanceTree->second) + { std::string mapFileName = getMapFileName(mapId); StaticMapTree* newTree = new StaticMapTree(mapId, basePath); if (!newTree->InitMap(mapFileName, this)) @@ -99,7 +128,7 @@ namespace VMAP delete newTree; return false; } - instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first; + instanceTree->second = newTree; } return instanceTree->second->LoadMapTile(tileX, tileY, this); @@ -108,13 +137,13 @@ namespace VMAP void VMapManager2::unloadMap(unsigned int mapId) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); - if (instanceTree != iInstanceMapTrees.end()) + if (instanceTree != iInstanceMapTrees.end() && instanceTree->second) { instanceTree->second->UnloadMap(this); if (instanceTree->second->numLoadedTiles() == 0) { delete instanceTree->second; - iInstanceMapTrees.erase(mapId); + instanceTree->second = nullptr; } } } @@ -122,13 +151,13 @@ namespace VMAP void VMapManager2::unloadMap(unsigned int mapId, int x, int y) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); - if (instanceTree != iInstanceMapTrees.end()) + if (instanceTree != iInstanceMapTrees.end() && instanceTree->second) { instanceTree->second->UnloadMapTile(x, y, this); if (instanceTree->second->numLoadedTiles() == 0) { delete instanceTree->second; - iInstanceMapTrees.erase(mapId); + instanceTree->second = nullptr; } } } @@ -138,7 +167,7 @@ namespace VMAP if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) return true; - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1); @@ -160,7 +189,7 @@ namespace VMAP { if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1); @@ -190,7 +219,7 @@ namespace VMAP { if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT)) { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos = convertPositionToInternalRep(x, y, z); @@ -209,7 +238,7 @@ namespace VMAP { if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) { - InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos = convertPositionToInternalRep(x, y, z); @@ -227,7 +256,7 @@ namespace VMAP { if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) { - InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { LocationInfo info; diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h index e13d5ab952b..a5891e9642b 100644 --- a/src/server/collision/Management/VMapManager2.h +++ b/src/server/collision/Management/VMapManager2.h @@ -21,6 +21,7 @@ #include <mutex> #include <unordered_map> +#include <vector> #include "Define.h" #include "IVMapManager.h" @@ -80,6 +81,7 @@ namespace VMAP // Tree to check collision ModelFileMap iLoadedModelFiles; InstanceTreeMap iInstanceMapTrees; + bool thread_safe_environment; // Mutex for iLoadedModelFiles std::mutex LoadedModelFilesLock; @@ -89,6 +91,8 @@ namespace VMAP static uint32 GetLiquidFlagsDummy(uint32) { return 0; } static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; } + InstanceTreeMap::const_iterator GetMapTree(uint32 mapId) const; + public: // public for debug G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const; @@ -97,6 +101,7 @@ namespace VMAP VMapManager2(); ~VMapManager2(void); + void InitializeThreadUnsafe(const std::vector<uint32>& mapIds); int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override; void unloadMap(unsigned int mapId, int x, int y) override; diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index dd1502c45b0..dbdc0554e06 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -20,13 +20,9 @@ #include "VMapManager2.h" #include "VMapDefinitions.h" #include "WorldModel.h" - #include "GameObjectModel.h" #include "Log.h" -#include "GameObject.h" -#include "Object.h" -#include "DBCStores.h" -#include "World.h" +#include "Timer.h" using G3D::Vector3; using G3D::Ray; @@ -44,13 +40,13 @@ struct GameobjectModelData typedef std::unordered_map<uint32, GameobjectModelData> ModelList; ModelList model_list; -void LoadGameObjectModelList() +void LoadGameObjectModelList(std::string const& dataPath) { #ifndef NO_CORE_FUNCS uint32 oldMSTime = getMSTime(); #endif - FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); + FILE* model_list_file = fopen((dataPath + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); if (!model_list_file) { VMAP_ERROR_LOG("misc", "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); @@ -84,7 +80,7 @@ void LoadGameObjectModelList() model_list.insert ( - ModelList::value_type( displayId, GameobjectModelData(std::string(buff, name_length), AABox(v1, v2)) ) + ModelList::value_type(displayId, GameobjectModelData(std::string(buff, name_length), AABox(v1, v2))) ); } @@ -98,9 +94,9 @@ GameObjectModel::~GameObjectModel() ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->releaseModelInstance(name); } -bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info) +bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath) { - ModelList::const_iterator it = model_list.find(info.Displayid); + ModelList::const_iterator it = model_list.find(modelOwner->GetDisplayId()); if (it == model_list.end()) return false; @@ -112,21 +108,18 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn return false; } - iModel = ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->acquireModelInstance(sWorld->GetDataPath() + "vmaps/", it->second.name); + iModel = ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->acquireModelInstance(dataPath + "vmaps/", it->second.name); if (!iModel) return false; name = it->second.name; - //flags = VMAP::MOD_M2; - //adtId = 0; - //ID = 0; - iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ()); - phasemask = go.GetPhaseMask(); - iScale = go.GetObjectScale(); + iPos = modelOwner->GetPosition(); + phasemask = modelOwner->GetPhaseMask(); + iScale = modelOwner->GetScale(); iInvScale = 1.f / iScale; - G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(go.GetOrientation(), 0, 0); + G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(modelOwner->GetOrientation(), 0, 0); iInvRot = iRotation.inverse(); // transform bounding box: mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale); @@ -140,22 +133,18 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn for (int i = 0; i < 8; ++i) { Vector3 pos(iBound.corner(i)); - go.SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN); + modelOwner->DebugVisualizeCorner(pos); } #endif - owner = &go; + owner = std::move(modelOwner); return true; } -GameObjectModel* GameObjectModel::Create(const GameObject& go) +GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath) { - const GameObjectDisplayInfoEntry* info = sGameObjectDisplayInfoStore.LookupEntry(go.GetDisplayId()); - if (!info) - return NULL; - GameObjectModel* mdl = new GameObjectModel(); - if (!mdl->initialize(go, *info)) + if (!mdl->initialize(std::move(modelOwner), dataPath)) { delete mdl; return NULL; @@ -166,7 +155,7 @@ GameObjectModel* GameObjectModel::Create(const GameObject& go) bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const { - if (!(phasemask & ph_mask) || !owner->isSpawned()) + if (!(phasemask & ph_mask) || !owner->IsSpawned()) return false; float time = ray.intersectionTime(iBound); @@ -203,7 +192,7 @@ bool GameObjectModel::UpdatePosition() return false; } - iPos = Vector3(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ()); + iPos = owner->GetPosition(); G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(owner->GetOrientation(), 0, 0); iInvRot = iRotation.inverse(); @@ -219,7 +208,7 @@ bool GameObjectModel::UpdatePosition() for (int i = 0; i < 8; ++i) { Vector3 pos(iBound.corner(i)); - owner->SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN); + owner->DebugVisualizeCorner(pos); } #endif diff --git a/src/server/collision/Models/GameObjectModel.h b/src/server/collision/Models/GameObjectModel.h index 43d299d6d8f..17669189af5 100644 --- a/src/server/collision/Models/GameObjectModel.h +++ b/src/server/collision/Models/GameObjectModel.h @@ -25,6 +25,7 @@ #include <G3D/Ray.h> #include "Define.h" +#include <memory> namespace VMAP { @@ -34,21 +35,21 @@ namespace VMAP class GameObject; struct GameObjectDisplayInfoEntry; -class GameObjectModel /*, public Intersectable*/ +class GameObjectModelOwnerBase { - uint32 phasemask; - G3D::AABox iBound; - G3D::Matrix3 iInvRot; - G3D::Vector3 iPos; - //G3D::Vector3 iRot; - float iInvScale; - float iScale; - VMAP::WorldModel* iModel; - GameObject const* owner; - - GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL), owner(NULL) { } - bool initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info); +public: + virtual bool IsSpawned() const { return false; } + virtual uint32 GetDisplayId() const { return 0; } + virtual uint32 GetPhaseMask() const { return 0; } + virtual G3D::Vector3 GetPosition() const { return G3D::Vector3::zero(); } + virtual float GetOrientation() const { return 0.0f; } + virtual float GetScale() const { return 1.0f; } + virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const { } +}; +class GameObjectModel /*, public Intersectable*/ +{ + GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { } public: std::string name; @@ -66,9 +67,21 @@ public: bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const; - static GameObjectModel* Create(const GameObject& go); + static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath); bool UpdatePosition(); + +private: + bool initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath); + + uint32 phasemask; + G3D::AABox iBound; + G3D::Matrix3 iInvRot; + G3D::Vector3 iPos; + float iInvScale; + float iScale; + VMAP::WorldModel* iModel; + std::unique_ptr<GameObjectModelOwnerBase> owner; }; #endif // _GAMEOBJECT_MODEL_H diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index efe55830b1b..1939c96dac9 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -22,6 +22,7 @@ #include "Define.h" #include "Unit.h" #include "Containers.h" +#include "EventMap.h" #include <list> class Player; diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 96a25588120..d76d106e81a 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -140,6 +140,30 @@ void CreatureAI::MoveInLineOfSight(Unit* who) // me->GetMotionMaster()->MoveChase(who->GetVictim()); } +// Distract creature, if player gets too close while stealthed/prowling +void CreatureAI::TriggerAlert(Unit const* who) const +{ + // If there's no target, or target isn't a player do nothing + if (!who || who->GetTypeId() != TYPEID_PLAYER) + return; + + // If this unit isn't an NPC, is already distracted, is in combat, is confused, stunned or fleeing, do nothing + if (me->GetTypeId() != TYPEID_UNIT || me->IsInCombat() || me->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED)) + return; + + // Only alert for hostiles! + if (me->IsCivilian() || me->HasReactState(REACT_PASSIVE) || !me->IsHostileTo(who) || !me->_IsTargetAcceptable(who)) + return; + + // Send alert sound (if any) for this creature + me->SendAIReaction(AI_REACTION_ALERT); + + // Face the unit (stealthed player) and set distracted state for 5 seconds + me->SetFacingTo(me->GetAngle(who->GetPositionX(), who->GetPositionY())); + me->StopMoving(); + me->GetMotionMaster()->MoveDistract(5 * IN_MILLISECONDS); +} + void CreatureAI::EnterEvadeMode() { if (!_EnterEvadeMode()) diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 2e862c37c0e..a205ef16833 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -89,6 +89,9 @@ class CreatureAI : public UnitAI // Called if IsVisible(Unit* who) is true at each who move, reaction at visibility zone enter void MoveInLineOfSight_Safe(Unit* who); + // Trigger Creature "Alert" state (creature can see stealthed unit) + void TriggerAlert(Unit const* who) const; + // Called in Creature::Update when deathstate = DEAD. Inherited classes may maniuplate the ability to respawn based on scripted events. virtual bool CanRespawn() { return true; } @@ -119,7 +122,7 @@ class CreatureAI : public UnitAI // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc) virtual void AttackedBy(Unit* /*attacker*/) { } - virtual bool IsEscorted() { return false; } + virtual bool IsEscorted() const { return false; } // Called when creature is spawned or respawned (for reseting variables) virtual void JustRespawned() { Reset(); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index ed87804474a..f1c53e2f9eb 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -120,7 +120,13 @@ void npc_escortAI::MoveInLineOfSight(Unit* who) { if (!me->GetVictim()) { - who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); + // Clear distracted state on combat + if (me->HasUnitState(UNIT_STATE_DISTRACTED)) + { + me->ClearUnitState(UNIT_STATE_DISTRACTED); + me->GetMotionMaster()->Clear(); + } + AttackStart(who); } else if (me->GetMap()->IsDungeon()) diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h index 75ff1b8dfc9..1d71652c948 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h @@ -94,16 +94,16 @@ struct npc_escortAI : public ScriptedAI void SetEscortPaused(bool on); bool HasEscortState(uint32 escortState) { return (m_uiEscortState & escortState) != 0; } - virtual bool IsEscorted() override { return (m_uiEscortState & STATE_ESCORT_ESCORTING); } + virtual bool IsEscorted() const override { return (m_uiEscortState & STATE_ESCORT_ESCORTING); } void SetMaxPlayerDistance(float newMax) { MaxPlayerDistance = newMax; } - float GetMaxPlayerDistance() { return MaxPlayerDistance; } + float GetMaxPlayerDistance() const { return MaxPlayerDistance; } void SetDespawnAtEnd(bool despawn) { DespawnAtEnd = despawn; } void SetDespawnAtFar(bool despawn) { DespawnAtFar = despawn; } - bool GetAttack() { return m_bIsActiveAttacker; }//used in EnterEvadeMode override + bool GetAttack() const { return m_bIsActiveAttacker; }//used in EnterEvadeMode override void SetCanAttack(bool attack) { m_bIsActiveAttacker = attack; } - ObjectGuid GetEventStarterGUID() { return m_uiPlayerGUID; } + ObjectGuid GetEventStarterGUID() const { return m_uiPlayerGUID; } protected: Player* GetPlayerForEscort() { return ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index 7fd21a8f791..8985f722cf2 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -117,7 +117,13 @@ void FollowerAI::MoveInLineOfSight(Unit* who) { if (!me->GetVictim()) { - who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); + // Clear distracted state on combat + if (me->HasUnitState(UNIT_STATE_DISTRACTED)) + { + me->ClearUnitState(UNIT_STATE_DISTRACTED); + me->GetMotionMaster()->Clear(); + } + AttackStart(who); } else if (me->GetMap()->IsDungeon()) diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 21a15fa4f99..1a51bb2d897 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -469,7 +469,13 @@ void SmartAI::MoveInLineOfSight(Unit* who) { if (!me->GetVictim()) { - who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); + // Clear distracted state on combat + if (me->HasUnitState(UNIT_STATE_DISTRACTED)) + { + me->ClearUnitState(UNIT_STATE_DISTRACTED); + me->GetMotionMaster()->Clear(); + } + AttackStart(who); } else/* if (me->GetMap()->IsDungeon())*/ @@ -763,6 +769,9 @@ void SmartAI::SetCombatMove(bool on) } else { + if (me->HasUnitState(UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE)) + return; + me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->Clear(true); me->StopMoving(); diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 8efde6b180a..1e287cd5b9e 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -214,7 +214,7 @@ class SmartAI : public CreatureAI uint32 mWPPauseTimer; WayPoint* mLastWP; Position mLastOOCPos;//set on enter combat - uint32 GetWPCount() { return mWayPoints ? mWayPoints->size() : 0; } + uint32 GetWPCount() const { return mWayPoints ? uint32(mWayPoints->size()) : 0; } bool mCanRepeatPath; bool mRun; bool mCanAutoAttack; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 267c038faaf..9fa2269fd8b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -765,6 +765,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u player->GroupEventHappens(e.action.quest.quest, GetBaseObject()); break; } + case SMART_ACTION_COMBAT_STOP: + { + if (!me) + break; + + me->CombatStop(true); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_COMBAT_STOP: %s CombatStop", me->GetGUID().ToString().c_str()); + break; + } case SMART_ACTION_REMOVEAURASFROMSPELL: { ObjectList* targets = GetTargets(e, unit); @@ -895,8 +904,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } else if (IsUnit(*itr)) // Special handling for vehicles if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) - for (SeatMap::iterator itr = vehicle->Seats.begin(); itr != vehicle->Seats.end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(itr->second.Passenger.Guid)) + for (SeatMap::iterator seatItr = vehicle->Seats.begin(); seatItr != vehicle->Seats.end(); ++seatItr) + if (Player* player = ObjectAccessor::FindPlayer(seatItr->second.Passenger.Guid)) player->KilledMonsterCredit(e.action.killedMonster.creature); } @@ -1721,7 +1730,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsUnit(*itr)) continue; - Unit* unit = (*itr)->ToUnit(); + Unit* targetUnit = (*itr)->ToUnit(); bool interruptedSpell = false; @@ -1734,11 +1743,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { if (!interruptedSpell && e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) { - unit->InterruptNonMeleeSpells(false); + targetUnit->InterruptNonMeleeSpells(false); interruptedSpell = true; } - unit->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0); + targetUnit->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0); } else TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*it)->GetGUID().ToString().c_str()); @@ -3257,10 +3266,6 @@ void SmartScript::InitTimer(SmartScriptHolder& e) case SMART_EVENT_UPDATE_OOC: RecalcTimer(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max); break; - case SMART_EVENT_IC_LOS: - case SMART_EVENT_OOC_LOS: - RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); - break; case SMART_EVENT_DISTANCE_CREATURE: case SMART_EVENT_DISTANCE_GAMEOBJECT: RecalcTimer(e, e.event.distance.repeat, e.event.distance.repeat); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 37187d9b04c..6ccc581c54e 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1135,6 +1135,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_STORE_TARGET_LIST: case SMART_ACTION_EVADE: case SMART_ACTION_FLEE_FOR_ASSIST: + case SMART_ACTION_COMBAT_STOP: case SMART_ACTION_DIE: case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: case SMART_ACTION_SET_ACTIVE: @@ -1228,11 +1229,11 @@ bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) default: if (e.entryOrGuid < 0) { - entry = uint32(std::abs(e.entryOrGuid)); - CreatureData const* data = sObjectMgr->GetCreatureData(entry); + ObjectGuid::LowType guid = ObjectGuid::LowType(-e.entryOrGuid); + CreatureData const* data = sObjectMgr->GetCreatureData(guid); if (!data) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), guid); return false; } else diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 1f4891d6c24..8565c5d3497 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -452,7 +452,7 @@ enum SMART_ACTION SMART_ACTION_EVADE = 24, // No Params SMART_ACTION_FLEE_FOR_ASSIST = 25, // With Emote SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // QuestID - // none = 27, + SMART_ACTION_COMBAT_STOP = 27, // SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid (0 removes all auras), charges (0 removes aura) SMART_ACTION_FOLLOW = 29, // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event) SMART_ACTION_RANDOM_PHASE = 30, // PhaseId1, PhaseId2, PhaseId3... diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 54ef1a34766..74ff060636e 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -1,265 +1,265 @@ -/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "RBAC.h"
-#include "AccountMgr.h"
-#include "DatabaseEnv.h"
-#include "Log.h"
-
-namespace rbac
-{
-
-std::string GetDebugPermissionString(RBACPermissionContainer const& perms)
-{
- std::string str = "";
- if (!perms.empty())
- {
- std::ostringstream o;
- RBACPermissionContainer::const_iterator itr = perms.begin();
- o << (*itr);
- for (++itr; itr != perms.end(); ++itr)
- o << ", " << uint32(*itr);
- str = o.str();
- }
-
- return str;
-}
-
-RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/)
-{
- // Check if permission Id exists
- RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
- if (!perm)
- {
- TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_ID_DOES_NOT_EXISTS;
- }
-
- // Check if already added in denied list
- if (HasDeniedPermission(permissionId))
- {
- TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_IN_DENIED_LIST;
- }
-
- // Already added?
- if (HasGrantedPermission(permissionId))
- {
- TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_CANT_ADD_ALREADY_ADDED;
- }
-
- AddGrantedPermission(permissionId);
-
- // Do not save to db when loading data from DB (realmId = 0)
- if (realmId)
- {
- TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
- GetId(), GetName().c_str(), permissionId, realmId);
- SavePermission(permissionId, true, realmId);
- CalculateNewPermissions();
- }
- else
- TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
- GetId(), GetName().c_str(), permissionId, realmId);
-
- return RBAC_OK;
-}
-
-RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* = 0*/)
-{
- // Check if permission Id exists
- RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId);
- if (!perm)
- {
- TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_ID_DOES_NOT_EXISTS;
- }
-
- // Check if already added in granted list
- if (HasGrantedPermission(permissionId))
- {
- TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_IN_GRANTED_LIST;
- }
-
- // Already added?
- if (HasDeniedPermission(permissionId))
- {
- TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_CANT_ADD_ALREADY_ADDED;
- }
-
- AddDeniedPermission(permissionId);
-
- // Do not save to db when loading data from DB (realmId = 0)
- if (realmId)
- {
- TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
- GetId(), GetName().c_str(), permissionId, realmId);
- SavePermission(permissionId, false, realmId);
- CalculateNewPermissions();
- }
- else
- TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
- GetId(), GetName().c_str(), permissionId, realmId);
-
- return RBAC_OK;
-}
-
-void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId)
-{
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION);
- stmt->setUInt32(0, GetId());
- stmt->setUInt32(1, permission);
- stmt->setBool(2, granted);
- stmt->setInt32(3, realmId);
- LoginDatabase.Execute(stmt);
-}
-
-RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/)
-{
- // Check if it's present in any list
- if (!HasGrantedPermission(permissionId) && !HasDeniedPermission(permissionId))
- {
- TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked",
- GetId(), GetName().c_str(), permissionId, realmId);
- return RBAC_CANT_REVOKE_NOT_IN_LIST;
- }
-
- RemoveGrantedPermission(permissionId);
- RemoveDeniedPermission(permissionId);
-
- // Do not save to db when loading data from DB (realmId = 0)
- if (realmId)
- {
- TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated",
- GetId(), GetName().c_str(), permissionId, realmId);
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION);
- stmt->setUInt32(0, GetId());
- stmt->setUInt32(1, permissionId);
- stmt->setInt32(2, realmId);
- LoginDatabase.Execute(stmt);
-
- CalculateNewPermissions();
- }
- else
- TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok",
- GetId(), GetName().c_str(), permissionId, realmId);
-
- return RBAC_OK;
-}
-
-void RBACData::LoadFromDB()
-{
- ClearData();
-
- TC_LOG_DEBUG("rbac", "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str());
- // Load account permissions (granted and denied) that affect current realm
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS);
- stmt->setUInt32(0, GetId());
- stmt->setInt32(1, GetRealmId());
-
- PreparedQueryResult result = LoginDatabase.Query(stmt);
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- if (fields[1].GetBool())
- GrantPermission(fields[0].GetUInt32());
- else
- DenyPermission(fields[0].GetUInt32());
- }
- while (result->NextRow());
- }
-
- // Add default permissions
- RBACPermissionContainer const& permissions = sAccountMgr->GetRBACDefaultPermissions(_secLevel);
- for (RBACPermissionContainer::const_iterator itr = permissions.begin(); itr != permissions.end(); ++itr)
- GrantPermission(*itr);
-
- // Force calculation of permissions
- CalculateNewPermissions();
-}
-
-void RBACData::CalculateNewPermissions()
-{
- TC_LOG_TRACE("rbac", "RBACData::CalculateNewPermissions [Id: %u Name: %s]", GetId(), GetName().c_str());
-
- // Get the list of granted permissions
- _globalPerms = GetGrantedPermissions();
- ExpandPermissions(_globalPerms);
- RBACPermissionContainer revoked = GetDeniedPermissions();
- ExpandPermissions(revoked);
- RemovePermissions(_globalPerms, revoked);
-}
-
-void RBACData::AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
-{
- for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
- permsTo.insert(*itr);
-}
-
-void RBACData::RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo)
-{
- for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr)
- permsTo.erase(*itr);
-}
-
-void RBACData::ExpandPermissions(RBACPermissionContainer& permissions)
-{
- RBACPermissionContainer toCheck = permissions;
- permissions.clear();
-
- while (!toCheck.empty())
- {
- // remove the permission from original list
- uint32 permissionId = *toCheck.begin();
- toCheck.erase(toCheck.begin());
-
- RBACPermission const* permission = sAccountMgr->GetRBACPermission(permissionId);
- if (!permission)
- continue;
-
- // insert into the final list (expanded list)
- permissions.insert(permissionId);
-
- // add all linked permissions (that are not already expanded) to the list of permissions to be checked
- RBACPermissionContainer const& linkedPerms = permission->GetLinkedPermissions();
- for (RBACPermissionContainer::const_iterator itr = linkedPerms.begin(); itr != linkedPerms.end(); ++itr)
- if (permissions.find(*itr) == permissions.end())
- toCheck.insert(*itr);
- }
-
- TC_LOG_DEBUG("rbac", "RBACData::ExpandPermissions: Expanded: %s", GetDebugPermissionString(permissions).c_str());
-}
-
-void RBACData::ClearData()
-{
- _grantedPerms.clear();
- _deniedPerms.clear();
- _globalPerms.clear();
-}
-
-}
+/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "RBAC.h" +#include "AccountMgr.h" +#include "DatabaseEnv.h" +#include "Log.h" + +namespace rbac +{ + +std::string GetDebugPermissionString(RBACPermissionContainer const& perms) +{ + std::string str = ""; + if (!perms.empty()) + { + std::ostringstream o; + RBACPermissionContainer::const_iterator itr = perms.begin(); + o << (*itr); + for (++itr; itr != perms.end(); ++itr) + o << ", " << uint32(*itr); + str = o.str(); + } + + return str; +} + +RBACCommandResult RBACData::GrantPermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if permission Id exists + RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); + if (!perm) + { + TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_ID_DOES_NOT_EXISTS; + } + + // Check if already added in denied list + if (HasDeniedPermission(permissionId)) + { + TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in deny list", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_IN_DENIED_LIST; + } + + // Already added? + if (HasGrantedPermission(permissionId)) + { + TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already granted", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_CANT_ADD_ALREADY_ADDED; + } + + AddGrantedPermission(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), permissionId, realmId); + SavePermission(permissionId, true, realmId); + CalculateNewPermissions(); + } + else + TC_LOG_TRACE("rbac", "RBACData::GrantPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok", + GetId(), GetName().c_str(), permissionId, realmId); + + return RBAC_OK; +} + +RBACCommandResult RBACData::DenyPermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if permission Id exists + RBACPermission const* perm = sAccountMgr->GetRBACPermission(permissionId); + if (!perm) + { + TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission does not exists", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_ID_DOES_NOT_EXISTS; + } + + // Check if already added in granted list + if (HasGrantedPermission(permissionId)) + { + TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission in grant list", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_IN_GRANTED_LIST; + } + + // Already added? + if (HasDeniedPermission(permissionId)) + { + TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Permission already denied", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_CANT_ADD_ALREADY_ADDED; + } + + AddDeniedPermission(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), permissionId, realmId); + SavePermission(permissionId, false, realmId); + CalculateNewPermissions(); + } + else + TC_LOG_TRACE("rbac", "RBACData::DenyPermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok", + GetId(), GetName().c_str(), permissionId, realmId); + + return RBAC_OK; +} + +void RBACData::SavePermission(uint32 permission, bool granted, int32 realmId) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, permission); + stmt->setBool(2, granted); + stmt->setInt32(3, realmId); + LoginDatabase.Execute(stmt); +} + +RBACCommandResult RBACData::RevokePermission(uint32 permissionId, int32 realmId /* = 0*/) +{ + // Check if it's present in any list + if (!HasGrantedPermission(permissionId) && !HasDeniedPermission(permissionId)) + { + TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Not granted or revoked", + GetId(), GetName().c_str(), permissionId, realmId); + return RBAC_CANT_REVOKE_NOT_IN_LIST; + } + + RemoveGrantedPermission(permissionId); + RemoveDeniedPermission(permissionId); + + // Do not save to db when loading data from DB (realmId = 0) + if (realmId) + { + TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok and DB updated", + GetId(), GetName().c_str(), permissionId, realmId); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, permissionId); + stmt->setInt32(2, realmId); + LoginDatabase.Execute(stmt); + + CalculateNewPermissions(); + } + else + TC_LOG_TRACE("rbac", "RBACData::RevokePermission [Id: %u Name: %s] (Permission %u, RealmId %d). Ok", + GetId(), GetName().c_str(), permissionId, realmId); + + return RBAC_OK; +} + +void RBACData::LoadFromDB() +{ + ClearData(); + + TC_LOG_DEBUG("rbac", "RBACData::LoadFromDB [Id: %u Name: %s]: Loading permissions", GetId(), GetName().c_str()); + // Load account permissions (granted and denied) that affect current realm + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS); + stmt->setUInt32(0, GetId()); + stmt->setInt32(1, GetRealmId()); + + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + { + do + { + Field* fields = result->Fetch(); + if (fields[1].GetBool()) + GrantPermission(fields[0].GetUInt32()); + else + DenyPermission(fields[0].GetUInt32()); + } + while (result->NextRow()); + } + + // Add default permissions + RBACPermissionContainer const& permissions = sAccountMgr->GetRBACDefaultPermissions(_secLevel); + for (RBACPermissionContainer::const_iterator itr = permissions.begin(); itr != permissions.end(); ++itr) + GrantPermission(*itr); + + // Force calculation of permissions + CalculateNewPermissions(); +} + +void RBACData::CalculateNewPermissions() +{ + TC_LOG_TRACE("rbac", "RBACData::CalculateNewPermissions [Id: %u Name: %s]", GetId(), GetName().c_str()); + + // Get the list of granted permissions + _globalPerms = GetGrantedPermissions(); + ExpandPermissions(_globalPerms); + RBACPermissionContainer revoked = GetDeniedPermissions(); + ExpandPermissions(revoked); + RemovePermissions(_globalPerms, revoked); +} + +void RBACData::AddPermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo) +{ + for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr) + permsTo.insert(*itr); +} + +void RBACData::RemovePermissions(RBACPermissionContainer const& permsFrom, RBACPermissionContainer& permsTo) +{ + for (RBACPermissionContainer::const_iterator itr = permsFrom.begin(); itr != permsFrom.end(); ++itr) + permsTo.erase(*itr); +} + +void RBACData::ExpandPermissions(RBACPermissionContainer& permissions) +{ + RBACPermissionContainer toCheck = permissions; + permissions.clear(); + + while (!toCheck.empty()) + { + // remove the permission from original list + uint32 permissionId = *toCheck.begin(); + toCheck.erase(toCheck.begin()); + + RBACPermission const* permission = sAccountMgr->GetRBACPermission(permissionId); + if (!permission) + continue; + + // insert into the final list (expanded list) + permissions.insert(permissionId); + + // add all linked permissions (that are not already expanded) to the list of permissions to be checked + RBACPermissionContainer const& linkedPerms = permission->GetLinkedPermissions(); + for (RBACPermissionContainer::const_iterator itr = linkedPerms.begin(); itr != linkedPerms.end(); ++itr) + if (permissions.find(*itr) == permissions.end()) + toCheck.insert(*itr); + } + + TC_LOG_DEBUG("rbac", "RBACData::ExpandPermissions: Expanded: %s", GetDebugPermissionString(permissions).c_str()); +} + +void RBACData::ClearData() +{ + _grantedPerms.clear(); + _deniedPerms.clear(); + _globalPerms.clear(); +} + +} diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 339788dee01..bf28d76ab9c 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -889,7 +889,7 @@ class RBACData */ void CalculateNewPermissions(); - int32 GetRealmId() { return _realmId; } + int32 GetRealmId() const { return _realmId; } // Auxiliar private functions - defined to allow to maintain same code even // if internal structure changes. diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 16d5f4b6959..4b48f1f341b 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -293,7 +293,7 @@ void AuctionHouseMgr::LoadAuctionItems() ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry); if (!proto) { - TC_LOG_ERROR("misc", "AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid, itemEntry); + TC_LOG_ERROR("misc", "AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u item entry: #%u) in auction, skipped.", item_guid, itemEntry); continue; } diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp index c0c753100bc..c905ccedf2d 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp @@ -97,6 +97,11 @@ void AuctionBotConfig::SetConfig(AuctionBotConfigBoolValues index, char const* f SetConfig(index, sConfigMgr->GetBoolDefault(fieldname, defvalue)); } +void AuctionBotConfig::SetConfig(AuctionBotConfigFloatValues index, char const* fieldname, float defvalue) +{ + SetConfig(index, sConfigMgr->GetFloatDefault(fieldname, defvalue)); +} + //Get AuctionHousebot configuration file void AuctionBotConfig::GetConfigFromFile() { @@ -111,6 +116,8 @@ void AuctionBotConfig::GetConfigFromFile() SetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED, "AuctionHouseBot.Buyer.Horde.Enabled", false); SetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED, "AuctionHouseBot.Buyer.Neutral.Enabled", false); + SetConfig(CONFIG_AHBOT_BUYER_CHANCE_FACTOR, "AuctionHouseBot.Buyer.ChanceFactor", 2.0f); + SetConfig(CONFIG_AHBOT_ITEMS_VENDOR, "AuctionHouseBot.Items.Vendor", false); SetConfig(CONFIG_AHBOT_ITEMS_LOOT, "AuctionHouseBot.Items.Loot", true); SetConfig(CONFIG_AHBOT_ITEMS_MISC, "AuctionHouseBot.Items.Misc", false); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h index d7570c37d44..225d3b7ee25 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h @@ -174,6 +174,12 @@ enum AuctionBotConfigBoolValues CONFIG_UINT32_AHBOT_BOOL_COUNT }; +enum AuctionBotConfigFloatValues +{ + CONFIG_AHBOT_BUYER_CHANCE_FACTOR, + CONFIG_AHBOT_FLOAT_COUNT +}; + // All basic config data used by other AHBot classes for self-configure. class AuctionBotConfig { @@ -196,8 +202,10 @@ public: uint32 GetConfig(AuctionBotConfigUInt32Values index) const { return _configUint32Values[index]; } bool GetConfig(AuctionBotConfigBoolValues index) const { return _configBoolValues[index]; } + float GetConfig(AuctionBotConfigFloatValues index) const { return _configFloatValues[index]; } void SetConfig(AuctionBotConfigBoolValues index, bool value) { _configBoolValues[index] = value; } void SetConfig(AuctionBotConfigUInt32Values index, uint32 value) { _configUint32Values[index] = value; } + void SetConfig(AuctionBotConfigFloatValues index, float value) { _configFloatValues[index] = value; } uint32 GetConfigItemAmountRatio(AuctionHouseType houseType) const; bool GetConfigBuyerEnabled(AuctionHouseType houseType) const; @@ -217,6 +225,7 @@ private: uint32 _configUint32Values[CONFIG_UINT32_AHBOT_UINT32_COUNT]; bool _configBoolValues[CONFIG_UINT32_AHBOT_BOOL_COUNT]; + float _configFloatValues[CONFIG_AHBOT_FLOAT_COUNT]; void SetAHBotIncludes(const std::string& AHBotIncludes) { _AHBotIncludes = AHBotIncludes; } void SetAHBotExcludes(const std::string& AHBotExcludes) { _AHBotExcludes = AHBotExcludes; } @@ -225,6 +234,7 @@ private: void SetConfigMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 maxvalue); void SetConfigMinMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue); void SetConfig(AuctionBotConfigBoolValues index, char const* fieldname, bool defvalue); + void SetConfig(AuctionBotConfigFloatValues index, char const* fieldname, float defvalue); void GetConfigFromFile(); }; diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp index 64463948574..4bf6aa950c6 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp @@ -157,18 +157,18 @@ bool AuctionBotBuyer::RollBuyChance(const BuyerItemInfo* ahInfo, const Item* ite if (!auction->buyout) return false; - uint32 itemBuyPrice = auction->buyout / item->GetCount(); - uint32 itemPrice = item->GetTemplate()->SellPrice ? item->GetTemplate()->SellPrice : GetVendorPrice(item->GetTemplate()->Quality); + float itemBuyPrice = float(auction->buyout / item->GetCount()); + float itemPrice = float(item->GetTemplate()->SellPrice ? item->GetTemplate()->SellPrice : GetVendorPrice(item->GetTemplate()->Quality)); // The AH cut needs to be added to the price, but we dont want a 100% chance to buy if the price is exactly AH default itemPrice *= 1.4f; // This value is between 0 and 100 and is used directly as the chance to buy or bid // Value equal or above 100 means 100% chance and value below 0 means 0% chance - float chance = 100 / sqrt(itemBuyPrice / float(itemPrice)); + float chance = std::min(100.f, std::pow(100.f, 1.f + (1.f - itemBuyPrice / itemPrice) / sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_FACTOR))); // If a player has bidded on item, have fifth of normal chance if (auction->bidder) - chance = chance / 5; + chance = chance / 5.f; if (ahInfo) { @@ -178,31 +178,29 @@ bool AuctionBotBuyer::RollBuyChance(const BuyerItemInfo* ahInfo, const Item* ite // If there are more than 5 items on AH of this entry, try weigh in the average buyout price if (ahInfo->BuyItemCount > 5) - { - chance *= 1 / sqrt(itemBuyPrice / avgBuyPrice); - } + chance *= 1.f / std::sqrt(itemBuyPrice / avgBuyPrice); } // Add config weigh in for quality chance *= GetChanceMultiplier(item->GetTemplate()->Quality) / 100.0f; - float rand = frand(0, 100); + float rand = frand(0.f, 100.f); bool win = rand <= chance; - TC_LOG_DEBUG("ahbot", "AHBot: %s BUY! chance = %.2f, price = %u, buyprice = %u.", win ? "WIN" : "LOSE", chance, itemPrice, itemBuyPrice); + TC_LOG_DEBUG("ahbot", "AHBot: %s BUY! chance = %.2f, price = %u, buyprice = %u.", win ? "WIN" : "LOSE", chance, uint32(itemPrice), uint32(itemBuyPrice)); return win; } // ahInfo can be NULL bool AuctionBotBuyer::RollBidChance(const BuyerItemInfo* ahInfo, const Item* item, const AuctionEntry* auction, uint32 bidPrice) { - uint32 itemBidPrice = bidPrice / item->GetCount(); - uint32 itemPrice = item->GetTemplate()->SellPrice ? item->GetTemplate()->SellPrice : GetVendorPrice(item->GetTemplate()->Quality); + float itemBidPrice = float(bidPrice / item->GetCount()); + float itemPrice = float(item->GetTemplate()->SellPrice ? item->GetTemplate()->SellPrice : GetVendorPrice(item->GetTemplate()->Quality)); // The AH cut needs to be added to the price, but we dont want a 100% chance to buy if the price is exactly AH default itemPrice *= 1.4f; // This value is between 0 and 100 and is used directly as the chance to buy or bid // Value equal or above 100 means 100% chance and value below 0 means 0% chance - float chance = 100 / sqrt(itemBidPrice / float(itemPrice)); + float chance = std::min(100.f, std::pow(100.f, 1.f + (1.f - itemBidPrice / itemPrice) / sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_FACTOR))); if (ahInfo) { @@ -212,21 +210,19 @@ bool AuctionBotBuyer::RollBidChance(const BuyerItemInfo* ahInfo, const Item* ite // If there are more than 5 items on AH of this entry, try weigh in the average bid price if (ahInfo->BidItemCount >= 5) - { - chance *= 1 / sqrt(itemBidPrice / avgBidPrice); - } + chance *= 1.f / std::sqrt(itemBidPrice / avgBidPrice); } // If a player has bidded on item, have fifth of normal chance if (auction->bidder) - chance = chance / 5; + chance = chance / 5.f; // Add config weigh in for quality chance *= GetChanceMultiplier(item->GetTemplate()->Quality) / 100.0f; - float rand = frand(0, 100); + float rand = frand(0.f, 100.f); bool win = rand <= chance; - TC_LOG_DEBUG("ahbot", "AHBot: %s BID! chance = %.2f, price = %u, bidprice = %u.", win ? "WIN" : "LOSE", chance, itemPrice, itemBidPrice); + TC_LOG_DEBUG("ahbot", "AHBot: %s BID! chance = %.2f, price = %u, bidprice = %u.", win ? "WIN" : "LOSE", chance, uint32(itemPrice), uint32(itemBidPrice)); return win; } diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 3dbe974f0af..c860d36e712 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -99,7 +99,7 @@ class BfCapturePoint GameObject* GetCapturePointGo(); uint32 GetCapturePointEntry() const { return m_capturePointEntry; } - TeamId GetTeamId() { return m_team; } + TeamId GetTeamId() const { return m_team; } protected: bool DelCapturePoint(); @@ -220,18 +220,18 @@ class Battlefield : public ZoneScript /// Called when a Unit is kill in battlefield zone virtual void HandleKill(Player* /*killer*/, Unit* /*killed*/) { }; - uint32 GetTypeId() { return m_TypeId; } - uint32 GetZoneId() { return m_ZoneId; } + uint32 GetTypeId() const { return m_TypeId; } + uint32 GetZoneId() const { return m_ZoneId; } void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0); /// Return true if battle is start, false if battle is not started - bool IsWarTime() { return m_isActive; } + bool IsWarTime() const { return m_isActive; } /// Enable or Disable battlefield void ToggleBattlefield(bool enable) { m_IsEnabled = enable; } /// Return if battlefield is enable - bool IsEnabled() { return m_IsEnabled; } + bool IsEnabled() const { return m_IsEnabled; } /** * \brief Kick player from battlefield and teleport him to kick-point location @@ -254,9 +254,9 @@ class Battlefield : public ZoneScript virtual void UpdateData(uint32 index, int32 pad) { m_Data32[index] += pad; } // Battlefield - generic methods - TeamId GetDefenderTeam() { return m_DefenderTeam; } - TeamId GetAttackerTeam() { return TeamId(1 - m_DefenderTeam); } - TeamId GetOtherTeam(TeamId team) { return (team == TEAM_HORDE ? TEAM_ALLIANCE : TEAM_HORDE); } + TeamId GetDefenderTeam() const { return m_DefenderTeam; } + TeamId GetAttackerTeam() const { return TeamId(1 - m_DefenderTeam); } + TeamId GetOtherTeam(TeamId team) const { return (team == TEAM_HORDE ? TEAM_ALLIANCE : TEAM_HORDE); } void SetDefenderTeam(TeamId team) { m_DefenderTeam = team; } // Group methods @@ -308,7 +308,7 @@ class Battlefield : public ZoneScript void PlayerAcceptInviteToQueue(Player* player); void PlayerAcceptInviteToWar(Player* player); - uint32 GetBattleId() { return m_BattleId; } + uint32 GetBattleId() const { return m_BattleId; } void AskToLeaveQueue(Player* player); virtual void DoCompleteOrIncrementAchievement(uint32 /*achievement*/, Player* /*player*/, uint8 /*incrementNumber = 1*/) { } @@ -328,9 +328,9 @@ class Battlefield : public ZoneScript void HideNpc(Creature* creature); void ShowNpc(Creature* creature, bool aggressive); - GraveyardVect GetGraveyardVector() { return m_GraveyardList; } + GraveyardVect GetGraveyardVector() const { return m_GraveyardList; } - uint32 GetTimer() { return m_Timer; } + uint32 GetTimer() const { return m_Timer; } void SetTimer(uint32 timer) { m_Timer = timer; } void DoPlaySoundToAll(uint32 SoundID); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 47196876126..dcad65afa85 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -149,7 +149,7 @@ class BfGraveyardWG : public BfGraveyard BfGraveyardWG(BattlefieldWG* Bf); void SetTextId(uint32 textId) { m_GossipTextId = textId; } - uint32 GetTextId() { return m_GossipTextId; } + uint32 GetTextId() const { return m_GossipTextId; } protected: uint32 m_GossipTextId; diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index b8f90ce7f1e..d54f7814137 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -21,8 +21,8 @@ #include "Log.h" #include "DatabaseEnv.h" #include "Language.h" -#include "ObjectAccessor.h" #include "Player.h" +#include "ObjectAccessor.h" ArenaTeamMgr::ArenaTeamMgr() { diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 562a20b340f..08134298569 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -26,6 +26,7 @@ #include "WorldPacket.h" #include "Object.h" #include "GameObject.h" +#include "EventMap.h" class Creature; class GameObject; diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 43b7acde925..d9950f4ccbc 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -290,10 +290,11 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) itr = m_QueuedPlayers.find(guid); if (itr == m_QueuedPlayers.end()) { + //This happens if a player logs out while in a bg because WorldSession::LogoutPlayer() notifies the bg twice std::string playerName = "Unknown"; if (Player* player = ObjectAccessor::FindPlayer(guid)) playerName = player->GetName(); - TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (%s)", playerName.c_str(), guid.ToString().c_str()); + TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: couldn't find player %s (%s)", playerName.c_str(), guid.ToString().c_str()); return; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index a92cda0817b..9c654a1793c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -21,7 +21,6 @@ #include "ObjectMgr.h" #include "WorldPacket.h" -#include "Formulas.h" #include "GameObject.h" #include "Language.h" #include "Player.h" @@ -1377,10 +1376,10 @@ bool BattlegroundAV::SetupBattleground() //creatures TC_LOG_DEBUG("bg.battleground", "BG_AV start poputlating nodes"); - for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i) + for (BG_AV_Nodes n = BG_AV_NODES_FIRSTAID_STATION; n < BG_AV_NODES_MAX; ++n) { - if (m_Nodes[i].Owner) - PopulateNode(i); + if (m_Nodes[n].Owner) + PopulateNode(n); } //all creatures which don't get despawned through the script are static TC_LOG_DEBUG("bg.battleground", "BG_AV: start spawning static creatures"); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp index 9e62a8c4616..02f9d6a32a6 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp @@ -18,7 +18,6 @@ #include "BattlegroundDS.h" #include "Creature.h" -#include "GameObject.h" #include "Player.h" #include "WorldPacket.h" diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index ef2e2b15411..fac6bbcfe99 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -17,13 +17,13 @@ */ #include "BattlegroundEY.h" -#include "ObjectMgr.h" #include "WorldPacket.h" #include "BattlegroundMgr.h" #include "Creature.h" #include "Language.h" #include "Player.h" #include "Util.h" +#include "ObjectAccessor.h" // these variables aren't used outside of this file, so declare them only here uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] = diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 3432c740c1f..9f13d4ab659 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -495,62 +495,62 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* target } } -void BattlegroundIC::UpdateNodeWorldState(ICNodePoint* nodePoint) +void BattlegroundIC::UpdateNodeWorldState(ICNodePoint* node) { //updating worldstate - if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTROLLED]) - nodePoint->nodeState = NODE_STATE_CONTROLLED_A; - else if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTESTED]) - nodePoint->nodeState = NODE_STATE_CONFLICT_A; - else if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_H_CONTROLLED]) - nodePoint->nodeState = NODE_STATE_CONTROLLED_H; - else if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_H_CONTESTED]) - nodePoint->nodeState = NODE_STATE_CONFLICT_H; + if (node->gameobject_entry == node->banners[BANNER_A_CONTROLLED]) + node->nodeState = NODE_STATE_CONTROLLED_A; + else if (node->gameobject_entry == node->banners[BANNER_A_CONTESTED]) + node->nodeState = NODE_STATE_CONFLICT_A; + else if (node->gameobject_entry == node->banners[BANNER_H_CONTROLLED]) + node->nodeState = NODE_STATE_CONTROLLED_H; + else if (node->gameobject_entry == node->banners[BANNER_H_CONTESTED]) + node->nodeState = NODE_STATE_CONFLICT_H; - uint32 worldstate = nodePoint->worldStates[nodePoint->nodeState]; + uint32 worldstate = node->worldStates[node->nodeState]; // with this we are sure we dont bug the client for (uint8 i = 0; i < 5; ++i) { - if (nodePoint->worldStates[i] == worldstate) + if (node->worldStates[i] == worldstate) continue; - UpdateWorldState(nodePoint->worldStates[i], 0); + UpdateWorldState(node->worldStates[i], 0); } UpdateWorldState(worldstate, 1); } -uint32 BattlegroundIC::GetNextBanner(ICNodePoint* nodePoint, uint32 team, bool returnDefinitve) +uint32 BattlegroundIC::GetNextBanner(ICNodePoint* node, uint32 team, bool returnDefinitve) { // this is only used in the update map function if (returnDefinitve) // here is a special case, here we must return the definitve faction banner after the grey banner was spawned 1 minute - return nodePoint->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTROLLED : BANNER_H_CONTROLLED)]; + return node->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTROLLED : BANNER_H_CONTROLLED)]; // there were no changes, this point has never been captured by any faction or at least clicked - if (nodePoint->last_entry == 0) + if (node->last_entry == 0) // 1 returns the CONTESTED ALLIANCE BANNER, 3 returns the HORDE one - return nodePoint->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTESTED : BANNER_H_CONTESTED)]; + return node->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTESTED : BANNER_H_CONTESTED)]; // If the actual banner is the definitive faction banner, we must return the grey banner of the player's faction - if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTROLLED] || nodePoint->gameobject_entry == nodePoint->banners[BANNER_H_CONTROLLED]) - return nodePoint->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTESTED : BANNER_H_CONTESTED)]; + if (node->gameobject_entry == node->banners[BANNER_A_CONTROLLED] || node->gameobject_entry == node->banners[BANNER_H_CONTROLLED]) + return node->banners[(team == TEAM_ALLIANCE ? BANNER_A_CONTESTED : BANNER_H_CONTESTED)]; // If the actual banner is the grey faction banner, we must return the previous banner - if (nodePoint->gameobject_entry == nodePoint->banners[BANNER_A_CONTESTED] || nodePoint->banners[BANNER_H_CONTESTED]) - return nodePoint->last_entry; + if (node->gameobject_entry == node->banners[BANNER_A_CONTESTED] || node->banners[BANNER_H_CONTESTED]) + return node->last_entry; // we should never be here... TC_LOG_ERROR("bg.battleground", "Isle Of Conquest: Unexpected return in GetNextBanner function"); return 0; } -void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint) +void BattlegroundIC::HandleContestedNodes(ICNodePoint* node) { - if (nodePoint->nodeType == NODE_TYPE_HANGAR) + if (node->nodeType == NODE_TYPE_HANGAR) { if (gunshipAlliance && gunshipHorde) - (nodePoint->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false); + (node->faction == TEAM_ALLIANCE ? gunshipHorde : gunshipAlliance)->EnableMovement(false); for (uint8 u = BG_IC_GO_HANGAR_TELEPORTER_1; u <= BG_IC_GO_HANGAR_TELEPORTER_3; ++u) DelObject(u); @@ -567,7 +567,7 @@ void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint) } std::list<Creature*> cannons; - if (nodePoint->faction == TEAM_HORDE) + if (node->faction == TEAM_HORDE) gunshipAlliance->GetCreatureListWithEntryInGrid(cannons, NPC_ALLIANCE_GUNSHIP_CANNON, 150.0f); else gunshipHorde->GetCreatureListWithEntryInGrid(cannons, NPC_HORDE_GUNSHIP_CANNON, 150.0f); @@ -578,22 +578,22 @@ void BattlegroundIC::HandleContestedNodes(ICNodePoint* nodePoint) cannon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } } - else if (nodePoint->nodeType == NODE_TYPE_WORKSHOP) + else if (node->nodeType == NODE_TYPE_WORKSHOP) { DelObject(BG_IC_GO_SEAFORIUM_BOMBS_1); DelObject(BG_IC_GO_SEAFORIUM_BOMBS_2); } } -void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) +void BattlegroundIC::HandleCapturedNodes(ICNodePoint* node, bool recapture) { - if (nodePoint->nodeType != NODE_TYPE_REFINERY && nodePoint->nodeType != NODE_TYPE_QUARRY) + if (node->nodeType != NODE_TYPE_REFINERY && node->nodeType != NODE_TYPE_QUARRY) { - if (!AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+nodePoint->nodeType-2, BG_IC_SpiritGuidePos[nodePoint->nodeType], nodePoint->faction)) - TC_LOG_ERROR("bg.battleground", "Isle of Conquest: Failed to spawn spirit guide! point: %u, team: %u, ", nodePoint->nodeType, nodePoint->faction); + if (!AddSpiritGuide(BG_IC_NPC_SPIRIT_GUIDE_1+node->nodeType-2, BG_IC_SpiritGuidePos[node->nodeType], node->faction)) + TC_LOG_ERROR("bg.battleground", "Isle of Conquest: Failed to spawn spirit guide! point: %u, team: %u, ", node->nodeType, node->faction); } - switch (nodePoint->gameobject_type) + switch (node->gameobject_type) { case BG_IC_GO_HANGAR_BANNER: { @@ -601,7 +601,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) break; std::list<Creature*> cannons; - if (nodePoint->faction == TEAM_ALLIANCE) + if (node->faction == TEAM_ALLIANCE) gunshipAlliance->GetCreatureListWithEntryInGrid(cannons, NPC_ALLIANCE_GUNSHIP_CANNON, 150.0f); else gunshipHorde->GetCreatureListWithEntryInGrid(cannons, NPC_HORDE_GUNSHIP_CANNON, 150.0f); @@ -612,20 +612,20 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) for (uint8 u = 0; u < MAX_HANGAR_TELEPORTERS_SPAWNS; ++u) { uint8 type = BG_IC_GO_HANGAR_TELEPORTER_1 + u; - if (!AddObject(type, (nodePoint->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL : GO_HORDE_GUNSHIP_PORTAL), BG_IC_HangarTeleporters[u], 0, 0, 0, 0, RESPAWN_ONE_DAY)) + if (!AddObject(type, (node->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL : GO_HORDE_GUNSHIP_PORTAL), BG_IC_HangarTeleporters[u], 0, 0, 0, 0, RESPAWN_ONE_DAY)) TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal. Type: %u", BG_IC_GO_HANGAR_TELEPORTER_1 + u); } for (uint8 u = 0; u < MAX_HANGAR_TELEPORTER_EFFECTS_SPAWNS; ++u) { uint8 type = BG_IC_GO_HANGAR_TELEPORTER_EFFECT_1 + u; - if (!AddObject(type, (nodePoint->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL_EFFECTS : GO_HORDE_GUNSHIP_PORTAL_EFFECTS), BG_IC_HangarTeleporterEffects[u], 0, 0, 0, 0, RESPAWN_ONE_DAY, GO_STATE_ACTIVE)) + if (!AddObject(type, (node->faction == TEAM_ALLIANCE ? GO_ALLIANCE_GUNSHIP_PORTAL_EFFECTS : GO_HORDE_GUNSHIP_PORTAL_EFFECTS), BG_IC_HangarTeleporterEffects[u], 0, 0, 0, 0, RESPAWN_ONE_DAY, GO_STATE_ACTIVE)) TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a gunship portal effects. Type: %u", BG_IC_GO_HANGAR_TELEPORTER_1 + u); } for (uint8 u = 0; u < MAX_TRIGGER_SPAWNS_PER_FACTION; ++u) { - if (!AddCreature(NPC_WORLD_TRIGGER_NOT_FLOATING, BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING, BG_IC_HangarTrigger[nodePoint->faction], nodePoint->faction, RESPAWN_ONE_DAY, nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)) + if (!AddCreature(NPC_WORLD_TRIGGER_NOT_FLOATING, BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING, BG_IC_HangarTrigger[node->faction], node->faction, RESPAWN_ONE_DAY, node->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)) TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a world trigger. Type: %u", BG_IC_NPC_WORLD_TRIGGER_NOT_FLOATING); } @@ -634,24 +634,24 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) uint8 type = BG_IC_NPC_GUNSHIP_CAPTAIN_1 + u; if (type == BG_IC_NPC_GUNSHIP_CAPTAIN_1) - if (AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_ALLIANCE_GUNSHIP_CAPTAIN : NPC_HORDE_GUNSHIP_CAPTAIN, type, BG_IC_HangarCaptains[nodePoint->faction == TEAM_ALLIANCE ? 2 : 0], nodePoint->faction, RESPAWN_ONE_DAY)) + if (AddCreature(node->faction == TEAM_ALLIANCE ? NPC_ALLIANCE_GUNSHIP_CAPTAIN : NPC_HORDE_GUNSHIP_CAPTAIN, type, BG_IC_HangarCaptains[node->faction == TEAM_ALLIANCE ? 2 : 0], node->faction, RESPAWN_ONE_DAY)) GetBGCreature(BG_IC_NPC_GUNSHIP_CAPTAIN_1)->GetAI()->DoAction(ACTION_GUNSHIP_READY); if (type == BG_IC_NPC_GUNSHIP_CAPTAIN_2) - if (!AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_ALLIANCE_GUNSHIP_CAPTAIN : NPC_HORDE_GUNSHIP_CAPTAIN, type, BG_IC_HangarCaptains[nodePoint->faction == TEAM_ALLIANCE ? 3 : 1], nodePoint->faction, RESPAWN_ONE_DAY, nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)) + if (!AddCreature(node->faction == TEAM_ALLIANCE ? NPC_ALLIANCE_GUNSHIP_CAPTAIN : NPC_HORDE_GUNSHIP_CAPTAIN, type, BG_IC_HangarCaptains[node->faction == TEAM_ALLIANCE ? 3 : 1], node->faction, RESPAWN_ONE_DAY, node->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)) TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning a world trigger. Type: %u", BG_IC_NPC_GUNSHIP_CAPTAIN_2); } - (nodePoint->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->EnableMovement(true); + (node->faction == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->EnableMovement(true); break; } case BG_IC_GO_QUARRY_BANNER: - RemoveAuraOnTeam(SPELL_QUARRY, (nodePoint->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE)); - CastSpellOnTeam(SPELL_QUARRY, (nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE)); + RemoveAuraOnTeam(SPELL_QUARRY, (node->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE)); + CastSpellOnTeam(SPELL_QUARRY, (node->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE)); break; case BG_IC_GO_REFINERY_BANNER: - RemoveAuraOnTeam(SPELL_OIL_REFINERY, (nodePoint->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE)); - CastSpellOnTeam(SPELL_OIL_REFINERY, (nodePoint->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE)); + RemoveAuraOnTeam(SPELL_OIL_REFINERY, (node->faction == TEAM_ALLIANCE ? HORDE : ALLIANCE)); + CastSpellOnTeam(SPELL_OIL_REFINERY, (node->faction == TEAM_ALLIANCE ? ALLIANCE : HORDE)); break; case BG_IC_GO_DOCKS_BANNER: if (recapture) @@ -661,7 +661,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) docksTimer = DOCKS_UPDATE_TIME; // we must del opposing faction vehicles when the node is captured (unused ones) - for (uint8 i = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_H : BG_IC_NPC_GLAIVE_THROWER_1_A); i < (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_2_H : BG_IC_NPC_GLAIVE_THROWER_2_A); ++i) + for (uint8 i = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_H : BG_IC_NPC_GLAIVE_THROWER_1_A); i < (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_2_H : BG_IC_NPC_GLAIVE_THROWER_2_A); ++i) { if (Creature* glaiveThrower = GetBGCreature(i, false)) { @@ -673,7 +673,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) } } - for (uint8 i = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_H : BG_IC_NPC_CATAPULT_1_A); i < (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_4_H : BG_IC_NPC_CATAPULT_4_A); ++i) + for (uint8 i = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_H : BG_IC_NPC_CATAPULT_1_A); i < (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_4_H : BG_IC_NPC_CATAPULT_4_A); ++i) { if (Creature* catapult = GetBGCreature(i, false)) { @@ -688,25 +688,25 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) // spawning glaive throwers for (uint8 i = 0; i < MAX_GLAIVE_THROWERS_SPAWNS_PER_FACTION; ++i) { - uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_A : BG_IC_NPC_GLAIVE_THROWER_1_H)+i; + uint8 type = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_GLAIVE_THROWER_1_A : BG_IC_NPC_GLAIVE_THROWER_1_H)+i; if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive()) continue; - if (AddCreature(nodePoint->faction == TEAM_ALLIANCE ? NPC_GLAIVE_THROWER_A : NPC_GLAIVE_THROWER_H, type, BG_IC_DocksVehiclesGlaives[i], nodePoint->faction, RESPAWN_ONE_DAY)) - GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]); + if (AddCreature(node->faction == TEAM_ALLIANCE ? NPC_GLAIVE_THROWER_A : NPC_GLAIVE_THROWER_H, type, BG_IC_DocksVehiclesGlaives[i], node->faction, RESPAWN_ONE_DAY)) + GetBGCreature(type)->setFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]); } // spawning catapults for (uint8 i = 0; i < MAX_CATAPULTS_SPAWNS_PER_FACTION; ++i) { - uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_A : BG_IC_NPC_CATAPULT_1_H)+i; + uint8 type = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_CATAPULT_1_A : BG_IC_NPC_CATAPULT_1_H)+i; if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive()) continue; - if (AddCreature(NPC_CATAPULT, type, BG_IC_DocksVehiclesCatapults[i], nodePoint->faction, RESPAWN_ONE_DAY)) - GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]); + if (AddCreature(NPC_CATAPULT, type, BG_IC_DocksVehiclesCatapults[i], node->faction, RESPAWN_ONE_DAY)) + GetBGCreature(type)->setFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]); } break; case BG_IC_GO_WORKSHOP_BANNER: @@ -717,7 +717,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) if (!recapture) { // we must del opposing faction vehicles when the node is captured (unused ones) - for (uint8 i = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_H : BG_IC_NPC_DEMOLISHER_1_A); i < (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_4_H : BG_IC_NPC_DEMOLISHER_4_A); ++i) + for (uint8 i = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_H : BG_IC_NPC_DEMOLISHER_1_A); i < (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_4_H : BG_IC_NPC_DEMOLISHER_4_A); ++i) { if (Creature* demolisher = GetBGCreature(i, false)) { @@ -732,17 +732,17 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) for (uint8 i = 0; i < MAX_DEMOLISHERS_SPAWNS_PER_FACTION; ++i) { - uint8 type = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H)+i; + uint8 type = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_DEMOLISHER_1_A : BG_IC_NPC_DEMOLISHER_1_H)+i; if (GetBGCreature(type, false) && GetBGCreature(type)->IsAlive()) continue; - if (AddCreature(NPC_DEMOLISHER, type, BG_IC_WorkshopVehicles[i], nodePoint->faction, RESPAWN_ONE_DAY)) - GetBGCreature(type)->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]); + if (AddCreature(NPC_DEMOLISHER, type, BG_IC_WorkshopVehicles[i], node->faction, RESPAWN_ONE_DAY)) + GetBGCreature(type)->setFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]); } // we check if the opossing siege engine is in use - int8 enemySiege = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_H : BG_IC_NPC_SIEGE_ENGINE_A); + int8 enemySiege = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_H : BG_IC_NPC_SIEGE_ENGINE_A); if (Creature* siegeEngine = GetBGCreature(enemySiege, false)) { @@ -754,16 +754,16 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) } } - uint8 siegeType = (nodePoint->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H); + uint8 siegeType = (node->faction == TEAM_ALLIANCE ? BG_IC_NPC_SIEGE_ENGINE_A : BG_IC_NPC_SIEGE_ENGINE_H); if (!GetBGCreature(siegeType, false) || !GetBGCreature(siegeType)->IsAlive()) { - AddCreature((nodePoint->faction == TEAM_ALLIANCE ? NPC_SIEGE_ENGINE_A : NPC_SIEGE_ENGINE_H), siegeType, - BG_IC_WorkshopVehicles[4], nodePoint->faction, RESPAWN_ONE_DAY); + AddCreature((node->faction == TEAM_ALLIANCE ? NPC_SIEGE_ENGINE_A : NPC_SIEGE_ENGINE_H), siegeType, + BG_IC_WorkshopVehicles[4], node->faction, RESPAWN_ONE_DAY); if (Creature* siegeEngine = GetBGCreature(siegeType)) { siegeEngine->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_UNK_14|UNIT_FLAG_IMMUNE_TO_PC); - siegeEngine->setFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]); + siegeEngine->setFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]); } } } @@ -778,7 +778,7 @@ void BattlegroundIC::HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture) if (GameObject* seaforiumBombs = GetBGObject(BG_IC_GO_SEAFORIUM_BOMBS_1+i)) { seaforiumBombs->SetRespawnTime(10); - seaforiumBombs->SetFaction(BG_IC_Factions[(nodePoint->faction == TEAM_ALLIANCE ? 0 : 1)]); + seaforiumBombs->SetFaction(BG_IC_Factions[(node->faction == TEAM_ALLIANCE ? 0 : 1)]); } } break; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index a313cd3901c..e2d511e0f1f 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -968,7 +968,7 @@ class BattlegroundIC : public Battleground Transport* gunshipAlliance; Transport* gunshipHorde; - uint32 GetNextBanner(ICNodePoint* nodePoint, uint32 team, bool returnDefinitve); + uint32 GetNextBanner(ICNodePoint* node, uint32 team, bool returnDefinitve); uint32 GetGateIDFromEntry(uint32 id) { @@ -1013,9 +1013,9 @@ class BattlegroundIC : public Battleground return uws; } - void UpdateNodeWorldState(ICNodePoint* nodePoint); - void HandleCapturedNodes(ICNodePoint* nodePoint, bool recapture); - void HandleContestedNodes(ICNodePoint* nodePoint); + void UpdateNodeWorldState(ICNodePoint* node); + void HandleCapturedNodes(ICNodePoint* node, bool recapture); + void HandleContestedNodes(ICNodePoint* node); }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index cc3daec1649..5c4b1025e8e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -20,10 +20,10 @@ #include "GameObject.h" #include "Language.h" #include "Object.h" -#include "ObjectMgr.h" #include "BattlegroundMgr.h" #include "Player.h" #include "WorldPacket.h" +#include "ObjectAccessor.h" // these variables aren't used outside of this file, so declare them only here enum BG_WSG_Rewards diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 3cbdcbcaff1..5a74ad05b66 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -19,7 +19,6 @@ #include "Common.h" #include "ObjectMgr.h" #include "World.h" -#include "WorldPacket.h" #include "WorldSession.h" #include "DatabaseEnv.h" @@ -29,9 +28,7 @@ #include "GridNotifiersImpl.h" #include "Language.h" #include "Log.h" -#include "Opcodes.h" #include "Player.h" -#include "UpdateMask.h" #include "ScriptMgr.h" #include "ChatLink.h" diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index ba59245cdaa..1b095534ad0 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -71,21 +71,21 @@ class ChatHandler void SendSysMessage(uint32 entry); template<typename... Args> - void PSendSysMessage(const char* fmt, Args const&... args) + void PSendSysMessage(const char* fmt, Args&&... args) { - SendSysMessage(Trinity::StringFormat(fmt, args...).c_str()); + SendSysMessage(Trinity::StringFormat(fmt, std::forward<Args>(args)...).c_str()); } template<typename... Args> - void PSendSysMessage(uint32 entry, Args const&... args) + void PSendSysMessage(uint32 entry, Args&&... args) { - SendSysMessage(PGetParseString(entry, args...).c_str()); + SendSysMessage(PGetParseString(entry, std::forward<Args>(args)...).c_str()); } template<typename... Args> - std::string PGetParseString(uint32 entry, Args const&... args) const + std::string PGetParseString(uint32 entry, Args&&... args) const { - return Trinity::StringFormat(GetTrinityString(entry), args...); + return Trinity::StringFormat(GetTrinityString(entry), std::forward<Args>(args)...); } bool ParseCommands(const char* text); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index b05f9ac2a0d..9106bfdd394 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -27,7 +27,6 @@ #include "ScriptMgr.h" #include "SpellAuras.h" #include "SpellMgr.h" -#include "Spell.h" char const* ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] = { diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 5cd9b363ae0..d9061dfb106 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -600,7 +600,7 @@ void LoadDBCStores(const std::string& dataPath) for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) { // not spell path - if (spellPaths.find(dest_i->second.ID) == spellPaths.end()) + if (dest_i->second.price || spellPaths.find(dest_i->second.ID) == spellPaths.end()) { ok = true; break; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6e51257eb82..84a12fd6409 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -36,7 +36,6 @@ #include "LootMgr.h" #include "MoveSpline.h" #include "ObjectMgr.h" -#include "Opcodes.h" #include "Player.h" #include "PoolMgr.h" #include "QuestDef.h" @@ -2554,7 +2553,7 @@ void Creature::UpdateMovementFlags() return; // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc) - float ground = GetMap()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); + float ground = GetMap()->GetHeight(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset()); bool isInAir = (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 0ad76ab2086..4c1b39211cb 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -451,7 +451,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool CanFly() const override { return (GetCreatureTemplate()->InhabitType & INHABIT_AIR) != 0; } void SetReactState(ReactStates st) { m_reactState = st; } - ReactStates GetReactState() { return m_reactState; } + ReactStates GetReactState() const { return m_reactState; } bool HasReactState(ReactStates state) const { return (m_reactState == state); } void InitializeReactState(); @@ -505,7 +505,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void SetCanDualWield(bool value) override; int8 GetOriginalEquipmentId() const { return m_originalEquipmentId; } - uint8 GetCurrentEquipmentId() { return m_equipmentId; } + uint8 GetCurrentEquipmentId() const { return m_equipmentId; } void SetCurrentEquipmentId(uint8 id) { m_equipmentId = id; } float GetSpellDamageMod(int32 Rank) const; @@ -550,7 +550,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void SetLootRecipient (Unit* unit); void AllLootRemovedFromCorpse(); - uint16 GetLootMode() { return m_LootMode; } + uint16 GetLootMode() const { return m_LootMode; } bool HasLootMode(uint16 lootMode) { return (m_LootMode & lootMode) != 0; } void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; } void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; } @@ -578,7 +578,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void CallAssistance(); void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; } void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; } - bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; } + bool HasSearchedAssistance() const { return m_AlreadySearchedAssistance; } bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const; bool _IsTargetAcceptable(const Unit* target) const; @@ -642,7 +642,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject Unit* SelectVictim(); void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; } - bool IsReputationGainDisabled() { return DisableReputationGain; } + bool IsReputationGainDisabled() const { return DisableReputationGain; } bool IsDamageEnoughForLootingAndReward() const { return m_PlayerDamageReq == 0; } void LowerPlayerDamageReq(uint32 unDamage); void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; } diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index c8a251394cc..63be8d06739 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -19,8 +19,6 @@ #include "QuestDef.h" #include "GossipDef.h" #include "ObjectMgr.h" -#include "Opcodes.h" -#include "WorldPacket.h" #include "WorldSession.h" #include "Formulas.h" diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 16fd7c11683..68c6cbb70e5 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -53,7 +53,7 @@ class TempSummon : public Creature Creature* GetSummonerCreatureBase() const; ObjectGuid GetSummonerGUID() const { return m_summonerGUID; } TempSummonType const& GetSummonType() { return m_type; } - uint32 GetTimer() { return m_timer; } + uint32 GetTimer() const { return m_timer; } const SummonPropertiesEntry* const m_Properties; private: diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 50981a163be..9777672e175 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -113,7 +113,8 @@ void GameObject::RemoveFromOwner() return; } - TC_LOG_FATAL("misc", "Removed GameObject (GUID: %u Entry: %u SpellId: %u LinkedGO: %u) that just lost any reference to the owner (%s) GO list", + // This happens when a mage portal is despawned after the caster changes map (for example using the portal) + TC_LOG_DEBUG("misc", "Removed GameObject (GUID: %u Entry: %u SpellId: %u LinkedGO: %u) that just lost any reference to the owner (%s) GO list", GetGUIDLow(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), ownerGUID.ToString().c_str()); SetOwnerGUID(ObjectGuid::Empty); } @@ -226,7 +227,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa SetDisplayId(goinfo->displayId); - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); // GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3 SetGoType(GameobjectTypes(goinfo->type)); SetGoState(go_state); @@ -1757,9 +1758,9 @@ void GameObject::Use(Unit* user) return; } - if (Player* player = user->ToPlayer())
- sOutdoorPvPMgr->HandleCustomSpell(player, spellId, this);
-
+ if (Player* player = user->ToPlayer()) + sOutdoorPvPMgr->HandleCustomSpell(player, spellId, this); + if (spellCaster) spellCaster->CastSpell(user, spellInfo, triggered); else @@ -2128,7 +2129,7 @@ void GameObject::UpdateModel() if (GetMap()->ContainsGameObjectModel(*m_model)) GetMap()->RemoveGameObjectModel(*m_model); delete m_model; - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); if (m_model) GetMap()->InsertGameObjectModel(*m_model); } @@ -2253,12 +2254,12 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t } else if (index == GAMEOBJECT_FLAGS) { - uint32 flags = m_uint32Values[GAMEOBJECT_FLAGS]; + uint32 goFlags = m_uint32Values[GAMEOBJECT_FLAGS]; if (GetGoType() == GAMEOBJECT_TYPE_CHEST) if (GetGOInfo()->chest.groupLootRules && !IsLootAllowedFor(target)) - flags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE; + goFlags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE; - fieldBuffer << flags; + fieldBuffer << goFlags; } else fieldBuffer << m_uint32Values[index]; // other cases @@ -2321,3 +2322,25 @@ void GameObject::UpdateModelPosition() GetMap()->InsertGameObjectModel(*m_model); } } + +class GameObjectModelOwnerImpl : public GameObjectModelOwnerBase +{ +public: + explicit GameObjectModelOwnerImpl(GameObject const* owner) : _owner(owner) { } + + virtual bool IsSpawned() const override { return _owner->isSpawned(); } + virtual uint32 GetDisplayId() const override { return _owner->GetDisplayId(); } + virtual uint32 GetPhaseMask() const override { return _owner->GetPhaseMask(); } + virtual G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); } + virtual float GetOrientation() const override { return _owner->GetOrientation(); } + virtual float GetScale() const override { return _owner->GetObjectScale(); } + virtual void DebugVisualizeCorner(G3D::Vector3 const& corner) const override { _owner->SummonCreature(1, corner.x, corner.y, corner.z, 0, TEMPSUMMON_MANUAL_DESPAWN); } + +private: + GameObject const* _owner; +}; + +GameObjectModel* GameObject::CreateModel() +{ + return GameObjectModel::Create(Trinity::make_unique<GameObjectModelOwnerImpl>(this), sWorld->GetDataPath()); +} diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 2311bc71179..7ef8ef2737d 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -744,8 +744,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map // Note: unit is only used when s = GO_ACTIVATED void SetLootState(LootState s, Unit* unit = NULL); - uint16 GetLootMode() { return m_LootMode; } - bool HasLootMode(uint16 lootMode) { return (m_LootMode & lootMode) != 0; } + uint16 GetLootMode() const { return m_LootMode; } + bool HasLootMode(uint16 lootMode) const { return (m_LootMode & lootMode) != 0; } void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; } void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; } void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; } @@ -850,6 +850,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map protected: bool AIM_Initialize(); + GameObjectModel* CreateModel(); void UpdateModel(); // updates model in case displayId were changed uint32 m_spellId; time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index be27f5eca30..042d66d7f9e 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -16,17 +16,17 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdlib.h> -#include <functional> #include "ItemEnchantmentMgr.h" #include "DatabaseEnv.h" #include "Log.h" #include "ObjectMgr.h" -#include <list> -#include <vector> #include "Util.h" #include "DBCStores.h" +#include <list> +#include <vector> +#include <stdlib.h> + struct EnchStoreItem { uint32 ench; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 6392c3ee51b..fc55c09bffa 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1539,7 +1539,7 @@ float WorldObject::GetSightRange(const WorldObject* target) const return 0.0f; } -bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck) const +bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck, bool checkAlert) const { if (this == obj) return true; @@ -1611,7 +1611,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo if (obj->IsInvisibleDueToDespawn()) return false; - if (!CanDetect(obj, ignoreStealth)) + if (!CanDetect(obj, ignoreStealth, checkAlert)) return false; return true; @@ -1622,7 +1622,7 @@ bool WorldObject::CanNeverSee(WorldObject const* obj) const return GetMap() != obj->GetMap() || !InSamePhase(obj); } -bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const +bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert) const { const WorldObject* seer = this; @@ -1637,7 +1637,7 @@ bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const if (!ignoreStealth && !seer->CanDetectInvisibilityOf(obj)) return false; - if (!ignoreStealth && !seer->CanDetectStealthOf(obj)) + if (!ignoreStealth && !seer->CanDetectStealthOf(obj, checkAlert)) return false; return true; @@ -1674,7 +1674,7 @@ bool WorldObject::CanDetectInvisibilityOf(WorldObject const* obj) const return true; } -bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const +bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) const { // Combat reach is the minimal distance (both in front and behind), // and it is also used in the range calculation. @@ -1724,9 +1724,19 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const // Calculate max distance float visibilityRange = float(detectionValue) * 0.3f + combatReach; - if (visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE) + // If this unit is an NPC then player detect range doesn't apply + if (unit && unit->GetTypeId() == TYPEID_PLAYER && visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE) visibilityRange = MAX_PLAYER_STEALTH_DETECT_RANGE; + // When checking for alert state, look 8% further, and then 1.5 yards more than that. + if (checkAlert) + visibilityRange += (visibilityRange * 0.08f) + 1.5f; + + // If checking for alert, and creature's visibility range is greater than aggro distance, No alert + Unit const* tunit = obj->ToUnit(); + if (checkAlert && unit && unit->ToCreature() && visibilityRange >= unit->ToCreature()->GetAttackDistance(tunit) + unit->ToCreature()->m_CombatDistance) + return false; + if (distance > visibilityRange) return false; } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index a560afa7f1b..e673e346a5f 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -514,7 +514,7 @@ class WorldObject : public Object, public WorldLocation float GetGridActivationRange() const; float GetVisibilityRange() const; float GetSightRange(WorldObject const* target = NULL) const; - bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false) const; + bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false) const; FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealth; FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealthDetect; @@ -634,9 +634,9 @@ class WorldObject : public Object, public WorldLocation bool CanNeverSee(WorldObject const* obj) const; virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; } - bool CanDetect(WorldObject const* obj, bool ignoreStealth) const; + bool CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert = false) const; bool CanDetectInvisibilityOf(WorldObject const* obj) const; - bool CanDetectStealthOf(WorldObject const* obj) const; + bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const; }; namespace Trinity diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index c15668c3887..b86a253a84d 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -18,6 +18,7 @@ #include "ObjectGuid.h" #include "World.h" +#include "ObjectMgr.h" #include <sstream> #include <iomanip> diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp index 530e51cd8f5..8f8e5743f8c 100644 --- a/src/server/game/Entities/Object/Position.cpp +++ b/src/server/game/Entities/Object/Position.cpp @@ -17,9 +17,10 @@ #include "Position.h" #include "ByteBuffer.h" -#include "G3D/g3dmath.h" #include "GridDefines.h" +#include <G3D/g3dmath.h> + bool Position::operator==(Position const &a) { return (G3D::fuzzyEq(a.m_positionX, m_positionX) && diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp index 937bda3a79d..ce27319de74 100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp @@ -20,7 +20,6 @@ #include "ByteBuffer.h" #include "WorldPacket.h" #include "UpdateData.h" -#include "Log.h" #include "Opcodes.h" #include "World.h" #include "zlib.h" diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 97cdb0cf1df..c9b9c72d432 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -343,10 +343,10 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c if (getPetType() == HUNTER_PET) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_DECLINED_NAME); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_DECLINED_NAME); stmt->setUInt32(0, owner->GetGUIDLow()); stmt->setUInt32(1, GetCharmInfo()->GetPetNumber()); - PreparedQueryResult result = CharacterDatabase.Query(stmt); + result = CharacterDatabase.Query(stmt); if (result) { @@ -1756,7 +1756,7 @@ void Pet::InitTalentForLevel() GetOwner()->SendTalentsInfoData(true); } -uint8 Pet::GetMaxTalentPointsForLevel(uint8 level) +uint8 Pet::GetMaxTalentPointsForLevel(uint8 level) const { uint8 points = (level >= 20) ? ((level - 16) / 4) : 0; // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 1cc86ea2a20..b1d7fcaa28a 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -130,8 +130,8 @@ class Pet : public Guardian static void resetTalentsForAllPetsOf(Player* owner, Pet* online_pet = nullptr); void InitTalentForLevel(); - uint8 GetMaxTalentPointsForLevel(uint8 level); - uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } + uint8 GetMaxTalentPointsForLevel(uint8 level) const; + uint8 GetFreeTalentPoints() const { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); } uint32 m_usedTalentCount; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 55d882c65d3..16485d25057 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3812,7 +3812,8 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent continue; ///@todo: confirm if rogues start with lockpicking skill at level 1 but only receive the spell to use it at level 16 - if ((_spell_idx->second->AutolearnType == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->id)) || (pSkill->id == SKILL_LOCKPICKING && _spell_idx->second->max_value == 0)) + // Also added for runeforging. It's already confirmed this happens upon learning for Death Knights, not from character creation. + if ((_spell_idx->second->AutolearnType == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->id)) || ((pSkill->id == SKILL_LOCKPICKING || pSkill->id == SKILL_RUNEFORGING) && _spell_idx->second->max_value == 0)) LearnDefaultSkill(pSkill->id, 0); if (pSkill->id == SKILL_MOUNTS && !Has310Flyer(false)) @@ -7265,7 +7266,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid) // stored zone is zero, use generic and slow zone detection stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_POSITION_XYZ); stmt->setUInt32(0, guidLow); - PreparedQueryResult result = CharacterDatabase.Query(stmt); + result = CharacterDatabase.Query(stmt); if (!result) return 0; @@ -18005,8 +18006,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) } else if (invalidBagMap.find(bagGuid) != invalidBagMap.end()) { - std::map<uint32, Item*>::iterator itr = invalidBagMap.find(bagGuid); - if (std::find(problematicItems.begin(), problematicItems.end(), itr->second) != problematicItems.end()) + std::map<uint32, Item*>::iterator invalidBagItr = invalidBagMap.find(bagGuid); + if (std::find(problematicItems.begin(), problematicItems.end(), invalidBagItr->second) != problematicItems.end()) err = EQUIP_ERR_INT_BAG_ERROR; } else @@ -22621,15 +22622,17 @@ void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 GetSession()->SendPacket(&data); } -void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time) +void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) { // type of warning, based on the time remaining until reset uint32 type; - if (time > 3600) + if (welcome) type = RAID_INSTANCE_WELCOME; - else if (time > 900 && time <= 3600) + else if (time > 21600) + type = RAID_INSTANCE_WELCOME; + else if (time > 3600) type = RAID_INSTANCE_WARNING_HOURS; - else if (time > 300 && time <= 900) + else if (time > 300) type = RAID_INSTANCE_WARNING_MIN; else type = RAID_INSTANCE_WARNING_MIN_SOON; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 98b9d8a3d07..c1417177320 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1129,7 +1129,7 @@ class Player : public Unit, public GridObject<Player> void SendInitialPacketsAfterAddToMap(); void SendSupercededSpell(uint32 oldSpell, uint32 newSpell); void SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg = 0); - void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time); + void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome); bool CanInteractWithQuestGiver(Object* questGiver); Creature* GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask); @@ -1181,8 +1181,8 @@ class Player : public Unit, public GridObject<Player> time_t m_logintime; time_t m_Last_tick; uint32 m_Played_time[MAX_PLAYED_TIME_INDEX]; - uint32 GetTotalPlayedTime() { return m_Played_time[PLAYED_TIME_TOTAL]; } - uint32 GetLevelPlayedTime() { return m_Played_time[PLAYED_TIME_LEVEL]; } + uint32 GetTotalPlayedTime() const { return m_Played_time[PLAYED_TIME_TOTAL]; } + uint32 GetLevelPlayedTime() const { return m_Played_time[PLAYED_TIME_LEVEL]; } void setDeathState(DeathState s) override; // overwrite Unit::setDeathState @@ -1658,7 +1658,7 @@ class Player : public Unit, public GridObject<Player> void SetSpellModTakingSpell(Spell* spell, bool apply); void RemoveArenaSpellCooldowns(bool removeActivePetCooldowns = false); - uint32 GetLastPotionId() { return m_lastPotionId; } + uint32 GetLastPotionId() const { return m_lastPotionId; } void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; } void UpdatePotionCooldown(Spell* spell = NULL); @@ -1718,7 +1718,7 @@ class Player : public Unit, public GridObject<Player> Guild* GetGuild(); static uint32 GetGuildIdFromDB(ObjectGuid guid); static uint8 GetRankFromDB(ObjectGuid guid); - int GetGuildIdInvited() { return m_GuildIdInvited; } + int GetGuildIdInvited() const { return m_GuildIdInvited; } static void RemovePetitionsAndSigns(ObjectGuid guid, uint32 type); // Arena Team @@ -1729,7 +1729,7 @@ class Player : public Unit, public GridObject<Player> uint32 GetArenaTeamId(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_ID); } uint32 GetArenaPersonalRating(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING); } void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; } - uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; } + uint32 GetArenaTeamIdInvited() const { return m_ArenaTeamIdInvited; } Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; } Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; } @@ -1917,7 +1917,7 @@ class Player : public Unit, public GridObject<Player> bool isHonorOrXPTarget(Unit* victim) const; bool GetsRecruitAFriendBonus(bool forXP); - uint8 GetGrantableLevels() { return m_grantableLevels; } + uint8 GetGrantableLevels() const { return m_grantableLevels; } void SetGrantableLevels(uint8 val) { m_grantableLevels = val; } ReputationMgr& GetReputationMgr() { return *m_reputationMgr; } @@ -2062,7 +2062,7 @@ class Player : public Unit, public GridObject<Player> bool isTotalImmune(); bool CanCaptureTowerPoint(); - bool GetRandomWinner() { return m_IsBGRandomWinner; } + bool GetRandomWinner() const { return m_IsBGRandomWinner; } void SetRandomWinner(bool isWinner); /*********************************************************/ @@ -2257,7 +2257,7 @@ class Player : public Unit, public GridObject<Player> uint32 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } uint32 GetRuneBaseCooldown(uint8 index); bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const; - RuneType GetLastUsedRune() { return m_runes->lastUsedRune; } + RuneType GetLastUsedRune() const { return m_runes->lastUsedRune; } void SetLastUsedRune(RuneType type) { m_runes->lastUsedRune = type; } void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; } void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; } diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 6d98a4c78b2..d6a130c0317 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -94,7 +94,7 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa SetName(goinfo->name); UpdateRotationFields(0.0f, 1.0f); - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); return true; } diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 67101dc8961..fb27fea7060 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -23,7 +23,6 @@ #include "SharedDefines.h" #include "SpellAuras.h" #include "SpellAuraEffects.h" -#include "SpellMgr.h" #include "World.h" inline bool _ModifyUInt32(bool apply, uint32& baseValue, int32& amount) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 31d93ed8d98..d03deeaed0a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -54,8 +54,8 @@ #include "SpellHistory.h" #include "SpellMgr.h" #include "TemporarySummon.h" -#include "Totem.h" #include "Transport.h" +#include "Totem.h" #include "UpdateFieldFlags.h" #include "Util.h" #include "Vehicle.h" @@ -288,6 +288,28 @@ Unit::~Unit() ASSERT(m_dynObj.empty()); } +// Check if unit in combat with specific unit +bool Unit::IsInCombatWith(Unit const* who) const +{ + // Check target exists + if (!who) + return false; + + // Search in threat list + ObjectGuid guid = who->GetGUID(); + for (ThreatContainer::StorageType::const_iterator i = m_ThreatManager.getThreatList().begin(); i != m_ThreatManager.getThreatList().end(); ++i) + { + HostileReference* ref = (*i); + + // Return true if the unit matches + if (ref && ref->getUnitGuid() == guid) + return true; + } + + // Nothing found, false. + return false; +} + void Unit::Update(uint32 p_time) { // WARNING! Order of execution here is important, do not change. @@ -2184,6 +2206,9 @@ uint32 Unit::CalculateDamage(WeaponAttackType attType, bool normalized, bool add } } + minDamage = std::max(0.f, minDamage); + maxDamage = std::max(0.f, maxDamage); + if (minDamage > maxDamage) std::swap(minDamage, maxDamage); @@ -9963,15 +9988,11 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); } - float tmpDamage = float(int32(pdamage) + DoneTotal); - // SPELLMOD_DOT will be applied in AuraEffect::HandlePeriodicDamageAurasTick. - if (damagetype != DOT) - { - tmpDamage *= SpellDamagePctDone(victim, spellProto, damagetype); - // apply spellmod to Done damage (flat and pct) - if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); - } + // Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods. + float tmpDamage = (int32(pdamage) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellDamagePctDone(victim, spellProto, damagetype)); + // apply spellmod to Done damage (flat and pct) + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); return uint32(std::max(tmpDamage, 0.0f)); } @@ -10811,15 +10832,11 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui DoneTotal = 0; } - float heal = float(int32(healamount) + DoneTotal); - // SPELLMOD_DOT will be applied in AuraEffect::HandlePeriodicHealAurasTick. - if (damagetype != DOT) - { - heal *= SpellHealingPctDone(victim, spellProto); - // apply spellmod to Done amount - if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, heal); - } + // Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods. + float heal = float(int32(healamount) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellHealingPctDone(victim, spellProto)); + // apply spellmod to Done amount + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); return uint32(std::max(heal, 0.0f)); } @@ -11884,8 +11901,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target)) return false; - // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. - if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))) + // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. Ignore stealth if target is player and unit in combat with same player + if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target))))) return false; // can't attack dead diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index a61b406cbbd..39b1c34be55 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1480,6 +1480,7 @@ class Unit : public WorldObject bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); } bool IsInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); } + bool IsInCombatWith(Unit const* who) const; void CombatStart(Unit* target, bool initialAggro = true); void SetInCombatState(bool PvP, Unit* enemy = NULL); void SetInCombatWith(Unit* enemy); diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 859633b16c4..35d6ba91401 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -16,9 +16,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <boost/thread/shared_mutex.hpp> -#include <boost/thread/locks.hpp> - #include "ObjectAccessor.h" #include "Corpse.h" #include "Creature.h" @@ -32,7 +29,9 @@ #include "Pet.h" #include "Player.h" #include "World.h" -#include "WorldPacket.h" + +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/locks.hpp> ObjectAccessor::ObjectAccessor() { } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 491a61f6f35..5699dba7cb4 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -25,7 +25,6 @@ #include "Common.h" #include "DatabaseEnv.h" #include "DisableMgr.h" -#include "GameEventMgr.h" #include "GossipDef.h" #include "GroupMgr.h" #include "GuildMgr.h" @@ -36,19 +35,15 @@ #include "MapManager.h" #include "Object.h" #include "ObjectMgr.h" -#include "Pet.h" #include "PoolMgr.h" #include "ReputationMgr.h" #include "ScriptMgr.h" #include "SpellAuras.h" -#include "Spell.h" #include "SpellMgr.h" #include "SpellScript.h" -#include "Transport.h" #include "UpdateMask.h" #include "Util.h" #include "Vehicle.h" -#include "WaypointManager.h" #include "World.h" ScriptMapMap sSpellScripts; @@ -1893,7 +1888,7 @@ uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float return guid; } -bool ObjectMgr::MoveCreData(uint32 guid, uint32 mapId, const Position& pos) +bool ObjectMgr::MoveCreatureData(uint32 guid, uint32 mapId, const Position& pos) { CreatureData& data = NewOrExistCreatureData(guid); if (!data.id) @@ -1917,7 +1912,7 @@ bool ObjectMgr::MoveCreData(uint32 guid, uint32 mapId, const Position& pos) Creature* creature = new Creature(); if (!creature->LoadCreatureFromDB(guid, map)) { - TC_LOG_ERROR("misc", "MoveCreData: Cannot add creature guid %u to map", guid); + TC_LOG_ERROR("misc", "MoveCreatureData: Cannot add creature guid %u to map", guid); delete creature; return false; } @@ -1926,7 +1921,7 @@ bool ObjectMgr::MoveCreData(uint32 guid, uint32 mapId, const Position& pos) return true; } -uint32 ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay /*= 0*/) +uint32 ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay /*= 0*/) { CreatureTemplate const* cInfo = GetCreatureTemplate(entry); if (!cInfo) @@ -6527,13 +6522,10 @@ void ObjectMgr::LoadGameObjectLocales() { uint32 oldMSTime = getMSTime(); - _gameObjectLocaleStore.clear(); // need for reload case - - QueryResult result = WorldDatabase.Query("SELECT entry, " - "name_loc1, name_loc2, name_loc3, name_loc4, name_loc5, name_loc6, name_loc7, name_loc8, " - "castbarcaption_loc1, castbarcaption_loc2, castbarcaption_loc3, castbarcaption_loc4, " - "castbarcaption_loc5, castbarcaption_loc6, castbarcaption_loc7, castbarcaption_loc8 FROM locales_gameobject"); + _gameObjectLocaleStore.clear(); // need for reload case + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT entry, locale, name, castBarCaption FROM gameobject_template_locale"); if (!result) return; @@ -6541,18 +6533,21 @@ void ObjectMgr::LoadGameObjectLocales() { Field* fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); + uint32 id = fields[0].GetUInt32(); + std::string localeName = fields[1].GetString(); - GameObjectLocale& data = _gameObjectLocaleStore[entry]; + std::string name = fields[2].GetString(); + std::string castBarCaption = fields[3].GetString(); + + GameObjectLocale& data = _gameObjectLocaleStore[id]; + LocaleConstant locale = GetLocaleByName(localeName); + + AddLocaleString(name, locale, data.Name); + AddLocaleString(castBarCaption, locale, data.CastBarCaption); - for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) - { - AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Name); - AddLocaleString(fields[i + (TOTAL_LOCALES - 1)].GetString(), LocaleConstant(i), data.CastBarCaption); - } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %u gameobject locale strings in %u ms", uint32(_gameObjectLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u gameobject_template_locale strings in %u ms", uint32(_gameObjectLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } inline void CheckGOLockId(GameObjectTemplate const* goInfo, uint32 dataN, uint32 N) @@ -9146,8 +9141,8 @@ void ObjectMgr::LoadGameObjectQuestItems() { uint32 oldMSTime = getMSTime(); - // 0 1 - QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId FROM gameobject_questitem ORDER BY Idx ASC"); + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT GameObjectEntry, ItemId, Idx FROM gameobject_questitem ORDER BY Idx ASC"); if (!result) { @@ -9161,7 +9156,22 @@ void ObjectMgr::LoadGameObjectQuestItems() Field* fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); - uint32 item = fields[1].GetUInt32(); + uint32 item = fields[1].GetUInt32(); + uint32 idx = fields[2].GetUInt32(); + + GameObjectTemplate const* goInfo = GetGameObjectTemplate(entry); + if (!goInfo) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject_questitem` has data for nonexistent gameobject (entry: %u, idx: %u), skipped", entry, idx); + continue; + }; + + ItemEntry const* db2Data = sItemStore.LookupEntry(item); + if (!db2Data) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject_questitem` has nonexistent item (ID: %u) in gameobject (entry: %u, idx: %u), skipped", item, entry, idx); + continue; + }; _gameObjectQuestItemStore[entry].push_back(item); @@ -9176,8 +9186,8 @@ void ObjectMgr::LoadCreatureQuestItems() { uint32 oldMSTime = getMSTime(); - // 0 1 - QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId FROM creature_questitem ORDER BY Idx ASC"); + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT CreatureEntry, ItemId, Idx FROM creature_questitem ORDER BY Idx ASC"); if (!result) { @@ -9191,7 +9201,22 @@ void ObjectMgr::LoadCreatureQuestItems() Field* fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); - uint32 item = fields[1].GetUInt32(); + uint32 item = fields[1].GetUInt32(); + uint32 idx = fields[2].GetUInt32(); + + CreatureTemplate const* creatureInfo = GetCreatureTemplate(entry); + if (!creatureInfo) + { + TC_LOG_ERROR("sql.sql", "Table `creature_questitem` has data for nonexistent creature (entry: %u, idx: %u), skipped", entry, idx); + continue; + }; + + ItemEntry const* db2Data = sItemStore.LookupEntry(item); + if (!db2Data) + { + TC_LOG_ERROR("sql.sql", "Table `creature_questitem` has nonexistent item (ID: %u) in creature (entry: %u, idx: %u), skipped", item, entry, idx); + continue; + }; _creatureQuestItemStore[entry].push_back(item); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 601537d9035..26f3ba7cff3 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1218,8 +1218,8 @@ class ObjectMgr void AddGameobjectToGrid(uint32 guid, GameObjectData const* data); void RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data); uint32 AddGOData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0); - uint32 AddCreData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0); - bool MoveCreData(uint32 guid, uint32 map, const Position& pos); + uint32 AddCreatureData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0); + bool MoveCreatureData(uint32 guid, uint32 map, const Position& pos); // reserved names void LoadReservedPlayersNames(); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index d52e559c408..15f3c7811cd 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -132,8 +132,13 @@ inline void CreatureUnitRelocationWorker(Creature* c, Unit* u) return; if (c->HasReactState(REACT_AGGRESSIVE) && !c->HasUnitState(UNIT_STATE_SIGHTLESS)) + { if (c->IsAIEnabled && c->CanSeeOrDetect(u, false, true)) c->AI()->MoveInLineOfSight_Safe(u); + else + if (u->GetTypeId() == TYPEID_PLAYER && u->HasStealthAura() && c->IsAIEnabled && c->CanSeeOrDetect(u, false, true, true)) + c->AI()->TriggerAlert(u); + } } void PlayerRelocationNotifier::Visit(PlayerMapType &m) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index f89c0e73008..7e3b758d92c 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -443,24 +443,24 @@ bool Group::AddMember(Player* player) if (itr->GetSource() == player) continue; - if (Player* member = itr->GetSource()) + if (Player* existingMember = itr->GetSource()) { - if (player->HaveAtClient(member)) + if (player->HaveAtClient(existingMember)) { - member->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER); - member->BuildValuesUpdateBlockForPlayer(&groupData, player); - member->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER); + existingMember->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER); + existingMember->BuildValuesUpdateBlockForPlayer(&groupData, player); + existingMember->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER); } - if (member->HaveAtClient(player)) + if (existingMember->HaveAtClient(player)) { UpdateData newData; WorldPacket newDataPacket; - player->BuildValuesUpdateBlockForPlayer(&newData, member); + player->BuildValuesUpdateBlockForPlayer(&newData, existingMember); if (newData.HasData()) { newData.BuildPacket(&newDataPacket); - member->SendDirectMessage(&newDataPacket); + existingMember->SendDirectMessage(&newDataPacket); } } } @@ -1989,8 +1989,8 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) { if (Group* group = SendMsgTo->GetGroup()) { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - if (Player* player = itr->GetSource()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + if (Player* player = groupRef->GetSource()) player->SendResetInstanceSuccess(instanceSave->GetMapId()); } diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index bfc6f2f9af3..b0ea9e1f4e5 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -328,7 +328,7 @@ private: uint8 GetLevel() const { return m_level; } uint8 GetFlags() const { return m_flags; } uint32 GetZoneId() const { return m_zoneId; } - bool IsOnline() { return (m_flags & GUILDMEMBER_STATUS_ONLINE); } + bool IsOnline() const { return (m_flags & GUILDMEMBER_STATUS_ONLINE); } void ChangeRank(uint8 newRank); diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 5ac5ae02b90..ead05033a35 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -17,17 +17,14 @@ */ #include "Player.h" -#include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "DatabaseEnv.h" - #include "ArenaTeam.h" -#include "Log.h" -#include "ObjectMgr.h" #include "SocialMgr.h" #include "ArenaTeamMgr.h" #include "Opcodes.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 4975d19743d..8ee14d6baa9 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -25,7 +25,6 @@ #include "AuctionHouseMgr.h" #include "Log.h" #include "Language.h" -#include "Opcodes.h" #include "UpdateMask.h" #include "Util.h" #include "AccountMgr.h" diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 9cb9077c5ff..0701271b5e4 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1983,9 +1983,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) stmt->setUInt32(0, oldReputation); stmt->setUInt32(1, lowGuid); - if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + if (PreparedQueryResult reputationResult = CharacterDatabase.Query(stmt)) { - Field* fields = result->Fetch(); + fields = reputationResult->Fetch(); int32 oldDBRep = fields[0].GetInt32(); FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation); diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 39ba593c8d9..ac33880cb98 100644 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -24,7 +24,6 @@ #include "CreatureAI.h" #include "Vehicle.h" #include "Player.h" -#include "Opcodes.h" void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 9d6359c56e9..f8531adeb88 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -22,7 +22,6 @@ #include "GroupMgr.h" #include "Log.h" #include "ObjectMgr.h" -#include "Opcodes.h" #include "Pet.h" #include "Player.h" #include "SocialMgr.h" diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 26d1737257e..18ad2e828f0 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -25,9 +25,7 @@ #include "LootMgr.h" #include "ObjectAccessor.h" #include "Object.h" -#include "Opcodes.h" #include "Player.h" -#include "World.h" #include "WorldPacket.h" #include "WorldSession.h" diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 7b8ce80ccd7..2f6a6dcc70b 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -28,7 +28,6 @@ #include "ObjectMgr.h" #include "GuildMgr.h" #include "WorldSession.h" -#include "LootMgr.h" #include "Chat.h" #include "zlib.h" #include "ObjectAccessor.h" @@ -37,7 +36,6 @@ #include "OutdoorPvP.h" #include "SocialMgr.h" #include "AccountMgr.h" -#include "CreatureAI.h" #include "DBCEnums.h" #include "ScriptMgr.h" #include "MapManager.h" diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index e86fa523f68..cedfed2e7c5 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -163,7 +163,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff)) { uint32 timeleft = uint32(timeReset - time(NULL)); - GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft); + GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true); } } } diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 03782481ef7..906c3017100 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -20,7 +20,6 @@ #include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Opcodes.h" #include "Log.h" #include "World.h" #include "ObjectMgr.h" @@ -174,15 +173,14 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData) IconName = info->IconName; CastBarCaption = info->castBarCaption; - int loc_idx = GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - { - if (GameObjectLocale const* gl = sObjectMgr->GetGameObjectLocale(entry)) + LocaleConstant localeConstant = GetSessionDbLocaleIndex(); + if (localeConstant >= LOCALE_enUS) + if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry)) { - ObjectMgr::GetLocaleString(gl->Name, loc_idx, Name); - ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption); + ObjectMgr::GetLocaleString(gameObjectLocale->Name, localeConstant, Name); + ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, localeConstant, CastBarCaption); } - } + TC_LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry); WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150); data << uint32(entry); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 3c6258b2d7c..b6297e1705a 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -20,7 +20,6 @@ #include "Log.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Opcodes.h" #include "World.h" #include "ObjectMgr.h" #include "Player.h" diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index cf864772b7c..f87198834b9 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -18,7 +18,6 @@ #include "WorldSession.h" #include "Player.h" #include "ObjectMgr.h" -#include "Opcodes.h" #include "Log.h" void WorldSession::HandleGrantLevel(WorldPacket& recvData) diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index 6da2efa38a6..5f50a7305ee 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -19,7 +19,6 @@ #include "Common.h" #include "Log.h" #include "ObjectAccessor.h" -#include "Opcodes.h" #include "Player.h" #include "Pet.h" #include "WorldPacket.h" diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index 3ae9d6c8672..f3b421a4b93 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -24,7 +24,6 @@ #include "Player.h" #include "TicketMgr.h" #include "Util.h" -#include "World.h" #include "WorldPacket.h" #include "WorldSession.h" diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 4f7e9f05725..c50888544de 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -22,7 +22,6 @@ #include "World.h" #include "ObjectAccessor.h" #include "Log.h" -#include "Opcodes.h" #include "Player.h" #include "Item.h" #include "Spell.h" diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp index 6b9d64be91a..6328eb3e2fe 100644 --- a/src/server/game/Handlers/VehicleHandler.cpp +++ b/src/server/game/Handlers/VehicleHandler.cpp @@ -17,7 +17,6 @@ #include "WorldPacket.h" #include "WorldSession.h" -#include "Opcodes.h" #include "Vehicle.h" #include "Player.h" #include "Log.h" diff --git a/src/server/game/Handlers/VoiceChatHandler.cpp b/src/server/game/Handlers/VoiceChatHandler.cpp index 277755c6eb1..e667eb4bfd9 100644 --- a/src/server/game/Handlers/VoiceChatHandler.cpp +++ b/src/server/game/Handlers/VoiceChatHandler.cpp @@ -19,7 +19,6 @@ #include "Common.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Log.h" void WorldSession::HandleVoiceSessionEnableOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 260c2966a52..b8a2168b34e 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -646,10 +646,10 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b if (warn) { - if (now <= resetTime) + if (now >= resetTime) timeLeft = 0; else - timeLeft = uint32(now - resetTime); + timeLeft = uint32(resetTime - now); ((InstanceMap*)map2)->SendResetWarnings(timeLeft); } @@ -660,19 +660,19 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b /// @todo delete creature/gameobject respawn times even if the maps are not loaded } -uint32 InstanceSaveManager::GetNumBoundPlayersTotal() +uint32 InstanceSaveManager::GetNumBoundPlayersTotal() const { uint32 ret = 0; - for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) + for (InstanceSaveHashMap::const_iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) ret += itr->second->GetPlayerCount(); return ret; } -uint32 InstanceSaveManager::GetNumBoundGroupsTotal() +uint32 InstanceSaveManager::GetNumBoundGroupsTotal() const { uint32 ret = 0; - for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) + for (InstanceSaveHashMap::const_iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end(); ++itr) ret += itr->second->GetGroupCount(); return ret; diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 7494d9f5746..5e8292057a8 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -222,9 +222,9 @@ class InstanceSaveManager InstanceSave* GetInstanceSave(uint32 InstanceId); /* statistics */ - uint32 GetNumInstanceSaves() { return m_instanceSaveById.size(); } - uint32 GetNumBoundPlayersTotal(); - uint32 GetNumBoundGroupsTotal(); + uint32 GetNumInstanceSaves() const { return uint32(m_instanceSaveById.size()); } + uint32 GetNumBoundPlayersTotal() const; + uint32 GetNumBoundGroupsTotal() const; protected: static uint16 ResetTimeDelay[]; diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index be0310017f7..e8eec55ed12 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -22,7 +22,6 @@ #include "World.h" #include "ObjectMgr.h" #include "Player.h" -#include "Unit.h" #include "BattlegroundMgr.h" #include "Item.h" #include "AuctionHouseMgr.h" diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c1a462497cd..354bbe4e269 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -317,7 +317,15 @@ void Map::SwitchGridContainers(Creature* obj, bool on) if (!IsGridLoaded(GridCoord(cell.data.Part.grid_x, cell.data.Part.grid_y))) return; - TC_LOG_DEBUG("maps", "Switch object %s from grid[%u, %u] %u", obj->GetGUID().ToString().c_str(), cell.data.Part.grid_x, cell.data.Part.grid_y, on); + if (sLog->ShouldLog("maps", LOG_LEVEL_DEBUG)) + { + // Extract bitfield values + uint32 const grid_x = cell.data.Part.grid_x; + uint32 const grid_y = cell.data.Part.grid_y; + + TC_LOG_DEBUG("maps", "Switch object %s from grid[%u, %u] %u", obj->GetGUID().ToString().c_str(), grid_x, grid_y, on); + } + NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY()); ASSERT(ngrid != NULL); @@ -354,7 +362,15 @@ void Map::SwitchGridContainers(GameObject* obj, bool on) if (!IsGridLoaded(GridCoord(cell.data.Part.grid_x, cell.data.Part.grid_y))) return; - TC_LOG_DEBUG("maps", "Switch object %s from grid[%u, %u] %u", obj->GetGUID().ToString().c_str(), cell.data.Part.grid_x, cell.data.Part.grid_y, on); + if (sLog->ShouldLog("maps", LOG_LEVEL_DEBUG)) + { + // Extract bitfield values + uint32 const grid_x = cell.data.Part.grid_x; + uint32 const grid_y = cell.data.Part.grid_y; + + TC_LOG_DEBUG("maps", "Switch object %s from grid[%u, %u] %u", obj->GetGUID().ToString().c_str(), grid_x, grid_y, on); + } + NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY()); ASSERT(ngrid != NULL); @@ -3171,7 +3187,7 @@ void InstanceMap::UnloadAll() void InstanceMap::SendResetWarnings(uint32 timeLeft) const { for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) - itr->GetSource()->SendInstanceResetWarning(GetId(), itr->GetSource()->GetDifficulty(IsRaid()), timeLeft); + itr->GetSource()->SendInstanceResetWarning(GetId(), itr->GetSource()->GetDifficulty(IsRaid()), timeLeft, false); } void InstanceMap::SetResetSchedule(bool on) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 43fcbaba31c..15d2169fbbc 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -675,7 +675,7 @@ class InstanceMap : public Map void Update(const uint32) override; void CreateInstanceData(bool load); bool Reset(uint8 method); - uint32 GetScriptId() { return i_script_id; } + uint32 GetScriptId() const { return i_script_id; } InstanceScript* GetInstanceScript() { return i_data; } void PermBindAllPlayers(Player* source); void UnloadAll() override; diff --git a/src/server/game/Maps/MapUpdater.cpp b/src/server/game/Maps/MapUpdater.cpp index 46b2fb86596..20b8da796a5 100644 --- a/src/server/game/Maps/MapUpdater.cpp +++ b/src/server/game/Maps/MapUpdater.cpp @@ -16,12 +16,11 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <mutex> -#include <condition_variable> - #include "MapUpdater.h" #include "Map.h" +#include <mutex> + class MapUpdateRequest { diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 879b8aea537..45fd252ddb9 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -39,7 +39,7 @@ class MovementGenerator virtual bool Update(Unit*, uint32 time_diff) = 0; - virtual MovementGeneratorType GetMovementGeneratorType() = 0; + virtual MovementGeneratorType GetMovementGeneratorType() const = 0; virtual void unitSpeedChanged() { } diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index 4cc4baa081f..5b6d6c96482 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -33,7 +33,7 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov void DoReset(T*); bool DoUpdate(T*, uint32); - MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return CONFUSED_MOTION_TYPE; } private: TimeTracker i_nextMoveTime; float i_x, i_y, i_z; diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index d7cb956e541..dc42dc74991 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -32,7 +32,7 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovem void DoReset(T*); bool DoUpdate(T*, uint32); - MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return FLEEING_MOTION_TYPE; } private: void _setTargetLocation(T*); @@ -49,7 +49,7 @@ class TimedFleeingMovementGenerator : public FleeingMovementGenerator<Creature> FleeingMovementGenerator<Creature>(fright), i_totalFleeTime(time) { } - MovementGeneratorType GetMovementGeneratorType() override { return TIMED_FLEEING_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return TIMED_FLEEING_MOTION_TYPE; } bool Update(Unit*, uint32) override; void Finalize(Unit*) override; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h index 099d81ff54e..cbb6f279c6d 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h @@ -38,7 +38,7 @@ class HomeMovementGenerator<Creature> : public MovementGeneratorMedium< Creature void DoFinalize(Creature*); void DoReset(Creature*); bool DoUpdate(Creature*, const uint32); - MovementGeneratorType GetMovementGeneratorType() override { return HOME_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return HOME_MOTION_TYPE; } private: void _setTargetLocation(Creature*); diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp index 78d86fb7abb..2aaaa719e94 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp @@ -81,12 +81,23 @@ void RotateMovementGenerator::Finalize(Unit* unit) void DistractMovementGenerator::Initialize(Unit* owner) { + // Distracted creatures stand up if not standing + if (!owner->IsStandState()) + owner->SetStandState(UNIT_STAND_STATE_STAND); + owner->AddUnitState(UNIT_STATE_DISTRACTED); } void DistractMovementGenerator::Finalize(Unit* owner) { owner->ClearUnitState(UNIT_STATE_DISTRACTED); + + // If this is a creature, then return orientation to original position (for idle movement creatures) + if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()) + { + float angle = owner->ToCreature()->GetHomePosition().GetOrientation(); + owner->SetFacingTo(angle); + } } bool DistractMovementGenerator::Update(Unit* /*owner*/, uint32 time_diff) diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h index e4ea99e00cb..30a8b9b868e 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h @@ -29,7 +29,7 @@ class IdleMovementGenerator : public MovementGenerator void Finalize(Unit*) override { } void Reset(Unit*) override; bool Update(Unit*, uint32) override { return true; } - MovementGeneratorType GetMovementGeneratorType() override { return IDLE_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return IDLE_MOTION_TYPE; } }; extern IdleMovementGenerator si_idleMovement; @@ -43,7 +43,7 @@ class RotateMovementGenerator : public MovementGenerator void Finalize(Unit*) override; void Reset(Unit* owner) override { Initialize(owner); } bool Update(Unit*, uint32) override; - MovementGeneratorType GetMovementGeneratorType() override { return ROTATE_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return ROTATE_MOTION_TYPE; } private: uint32 m_duration, m_maxDuration; @@ -59,7 +59,7 @@ class DistractMovementGenerator : public MovementGenerator void Finalize(Unit*) override; void Reset(Unit* owner) override { Initialize(owner); } bool Update(Unit*, uint32) override; - MovementGeneratorType GetMovementGeneratorType() override { return DISTRACT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return DISTRACT_MOTION_TYPE; } private: uint32 m_timer; @@ -71,7 +71,7 @@ class AssistanceDistractMovementGenerator : public DistractMovementGenerator AssistanceDistractMovementGenerator(uint32 timer) : DistractMovementGenerator(timer) { } - MovementGeneratorType GetMovementGeneratorType() override { return ASSISTANCE_DISTRACT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return ASSISTANCE_DISTRACT_MOTION_TYPE; } void Finalize(Unit*) override; }; diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index e967bd7f0ba..f143e19b24b 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -38,7 +38,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG void unitSpeedChanged() { i_recalculateSpeed = true; } - MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return POINT_MOTION_TYPE; } void GetDestination(float& x, float& y, float& z) const { x = i_x; y = i_y; z = i_z; } private: @@ -55,7 +55,7 @@ class AssistanceMovementGenerator : public PointMovementGenerator<Creature> AssistanceMovementGenerator(float _x, float _y, float _z) : PointMovementGenerator<Creature>(0, _x, _y, _z, true) { } - MovementGeneratorType GetMovementGeneratorType() override { return ASSISTANCE_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return ASSISTANCE_MOTION_TYPE; } void Finalize(Unit*) override; }; @@ -68,7 +68,7 @@ class EffectMovementGenerator : public MovementGenerator void Finalize(Unit*) override; void Reset(Unit*) override { } bool Update(Unit*, uint32) override; - MovementGeneratorType GetMovementGeneratorType() override { return EFFECT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return EFFECT_MOTION_TYPE; } private: uint32 m_Id; }; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h index 175e512c35d..763e3294613 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h @@ -33,7 +33,7 @@ class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovemen void DoReset(T*); bool DoUpdate(T*, const uint32); bool GetResetPos(T*, float& x, float& y, float& z); - MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return RANDOM_MOTION_TYPE; } private: TimeTrackerSmall i_nextMoveTime; diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 44d64909a3c..77a669e0738 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -73,7 +73,7 @@ class ChaseMovementGenerator : public TargetedMovementGeneratorMedium<T, ChaseMo : TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target, offset, angle) { } ~ChaseMovementGenerator() { } - MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return CHASE_MOTION_TYPE; } void DoInitialize(T*); void DoFinalize(T*); @@ -97,7 +97,7 @@ class FollowMovementGenerator : public TargetedMovementGeneratorMedium<T, Follow : TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >(target, offset, angle) { } ~FollowMovementGenerator() { } - MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return FOLLOW_MOTION_TYPE; } void DoInitialize(T*); void DoFinalize(T*); diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index f65af3fb73d..eb8533159a9 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -72,7 +72,7 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Crea void MovementInform(Creature*); - MovementGeneratorType GetMovementGeneratorType() override { return WAYPOINT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return WAYPOINT_MOTION_TYPE; } // now path movement implmementation void LoadPath(Creature*); @@ -126,7 +126,7 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig void DoReset(Player*); void DoFinalize(Player*); bool DoUpdate(Player*, uint32); - MovementGeneratorType GetMovementGeneratorType() override { return FLIGHT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() const override { return FLIGHT_MOTION_TYPE; } TaxiPathNodeList const& GetPath() { return *i_path; } uint32 GetPathAtMapEnd() const; diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index efefcdce834..186b5d400b2 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -853,16 +853,16 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo npolys -= npos; // Handle the connection. - float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE]; - if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos))) + float connectionStartPos[VERTEX_SIZE], connectionEndPos[VERTEX_SIZE]; + if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, connectionStartPos, connectionEndPos))) { if (nsmoothPath < maxSmoothPathSize) { - dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], startPos); + dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], connectionStartPos); nsmoothPath++; } // Move position at the other side of the off-mesh link. - dtVcopy(iterPos, endPos); + dtVcopy(iterPos, connectionEndPos); _navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]); iterPos[1] += 0.5f; } diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 1beeebbbad3..ccf8824051b 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -17,10 +17,11 @@ */ #include "MoveSpline.h" -#include <sstream> #include "Log.h" #include "Creature.h" +#include <sstream> + namespace Movement{ Location MoveSpline::ComputePosition() const diff --git a/src/server/game/Movement/Spline/Spline.cpp b/src/server/game/Movement/Spline/Spline.cpp index b8a028b6fc0..fff83b788f9 100644 --- a/src/server/game/Movement/Spline/Spline.cpp +++ b/src/server/game/Movement/Spline/Spline.cpp @@ -204,7 +204,7 @@ void SplineBase::init_spline(const Vector3 * controls, index_type count, Evaluat m_mode = m; cyclic = false; - (this->*initializers[m_mode])(controls, count, cyclic, 0); + (this->*initializers[m_mode])(controls, count, 0); } void SplineBase::init_cyclic_spline(const Vector3 * controls, index_type count, EvaluationMode m, index_type cyclic_point) @@ -212,10 +212,10 @@ void SplineBase::init_cyclic_spline(const Vector3 * controls, index_type count, m_mode = m; cyclic = true; - (this->*initializers[m_mode])(controls, count, cyclic, cyclic_point); + (this->*initializers[m_mode])(controls, count, cyclic_point); } -void SplineBase::InitLinear(const Vector3* controls, index_type count, bool cyclic, index_type cyclic_point) +void SplineBase::InitLinear(const Vector3* controls, index_type count, index_type cyclic_point) { ASSERT(count >= 2); const int real_size = count + 1; @@ -235,7 +235,7 @@ void SplineBase::InitLinear(const Vector3* controls, index_type count, bool cycl index_hi = cyclic ? count : (count - 1); } -void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, bool cyclic, index_type cyclic_point) +void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, index_type cyclic_point) { const int real_size = count + (cyclic ? (1+2) : (1+1)); @@ -268,7 +268,7 @@ void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, bool index_hi = high_index + (cyclic ? 1 : 0); } -void SplineBase::InitBezier3(const Vector3* controls, index_type count, bool /*cyclic*/, index_type /*cyclic_point*/) +void SplineBase::InitBezier3(const Vector3* controls, index_type count, index_type /*cyclic_point*/) { index_type c = count / 3u * 3u; index_type t = c / 3u; diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index 6e8a5a0281d..c8b7a19c943 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -76,10 +76,10 @@ protected: typedef float (SplineBase::*SegLenghtMethtod)(index_type) const; static SegLenghtMethtod seglengths[ModesEnd]; - void InitLinear(const Vector3*, index_type, bool, index_type); - void InitCatmullRom(const Vector3*, index_type, bool, index_type); - void InitBezier3(const Vector3*, index_type, bool, index_type); - typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, bool, index_type); + void InitLinear(const Vector3*, index_type, index_type); + void InitCatmullRom(const Vector3*, index_type, index_type); + void InitBezier3(const Vector3*, index_type, index_type); + typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, index_type); static InitMethtod initializers[ModesEnd]; void UninitializedSpline() const { ASSERT(false);} diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index c8bc68d0ddf..3648fe5cde5 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -125,7 +125,7 @@ bool OPvPCapturePoint::AddObject(uint32 type, uint32 entry, uint32 map, float x, bool OPvPCapturePoint::AddCreature(uint32 type, uint32 entry, uint32 map, float x, float y, float z, float o, TeamId /*teamId = TEAM_NEUTRAL*/, uint32 spawntimedelay /*= 0*/) { - if (uint32 guid = sObjectMgr->AddCreData(entry, map, x, y, z, o, spawntimedelay)) + if (uint32 guid = sObjectMgr->AddCreatureData(entry, map, x, y, z, o, spawntimedelay)) { AddCre(type, guid, entry); return true; diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index ad99c64fbbd..d5839956e32 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -236,7 +236,7 @@ class OutdoorPvP : public ZoneScript // awards rewards for player kill virtual void AwardKillBonus(Player* /*player*/) { } - uint32 GetTypeId() {return m_TypeId;} + uint32 GetTypeId() const {return m_TypeId;} virtual bool HandleDropFlag(Player* player, uint32 spellId); diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp index 3beaa7daa9b..f5c4375712c 100644 --- a/src/server/game/Scripting/MapScripts.cpp +++ b/src/server/game/Scripting/MapScripts.cpp @@ -23,6 +23,7 @@ #include "Map.h" #include "ObjectMgr.h" #include "Pet.h" +#include "Item.h" #include "ScriptedCreature.h" #include "ScriptMgr.h" #include "Transport.h" diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index f0ee013bcc2..7c4b11769b5 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -360,7 +360,6 @@ void AddSC_orgrimmar(); void AddSC_silithus(); void AddSC_stonetalon_mountains(); void AddSC_tanaris(); -void AddSC_teldrassil(); void AddSC_the_barrens(); void AddSC_thousand_needles(); void AddSC_thunder_bluff(); @@ -1066,7 +1065,6 @@ void AddKalimdorScripts() AddSC_silithus(); AddSC_stonetalon_mountains(); AddSC_tanaris(); - AddSC_teldrassil(); AddSC_the_barrens(); AddSC_thousand_needles(); AddSC_thunder_bluff(); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 14ce4cfe3c1..4f7b8f510b0 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1273,7 +1273,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4DC*/ { "SMSG_PVP_QUEUE_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x4DD*/ { "CMSG_SET_PAID_SERVICE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse }, + /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBfEntryInviteResponse }, /*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse }, diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index d6055e9733b..bb22d27221e 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -39,10 +39,12 @@ #include "BattlegroundMgr.h" #include "OutdoorPvPMgr.h" #include "SocialMgr.h" -#include "zlib.h" #include "ScriptMgr.h" #include "WardenWin.h" #include "MoveSpline.h" +#include "WardenMac.h" + +#include <zlib.h> namespace { diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index eda8f0bb6d9..87a40657e24 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -288,7 +288,7 @@ class WorldSession uint32 GetGuidLow() const; void SetSecurity(AccountTypes security) { _security = security; } - std::string const& GetRemoteAddress() { return m_Address; } + std::string const& GetRemoteAddress() const { return m_Address; } void SetPlayer(Player* player); uint8 Expansion() const { return m_expansion; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index cff423c71c6..066a4e501be 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -19,10 +19,10 @@ #include "WorldSocket.h" #include "BigNumber.h" #include "Opcodes.h" -#include "Player.h" #include "ScriptMgr.h" #include "SHA1.h" #include "PacketLog.h" + #include <memory> using boost::asio::ip::tcp; @@ -509,6 +509,8 @@ void WorldSocket::SendAuthResponseError(uint8 code) bool WorldSocket::HandlePing(WorldPacket& recvPacket) { + using namespace std::chrono; + uint32 ping; uint32 latency; diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp index 86c09ef6b6b..da35017cc2b 100644 --- a/src/server/game/Server/WorldSocketMgr.cpp +++ b/src/server/game/Server/WorldSocketMgr.cpp @@ -21,6 +21,7 @@ #include "ScriptMgr.h" #include "WorldSocket.h" #include "WorldSocketMgr.h" + #include <boost/system/error_code.hpp> static void OnSocketAccept(tcp::socket&& sock) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 286cdf51bf1..2fe4b624164 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -25,15 +25,15 @@ #include "Player.h" #include "Unit.h" #include "ObjectAccessor.h" +#include "CellImpl.h" #include "Util.h" #include "Spell.h" #include "SpellHistory.h" #include "SpellAuraEffects.h" #include "Battleground.h" #include "OutdoorPvPMgr.h" -#include "Formulas.h" #include "GridNotifiers.h" -#include "CellImpl.h" +#include "GridNotifiersImpl.h" #include "ScriptMgr.h" #include "Vehicle.h" #include "Battlefield.h" diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index e3a72372b1c..a8ff36a94b6 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1066,8 +1066,8 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar { case TARGET_OBJECT_TYPE_UNIT: { - if (Unit* unitTarget = target->ToUnit()) - AddUnitTarget(unitTarget, effMask, true, false); + if (Unit* unit = target->ToUnit()) + AddUnitTarget(unit, effMask, true, false); else { TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set object of wrong type, expected unit, got %s, effect %u", m_spellInfo->Id, target->GetGUID().GetTypeName(), effMask); @@ -1132,8 +1132,8 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) { - if (Unit* unitTarget = (*itr)->ToUnit()) - AddUnitTarget(unitTarget, effMask, false); + if (Unit* unit = (*itr)->ToUnit()) + AddUnitTarget(unit, effMask, false); else if (GameObject* gObjTarget = (*itr)->ToGameObject()) AddGOTarget(gObjTarget, effMask); } @@ -1213,8 +1213,8 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) { - if (Unit* unitTarget = (*itr)->ToUnit()) - AddUnitTarget(unitTarget, effMask, false, true, center); + if (Unit* unit = (*itr)->ToUnit()) + AddUnitTarget(unit, effMask, false, true, center); else if (GameObject* gObjTarget = (*itr)->ToGameObject()) AddGOTarget(gObjTarget, effMask); } @@ -1472,8 +1472,8 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType); for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) - if (Unit* unitTarget = (*itr)->ToUnit()) - AddUnitTarget(unitTarget, effMask, false); + if (Unit* unit = (*itr)->ToUnit()) + AddUnitTarget(unit, effMask, false); } } @@ -1528,12 +1528,12 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) if (m_spellInfo->CheckTarget(m_caster, *itr, true) != SPELL_CAST_OK) continue; - if (Unit* unitTarget = (*itr)->ToUnit()) + if (Unit* unit = (*itr)->ToUnit()) { - if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || unitTarget->GetVehicle()) + if (m_caster == *itr || m_caster->IsOnVehicle(unit) || unit->GetVehicle()) continue; - if (Creature* creatureTarget = unitTarget->ToCreature()) + if (Creature* creatureTarget = unit->ToCreature()) { if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PROJECTILE_COLLISION)) continue; @@ -1682,8 +1682,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)) { - if (Unit* unitTarget = m_targets.GetUnitTarget()) - target = unitTarget; + if (Unit* unit = m_targets.GetUnitTarget()) + target = unit; else if (targetMask & TARGET_FLAG_CORPSE_MASK) { if (Corpse* corpseTarget = m_targets.GetCorpseTarget()) @@ -1698,8 +1698,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) } if (targetMask & TARGET_FLAG_ITEM_MASK) { - if (Item* itemTarget = m_targets.GetItemTarget()) - AddItemTarget(itemTarget, 1 << effIndex); + if (Item* item = m_targets.GetItemTarget()) + AddItemTarget(item, 1 << effIndex); return; } if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK) @@ -1876,10 +1876,10 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar uint32 maxHPDeficit = 0; for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr) { - if (Unit* unitTarget = (*itr)->ToUnit()) + if (Unit* unit = (*itr)->ToUnit()) { - uint32 deficit = unitTarget->GetMaxHealth() - unitTarget->GetHealth(); - if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unitTarget, jumpRadius) && target->IsWithinLOSInMap(unitTarget)) + uint32 deficit = unit->GetMaxHealth() - unit->GetHealth(); + if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit)) { foundItr = itr; maxHPDeficit = deficit; @@ -2901,6 +2901,14 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered triggeredByAura->GetBase()->SetDuration(0); } + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + m_caster->ToPlayer()->RestoreSpellMods(this); + // cleanup after mod system + // triggered spell pointer can be not removed in some cases + m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + } + SendCastResult(result); finish(false); @@ -5003,12 +5011,12 @@ SpellCastResult Spell::CheckCast(bool strict) case SPELL_EFFECT_LEARN_PET_SPELL: { // check target only for unit target case - if (Unit* unitTarget = m_targets.GetUnitTarget()) + if (Unit* unit = m_targets.GetUnitTarget()) { if (m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_BAD_TARGETS; - Pet* pet = unitTarget->ToPet(); + Pet* pet = unit->ToPet(); if (!pet || pet->GetOwner() != m_caster) return SPELL_FAILED_BAD_TARGETS; @@ -5088,12 +5096,13 @@ SpellCastResult Spell::CheckCast(bool strict) m_preGeneratedPath.SetPathLengthLimit(range); // first try with raycast, if it fails fall back to normal path - bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize() / 2.f, false, true); + float targetObjectSize = std::min(target->GetObjectSize(), 4.0f); + bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true); if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) { - result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + target->GetObjectSize() / 2.f, false, false); + result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, false); if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) @@ -5390,8 +5399,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER) return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED; - int32 damage = CalculateDamage(i, target); - if (damage && int32(target->getLevel()) > damage) + int32 value = CalculateDamage(i, target); + if (value && int32(target->getLevel()) > value) return SPELL_FAILED_HIGHLEVEL; } @@ -6463,8 +6472,8 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo return false; if (target->GetCharmerGUID()) return false; - if (int32 damage = CalculateDamage(eff, target)) - if ((int32)target->getLevel() > damage) + if (int32 value = CalculateDamage(eff, target)) + if ((int32)target->getLevel() > value) return false; break; default: diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 965b2463139..69607b43785 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3408,9 +3408,9 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) uint32 eff_damage(std::max(weaponDamage, 0)); // Add melee damage bonuses (also check for negative) - uint32 damage = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo); + uint32 damageBonusDone = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo); - m_damage += unitTarget->MeleeDamageBonusTaken(m_caster, damage, m_attackType, m_spellInfo); + m_damage += unitTarget->MeleeDamageBonusTaken(m_caster, damageBonusDone, m_attackType, m_spellInfo); } void Spell::EffectThreat(SpellEffIndex /*effIndex*/) @@ -3664,9 +3664,9 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) case 54426: if (unitTarget) { - int32 damage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5)); - if (damage > 0) - m_caster->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, damage, unitTarget); + int32 decimateDamage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5)); + if (decimateDamage > 0) + m_caster->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, decimateDamage, unitTarget); } return; // Mirren's Drinking Hat diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 53b44fdd5cc..a7439171f8f 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3147,6 +3147,11 @@ void SpellMgr::LoadSpellInfoCorrections() case 28200: // Ascendance (Talisman of Ascendance trinket) spellInfo->ProcCharges = 6; break; + case 49224: // Magic Suppression - DK + case 49610: // Magic Suppression - DK + case 49611: // Magic Suppression - DK + spellInfo->ProcCharges = 0; + break; case 37408: // Oscillation Field spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS; break; @@ -3158,6 +3163,11 @@ void SpellMgr::LoadSpellInfoCorrections() // add corruption to affected spells spellInfo->Effects[EFFECT_1].SpellClassMask[0] |= 2; break; + case 57470: // Renewed Hope (Rank 1) + case 57472: // Renewed Hope (Rank 2) + // should also affect Flash Heal + spellInfo->Effects[EFFECT_0].SpellClassMask[0] |= 0x800; + break; case 51852: // The Eye of Acherus (no spawn in phase 2 in db) spellInfo->Effects[EFFECT_0].MiscValue |= 1; break; @@ -3235,6 +3245,9 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_1].BasePoints = -6; // -5% break; case 50526: // Wandering Plague + case 15290: // Vampiric Embrace + spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO; + break; case 63675: // Improved Devouring Plague spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS; break; diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 09f557dc63b..95857be27dc 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -15,10 +15,11 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <string> #include "Spell.h" #include "SpellAuras.h" #include "SpellScript.h" +#include "SpellMgr.h" +#include <string> bool _SpellScript::_Validate(SpellInfo const* entry) { @@ -84,9 +85,9 @@ uint8 _SpellScript::EffectHook::GetAffectedEffectsMask(SpellInfo const* spellEnt return mask; } -bool _SpellScript::EffectHook::IsEffectAffected(SpellInfo const* spellEntry, uint8 effIndex) +bool _SpellScript::EffectHook::IsEffectAffected(SpellInfo const* spellEntry, uint8 effIndexToCheck) { - return (GetAffectedEffectsMask(spellEntry) & 1 << effIndex) != 0; + return (GetAffectedEffectsMask(spellEntry) & 1 << effIndexToCheck) != 0; } std::string _SpellScript::EffectHook::EffIndexToString() @@ -182,14 +183,14 @@ std::string SpellScript::EffectHandler::ToString() return "Index: " + EffIndexToString() + " Name: " +_SpellScript::EffectNameCheck::ToString(); } -bool SpellScript::EffectHandler::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) +bool SpellScript::EffectHandler::CheckEffect(SpellInfo const* spellEntry, uint8 effIndexToCheck) { - return _SpellScript::EffectNameCheck::Check(spellEntry, effIndex); + return _SpellScript::EffectNameCheck::Check(spellEntry, effIndexToCheck); } -void SpellScript::EffectHandler::Call(SpellScript* spellScript, SpellEffIndex effIndex) +void SpellScript::EffectHandler::Call(SpellScript* spellScript, SpellEffIndex effIndexToHandle) { - (spellScript->*pEffectHandlerScript)(effIndex); + (spellScript->*pEffectHandlerScript)(effIndexToHandle); } SpellScript::HitHandler::HitHandler(SpellHitFnType _pHitHandlerScript) @@ -212,13 +213,13 @@ std::string SpellScript::TargetHook::ToString() return oss.str(); } -bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) +bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 effIndexToCheck) { if (!targetType) return false; - if (spellEntry->Effects[effIndex].TargetA.GetTarget() != targetType && - spellEntry->Effects[effIndex].TargetB.GetTarget() != targetType) + if (spellEntry->Effects[effIndexToCheck].TargetA.GetTarget() != targetType && + spellEntry->Effects[effIndexToCheck].TargetB.GetTarget() != targetType) return false; SpellImplicitTargetInfo targetInfo(targetType); @@ -758,9 +759,9 @@ void AuraScript::AuraDispelHandler::Call(AuraScript* auraScript, DispelInfo* _di AuraScript::EffectBase::EffectBase(uint8 _effIndex, uint16 _effName) : _SpellScript::EffectAuraNameCheck(_effName), _SpellScript::EffectHook(_effIndex) { } -bool AuraScript::EffectBase::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex) +bool AuraScript::EffectBase::CheckEffect(SpellInfo const* spellEntry, uint8 effIndexToCheck) { - return _SpellScript::EffectAuraNameCheck::Check(spellEntry, effIndex); + return _SpellScript::EffectAuraNameCheck::Check(spellEntry, effIndexToCheck); } std::string AuraScript::EffectBase::ToString() diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index ecf7697db0d..69facc6895b 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -22,12 +22,13 @@ #include "Log.h" #include "Opcodes.h" #include "ByteBuffer.h" -#include <openssl/sha.h> #include "World.h" #include "Util.h" #include "Warden.h" #include "AccountMgr.h" +#include <openssl/sha.h> + Warden::Warden() : _session(NULL), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), _dataSent(false), _previousTimestamp(0), _module(NULL), _initialized(false) { diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp index 2eccd4c46ff..8abd48bd3f7 100644 --- a/src/server/game/Warden/WardenMac.cpp +++ b/src/server/game/Warden/WardenMac.cpp @@ -23,13 +23,14 @@ #include "Log.h" #include "Opcodes.h" #include "ByteBuffer.h" -#include <openssl/md5.h> #include "World.h" #include "Player.h" #include "Util.h" #include "WardenMac.h" #include "WardenModuleMac.h" +#include <openssl/md5.h> + WardenMac::WardenMac() : Warden() { } WardenMac::~WardenMac() { } diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 7db5e8f39e5..2fe11a7eeed 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -24,7 +24,6 @@ #include "Log.h" #include "Opcodes.h" #include "ByteBuffer.h" -#include <openssl/md5.h> #include "Database/DatabaseEnv.h" #include "World.h" #include "Player.h" @@ -32,6 +31,7 @@ #include "WardenWin.h" #include "WardenModuleWin.h" #include "WardenCheckMgr.h" +#include <openssl/md5.h> WardenWin::WardenWin() : Warden(), _serverTicks(0) {} diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 9100dd464b9..64775a05faa 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -25,7 +25,6 @@ #include "Log.h" #include "ObjectMgr.h" #include "Player.h" -#include "WorldPacket.h" #include "WorldSession.h" namespace WeatherMgr diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 7cddfc3f61e..9c4cb1002c7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1299,7 +1299,7 @@ void World::LoadConfigSettings(bool reload) sScriptMgr->OnConfigLoad(reload); } -extern void LoadGameObjectModelList(); +extern void LoadGameObjectModelList(std::string const& dataPath); /// Initialize the World void World::SetInitialWorldSettings() @@ -1375,6 +1375,17 @@ void World::SetInitialWorldSettings() LoadDBCStores(m_dataPath); DetectDBCLang(); + std::vector<uint32> mapIds; + for (uint32 mapId = 0; mapId < sMapStore.GetNumRows(); mapId++) + if (sMapStore.LookupEntry(mapId)) + mapIds.push_back(mapId); + + if (VMAP::VMapManager2* vmmgr2 = dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())) + vmmgr2->InitializeThreadUnsafe(mapIds); + + MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager(); + mmmgr->InitializeThreadUnsafe(mapIds); + TC_LOG_INFO("server.loading", "Loading SpellInfo store..."); sSpellMgr->LoadSpellInfoStore(); @@ -1388,7 +1399,7 @@ void World::SetInitialWorldSettings() sSpellMgr->LoadSpellInfoCustomAttributes(); TC_LOG_INFO("server.loading", "Loading GameObject models..."); - LoadGameObjectModelList(); + LoadGameObjectModelList(m_dataPath); TC_LOG_INFO("server.loading", "Loading Script Names..."); sObjectMgr->LoadScriptNames(); diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index 39ad786cf83..3e4b46804ff 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -500,7 +500,7 @@ public: stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_LIST_INFO); stmt->setUInt32(0, targetGuid.GetCounter()); - PreparedQueryResult queryResult = CharacterDatabase.Query(stmt); + queryResult = CharacterDatabase.Query(stmt); if (queryResult) { diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index c8a908f6930..7baef489865 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1325,8 +1325,8 @@ public: static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) { - Player* SelectedPlayer = handler->getSelectedPlayer(); - if (!SelectedPlayer) + Player* player = handler->getSelectedPlayerOrSelf(); + if (!player) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); handler->SetSentErrorMessage(true); @@ -1334,7 +1334,7 @@ public: } // each skills that have max skill value dependent from level seted to current level max skill value - SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); + player->UpdateSkillsToMaxSkillsForLevel(); return true; } diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index 497bd45ec5c..03f35e6ba65 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -1,383 +1,383 @@ -/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* ScriptData
-Name: rbac_commandscript
-%Complete: 100
-Comment: All role based access control related commands (including account related)
-Category: commandscripts
-EndScriptData */
-
-#include "AccountMgr.h"
-#include "Config.h"
-#include "Chat.h"
-#include "Language.h"
-#include "Player.h"
-#include "ScriptMgr.h"
-
-struct RBACCommandData
-{
- RBACCommandData(): id(0), realmId(0), rbac(NULL), needDelete(false) { }
- ~RBACCommandData()
- {
- if (needDelete)
- delete rbac;
- }
-
- uint32 id;
- int32 realmId;
- rbac::RBACData* rbac;
- bool needDelete;
-};
-
-class rbac_commandscript : public CommandScript
-{
-public:
- rbac_commandscript() : CommandScript("rbac_commandscript") { }
-
- ChatCommand* GetCommands() const
- {
- static ChatCommand rbacAccountCommandTable[] =
- {
- { "list", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST, true, &HandleRBACPermListCommand, "", NULL },
- { "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, true, &HandleRBACPermGrantCommand, "", NULL },
- { "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, true, &HandleRBACPermDenyCommand, "", NULL },
- { "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, true, &HandleRBACPermRevokeCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand rbacCommandTable[] =
- {
- { "account", rbac::RBAC_PERM_COMMAND_RBAC_ACC, true, NULL, "", rbacAccountCommandTable },
- { "list", rbac::RBAC_PERM_COMMAND_RBAC_LIST, true, &HandleRBACListPermissionsCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand commandTable[] =
- {
- { "rbac", rbac::RBAC_PERM_COMMAND_RBAC, true, NULL, "", rbacCommandTable },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- return commandTable;
- }
-
- static RBACCommandData* ReadParams(ChatHandler* handler, char const* args, bool checkParams = true)
- {
- if (!args)
- return NULL;
-
- char* param1 = strtok((char*)args, " ");
- char* param2 = strtok(NULL, " ");
- char* param3 = strtok(NULL, " ");
-
- int32 realmId = -1;
- uint32 accountId = 0;
- std::string accountName;
- uint32 id = 0;
- RBACCommandData* data = NULL;
- rbac::RBACData* rdata = NULL;
- bool useSelectedPlayer = false;
-
- if (checkParams)
- {
- if (!param3)
- {
- if (param2)
- realmId = atoi(param2);
-
- if (param1)
- id = atoi(param1);
-
- useSelectedPlayer = true;
- }
- else
- {
- id = atoi(param2);
- realmId = atoi(param3);
- }
-
- if (!id)
- {
- handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
- handler->SetSentErrorMessage(true);
- return NULL;
- }
-
- if (realmId < -1 || !realmId)
- {
- handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_REALM, realmId);
- handler->SetSentErrorMessage(true);
- return NULL;
- }
- }
- else if (!param1)
- useSelectedPlayer = true;
-
- if (useSelectedPlayer)
- {
- Player* player = handler->getSelectedPlayer();
- if (!player)
- return NULL;
-
- rdata = player->GetSession()->GetRBACData();
- accountId = rdata->GetId();
- AccountMgr::GetName(accountId, accountName);
- }
- else
- {
- accountName = param1;
-
- if (AccountMgr::normalizeString(accountName))
- accountId = AccountMgr::GetId(accountName);
-
- if (!accountId)
- {
- handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str());
- handler->SetSentErrorMessage(true);
- return NULL;
- }
- }
-
- if (checkParams && handler->HasLowerSecurityAccount(NULL, accountId, true))
- return NULL;
-
- data = new RBACCommandData();
-
- if (!rdata)
- {
- data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID));
- data->rbac->LoadFromDB();
- data->needDelete = true;
- }
- else
- data->rbac = rdata;
-
- data->id = id;
- data->realmId = realmId;
- return data;
- }
-
- static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args)
- {
- RBACCommandData* command = ReadParams(handler, args);
-
- if (!command)
- {
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- rbac::RBACCommandResult result = command->rbac->GrantPermission(command->id, command->realmId);
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id);
-
- switch (result)
- {
- case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
- handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_LIST, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_IN_DENIED_LIST:
- handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_OK:
- handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_ID_DOES_NOT_EXISTS:
- handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
- break;
- default:
- break;
- }
-
- delete command;
-
- return true;
- }
-
- static bool HandleRBACPermDenyCommand(ChatHandler* handler, char const* args)
- {
- RBACCommandData* command = ReadParams(handler, args);
-
- if (!command)
- {
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- rbac::RBACCommandResult result = command->rbac->DenyPermission(command->id, command->realmId);
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id);
-
- switch (result)
- {
- case rbac::RBAC_CANT_ADD_ALREADY_ADDED:
- handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_LIST, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_IN_GRANTED_LIST:
- handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_OK:
- handler->PSendSysMessage(LANG_RBAC_PERM_DENIED, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_ID_DOES_NOT_EXISTS:
- handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
- break;
- default:
- break;
- }
-
- delete command;
-
- return true;
- }
-
- static bool HandleRBACPermRevokeCommand(ChatHandler* handler, char const* args)
- {
- RBACCommandData* command = ReadParams(handler, args);
-
- if (!command)
- {
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- rbac::RBACCommandResult result = command->rbac->RevokePermission(command->id, command->realmId);
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id);
-
- switch (result)
- {
- case rbac::RBAC_CANT_REVOKE_NOT_IN_LIST:
- handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED_NOT_IN_LIST, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_OK:
- handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED, command->id, permission->GetName().c_str(),
- command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str());
- break;
- case rbac::RBAC_ID_DOES_NOT_EXISTS:
- handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id);
- break;
- default:
- break;
- }
-
- delete command;
-
- return true;
- }
-
- static bool HandleRBACPermListCommand(ChatHandler* handler, char const* args)
- {
- RBACCommandData* command = ReadParams(handler, args, false);
-
- if (!command)
- {
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str());
- rbac::RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions();
- if (granted.empty())
- handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
- else
- {
- for (rbac::RBACPermissionContainer::const_iterator itr = granted.begin(); itr != granted.end(); ++itr)
- {
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr);
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
- }
- }
-
- handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str());
- rbac::RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions();
- if (denied.empty())
- handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
- else
- {
- for (rbac::RBACPermissionContainer::const_iterator itr = denied.begin(); itr != denied.end(); ++itr)
- {
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr);
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
- }
- }
- handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_BY_SEC_LEVEL, command->rbac->GetId(), command->rbac->GetName().c_str(), command->rbac->GetSecurityLevel());
- rbac::RBACPermissionContainer const& defaultPermissions = sAccountMgr->GetRBACDefaultPermissions(command->rbac->GetSecurityLevel());
- if (defaultPermissions.empty())
- handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY));
- else
- {
- for (rbac::RBACPermissionContainer::const_iterator itr = defaultPermissions.begin(); itr != defaultPermissions.end(); ++itr)
- {
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr);
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
- }
- }
-
- delete command;
-
- return true;
- }
-
- static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args)
- {
- uint32 id = 0;
- if (char* param1 = strtok((char*)args, " "))
- id = atoi(param1);
-
- if (!id)
- {
- rbac::RBACPermissionsContainer const& permissions = sAccountMgr->GetRBACPermissionList();
- handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
- for (rbac::RBACPermissionsContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it)
- {
- rbac::RBACPermission const* permission = it->second;
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
- }
- }
- else
- {
- rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(id);
- if (!permission)
- {
- handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER));
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str());
- handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMS_LINKED_HEADER));
- rbac::RBACPermissionContainer const& permissions = permission->GetLinkedPermissions();
- for (rbac::RBACPermissionContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it)
- if (rbac::RBACPermission const* rbacPermission = sAccountMgr->GetRBACPermission(*it))
- handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, rbacPermission->GetId(), rbacPermission->GetName().c_str());
- }
-
- return true;
- }
-};
-
-void AddSC_rbac_commandscript()
-{
- new rbac_commandscript();
-}
+/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* ScriptData +Name: rbac_commandscript +%Complete: 100 +Comment: All role based access control related commands (including account related) +Category: commandscripts +EndScriptData */ + +#include "AccountMgr.h" +#include "Config.h" +#include "Chat.h" +#include "Language.h" +#include "Player.h" +#include "ScriptMgr.h" + +struct RBACCommandData +{ + RBACCommandData(): id(0), realmId(0), rbac(NULL), needDelete(false) { } + ~RBACCommandData() + { + if (needDelete) + delete rbac; + } + + uint32 id; + int32 realmId; + rbac::RBACData* rbac; + bool needDelete; +}; + +class rbac_commandscript : public CommandScript +{ +public: + rbac_commandscript() : CommandScript("rbac_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand rbacAccountCommandTable[] = + { + { "list", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST, true, &HandleRBACPermListCommand, "", NULL }, + { "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, true, &HandleRBACPermGrantCommand, "", NULL }, + { "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, true, &HandleRBACPermDenyCommand, "", NULL }, + { "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, true, &HandleRBACPermRevokeCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand rbacCommandTable[] = + { + { "account", rbac::RBAC_PERM_COMMAND_RBAC_ACC, true, NULL, "", rbacAccountCommandTable }, + { "list", rbac::RBAC_PERM_COMMAND_RBAC_LIST, true, &HandleRBACListPermissionsCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "rbac", rbac::RBAC_PERM_COMMAND_RBAC, true, NULL, "", rbacCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + + return commandTable; + } + + static RBACCommandData* ReadParams(ChatHandler* handler, char const* args, bool checkParams = true) + { + if (!args) + return NULL; + + char* param1 = strtok((char*)args, " "); + char* param2 = strtok(NULL, " "); + char* param3 = strtok(NULL, " "); + + int32 realmId = -1; + uint32 accountId = 0; + std::string accountName; + uint32 id = 0; + RBACCommandData* data = NULL; + rbac::RBACData* rdata = NULL; + bool useSelectedPlayer = false; + + if (checkParams) + { + if (!param3) + { + if (param2) + realmId = atoi(param2); + + if (param1) + id = atoi(param1); + + useSelectedPlayer = true; + } + else + { + id = atoi(param2); + realmId = atoi(param3); + } + + if (!id) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return NULL; + } + + if (realmId < -1 || !realmId) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_REALM, realmId); + handler->SetSentErrorMessage(true); + return NULL; + } + } + else if (!param1) + useSelectedPlayer = true; + + if (useSelectedPlayer) + { + Player* player = handler->getSelectedPlayer(); + if (!player) + return NULL; + + rdata = player->GetSession()->GetRBACData(); + accountId = rdata->GetId(); + AccountMgr::GetName(accountId, accountName); + } + else + { + accountName = param1; + + if (AccountMgr::normalizeString(accountName)) + accountId = AccountMgr::GetId(accountName); + + if (!accountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return NULL; + } + } + + if (checkParams && handler->HasLowerSecurityAccount(NULL, accountId, true)) + return NULL; + + data = new RBACCommandData(); + + if (!rdata) + { + data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID)); + data->rbac->LoadFromDB(); + data->needDelete = true; + } + else + data->rbac = rdata; + + data->id = id; + data->realmId = realmId; + return data; + } + + static bool HandleRBACPermGrantCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + rbac::RBACCommandResult result = command->rbac->GrantPermission(command->id, command->realmId); + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case rbac::RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_IN_DENIED_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED_IN_DENIED_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_GRANTED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + delete command; + + return true; + } + + static bool HandleRBACPermDenyCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + rbac::RBACCommandResult result = command->rbac->DenyPermission(command->id, command->realmId); + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case rbac::RBAC_CANT_ADD_ALREADY_ADDED: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_IN_GRANTED_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED_IN_GRANTED_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_DENIED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + delete command; + + return true; + } + + static bool HandleRBACPermRevokeCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + rbac::RBACCommandResult result = command->rbac->RevokePermission(command->id, command->realmId); + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(command->id); + + switch (result) + { + case rbac::RBAC_CANT_REVOKE_NOT_IN_LIST: + handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED_NOT_IN_LIST, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_OK: + handler->PSendSysMessage(LANG_RBAC_PERM_REVOKED, command->id, permission->GetName().c_str(), + command->realmId, command->rbac->GetId(), command->rbac->GetName().c_str()); + break; + case rbac::RBAC_ID_DOES_NOT_EXISTS: + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, command->id); + break; + default: + break; + } + + delete command; + + return true; + } + + static bool HandleRBACPermListCommand(ChatHandler* handler, char const* args) + { + RBACCommandData* command = ReadParams(handler, args, false); + + if (!command) + { + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_GRANTED, command->rbac->GetId(), command->rbac->GetName().c_str()); + rbac::RBACPermissionContainer const& granted = command->rbac->GetGrantedPermissions(); + if (granted.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (rbac::RBACPermissionContainer::const_iterator itr = granted.begin(); itr != granted.end(); ++itr) + { + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_DENIED, command->rbac->GetId(), command->rbac->GetName().c_str()); + rbac::RBACPermissionContainer const& denied = command->rbac->GetDeniedPermissions(); + if (denied.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (rbac::RBACPermissionContainer::const_iterator itr = denied.begin(); itr != denied.end(); ++itr) + { + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + handler->PSendSysMessage(LANG_RBAC_LIST_HEADER_BY_SEC_LEVEL, command->rbac->GetId(), command->rbac->GetName().c_str(), command->rbac->GetSecurityLevel()); + rbac::RBACPermissionContainer const& defaultPermissions = sAccountMgr->GetRBACDefaultPermissions(command->rbac->GetSecurityLevel()); + if (defaultPermissions.empty()) + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_EMPTY)); + else + { + for (rbac::RBACPermissionContainer::const_iterator itr = defaultPermissions.begin(); itr != defaultPermissions.end(); ++itr) + { + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(*itr); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + + delete command; + + return true; + } + + static bool HandleRBACListPermissionsCommand(ChatHandler* handler, char const* args) + { + uint32 id = 0; + if (char* param1 = strtok((char*)args, " ")) + id = atoi(param1); + + if (!id) + { + rbac::RBACPermissionsContainer const& permissions = sAccountMgr->GetRBACPermissionList(); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + for (rbac::RBACPermissionsContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it) + { + rbac::RBACPermission const* permission = it->second; + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + } + } + else + { + rbac::RBACPermission const* permission = sAccountMgr->GetRBACPermission(id); + if (!permission) + { + handler->PSendSysMessage(LANG_RBAC_WRONG_PARAMETER_ID, id); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMISSIONS_HEADER)); + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, permission->GetId(), permission->GetName().c_str()); + handler->PSendSysMessage("%s", handler->GetTrinityString(LANG_RBAC_LIST_PERMS_LINKED_HEADER)); + rbac::RBACPermissionContainer const& permissions = permission->GetLinkedPermissions(); + for (rbac::RBACPermissionContainer::const_iterator it = permissions.begin(); it != permissions.end(); ++it) + if (rbac::RBACPermission const* rbacPermission = sAccountMgr->GetRBACPermission(*it)) + handler->PSendSysMessage(LANG_RBAC_LIST_ELEMENT, rbacPermission->GetId(), rbacPermission->GetName().c_str()); + } + + return true; + } +}; + +void AddSC_rbac_commandscript() +{ + new rbac_commandscript(); +} diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 92c3f83034d..f3c59654295 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -552,11 +552,11 @@ public: YellTimer = 10000; } - uint32 NextStep(uint32 Step) + uint32 NextStep(uint32 step) { Creature* arca = ObjectAccessor::GetCreature(*me, ArcanagosGUID); Map* map = me->GetMap(); - switch (Step) + switch (step) { case 0: return 9999999; case 1: diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index 326360428d2..b37d505d766 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -152,6 +152,7 @@ public: if (id == 1) { wait_timer = 5000; + me->LoadEquipment(1); me->CastSpell(me, SPELL_DK_INITIATE_VISUAL, true); if (Player* starter = ObjectAccessor::GetPlayer(*me, playerGUID)) diff --git a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp index ecfd705cf4d..d346cc4cd1b 100644 --- a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp +++ b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp @@ -68,6 +68,7 @@ public: if (quest->GetQuestId() == QUEST_MISSING_IN_ACTION) { Talk(SAY_CORPORAL_1, player); + me->setFaction(250); npc_escortAI::Start(true, false, player->GetGUID(), quest); } } diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index ce8d0cfbcfd..f74b809c814 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -111,7 +111,6 @@ set(scripts_STAT_SRCS Kalimdor/zone_winterspring.cpp Kalimdor/zone_thousand_needles.cpp Kalimdor/zone_ashenvale.cpp - Kalimdor/zone_teldrassil.cpp Kalimdor/OnyxiasLair/boss_onyxia.cpp Kalimdor/OnyxiasLair/onyxias_lair.h Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp index 5c9a57acec7..388834d1eff 100644 --- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp @@ -465,13 +465,13 @@ public: SayTimer = 8000; } - uint32 NextStep(uint8 Step) + uint32 NextStep(uint8 step) { Creature* Spark = ObjectAccessor::GetCreature(*me, SparkGUID); if (!Spark) return 99999999; - switch (Step) + switch (step) { case 0: Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f); diff --git a/src/server/scripts/Kalimdor/zone_teldrassil.cpp b/src/server/scripts/Kalimdor/zone_teldrassil.cpp deleted file mode 100644 index 2173cd6de06..00000000000 --- a/src/server/scripts/Kalimdor/zone_teldrassil.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -SDName: Teldrassil -SD%Complete: 100 -SDComment: Quest support: 938 -SDCategory: Teldrassil -EndScriptData */ - -/* ContentData -npc_mist -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" - -/*#### -# npc_mist -####*/ - -enum Mist -{ - SAY_AT_HOME = 0, - EMOTE_AT_HOME = 1, - QUEST_MIST = 938, - NPC_ARYNIA = 3519, - FACTION_DARNASSUS = 79 -}; - -class npc_mist : public CreatureScript -{ -public: - npc_mist() : CreatureScript("npc_mist") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_MIST) - if (npc_mistAI* pMistAI = CAST_AI(npc_mist::npc_mistAI, creature->AI())) - pMistAI->StartFollow(player, FACTION_DARNASSUS, quest); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_mistAI(creature); - } - - struct npc_mistAI : public FollowerAI - { - npc_mistAI(Creature* creature) : FollowerAI(creature) { } - - void Reset() override { } - - void MoveInLineOfSight(Unit* who) override - - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_ARYNIA) - { - if (me->IsWithinDistInMap(who, 10.0f)) - { - Talk(SAY_AT_HOME, who); - DoComplete(); - } - } - } - - void DoComplete() - { - Talk(EMOTE_AT_HOME); - - Player* player = GetLeaderForFollower(); - if (player && player->GetQuestStatus(QUEST_MIST) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_MIST, me); - - //The follow is over (and for later development, run off to the woods before really end) - SetFollowComplete(); - } - - //call not needed here, no known abilities - /*void UpdateFollowerAI(const uint32 Diff) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - }*/ - }; - -}; - -void AddSC_teldrassil() -{ - new npc_mist(); -} diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 434028ab255..0b8fa7459a8 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -105,7 +105,7 @@ enum Spells SPELL_LEAVE_TWILIGHT_REALM = 74812, SPELL_TWILIGHT_PHASING = 74808, // Phase spell from phase 1 to phase 2 SPELL_SUMMON_TWILIGHT_PORTAL = 74809, // Summons go 202794 - SPELL_SUMMON_EXIT_PORTALS = 74805, // Custom spell created in spell_dbc. + SPELL_SUMMON_EXIT_PORTALS = 74805, // Custom spell created in spell_dbc. // Used in Cataclysm, need a sniff of cata and up SPELL_TWILIGHT_MENDING = 75509, SPELL_TWILIGHT_REALM = 74807, SPELL_DUSK_SHROUD = 75476, @@ -124,20 +124,20 @@ enum Events EVENT_TAIL_LASH = 6, // Twilight Halion - EVENT_SOUL_CONSUMPTION = 8, + EVENT_SOUL_CONSUMPTION = 7, // Meteor Strike - EVENT_SPAWN_METEOR_FLAME = 9, + EVENT_SPAWN_METEOR_FLAME = 8, // Halion Controller - EVENT_START_INTRO = 10, - EVENT_INTRO_PROGRESS_1 = 11, - EVENT_INTRO_PROGRESS_2 = 12, - EVENT_INTRO_PROGRESS_3 = 13, - EVENT_CHECK_CORPOREALITY = 14, - EVENT_SHADOW_PULSARS_SHOOT = 15, - EVENT_TRIGGER_BERSERK = 16, - EVENT_TWILIGHT_MENDING = 17, + EVENT_START_INTRO = 9, + EVENT_INTRO_PROGRESS_1 = 10, + EVENT_INTRO_PROGRESS_2 = 11, + EVENT_INTRO_PROGRESS_3 = 12, + EVENT_CHECK_CORPOREALITY = 13, + EVENT_SHADOW_PULSARS_SHOOT = 14, + EVENT_TRIGGER_BERSERK = 15, + EVENT_TWILIGHT_MENDING = 16 }; enum Actions @@ -150,13 +150,7 @@ enum Actions ACTION_MONITOR_CORPOREALITY = 3, // Orb Carrier - ACTION_SHOOT = 4, - - // Living Inferno - ACTION_SUMMON_LIVING_EMBERS = 5, - - // Meteor Flame - ACTION_SUMMON_FLAME = 6 + ACTION_SHOOT = 4 }; enum Phases @@ -1006,8 +1000,7 @@ class npc_meteor_strike_initial : public CreatureScript if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI())) { Position const* ownerPos = halionAI->GetMeteorStrikePosition(); - // Adjust randomness between 0 and pi. - float randomAdjustment = frand(static_cast<float>(M_PI / 14), static_cast<float>(13 * M_PI / 14)); + float randomAdjustment = frand(0.0f, static_cast<float>(M_PI / 5.0f)); float angle[4]; angle[0] = me->GetAngle(ownerPos); angle[1] = angle[0] + randomAdjustment; @@ -1088,16 +1081,12 @@ class npc_meteor_strike : public CreatureScript void UpdateAI(uint32 diff) override { _events.Update(diff); + if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME) { - Position pos = me->GetNearPosition(5.0f, 0.0f); + Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f))); if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000)) - { - flame->SetOrientation(me->GetOrientation()); - - flame->AI()->SetGUID(GetGUID()); - flame->AI()->DoAction(ACTION_SUMMON_FLAME); - } + flame->AI()->SetGUID(me->GetGUID()); } } @@ -1129,43 +1118,43 @@ class npc_meteor_strike_flame : public CreatureScript void SetGUID(ObjectGuid guid, int32 /*id = 0 */) override { _rootOwnerGuid = guid; + _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 800); } - void DoAction(int32 action) override + void IsSummonedBy(Unit* /*summoner*/) override + { + // Let Halion Controller count as summoner. + if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) + controller->AI()->JustSummoned(me); + } + + void UpdateAI(uint32 diff) override { - if (action != ACTION_SUMMON_FLAME || _rootOwnerGuid.IsEmpty()) + _events.Update(diff); + if (_events.ExecuteEvent() != EVENT_SPAWN_METEOR_FLAME) return; me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true); Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid); - if (!meteorStrike || meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5) + if (!meteorStrike) return; - me->SetOrientation(me->GetOrientation() + frand(static_cast<float>(-M_PI / 16), static_cast<float>(M_PI / 16))); - Position pos = me->GetNearPosition(5.0f, 0.0f); + meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1); + if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5) + return; + Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f))); if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000)) - { flame->AI()->SetGUID(_rootOwnerGuid); - meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1); - } - } - - void IsSummonedBy(Unit* /*summoner*/) override - { - // Let Halion Controller count as summoner. - if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) - controller->AI()->JustSummoned(me); } - void UpdateAI(uint32 /*diff*/) override { } void EnterEvadeMode() override { } private: InstanceScript* _instance; EventMap _events; - ObjectGuid _rootOwnerGuid = ObjectGuid::Empty; + ObjectGuid _rootOwnerGuid; }; CreatureAI* GetAI(Creature* creature) const override @@ -1362,7 +1351,7 @@ class go_twilight_portal : public GameObjectScript _spellId = gameobject->GetGOInfo()->goober.spellId; break; case GO_HALION_PORTAL_1: - case GO_HALION_PORTAL_2: // Not used, not seen in sniffs. Just in case. + case GO_HALION_PORTAL_2: gameobject->SetPhaseMask(0x1, true); /// Because WDB template has non-existent spell ID, not seen in sniffs either, meh _spellId = SPELL_TWILIGHT_REALM; diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index 0b829c2c6dd..620eb54ffa9 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -123,11 +123,13 @@ class boss_bronjahm : public CreatureScript void JustSummoned(Creature* summon) override { - summons.Summon(summon); - summon->SetReactState(REACT_PASSIVE); - summon->GetMotionMaster()->Clear(); - summon->GetMotionMaster()->MoveFollow(me, me->GetObjectSize(), 0.0f); - summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true); + if (summon->GetEntry() == NPC_CORRUPTED_SOUL_FRAGMENT) + { + summons.Summon(summon); + summon->SetReactState(REACT_PASSIVE); + summon->GetMotionMaster()->MoveFollow(me, me->GetObjectSize(), 0.0f); + summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true); + } } uint32 GetData(uint32 type) const override @@ -223,9 +225,15 @@ class npc_corrupted_soul_fragment : public CreatureScript instance = me->GetInstanceScript(); } + void IsSummonedBy(Unit* /*summoner*/) override + { + if (Creature* bronjahm = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRONJAHM))) + bronjahm->AI()->JustSummoned(me); + } + void MovementInform(uint32 type, uint32 id) override { - if (type != CHASE_MOTION_TYPE) + if (type != FOLLOW_MOTION_TYPE) return; if (instance->GetGuidData(DATA_BRONJAHM).GetCounter() != id) diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp index f10c108c00c..5111247b84c 100644 --- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp +++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp @@ -20,6 +20,7 @@ #include "ScriptMgr.h" #include "WorldSession.h" #include "gundrak.h" +#include "EventMap.h" DoorData const doorData[] = { diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index 705d15081c1..3ef6a7c15e3 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -221,12 +221,12 @@ public: } } - void MovementInform(uint32 type, uint32 id) override + void MovementInform(uint32 type, uint32 point) override { if (type != POINT_MOTION_TYPE) return; - if (id == 2 || id == 5 || id == 8 || id == 11) + if (point == 2 || point == 5 || point == 8 || point == 11) { movementCompleted = true; me->SetReactState(REACT_AGGRESSIVE); @@ -251,7 +251,7 @@ public: } nextMovementStarted = false; - nextWP = id + 1; + nextWP = point + 1; } // switch to "who" if nearer than current target. diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index 7a76e8b8217..dd67f2b1ac0 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -176,8 +176,6 @@ class boss_gothik : public CreatureScript } uint32 waveCount; - typedef std::vector<Creature*> TriggerVct; - TriggerVct liveTrigger, deadTrigger; bool mergedSides; bool phaseTwo; bool thirtyPercentReached; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 2228a860e0d..05bdb568a2e 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -594,8 +594,8 @@ class boss_freya : public CreatureScript const uint32 summonSpell[2][4] = { /* 0Elder, 1Elder, 2Elder, 3Elder */ - /* 10N */ {62950, 62953, 62955, 62957}, - /* 25N */ {62952, 62954, 62956, 62958} + /* 10N */ {62950, 62952, 62953, 62954}, + /* 25N */ {62955, 62956, 62957, 62958} }; me->CastSpell((Unit*)NULL, summonSpell[me->GetMap()->GetDifficulty()][elderCount], true); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 3c068915585..bd4fee60c42 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -120,7 +120,7 @@ enum Spells SPELL_SUMMON_ROCKET_STRIKE = 63036, SPELL_SCRIPT_EFFECT_ROCKET_STRIKE = 63681, // Cast by Rocket (Mimiron Visual) SPELL_ROCKET_STRIKE = 64064, // Added in creature_template_addon - SPELL_ROCKET_STRIKE_LEFT = 64402, // Cast by VX-001 + SPELL_ROCKET_STRIKE_SINGLE = 64402, // Cast by VX-001 SPELL_ROCKET_STRIKE_BOTH = 65034, // Cast by VX-001 // Flames @@ -320,6 +320,12 @@ enum Waypoints WP_AERIAL_P4_POS }; +enum SeatIds : int8 +{ + ROCKET_SEAT_LEFT = 5, + ROCKET_SEAT_RIGHT = 6 +}; + uint32 const RepairSpells[4] = { SPELL_SEAT_1, @@ -1043,18 +1049,18 @@ class boss_vx_001 : public CreatureScript events.RescheduleEvent(EVENT_RAPID_BURST, 3000, 0, PHASE_VX_001); break; case EVENT_ROCKET_STRIKE: - DoCastAOE(events.IsInPhase(PHASE_VX_001) ? SPELL_ROCKET_STRIKE_LEFT : SPELL_ROCKET_STRIKE_BOTH); + DoCastAOE(events.IsInPhase(PHASE_VX_001) ? SPELL_ROCKET_STRIKE_SINGLE : SPELL_ROCKET_STRIKE_BOTH); events.ScheduleEvent(EVENT_RELOAD, 10000); events.RescheduleEvent(EVENT_ROCKET_STRIKE, urand(20000, 25000)); break; case EVENT_RELOAD: - for (uint8 seat = 6; seat <= 7; seat++) + for (int8 seat = ROCKET_SEAT_LEFT; seat <= ROCKET_SEAT_RIGHT; ++seat) if (Unit* rocket = me->GetVehicleKit()->GetPassenger(seat)) rocket->SetDisplayId(rocket->GetNativeDisplayId()); break; case EVENT_HAND_PULSE: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 120, true)) - DoCast(target, urand(0, 1) == 0 ? SPELL_HAND_PULSE_LEFT : SPELL_HAND_PULSE_RIGHT); + DoCast(target, RAND(SPELL_HAND_PULSE_LEFT, SPELL_HAND_PULSE_RIGHT)); events.RescheduleEvent(EVENT_HAND_PULSE, urand(1500, 3000), 0, PHASE_VOL7RON); break; case EVENT_FROST_BOMB: @@ -2187,8 +2193,8 @@ class spell_mimiron_rocket_strike : public SpellScriptLoader if (targets.empty()) return; - if (m_scriptSpellId == SPELL_ROCKET_STRIKE_LEFT && GetCaster()->IsVehicle()) - if (WorldObject* target = GetCaster()->GetVehicleKit()->GetPassenger(6)) + if (m_scriptSpellId == SPELL_ROCKET_STRIKE_SINGLE && GetCaster()->IsVehicle()) + if (WorldObject* target = GetCaster()->GetVehicleKit()->GetPassenger(RAND(ROCKET_SEAT_LEFT, ROCKET_SEAT_RIGHT))) { targets.clear(); targets.push_back(target); diff --git a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp index 1f9fc6d7981..8ead8ab559e 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp @@ -113,7 +113,7 @@ public: { if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1))) pGuard1->Respawn(); - + if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2))) pGuard2->Respawn(); } @@ -254,7 +254,7 @@ public: else breakBondsCd -= diff; - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_EARTH_SHIELD: if (Unit* ally = DoSelectLowestHpFriendly(30.0f)) diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp index cfdacb10896..caf1392ea38 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp @@ -345,7 +345,7 @@ public: events.Update(diff); - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_WATER_BLAST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) @@ -367,7 +367,7 @@ public: bIsDrained = true; drainedTimer = 50; uint32 damage = me->CountPctFromMaxHealth(30); - if (me->GetHealth() < damage) + if (me->GetHealth() < damage) me->SetHealth(me->CountPctFromMaxHealth(1)); else { @@ -398,7 +398,7 @@ public: events.Update(diff); - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_WATER_BLAST: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) diff --git a/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp b/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp index 8dc0e32fb31..8b77b512ca4 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp @@ -106,7 +106,7 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_FIREBOLT: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) diff --git a/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp b/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp index f9e223d3bab..e9ee996b65b 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp @@ -27,7 +27,7 @@ enum Spells SPELL_OPTIC_LINK = 54396, SPELL_RAY_OF_PAIN = 54438, // NYI missing spelldifficulty SPELL_RAY_OF_SUFFERING = 54442, // NYI missing spelldifficulty - + // Visual SPELL_OPTIC_LINK_LEVEL_1 = 54393, SPELL_OPTIC_LINK_LEVEL_2 = 54394, @@ -108,7 +108,7 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_OPTIC_LINK: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) diff --git a/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp b/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp index 4fb7646558d..fe0f161cc27 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp @@ -63,7 +63,7 @@ enum XevozzEvents EVENT_ARCANE_BUFFET, EVENT_SUMMON_SPHERE, EVENT_SUMMON_SPHERE_2, - EVENT_RANGE_CHECK, + EVENT_RANGE_CHECK, EVENT_SUMMON_PLAYERS, EVENT_DESPAWN_SPHERE }; @@ -196,7 +196,7 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_ARCANE_BARRAGE: DoCast(SPELL_ARCANE_BARRAGE_VOLLEY); @@ -220,11 +220,14 @@ public: DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_2); break; case EVENT_SUMMON_PLAYERS: - if (Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE, 150.0f)) - sphere->GetAI()->DoAction(ACTION_SUMMON); - else if (Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE2, 150.0f)) + { + Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE, 150.0f); + if (!sphere) + sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE2, 150.0f); + if (sphere) sphere->GetAI()->DoAction(ACTION_SUMMON); break; + } default: break; } @@ -286,7 +289,7 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_RANGE_CHECK: if (Creature* xevozz = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_XEVOZZ))) diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp index 02e479a22f4..5b3f06c9e40 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp @@ -180,7 +180,7 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - switch (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { case EVENT_SUMMON_VOID: DoCast(SPELL_SUMMON_VOID_SENTRY); diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.h b/src/server/scripts/Northrend/VioletHold/violet_hold.h index e8da9576c13..2bd90672024 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.h +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.h @@ -102,7 +102,7 @@ enum CreaturesIds NPC_SABOTEOUR = 31079, NPC_VIOLET_HOLD_GUARD = 30659, NPC_DEFENSE_SYSTEM = 30837, - NPC_VOID_SENTRY = 29364, + NPC_VOID_SENTRY = 29364, NPC_VOID_SENTRY_BALL = 29365 }; diff --git a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp index 61b202fcfeb..0bc6a4f49a4 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp @@ -1,215 +1,215 @@ -/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "black_temple.h"
-#include "Player.h"
-#include "SpellInfo.h"
-
-enum Texts
-{
- SAY_AGGRO = 0,
- SAY_NEEDLE = 1,
- SAY_SLAY = 2,
- SAY_SPECIAL = 3,
- SAY_ENRAGE = 4,
- SAY_DEATH = 5
-};
-
-enum Spells
-{
- SPELL_NEEDLE_SPINE = 39992,
- SPELL_TIDAL_BURST = 39878,
- SPELL_TIDAL_SHIELD = 39872,
- SPELL_IMPALING_SPINE = 39837,
- SPELL_CREATE_NAJENTUS_SPINE = 39956,
- SPELL_HURL_SPINE = 39948,
- SPELL_BERSERK = 26662
-
-};
-
-enum Events
-{
- EVENT_BERSERK = 1,
- EVENT_YELL = 2,
- EVENT_NEEDLE = 3,
- EVENT_SPINE = 4,
- EVENT_SHIELD = 5
-};
-
-enum EventGroups
-{
- GCD_CAST = 1,
- GCD_YELL = 2
-};
-
-class boss_najentus : public CreatureScript
-{
-public:
- boss_najentus() : CreatureScript("boss_najentus") { }
-
- struct boss_najentusAI : public BossAI
- {
- boss_najentusAI(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS)
- {
- }
-
- void Reset() override
- {
- _Reset();
- SpineTargetGUID.Clear();
- }
-
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_SLAY);
- events.DelayEvents(5000, GCD_YELL);
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
-
- void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
- {
- if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD))
- {
- me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
- DoCast(me, SPELL_TIDAL_BURST, true);
- ResetTimer();
- }
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- _EnterCombat();
- Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_BERSERK, 480000, GCD_CAST);
- events.ScheduleEvent(EVENT_YELL, 45000 + (rand32() % 76) * 1000, GCD_YELL);
- ResetTimer();
- }
-
- bool RemoveImpalingSpine()
- {
- if (!SpineTargetGUID)
- return false;
-
- Unit* target = ObjectAccessor::GetUnit(*me, SpineTargetGUID);
- if (target && target->HasAura(SPELL_IMPALING_SPINE))
- target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
- SpineTargetGUID.Clear();
- return true;
- }
-
- void ResetTimer(uint32 inc = 0)
- {
- events.RescheduleEvent(EVENT_NEEDLE, 10000 + inc, GCD_CAST);
- events.RescheduleEvent(EVENT_SPINE, 20000 + inc, GCD_CAST);
- events.RescheduleEvent(EVENT_SHIELD, 60000 + inc);
- }
-
- void ExecuteEvent(uint32 eventId) override
- {
- switch (eventId)
- {
- case EVENT_SHIELD:
- DoCast(me, SPELL_TIDAL_SHIELD, true);
- ResetTimer(45000);
- break;
- case EVENT_BERSERK:
- Talk(SAY_ENRAGE);
- DoCast(me, SPELL_BERSERK, true);
- events.DelayEvents(15000, GCD_YELL);
- break;
- case EVENT_SPINE:
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
-
- if (!target)
- target = me->GetVictim();
-
- if (target)
- {
- DoCast(target, SPELL_IMPALING_SPINE, true);
- SpineTargetGUID = target->GetGUID();
- //must let target summon, otherwise you cannot click the spine
- target->SummonGameObject(GO_NAJENTUS_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation(), 0, 0, 0, 0, 30);
- Talk(SAY_NEEDLE);
- events.DelayEvents(1500, GCD_CAST);
- events.DelayEvents(15000, GCD_YELL);
- }
- events.ScheduleEvent(EVENT_SPINE, 21000, GCD_CAST);
- return;
- }
- case EVENT_NEEDLE:
- {
- //DoCast(me, SPELL_NEEDLE_SPINE, true);
- std::list<Unit*> targets;
- SelectTargetList(targets, 3, SELECT_TARGET_RANDOM, 80, true);
- for (std::list<Unit*>::const_iterator i = targets.begin(); i != targets.end(); ++i)
- DoCast(*i, 39835, true);
- events.ScheduleEvent(EVENT_NEEDLE, urand(15000, 25000), GCD_CAST);
- events.DelayEvents(1500, GCD_CAST);
- return;
- }
- case EVENT_YELL:
- Talk(SAY_SPECIAL);
- events.ScheduleEvent(EVENT_YELL, urand(25000, 100000), GCD_YELL);
- events.DelayEvents(15000, GCD_YELL);
- break;
- default:
- break;
- }
- }
-
- private:
- ObjectGuid SpineTargetGUID;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetBlackTempleAI<boss_najentusAI>(creature);
- }
-};
-
-class go_najentus_spine : public GameObjectScript
-{
-public:
- go_najentus_spine() : GameObjectScript("go_najentus_spine") { }
-
- bool OnGossipHello(Player* player, GameObject* go) override
- {
- if (InstanceScript* instance = go->GetInstanceScript())
- if (Creature* Najentus = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_HIGH_WARLORD_NAJENTUS)))
- if (ENSURE_AI(boss_najentus::boss_najentusAI, Najentus->AI())->RemoveImpalingSpine())
- {
- player->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true);
- go->Delete();
- }
- return true;
- }
-
-};
-
-void AddSC_boss_najentus()
-{
- new boss_najentus();
- new go_najentus_spine();
-}
+/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "black_temple.h" +#include "Player.h" +#include "SpellInfo.h" + +enum Texts +{ + SAY_AGGRO = 0, + SAY_NEEDLE = 1, + SAY_SLAY = 2, + SAY_SPECIAL = 3, + SAY_ENRAGE = 4, + SAY_DEATH = 5 +}; + +enum Spells +{ + SPELL_NEEDLE_SPINE = 39992, + SPELL_TIDAL_BURST = 39878, + SPELL_TIDAL_SHIELD = 39872, + SPELL_IMPALING_SPINE = 39837, + SPELL_CREATE_NAJENTUS_SPINE = 39956, + SPELL_HURL_SPINE = 39948, + SPELL_BERSERK = 26662 + +}; + +enum Events +{ + EVENT_BERSERK = 1, + EVENT_YELL = 2, + EVENT_NEEDLE = 3, + EVENT_SPINE = 4, + EVENT_SHIELD = 5 +}; + +enum EventGroups +{ + GCD_CAST = 1, + GCD_YELL = 2 +}; + +class boss_najentus : public CreatureScript +{ +public: + boss_najentus() : CreatureScript("boss_najentus") { } + + struct boss_najentusAI : public BossAI + { + boss_najentusAI(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) + { + } + + void Reset() override + { + _Reset(); + SpineTargetGUID.Clear(); + } + + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_SLAY); + events.DelayEvents(5000, GCD_YELL); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + } + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override + { + if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD)) + { + me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); + DoCast(me, SPELL_TIDAL_BURST, true); + ResetTimer(); + } + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_BERSERK, 480000, GCD_CAST); + events.ScheduleEvent(EVENT_YELL, 45000 + (rand32() % 76) * 1000, GCD_YELL); + ResetTimer(); + } + + bool RemoveImpalingSpine() + { + if (!SpineTargetGUID) + return false; + + Unit* target = ObjectAccessor::GetUnit(*me, SpineTargetGUID); + if (target && target->HasAura(SPELL_IMPALING_SPINE)) + target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); + SpineTargetGUID.Clear(); + return true; + } + + void ResetTimer(uint32 inc = 0) + { + events.RescheduleEvent(EVENT_NEEDLE, 10000 + inc, GCD_CAST); + events.RescheduleEvent(EVENT_SPINE, 20000 + inc, GCD_CAST); + events.RescheduleEvent(EVENT_SHIELD, 60000 + inc); + } + + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_SHIELD: + DoCast(me, SPELL_TIDAL_SHIELD, true); + ResetTimer(45000); + break; + case EVENT_BERSERK: + Talk(SAY_ENRAGE); + DoCast(me, SPELL_BERSERK, true); + events.DelayEvents(15000, GCD_YELL); + break; + case EVENT_SPINE: + { + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); + + if (!target) + target = me->GetVictim(); + + if (target) + { + DoCast(target, SPELL_IMPALING_SPINE, true); + SpineTargetGUID = target->GetGUID(); + //must let target summon, otherwise you cannot click the spine + target->SummonGameObject(GO_NAJENTUS_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation(), 0, 0, 0, 0, 30); + Talk(SAY_NEEDLE); + events.DelayEvents(1500, GCD_CAST); + events.DelayEvents(15000, GCD_YELL); + } + events.ScheduleEvent(EVENT_SPINE, 21000, GCD_CAST); + return; + } + case EVENT_NEEDLE: + { + //DoCast(me, SPELL_NEEDLE_SPINE, true); + std::list<Unit*> targets; + SelectTargetList(targets, 3, SELECT_TARGET_RANDOM, 80, true); + for (std::list<Unit*>::const_iterator i = targets.begin(); i != targets.end(); ++i) + DoCast(*i, 39835, true); + events.ScheduleEvent(EVENT_NEEDLE, urand(15000, 25000), GCD_CAST); + events.DelayEvents(1500, GCD_CAST); + return; + } + case EVENT_YELL: + Talk(SAY_SPECIAL); + events.ScheduleEvent(EVENT_YELL, urand(25000, 100000), GCD_YELL); + events.DelayEvents(15000, GCD_YELL); + break; + default: + break; + } + } + + private: + ObjectGuid SpineTargetGUID; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetBlackTempleAI<boss_najentusAI>(creature); + } +}; + +class go_najentus_spine : public GameObjectScript +{ +public: + go_najentus_spine() : GameObjectScript("go_najentus_spine") { } + + bool OnGossipHello(Player* player, GameObject* go) override + { + if (InstanceScript* instance = go->GetInstanceScript()) + if (Creature* Najentus = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_HIGH_WARLORD_NAJENTUS))) + if (ENSURE_AI(boss_najentus::boss_najentusAI, Najentus->AI())->RemoveImpalingSpine()) + { + player->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); + go->Delete(); + } + return true; + } + +}; + +void AddSC_boss_najentus() +{ + new boss_najentus(); + new go_najentus_spine(); +} diff --git a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp index a6c00c05dce..749f5cbf88b 100644 --- a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp @@ -364,21 +364,21 @@ class boss_vazruden_the_herald : public CreatureScript } } - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summon) override { - if (!summoned) + if (!summon) return; Unit* victim = me->GetVictim(); - if (summoned->GetEntry() == NPC_NAZAN) + if (summon->GetEntry() == NPC_NAZAN) { - summoned->SetDisableGravity(true); - summoned->SetSpeed(MOVE_FLIGHT, 2.5f); + summon->SetDisableGravity(true); + summon->SetSpeed(MOVE_FLIGHT, 2.5f); if (victim) AttackStartNoMove(victim); } else if (victim) - summoned->AI()->AttackStart(victim); + summon->AI()->AttackStart(victim); } void SentryDownBy(Unit* killer) diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index 7f2e08b39ca..9f7592a9ee4 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -127,18 +127,18 @@ class boss_warchief_kargath_bladefist : public CreatureScript Talk(SAY_AGGRO); } - void JustSummoned(Creature* summoned) override + void JustSummoned(Creature* summon) override { - switch (summoned->GetEntry()) + switch (summon->GetEntry()) { case NPC_HEARTHEN_GUARD: case NPC_SHARPSHOOTER_GUARD: case NPC_REAVER_GUARD: - summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - adds.push_back(summoned->GetGUID()); + summon->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); + adds.push_back(summon->GetGUID()); break; case NPC_SHATTERED_ASSASSIN: - assassins.push_back(summoned->GetGUID()); + assassins.push_back(summon->GetGUID()); break; } } diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index d1a31906d58..fcfa77bc2e0 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -165,7 +165,6 @@ public: void Reset() override { - ryga = NULL; } // Override Evade Mode event, recast buff that was removed by standard handler @@ -175,15 +174,6 @@ public: DoCast(me, SPELL_ANCESTRAL_WOLF_BUFF, true); } - void MoveInLineOfSight(Unit* who) override - { - if (!ryga && who->GetEntry() == NPC_RYGA && me->IsWithinDistInMap(who, 15.0f)) - if (Creature* temp = who->ToCreature()) - ryga = temp; - - npc_escortAI::MoveInLineOfSight(who); - } - void WaypointReached(uint32 waypointId) override { switch (waypointId) @@ -238,9 +228,6 @@ public: break; } } - - private: - Creature* ryga; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 75df264360f..f2871871c30 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -213,6 +213,8 @@ class spell_hun_chimera_shot : public SpellScriptLoader basePoint = (aurEff->GetAmount() + aurEff->GetBonusAmount()) * aurEff->GetDonePct(); ApplyPct(basePoint, TickCount * 40); basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); + if (Player* modOwner = caster->GetSpellModOwner()) + modOwner->ApplySpellMod(aura->GetSpellInfo()->Id, SPELLMOD_DOT, basePoint); aurEff->SetBonusAmount(caster->SpellDamageBonusDone(unitTarget, aurEff->GetSpellInfo(), 0, DOT)); } @@ -638,6 +640,45 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader } }; +// 56654, 58882 - Rapid Recuperation +class spell_hun_rapid_recuperation : public SpellScriptLoader +{ + public: + spell_hun_rapid_recuperation() : SpellScriptLoader("spell_hun_rapid_recuperation") { } + + class spell_hun_rapid_recuperation_AuraScript : public AuraScript + { + PrepareAuraScript(spell_hun_rapid_recuperation_AuraScript); + + bool Validate(SpellInfo const* spellInfo) override + { + if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell)) + return false; + return true; + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + + Unit* target = GetTarget(); + uint32 mana = CalculatePct(target->GetMaxPower(POWER_MANA), aurEff->GetAmount()); + + target->CastCustomSpell(GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, SPELLVALUE_BASE_POINT0, int32(mana), target, true, nullptr, aurEff); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_hun_rapid_recuperation_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_hun_rapid_recuperation_AuraScript(); + } +}; + // 23989 - Readiness class spell_hun_readiness : public SpellScriptLoader { @@ -919,6 +960,7 @@ void AddSC_hunter_spell_scripts() new spell_hun_misdirection_proc(); new spell_hun_pet_carrion_feeder(); new spell_hun_pet_heart_of_the_phoenix(); + new spell_hun_rapid_recuperation(); new spell_hun_readiness(); new spell_hun_scatter_shot(); new spell_hun_sniper_training(); diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 60ff67d74c0..8af97e46dee 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -2453,6 +2453,35 @@ class spell_q12414_hand_over_reins : public SpellScriptLoader } }; +// 13790 13793 13811 13814 - Among the Champions +// 13665 13745 13750 13756 13761 13767 13772 13777 13782 13787 - The Grand Melee +class spell_q13665_q13790_bested_trigger : public SpellScriptLoader +{ + public: + spell_q13665_q13790_bested_trigger() : SpellScriptLoader("spell_q13665_q13790_bested_trigger") { } + + class spell_q13665_q13790_bested_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q13665_q13790_bested_trigger_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit()->GetCharmerOrOwnerOrSelf(); + target->CastSpell(target, uint32(GetEffectValue())); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_q13665_q13790_bested_trigger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_q13665_q13790_bested_trigger_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -2512,4 +2541,5 @@ void AddSC_quest_spell_scripts() new spell_q14100_q14111_make_player_destroy_totems(); new spell_q10929_fumping(); new spell_q12414_hand_over_reins(); + new spell_q13665_q13790_bested_trigger(); } diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index dc4a4d231b1..09d64acc795 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -38,6 +38,7 @@ #include <queue> #include <sstream> #include <algorithm> +#include <memory> #include "Debugging/Errors.h" @@ -144,4 +145,14 @@ typedef std::vector<std::string> StringVector; #define MAX_QUERY_LEN 32*1024 +namespace Trinity +{ + //! std::make_unique implementation (TODO: remove this once C++14 is supported) + template<typename T, typename ...Args> + std::unique_ptr<T> make_unique(Args&& ...args) + { + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + } +} + #endif diff --git a/src/server/shared/Cryptography/WardenKeyGeneration.h b/src/server/shared/Cryptography/WardenKeyGeneration.h index 0e8a8be7e03..bfa0337d347 100644 --- a/src/server/shared/Cryptography/WardenKeyGeneration.h +++ b/src/server/shared/Cryptography/WardenKeyGeneration.h @@ -28,16 +28,16 @@ class SHA1Randx public: SHA1Randx(uint8* buff, uint32 size) { - uint32 taken = size/2; + uint32 halfSize = size / 2; sh.Initialize(); - sh.UpdateData(buff, taken); + sh.UpdateData(buff, halfSize); sh.Finalize(); memcpy(o1, sh.GetDigest(), 20); sh.Initialize(); - sh.UpdateData(buff + taken, size - taken); + sh.UpdateData(buff + halfSize, size - halfSize); sh.Finalize(); memcpy(o2, sh.GetDigest(), 20); diff --git a/src/server/shared/Database/AdhocStatement.h b/src/server/shared/Database/AdhocStatement.h index 8195d9add98..c449e0f6e59 100644 --- a/src/server/shared/Database/AdhocStatement.h +++ b/src/server/shared/Database/AdhocStatement.h @@ -32,7 +32,7 @@ class BasicStatementTask : public SQLOperation ~BasicStatementTask(); bool Execute() override; - QueryResultFuture GetFuture() { return m_result->get_future(); } + QueryResultFuture GetFuture() const { return m_result->get_future(); } private: const char* m_sql; //- Raw query to be executed diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 6bc204fbf76..f5002c6943b 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -162,7 +162,7 @@ class DatabaseWorkerPool //! This method should only be used for queries that are only executed once, e.g during startup. void Execute(const char* sql) { - if (!sql) + if (Trinity::IsFormatEmptyOrNull(sql)) return; BasicStatementTask* task = new BasicStatementTask(sql); @@ -171,13 +171,13 @@ class DatabaseWorkerPool //! Enqueues a one-way SQL operation in string format -with variable args- that will be executed asynchronously. //! This method should only be used for queries that are only executed once, e.g during startup. - template<typename... Args> - void PExecute(const char* sql, Args const&... args) + template<typename Format, typename... Args> + void PExecute(Format&& sql, Args&&... args) { - if (!sql) + if (Trinity::IsFormatEmptyOrNull(sql)) return; - Execute(Trinity::StringFormat(sql, args...).c_str()); + Execute(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); } //! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously. @@ -206,13 +206,13 @@ class DatabaseWorkerPool //! Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished. //! This method should only be used for queries that are only executed once, e.g during startup. - template<typename... Args> - void DirectPExecute(const char* sql, Args const&... args) + template<typename Format, typename... Args> + void DirectPExecute(Format&& sql, Args&&... args) { - if (!sql) + if (Trinity::IsFormatEmptyOrNull(sql)) return; - DirectExecute(Trinity::StringFormat(sql, args...).c_str()); + DirectExecute(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); } //! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished. @@ -233,7 +233,7 @@ class DatabaseWorkerPool //! Directly executes an SQL query in string format that will block the calling thread until finished. //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - QueryResult Query(const char* sql, T* conn = NULL) + QueryResult Query(const char* sql, T* conn = nullptr) { if (!conn) conn = GetFreeConnection(); @@ -251,24 +251,24 @@ class DatabaseWorkerPool //! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished. //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - template<typename... Args> - QueryResult PQuery(const char* sql, T* conn, Args const&... args) + template<typename Format, typename... Args> + QueryResult PQuery(Format&& sql, T* conn, Args&&... args) { - if (!sql) - return QueryResult(NULL); + if (Trinity::IsFormatEmptyOrNull(sql)) + return QueryResult(nullptr); - return Query(Trinity::StringFormat(sql, args...).c_str(), conn); + return Query(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str(), conn); } //! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished. //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - template<typename... Args> - QueryResult PQuery(const char* sql, Args const&... args) + template<typename Format, typename... Args> + QueryResult PQuery(Format&& sql, Args&&... args) { if (!sql) - return QueryResult(NULL); + return QueryResult(nullptr); - return Query(Trinity::StringFormat(sql, args...).c_str()); + return Query(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); } //! Directly executes an SQL query in prepared format that will block the calling thread until finished. @@ -309,10 +309,10 @@ class DatabaseWorkerPool //! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed. //! The return value is then processed in ProcessQueryCallback methods. - template<typename... Args> - QueryResultFuture AsyncPQuery(const char* sql, Args const&... args) + template<typename Format, typename... Args> + QueryResultFuture AsyncPQuery(Format&& sql, Args&&... args) { - return AsyncQuery(Trinity::StringFormat(sql, args...).c_str()); + return AsyncQuery(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); } //! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed. @@ -503,7 +503,7 @@ class DatabaseWorkerPool { while (_connectionCount[type] != 0) { - T* t = _connections[type][i--]; + t = _connections[type][i--]; delete t; --_connectionCount[type]; } diff --git a/src/server/shared/Database/QueryHolder.h b/src/server/shared/Database/QueryHolder.h index 4102bba1223..b64da948a16 100644 --- a/src/server/shared/Database/QueryHolder.h +++ b/src/server/shared/Database/QueryHolder.h @@ -30,8 +30,11 @@ class SQLQueryHolder SQLQueryHolder() { } ~SQLQueryHolder(); bool SetQuery(size_t index, const char* sql); - template<typename... Args> - bool SetPQuery(size_t index, const char* sql, Args const&... args) { return SetQuery(index, Trinity::StringFormat(sql, args...).c_str()); } + template<typename Format, typename... Args> + bool SetPQuery(size_t index, Format&& sql, Args&&... args) + { + return SetQuery(index, Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); + } bool SetPreparedQuery(size_t index, PreparedStatement* stmt); void SetSize(size_t size); QueryResult GetResult(size_t index); diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h index a51c96ea93b..4fbbe1ed45b 100644 --- a/src/server/shared/Database/Transaction.h +++ b/src/server/shared/Database/Transaction.h @@ -39,8 +39,11 @@ class Transaction void Append(PreparedStatement* statement); void Append(const char* sql); - template<typename... Args> - void PAppend(const char* sql, Args const&... args) { Append(Trinity::StringFormat(sql, args...).c_str()); } + template<typename Format, typename... Args> + void PAppend(Format&& sql, Args&&... args) + { + Append(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); + } size_t GetSize() const { return m_queries.size(); } diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp index e9f888f280d..02916ca12d2 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp @@ -1008,9 +1008,9 @@ bool logChildren) // Get the size of the child member ULONG64 length; SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length); - char buffer[50]; - FormatOutputValue(buffer, basicType, length, (PVOID)address, sizeof(buffer)); - symbolDetails.top().Value = buffer; + char buffer2[50]; + FormatOutputValue(buffer2, basicType, length, (PVOID)address, sizeof(buffer)); + symbolDetails.top().Value = buffer2; } bHandled = true; return pszCurrBuffer; @@ -1233,16 +1233,16 @@ size_t countOverride) else length = strlen((char*)pAddress); if (length > bufferSize - 6) - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", bufferSize - 6, (char*)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), (char*)pAddress); else - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", length, (char*)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", (DWORD)length, (char*)pAddress); break; } case btStdString: { std::string* value = static_cast<std::string*>(pAddress); if (value->length() > bufferSize - 6) - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", bufferSize - 6, value->c_str()); + pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), value->c_str()); else pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", value->c_str()); break; @@ -1264,7 +1264,7 @@ size_t countOverride) { if (basicType == btFloat) { - pszCurrBuffer += sprintf(pszCurrBuffer, "%lf", + pszCurrBuffer += sprintf(pszCurrBuffer, "%f", *(double *)pAddress); } else @@ -1274,9 +1274,9 @@ size_t countOverride) else { #if _WIN64 - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X", (DWORD64*)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X", (DWORD64)pAddress); #else - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", (PDWORD)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", (DWORD)pAddress); #endif } break; @@ -1285,9 +1285,9 @@ size_t countOverride) __except (EXCEPTION_EXECUTE_HANDLER) { #if _WIN64 - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X <Unable to read memory>", (DWORD64*)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X <Unable to read memory>", (DWORD64)pAddress); #else - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X <Unable to read memory>", (PDWORD)pAddress); + pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X <Unable to read memory>", (DWORD)pAddress); #endif } } diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h index ef6334add16..8c2479d5232 100644 --- a/src/server/shared/Debugging/WheatyExceptionReport.h +++ b/src/server/shared/Debugging/WheatyExceptionReport.h @@ -7,6 +7,7 @@ #include <set> #include <stdlib.h> #include <stack> +#include <mutex> #define countof _countof #define WER_MAX_ARRAY_ELEMENTS_COUNT 10 diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 5a8d610a36b..c9cc1935c7a 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -22,20 +22,19 @@ # include <Windows.h> #endif -AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* _filename, const char* _logDir, const char* _mode, AppenderFlags _flags, uint64 fileSize): - Appender(id, name, APPENDER_FILE, level, _flags), +AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags, uint64 fileSize): + Appender(id, name, APPENDER_FILE, level, flags), logfile(NULL), - filename(_filename), - logDir(_logDir), - mode(_mode), - maxFileSize(fileSize), - fileSize(0) + _fileName(filename), + _logDir(logDir), + _maxFileSize(fileSize), + _fileSize(0) { - dynamicName = std::string::npos != filename.find("%s"); - backup = (_flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0; + _dynamicName = std::string::npos != _fileName.find("%s"); + _backup = (flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0; - if (!dynamicName) - logfile = OpenFile(_filename, _mode, mode == "w" && backup); + if (!_dynamicName) + logfile = OpenFile(filename, mode, !strcmp(mode, "w") && _backup); } AppenderFile::~AppenderFile() @@ -45,36 +44,36 @@ AppenderFile::~AppenderFile() void AppenderFile::_write(LogMessage const* message) { - bool exceedMaxSize = maxFileSize > 0 && (fileSize.load() + message->Size()) > maxFileSize; + bool exceedMaxSize = _maxFileSize > 0 && (_fileSize.load() + message->Size()) > _maxFileSize; - if (dynamicName) + if (_dynamicName) { char namebuf[TRINITY_PATH_MAX]; - snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message->param1.c_str()); + snprintf(namebuf, TRINITY_PATH_MAX, _fileName.c_str(), message->param1.c_str()); // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call - FILE* file = OpenFile(namebuf, "a", backup || exceedMaxSize); + FILE* file = OpenFile(namebuf, "a", _backup || exceedMaxSize); if (!file) return; fprintf(file, "%s%s\n", message->prefix.c_str(), message->text.c_str()); fflush(file); - fileSize += uint64(message->Size()); + _fileSize += uint64(message->Size()); fclose(file); return; } else if (exceedMaxSize) - logfile = OpenFile(filename, "w", true); + logfile = OpenFile(_fileName, "w", true); if (!logfile) return; fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str()); fflush(logfile); - fileSize += uint64(message->Size()); + _fileSize += uint64(message->Size()); } -FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mode, bool backup) +FILE* AppenderFile::OpenFile(std::string const& filename, std::string const& mode, bool backup) { - std::string fullName(logDir + filename); + std::string fullName(_logDir + filename); if (backup) { CloseFile(); @@ -87,7 +86,7 @@ FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mod if (FILE* ret = fopen(fullName.c_str(), mode.c_str())) { - fileSize = ftell(ret); + _fileSize = ftell(ret); return ret; } diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index 36afdd23ad1..4082b34a2b4 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -24,21 +24,20 @@ class AppenderFile: public Appender { public: - AppenderFile(uint8 _id, std::string const& _name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags, uint64 maxSize); + AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags, uint64 maxSize); ~AppenderFile(); - FILE* OpenFile(std::string const& _name, std::string const& _mode, bool _backup); + FILE* OpenFile(std::string const& name, std::string const& mode, bool backup); private: void CloseFile(); void _write(LogMessage const* message) override; FILE* logfile; - std::string filename; - std::string logDir; - std::string mode; - bool dynamicName; - bool backup; - uint64 maxFileSize; - std::atomic<uint64> fileSize; + std::string _fileName; + std::string _logDir; + bool _dynamicName; + bool _backup; + uint64 _maxFileSize; + std::atomic<uint64> _fileSize; }; #endif diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index a2150733c6b..6c2580b3168 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -269,7 +269,7 @@ void Log::write(std::unique_ptr<LogMessage>&& msg) const if (_ioService) { - auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::forward<std::unique_ptr<LogMessage>>(msg))); + auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::move(msg))); _ioService->post(_strand->wrap([logOperation](){ logOperation->call(); })); } @@ -290,9 +290,8 @@ std::string Log::GetTimestampStr() // HH hour (2 digits 00-23) // MM minutes (2 digits 00-59) // SS seconds (2 digits 00-59) - char buf[20]; - snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec); - return std::string(buf); + return Trinity::StringFormat("%04d-%02d-%02d_%02d-%02d-%02d", + aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec); } bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLogger /* = true */) diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index e22a06e635e..ab7b2169ed2 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -23,6 +23,7 @@ #include "Appender.h" #include "Logger.h" #include "StringFormat.h" +#include "Common.h" #include <boost/asio/io_service.hpp> #include <boost/asio/strand.hpp> @@ -61,19 +62,22 @@ class Log bool ShouldLog(std::string const& type, LogLevel level) const; bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true); - template<typename... Args> - inline void outMessage(std::string const& filter, LogLevel const level, const char* fmt, Args const&... args) + template<typename Format, typename... Args> + inline void outMessage(std::string const& filter, LogLevel const level, Format&& fmt, Args&&... args) { - write(std::unique_ptr<LogMessage>(new LogMessage(level, filter, Trinity::StringFormat(fmt, args...)))); + write(Trinity::make_unique<LogMessage>(level, filter, + Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...))); } - template<typename... Args> - void outCommand(uint32 account, const char* fmt, Args const&... args) + template<typename Format, typename... Args> + void outCommand(uint32 account, Format&& fmt, Args&&... args) { if (!ShouldLog("commands.gm", LOG_LEVEL_INFO)) return; - std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...)))); + std::unique_ptr<LogMessage> msg = + Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm", + Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...)); msg->param1 = std::to_string(account); @@ -159,7 +163,8 @@ inline bool Log::ShouldLog(std::string const& type, LogLevel level) const } #if PLATFORM != PLATFORM_WINDOWS -void check_args(const char* format, ...) ATTR_PRINTF(1, 2); +void check_args(const char*, ...) ATTR_PRINTF(1, 2); +void check_args(std::string const&, ...); // This will catch format errors on build time #define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \ diff --git a/src/server/shared/PrecompiledHeaders/sharedPCH.h b/src/server/shared/PrecompiledHeaders/sharedPCH.h index 87af9f44eb7..d99476bc7a8 100644 --- a/src/server/shared/PrecompiledHeaders/sharedPCH.h +++ b/src/server/shared/PrecompiledHeaders/sharedPCH.h @@ -7,3 +7,4 @@ #include "Errors.h" #include "TypeList.h" #include "TaskScheduler.h" +#include "EventMap.h" diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h index e2f13e5c339..96546960393 100644 --- a/src/server/shared/Threading/ProducerConsumerQueue.h +++ b/src/server/shared/Threading/ProducerConsumerQueue.h @@ -70,7 +70,8 @@ public: { std::unique_lock<std::mutex> lock(_queueLock); - // we could be using .wait(lock, predicate) overload here but some threading error analysis tools produce false positives + // we could be using .wait(lock, predicate) overload here but it is broken + // https://connect.microsoft.com/VisualStudio/feedback/details/1098841 while (_queue.empty() && !_shutdown) _condition.wait(lock); diff --git a/src/server/shared/Utilities/Duration.h b/src/server/shared/Utilities/Duration.h new file mode 100644 index 00000000000..58a08e5842f --- /dev/null +++ b/src/server/shared/Utilities/Duration.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _DURATION_H_ +#define _DURATION_H_ + +#include <chrono> + +/// Milliseconds shorthand typedef. +typedef std::chrono::milliseconds Milliseconds; + +/// Seconds shorthand typedef. +typedef std::chrono::seconds Seconds; + +/// Minutes shorthand typedef. +typedef std::chrono::minutes Minutes; + +/// Hours shorthand typedef. +typedef std::chrono::hours Hours; + +/// Makes std::chrono_literals globally available. +// ToDo: Enable this when TC supports C++14. +// using namespace std::chrono_literals; + +#endif // _DURATION_H_ diff --git a/src/server/shared/Utilities/EventMap.cpp b/src/server/shared/Utilities/EventMap.cpp new file mode 100644 index 00000000000..8c3f60afe82 --- /dev/null +++ b/src/server/shared/Utilities/EventMap.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "EventMap.h" + +void EventMap::Reset() +{ + _eventMap.clear(); + _time = 0; + _phase = 0; +} + +void EventMap::SetPhase(uint8 phase) +{ + if (!phase) + _phase = 0; + else if (phase <= 8) + _phase = uint8(1 << (phase - 1)); +} + +void EventMap::ScheduleEvent(uint32 eventId, uint32 time, uint32 group /*= 0*/, uint8 phase /*= 0*/) +{ + if (group && group <= 8) + eventId |= (1 << (group + 15)); + + if (phase && phase <= 8) + eventId |= (1 << (phase + 23)); + + _eventMap.insert(EventStore::value_type(_time + time, eventId)); +} + +uint32 EventMap::ExecuteEvent() +{ + while (!Empty()) + { + EventStore::iterator itr = _eventMap.begin(); + + if (itr->first > _time) + return 0; + else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) + _eventMap.erase(itr); + else + { + uint32 eventId = (itr->second & 0x0000FFFF); + _lastEvent = itr->second; // include phase/group + _eventMap.erase(itr); + return eventId; + } + } + + return 0; +} + +void EventMap::DelayEvents(uint32 delay, uint32 group) +{ + if (!group || group > 8 || Empty()) + return; + + EventStore delayed; + + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + { + if (itr->second & (1 << (group + 15))) + { + delayed.insert(EventStore::value_type(itr->first + delay, itr->second)); + _eventMap.erase(itr++); + } + else + ++itr; + } + + _eventMap.insert(delayed.begin(), delayed.end()); +} + +void EventMap::CancelEvent(uint32 eventId) +{ + if (Empty()) + return; + + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + { + if (eventId == (itr->second & 0x0000FFFF)) + _eventMap.erase(itr++); + else + ++itr; + } +} + +void EventMap::CancelEventGroup(uint32 group) +{ + if (!group || group > 8 || Empty()) + return; + + for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) + { + if (itr->second & (1 << (group + 15))) + _eventMap.erase(itr++); + else + ++itr; + } +} + +uint32 EventMap::GetNextEventTime(uint32 eventId) const +{ + if (Empty()) + return 0; + + for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) + if (eventId == (itr->second & 0x0000FFFF)) + return itr->first; + + return 0; +} + +uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const +{ + for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) + if (eventId == (itr->second & 0x0000FFFF)) + return itr->first - _time; + + return std::numeric_limits<uint32>::max(); +} diff --git a/src/server/shared/Utilities/EventMap.h b/src/server/shared/Utilities/EventMap.h new file mode 100644 index 00000000000..021dffc4940 --- /dev/null +++ b/src/server/shared/Utilities/EventMap.h @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _EVENT_MAP_H_ +#define _EVENT_MAP_H_ + +#include "Common.h" +#include "Duration.h" +#include "Util.h" + +class EventMap +{ + /** + * Internal storage type. + * Key: Time as uint32 when the event should occur. + * Value: The event data as uint32. + * + * Structure of event data: + * - Bit 0 - 15: Event Id. + * - Bit 16 - 23: Group + * - Bit 24 - 31: Phase + * - Pattern: 0xPPGGEEEE + */ + typedef std::multimap<uint32, uint32> EventStore; + +public: + EventMap() : _time(0), _phase(0), _lastEvent(0) { } + + /** + * @name Reset + * @brief Removes all scheduled events and resets time and phase. + */ + void Reset(); + + /** + * @name Update + * @brief Updates the timer of the event map. + * @param time Value in ms to be added to time. + */ + void Update(uint32 time) + { + _time += time; + } + + /** + * @name GetTimer + * @return Current timer in ms value. + */ + uint32 GetTimer() const + { + return _time; + } + + /** + * @name GetPhaseMask + * @return Active phases as mask. + */ + uint8 GetPhaseMask() const + { + return _phase; + } + + /** + * @name Empty + * @return True, if there are no events scheduled. + */ + bool Empty() const + { + return _eventMap.empty(); + } + + /** + * @name SetPhase + * @brief Sets the phase of the map (absolute). + * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase. + */ + void SetPhase(uint8 phase); + + /** + * @name AddPhase + * @brief Activates the given phase (bitwise). + * @param phase Phase which should be activated. Values: 1 - 8 + */ + void AddPhase(uint8 phase) + { + if (phase && phase <= 8) + _phase |= uint8(1 << (phase - 1)); + } + + /** + * @name RemovePhase + * @brief Deactivates the given phase (bitwise). + * @param phase Phase which should be deactivated. Values: 1 - 8. + */ + void RemovePhase(uint8 phase) + { + if (phase && phase <= 8) + _phase &= uint8(~(1 << (phase - 1))); + } + + /** + * @name ScheduleEvent + * @brief Creates new event entry in map. + * @param eventId The id of the new event. + * @param time The time in milliseconds as std::chrono::duration until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void ScheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0) + { + ScheduleEvent(eventId, time.count(), group, phase); + } + + /** + * @name ScheduleEvent + * @brief Creates new event entry in map. + * @param eventId The id of the new event. + * @param time The time in milliseconds until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0); + + /** + * @name RescheduleEvent + * @brief Cancels the given event and reschedules it. + * @param eventId The id of the event. + * @param time The time in milliseconds as std::chrono::duration until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void RescheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0) + { + RescheduleEvent(eventId, time.count(), group, phase); + } + + /** + * @name RescheduleEvent + * @brief Cancels the given event and reschedules it. + * @param eventId The id of the event. + * @param time The time in milliseconds until the event occurs. + * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. + * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. + */ + void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) + { + CancelEvent(eventId); + ScheduleEvent(eventId, time, group, phase); + } + + /** + * @name RepeatEvent + * @brief Repeats the mostly recently executed event. + * @param time Time until in milliseconds as std::chrono::duration the event occurs. + */ + void Repeat(Milliseconds const& time) + { + Repeat(time.count()); + } + + /** + * @name RepeatEvent + * @brief Repeats the mostly recently executed event. + * @param time Time until the event occurs. + */ + void Repeat(uint32 time) + { + _eventMap.insert(EventStore::value_type(_time + time, _lastEvent)); + } + + /** + * @name RepeatEvent + * @brief Repeats the mostly recently executed event. + * @param minTime Minimum time as std::chrono::duration until the event occurs. + * @param maxTime Maximum time as std::chrono::duration until the event occurs. + */ + void Repeat(Milliseconds const& minTime, Milliseconds const& maxTime) + { + Repeat(minTime.count(), maxTime.count()); + } + + /** + * @name RepeatEvent + * @brief Repeats the mostly recently executed event, Equivalent to Repeat(urand(minTime, maxTime). + * @param minTime Minimum time until the event occurs. + * @param maxTime Maximum time until the event occurs. + */ + void Repeat(uint32 minTime, uint32 maxTime) + { + Repeat(urand(minTime, maxTime)); + } + + /** + * @name ExecuteEvent + * @brief Returns the next event to execute and removes it from map. + * @return Id of the event to execute. + */ + uint32 ExecuteEvent(); + + /** + * @name DelayEvents + * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. + * @param delay Amount of delay in ms as std::chrono::duration. + */ + void DelayEvents(Milliseconds const& delay) + { + DelayEvents(delay.count()); + } + + /** + * @name DelayEvents + * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. + * @param delay Amount of delay. + */ + void DelayEvents(uint32 delay) + { + _time = delay < _time ? _time - delay : 0; + } + + /** + * @name DelayEvents + * @brief Delay all events of the same group. + * @param delay Amount of delay in ms as std::chrono::duration. + * @param group Group of the events. + */ + void DelayEvents(Milliseconds const& delay, uint32 group) + { + DelayEvents(delay.count(), group); + } + + /** + * @name DelayEvents + * @brief Delay all events of the same group. + * @param delay Amount of delay. + * @param group Group of the events. + */ + void DelayEvents(uint32 delay, uint32 group); + + /** + * @name CancelEvent + * @brief Cancels all events of the specified id. + * @param eventId Event id to cancel. + */ + void CancelEvent(uint32 eventId); + + /** + * @name CancelEventGroup + * @brief Cancel events belonging to specified group. + * @param group Group to cancel. + */ + void CancelEventGroup(uint32 group); + + /** + * @name GetNextEventTime + * @brief Returns closest occurence of specified event. + * @param eventId Wanted event id. + * @return Time of found event. + */ + uint32 GetNextEventTime(uint32 eventId) const; + + /** + * @name GetNextEventTime + * @return Time of next event. + */ + uint32 GetNextEventTime() const + { + return Empty() ? 0 : _eventMap.begin()->first; + } + + /** + * @name IsInPhase + * @brief Returns whether event map is in specified phase or not. + * @param phase Wanted phase. + * @return True, if phase of event map contains specified phase. + */ + bool IsInPhase(uint8 phase) const + { + return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); + } + + /** + * @name GetTimeUntilEvent + * @brief Returns time in milliseconds until next event. + * @param eventId of the event. + * @return Time of next event. + */ + uint32 GetTimeUntilEvent(uint32 eventId) const; + +private: + /** + * @name _time + * @brief Internal timer. + * + * This does not represent the real date/time value. + * It's more like a stopwatch: It can run, it can be stopped, + * it can be resetted and so on. Events occur when this timer + * has reached their time value. Its value is changed in the + * Update method. + */ + uint32 _time; + + /** + * @name _phase + * @brief Phase mask of the event map. + * + * Contains the phases the event map is in. Multiple + * phases from 1 to 8 can be set with SetPhase or + * AddPhase. RemovePhase deactives a phase. + */ + uint8 _phase; + + /** + * @name _eventMap + * @brief Internal event storage map. Contains the scheduled events. + * + * See typedef at the beginning of the class for more + * details. + */ + EventStore _eventMap; + + /** + * @name _lastEvent + * @brief Stores information on the most recently executed event + */ + uint32 _lastEvent; +}; + +#endif // _EVENT_MAP_H_ diff --git a/src/server/shared/Utilities/StringFormat.h b/src/server/shared/Utilities/StringFormat.h index 70d9aefb14d..67e0100e7c8 100644 --- a/src/server/shared/Utilities/StringFormat.h +++ b/src/server/shared/Utilities/StringFormat.h @@ -19,15 +19,27 @@ #ifndef TRINITYCORE_STRING_FORMAT_H #define TRINITYCORE_STRING_FORMAT_H -#include <format.h> +#include "format.h" namespace Trinity { - //! Default TC string format function - template<typename... Args> - inline std::string StringFormat(const char* fmt, Args const&... args) + /// Default TC string format function. + template<typename Format, typename... Args> + inline std::string StringFormat(Format&& fmt, Args&&... args) { - return fmt::sprintf(fmt, args...); + return fmt::sprintf(std::forward<Format>(fmt), std::forward<Args>(args)...); + } + + /// Returns true if the given char pointer is null. + inline bool IsFormatEmptyOrNull(const char* fmt) + { + return fmt == nullptr; + } + + /// Returns true if the given std::string is empty. + inline bool IsFormatEmptyOrNull(std::string const& fmt) + { + return fmt.empty(); } } diff --git a/src/server/shared/Utilities/TaskScheduler.h b/src/server/shared/Utilities/TaskScheduler.h index d45835b5f17..f1fe7ea0a21 100644 --- a/src/server/shared/Utilities/TaskScheduler.h +++ b/src/server/shared/Utilities/TaskScheduler.h @@ -29,6 +29,7 @@ #include <boost/optional.hpp> #include "Util.h" +#include "Duration.h" class TaskContext; @@ -646,16 +647,4 @@ private: void Invoke(); }; -/// Milliseconds shorthand typedef. -typedef std::chrono::milliseconds Milliseconds; - -/// Seconds shorthand typedef. -typedef std::chrono::seconds Seconds; - -/// Minutes shorthand typedef. -typedef std::chrono::minutes Minutes; - -/// Hours shorthand typedef. -typedef std::chrono::hours Hours; - #endif /// _TASK_SCHEDULER_H_ diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h index b7d2fa1b5ad..c54903d7be2 100644 --- a/src/server/shared/Utilities/Timer.h +++ b/src/server/shared/Utilities/Timer.h @@ -21,10 +21,10 @@ #include <chrono> -using namespace std::chrono; - inline uint32 getMSTime() { + using namespace std::chrono; + static const system_clock::time_point ApplicationStartTime = system_clock::now(); return uint32(duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count()); diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index c4e47a6ee07..33c273fb05f 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -560,12 +560,3 @@ std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse return ss.str(); } - -uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const -{ - for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) - if (eventId == (itr->second & 0x0000FFFF)) - return itr->first - _time; - - return std::numeric_limits<uint32>::max(); -} diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index cd523511c1d..3da1c800410 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -542,346 +542,4 @@ bool CompareValues(ComparisionType type, T val1, T val2) } } -class EventMap -{ - /** - * Internal storage type. - * Key: Time as uint32 when the event should occur. - * Value: The event data as uint32. - * - * Structure of event data: - * - Bit 0 - 15: Event Id. - * - Bit 16 - 23: Group - * - Bit 24 - 31: Phase - * - Pattern: 0xPPGGEEEE - */ - typedef std::multimap<uint32, uint32> EventStore; - - public: - EventMap() : _time(0), _phase(0), _lastEvent(0) { } - - /** - * @name Reset - * @brief Removes all scheduled events and resets time and phase. - */ - void Reset() - { - _eventMap.clear(); - _time = 0; - _phase = 0; - } - - /** - * @name Update - * @brief Updates the timer of the event map. - * @param time Value to be added to time. - */ - void Update(uint32 time) - { - _time += time; - } - - /** - * @name GetTimer - * @return Current timer value. - */ - uint32 GetTimer() const - { - return _time; - } - - /** - * @name GetPhaseMask - * @return Active phases as mask. - */ - uint8 GetPhaseMask() const - { - return _phase; - } - - /** - * @name Empty - * @return True, if there are no events scheduled. - */ - bool Empty() const - { - return _eventMap.empty(); - } - - /** - * @name SetPhase - * @brief Sets the phase of the map (absolute). - * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase. - */ - void SetPhase(uint8 phase) - { - if (!phase) - _phase = 0; - else if (phase <= 8) - _phase = uint8(1 << (phase - 1)); - } - - /** - * @name AddPhase - * @brief Activates the given phase (bitwise). - * @param phase Phase which should be activated. Values: 1 - 8 - */ - void AddPhase(uint8 phase) - { - if (phase && phase <= 8) - _phase |= uint8(1 << (phase - 1)); - } - - /** - * @name RemovePhase - * @brief Deactivates the given phase (bitwise). - * @param phase Phase which should be deactivated. Values: 1 - 8. - */ - void RemovePhase(uint8 phase) - { - if (phase && phase <= 8) - _phase &= uint8(~(1 << (phase - 1))); - } - - /** - * @name ScheduleEvent - * @brief Creates new event entry in map. - * @param eventId The id of the new event. - * @param time The time in milliseconds until the event occurs. - * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. - * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. - */ - void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) - { - if (group && group <= 8) - eventId |= (1 << (group + 15)); - - if (phase && phase <= 8) - eventId |= (1 << (phase + 23)); - - _eventMap.insert(EventStore::value_type(_time + time, eventId)); - } - - /** - * @name RescheduleEvent - * @brief Cancels the given event and reschedules it. - * @param eventId The id of the event. - * @param time The time in milliseconds until the event occurs. - * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. - * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. - */ - void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) - { - CancelEvent(eventId); - ScheduleEvent(eventId, time, group, phase); - } - - /** - * @name RepeatEvent - * @brief Repeats the mostly recently executed event. - * @param time Time until the event occurs. - */ - void Repeat(uint32 time) - { - _eventMap.insert(EventStore::value_type(_time + time, _lastEvent)); - } - - /** - * @name RepeatEvent - * @brief Repeats the mostly recently executed event, Equivalent to Repeat(urand(minTime, maxTime). - * @param minTime Minimum time until the event occurs. - * @param maxTime Maximum time until the event occurs. - */ - void Repeat(uint32 minTime, uint32 maxTime) - { - Repeat(urand(minTime, maxTime)); - } - - /** - * @name ExecuteEvent - * @brief Returns the next event to execute and removes it from map. - * @return Id of the event to execute. - */ - uint32 ExecuteEvent() - { - while (!Empty()) - { - EventStore::iterator itr = _eventMap.begin(); - - if (itr->first > _time) - return 0; - else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) - _eventMap.erase(itr); - else - { - uint32 eventId = (itr->second & 0x0000FFFF); - _lastEvent = itr->second; // include phase/group - _eventMap.erase(itr); - return eventId; - } - } - - return 0; - } - - /** - * @name DelayEvents - * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. - * @param delay Amount of delay. - */ - void DelayEvents(uint32 delay) - { - _time = delay < _time ? _time - delay : 0; - } - - /** - * @name DelayEvents - * @brief Delay all events of the same group. - * @param delay Amount of delay. - * @param group Group of the events. - */ - void DelayEvents(uint32 delay, uint32 group) - { - if (!group || group > 8 || Empty()) - return; - - EventStore delayed; - - for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) - { - if (itr->second & (1 << (group + 15))) - { - delayed.insert(EventStore::value_type(itr->first + delay, itr->second)); - _eventMap.erase(itr++); - } - else - ++itr; - } - - _eventMap.insert(delayed.begin(), delayed.end()); - } - - /** - * @name CancelEvent - * @brief Cancels all events of the specified id. - * @param eventId Event id to cancel. - */ - void CancelEvent(uint32 eventId) - { - if (Empty()) - return; - - for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) - { - if (eventId == (itr->second & 0x0000FFFF)) - _eventMap.erase(itr++); - else - ++itr; - } - } - - /** - * @name CancelEventGroup - * @brief Cancel events belonging to specified group. - * @param group Group to cancel. - */ - void CancelEventGroup(uint32 group) - { - if (!group || group > 8 || Empty()) - return; - - for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) - { - if (itr->second & (1 << (group + 15))) - _eventMap.erase(itr++); - else - ++itr; - } - } - - /** - * @name GetNextEventTime - * @brief Returns closest occurence of specified event. - * @param eventId Wanted event id. - * @return Time of found event. - */ - uint32 GetNextEventTime(uint32 eventId) const - { - if (Empty()) - return 0; - - for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) - if (eventId == (itr->second & 0x0000FFFF)) - return itr->first; - - return 0; - } - - /** - * @name GetNextEventTime - * @return Time of next event. - */ - uint32 GetNextEventTime() const - { - return Empty() ? 0 : _eventMap.begin()->first; - } - - /** - * @name IsInPhase - * @brief Returns wether event map is in specified phase or not. - * @param phase Wanted phase. - * @return True, if phase of event map contains specified phase. - */ - bool IsInPhase(uint8 phase) - { - return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); - } - - /** - * @name GetTimeUntilEvent - * @brief Returns time in milliseconds until next event. - * @param eventId of the event. - * @return Time of next event. - */ - uint32 GetTimeUntilEvent(uint32 eventId) const; - - private: - /** - * @name _time - * @brief Internal timer. - * - * This does not represent the real date/time value. - * It's more like a stopwatch: It can run, it can be stopped, - * it can be resetted and so on. Events occur when this timer - * has reached their time value. Its value is changed in the - * Update method. - */ - uint32 _time; - - /** - * @name _phase - * @brief Phase mask of the event map. - * - * Contains the phases the event map is in. Multiple - * phases from 1 to 8 can be set with SetPhase or - * AddPhase. RemovePhase deactives a phase. - */ - uint8 _phase; - - /** - * @name _eventMap - * @brief Internal event storage map. Contains the scheduled events. - * - * See typedef at the beginning of the class for more - * details. - */ - EventStore _eventMap; - - /** - * @name _lastEvent - * @brief Stores information on the most recently executed event - */ - uint32 _lastEvent; -}; - #endif diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 447ef9a45a8..8e06c1c9ca4 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2265,7 +2265,7 @@ Battleground.RewardLoserHonorLast = 5 # Wintergrasp.Enable # Description: Enable the Wintergrasp battlefield. # Default: 0 - (Disabled) -# 1 - (Enabled, Experimental as of still being in development) +# 1 - (Enabled, Experimental as in incomplete, bugged and with crashes) Wintergrasp.Enable = 0 @@ -2943,6 +2943,19 @@ AuctionHouseBot.Horde.Price.Ratio = 100 AuctionHouseBot.Neutral.Price.Ratio = 100 # +# AuctionHouseBot.Items.QUALITY.Price.Ratio +# Description: Percentage by which the price of items sold of each quality is incremented / decreased (for all houses) +# Default: 100 - (No change) + +AuctionHouseBot.Items.Gray.Price.Ratio = 100 +AuctionHouseBot.Items.White.Price.Ratio = 100 +AuctionHouseBot.Items.Green.Price.Ratio = 100 +AuctionHouseBot.Items.Blue.Price.Ratio = 100 +AuctionHouseBot.Items.Purple.Price.Ratio = 100 +AuctionHouseBot.Items.Orange.Price.Ratio = 100 +AuctionHouseBot.Items.Yellow.Price.Ratio = 100 + +# # AuctionHouseBot.Items.ItemLevel.* # Description: Prevent seller from listing items below/above this item level # Default: 0 - (Disabled) @@ -3115,6 +3128,13 @@ AuctionHouseBot.Buyer.Alliance.Enabled = 0 AuctionHouseBot.Buyer.Horde.Enabled = 0 AuctionHouseBot.Buyer.Neutral.Enabled = 0 +# AuctionHouseBot.Buyer.ChanceFactor +# Description: k value in the formula used for the chance to buy an item "100^(1 + (1 - (AuctionBid / ItemPrice)) / k)" +# It must be a decimal number in the range of (0, +infinity). The higher the number the higher chance to buy overpriced auctions +# Default: 2 + +AuctionHouseBot.Buyer.ChanceFactor = 2 + # # AuctionHouseBot.Buyer.Baseprice.QUALITY # Description: Base sellprices in copper for non priced items for each quality. |