diff options
Diffstat (limited to 'src')
144 files changed, 4478 insertions, 3778 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp index 7a97cbee3de..bdb96ca0d25 100644 --- a/src/server/authserver/Authentication/AuthCodes.cpp +++ b/src/server/authserver/Authentication/AuthCodes.cpp @@ -16,17 +16,65 @@ */ #include "AuthCodes.h" +#include <cstddef> namespace AuthHelper { - bool IsAcceptedClientBuild(int build) + static RealmBuildInfo const PostBcAcceptedClientBuilds[] = + { + {15595, 4, 3, 4, ' '}, + {14545, 4, 2, 2, ' '}, + {13623, 4, 0, 6, 'a'}, + {12340, 3, 3, 5, 'a'}, + {11723, 3, 3, 3, 'a'}, + {11403, 3, 3, 2, ' '}, + {11159, 3, 3, 0, 'a'}, + {10505, 3, 2, 2, 'a'}, + {9947, 3, 1, 3, ' '}, + {8606, 2, 4, 3, ' '}, + {0, 0, 0, 0, ' '} // terminator + }; + + static RealmBuildInfo const PreBcAcceptedClientBuilds[] = + { + {6005, 1, 12, 2, ' '}, + {5875, 1, 12, 1, ' '}, + {0, 0, 0, 0, ' '} // terminator + }; + + bool IsPreBCAcceptedClientBuild(int build) { - static int accepted_versions[] = TRINITYCORE_ACCEPTED_CLIENT_BUILD; + for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i) + if (PreBcAcceptedClientBuilds[i].Build == build) + return true; - for (int i = 0; accepted_versions[i]; ++i) - if (build == accepted_versions[i]) + return false; + } + + bool IsPostBCAcceptedClientBuild(int build) + { + for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) + if (PostBcAcceptedClientBuilds[i].Build == build) return true; return false; } + + bool IsAcceptedClientBuild(int build) + { + return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); + } + + RealmBuildInfo const* GetBuildInfo(int build) + { + for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) + if (PostBcAcceptedClientBuilds[i].Build == build) + return &PostBcAcceptedClientBuilds[i]; + + for (int i = 0; PreBcAcceptedClientBuilds[i].Build; ++i) + if (PreBcAcceptedClientBuilds[i].Build == build) + return &PreBcAcceptedClientBuilds[i]; + + return NULL; + } }; diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index 9d631a5800d..148225377ff 100755 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -65,12 +65,28 @@ enum LoginResult LOGIN_LOCKED_ENFORCED = 0x10, }; -#define TRINITYCORE_ACCEPTED_CLIENT_BUILD {15595, 12340, 0} // accept one Cataclysm and one Wrath of the Lich King build +enum ExpansionFlags +{ + POST_BC_EXP_FLAG = 0x2, + PRE_BC_EXP_FLAG = 0x1, + NO_VALID_EXP_FLAG = 0x0 +}; +struct RealmBuildInfo +{ + int Build; + int MajorVersion; + int MinorVersion; + int BugfixVersion; + int HotfixVersion; +}; namespace AuthHelper { + RealmBuildInfo const* GetBuildInfo(int build); bool IsAcceptedClientBuild(int build); + bool IsPostBCAcceptedClientBuild(int build); + bool IsPreBCAcceptedClientBuild(int build); }; #endif diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index b938706a0be..ed0fa9ab06a 100755 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -80,7 +80,7 @@ extern int main(int argc, char **argv) { if (++c >= argc) { - sLog->outError(LOG_FILTER_AUTHSERVER, "Runtime-Error: -c option requires an input argument"); + printf("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } @@ -92,8 +92,8 @@ extern int main(int argc, char **argv) if (!ConfigMgr::Load(cfg_file)) { - sLog->outError(LOG_FILTER_AUTHSERVER, "Invalid or missing configuration file : %s", cfg_file); - sLog->outError(LOG_FILTER_AUTHSERVER, "Verify that the file exists and has \'[authserver]\' written in the top of the file!"); + printf("Invalid or missing configuration file : %s", cfg_file); + printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!"); return 1; } diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index c0cf24efbfb..d55d2cf02b3 100644 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -196,7 +196,7 @@ const AuthHandler table[] = Patcher PatchesCache; // Constructor - set the N and g values for SRP6 -AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket) +AuthSocket::AuthSocket(RealmSocket& socket) : socket_(socket), pPatch(NULL) { N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); @@ -343,6 +343,7 @@ bool AuthSocket::_HandleLogonChallenge() _login = (const char*)ch->I; _build = ch->build; + _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); _os = (const char*)ch->os; if (_os.size() > 4) @@ -357,13 +358,13 @@ bool AuthSocket::_HandleLogonChallenge() // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); - const std::string& ip_address = socket().getRemoteAddress(); - PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED); + std::string const& ip_address = socket().getRemoteAddress(); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED); stmt->setString(0, ip_address); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) { - pkt << (uint8)WOW_FAIL_BANNED; + pkt << uint8(WOW_FAIL_BANNED); sLog->outDebug(LOG_FILTER_AUTHSERVER, "'%s:%d' [AuthChallenge] Banned ip tries to login!",socket().getRemoteAddress().c_str(), socket().getRemotePort()); } else @@ -388,7 +389,7 @@ bool AuthSocket::_HandleLogonChallenge() if (strcmp(fields[3].GetCString(), ip_address.c_str())) { sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP differs"); - pkt << uint8(WOW_FAIL_SUSPENDED); + pkt << (uint8) WOW_FAIL_SUSPENDED; locked = true; } else @@ -410,12 +411,12 @@ bool AuthSocket::_HandleLogonChallenge() { if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) { - pkt << (uint8)WOW_FAIL_BANNED; + pkt << uint8(WOW_FAIL_BANNED); sLog->outDebug(LOG_FILTER_AUTHSERVER, "'%s:%d' [AuthChallenge] Banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ()); } else { - pkt << (uint8)WOW_FAIL_SUSPENDED; + pkt << uint8(WOW_FAIL_SUSPENDED); sLog->outDebug(LOG_FILTER_AUTHSERVER, "'%s:%d' [AuthChallenge] Temporarily banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ()); } } @@ -449,11 +450,10 @@ bool AuthSocket::_HandleLogonChallenge() unk3.SetRand(16 * 8); // Fill the response packet with the result - // If the client has no valid version - if (!AuthHelper::IsAcceptedClientBuild(_build)) - pkt << uint8(WOW_FAIL_VERSION_INVALID); - else + if (AuthHelper::IsAcceptedClientBuild(_build)) pkt << uint8(WOW_SUCCESS); + else + pkt << uint8(WOW_FAIL_VERSION_INVALID); // B may be calculated < 32B so we force minimal length to 32B pkt.append(B.AsByteArray(32), 32); // 32 bytes @@ -498,7 +498,7 @@ bool AuthSocket::_HandleLogonChallenge() } } else //no account - pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); + pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT; } socket().send((char const*)pkt.contents(), pkt.size()); @@ -515,6 +515,15 @@ bool AuthSocket::_HandleLogonProof() if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) return false; + // If the client has no valid version + if (_expversion == NO_VALID_EXP_FLAG) + { + // Check if we have the appropriate patch on the disk + sLog->outDebug(LOG_FILTER_NETWORKIO, "Client with invalid version, patching is not implemented"); + socket().shutdown(); + return true; + } + // Continue the SRP6 calculation based on data received from the client BigNumber A; @@ -615,14 +624,26 @@ bool AuthSocket::_HandleLogonProof() sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); - sAuthLogonProof_S proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) - proof.unk2 = 0x00; // SurveyId - proof.unk3 = 0x00; - socket().send((char *)&proof, sizeof(proof)); + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + { + sAuthLogonProof_S proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) + proof.unk2 = 0x00; // SurveyId + proof.unk3 = 0x00; + socket().send((char *)&proof, sizeof(proof)); + } + else + { + sAuthLogonProof_S_Old proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk2 = 0x00; + socket().send((char *)&proof, sizeof(proof)); + } _authed = true; } @@ -731,6 +752,7 @@ bool AuthSocket::_HandleReconnectChallenge() // Reinitialize build, expansion and the account securitylevel _build = ch->build; + _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG)); _os = (const char*)ch->os; if (_os.size() > 4) @@ -830,57 +852,87 @@ bool AuthSocket::_HandleRealmList() for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client - if (i->second.gamebuild != _build) - continue; - - uint8 AmountOfCharacters; + bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)); // No SQL injection. id of realm is controlled by the database. + uint32 flag = i->second.flag; + RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(i->second.gamebuild); + if (!okBuild) + { + if (!buildInfo) + continue; + + flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for + } + + if (!buildInfo) + flag &= ~REALM_FLAG_SPECIFYBUILD; + + std::string name = i->first; + if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) + { + std::ostringstream ss; + ss << name << " (" << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << ')'; + name = ss.str(); + } + + uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + + uint8 AmountOfCharacters = 0; stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM); stmt->setUInt32(0, i->second.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); - else - AmountOfCharacters = 0; - - uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; pkt << i->second.icon; // realm type - pkt << lock; // if 1, then realm locked - pkt << uint8(i->second.flag); // RealmFlags - pkt << i->first; + if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients + pkt << lock; // if 1, then realm locked + pkt << uint8(flag); // RealmFlags + pkt << name; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category - pkt << uint8(0x2C); // unk, may be realm number/id? + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + pkt << uint8(0x2C); // unk, may be realm number/id? + else + pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients - if (i->second.flag & REALM_FLAG_SPECIFYBUILD) + if (_expversion & POST_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD) { - // TODO: Make this customizable - pkt << uint8(3); - pkt << uint8(3); - pkt << uint8(5); - pkt << uint16(12340); + pkt << uint8(buildInfo->MajorVersion); + pkt << uint8(buildInfo->MinorVersion); + pkt << uint8(buildInfo->BugfixVersion); + pkt << uint16(buildInfo->Build); } ++RealmListSize; } - pkt << uint8(0x10); - pkt << uint8(0x00); - + if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients + { + pkt << uint8(0x10); + pkt << uint8(0x00); + } + else // 1.12.1 and 1.12.2 clients + { + pkt << uint8(0x00); + pkt << uint8(0x02); + } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; - RealmListSizeBuffer << (uint32)0; - RealmListSizeBuffer << uint16(RealmListSize); + RealmListSizeBuffer << uint32(0); + if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients + RealmListSizeBuffer << uint16(RealmListSize); + else + RealmListSizeBuffer << uint32(RealmListSize); ByteBuffer hdr; hdr << uint8(REALM_LIST); - hdr << uint16((pkt.size() + RealmListSizeBuffer.size())); + hdr << uint16(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist @@ -894,7 +946,7 @@ bool AuthSocket::_HandleXferResume() { sLog->outDebug(LOG_FILTER_AUTHSERVER, "Entering _HandleXferResume"); // Check packet length and patch existence - if (socket().recv_len() < 9 || !pPatch) + if (socket().recv_len() < 9 || !pPatch) // FIXME: pPatch is never used { sLog->outError(LOG_FILTER_AUTHSERVER, "Error while resuming patch transfer (wrong packet)"); return false; @@ -948,7 +1000,9 @@ PatcherRunnable::PatcherRunnable(class AuthSocket* as) } // Send content of patch file to the client -void PatcherRunnable::run() {} +void PatcherRunnable::run() +{ +} // Preload MD5 hashes of existing patch files on server #ifndef _WIN32 diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h index edd2b345183..9be2136b55c 100755 --- a/src/server/authserver/Server/AuthSocket.h +++ b/src/server/authserver/Server/AuthSocket.h @@ -70,6 +70,7 @@ private: std::string _localizationName; std::string _os; uint16 _build; + uint8 _expversion; AccountTypes _accountSecurityLevel; }; diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index ee7e5970155..67d22c49da1 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -9,6 +9,7 @@ # EXAMPLE CONFIG # AUTH SERVER SETTINGS # MYSQL SETTINGS +# LOGGING SYSTEM SETTINGS # ################################################################################################### @@ -148,7 +149,7 @@ LoginDatabase.WorkerThreads = 1 ################################################################################################### # -# Logging system options. +# LOGGING SYSTEM SETTINGS # # Appender config values: Given a appender "name" # Appender.name @@ -247,3 +248,6 @@ Logger.Root=0,3,Console Auth # Default: "root" Loggers=Root + +# +###################################################################################################
\ No newline at end of file diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 6489ddd7a4f..f35e36d92fd 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -124,8 +124,8 @@ namespace VMAP return intersectionCallBack.result; } - StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath): - iMapID(mapID), iTreeValues(0), iBasePath(basePath) + StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath) + : iMapID(mapID), iTreeValues(0), iBasePath(basePath), iIsTiled(false) { if (iBasePath.length() > 0 && iBasePath[iBasePath.length()-1] != '/' && iBasePath[iBasePath.length()-1] != '\\') { diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp index 207b652a4d6..8458ffdd5d3 100644 --- a/src/server/collision/Maps/TileAssembler.cpp +++ b/src/server/collision/Maps/TileAssembler.cpp @@ -54,11 +54,8 @@ namespace VMAP //================================================================= TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName) + : iSrcDir(pSrcDirName), iDestDir(pDestDirName), iCurrentUniqueNameId(0), iFilterMethod(NULL) { - iCurrentUniqueNameId = 0; - iFilterMethod = NULL; - iSrcDir = pSrcDirName; - iDestDir = pDestDirName; //mkdir(iDestDir); //init(); } diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h index 1118b654578..2745628ac7e 100755 --- a/src/server/collision/Models/ModelInstance.h +++ b/src/server/collision/Models/ModelInstance.h @@ -63,7 +63,7 @@ namespace VMAP class ModelInstance: public ModelSpawn { public: - ModelInstance(): iModel(0) {} + ModelInstance(): iModel(0), iInvScale(0.0f) {} ModelInstance(const ModelSpawn &spawn, WorldModel* model); void setUnloaded() { iModel = 0; } bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const; diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index ba0a94d2590..aa46d555b7d 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -41,8 +41,10 @@ class SummonList : public std::list<uint64> template <class Predicate> void DoAction(int32 info, Predicate& predicate, uint16 max = 0) { - Trinity::Containers::RandomResizeList<uint64, Predicate>(*this, predicate, max); - for (iterator i = begin(); i != end(); ) + // We need to use a copy of SummonList here, otherwise original SummonList would be modified + std::list<uint64> listCopy = *this; + Trinity::Containers::RandomResizeList<uint64, Predicate>(listCopy, predicate, max); + for (iterator i = listCopy.begin(); i != listCopy.end(); ) { Creature* summon = Unit::GetCreature(*me, *i++); if (summon && summon->IsAIEnabled) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 6e5a34e8c33..69ecb1ef581 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -79,6 +79,7 @@ SmartScript::SmartScript() { go = NULL; me = NULL; + trigger = NULL; mEventPhase = 0; mPathId = 0; mTargetStorage = new ObjectListMap(); @@ -92,6 +93,7 @@ SmartScript::SmartScript() meOrigGUID = 0; goOrigGUID = 0; mLastInvoker = 0; + mScriptType = SMART_SCRIPT_TYPE_CREATURE; } SmartScript::~SmartScript() @@ -1117,10 +1119,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_SUMMON_CREATURE: { - float x, y, z, o; ObjectList* targets = GetTargets(e, unit); if (targets) { + float x, y, z, o; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { (*itr)->GetPosition(x, y, z, o); @@ -1149,10 +1151,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!GetBaseObject()) break; - float x, y, z, o; ObjectList* targets = GetTargets(e, unit); if (targets) { + float x, y, z, o; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { if (!IsUnit(*itr)) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index a40024a81cd..37fd91fcc1b 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -913,7 +913,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return true; } -bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) +/*bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused { bool error = false; uint32 entry = 0; @@ -938,4 +938,4 @@ bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) return false; } return true; -} +}*/ diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 2a81339a930..b0a3c5b6bb6 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1216,16 +1216,9 @@ enum SmartCastFlags // one line in DB is one event struct SmartScriptHolder { - SmartScriptHolder() - { - timer = 0; - active = false; - runOnce = false; - link = 0; - entryOrGuid = 0; - event_id = 0; - enableTimed = false; - } + SmartScriptHolder() : timer(0), active(false), runOnce(false), link(0), entryOrGuid(0), + event_id(0), enableTimed(false), source_type(SMART_SCRIPT_TYPE_CREATURE) {} + int32 entryOrGuid; SmartScriptType source_type; uint32 event_id; @@ -1437,7 +1430,7 @@ class SmartAIMgr return true; } - bool IsTextValid(SmartScriptHolder const& e, uint32 id); + //bool IsTextValid(SmartScriptHolder const& e, uint32 id); }; #define sSmartScriptMgr ACE_Singleton<SmartAIMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 7a73b9f8f69..ee2795a83a8 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -80,7 +80,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) return false; } - switch (criteria->requiredType) + switch (criteria->type) { case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: @@ -108,7 +108,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) default: if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT) { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->requiredType); + sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->type); return false; } break; @@ -124,7 +124,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!creature.id || !sObjectMgr->GetCreatureTemplate(creature.id)) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) has non-existing creature id in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, creature.id); + criteria->ID, criteria->type, dataType, creature.id); return false; } return true; @@ -132,19 +132,19 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!classRace.class_id && !classRace.race_id) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.", - criteria->ID, criteria->requiredType, dataType); + criteria->ID, criteria->type, dataType); return false; } if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, classRace.class_id); + criteria->ID, criteria->type, dataType, classRace.class_id); return false; } if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, classRace.race_id); + criteria->ID, criteria->type, dataType, classRace.race_id); return false; } return true; @@ -152,7 +152,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (health.percent < 1 || health.percent > 100) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) has wrong percent value in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, health.percent); + criteria->ID, criteria->type, dataType, health.percent); return false; } return true; @@ -163,19 +163,19 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!spellEntry) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell id in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id); + criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id); return false; } if (aura.effect_idx >= 3) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell effect index in value2 (%u), ignored.", - criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx); + criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx); return false; } if (!spellEntry->Effects[aura.effect_idx].ApplyAuraName) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has non-aura spell effect (ID: %u Effect: %u), ignores.", - criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id, aura.effect_idx); + criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id, aura.effect_idx); return false; } return true; @@ -184,7 +184,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (level.minlevel > STRONG_MAX_LEVEL) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL (%u) has wrong minlevel in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, level.minlevel); + criteria->ID, criteria->type, dataType, level.minlevel); return false; } return true; @@ -192,7 +192,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (gender.gender > GENDER_NONE) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER (%u) has wrong gender in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, gender.gender); + criteria->ID, criteria->type, dataType, gender.gender); return false; } return true; @@ -200,7 +200,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!ScriptId) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT (%u) does not have ScriptName set, ignored.", - criteria->ID, criteria->requiredType, dataType); + criteria->ID, criteria->type, dataType); return false; } return true; @@ -208,7 +208,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (map_players.maxcount <= 0) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT (%u) has wrong max players count in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, map_players.maxcount); + criteria->ID, criteria->type, dataType, map_players.maxcount); return false; } return true; @@ -216,7 +216,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (team.team != ALLIANCE && team.team != HORDE) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM (%u) has unknown team in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, team.team); + criteria->ID, criteria->type, dataType, team.team); return false; } return true; @@ -224,7 +224,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (drunk.state >= MAX_DRUNKEN) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK (%u) has unknown drunken state in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, drunk.state); + criteria->ID, criteria->type, dataType, drunk.state); return false; } return true; @@ -232,7 +232,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!sHolidaysStore.LookupEntry(holiday.id)) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY (%u) has unknown holiday in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, holiday.id); + criteria->ID, criteria->type, dataType, holiday.id); return false; } return true; @@ -242,7 +242,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (equipped_item.item_quality >= MAX_ITEM_QUALITY) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, equipped_item.item_quality); + criteria->ID, criteria->type, dataType, equipped_item.item_quality); return false; } return true; @@ -250,29 +250,29 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) if (!classRace.class_id && !classRace.race_id) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.", - criteria->ID, criteria->requiredType, dataType); + criteria->ID, criteria->type, dataType); return false; } if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, classRace.class_id); + criteria->ID, criteria->type, dataType, classRace.class_id); return false; } if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0) { sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, classRace.race_id); + criteria->ID, criteria->type, dataType, classRace.race_id); return false; } return true; default: - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType); + sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->type, dataType); return false; } } -bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscvalue1 /*= 0*/) const +bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscValue1 /*= 0*/) const { switch (dataType) { @@ -307,7 +307,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA: return target && target->HasAuraEffect(aura.spell_id, aura.effect_idx); case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE: - return miscvalue1 >= value.minvalue; + return miscValue1 >= value.minvalue; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL: if (!target) return false; @@ -353,11 +353,11 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId()); return false; } - return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1); + return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscValue1); } case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM: { - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscvalue1); + ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscValue1); if (!pProto) return false; return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality; @@ -368,10 +368,10 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un return false; } -bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscvalue /*= 0*/) const +bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscValue /*= 0*/) const { for (Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr) - if (!itr->Meets(criteria_id, source, target, miscvalue)) + if (!itr->Meets(criteria_id, source, target, miscValue)) return false; return true; @@ -454,9 +454,9 @@ void AchievementMgr<Guild>::RemoveCriteriaProgress(const AchievementCriteriaEntr } template<class T> -void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete) +void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2, bool evenIfCriteriaComplete) { - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2); + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2); // disable for gamemasters with GM-mode enabled if (GetOwner()->isGameMaster()) @@ -467,7 +467,7 @@ void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, { AchievementCriteriaEntry const* achievementCriteria = (*i); - AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->achievement); if (!achievement) continue; @@ -476,9 +476,9 @@ void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, continue; for (uint8 j = 0; j < MAX_CRITERIA_REQUIREMENTS; ++j) - if (achievementCriteria->additionalRequirements[j].additionalRequirement_type == miscvalue1 && + if (achievementCriteria->additionalRequirements[j].additionalRequirement_type == miscValue1 && (!achievementCriteria->additionalRequirements[j].additionalRequirement_value || - achievementCriteria->additionalRequirements[j].additionalRequirement_value == miscvalue2)) + achievementCriteria->additionalRequirements[j].additionalRequirement_value == miscValue2)) { RemoveCriteriaProgress(achievementCriteria); break; @@ -487,7 +487,7 @@ void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, } template<> -void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint32 /*miscvalue1*/, uint32 /*miscvalue2*/, bool /*evenIfCriteriaComplete*/) +void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint32 /*miscValue1*/, uint32 /*miscValue2*/, bool /*evenIfCriteriaComplete*/) { // Not needed } @@ -703,7 +703,7 @@ void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, P uint32 achievementid = fields[0].GetUInt16(); // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements() - AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementid); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementid); if (!achievement) continue; @@ -718,11 +718,13 @@ void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, P if (!GetOwner()->HasTitle(titleEntry)) GetOwner()->SetTitle(titleEntry); - } while (achievementResult->NextRow()); + } + while (achievementResult->NextRow()); } if (criteriaResult) { + time_t now = time(NULL); do { Field* fields = criteriaResult->Fetch(); @@ -730,7 +732,7 @@ void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, P uint32 counter = fields[1].GetUInt32(); time_t date = time_t(fields[2].GetUInt32()); - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); + AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id); if (!criteria) { // we will remove not existed criteria for all characters @@ -743,14 +745,15 @@ void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, P continue; } - if (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL)) + if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now) continue; CriteriaProgress& progress = m_criteriaProgress[id]; progress.counter = counter; progress.date = date; progress.changed = false; - } while (criteriaResult->NextRow()); + } + while (criteriaResult->NextRow()); } } @@ -765,7 +768,7 @@ void AchievementMgr<Guild>::LoadFromDB(PreparedQueryResult achievementResult, Pr uint32 achievementid = fields[0].GetUInt16(); // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements() - AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementid); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementid); if (!achievement) continue; @@ -776,8 +779,8 @@ void AchievementMgr<Guild>::LoadFromDB(PreparedQueryResult achievementResult, Pr ca.guids.insert(MAKE_NEW_GUID(atol(guids[i]), 0, HIGHGUID_PLAYER)); ca.changed = false; - - } while (achievementResult->NextRow()); + } + while (achievementResult->NextRow()); } if (criteriaResult) @@ -791,11 +794,11 @@ void AchievementMgr<Guild>::LoadFromDB(PreparedQueryResult achievementResult, Pr time_t date = time_t(fields[2].GetUInt32()); uint64 guid = fields[3].GetUInt32(); - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); + AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id); if (!criteria) { // we will remove not existed criteria for all guilds - sLog->outError(LOG_FILTER_GENERAL, "Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id); + sLog->outError(LOG_FILTER_ACHIEVEMENTSYS, "Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA); stmt->setUInt16(0, uint16(id)); @@ -839,7 +842,7 @@ void AchievementMgr<Player>::Reset() m_completedAchievements.clear(); m_criteriaProgress.clear(); - DeleteFromDB(_owner->GetGUIDLow()); + DeleteFromDB(GetOwner()->GetGUIDLow()); // re-fill data CheckAllAchievementCriteria(GetOwner()); @@ -874,23 +877,21 @@ void AchievementMgr<Guild>::Reset() } while (!m_criteriaProgress.empty()) - if (AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(m_criteriaProgress.begin()->first)) + if (AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(m_criteriaProgress.begin()->first)) RemoveCriteriaProgress(criteria); m_completedAchievements.clear(); - DeleteFromDB(_owner->GetId()); + DeleteFromDB(GetOwner()->GetId()); } template<class T> void AchievementMgr<T>::SendAchievementEarned(AchievementEntry const* achievement) const { - // Don't send for achievements with ACHIEVEMENT_FLAG_TRACKING + // Don't send for achievements with ACHIEVEMENT_FLAG_HIDDEN if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN) return; - #ifdef TRINITY_DEBUG - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SendAchievementEarned(%u)", achievement->ID); - #endif + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SendAchievementEarned(%u)", achievement->ID); if (Guild* guild = sGuildMgr->GetGuildById(GetOwner()->GetGuildId())) { @@ -902,7 +903,7 @@ void AchievementMgr<T>::SendAchievementEarned(AchievementEntry const* achievemen if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL | ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) { // broadcast realm first reached - WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetOwner()->GetName())+1+8+4+4); + WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetOwner()->GetName()) + 1 + 8 + 4 + 4); data << GetOwner()->GetName(); data << uint64(GetOwner()->GetGUID()); data << uint32(achievement->ID); @@ -969,7 +970,7 @@ void AchievementMgr<T>::SendCriteriaUpdate(AchievementCriteriaEntry const* /*ent template<> void AchievementMgr<Player>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const { - WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8); + WorldPacket data(SMSG_CRITERIA_UPDATE, 8 + 4 + 8); data << uint32(entry->ID); // the counter is packed like a packed Guid @@ -1051,7 +1052,7 @@ void AchievementMgr<T>::CheckAllAchievementCriteria(Player* referencePlayer) UpdateAchievementCriteria(AchievementCriteriaTypes(i), 0, 0, NULL, referencePlayer); } -static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 }; +static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = {1057, 1107, 1108}; static const uint32 achievIdForDungeon[][4] = { // ach_cr_id, is_dungeon, is_raid, is_heroic_dungeon @@ -1071,9 +1072,9 @@ template<> bool IsGuild<Guild>() { return true; } * this function will be called whenever the user might have done a criteria relevant action */ template<class T> -void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/, Player* referencePlayer /*= NULL*/) +void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit const* unit /*= NULL*/, Player* referencePlayer /*= NULL*/) { - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::UpdateAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2); + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2); // disable for gamemasters with GM-mode enabled if (referencePlayer->isGameMaster()) @@ -1083,9 +1084,12 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i) { AchievementCriteriaEntry const* achievementCriteria = (*i); - AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->achievement); if (!achievement) + { + sLog->outError(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria: Achievement %u not found!", achievementCriteria->achievement); continue; + } if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, unit, referencePlayer)) continue; @@ -1108,12 +1112,37 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_DEATH: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: + case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT: + case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: + case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: + case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: + case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: + case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: + case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: + case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL: + case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; - // std case: increment at miscvalue1 + // std case: increment at miscValue1 case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS: case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS: case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD: @@ -1124,82 +1153,42 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED: case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: + case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: + case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE: SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; - // std case: high value at miscvalue1 + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: + case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: + SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); + break; + // std case: high value at miscValue1 case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST); break; - - // specialized cases - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - if (achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId()) - continue; - - SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - if (achievementCriteria->kill_creature.creatureID != miscValue1) - continue; - - SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); - break; - } case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: SetCriteriaProgress(achievementCriteria, referencePlayer->getLevel(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: - // update at loading or specific skill update - if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID) - continue; if (uint32 skillvalue = referencePlayer->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID)) SetCriteriaProgress(achievementCriteria, skillvalue, referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL: - // update at loading or specific skill update - if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID) - continue; if (uint32 maxSkillvalue = referencePlayer->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID)) SetCriteriaProgress(achievementCriteria, maxSkillvalue, referencePlayer); break; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: - if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end()) - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); - break; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: - { SetCriteriaProgress(achievementCriteria, referencePlayer->GetRewardedQuestCount(), referencePlayer); break; - } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: { time_t nextDailyResetTime = sWorld->GetNextDailyQuestsResetTime(); @@ -1218,7 +1207,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, // 1st time. Start count. progressType = PROGRESS_SET; else if (progress->date < (nextDailyResetTime - 2 * DAY)) - // last progress is older than 2 days. Player missed 1 day => Retart count. + // last progress is older than 2 days. Player missed 1 day => Restart count. progressType = PROGRESS_SET; else if (progress->date < (nextDailyResetTime - DAY)) // last progress is between 1 and 2 days. => 1st time of the day. @@ -1232,10 +1221,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: { - // speedup for non-login case - if (miscValue1 && miscValue1 != achievementCriteria->complete_quests_in_zone.zoneID) - continue; - uint32 counter = 0; const RewardedQuestSet &rewQuests = referencePlayer->getRewardedQuests(); @@ -1248,371 +1233,34 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, SetCriteriaProgress(achievementCriteria, counter, referencePlayer); break; } - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - if (referencePlayer->GetMapId() != achievementCriteria->complete_battleground.mapID) - continue; - SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - if (referencePlayer->GetMapId() != achievementCriteria->death_at_map.mapID) - continue; - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_DEATH: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - // skip wrong arena achievements, if not achievIdByArenaSlot then normal total death counter - bool notfit = false; - for (int j = 0; j < MAX_ARENA_SLOT; ++j) - { - if (achievIdByArenaSlot[j] == achievement->ID) - { - Battleground* bg = referencePlayer->GetBattleground(); - if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j) - notfit = true; - - break; - } - } - if (notfit) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - - Map const* map = referencePlayer->IsInWorld() ? referencePlayer->GetMap() : sMapMgr->FindMap(referencePlayer->GetMapId(), referencePlayer->GetInstanceId()); - if (!map || !map->IsDungeon()) - continue; - - // search case - bool found = false; - for (int j = 0; achievIdForDungeon[j][0]; ++j) - { - if (achievIdForDungeon[j][0] == achievement->ID) - { - if (map->IsRaid()) - { - // if raid accepted (ignore difficulty) - if (!achievIdForDungeon[j][2]) - break; // for - } - else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL) - { - // dungeon in normal mode accepted - if (!achievIdForDungeon[j][1]) - break; // for - } - else - { - // dungeon in heroic mode accepted - if (!achievIdForDungeon[j][3]) - break; // for - } - - found = true; - break; // for - } - } - if (!found) - continue; - - //FIXME: work only for instances where max == min for players - if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit) - continue; - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - - } - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - if (miscValue1 != achievementCriteria->killed_by_creature.creatureEntry) - continue; - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - - // if team check required: must kill by opposition faction - if (achievement->ID == 318 && miscValue2 == referencePlayer->GetTeam()) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - - // miscvalue1 is the ingame fallheight*100 as stored in dbc + // miscValue1 is the ingame fallheight*100 as stored in dbc SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer); break; - } - case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - if (miscValue2 != achievementCriteria->death_from.type) - continue; - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: - { - // if miscvalues != 0, it contains the questID. - if (miscValue1) - { - if (miscValue1 != achievementCriteria->complete_quest.questID) - continue; - } - else - { - // login case. - if (!referencePlayer->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) - continue; - } - - if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria)) - if (!data->Meets(referencePlayer, unit)) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: - case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: - { - if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: - { - if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: - if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID) - continue; - - if (referencePlayer->HasSpell(achievementCriteria->learn_spell.spellID)) - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); - break; - case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: - { - // miscvalue1=loot_type (note: 0 = LOOT_CORPSE and then it ignored) - // miscvalue2=count of item loot - if (!miscValue1 || !miscValue2) - continue; - if (miscValue1 != achievementCriteria->loot_type.lootType) - continue; - - SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: - // speedup for non-login case - if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1) - continue; - SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: - if (!miscValue1) // no update at login - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - - if (achievementCriteria->use_item.itemID != miscValue1) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: - // You _have_ to loot that item, just owning it when logging in does _not_ count! - if (!miscValue1) - continue; - if (miscValue1 != achievementCriteria->own_item.itemID) - continue; - SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); - break; case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: - { - WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference); - if (!worldOverlayEntry) - break; - - bool matchFound = false; - for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j) - { - uint32 area_id = worldOverlayEntry->areatableID[j]; - if (!area_id) // array have 0 only in empty tail - break; - - int32 exploreFlag = GetAreaFlagByAreaID(area_id); - if (exploreFlag < 0) - continue; - - uint32 playerIndexOffset = uint32(exploreFlag) / 32; - uint32 mask = 1<< (uint32(exploreFlag) % 32); - - if (referencePlayer->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) - { - matchFound = true; - break; - } - } - - if (matchFound) - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); + case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: + case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; - } case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: SetCriteriaProgress(achievementCriteria, referencePlayer->GetBankBagSlotCount(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: { - // skip faction check only at loading - if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID) - continue; - int32 reputation = referencePlayer->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID); if (reputation > 0) SetCriteriaProgress(achievementCriteria, reputation, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: - { SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetExaltedFactionCount(), referencePlayer); break; - } - case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: - { - // skip for login case - if (!miscValue1) - continue; - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: - { - // miscvalue1 = itemid - // miscvalue2 = itemSlot - if (!miscValue1) - continue; - - if (miscValue2 != achievementCriteria->equip_epic_item.itemSlot) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); - break; - } - - case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT: - case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT: - { - // miscvalue1 = itemid - // miscvalue2 = diced value - if (!miscValue1) - continue; - if (miscValue2 != achievementCriteria->roll_greed_on_loot.rollValue) - continue; - - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscValue1); - if (!pProto) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: - { - // miscvalue1 = emote - if (!miscValue1) - continue; - if (miscValue1 != achievementCriteria->do_emote.emoteID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: - case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE: - { - if (!miscValue1) - continue; - - if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP) - { - if (referencePlayer->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value) - continue; - - // map specific case (BG in fact) expected player targeted damage/heal - if (!unit || unit->GetTypeId() != TYPEID_PLAYER) - continue; - } - - SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: - // miscvalue1 = item_id - if (!miscValue1) - continue; - if (miscValue1 != achievementCriteria->equip_item.itemID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer); - break; - case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: - // miscvalue1 = go entry - if (!miscValue1) - continue; - if (miscValue1 != achievementCriteria->use_gameobject.goEntry) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: - if (!miscValue1) - continue; - if (miscValue1 != achievementCriteria->fish_in_gameobject.goEntry) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: { - if (miscValue1 && miscValue1 != achievementCriteria->learn_skillline_spell.skillLine) - continue; - uint32 spellCount = 0; for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin(); spellIter != referencePlayer->GetSpellMap().end(); @@ -1628,13 +1276,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer); break; } - case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetReveredFactionCount(), referencePlayer); break; @@ -1644,23 +1285,8 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS: SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetVisibleFactionCount(), referencePlayer); break; - case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: - case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if (!miscValue1) - continue; - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1); - if (!proto || proto->Quality < ITEM_QUALITY_EPIC) - continue; - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE: { - if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_line.skillLine) - continue; - uint32 spellCount = 0; for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin(); spellIter != referencePlayer->GetSpellMap().end(); @@ -1677,18 +1303,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL: SetCriteriaProgress(achievementCriteria, referencePlayer->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS), referencePlayer); break; - case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: - if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: - if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED: SetCriteriaProgress(achievementCriteria, referencePlayer->GetMoney(), referencePlayer, PROGRESS_HIGHEST); break; @@ -1698,7 +1312,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, { uint32 points = 0; for (CompletedAchievementMap::iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) - if (AchievementEntry const* pAchievement = sAchievementStore.LookupEntry(itr->first)) + if (AchievementEntry const* pAchievement = sAchievementMgr->GetAchievement(itr->first)) points += pAchievement->points; SetCriteriaProgress(achievementCriteria, points, referencePlayer, PROGRESS_SET); } @@ -1706,33 +1320,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; } - case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: - { - if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: - case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL: - case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: - { - // skip login update - if (!miscValue1) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: - { - if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID) - continue; - - SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); - break; - } case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING: { uint32 reqTeamType = achievementCriteria->highest_team_rating.teamtype; @@ -1744,7 +1331,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST); } - else // login case + else // login case { for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) { @@ -1774,7 +1361,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST); } - else // login case + else // login case { for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) { @@ -1796,15 +1383,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, break; } - case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: - if (!miscValue1 || !miscValue2) - continue; - if (miscValue1 != achievementCriteria->currencyGain.currency) - continue; - if (int64(miscValue2) < 0) - continue; - SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); - break; // FIXME: not triggered in code as result, need to implement case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: @@ -1812,7 +1390,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK: case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE: - case ACHIEVEMENT_CRITERIA_TYPE_TOTAL: case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS: case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL: case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: @@ -1882,7 +1459,7 @@ bool AchievementMgr<T>::IsCompletedCriteria(AchievementCriteriaEntry const* achi if (!progress) return false; - switch (achievementCriteria->requiredType) + switch (achievementCriteria->type) { case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: return progress->counter >= achievementCriteria->win_bg.winCount; @@ -2045,16 +1622,16 @@ bool AchievementMgr<T>::IsCompletedAchievement(AchievementEntry const* entry) return false; // for achievement with referenced achievement criterias get from referenced and counter from self - uint32 achievmentForTestId = entry->refAchievement ? entry->refAchievement : entry->ID; - uint32 achievmentForTestCount = entry->count; + uint32 achievementForTestId = entry->refAchievement ? entry->refAchievement : entry->ID; + uint32 achievementForTestCount = entry->count; - AchievementCriteriaEntryList const* cList = sAchievementMgr->GetAchievementCriteriaByAchievement(achievmentForTestId); + AchievementCriteriaEntryList const* cList = sAchievementMgr->GetAchievementCriteriaByAchievement(achievementForTestId); if (!cList) return false; uint32 count = 0; // For SUMM achievements, we have to count the progress of each criteria of the achievement. - // Oddly, the target count is NOT countained in the achievement, but in each individual criteria + // Oddly, the target count is NOT contained in the achievement, but in each individual criteria if (entry->flags & ACHIEVEMENT_FLAG_SUMM) { for (AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr) @@ -2089,12 +1666,12 @@ bool AchievementMgr<T>::IsCompletedAchievement(AchievementEntry const* entry) completed_all = false; // completed as have req. count of completed criterias - if (achievmentForTestCount > 0 && achievmentForTestCount <= count) + if (achievementForTestCount > 0 && achievementForTestCount <= count) return true; } // all criterias completed requirement - if (completed_all && achievmentForTestCount == 0) + if (completed_all && achievementForTestCount == 0) return true; return false; @@ -2162,7 +1739,7 @@ void AchievementMgr<T>::SetCriteriaProgress(AchievementCriteriaEntry const* entr progress->changed = true; progress->date = time(NULL); // set the date to the latest update. - AchievementEntry const* achievement = sAchievementStore.LookupEntry(entry->referredAchievement); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(entry->achievement); uint32 timeElapsed = 0; bool criteriaComplete = IsCompletedCriteria(entry, achievement); @@ -2192,7 +1769,7 @@ void AchievementMgr<T>::UpdateTimedAchievements(uint32 timeDiff) // Time is up, remove timer and reset progress if (itr->second <= timeDiff) { - AchievementCriteriaEntry const* entry = sAchievementCriteriaStore.LookupEntry(itr->first); + AchievementCriteriaEntry const* entry = sAchievementMgr->GetAchievementCriteria(itr->first); RemoveCriteriaProgress(entry); m_timedAchievements.erase(itr++); } @@ -2219,7 +1796,7 @@ void AchievementMgr<Player>::StartTimedAchievement(AchievementCriteriaTimedTypes if ((*i)->timedCriteriaMiscId != entry) continue; - AchievementEntry const* achievement = sAchievementStore.LookupEntry((*i)->referredAchievement); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement((*i)->achievement); if (m_timedAchievements.find((*i)->ID) == m_timedAchievements.end() && !IsCompletedCriteria(*i, achievement)) { // Start the timer @@ -2238,7 +1815,7 @@ template<class T> void AchievementMgr<T>::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) { AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type); - for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i) + for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i) { if ((*i)->timedCriteriaMiscId != entry) continue; @@ -2262,7 +1839,7 @@ void AchievementMgr<T>::CompletedAchievement(AchievementEntry const* achievement sLog->outInfo(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::CompletedAchievement(%u)", achievement->ID); // disable for gamemasters with GM-mode enabled - if (_owner->isGameMaster()) + if (GetOwner()->isGameMaster()) return; if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) @@ -2338,7 +1915,7 @@ void AchievementMgr<T>::CompletedAchievement(AchievementEntry const* achievement template<> void AchievementMgr<Guild>::CompletedAchievement(AchievementEntry const* achievement, Player* referencePlayer) { - sLog->outInfo(LOG_FILTER_GENERAL, "AchievementMgr<Guild>::CompletedAchievement(%u)", achievement->ID); + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr<Guild>::CompletedAchievement(%u)", achievement->ID); if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) return; @@ -2370,7 +1947,7 @@ struct VisibleAchievementPred { bool operator()(CompletedAchievementMap::value_type const& val) { - AchievementEntry const* achievement = sAchievementStore.LookupEntry(val.first); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(val.first); return achievement && !(achievement->flags & ACHIEVEMENT_FLAG_HIDDEN); } }; @@ -2450,7 +2027,7 @@ void AchievementMgr<T>::SendAllAchievementData(Player* /*receiver*/) const template<> void AchievementMgr<Guild>::SendAllAchievementData(Player* receiver) const { - WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DATA, m_completedAchievements.size() * (4 + 4) + 4); + WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DATA, m_completedAchievements.size() * (4 + 4) + 3); data.WriteBits(m_completedAchievements.size(), 23); for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) { @@ -2652,22 +2229,64 @@ bool AchievementMgr<T>::HasAchieved(uint32 achievementId) const } template<class T> -bool AchievementMgr<T>::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 /*miscValue2*/, Unit* unit, Player* referencePlayer) +bool AchievementMgr<T>::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) { if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Disabled", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); return false; + } if (achievement->mapID != -1 && referencePlayer->GetMapId() != uint32(achievement->mapID)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Wrong map", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); return false; + } + + if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && referencePlayer->GetTeam() != HORDE) || + (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && referencePlayer->GetTeam() != ALLIANCE)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Wrong faction", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); + return false; + } - // don't update already completed criteria if (IsCompletedCriteria(criteria, achievement)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Is Completed", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); return false; + } - if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && referencePlayer->GetTeam() != HORDE) || - (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && referencePlayer->GetTeam() != ALLIANCE)) + if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, unit, referencePlayer)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Requirements not satisfied", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); return false; + } + if (!AdditionalRequirementsSatisfied(criteria, miscValue1, miscValue2, unit, referencePlayer)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Additional requirements not satisfied", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); + return false; + } + + if (!ConditionsSatisfied(criteria, referencePlayer)) + { + sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Conditions not satisfied", + criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); + return false; + } + + return true; +} + +template<class T> +bool AchievementMgr<T>::ConditionsSatisfied(AchievementCriteriaEntry const *criteria, Player* referencePlayer) const +{ for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i) { if (!criteria->additionalRequirements[i].additionalRequirement_type) @@ -2688,128 +2307,716 @@ bool AchievementMgr<T>::CanUpdateCriteria(AchievementCriteriaEntry const* criter } } - // additional conditions - for (int8 i = 0; i < MAX_ADDITIONAL_CRITERIA_CONDITIONS; ++i) + return true; +} + +template<class T> +bool AchievementMgr<T>::RequirementsSatisfied(AchievementCriteriaEntry const *achievementCriteria, uint64 miscValue1, uint64 miscValue2, Unit const *unit, Player* referencePlayer) const +{ + switch (AchievementCriteriaTypes(achievementCriteria->type)) { - if (!criteria->additionalConditionType[i]) - continue; + case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: + case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION: + case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: + case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: + case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS: + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER: + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL: + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS: + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED: + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY: + case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL: + case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD: + case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS: + case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS: + case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: + case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL: + case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED: + case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED: + case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS: + case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: + case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: + if (!miscValue1) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: + case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: + case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS: + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION: + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING: + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING: + case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS: + case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: + break; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: + if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) == m_completedAchievements.end()) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + if (!miscValue1 || achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId()) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: + if (!miscValue1 || achievementCriteria->kill_creature.creatureID != miscValue1) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: + // update at loading or specific skill update + if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL: + // update at loading or specific skill update + if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: + if (miscValue1 && miscValue1 != achievementCriteria->complete_quests_in_zone.zoneID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: + if (!miscValue1 || referencePlayer->GetMapId() != achievementCriteria->complete_battleground.mapID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: + if (!miscValue1 || referencePlayer->GetMapId() != achievementCriteria->death_at_map.mapID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_DEATH: + { + if (!miscValue1) + return false; + // skip wrong arena achievements, if not achievIdByArenaSlot then normal total death counter + bool notfit = false; + for (int j = 0; j < MAX_ARENA_SLOT; ++j) + { + if (achievIdByArenaSlot[j] == achievementCriteria->achievement) + { + Battleground* bg = referencePlayer->GetBattleground(); + if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j) + notfit = true; + break; + } + } + if (notfit) + return false; + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: + { + if (!miscValue1) + return false; - uint32 value = criteria->additionalConditionValue[i]; - switch (criteria->additionalConditionType[i]) + Map const* map = referencePlayer->IsInWorld() ? referencePlayer->GetMap() : sMapMgr->FindMap(referencePlayer->GetMapId(), referencePlayer->GetInstanceId()); + if (!map || !map->IsDungeon()) + return false; + + // search case + bool found = false; + for (int j = 0; achievIdForDungeon[j][0]; ++j) + { + if (achievIdForDungeon[j][0] == achievementCriteria->achievement) + { + if (map->IsRaid()) + { + // if raid accepted (ignore difficulty) + if (!achievIdForDungeon[j][2]) + break; // for + } + else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL) + { + // dungeon in normal mode accepted + if (!achievIdForDungeon[j][1]) + break; // for + } + else + { + // dungeon in heroic mode accepted + if (!achievIdForDungeon[j][3]) + break; // for + } + + found = true; + break; // for + } + } + if (!found) + return false; + + //FIXME: work only for instances where max == min for players + if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit) + return false; + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: + if (!miscValue1 || miscValue1 != achievementCriteria->killed_by_creature.creatureEntry) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + if (!miscValue1) + return false; + + // if team check required: must kill by opposition faction + if (achievementCriteria->achievement == 318 && miscValue2 == referencePlayer->GetTeam()) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: + if (!miscValue1 || miscValue2 != achievementCriteria->death_from.type) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: { - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER: - if (!unit || !unit->ToPlayer()) + // if miscValues != 0, it contains the questID. + if (miscValue1) + { + if (miscValue1 != achievementCriteria->complete_quest.questID) return false; - break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD: - if (!unit || unit->isAlive()) + } + else + { + // login case. + if (!referencePlayer->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) return false; - break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED: - if (!unit || !unit->IsMounted()) + } + + if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria)) + if (!data->Meets(referencePlayer, unit)) return false; + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: + if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: + if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: + if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID) + return false; + + if (!referencePlayer->HasSpell(achievementCriteria->learn_spell.spellID)) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: + // miscValue1 = loot_type (note: 0 = LOOT_CORPSE and then it ignored) + // miscValue2 = count of item loot + if (!miscValue1 || !miscValue2 || miscValue1 != achievementCriteria->loot_type.lootType) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: + if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: + if (!miscValue1 || achievementCriteria->use_item.itemID != miscValue1) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: + if (!miscValue1 || miscValue1 != achievementCriteria->own_item.itemID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: + { + WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference); + if (!worldOverlayEntry) break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: - if (uint32(referencePlayer->GetMap()->GetDifficulty()) != value) + + bool matchFound = false; + for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j) + { + uint32 area_id = worldOverlayEntry->areatableID[j]; + if (!area_id) // array have 0 only in empty tail + break; + + int32 exploreFlag = GetAreaFlagByAreaID(area_id); + if (exploreFlag < 0) + continue; + + uint32 playerIndexOffset = uint32(exploreFlag) / 32; + uint32 mask = 1 << (uint32(exploreFlag) % 32); + + if (referencePlayer->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) + { + matchFound = true; + break; + } + } + + if (!matchFound) + return false; + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: + if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: + // miscValue1 = itemid miscValue2 = itemSlot + if (!miscValue1 || miscValue2 != achievementCriteria->equip_epic_item.itemSlot) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT: + { + // miscValue1 = itemid miscValue2 = diced value + if (!miscValue1 || miscValue2 != achievementCriteria->roll_greed_on_loot.rollValue) + return false; + + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(uint32(miscValue1)); + if (!proto) + return false; + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: + if (!miscValue1 || miscValue1 != achievementCriteria->do_emote.emoteID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: + case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE: + if (!miscValue1) + return false; + + if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP) + { + if (referencePlayer->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value) return false; - break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: - if (referencePlayer->GetMapId() != value) + + // map specific case (BG in fact) expected player targeted damage/heal + if (!unit || unit->GetTypeId() != TYPEID_PLAYER) + return false; + } + break; + case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: + // miscValue1 = item_id + if (!miscValue1 || miscValue1 != achievementCriteria->equip_item.itemID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: + if (!miscValue1 || miscValue1 != achievementCriteria->use_gameobject.goEntry) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: + if (!miscValue1 || miscValue1 != achievementCriteria->fish_in_gameobject.goEntry) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: + if (miscValue1 && miscValue1 != achievementCriteria->learn_skillline_spell.skillLine) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: + case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: + { + if (!miscValue1) + return false; + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1); + if (!proto || proto->Quality < ITEM_QUALITY_EPIC) + return false; + break; + } + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE: + if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_line.skillLine) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: + if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: + if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: + if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: + if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID) + return false; + break; + case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: + if (!miscValue1 || !miscValue2 || int64(miscValue2) < 0 + || miscValue1 != achievementCriteria->currencyGain.currency) + return false; + break; + default: + break; + } + return true; +} + +template<class T> +bool AchievementMgr<T>::AdditionalRequirementsSatisfied(AchievementCriteriaEntry const *criteria, uint64 miscValue1, uint64 /*miscValue2*/, Unit const* unit, Player* referencePlayer) const +{ + for (uint8 i = 0; i < MAX_ADDITIONAL_CRITERIA_CONDITIONS; ++i) + { + uint32 const reqType = criteria->additionalConditionType[i]; + uint32 const reqValue = criteria->additionalConditionValue[i]; + + switch (AchievementCriteriaAdditionalCondition(reqType)) + { + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY: // 4 + if (!unit || unit->GetEntry() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE: - if (referencePlayer->GetZoneId() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER: // 5 + if (!unit || unit->GetTypeId() != TYPEID_PLAYER) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA: - if (referencePlayer->GetAreaId() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD: // 6 + if (!unit || unit->isAlive()) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY: + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY: // 7 if (!unit) return false; if (const Player* player = unit->ToPlayer()) if (player->GetTeam() == referencePlayer->GetTeam()) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY: - if (!unit || !unit->ToCreature()) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA: // 8 + if (!referencePlayer->HasAura(reqValue)) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA: // 10 + if (!unit || !unit->HasAura(reqValue)) return false; - if (unit->ToCreature()->GetEntry() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED: // 11 + if (!unit || !unit->IsMounted()) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA: - if (!referencePlayer->HasAura(value)) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN: // 14 + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS: // 15 + { + // miscValue1 is itemid + ItemTemplate const * const item = sObjectMgr->GetItemTemplate(uint32(miscValue1)); + if (!item || item->Quality < reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA: - if (!unit || !unit->HasAura(value)) + } + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: // 20 + if (uint32(referencePlayer->GetMap()->GetDifficulty()) != reqValue) return false; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN: - if (ItemTemplate const * itemProto = sObjectMgr->GetItemTemplate(miscValue1)) - if (itemProto->Quality < value) - return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS: - if (ItemTemplate const * itemProto = sObjectMgr->GetItemTemplate(miscValue1)) - if (itemProto->Quality < value) - return false; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: // 32 + if (referencePlayer->GetMapId() != reqValue) + return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE: - if (referencePlayer->getRace() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE: // 18 + if (referencePlayer->GetZoneId() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS: - if (referencePlayer->getClass() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA: // 17 + if (referencePlayer->GetAreaId() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE: - if (!unit || !unit->ToPlayer()) - break; - if (unit->ToPlayer()->getRace() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE: // 25 + if (referencePlayer->getRace() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS: - if (!unit || !unit->ToPlayer()) - break; - if (unit->ToPlayer()->getClass() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS: // 26 + if (referencePlayer->getClass() != reqValue) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE: // 27 + if (!unit || unit->GetTypeId() != TYPEID_PLAYER || unit->getRace() != reqValue) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS: // 28 + if (!unit || unit->GetTypeId() != TYPEID_PLAYER || unit->getClass() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS: - if (referencePlayer->GetGroup() && referencePlayer->GetGroup()->GetMembersCount() >= value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS: // 29 + if (referencePlayer->GetGroup() && referencePlayer->GetGroup()->GetMembersCount() >= reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE: - if (!unit || !unit->ToCreature()) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE: // 30 + { + if (!unit) return false; - if (unit->ToCreature()->GetCreatureType() != value) + Creature const * const creature = unit->ToCreature(); + if (!creature || creature->GetCreatureType() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL: - if (referencePlayer->getLevel() != value) + } + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: // 38 + // miscValue1 is title's bit index + if (miscValue1 != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL: - if (!unit || unit->getLevel() != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL: // 39 + if (referencePlayer->getLevel() != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: - if (!unit || unit->GetHealthPct() >= value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL: // 40 + if (!unit || unit->getLevel() != reqValue) return false; break; - // generic, compare miscValue1 with DBC value - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: - if (miscValue1 != value) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: // 46 + if (!unit || unit->GetHealthPct() >= reqValue) return false; break; default: break; } } - return true; } +char const* AchievementGlobalMgr::GetCriteriaTypeString(uint32 type) +{ + return GetCriteriaTypeString(AchievementCriteriaTypes(type)); +} + +char const* AchievementGlobalMgr::GetCriteriaTypeString(AchievementCriteriaTypes type) +{ + switch (type) + { + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: + return "KILL_CREATURE"; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + return "TYPE_WIN_BG"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS: + return "COMPLETE_RESEARCH"; + case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: + return "REACH_LEVEL"; + case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: + return "REACH_SKILL_LEVEL"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: + return "COMPLETE_ACHIEVEMENT"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: + return "COMPLETE_QUEST_COUNT"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: + return "COMPLETE_DAILY_QUEST_DAILY"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: + return "COMPLETE_QUESTS_IN_ZONE"; + case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: + return "CURRENCY"; + case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: + return "DAMAGE_DONE"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: + return "COMPLETE_DAILY_QUEST"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: + return "COMPLETE_BATTLEGROUND"; + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: + return "DEATH_AT_MAP"; + case ACHIEVEMENT_CRITERIA_TYPE_DEATH: + return "DEATH"; + case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: + return "DEATH_IN_DUNGEON"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: + return "COMPLETE_RAID"; + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: + return "KILLED_BY_CREATURE"; + case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: + return "KILLED_BY_PLAYER"; + case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: + return "FALL_WITHOUT_DYING"; + case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: + return "DEATHS_FROM"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: + return "COMPLETE_QUEST"; + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: + return "BE_SPELL_TARGET"; + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: + return "CAST_SPELL"; + case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: + return "BG_OBJECTIVE_CAPTURE"; + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: + return "HONORABLE_KILL_AT_AREA"; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: + return "WIN_ARENA"; + case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA: + return "PLAY_ARENA"; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: + return "LEARN_SPELL"; + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: + return "HONORABLE_KILL"; + case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: + return "OWN_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: + return "WIN_RATED_ARENA"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING: + return "HIGHEST_TEAM_RATING"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING: + return "HIGHEST_PERSONAL_RATING"; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL: + return "LEARN_SKILL_LEVEL"; + case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: + return "USE_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: + return "LOOT_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: + return "EXPLORE_AREA"; + case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK: + return "OWN_RANK"; + case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: + return "BUY_BANK_SLOT"; + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: + return "GAIN_REPUTATION"; + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: + return "GAIN_EXALTED_REPUTATION"; + case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: + return "VISIT_BARBER_SHOP"; + case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: + return "EQUIP_EPIC_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT: + return "ROLL_NEED_ON_LOOT"; + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT: + return "GREED_ON_LOOT"; + case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: + return "HK_CLASS"; + case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: + return "HK_RACE"; + case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: + return "DO_EMOTE"; + case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE: + return "HEALING_DONE"; + case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: + return "GET_KILLING_BLOWS"; + case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: + return "EQUIP_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS: + return "MONEY_FROM_VENDORS"; + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS: + return "GOLD_SPENT_FOR_TALENTS"; + case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS: + return "NUMBER_OF_TALENT_RESETS"; + case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD: + return "MONEY_FROM_QUEST_REWARD"; + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING: + return "GOLD_SPENT_FOR_TRAVELLING"; + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER: + return "GOLD_SPENT_AT_BARBER"; + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL: + return "GOLD_SPENT_FOR_MAIL"; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY: + return "LOOT_MONEY"; + case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: + return "USE_GAMEOBJECT"; + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: + return "BE_SPELL_TARGET2"; + case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL: + return "SPECIAL_PVP_KILL"; + case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: + return "FISH_IN_GAMEOBJECT"; + case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: + return "EARNED_PVP_TITLE"; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: + return "LEARN_SKILLLINE_SPELLS"; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: + return "WIN_DUEL"; + case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL: + return "LOSE_DUEL"; + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE: + return "KILL_CREATURE_TYPE"; + case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS: + return "GOLD_EARNED_BY_AUCTIONS"; + case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION: + return "CREATE_AUCTION"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID: + return "HIGHEST_AUCTION_BID"; + case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: + return "WON_AUCTIONS"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: + return "HIGHEST_AUCTION_SOLD"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED: + return "HIGHEST_GOLD_VALUE_OWNED"; + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: + return "GAIN_REVERED_REPUTATION"; + case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION: + return "GAIN_HONORED_REPUTATION"; + case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS: + return "KNOWN_FACTIONS"; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: + return "LOOT_EPIC_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: + return "RECEIVE_EPIC_ITEM"; + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: + return "ROLL_NEED"; + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: + return "ROLL_GREED"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT: + return "HIT_DEALT"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED: + return "HIT_RECEIVED"; + case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED: + return "TOTAL_DAMAGE_RECEIVED"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED: + return "HIGHEST_HEAL_CASTED"; + case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED: + return "TOTAL_HEALING_RECEIVED"; + case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED: + return "HIGHEST_HEALING_RECEIVED"; + case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: + return "QUEST_ABANDONED"; + case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: + return "FLIGHT_PATHS_TAKEN"; + case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: + return "LOOT_TYPE"; + case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: + return "CAST_SPELL2"; + case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE: + return "LEARN_SKILL_LINE"; + case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL: + return "EARN_HONORABLE_KILL"; + case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: + return "ACCEPTED_SUMMONINGS"; + case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS: + return "EARN_ACHIEVEMENT_POINTS"; + case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS: + return "USE_LFD_TO_GROUP_WITH_PLAYERS"; + case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS: + return "SPENT_GOLD_GUILD_REPAIRS"; + case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL: + return "REACH_GUILD_LEVEL"; + case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: + return "CRAFT_ITEMS_GUILD"; + case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL: + return "CATCH_FROM_POOL"; + case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS: + return "BUY_GUILD_BANK_SLOTS"; + case ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS: + return "EARN_GUILD_ACHIEVEMENT_POINTS"; + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND: + return "WIN_RATED_BATTLEGROUND"; + case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING: + return "REACH_BG_RATING"; + case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD: + return "BUY_GUILD_TABARD"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD: + return "COMPLETE_QUESTS_GUILD"; + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD: + return "HONORABLE_KILLS_GUILD"; + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD: + return "KILL_CREATURE_TYPE_GUILD"; + default: + return "MISSING_TYPE"; + } + return ""; +} + template class AchievementMgr<Guild>; template class AchievementMgr<Player>; @@ -2828,18 +3035,18 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() uint32 guildCriterias = 0; for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId) { - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); + AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(entryId); if (!criteria) continue; - AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(criteria->achievement); - m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria); + m_AchievementCriteriaListByAchievement[criteria->achievement].push_back(criteria); if (achievement && achievement->flags & ACHIEVEMENT_FLAG_GUILD) - ++guildCriterias, m_GuildAchievementCriteriasByType[criteria->requiredType].push_back(criteria); + ++guildCriterias, m_GuildAchievementCriteriasByType[criteria->type].push_back(criteria); else - ++criterias, m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); + ++criterias, m_AchievementCriteriasByType[criteria->type].push_back(criteria); if (criteria->timeLimit) m_AchievementCriteriasByTimedType[criteria->timedCriteriaStartType].push_back(criteria); @@ -2862,7 +3069,7 @@ void AchievementGlobalMgr::LoadAchievementReferenceList() for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId) { - AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(entryId); if (!achievement || !achievement->refAchievement) continue; @@ -2871,7 +3078,7 @@ void AchievementGlobalMgr::LoadAchievementReferenceList() } // Once Bitten, Twice Shy (10 player) - Icecrown Citadel - if (AchievementEntry const* achievement = sAchievementStore.LookupEntry(4539)) + if (AchievementEntry const* achievement = sAchievementMgr->GetAchievement(4539)) const_cast<AchievementEntry*>(achievement)->mapID = 631; // Correct map requirement (currently has Ulduar) sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u achievement references in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); @@ -2898,7 +3105,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() Field* fields = result->Fetch(); uint32 criteria_id = fields[0].GetUInt32(); - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(criteria_id); + AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(criteria_id); if (!criteria) { @@ -2955,7 +3162,7 @@ void AchievementGlobalMgr::LoadCompletedAchievements() Field* fields = result->Fetch(); uint16 achievementId = fields[0].GetUInt16(); - const AchievementEntry* achievement = sAchievementStore.LookupEntry(achievementId); + const AchievementEntry* achievement = sAchievementMgr->GetAchievement(achievementId); if (!achievement) { // Remove non existent achievements from all characters @@ -2971,7 +3178,8 @@ void AchievementGlobalMgr::LoadCompletedAchievements() } else if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) m_allCompletedAchievements.insert(achievementId); - } while (result->NextRow()); + } + while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %lu completed achievements in %u ms", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime)); } @@ -2982,7 +3190,7 @@ void AchievementGlobalMgr::LoadRewards() m_achievementRewards.clear(); // need for reload case - // 0 1 2 3 4 5 6 + // 0 1 2 3 4 5 6 QueryResult result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text FROM achievement_reward"); if (!result) @@ -2997,10 +3205,10 @@ void AchievementGlobalMgr::LoadRewards() { Field* fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); - const AchievementEntry* pAchievement = sAchievementStore.LookupEntry(entry); + const AchievementEntry* pAchievement = GetAchievement(entry); if (!pAchievement) { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_reward` has wrong achievement (Entry: %u), ignore", entry); + sLog->outError(LOG_FILTER_SQL, "Table `achievement_reward` has wrong achievement (Entry: %u), ignored.", entry); continue; } @@ -3015,7 +3223,7 @@ void AchievementGlobalMgr::LoadRewards() // must be title or mail at least if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender) { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_reward` (Entry: %u) not have title or item reward data, ignore.", entry); + sLog->outError(LOG_FILTER_SQL, "Table `achievement_reward` (Entry: %u) does not have title or item reward data, ignored.", entry); continue; } @@ -3074,7 +3282,6 @@ void AchievementGlobalMgr::LoadRewards() m_achievementRewards[entry] = reward; ++count; - } while (result->NextRow()); @@ -3117,7 +3324,18 @@ void AchievementGlobalMgr::LoadRewardLocales() ObjectMgr::AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.subject); ObjectMgr::AddLocaleString(fields[1 + 2 * (i - 1) + 1].GetString(), locale, data.text); } - } while (result->NextRow()); + } + while (result->NextRow()); sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %lu achievement reward locale strings in %u ms", (unsigned long)m_achievementRewardLocales.size(), GetMSTimeDiffToNow(oldMSTime)); } + +AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementId) const +{ + return sAchievementStore.LookupEntry(achievementId); +} + +AchievementCriteriaEntry const* AchievementGlobalMgr::GetAchievementCriteria(uint32 criteriaId) const +{ + return sAchievementCriteriaStore.LookupEntry(criteriaId); +} diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index bcedbd09901..4196f6728fe 100755 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -15,6 +15,7 @@ * 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 __TRINITY_ACHIEVEMENTMGR_H #define __TRINITY_ACHIEVEMENTMGR_H @@ -67,6 +68,7 @@ enum AchievementCriteriaDataType #define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 22 // maximum value in AchievementCriteriaDataType enum class Player; class Unit; +class WorldPacket; struct AchievementCriteriaData { @@ -217,10 +219,6 @@ struct CompletedAchievementData typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap; typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap; -class Unit; -class Player; -class WorldPacket; - template<class T> class AchievementMgr { @@ -232,8 +230,8 @@ class AchievementMgr static void DeleteFromDB(uint32 lowguid); void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult); void SaveToDB(SQLTransaction& trans); - void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, bool evenIfCriteriaComplete = false); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL, Player* referencePlayer = NULL); + void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit const* unit = NULL, Player* referencePlayer = NULL); void CompletedAchievement(AchievementEntry const* entry, Player* referencePlayer); void CheckAllAchievementCriteria(Player* referencePlayer); void SendAllAchievementData(Player* receiver) const; @@ -255,9 +253,13 @@ class AchievementMgr void CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer); bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement); bool IsCompletedAchievement(AchievementEntry const* entry); - bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit, Player* referencePlayer); + bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer); void SendPacket(WorldPacket* data) const; + bool ConditionsSatisfied(AchievementCriteriaEntry const *criteria, Player* referencePlayer) const; + bool RequirementsSatisfied(AchievementCriteriaEntry const *criteria, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; + bool AdditionalRequirementsSatisfied(AchievementCriteriaEntry const* criteria, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; + T* _owner; CriteriaProgressMap m_criteriaProgress; CompletedAchievementMap m_completedAchievements; @@ -272,6 +274,9 @@ class AchievementGlobalMgr ~AchievementGlobalMgr() {} public: + static char const* GetCriteriaTypeString(AchievementCriteriaTypes type); + static char const* GetCriteriaTypeString(uint32 type); + AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type, bool guild = false) const { return guild ? m_GuildAchievementCriteriasByType[type] : m_AchievementCriteriasByType[type]; @@ -346,6 +351,8 @@ class AchievementGlobalMgr void LoadCompletedAchievements(); void LoadRewards(); void LoadRewardLocales(); + AchievementEntry const* GetAchievement(uint32 achievementId) const; + AchievementCriteriaEntry const* GetAchievementCriteria(uint32 achievementId) const; private: AchievementCriteriaDataMap m_criteriaDataMap; diff --git a/src/server/game/Addons/AddonMgr.h b/src/server/game/Addons/AddonMgr.h index 38338b3980f..fd227b258c5 100755 --- a/src/server/game/Addons/AddonMgr.h +++ b/src/server/game/Addons/AddonMgr.h @@ -25,13 +25,7 @@ struct AddonInfo { AddonInfo(const std::string& name, uint8 enabled, uint32 crc, uint8 state, bool crcOrPubKey) - { - Name = name; - Enabled = enabled; - CRC = crc; - State = state; - UsePublicKeyOrCRC = crcOrPubKey; - } + : Name(name), Enabled(enabled), CRC(crc), State(state), UsePublicKeyOrCRC(crcOrPubKey) {} std::string Name; uint8 Enabled; diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 99852f14277..ee976e0f704 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -34,6 +34,8 @@ Battlefield::Battlefield() { + m_Guid = MAKE_NEW_GUID(m_TypeId, 0, HIGHGUID_TYPE_BATTLEGROUND); + m_Timer = 0; m_IsEnabled = true; m_isActive = false; @@ -100,7 +102,7 @@ void Battlefield::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/) if (m_PlayersInWar[player->GetTeamId()].find(player->GetGUID()) != m_PlayersInWar[player->GetTeamId()].end()) { m_PlayersInWar[player->GetTeamId()].erase(player->GetGUID()); - player->GetSession()->SendBfLeaveMessage(m_BattleId); + player->GetSession()->SendBfLeaveMessage(m_Guid); if (Group* group = player->GetGroup()) // Remove the player from the raid group group->RemoveMember(player->GetGUID()); @@ -133,7 +135,7 @@ bool Battlefield::Update(uint32 diff) m_Timer -= diff; // Invite players a few minutes before the battle's beginning - if (!m_StartGrouping && m_Timer <= m_StartGroupingTimer) + if (!IsWarTime() && !m_StartGrouping && m_Timer <= m_StartGroupingTimer) { m_StartGrouping = true; InvitePlayersInZoneToQueue(); @@ -155,13 +157,13 @@ bool Battlefield::Update(uint32 diff) if (m_uiKickDontAcceptTimer <= diff) { for (int team = 0; team < 2; team++) - for (PlayerTimerMap::iterator itr = m_InvitedPlayers[team].begin(); itr != m_InvitedPlayers[team].end(); itr++) + for (PlayerTimerMap::iterator itr = m_InvitedPlayers[team].begin(); itr != m_InvitedPlayers[team].end(); ++itr) if ((*itr).second <= time(NULL)) KickPlayerFromBattlefield((*itr).first); InvitePlayersInZoneToWar(); for (int team = 0; team < 2; team++) - for (PlayerTimerMap::iterator itr = m_PlayersWillBeKick[team].begin(); itr != m_PlayersWillBeKick[team].end(); itr++) + for (PlayerTimerMap::iterator itr = m_PlayersWillBeKick[team].begin(); itr != m_PlayersWillBeKick[team].end(); ++itr) if ((*itr).second <= time(NULL)) KickPlayerFromBattlefield((*itr).first); @@ -203,7 +205,7 @@ void Battlefield::InvitePlayerToQueue(Player* player) return; if (m_PlayersInQueue[player->GetTeamId()].size() <= m_MinPlayer || m_PlayersInQueue[GetOtherTeam(player->GetTeamId())].size() >= m_MinPlayer) - player->GetSession()->SendBfInvitePlayerToQueue(m_BattleId); + player->GetSession()->SendBfInvitePlayerToQueue(m_Guid); } void Battlefield::InvitePlayersInQueueToWar() @@ -272,7 +274,7 @@ void Battlefield::InvitePlayerToWar(Player* player) m_PlayersWillBeKick[player->GetTeamId()].erase(player->GetGUID()); m_InvitedPlayers[player->GetTeamId()][player->GetGUID()] = time(NULL) + m_TimeForAcceptInvite; - player->GetSession()->SendBfInvitePlayerToWar(m_BattleId, m_ZoneId, m_TimeForAcceptInvite); + player->GetSession()->SendBfInvitePlayerToWar(m_Guid, m_ZoneId, m_TimeForAcceptInvite); } void Battlefield::InitStalker(uint32 entry, float x, float y, float z, float o) @@ -368,7 +370,7 @@ void Battlefield::PlayerAcceptInviteToQueue(Player* player) // Add player in queue m_PlayersInQueue[player->GetTeamId()].insert(player->GetGUID()); // Send notification - player->GetSession()->SendBfQueueInviteResponse(m_BattleId, m_ZoneId); + player->GetSession()->SendBfQueueInviteResponse(m_Guid, m_ZoneId); } // Called in WorldSession::HandleBfExitRequest @@ -386,7 +388,7 @@ void Battlefield::PlayerAcceptInviteToWar(Player* player) if (AddOrSetPlayerToCorrectBfGroup(player)) { - player->GetSession()->SendBfEntered(m_BattleId); + player->GetSession()->SendBfEntered(m_Guid); m_PlayersInWar[player->GetTeamId()].insert(player->GetGUID()); m_InvitedPlayers[player->GetTeamId()].erase(player->GetGUID()); @@ -862,7 +864,8 @@ BfCapturePoint::BfCapturePoint(Battlefield* battlefield) : m_Bf(battlefield), m_ { m_team = TEAM_NEUTRAL; m_value = 0; - m_maxValue = 0; + m_minValue = 0.0f; + m_maxValue = 0.0f; m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL; m_OldState = BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL; m_capturePointEntry = 0; diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 07daf33d431..175bb039744 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -239,6 +239,7 @@ class Battlefield : public ZoneScript uint32 GetTypeId() { return m_TypeId; } uint32 GetZoneId() { return m_ZoneId; } + uint64 GetGUID() { return m_Guid; } void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0); @@ -357,6 +358,8 @@ class Battlefield : public ZoneScript void InitStalker(uint32 entry, float x, float y, float z, float o); protected: + uint64 m_Guid; + uint64 StalkerGuid; uint32 m_Timer; // Global timer for event bool m_IsEnabled; diff --git a/src/server/game/Battlefield/BattlefieldHandler.cpp b/src/server/game/Battlefield/BattlefieldHandler.cpp index b852082d582..f16237b6e31 100644 --- a/src/server/game/Battlefield/BattlefieldHandler.cpp +++ b/src/server/game/Battlefield/BattlefieldHandler.cpp @@ -21,130 +21,298 @@ #include "ObjectMgr.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "Object.h" #include "Battlefield.h" #include "BattlefieldMgr.h" #include "Opcodes.h" //This send to player windows for invite player to join the war -//Param1:(BattleId) the BattleId of Bf +//Param1:(guid) the guid of Bf //Param2:(ZoneId) the zone where the battle is (4197 for wg) //Param3:(time) Time in second that the player have for accept -void WorldSession::SendBfInvitePlayerToWar(uint32 BattleId, uint32 ZoneId, uint32 p_time) +void WorldSession::SendBfInvitePlayerToWar(uint64 guid, uint32 zoneId, uint32 pTime) { - //Send packet - WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, 12); - data << uint32(BattleId); - data << uint32(ZoneId); - data << uint32((time(NULL) + p_time)); + ObjectGuid guidBytes = guid; + + WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, 16); + + data.WriteBit(guidBytes[5]); + data.WriteBit(guidBytes[3]); + data.WriteBit(guidBytes[7]); + data.WriteBit(guidBytes[2]); + data.WriteBit(guidBytes[6]); + data.WriteBit(guidBytes[4]); + data.WriteBit(guidBytes[1]); + data.WriteBit(guidBytes[0]); + + data.WriteByteSeq(guidBytes[6]); + data << uint32(zoneId); // Zone Id + data.WriteByteSeq(guidBytes[1]); + data.WriteByteSeq(guidBytes[3]); + data.WriteByteSeq(guidBytes[4]); + data.WriteByteSeq(guidBytes[2]); + data.WriteByteSeq(guidBytes[0]); + data << uint32(time(NULL) + pTime); // Invite lasts until + data.WriteByteSeq(guidBytes[7]); + data.WriteByteSeq(guidBytes[5]); //Sending the packet to player SendPacket(&data); } //This send invitation to player to join the queue -//Param1:(BattleId) the BattleId of Bf -void WorldSession::SendBfInvitePlayerToQueue(uint32 BattleId) +void WorldSession::SendBfInvitePlayerToQueue(uint64 guid) { + ObjectGuid guidBytes = guid; + WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, 5); - data << uint32(BattleId); - data << uint8(1); //warmup ? used ? + data.WriteBit(1); // unk + data.WriteBit(0); // Has Warmup + data.WriteBit(1); // unk + data.WriteBit(guidBytes[0]); + data.WriteBit(1); // unk + data.WriteBit(guidBytes[2]); + data.WriteBit(guidBytes[6]); + data.WriteBit(guidBytes[3]); + data.WriteBit(1); // unk + data.WriteBit(0); // unk + data.WriteBit(guidBytes[1]); + data.WriteBit(guidBytes[5]); + data.WriteBit(guidBytes[4]); + data.WriteBit(1); // unk + data.WriteBit(guidBytes[7]); + + data.FlushBits(); + + data.WriteByteSeq(guidBytes[2]); + data.WriteByteSeq(guidBytes[3]); + data.WriteByteSeq(guidBytes[6]); + data << uint8(1); // Warmup + data.WriteByteSeq(guidBytes[5]); + data.WriteByteSeq(guidBytes[0]); + data.WriteByteSeq(guidBytes[4]); + data.WriteByteSeq(guidBytes[1]); + data.WriteByteSeq(guidBytes[7]); //Sending packet to player SendPacket(&data); } //This send packet for inform player that he join queue -//Param1:(BattleId) the BattleId of Bf +//Param1:(guid) the guid of Bf //Param2:(ZoneId) the zone where the battle is (4197 for wg) //Param3:(CanQueue) if able to queue //Param4:(Full) on log in is full -void WorldSession::SendBfQueueInviteResponse(uint32 BattleId,uint32 ZoneId, bool CanQueue, bool Full) +void WorldSession::SendBfQueueInviteResponse(uint64 guid, uint32 ZoneId, bool CanQueue, bool Full) { - WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 11); - data << uint32(BattleId); + const bool hasSecondGuid = false; + const bool warmup = true; + ObjectGuid guidBytes = guid; + + WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 16); + + data.WriteBit(guidBytes[1]); + data.WriteBit(guidBytes[6]); + data.WriteBit(guidBytes[5]); + data.WriteBit(guidBytes[7]); + data.WriteBit(Full); // Logging In, VERIFYME + data.WriteBit(guidBytes[0]); + data.WriteBit(!hasSecondGuid); + data.WriteBit(guidBytes[4]); + + // if (hasSecondGuid) 7 3 0 4 2 6 1 5 + + data.WriteBit(guidBytes[3]); + data.WriteBit(guidBytes[2]); + + // if (hasSecondGuid) 2 5 3 0 4 6 1 7 + + data.FlushBits(); + + data << uint8(CanQueue); // Accepted + + data.WriteByteSeq(guidBytes[1]); + data.WriteByteSeq(guidBytes[3]); + data.WriteByteSeq(guidBytes[6]); + data.WriteByteSeq(guidBytes[7]); + data.WriteByteSeq(guidBytes[0]); + + data << uint8(warmup); + + data.WriteByteSeq(guidBytes[2]); + data.WriteByteSeq(guidBytes[4]); + data.WriteByteSeq(guidBytes[5]); + data << uint32(ZoneId); - data << uint8((CanQueue ? 1 : 0)); //Accepted //0 you cannot queue wg //1 you are queued - data << uint8((Full ? 0 : 1)); //Logging In //0 wg full //1 queue for upcoming - data << uint8(1); //Warmup + SendPacket(&data); } //This is call when player accept to join war -//Param1:(BattleId) the BattleId of Bf -void WorldSession::SendBfEntered(uint32 BattleId) +void WorldSession::SendBfEntered(uint64 guid) { -// m_PlayerInWar[player->GetTeamId()].insert(player->GetGUID()); - WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 7); - data << uint32(BattleId); - data << uint8(1); //unk - data << uint8(1); //unk - data << uint8(_player->isAFK() ? 1 : 0); //Clear AFK + uint8 isAFK = _player->isAFK() ? 1 : 0; + ObjectGuid guidBytes = guid; + + WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 11); + + data.WriteBit(0); // unk + data.WriteBit(isAFK); // Clear AFK + data.WriteBit(guidBytes[1]); + data.WriteBit(guidBytes[4]); + data.WriteBit(guidBytes[5]); + data.WriteBit(guidBytes[0]); + data.WriteBit(guidBytes[3]); + data.WriteBit(0); // unk + data.WriteBit(guidBytes[6]); + data.WriteBit(guidBytes[7]); + data.WriteBit(guidBytes[2]); + + data.FlushBits(); + + data.WriteByteSeq(guidBytes[5]); + data.WriteByteSeq(guidBytes[3]); + data.WriteByteSeq(guidBytes[0]); + data.WriteByteSeq(guidBytes[4]); + data.WriteByteSeq(guidBytes[1]); + data.WriteByteSeq(guidBytes[7]); + data.WriteByteSeq(guidBytes[2]); + data.WriteByteSeq(guidBytes[6]); + SendPacket(&data); } -void WorldSession::SendBfLeaveMessage(uint32 BattleId, BFLeaveReason reason) +void WorldSession::SendBfLeaveMessage(uint64 guid, BFLeaveReason reason) { - WorldPacket data(SMSG_BATTLEFIELD_MGR_EJECTED, 7); - data << uint32(BattleId); - data << uint8(reason);//byte Reason - data << uint8(2);//byte BattleStatus - data << uint8(0);//bool Relocated + ObjectGuid guidBytes = guid; + + WorldPacket data(SMSG_BATTLEFIELD_MGR_EJECTED, 11); + + data.WriteBit(guidBytes[2]); + data.WriteBit(guidBytes[5]); + data.WriteBit(guidBytes[1]); + data.WriteBit(guidBytes[0]); + data.WriteBit(guidBytes[3]); + data.WriteBit(guidBytes[6]); + data.WriteBit(0); // Relocated + data.WriteBit(guidBytes[7]); + data.WriteBit(guidBytes[4]); + + data.FlushBits(); + + data << uint8(2); // BattleStatus + data.WriteByteSeq(guidBytes[1]); + data.WriteByteSeq(guidBytes[7]); + data.WriteByteSeq(guidBytes[4]); + data.WriteByteSeq(guidBytes[2]); + data.WriteByteSeq(guidBytes[3]); + data << uint8(reason); // Reason + data.WriteByteSeq(guidBytes[6]); + data.WriteByteSeq(guidBytes[0]); + data.WriteByteSeq(guidBytes[5]); + SendPacket(&data); } //Send by client when he click on accept for queue -void WorldSession::HandleBfQueueInviteResponse(WorldPacket & recv_data) +void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData) { - uint32 BattleId; - uint8 Accepted; + uint8 accepted; + ObjectGuid guid; + + guid[2] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + accepted = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[5]); - recv_data >> BattleId >> Accepted; - sLog->outError(LOG_FILTER_GENERAL, "HandleQueueInviteResponse: BattleID:%u Accepted:%u", BattleId, Accepted); - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); - if (!Bf) + sLog->outError(LOG_FILTER_GENERAL, "HandleQueueInviteResponse: GUID:"UI64FMTD" Accepted:%u", (uint64)guid, accepted); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid); + if (!bf) return; - if (Accepted) - { - Bf->PlayerAcceptInviteToQueue(_player); - } + if (accepted) + bf->PlayerAcceptInviteToQueue(_player); } //Send by client on clicking in accept or refuse of invitation windows for join game -void WorldSession::HandleBfEntryInviteResponse(WorldPacket & recv_data) +void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData) { - uint32 BattleId; - uint8 Accepted; + uint8 accepted; + ObjectGuid guid; + + guid[6] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + accepted = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[2] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[5]); + + sLog->outError(LOG_FILTER_GENERAL, "HandleBattlefieldInviteResponse: GUID:"UI64FMTD" Accepted:%u", (uint64)guid, accepted); - recv_data >> BattleId >> Accepted; - sLog->outError(LOG_FILTER_GENERAL, "HandleBattlefieldInviteResponse: BattleID:%u Accepted:%u", BattleId, Accepted); - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); - if (!Bf) + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid); + if (!bf) return; - //If player accept invitation - if (Accepted) - { - Bf->PlayerAcceptInviteToWar(_player); - } + if (accepted) + bf->PlayerAcceptInviteToWar(_player); else - { - if (_player->GetZoneId() == Bf->GetZoneId()) - Bf->KickPlayerFromBattlefield(_player->GetGUID()); - } + if (_player->GetZoneId() == bf->GetZoneId()) + bf->KickPlayerFromBattlefield(_player->GetGUID()); } -void WorldSession::HandleBfExitRequest(WorldPacket & recv_data) +void WorldSession::HandleBfExitRequest(WorldPacket& recvData) { - uint32 BattleId; + ObjectGuid guid; - recv_data >> BattleId; - sLog->outError(LOG_FILTER_GENERAL, "HandleBfExitRequest: BattleID:%u ", BattleId); - Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); - if (!Bf) - return; + guid[2] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[5]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[6]); + + sLog->outError(LOG_FILTER_GENERAL, "HandleBfExitRequest: GUID:"UI64FMTD" ", (uint64)guid); - Bf->AskToLeaveQueue(_player); + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid)) + bf->AskToLeaveQueue(_player); } diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 6122b25e8e8..d2ecf43ee9b 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -118,6 +118,15 @@ Battlefield *BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleid) return NULL; } +Battlefield* BattlefieldMgr::GetBattlefieldByGUID(uint64 guid) +{ + for (BattlefieldSet::iterator itr = m_BattlefieldSet.begin(); itr != m_BattlefieldSet.end(); ++itr) + if ((*itr)->GetGUID() == guid) + return (*itr); + + return NULL; +} + void BattlefieldMgr::Update(uint32 diff) { m_UpdateTimer += diff; diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h index 4ee37e424fd..b448cd4ead2 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.h +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -48,6 +48,7 @@ class BattlefieldMgr // return assigned battlefield Battlefield *GetBattlefieldToZoneId(uint32 zoneid); Battlefield *GetBattlefieldByBattleId(uint32 battleid); + Battlefield *GetBattlefieldByGUID(uint64 guid); ZoneScript *GetZoneScript(uint32 zoneId); diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 634b1bb2cea..09783176094 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -25,12 +25,6 @@ #include "SpellAuras.h" #include "Vehicle.h" -enum WintergrastData -{ - BATTLEFIELD_WG_ZONEID = 4197, // Wintergrasp - BATTLEFIELD_WG_MAPID = 571, // Northrend -}; - enum WGVehicles { NPC_WG_SEIGE_ENGINE_ALLIANCE = 28312, @@ -39,6 +33,12 @@ enum WGVehicles NPC_WG_CATAPULT = 27881, }; +BattlefieldWG::~BattlefieldWG() +{ + for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) + delete *itr; +} + bool BattlefieldWG::SetupBattlefield() { InitStalker(BATTLEFIELD_WG_NPC_STALKER, WintergraspStalkerPos[0], WintergraspStalkerPos[1], WintergraspStalkerPos[2], WintergraspStalkerPos[3]); @@ -172,6 +172,8 @@ bool BattlefieldWG::SetupBattlefield() GameObject* go = SpawnGameObject(WGGameObjectBuilding[i].entry, WGGameObjectBuilding[i].x, WGGameObjectBuilding[i].y, WGGameObjectBuilding[i].z, WGGameObjectBuilding[i].o); BfWGGameObjectBuilding* b = new BfWGGameObjectBuilding(this); b->Init(go, WGGameObjectBuilding[i].type, WGGameObjectBuilding[i].WorldState, WGGameObjectBuilding[i].nameId); + if (!IsEnabled() && go->GetEntry() == GO_WINTERGRASP_VAULT_GATE) + go->SetDestructibleState(GO_DESTRUCTIBLE_DESTROYED); BuildingsInZone.insert(b); } @@ -538,7 +540,6 @@ void BattlefieldWG::OnCreatureCreate(Creature* creature) { UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, 1); creature->AddAura(SPELL_HORDE_FLAG, creature); - creature->setFaction(creator->getFaction()); m_vehicles[team].insert(creature->GetGUID()); UpdateVehicleCountWG(); } @@ -555,7 +556,6 @@ void BattlefieldWG::OnCreatureCreate(Creature* creature) { UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, 1); creature->AddAura(SPELL_ALLIANCE_FLAG, creature); - creature->setFaction(creator->getFaction()); m_vehicles[team].insert(creature->GetGUID()); UpdateVehicleCountWG(); } @@ -1084,10 +1084,12 @@ WintergraspCapturePoint::WintergraspCapturePoint(BattlefieldWG* battlefield, Tea { m_Bf = battlefield; m_team = teamInControl; + m_Workshop = NULL; } void WintergraspCapturePoint::ChangeTeam(TeamId /*oldTeam*/) { + ASSERT(m_Workshop); m_Workshop->GiveControlTo(m_team, false); } diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index be062704b52..734154020d9 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -29,7 +29,7 @@ uint32 const VehNumWorldState[2] = { 3680, 3490 }; uint32 const MaxVehNumWorldState[2] = { 3681, 3491 }; uint32 const ClockWorldState[2] = { 3781, 4354 }; -uint32 const WintergraspFaction[3] = { 1, 2, 35 }; +uint32 const WintergraspFaction[3] = { 1732, 1735, 35 }; float const WintergraspStalkerPos[4] = { 0, 0, 0, 0 }; class BattlefieldWG; @@ -44,6 +44,12 @@ typedef std::set<WGWorkshop*> Workshop; typedef std::set<Group*> GroupSet; //typedef std::set<WintergraspCapturePoint *> CapturePointSet; unused ? +enum WintergrastData +{ + BATTLEFIELD_WG_ZONEID = 4197, // Wintergrasp + BATTLEFIELD_WG_MAPID = 571, // Northrend +}; + enum WintergraspSpells { // Wartime auras @@ -273,6 +279,7 @@ class WintergraspCapturePoint : public BfCapturePoint class BattlefieldWG : public Battlefield { public: + ~BattlefieldWG(); /** * \brief Called when the battle start * - Spawn relic and turret @@ -434,7 +441,6 @@ class BattlefieldWG : public Battlefield GameObject* m_titansRelic; }; -uint32 const NORTHREND_WINTERGRASP = 4197; uint8 const WG_MAX_OBJ = 32; uint8 const WG_KEEPGAMEOBJECT_MAX = 44; uint8 const WG_MAX_TURRET = 15; @@ -539,6 +545,12 @@ enum WintergraspGameObject GO_WINTERGRASP_SHADOWSIGHT_TOWER = 190356, GO_WINTERGRASP_WINTER_S_EDGE_TOWER = 190357, GO_WINTERGRASP_FLAMEWATCH_TOWER = 190358, + + GO_WINTERGRASP_FORTRESS_GATE = 190375, + GO_WINTERGRASP_VAULT_GATE = 191810, + + GO_WINTERGRASP_KEEP_COLLISION_WALL = 194323, + }; struct WintergraspObjectPositionData @@ -609,10 +621,10 @@ const WintergraspBuildingSpawnData WGGameObjectBuilding[WG_MAX_OBJ] = { 190358, 3706, 4459.1f, 1944.33f, 434.991f, -2.00276f, BATTLEFIELD_WG_OBJECTTYPE_TOWER, BATTLEFIELD_WG_TEXT_TOWER_NAME_E }, // Door of forteress (Not spawned in db) - { 190375, 3763, 5162.99f, 2841.23f, 410.162f, -3.13286f, BATTLEFIELD_WG_OBJECTTYPE_DOOR, 0 }, + { GO_WINTERGRASP_FORTRESS_GATE, 3763, 5162.99f, 2841.23f, 410.162f, -3.13286f, BATTLEFIELD_WG_OBJECTTYPE_DOOR, 0 }, // Last door (Not spawned in db) - { 191810, 3773, 5397.11f, 2841.54f, 425.899f, 3.14159f, BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST, 0 }, + { GO_WINTERGRASP_VAULT_GATE, 3773, 5397.11f, 2841.54f, 425.899f, 3.14159f, BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST, 0 }, }; @@ -1195,6 +1207,9 @@ struct BfWGGameObjectBuilding if (m_Build->IsDestructibleBuilding()) { m_Build->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, NULL, true); + if (m_Build->GetEntry() == GO_WINTERGRASP_VAULT_GATE) + if (GameObject* go = m_Build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 10.0f)) + go->EnableCollision(true); // Update worldstate m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT - (m_Team * 3); @@ -1250,6 +1265,8 @@ struct BfWGGameObjectBuilding m_WG->UpdatedDestroyedTowerCount(TeamId(m_Team)); break; case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: + if (GameObject* go = m_Build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 10.0f)) + go->EnableCollision(false); m_WG->SetRelicInteractible(true); if (m_WG->GetRelic()) m_WG->GetRelic()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); @@ -1403,7 +1420,7 @@ struct BfWGGameObjectBuilding { Position towerCannonPos; TowerCannon[towerid].TurretTop[i].GetPosition(&towerCannonPos); - if (Creature *turret = m_WG->SpawnCreature(28366, towerCannonPos, TeamId(0))) + if (Creature* turret = m_WG->SpawnCreature(28366, towerCannonPos, TeamId(0))) { m_TurretTopList.insert(turret->GetGUID()); switch (go->GetEntry()) @@ -1473,17 +1490,17 @@ struct BfWGGameObjectBuilding switch (m_Build->GetEntry()) { - case 190221: - case 190373: - case 190377: - case 190378: + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: { creature->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); break; } - case 190356: - case 190357: - case 190358: + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: { creature->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); break; @@ -1509,17 +1526,17 @@ struct BfWGGameObjectBuilding switch (m_Build->GetEntry()) { - case 190221: - case 190373: - case 190377: - case 190378: + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: { creature->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); break; } - case 190356: - case 190357: - case 190358: + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: { creature->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); break; @@ -1643,9 +1660,9 @@ struct WintergraspWorkshopData // Spawning Associate gameobject and store them void AddGameObject(WintergraspObjectPositionData obj) { - if (GameObject *gameobject = m_WG->SpawnGameObject(obj.entryHorde, obj.x, obj.y, obj.z, obj.o)) + if (GameObject* gameobject = m_WG->SpawnGameObject(obj.entryHorde, obj.x, obj.y, obj.z, obj.o)) m_GameObjectOnPoint[TEAM_HORDE].insert(gameobject); - if (GameObject *gameobject = m_WG->SpawnGameObject(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o)) + if (GameObject* gameobject = m_WG->SpawnGameObject(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o)) m_GameObjectOnPoint[TEAM_ALLIANCE].insert(gameobject); } diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 61b15bdd182..e88c501398e 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -24,16 +24,9 @@ #include "ArenaTeamMgr.h" ArenaTeam::ArenaTeam() + : TeamId(0), Type(0), TeamName(), CaptainGuid(0), BackgroundColor(0), EmblemStyle(0), EmblemColor(0), + BorderStyle(0), BorderColor(0) { - TeamId = 0; - Type = 0; - TeamName = ""; - CaptainGuid = 0; - BackgroundColor = 0; - EmblemStyle = 0; - EmblemColor = 0; - BorderStyle = 0; - BorderColor = 0; Stats.WeekGames = 0; Stats.SeasonGames = 0; Stats.Rank = 0; @@ -343,7 +336,7 @@ void ArenaTeam::Disband(WorldSession* session) // Broadcast update if (session) { - BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName().c_str(), GetName(), ""); + BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName(), GetName(), ""); if (Player* player = session->GetPlayer()) sLog->outInfo(LOG_FILTER_ARENAS, "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 98b95b5d32b..ab69ed40943 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -131,6 +131,7 @@ void Battleground::BroadcastWorker(Do& _do) Battleground::Battleground() { + m_Guid = MAKE_NEW_GUID(m_TypeID, 0, HIGHGUID_TYPE_BATTLEGROUND); m_TypeID = BATTLEGROUND_TYPE_NONE; m_RandomTypeID = BATTLEGROUND_TYPE_NONE; m_InstanceID = 0; @@ -493,7 +494,7 @@ inline void Battleground::_ProcessJoin(uint32 diff) WorldPacket status; BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, player, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType()); player->GetSession()->SendPacket(&status); player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION); @@ -914,7 +915,7 @@ void Battleground::EndBattleground(uint32 winner) player->GetSession()->SendPacket(&data); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType()); player->GetSession()->SendPacket(&data); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } @@ -1020,7 +1021,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac if (SendPacket) { WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0); player->GetSession()->SendPacket(&data); } @@ -1144,14 +1145,14 @@ void Battleground::AddPlayer(Player* player) UpdatePlayersCountByTeam(team, false); // +1 player WorldPacket data; - sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player); + sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player->GetGUID()); SendPacketToTeam(team, &data, player, false); // BG Status packet WorldPacket status; BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType()); uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), isArena() ? 0 : 1); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, player, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), isArena() ? 0 : 1); player->GetSession()->SendPacket(&status); player->RemoveAurasByType(SPELL_AURA_MOUNTED); @@ -1860,7 +1861,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player) sBattlegroundMgr->BuildPvpLogDataPacket(&data, this); player->GetSession()->SendPacket(&data); - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType()); player->GetSession()->SendPacket(&data); } diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 234cda4105c..29523864329 100755 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -133,12 +133,12 @@ enum BattlegroundBuffObjects enum BattlegroundRandomRewards { - BG_REWARD_WINNER_HONOR_FIRST = 30, - BG_REWARD_WINNER_ARENA_FIRST = 25, - BG_REWARD_WINNER_HONOR_LAST = 15, - BG_REWARD_WINNER_ARENA_LAST = 0, - BG_REWARD_LOSER_HONOR_FIRST = 5, - BG_REWARD_LOSER_HONOR_LAST = 5 + BG_REWARD_WINNER_HONOR_FIRST = 270, + BG_REWARD_WINNER_CONQUEST_FIRST = 100, + BG_REWARD_WINNER_HONOR_LAST = 135, + BG_REWARD_WINNER_CONQUEST_LAST = 50, + BG_REWARD_LOSER_HONOR_FIRST = 45, + BG_REWARD_LOSER_HONOR_LAST = 35 }; const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY }; @@ -342,6 +342,7 @@ class Battleground /* Battleground */ // Get methods: char const* GetName() const { return m_Name; } + uint64 GetGUID() { return m_Guid; } BattlegroundTypeId GetTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_TypeID; } BattlegroundBracketId GetBracketId() const { return m_BracketId; } uint32 GetInstanceID() const { return m_InstanceID; } @@ -635,6 +636,7 @@ class Battleground bool m_PrematureCountDown; uint32 m_PrematureCountDownTimer; char const* m_Name; + uint64 m_Guid; /* Pre- and post-update hooks */ diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 86b06de2cec..afc63ed6704 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -180,102 +180,275 @@ void BattlegroundMgr::Update(uint32 diff) } } -void BattlegroundMgr::BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype, uint8 uiFrame) +void BattlegroundMgr::BuildBattlegroundStatusPacket(WorldPacket *data, Battleground *bg, Player * pPlayer, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype, uint8 uiFrame) { - // we can be in 2 queues in same time... + if (!bg) + StatusID = STATUS_NONE; - if (StatusID == 0 || !bg) - { - data->Initialize(SMSG_BATTLEFIELD_STATUS, 4+8); - *data << uint32(QueueSlot); // queue id (0...1) - *data << uint64(0); - return; - } + ObjectGuid guidBytes1 = pPlayer->GetGUID(); + ObjectGuid guidBytes2 = bg->GetGUID(); - data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+8+1+1+4+1+4+4+4)); - *data << uint32(QueueSlot); // queue id (0...1) - player can be in 2 queues in time - // The following segment is read as uint64 in client but can be appended as their original type. - *data << uint8(arenatype); - sLog->outDebug(LOG_FILTER_NETWORKIO, "BattlegroundMgr::BuildBattlegroundStatusPacket: arenatype = %u for bg instanceID %u, TypeID %u.", arenatype, bg->GetClientInstanceID(), bg->GetTypeID()); - *data << uint8(bg->isArena() ? 0xC : 0x2); - *data << uint32(bg->GetTypeID()); - *data << uint16(0x1F90); - // End of uint64 segment, decomposed this way for simplicity - *data << uint8(0); // 3.3.0, some level, only saw 80... - *data << uint8(0); // 3.3.0, some level, only saw 80... - *data << uint32(bg->GetClientInstanceID()); - // alliance/horde for BG and skirmish/rated for Arenas - // following displays the minimap-icon 0 = faction icon 1 = arenaicon - *data << uint8(bg->isRated()); // 1 for rated match, 0 for bg or non rated match - - *data << uint32(StatusID); // status switch (StatusID) { - case STATUS_WAIT_QUEUE: // status_in_queue - *data << uint32(Time1); // average wait time, milliseconds - *data << uint32(Time2); // time in queue, updated every minute!, milliseconds + case STATUS_NONE: + { + //data->Initialize(SMSG_BATTLEFIELD_STATUS_FAILED); + sLog->outDebug(LOG_FILTER_NETWORKIO, ">>>>> STATUS_NONE"); break; - case STATUS_WAIT_JOIN: // status_invite - *data << uint32(bg->GetMapId()); // map id - *data << uint64(0); // 3.3.5, unknown - *data << uint32(Time1); // time to remove from queue, milliseconds + } + case STATUS_WAIT_QUEUE: + { + data->Initialize(SMSG_BATTLEFIELD_STATUS_QUEUED); + + data->WriteBit(guidBytes1[3]); + data->WriteBit(guidBytes1[0]); + data->WriteBit(guidBytes2[3]); + data->WriteBit(guidBytes1[2]); + data->WriteBit(0); // unk + data->WriteBit(0); // Join Failed + data->WriteBit(guidBytes2[2]); + data->WriteBit(guidBytes1[1]); + data->WriteBit(guidBytes2[0]); + data->WriteBit(guidBytes2[6]); + data->WriteBit(guidBytes2[4]); + data->WriteBit(guidBytes1[6]); + data->WriteBit(guidBytes1[7]); + data->WriteBit(guidBytes2[7]); + data->WriteBit(guidBytes2[5]); + data->WriteBit(guidBytes1[4]); + data->WriteBit(guidBytes1[5]); + data->WriteBit(0); // unk + data->WriteBit(0); // unk + data->WriteBit(guidBytes2[1]); + + data->FlushBits(); + + data->WriteByteSeq(guidBytes1[0]); + *data << uint32(0); // unk + data->WriteByteSeq(guidBytes2[5]); + data->WriteByteSeq(guidBytes1[3]); + *data << uint32(0); // unk + data->WriteByteSeq(guidBytes2[7]); + data->WriteByteSeq(guidBytes2[1]); + data->WriteByteSeq(guidBytes2[2]); + *data << uint8(0); // unk + data->WriteByteSeq(guidBytes2[4]); + data->WriteByteSeq(guidBytes1[2]); + *data << uint8(0); // unk + data->WriteByteSeq(guidBytes2[6]); + data->WriteByteSeq(guidBytes1[7]); + data->WriteByteSeq(guidBytes2[3]); + data->WriteByteSeq(guidBytes1[6]); + data->WriteByteSeq(guidBytes2[0]); + *data << uint32(bg->GetStartTime()); // Time + *data << uint32(0); // unk + *data << uint8(bg->GetMinLevel()); // Min Level + *data << uint32(0); // unk + data->WriteByteSeq(guidBytes1[1]); + data->WriteByteSeq(guidBytes1[5]); + *data << uint32(0); // unk + data->WriteByteSeq(guidBytes1[4]); + break; - case STATUS_IN_PROGRESS: // status_in_progress - *data << uint32(bg->GetMapId()); // map id - *data << uint64(0); // 3.3.5, unknown - *data << uint32(Time1); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds - *data << uint32(Time2); // time from bg start, milliseconds - *data << uint8(uiFrame); + } + case STATUS_WAIT_JOIN: + { + data->Initialize(SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION, 44); + + *data << uint32(bg->GetClientInstanceID()); // Client Instance ID + *data << uint32(Time1); // Time until closed + *data << uint8(0); // unk + *data << uint32(QueueSlot); // Queue slot + *data << uint32(Time2); // Time + *data << uint8(bg->GetMinLevel()); // Min Level + *data << uint32(bg->GetStatus()); // Status + *data << uint32(bg->GetMapId()); // Map Id + *data << uint8(0); // unk + + data->WriteBit(guidBytes1[5]); + data->WriteBit(guidBytes1[2]); + data->WriteBit(guidBytes1[1]); + data->WriteBit(guidBytes2[2]); + data->WriteBit(guidBytes1[4]); + data->WriteBit(guidBytes2[6]); + data->WriteBit(guidBytes2[3]); + data->WriteBit(bg->isRated()); // Is Rated + data->WriteBit(guidBytes1[7]); + data->WriteBit(guidBytes1[3]); + data->WriteBit(guidBytes2[7]); + data->WriteBit(guidBytes2[0]); + data->WriteBit(guidBytes2[4]); + data->WriteBit(guidBytes1[6]); + data->WriteBit(guidBytes2[1]); + data->WriteBit(guidBytes2[5]); + data->WriteBit(guidBytes1[0]); + + data->FlushBits(); + + data->WriteByteSeq(guidBytes2[6]); + data->WriteByteSeq(guidBytes2[5]); + data->WriteByteSeq(guidBytes2[7]); + data->WriteByteSeq(guidBytes2[0]); + data->WriteByteSeq(guidBytes1[0]); + data->WriteByteSeq(guidBytes1[7]); + data->WriteByteSeq(guidBytes2[4]); + data->WriteByteSeq(guidBytes1[1]); + data->WriteByteSeq(guidBytes2[0]); + data->WriteByteSeq(guidBytes1[4]); + data->WriteByteSeq(guidBytes2[1]); + data->WriteByteSeq(guidBytes1[5]); + data->WriteByteSeq(guidBytes2[3]); + data->WriteByteSeq(guidBytes1[6]); + data->WriteByteSeq(guidBytes1[2]); + data->WriteByteSeq(guidBytes1[3]); break; - default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "Unknown BG status!"); + } + case STATUS_IN_PROGRESS: + { + data->Initialize(SMSG_BATTLEFIELD_STATUS_ACTIVE, 49); + + data->WriteBit(guidBytes1[2]); + data->WriteBit(guidBytes1[7]); + data->WriteBit(guidBytes2[7]); + data->WriteBit(guidBytes2[1]); + data->WriteBit(guidBytes1[5]); + data->WriteBit(0); // Unk + data->WriteBit(guidBytes2[0]); + data->WriteBit(guidBytes1[1]); + data->WriteBit(guidBytes2[3]); + data->WriteBit(guidBytes1[6]); + data->WriteBit(guidBytes2[5]); + data->WriteBit(0); // Unk Bit 64 + data->WriteBit(guidBytes1[4]); + data->WriteBit(guidBytes2[6]); + data->WriteBit(guidBytes2[4]); + data->WriteBit(guidBytes2[2]); + data->WriteBit(guidBytes1[3]); + data->WriteBit(guidBytes1[0]); + + data->FlushBits(); + + data->WriteByteSeq(guidBytes2[4]); + data->WriteByteSeq(guidBytes2[5]); + data->WriteByteSeq(guidBytes1[5]); + data->WriteByteSeq(guidBytes2[1]); + data->WriteByteSeq(guidBytes2[6]); + data->WriteByteSeq(guidBytes2[3]); + data->WriteByteSeq(guidBytes2[7]); + data->WriteByteSeq(guidBytes1[6]); + + *data << uint32(Time2); // Time + *data << uint8(bg->GetPlayersCountByTeam(bg->GetPlayerTeam(pPlayer->GetGUID()))); // Teamsize + + data->WriteByteSeq(guidBytes1[4]); + data->WriteByteSeq(guidBytes1[1]); + + *data << uint32(QueueSlot); // Queue slot + *data << uint8(bg->GetMaxLevel()); // Max Level + *data << uint32(bg->GetStatus()); // Status + *data << uint32(bg->GetMapId()); // Map Id + *data << uint8(bg->GetMinLevel()); // Min Level + *data << uint32(Time1); // Time until closed + + data->WriteByteSeq(guidBytes1[2]); + + *data << uint32(bg->GetStartTime()); // Time since started + + data->WriteByteSeq(guidBytes1[0]); + data->WriteByteSeq(guidBytes1[3]); + data->WriteByteSeq(guidBytes1[2]); + + *data << uint32(bg->GetClientInstanceID()); // Client Instance ID + + data->WriteByteSeq(guidBytes2[0]); + data->WriteByteSeq(guidBytes1[7]); break; + } + case STATUS_WAIT_LEAVE: + { + data->Initialize(SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS, 48); + + *data << uint8(0); // unk + *data << uint32(bg->GetStatus()); // Status + *data << uint32(QueueSlot); // Queue slot + *data << uint32(Time1); // Time until closed + *data << uint32(0); // unk + *data << uint8(0); // unk + *data << uint8(0); // unk + *data << uint8(bg->GetMinLevel()); // Min Level + *data << uint8(0); // unk + *data << uint8(0); // unk + *data << uint32(bg->GetMapId()); // Map Id + *data << uint32(Time2); // Time + *data << uint8(0); // unk + + data->WriteBit(guidBytes2[0]); + data->WriteBit(guidBytes2[1]); + data->WriteBit(guidBytes2[7]); + data->WriteBit(guidBytes1[7]); + data->WriteBit(guidBytes1[0]); + data->WriteBit(guidBytes2[4]); + data->WriteBit(guidBytes1[6]); + data->WriteBit(guidBytes1[2]); + data->WriteBit(guidBytes1[3]); + data->WriteBit(guidBytes2[3]); + data->WriteBit(guidBytes1[4]); + data->WriteBit(guidBytes2[5]); + data->WriteBit(guidBytes1[5]); + data->WriteBit(guidBytes2[2]); + data->WriteBit(bg->isRated()); // Is Rated + data->WriteBit(guidBytes1[1]); + data->WriteBit(guidBytes2[6]); + + data->FlushBits(); + + data->WriteByteSeq(guidBytes1[0]); + data->WriteByteSeq(guidBytes2[4]); + data->WriteByteSeq(guidBytes1[3]); + data->WriteByteSeq(guidBytes2[1]); + data->WriteByteSeq(guidBytes2[0]); + data->WriteByteSeq(guidBytes2[2]); + data->WriteByteSeq(guidBytes1[2]); + data->WriteByteSeq(guidBytes2[7]); + data->WriteByteSeq(guidBytes1[1]); + data->WriteByteSeq(guidBytes1[6]); + data->WriteByteSeq(guidBytes2[6]); + data->WriteByteSeq(guidBytes2[5]); + data->WriteByteSeq(guidBytes1[5]); + data->WriteByteSeq(guidBytes1[4]); + data->WriteByteSeq(guidBytes1[7]); + data->WriteByteSeq(guidBytes2[3]); + break; + } } } void BattlegroundMgr::BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg) { - uint8 type = (bg->isArena() ? 1 : 0); - // last check on 3.0.3 - data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize())); - *data << uint8(type); // type (battleground=0/arena=1) - - if (type) // arena - { - // it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H - for (int8 i = 1; i >= 0; --i) - { - int32 rating_change = bg->GetArenaTeamRatingChangeByIndex(i); + uint8 isRated = (bg->isRated() ? 1 : 0); // type (normal=0/rated=1) -- ATM arena or bg, RBG NYI + uint8 isArena = (bg->isArena() ? 1 : 0); // Arena names - uint32 pointsLost = rating_change < 0 ? -rating_change : 0; - uint32 pointsGained = rating_change > 0 ? rating_change : 0; - uint32 MatchmakerRating = bg->GetArenaMatchmakerRatingByIndex(i); + data->Initialize(SMSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize())); + data->WriteBit(isArena); + data->WriteBit(isRated); - *data << uint32(pointsLost); // Rating Lost - *data << uint32(pointsGained); // Rating gained - *data << uint32(MatchmakerRating); // Matchmaking Value - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "rating change: %d", rating_change); - } + if (isArena) + { for (int8 i = 1; i >= 0; --i) { if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(bg->GetArenaTeamIdByIndex(i))) - *data << at->GetName(); + data->WriteBits(at->GetName().length(), 8); else - *data << uint8(0); + data->WriteBits(0, 8); } } - if (bg->GetStatus() != STATUS_WAIT_LEAVE) - *data << uint8(0); // bg not ended - else - { - *data << uint8(1); // bg ended - *data << uint8(bg->GetWinner()); // who win - } + size_t count_pos = data->bitwpos(); + + data->WriteBits(0, 21); // Placeholder - size_t wpos = data->wpos(); - uint32 scoreCount = 0; - *data << uint32(scoreCount); // placeholder + int32 count = 0; + ByteBuffer buff; Battleground::BattlegroundScoreMap::const_iterator itr2 = bg->GetPlayerScoresBegin(); for (Battleground::BattlegroundScoreMap::const_iterator itr = itr2; itr != bg->GetPlayerScoresEnd();) @@ -286,145 +459,211 @@ void BattlegroundMgr::BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg) sLog->outError(LOG_FILTER_BATTLEGROUND, "Player " UI64FMTD " has scoreboard entry for battleground %u but is not in battleground!", itr->first, bg->GetTypeID(true)); continue; } - - *data << uint64(itr2->first); - *data << uint32(itr2->second->KillingBlows); - if (type == 0) + ObjectGuid guid = itr2->first; + Player* player = ObjectAccessor::FindPlayer(itr2->first); + data->WriteBit(0); // Unk 1 + data->WriteBit(0); // Unk 2 + data->WriteBit(guid[2]); + data->WriteBit(!isArena); // Unk 3 -- Prolly if (bg) + data->WriteBit(0); // Unk 4 + data->WriteBit(0); // Unk 5 + data->WriteBit(0); // Unk 6 + data->WriteBit(guid[3]); + data->WriteBit(guid[0]); + data->WriteBit(guid[5]); + data->WriteBit(guid[1]); + data->WriteBit(guid[6]); + data->WriteBit(player->GetTeam() == ALLIANCE); + data->WriteBit(guid[7]); + + buff << uint32(itr2->second->HealingDone); // healing done + buff << uint32(itr2->second->DamageDone); // damage done + + if (!isArena) // Unk 3 prolly is (bg) { - *data << uint32(itr2->second->HonorableKills); - *data << uint32(itr2->second->Deaths); - *data << uint32(itr2->second->BonusHonor); + buff << uint32(itr2->second->BonusHonor); + buff << uint32(itr2->second->Deaths); + buff << uint32(itr2->second->HonorableKills); } - else - { - Player* player = ObjectAccessor::FindPlayer(itr2->first); - uint32 team = bg->GetPlayerTeam(itr2->first); - if (!team && player) - team = player->GetBGTeam(); - *data << uint8(team == ALLIANCE ? 1 : 0); // green or yellow - } - *data << uint32(itr2->second->DamageDone); // damage done - *data << uint32(itr2->second->HealingDone); // healing done - switch (bg->GetTypeID(true)) // battleground specific things + + buff.WriteByteSeq(guid[4]); + buff << uint32(itr2->second->KillingBlows); + + // if (unk 5) << uint32() unk + + buff.WriteByteSeq(guid[5]); + + // if (unk 6) << uint32() unk + // if (unk 2) << uint32() unk + + buff.WriteByteSeq(guid[1]); + buff.WriteByteSeq(guid[6]); + + buff << int32(player->GetPrimaryTalentTree(player->GetActiveSpec())); + + switch (bg->GetTypeID(true)) // Custom values { case BATTLEGROUND_RB: switch (bg->GetMapId()) { case 489: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundWGScore*)itr2->second)->FlagCaptures); // flag captures - *data << uint32(((BattlegroundWGScore*)itr2->second)->FlagReturns); // flag returns + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundWGScore*)itr2->second)->FlagCaptures); // flag captures + buff << uint32(((BattlegroundWGScore*)itr2->second)->FlagReturns); // flag returns break; case 566: - *data << uint32(0x00000001); // count of next fields - *data << uint32(((BattlegroundEYScore*)itr2->second)->FlagCaptures); // flag captures + data->WriteBits(0x00000001, 24); + buff << uint32(((BattlegroundEYScore*)itr2->second)->FlagCaptures); // flag captures break; case 529: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundABScore*)itr2->second)->BasesAssaulted); // bases asssulted - *data << uint32(((BattlegroundABScore*)itr2->second)->BasesDefended); // bases defended + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundABScore*)itr2->second)->BasesAssaulted); // bases asssulted + buff << uint32(((BattlegroundABScore*)itr2->second)->BasesDefended); // bases defended break; case 30: - *data << uint32(0x00000005); // count of next fields - *data << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsAssaulted); // GraveyardsAssaulted - *data << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsDefended); // GraveyardsDefended - *data << uint32(((BattlegroundAVScore*)itr2->second)->TowersAssaulted); // TowersAssaulted - *data << uint32(((BattlegroundAVScore*)itr2->second)->TowersDefended); // TowersDefended - *data << uint32(((BattlegroundAVScore*)itr2->second)->MinesCaptured); // MinesCaptured + data->WriteBits(0x00000005, 24); + buff << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsAssaulted); // GraveyardsAssaulted + buff << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsDefended); // GraveyardsDefended + buff << uint32(((BattlegroundAVScore*)itr2->second)->TowersAssaulted); // TowersAssaulted + buff << uint32(((BattlegroundAVScore*)itr2->second)->TowersDefended); // TowersDefended + buff << uint32(((BattlegroundAVScore*)itr2->second)->MinesCaptured); // MinesCaptured break; case 607: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundSAScore*)itr2->second)->demolishers_destroyed); - *data << uint32(((BattlegroundSAScore*)itr2->second)->gates_destroyed); + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundSAScore*)itr2->second)->demolishers_destroyed); + buff << uint32(((BattlegroundSAScore*)itr2->second)->gates_destroyed); break; case 628: // IC - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundICScore*)itr2->second)->BasesAssaulted); // bases asssulted - *data << uint32(((BattlegroundICScore*)itr2->second)->BasesDefended); // bases defended + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundICScore*)itr2->second)->BasesAssaulted); // bases asssulted + buff << uint32(((BattlegroundICScore*)itr2->second)->BasesDefended); // bases defended + break; case 726: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundTPScore*)itr2->second)->FlagCaptures); // flag captures - *data << uint32(((BattlegroundTPScore*)itr2->second)->FlagReturns); // flag returns + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundTPScore*)itr2->second)->FlagCaptures); // flag captures + buff << uint32(((BattlegroundTPScore*)itr2->second)->FlagReturns); // flag returns break; case 761: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundBFGScore*)itr2->second)->BasesAssaulted); // bases asssulted - *data << uint32(((BattlegroundBFGScore*)itr2->second)->BasesDefended); // bases defended + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundBFGScore*)itr2->second)->BasesAssaulted); // bases asssulted + buff << uint32(((BattlegroundBFGScore*)itr2->second)->BasesDefended); // bases defended break; default: - *data << uint32(0); + data->WriteBits(0, 24); break; } + break; case BATTLEGROUND_AV: - *data << uint32(0x00000005); // count of next fields - *data << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsAssaulted); // GraveyardsAssaulted - *data << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsDefended); // GraveyardsDefended - *data << uint32(((BattlegroundAVScore*)itr2->second)->TowersAssaulted); // TowersAssaulted - *data << uint32(((BattlegroundAVScore*)itr2->second)->TowersDefended); // TowersDefended - *data << uint32(((BattlegroundAVScore*)itr2->second)->MinesCaptured); // MinesCaptured + data->WriteBits(0x00000005, 24); + buff << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsAssaulted); // GraveyardsAssaulted + buff << uint32(((BattlegroundAVScore*)itr2->second)->GraveyardsDefended); // GraveyardsDefended + buff << uint32(((BattlegroundAVScore*)itr2->second)->TowersAssaulted); // TowersAssaulted + buff << uint32(((BattlegroundAVScore*)itr2->second)->TowersDefended); // TowersDefended + buff << uint32(((BattlegroundAVScore*)itr2->second)->MinesCaptured); // MinesCaptured break; case BATTLEGROUND_WS: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundWGScore*)itr2->second)->FlagCaptures); // flag captures - *data << uint32(((BattlegroundWGScore*)itr2->second)->FlagReturns); // flag returns + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundWGScore*)itr2->second)->FlagCaptures); // flag captures + buff << uint32(((BattlegroundWGScore*)itr2->second)->FlagReturns); // flag returns break; case BATTLEGROUND_AB: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundABScore*)itr2->second)->BasesAssaulted); // bases asssulted - *data << uint32(((BattlegroundABScore*)itr2->second)->BasesDefended); // bases defended + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundABScore*)itr2->second)->BasesAssaulted); // bases asssulted + buff << uint32(((BattlegroundABScore*)itr2->second)->BasesDefended); // bases defended break; case BATTLEGROUND_EY: - *data << uint32(0x00000001); // count of next fields - *data << uint32(((BattlegroundEYScore*)itr2->second)->FlagCaptures); // flag captures + data->WriteBits(0x00000001, 24); + buff << uint32(((BattlegroundEYScore*)itr2->second)->FlagCaptures); // flag captures break; case BATTLEGROUND_SA: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundSAScore*)itr2->second)->demolishers_destroyed); - *data << uint32(((BattlegroundSAScore*)itr2->second)->gates_destroyed); + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundSAScore*)itr2->second)->demolishers_destroyed); + buff << uint32(((BattlegroundSAScore*)itr2->second)->gates_destroyed); break; - case BATTLEGROUND_IC: // wotlk - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundICScore*)itr2->second)->BasesAssaulted); // bases asssulted - *data << uint32(((BattlegroundICScore*)itr2->second)->BasesDefended); // bases defended + case BATTLEGROUND_IC: + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundICScore*)itr2->second)->BasesAssaulted); // bases asssulted + buff << uint32(((BattlegroundICScore*)itr2->second)->BasesDefended); // bases defended break; case BATTLEGROUND_TP: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundTPScore*)itr2->second)->FlagCaptures); // flag captures - *data << uint32(((BattlegroundTPScore*)itr2->second)->FlagReturns); // flag returns + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundTPScore*)itr2->second)->FlagCaptures); // flag captures + buff << uint32(((BattlegroundTPScore*)itr2->second)->FlagReturns); // flag returns + break; case BATTLEGROUND_BFG: - *data << uint32(0x00000002); // count of next fields - *data << uint32(((BattlegroundBFGScore*)itr2->second)->BasesAssaulted); // bases asssulted - *data << uint32(((BattlegroundBFGScore*)itr2->second)->BasesDefended); // bases defended + data->WriteBits(0x00000002, 24); + buff << uint32(((BattlegroundBFGScore*)itr2->second)->BasesAssaulted); // bases asssulted + buff << uint32(((BattlegroundBFGScore*)itr2->second)->BasesDefended); // bases defended + break; case BATTLEGROUND_NA: case BATTLEGROUND_BE: case BATTLEGROUND_AA: case BATTLEGROUND_RL: case BATTLEGROUND_DS: // wotlk case BATTLEGROUND_RV: // wotlk - *data << uint32(0); + data->WriteBits(0, 24); break; default: - sLog->outDebug(LOG_FILTER_NETWORKIO, "Unhandled MSG_PVP_LOG_DATA for BG id %u", bg->GetTypeID()); - *data << uint32(0); + data->WriteBits(0, 24); break; } - // should never happen - if (++scoreCount >= bg->GetMaxPlayers() && itr != bg->GetPlayerScoresEnd()) + data->WriteBit(guid[4]); + + buff.WriteByteSeq(guid[0]); + buff.WriteByteSeq(guid[3]); + + // if (unk 4) << uint32() unk + + buff.WriteByteSeq(guid[7]); + buff.WriteByteSeq(guid[2]); + + ++count; + } + + data->WriteBit(bg->GetStatus() == STATUS_WAIT_LEAVE); // If Ended + data->FlushBits(); + data->PutBits<int32>(count_pos, count, 21); // Number of Players + + if (isRated) // arena TODO : Fix Order on Rated Implementation + { + // it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H + for (int8 i = 1; i >= 0; --i) { - sLog->outError(LOG_FILTER_BATTLEGROUND, "Battleground %u scoreboard has more entries (%u) than allowed players in this bg (%u)", bg->GetTypeID(true), bg->GetPlayerScoresSize(), bg->GetMaxPlayers()); - break; + int32 rating_change = bg->GetArenaTeamRatingChangeByIndex(i); + + uint32 pointsLost = rating_change < 0 ? -rating_change : 0; + uint32 pointsGained = rating_change > 0 ? rating_change : 0; + uint32 MatchmakerRating = bg->GetArenaMatchmakerRatingByIndex(i); + + *data << uint32(pointsLost); // Rating Lost + *data << uint32(pointsGained); // Rating gained + *data << uint32(MatchmakerRating); // Matchmaking Value + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "rating change: %d", rating_change); } } - data->put(wpos, scoreCount); + data->append(buff); + + if (isArena) + for (int8 i = 1; i >= 0; --i) + if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(bg->GetArenaTeamIdByIndex(i))) + data->WriteString(at->GetName()); + + *data << uint8(0); // unk + + if (bg->GetStatus() == STATUS_WAIT_LEAVE) + *data << uint8(bg->GetWinner()); // who win + + *data << uint8(0); // unk } -void BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result) +void BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket* data, Battleground* bg, Player* pPlayer, GroupJoinBattlegroundResult result) { - data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4); - *data << int32(result); - if (result == ERR_BATTLEGROUND_JOIN_TIMED_OUT || result == ERR_BATTLEGROUND_JOIN_FAILED) - *data << uint64(0); // player guid + ObjectGuid guidBytes1 = pPlayer->GetGUID(); + ObjectGuid guidBytes2 = bg->GetGUID(); + + data->Initialize(SMSG_BATTLEFIELD_STATUS_FAILED); + } void BattlegroundMgr::BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value) @@ -442,14 +681,52 @@ void BattlegroundMgr::BuildPlaySoundPacket(WorldPacket* data, uint32 soundid) void BattlegroundMgr::BuildPlayerLeftBattlegroundPacket(WorldPacket* data, uint64 guid) { + ObjectGuid guidBytes = guid; + data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8); - *data << uint64(guid); + + data->WriteBit(guidBytes[7]); + data->WriteBit(guidBytes[6]); + data->WriteBit(guidBytes[2]); + data->WriteBit(guidBytes[4]); + data->WriteBit(guidBytes[5]); + data->WriteBit(guidBytes[1]); + data->WriteBit(guidBytes[3]); + data->WriteBit(guidBytes[0]); + + data->WriteByteSeq(guidBytes[4]); + data->WriteByteSeq(guidBytes[2]); + data->WriteByteSeq(guidBytes[5]); + data->WriteByteSeq(guidBytes[7]); + data->WriteByteSeq(guidBytes[0]); + data->WriteByteSeq(guidBytes[6]); + data->WriteByteSeq(guidBytes[1]); + data->WriteByteSeq(guidBytes[3]); } -void BattlegroundMgr::BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player) +void BattlegroundMgr::BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, uint64 guid) { + ObjectGuid guidBytes = guid; + data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8); - *data << uint64(player->GetGUID()); + + data->WriteBit(guidBytes[0]); + data->WriteBit(guidBytes[4]); + data->WriteBit(guidBytes[3]); + data->WriteBit(guidBytes[5]); + data->WriteBit(guidBytes[7]); + data->WriteBit(guidBytes[6]); + data->WriteBit(guidBytes[2]); + data->WriteBit(guidBytes[1]); + + data->WriteByteSeq(guidBytes[1]); + data->WriteByteSeq(guidBytes[5]); + data->WriteByteSeq(guidBytes[3]); + data->WriteByteSeq(guidBytes[2]); + data->WriteByteSeq(guidBytes[0]); + data->WriteByteSeq(guidBytes[7]); + data->WriteByteSeq(guidBytes[4]); + data->WriteByteSeq(guidBytes[6]); } Battleground* BattlegroundMgr::GetBattlegroundThroughClientInstance(uint32 instanceId, BattlegroundTypeId bgTypeId) @@ -846,63 +1123,68 @@ void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, uint64 guid if (!player) return; - uint32 winner_kills = player->GetRandomWinner() ? BG_REWARD_WINNER_HONOR_LAST : BG_REWARD_WINNER_HONOR_FIRST; - uint32 winner_arena = player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST; - uint32 loser_kills = player->GetRandomWinner() ? BG_REWARD_LOSER_HONOR_LAST : BG_REWARD_LOSER_HONOR_FIRST; + uint32 winner_conquest = player->GetRandomWinner() ? BG_REWARD_WINNER_CONQUEST_FIRST : BG_REWARD_WINNER_CONQUEST_LAST; + uint32 winner_honor = player->GetRandomWinner() ? BG_REWARD_WINNER_HONOR_FIRST : BG_REWARD_WINNER_HONOR_LAST; + uint32 loser_honor = !player->GetRandomWinner() ? BG_REWARD_LOSER_HONOR_FIRST : BG_REWARD_LOSER_HONOR_LAST; - winner_kills = Trinity::Honor::hk_honor_at_level(player->getLevel(), float(winner_kills)); - loser_kills = Trinity::Honor::hk_honor_at_level(player->getLevel(), float(loser_kills)); + ObjectGuid guidBytes = guid; data->Initialize(SMSG_BATTLEFIELD_LIST); - // TODO: Fix guid - *data << uint64(guid); // battlemaster guid + *data << uint32(winner_conquest); // Winner Conquest Reward or Random Winner Conquest Reward + *data << uint32(winner_conquest); // Winner Conquest Reward or Random Winner Conquest Reward + *data << uint32(loser_honor); // Loser Honor Reward or Random Loser Honor Reward *data << uint32(bgTypeId); // battleground id - *data << uint8(0); // unk - *data << uint8(0); // unk - - // Rewards - *data << uint8(player->GetRandomWinner()); // 3.3.3 hasWin - *data << uint32(winner_kills); // 3.3.3 winHonor - *data << uint32(winner_arena); // 3.3.3 winArena - *data << uint32(loser_kills); // 3.3.3 lossHonor - - uint8 isRandom = bgTypeId == BATTLEGROUND_RB; - - *data << uint8(isRandom); // 3.3.3 isRandom - if (isRandom) - { - // Rewards (random) - *data << uint8(player->GetRandomWinner()); // 3.3.3 hasWin_Random - *data << uint32(winner_kills); // 3.3.3 winHonor_Random - *data << uint32(winner_arena); // 3.3.3 winArena_Random - *data << uint32(loser_kills); // 3.3.3 lossHonor_Random - } - - if (bgTypeId == BATTLEGROUND_AA) // arena + *data << uint32(loser_honor); // Loser Honor Reward or Random Loser Honor Reward + *data << uint32(winner_honor); // Winner Honor Reward or Random Winner Honor Reward + *data << uint32(winner_honor); // Winner Honor Reward or Random Winner Honor Reward + *data << uint8(0); // max level + *data << uint8(0); // min level + + data->WriteBit(guidBytes[0]); + data->WriteBit(guidBytes[1]); + data->WriteBit(guidBytes[7]); + data->WriteBit(0); // unk + data->WriteBit(0); // unk + + data->FlushBits(); + size_t count_pos = data->bitwpos(); + data->WriteBits(0, 24); // placeholder + + data->WriteBit(guidBytes[6]); + data->WriteBit(guidBytes[4]); + data->WriteBit(guidBytes[2]); + data->WriteBit(guidBytes[3]); + data->WriteBit(0); // unk + data->WriteBit(guidBytes[5]); + data->WriteBit(0); // unk + + data->FlushBits(); + + data->WriteByteSeq(guidBytes[6]); + data->WriteByteSeq(guidBytes[1]); + data->WriteByteSeq(guidBytes[7]); + data->WriteByteSeq(guidBytes[5]); + + if (Battleground* bgTemplate = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId)) { - *data << uint32(0); // unk (count?) - } - else // battleground - { - size_t count_pos = data->wpos(); - *data << uint32(0); // number of bg instances - - if (Battleground* bgTemplate = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId)) + // expected bracket entry + if (PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgTemplate->GetMapId(), player->getLevel())) { - // expected bracket entry - if (PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgTemplate->GetMapId(), player->getLevel())) + uint32 count = 0; + BattlegroundBracketId bracketId = bracketEntry->GetBracketId(); + for (std::set<uint32>::iterator itr = m_ClientBattlegroundIds[bgTypeId][bracketId].begin(); itr != m_ClientBattlegroundIds[bgTypeId][bracketId].end();++itr) { - uint32 count = 0; - BattlegroundBracketId bracketId = bracketEntry->GetBracketId(); - for (std::set<uint32>::iterator itr = m_ClientBattlegroundIds[bgTypeId][bracketId].begin(); itr != m_ClientBattlegroundIds[bgTypeId][bracketId].end();++itr) - { - *data << uint32(*itr); - ++count; - } - data->put<uint32>(count_pos, count); + *data << uint32(*itr); // instance id + ++count; } + data->PutBits(count_pos, count, 24); // bg instance count } } + + data->WriteByteSeq(guidBytes[0]); + data->WriteByteSeq(guidBytes[2]); + data->WriteByteSeq(guidBytes[4]); + data->WriteByteSeq(guidBytes[3]); } void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, BattlegroundTypeId bgTypeId) diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 4edad4da742..a161f36fc6d 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -66,14 +66,14 @@ class BattlegroundMgr void Update(uint32 diff); /* Packet Building */ - void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player); + void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, uint64 guid); void BuildPlayerLeftBattlegroundPacket(WorldPacket* data, uint64 guid); void BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId); - void BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result); + void BuildGroupJoinedBattlegroundPacket(WorldPacket* data, Battleground* bg, Player* player, GroupJoinBattlegroundResult result); void BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value); void BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg); - void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype, uint8 uiFrame = 1); - void BuildPlaySoundPacket(WorldPacket* data, uint32 soundid); + void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, Player* player, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, uint8 arenaType, uint8 uiFrame = 1); + void BuildPlaySoundPacket(WorldPacket* data, uint32 soundId); void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, uint64 guid); /* Battlegrounds */ diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 85d41977d13..7e7502b0538 100755 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -391,7 +391,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) plr2->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to // queue->removeplayer, it causes bugs WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, plr2, queueSlot, STATUS_NONE, 0, 0, 0); plr2->GetSession()->SendPacket(&data); } // then actually delete, this may delete the group as well! @@ -470,7 +470,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: invited player %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.", player->GetName(), player->GetGUIDLow(), bg->GetInstanceID(), queueSlot, bg->GetTypeID()); // send status packet - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, player, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType); player->GetSession()->SendPacket(&data); } return true; @@ -1022,7 +1022,7 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { WorldPacket data; //we must send remaining time in queue - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, player, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType); player->GetSession()->SendPacket(&data); } } @@ -1070,7 +1070,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) sBattlegroundMgr->ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetBracketId()); WorldPacket data; - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, player, queueSlot, STATUS_NONE, 0, 0, 0); player->GetSession()->SendPacket(&data); } } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 051234f1e4f..d2f5d43c187 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -52,6 +52,8 @@ BattlegroundWS::BattlegroundWS() StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE; StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE; StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN; + _flagSpellForceTimer = 0; + _bothFlagsKept = false; _flagDebuffState = 0; } diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index c0560ee0e27..bbb9870338c 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -47,8 +47,8 @@ class ChatHandler { public: WorldSession* GetSession() { return m_session; } - explicit ChatHandler(WorldSession* session) : m_session(session) {} - explicit ChatHandler(Player* player) : m_session(player->GetSession()) {} + explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) {} + explicit ChatHandler(Player* player) : m_session(player->GetSession()), sentErrorMessage(false) {} virtual ~ChatHandler() {} static void FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker, const char* addonPrefix = NULL); @@ -126,7 +126,7 @@ class ChatHandler bool ShowHelpForCommand(ChatCommand* table, const char* cmd); protected: - explicit ChatHandler() : m_session(NULL) {} // for CLI subclass + explicit ChatHandler() : m_session(NULL), sentErrorMessage(false) {} // for CLI subclass static bool SetDataForCommandInTable(ChatCommand* table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand); bool ExecuteCommandInTable(ChatCommand* table, const char* text, const std::string& fullcmd); bool ShowHelpForSubCommands(ChatCommand* table, char const* cmd, char const* subcmd); diff --git a/src/server/game/Combat/UnitEvents.h b/src/server/game/Combat/UnitEvents.h index de60491de89..07d8b20af52 100755 --- a/src/server/game/Combat/UnitEvents.h +++ b/src/server/game/Combat/UnitEvents.h @@ -123,8 +123,8 @@ class ThreatManagerEvent : public ThreatRefStatusChangeEvent private: ThreatContainer* iThreatContainer; public: - ThreatManagerEvent(uint32 pType) : ThreatRefStatusChangeEvent(pType) {} - ThreatManagerEvent(uint32 pType, HostileReference* pHostileReference) : ThreatRefStatusChangeEvent(pType, pHostileReference) {} + ThreatManagerEvent(uint32 pType) : ThreatRefStatusChangeEvent(pType), iThreatContainer(NULL) {} + ThreatManagerEvent(uint32 pType, HostileReference* pHostileReference) : ThreatRefStatusChangeEvent(pType, pHostileReference), iThreatContainer(NULL) {} void setThreatContainer(ThreatContainer* pThreatContainer) { iThreatContainer = pThreatContainer; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index ab3c6aba791..d1db3d9577c 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -867,7 +867,6 @@ void ConditionMgr::LoadConditions(bool isReload) valid = true; ++count; continue; // do not add to m_AllocatedMemory to avoid double deleting - break; } case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET: valid = addToSpellImplicitTargetConditions(cond); diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index cd8accd3759..5ab9949d9cf 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -19,18 +19,21 @@ #ifndef DBCENUMS_H #define DBCENUMS_H -// Client expected level limitation, like as used in DBC item max levels for "until max player level" -// use as default max player level, must be fit max level for used client -// also see MAX_LEVEL and STRONG_MAX_LEVEL define -#define DEFAULT_MAX_LEVEL 85 - -// client supported max level for player/pets/etc. Avoid overflow or client stability affected. -// also see GT_MAX_LEVEL define -#define MAX_LEVEL 100 - -// Server side limitation. Base at used code requirements. -// also see MAX_LEVEL and GT_MAX_LEVEL define -#define STRONG_MAX_LEVEL 255 +enum LevelLimit +{ + // Client expected level limitation, like as used in DBC item max levels for "until max player level" + // use as default max player level, must be fit max level for used client + // also see MAX_LEVEL and STRONG_MAX_LEVEL define + DEFAULT_MAX_LEVEL = 85, + + // client supported max level for player/pets/etc. Avoid overflow or client stability affected. + // also see GT_MAX_LEVEL define + MAX_LEVEL = 100, + + // Server side limitation. Base at used code requirements. + // also see MAX_LEVEL and GT_MAX_LEVEL define + STRONG_MAX_LEVEL = 255, +}; enum BattlegroundBracketId // bracketId for level ranges { @@ -58,27 +61,30 @@ enum AchievementFaction enum AchievementFlags { - ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete) - ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only - ACHIEVEMENT_FLAG_PLAY_NO_VISUAL = 0x00000004, // Client does not play achievement earned visual - ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value) - ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) - ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value) - ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) - ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) - ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // - ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // - ACHIEVEMENT_FLAG_UNK3 = 0x00000400, // ACHIEVEMENT_FLAG_HIDE_NAME_IN_TIE - ACHIEVEMENT_FLAG_REALM_FIRST_GUILD = 0x00000800, // first guild on realm done something - ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS = 0x00001000, // Shows in guild news - ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER = 0x00002000, // Shows in guild news header - ACHIEVEMENT_FLAG_GUILD = 0x00004000, // - ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS = 0x00008000, // - ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS = 0x00010000, // - + ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete) + ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only + ACHIEVEMENT_FLAG_PLAY_NO_VISUAL = 0x00000004, // Client does not play achievement earned visual + ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all requirements (and calculate max value) + ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) + ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value) + ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) + ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) + ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // + ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // + ACHIEVEMENT_FLAG_UNK3 = 0x00000400, // ACHIEVEMENT_FLAG_HIDE_NAME_IN_TIE + ACHIEVEMENT_FLAG_REALM_FIRST_GUILD = 0x00000800, // first guild on realm done something + ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS = 0x00001000, // Shows in guild news + ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER = 0x00002000, // Shows in guild news header + ACHIEVEMENT_FLAG_GUILD = 0x00004000, // + ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS = 0x00008000, // + ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS = 0x00010000, // }; -#define MAX_CRITERIA_REQUIREMENTS 2 +enum +{ + MAX_CRITERIA_REQUIREMENTS = 2, + MAX_ADDITIONAL_CRITERIA_CONDITIONS = 3 +}; enum AchievementCriteriaCondition { @@ -92,80 +98,53 @@ enum AchievementCriteriaCondition ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk }; -#define MAX_ADDITIONAL_CRITERIA_CONDITIONS 3 - enum AchievementCriteriaAdditionalCondition { - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK2 = 2, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY = 4, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER = 5, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD = 6, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY = 7, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA = 8, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK9 = 9, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA = 10, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED = 11, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK12 = 12, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK13 = 13, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN = 14, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS = 15, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK16 = 16, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA = 17, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE = 18, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK19 = 19, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 20, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_YIELDS_XP = 21, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK22 = 22, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK23 = 23, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ARENA_TEAM_SIZE = 24, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE = 25, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS = 26, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE = 27, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS = 28, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS = 29, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE = 30, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK31 = 31, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK35 = 35, // related to timed completing-quests achievements - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK36 = 36, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE) - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL = 39, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL = 40, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK42 = 42, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK43 = 43, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK44 = 44, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK45 = 45, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW = 46, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK47 = 47, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK48 = 48, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK49 = 49, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK50 = 50, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK51 = 51, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK52 = 52, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK53 = 53, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK54 = 54, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK55 = 55, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK57 = 57, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_LFG_GROUP = 58, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK59 = 59, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK60 = 60, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_GUILD_GROUP = 61, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION = 62, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND = 63, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK64 = 64, // unused in 4.0.6a - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK65 = 65, // Archaeology, item quality related - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK66 = 66, // Archaeology, race related + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK2 = 2, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY = 4, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER = 5, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD = 6, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY = 7, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA = 8, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA = 10, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED = 11, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN = 14, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS = 15, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK16 = 16, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA = 17, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE = 18, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 20, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_YIELDS_XP = 21, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ARENA_TEAM_SIZE = 24, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE = 25, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS = 26, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE = 27, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS = 28, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS = 29, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE = 30, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK35 = 35, // related to timed completing-quests achievements + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE) + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL = 39, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL = 40, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW = 46, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK55 = 55, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_LFG_GROUP = 58, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK60 = 60, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_GUILD_GROUP = 61, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION = 62, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND = 63, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PROJECT_RARITY = 65, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PROJECT_RACE = 66, }; -#define MAX_ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TYPE 66 - enum AchievementCriteriaFlags { ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar @@ -198,8 +177,7 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9, - // you have to complete a daily quest x times in a row - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, // you have to complete a daily quest x times in a row ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12, ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, @@ -234,18 +212,15 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT = 45, ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION = 46, ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION = 47, - // noted: rewarded as soon as the player payed, not at taking place at the seat ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48, ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49, - // TODO: itemlevel is mentioned in text but not present in dbc - ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, // TODO: itemlevel is mentioned in text but not present in dbc ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT = 51, ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52, ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53, ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54, ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55, - // TODO: in some cases map not present, and in some cases need do without die - ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56, + ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56, // TODO: in some cases map not present, and in some cases need do without die ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57, ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59, ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60, @@ -259,13 +234,11 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2 = 69, ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70, ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72, - // TODO: title id is not mentioned in dbc - ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, + ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, // TODO: title id is not mentioned in dbc ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75, ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76, ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77, - // TODO: creature type (demon, undead etc.) is not stored in dbc - ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, + ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, // TODO: creature type (demon, undead etc.) is not stored in dbc ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS = 80, ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION = 82, ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID = 83, @@ -288,8 +261,7 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107, ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108, ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109, - // TODO: target entry is missing - ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, + ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, // TODO: target entry is missing ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE = 112, ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, @@ -326,10 +298,10 @@ enum AchievementCriteriaTypes ACHIEVEMENT_CRITERIA_TYPE_UNK148 = 148, ACHIEVEMENT_CRITERIA_TYPE_UNK149 = 149, ACHIEVEMENT_CRITERIA_TYPE_UNK150 = 150, - // 0..144 => 145 criteria types total - ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 151, }; +#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 151 + enum AchievementCategory { CATEGORY_CHILDRENS_WEEK = 163, diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index b12aee36fc1..1d397e8f3ec 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -67,8 +67,8 @@ struct AchievementCategoryEntry struct AchievementCriteriaEntry { uint32 ID; // 0 - uint32 referredAchievement; // 1 - uint32 requiredType; // 2 + uint32 achievement; // 1 + uint32 type; // 2 union { // ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0 diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 653a731b5b2..3e7dfc125f9 100755 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -26,8 +26,7 @@ #include "GossipDef.h" #include "World.h" -Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES) -, m_type(type) +Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type) { m_objectType |= TYPEMASK_CORPSE; m_objectTypeId = TYPEID_CORPSE; @@ -39,6 +38,7 @@ Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES) m_time = time(NULL); lootForBody = false; + lootRecipient = NULL; } Corpse::~Corpse() diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6e2fc197a5f..6270b3b64c0 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -381,7 +381,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags); - SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER); + SetUInt32Value(UNIT_FIELD_FLAGS_2, cInfo->unit_flags2); SetUInt32Value(UNIT_DYNAMIC_FLAGS, dynamicflags); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 14a680d62d1..669d8461d34 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -112,6 +112,7 @@ struct CreatureTemplate uint32 rangeattacktime; uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. uint32 unit_flags; // enum UnitFlags mask values + uint32 unit_flags2; // enum UnitFlags2 mask values uint32 dynamicflags; uint32 family; // enum CreatureFamily values (optional) uint32 trainer_type; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 05ec6f6920d..52a9de09f30 100755 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -417,8 +417,8 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << int32(quest->GetRewSpellCast()); // casted spell // rewarded honor points - data << Trinity::Honor::hk_honor_at_level(_session->GetPlayer()->getLevel(), quest->GetRewHonorMultiplier()); - data << float(0); // new reward honor (multipled by ~62 at client side) + data << uint32(quest->GetRewHonorAddition()); + data << float(quest->GetRewHonorMultiplier()); data << uint32(quest->GetSrcItemId()); // source item id data << uint32(quest->GetFlags() & 0xFFFF); // quest flags data << uint32(quest->GetMinimapTargetMark()); // minimap target mark (skull, etc. missing enum) diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index f82dfa53f4d..b60197ff613 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -29,7 +29,7 @@ class TempSummon : public Creature void Update(uint32 time); virtual void InitStats(uint32 lifetime); virtual void InitSummon(); - void UnSummon(uint32 msTime = 0); + virtual void UnSummon(uint32 msTime = 0); void RemoveFromWorld(); void SetTempSummonType(TempSummonType type); void SaveToDB(uint32 /*mapid*/, uint8 /*spawnMask*/, uint32 /*phaseMask*/) {} diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 18ed5632793..db0903832c0 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1419,7 +1419,8 @@ void GameObject::Use(Unit* user) // full amount unique participants including original summoner if (GetUniqueUseCount() == info->summoningRitual.reqParticipants) { - spellCaster = m_ritualOwner ? m_ritualOwner : spellCaster; + if (m_ritualOwner) + spellCaster = m_ritualOwner; spellId = info->summoningRitual.spellId; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 3eb9aabab14..faa91c2672a 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1039,7 +1039,7 @@ Item* Item::CreateItem(uint32 item, uint32 count, Player const* player) if (count > pProto->GetMaxStackSize()) count = pProto->GetMaxStackSize(); - ASSERT(count !=0 && "pProto->Stackable == 0 but checked at loading already"); + ASSERT(count != 0 && "pProto->Stackable == 0 but checked at loading already"); Item* pItem = NewItemOrBag(pProto); if (pItem->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), item, player)) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 2ccb5b68bca..4b4bcfd019a 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1916,10 +1916,10 @@ bool WorldObject::canSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj)) return true; - bool corpseCheck = false; bool corpseVisibility = false; if (distanceCheck) { + bool corpseCheck = false; if (Player const* thisPlayer = ToPlayer()) { if (thisPlayer->isDead() && thisPlayer->GetHealth() > 0 && // Cheap way to check for ghost state diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index 9fd4279a79c..b971943954e 100755 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -43,6 +43,7 @@ enum HighGuid HIGHGUID_VEHICLE = 0xF15, // blizz F550 HIGHGUID_DYNAMICOBJECT = 0xF10, // blizz F100 HIGHGUID_CORPSE = 0xF101, // blizz F100 + HIGHGUID_TYPE_BATTLEGROUND = 0x1F1, // new 4.x HIGHGUID_MO_TRANSPORT = 0x1FC, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) HIGHGUID_GROUP = 0x1F5, HIGHGUID_GUILD = 0x1FF5, // new 4.x diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 800498a82dd..180f43109f2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -846,6 +846,8 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_SeasonalQuestChanged = false; SetPendingBind(0, 0); + + _activeCheats = CHEAT_NONE; memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); } @@ -7337,7 +7339,6 @@ bool Player::HasCurrency(uint32 id, uint32 count) const PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id); return itr != m_currencies.end() && itr->second.totalCount >= count; } - void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/) { if (!count) @@ -7379,7 +7380,6 @@ void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/) newTotalCount = int32(currency->TotalCap); newWeekCount -= delta; } - // TODO: fix conquest points uint32 weekCap = _GetCurrencyWeekCap(currency); if (weekCap && int32(weekCap) < newTotalCount) @@ -7599,13 +7599,9 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) { SetGroupUpdateFlag(GROUP_UPDATE_FULL); if (GetSession() && group->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID())) - { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { if (Player* member = itr->getSource()) GetSession()->SendNameQueryOpcode(member->GetGUID()); - } - } } m_zoneUpdateId = newZone; @@ -7670,8 +7666,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) if (GetRestType() == REST_TYPE_IN_TAVERN) // Still inside a tavern or has recently left { // Remove rest state if we have recently left a tavern. - // Why is 40 yd hardcoded? - if (GetMapId() != GetInnPosMapId() || GetExactDist(GetInnPosX(), GetInnPosY(), GetInnPosZ()) > 40.0f) + if (GetMapId() != GetInnPosMapId() || GetExactDist(GetInnPosX(), GetInnPosY(), GetInnPosZ()) > 1.0f) { RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_NO); @@ -9139,9 +9134,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) case 2918: NumberOfFields = 8; break; - case 139: - NumberOfFields = 41; - break; case 1377: NumberOfFields = 15; break; @@ -9229,46 +9221,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) case 2257: // Deeprun Tram case 3703: // Shattrath City break; - case 139: // Eastern Plaguelands - if (pvp && pvp->GetTypeId() == OUTDOOR_PVP_EP) - pvp->FillInitialWorldStates(data); - else - { - data << uint32(0x97a) << uint32(0x0); // 10 2426 - data << uint32(0x917) << uint32(0x0); // 11 2327 - data << uint32(0x918) << uint32(0x0); // 12 2328 - data << uint32(0x97b) << uint32(0x32); // 13 2427 - data << uint32(0x97c) << uint32(0x32); // 14 2428 - data << uint32(0x933) << uint32(0x1); // 15 2355 - data << uint32(0x946) << uint32(0x0); // 16 2374 - data << uint32(0x947) << uint32(0x0); // 17 2375 - data << uint32(0x948) << uint32(0x0); // 18 2376 - data << uint32(0x949) << uint32(0x0); // 19 2377 - data << uint32(0x94a) << uint32(0x0); // 20 2378 - data << uint32(0x94b) << uint32(0x0); // 21 2379 - data << uint32(0x932) << uint32(0x0); // 22 2354 - data << uint32(0x934) << uint32(0x0); // 23 2356 - data << uint32(0x935) << uint32(0x0); // 24 2357 - data << uint32(0x936) << uint32(0x0); // 25 2358 - data << uint32(0x937) << uint32(0x0); // 26 2359 - data << uint32(0x938) << uint32(0x0); // 27 2360 - data << uint32(0x939) << uint32(0x1); // 28 2361 - data << uint32(0x930) << uint32(0x1); // 29 2352 - data << uint32(0x93a) << uint32(0x0); // 30 2362 - data << uint32(0x93b) << uint32(0x0); // 31 2363 - data << uint32(0x93c) << uint32(0x0); // 32 2364 - data << uint32(0x93d) << uint32(0x0); // 33 2365 - data << uint32(0x944) << uint32(0x0); // 34 2372 - data << uint32(0x945) << uint32(0x0); // 35 2373 - data << uint32(0x931) << uint32(0x1); // 36 2353 - data << uint32(0x93e) << uint32(0x0); // 37 2366 - data << uint32(0x931) << uint32(0x1); // 38 2367 ?? grey horde not in dbc! send for consistency's sake, and to match field count - data << uint32(0x940) << uint32(0x0); // 39 2368 - data << uint32(0x941) << uint32(0x0); // 7 2369 - data << uint32(0x942) << uint32(0x0); // 8 2370 - data << uint32(0x943) << uint32(0x0); // 9 2371 - } - break; case 1377: // Silithus if (pvp && pvp->GetTypeId() == OUTDOOR_PVP_SI) pvp->FillInitialWorldStates(data); @@ -15601,7 +15553,6 @@ bool Player::TakeQuestSourceItem(uint32 questId, bool msg) { uint32 srcItemId = quest->GetSrcItemId(); ItemTemplate const* item = sObjectMgr->GetItemTemplate(srcItemId); - bool destroyItem = true; if (srcItemId > 0) { @@ -15621,6 +15572,7 @@ bool Player::TakeQuestSourceItem(uint32 questId, bool msg) return false; } + bool destroyItem = true; for (uint8 n = 0; n < QUEST_ITEM_OBJECTIVES_COUNT; ++n) if (item->StartQuest == questId && srcItemId == quest->RequiredItemId[n]) destroyItem = false; @@ -17039,7 +16991,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) SetUInt64Value(PLAYER_FARSIGHT, 0); SetCreatorGUID(0); - RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVEMENT); // reset some aura modifiers before aura apply SetUInt32Value(PLAYER_TRACK_CREATURES, 0); @@ -17465,8 +17417,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { uint32 zoneId = GetZoneId(); - std::map<uint64, Bag*> bagMap; // fast guid lookup for bags - std::map<uint64, Item*> invalidBagMap; // fast guid lookup for bags + std::map<uint32, Bag*> bagMap; // fast guid lookup for bags + std::map<uint32, Item*> invalidBagMap; // fast guid lookup for bags std::list<Item*> problematicItems; SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -17525,7 +17477,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { item->SetSlot(NULL_SLOT); // Item is in the bag, find the bag - std::map<uint64, Bag*>::iterator itr = bagMap.find(bagGuid); + std::map<uint32, Bag*>::iterator itr = bagMap.find(bagGuid); if (itr != bagMap.end()) { ItemPosCountVec dest; @@ -17535,8 +17487,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) } else if (invalidBagMap.find(bagGuid) != invalidBagMap.end()) { - std::map<uint64, Item*>::iterator itr = invalidBagMap.find(bagGuid); - if (std::find(problematicItems.begin(),problematicItems.end(),itr->second) != problematicItems.end()) + std::map<uint32, Item*>::iterator itr = invalidBagMap.find(bagGuid); + if (std::find(problematicItems.begin(), problematicItems.end(), itr->second) != problematicItems.end()) err = EQUIP_ERR_INTERNAL_BAG_ERROR; } else @@ -17632,7 +17584,6 @@ void Player::_LoadVoidStorage(PreparedQueryResult result) Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields) { - PreparedStatement* stmt = NULL; Item* item = NULL; uint32 itemGuid = fields[13].GetUInt32(); uint32 itemEntry = fields[14].GetUInt32(); @@ -17642,6 +17593,8 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F item = NewItemOrBag(proto); if (item->LoadFromDB(itemGuid, GetGUID(), fields, itemEntry)) { + PreparedStatement* stmt = NULL; + // Do not allow to have item limited to another map/zone in alive state if (isAlive() && item->IsLimitedToAnotherMapOrZone(GetMapId(), zoneId)) { diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 09c7e0ff2a1..c4047485033 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -115,7 +115,7 @@ struct PlayerTalent // Spell modifier (used for modify other spells) struct SpellModifier { - SpellModifier(Aura* _ownerAura = NULL) : charges(0), ownerAura(_ownerAura) {} + SpellModifier(Aura* _ownerAura = NULL) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), value(0), mask(), spellId(0), ownerAura(_ownerAura) {} SpellModOp op : 8; SpellModType type : 8; int16 charges : 16; @@ -875,6 +875,16 @@ enum PlayerRestState REST_STATE_RAF_LINKED = 0x06 }; +enum PlayerCommandStates +{ + CHEAT_NONE = 0x00, + CHEAT_GOD = 0x01, + CHEAT_CASTTIME = 0x02, + CHEAT_COOLDOWN = 0x04, + CHEAT_POWER = 0x08, + CHEAT_WATERWALK = 0x10 +}; + class PlayerTaxi { public: @@ -1196,6 +1206,11 @@ class Player : public Unit, public GridObject<Player> void InitStatsForLevel(bool reapplyMods = false); + // .cheat command related + bool GetCommandStatus(uint32 command) const { return _activeCheats & command; } + void SetCommandStatusOn(uint32 command) { _activeCheats |= command; } + void SetCommandStatusOff(uint32 command) { _activeCheats &= ~command; } + // Played Time Stuff time_t m_logintime; time_t m_Last_tick; @@ -2936,6 +2951,8 @@ class Player : public Unit, public GridObject<Player> InstanceTimeMap _instanceResetTimes; uint32 _pendingBindId; uint32 _pendingBindTimer; + + uint32 _activeCheats; }; void AddItemsSetItem(Player*player, Item* item); diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index 3c7d13070fa..99a40d6110f 100755 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -54,24 +54,12 @@ struct FriendInfo uint8 Class; std::string Note; - FriendInfo() + FriendInfo() : Status(FRIEND_STATUS_OFFLINE), Flags(0), Area(0), Level(0), Class(0), Note() { - Status = FRIEND_STATUS_OFFLINE; - Flags = 0; - Area = 0; - Level = 0; - Class = 0; - Note = ""; } - FriendInfo(uint8 flags, const std::string& note) + FriendInfo(uint8 flags, const std::string& note) : Status(FRIEND_STATUS_OFFLINE), Flags(flags), Area(0), Level(0), Class(0), Note(note) { - Status = FRIEND_STATUS_OFFLINE; - Flags = flags; - Area = 0; - Level = 0; - Class = 0; - Note = note; } }; diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp index 80c5de35e59..a9a0484a4ea 100755 --- a/src/server/game/Entities/Totem/Totem.cpp +++ b/src/server/game/Entities/Totem/Totem.cpp @@ -86,7 +86,7 @@ void Totem::InitStats(uint32 duration) void Totem::InitSummon() { - if (m_type == TOTEM_PASSIVE) + if (m_type == TOTEM_PASSIVE && GetSpell()) { CastSpell(this, GetSpell(), true); } @@ -96,10 +96,10 @@ void Totem::InitSummon() CastSpell(this, GetSpell(1), true); } -void Totem::UnSummon() +void Totem::UnSummon(uint32 msTime) { CombatStop(); - RemoveAurasDueToSpell(GetSpell()); + RemoveAurasDueToSpell(GetSpell(), GetGUID()); // clear owner's totem slot for (int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i) @@ -111,7 +111,11 @@ void Totem::UnSummon() } } - m_owner->RemoveAurasDueToSpell(GetSpell()); + m_owner->RemoveAurasDueToSpell(GetSpell(), GetGUID()); + + // Remove Sentry Totem Aura + if (GetEntry() == SENTRY_TOTEM_ENTRY) + m_owner->RemoveAurasDueToSpell(SENTRY_TOTEM_SPELLID); //remove aura all party members too if (Player* owner = m_owner->ToPlayer()) @@ -127,7 +131,7 @@ void Totem::UnSummon() { Player* target = itr->getSource(); if (target && group->SameSubGroup(owner, target)) - target->RemoveAurasDueToSpell(GetSpell()); + target->RemoveAurasDueToSpell(GetSpell(), GetGUID()); } } } diff --git a/src/server/game/Entities/Totem/Totem.h b/src/server/game/Entities/Totem/Totem.h index c33b8776660..6271253498d 100755 --- a/src/server/game/Entities/Totem/Totem.h +++ b/src/server/game/Entities/Totem/Totem.h @@ -27,8 +27,10 @@ enum TotemType TOTEM_ACTIVE = 1, TOTEM_STATUE = 2 // copied straight from MaNGOS, may need more implementation to work }; +// Some Totems cast spells that are not in creature DB +#define SENTRY_TOTEM_SPELLID 6495 -#define SENTRY_TOTEM_ENTRY 3968 +#define SENTRY_TOTEM_ENTRY 3968 class Totem : public Minion { @@ -38,7 +40,7 @@ class Totem : public Minion void Update(uint32 time); void InitStats(uint32 duration); void InitSummon(); - void UnSummon(); + void UnSummon(uint32 msTime = 0); uint32 GetSpell(uint8 slot = 0) const { return m_spells[slot]; } uint32 GetTotemDuration() const { return m_duration; } void SetTotemDuration(uint32 duration) { m_duration = duration; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 76644b1aa99..8c372bad34a 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -159,7 +159,7 @@ m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(fa m_ControlledByPlayer(false), movespline(new Movement::MoveSpline()), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0), m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), -m_HostileRefManager(this) +m_HostileRefManager(this), m_TempSpeed(0.0f), m_AutoRepeatFirstCast(false) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -544,6 +544,10 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam if (IsAIEnabled) GetAI()->DamageDealt(victim, damage, damagetype); + if (victim->GetTypeId() == TYPEID_PLAYER) + if (victim->ToPlayer()->GetCommandStatus(CHEAT_GOD)) + return 0; + // Signal to pets that their owner was attacked if (victim->GetTypeId() == TYPEID_PLAYER) { @@ -13066,7 +13070,8 @@ void Unit::DeleteCharmInfo() CharmInfo::CharmInfo(Unit* unit) : m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_petnumber(0), m_barInit(false), - m_isCommandAttack(false), m_isAtStay(false), m_isFollowing(false), m_isReturning(false) + m_isCommandAttack(false), m_isAtStay(false), m_isFollowing(false), m_isReturning(false), + m_stayX(0.0f), m_stayY(0.0f), m_stayZ(0.0f) { for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i) m_charmspells[i].SetActionAndType(0, ACT_DISABLED); @@ -15654,14 +15659,14 @@ void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack) aura->SetStackAmount(stack); } -void Unit::SendPlaySpellVisual(uint32 id) +void Unit::SendPlaySpellVisualKit(uint32 id, uint32 unkParam) { ObjectGuid guid = GetGUID(); - WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 4 * 3 + 8); - data << uint32(0); - data << uint32(id); // SpellVisualKit.dbc index + WorldPacket data(SMSG_PLAY_SPELL_VISUAL_KIT, 4 + 4+ 4 + 8); data << uint32(0); + data << uint32(id); // SpellVisualKit.dbc index + data << uint32(unkParam); data.WriteBit(guid[4]); data.WriteBit(guid[7]); data.WriteBit(guid[5]); @@ -15679,15 +15684,7 @@ void Unit::SendPlaySpellVisual(uint32 id) data.WriteByteSeq(guid[2]); data.WriteByteSeq(guid[3]); data.WriteByteSeq(guid[5]); - SendMessageToSet(&data, false); -} - -void Unit::SendPlaySpellImpact(uint64 guid, uint32 id) -{ - WorldPacket data(SMSG_PLAY_SPELL_IMPACT, 8 + 4); - data << uint64(guid); // target - data << uint32(id); // SpellVisualKit.dbc index - SendMessageToSet(&data, false); + SendMessageToSet(&data, true); } void Unit::ApplyResilience(Unit const* victim, float* crit, int32* damage, bool isCrit, CombatRating type) const diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 9dcb981c95a..4e68ae9a3a0 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -623,17 +623,24 @@ enum UnitFlags // Value masks for UNIT_FIELD_FLAGS_2 enum UnitFlags2 { - UNIT_FLAG2_FEIGN_DEATH = 0x00000001, - UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) - UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, - UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, - UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, - UNIT_FLAG2_FORCE_MOVE = 0x00000040, - UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, - UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) - UNIT_FLAG2_REGENERATE_POWER = 0x00000800, - UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, - UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) + UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, + UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, + UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, + UNIT_FLAG2_INSTANTLY_APPEAR_MODEL = 0x00000020, // Unit model instantly appears when summoned (does not fade in) + UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040, + UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, + UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames) + UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) + UNIT_FLAG2_REGENERATE_POWER = 0x00000800, + UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid + UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick + UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, + UNIT_FLAG2_DISABLE_TURN = 0x00008000, + UNIT_FLAG2_UNK2 = 0x00010000, + UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death + UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000, // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL }; /// Non Player Character flags @@ -1572,8 +1579,7 @@ class Unit : public WorldObject Aura* AddAura(uint32 spellId, Unit* target); Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target); void SetAuraStack(uint32 spellId, Unit* target, uint32 stack); - void SendPlaySpellVisual(uint32 id); - void SendPlaySpellImpact(uint64 guid, uint32 id); + void SendPlaySpellVisualKit(uint32 id, uint32 unkParam); void DeMorph(); @@ -2192,10 +2198,14 @@ class Unit : public WorldObject virtual bool isBeingLoaded() const { return false;} bool IsDuringRemoveFromWorld() const {return m_duringRemoveFromWorld;} - Pet* ToPet(){ if (isPet()) return reinterpret_cast<Pet*>(this); else return NULL; } - Totem* ToTotem(){ if (isTotem()) return reinterpret_cast<Totem*>(this); else return NULL; } + Pet* ToPet() { if (isPet()) return reinterpret_cast<Pet*>(this); else return NULL; } + Pet const* ToPet() const { if (isPet()) return reinterpret_cast<Pet const*>(this); else return NULL; } + + Totem* ToTotem() { if (isTotem()) return reinterpret_cast<Totem*>(this); else return NULL; } + Totem const* ToTotem() const { if (isTotem()) return reinterpret_cast<Totem const*>(this); else return NULL; } + TempSummon* ToTempSummon() { if (isSummon()) return reinterpret_cast<TempSummon*>(this); else return NULL; } - const TempSummon* ToTempSummon() const { if (isSummon()) return reinterpret_cast<const TempSummon*>(this); else return NULL; } + TempSummon const* ToTempSummon() const { if (isSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; } void SetTarget(uint64 guid) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index b87cb2d7fbf..2f128a70b02 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -369,17 +369,17 @@ void ObjectMgr::LoadCreatureTemplates() QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " // 9 10 11 12 13 14 15 16 17 18 19 20 21 "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, " - // 22 23 24 25 26 27 28 29 30 31 32 33 - "speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, " - // 34 35 36 37 38 39 40 41 42 43 + // 22 23 24 25 26 27 28 29 30 31 32 33 34 + "speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, " + // 35 36 37 38 39 40 41 42 43 44 "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 44 45 46 47 48 49 50 51 52 53 54 + // 45 46 47 48 49 50 51 52 53 54 55 "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, " - // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 + // 56 57 58 59 60 61 62 63 64 65 66 67 68 69 "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 69 70 71 72 73 74 75 76 77 78 79 80 + // 70 71 72 73 74 75 76 77 78 79 80 81 "InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 81 82 83 84 85 86 87 + // 82 83 84 85 86 87 88 " questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName " "FROM creature_template;"); @@ -436,51 +436,52 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.rangeattacktime = fields[31].GetUInt32(); creatureTemplate.unit_class = uint32(fields[32].GetUInt8()); creatureTemplate.unit_flags = fields[33].GetUInt32(); - creatureTemplate.dynamicflags = fields[34].GetUInt32(); - creatureTemplate.family = uint32(fields[35].GetUInt8()); - creatureTemplate.trainer_type = uint32(fields[36].GetUInt8()); - creatureTemplate.trainer_spell = fields[37].GetUInt32(); - creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); - creatureTemplate.minrangedmg = fields[40].GetFloat(); - creatureTemplate.maxrangedmg = fields[41].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); - creatureTemplate.type = uint32(fields[43].GetUInt8()); - creatureTemplate.type_flags = fields[44].GetUInt32(); - creatureTemplate.type_flags2 = fields[45].GetUInt32(); - creatureTemplate.lootid = fields[46].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[47].GetUInt32(); - creatureTemplate.SkinLootId = fields[48].GetUInt32(); + creatureTemplate.unit_flags2 = fields[34].GetUInt32(); + creatureTemplate.dynamicflags = fields[35].GetUInt32(); + creatureTemplate.family = uint32(fields[36].GetUInt8()); + creatureTemplate.trainer_type = uint32(fields[37].GetUInt8()); + creatureTemplate.trainer_spell = fields[38].GetUInt32(); + creatureTemplate.trainer_class = uint32(fields[39].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[40].GetUInt8()); + creatureTemplate.minrangedmg = fields[41].GetFloat(); + creatureTemplate.maxrangedmg = fields[42].GetFloat(); + creatureTemplate.rangedattackpower = uint32(fields[43].GetUInt16()); + creatureTemplate.type = uint32(fields[44].GetUInt8()); + creatureTemplate.type_flags = fields[45].GetUInt32(); + creatureTemplate.type_flags2 = fields[46].GetUInt32(); + creatureTemplate.lootid = fields[47].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[48].GetUInt32(); + creatureTemplate.SkinLootId = fields[49].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); + creatureTemplate.resistance[i] = fields[50 + i - 1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[63].GetUInt32(); - creatureTemplate.VehicleId = fields[64].GetUInt32(); - creatureTemplate.mingold = fields[65].GetUInt32(); - creatureTemplate.maxgold = fields[66].GetUInt32(); - creatureTemplate.AIName = fields[67].GetString(); - creatureTemplate.MovementType = uint32(fields[68].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[69].GetUInt8()); - creatureTemplate.HoverHeight = fields[70].GetFloat(); - creatureTemplate.ModHealth = fields[71].GetFloat(); - creatureTemplate.ModMana = fields[72].GetFloat(); - creatureTemplate.ModManaExtra = fields[73].GetFloat(); - creatureTemplate.ModArmor = fields[74].GetFloat(); - creatureTemplate.RacialLeader = fields[75].GetBool(); + creatureTemplate.spells[i] = fields[56 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[64].GetUInt32(); + creatureTemplate.VehicleId = fields[65].GetUInt32(); + creatureTemplate.mingold = fields[66].GetUInt32(); + creatureTemplate.maxgold = fields[67].GetUInt32(); + creatureTemplate.AIName = fields[68].GetString(); + creatureTemplate.MovementType = uint32(fields[69].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[70].GetUInt8()); + creatureTemplate.HoverHeight = fields[71].GetFloat(); + creatureTemplate.ModHealth = fields[72].GetFloat(); + creatureTemplate.ModMana = fields[73].GetFloat(); + creatureTemplate.ModManaExtra = fields[74].GetFloat(); + creatureTemplate.ModArmor = fields[75].GetFloat(); + creatureTemplate.RacialLeader = fields[76].GetBool(); for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[76 + i].GetUInt32(); + creatureTemplate.questItems[i] = fields[77 + i].GetUInt32(); - creatureTemplate.movementId = fields[82].GetUInt32(); - creatureTemplate.RegenHealth = fields[83].GetBool(); - creatureTemplate.equipmentId = fields[84].GetUInt32(); - creatureTemplate.MechanicImmuneMask = fields[85].GetUInt32(); - creatureTemplate.flags_extra = fields[86].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[87].GetCString()); + creatureTemplate.movementId = fields[83].GetUInt32(); + creatureTemplate.RegenHealth = fields[84].GetBool(); + creatureTemplate.equipmentId = fields[85].GetUInt32(); + creatureTemplate.MechanicImmuneMask = fields[86].GetUInt32(); + creatureTemplate.flags_extra = fields[87].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[88].GetCString()); ++count; } @@ -7875,8 +7876,6 @@ void ObjectMgr::LoadTrainerSpell() // For reload case _cacheTrainerSpellStore.clear(); - std::set<uint32> skip_trainers; - QueryResult result = WorldDatabase.Query("SELECT b.entry, a.spell, a.spellcost, a.reqskill, a.reqskillvalue, a.reqlevel FROM npc_trainer AS a " "INNER JOIN npc_trainer AS b ON a.entry = -(b.spell) " "UNION SELECT * FROM npc_trainer WHERE spell > 0"); diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h index b5701a7a590..6bf558a4d5e 100755 --- a/src/server/game/Grids/NGrid.h +++ b/src/server/game/Grids/NGrid.h @@ -79,9 +79,8 @@ class NGrid public: typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridType; NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true) - : i_gridId(id), i_x(x), i_y(y), i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false) + : i_gridId(id), i_x(x), i_y(y), i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false), i_GridInfo(GridInfo(expiry, unload)) { - i_GridInfo = GridInfo(expiry, unload); } GridType& GetGridType(const uint32 x, const uint32 y) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index d0bbaffacea..b9ede2ec985 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1531,6 +1531,7 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) { data << uint8(sLFGMgr->GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done data << uint32(sLFGMgr->GetDungeon(m_guid)); + data << uint8(0); // 4.x new } data << uint64(m_guid); @@ -1543,7 +1544,7 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) Player* member = ObjectAccessor::FindPlayer(citr->guid); - uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; + uint8 onlineState = member ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0); data << citr->name; diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index e6da9caea32..c24b3f3deae 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -96,36 +96,38 @@ enum GroupType enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing - GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags - GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32 - GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32 - GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 - GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // uint16 - GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // uint16 - GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 - GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 - GROUP_UPDATE_FLAG_POSITION = 0x00000100, // uint16, uint16 - GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint32 spellid + uint8 unk - GROUP_UPDATE_FLAG_PET_GUID = 0x00000400, // uint64 pet guid - GROUP_UPDATE_FLAG_PET_NAME = 0x00000800, // pet name, NULL terminated string - GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00001000, // uint16, model id - GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint32 pet cur health - GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint32 pet max health - GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00008000, // uint8 pet power type - GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power - GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power - GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras... - GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint8, uint64, if (uint32 != 0) { uint32, if (uint16 & 0x40) { uint32, uint32, uint32 } } - GROUP_UPDATE_FLAG_UNKNOWN_1 = 0x00100000, // uint32 - GROUP_UPDATE_FLAG_UNKNOWN_2 = 0x00200000, // uint32, uint32, string - GROUP_UPDATE_PET = 0x0007FC00, // all pet flags - GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags + GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16 (GroupMemberStatusFlag) + GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32 (HP) + GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32 (HP) + GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 (PowerType) + GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // int16 (power value) + GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // int16 (power value) + GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 (level value) + GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 (zone id) + GROUP_UPDATE_FLAG_UNK100 = 0x00000100, // int16 (unk) + GROUP_UPDATE_FLAG_POSITION = 0x00000200, // uint16 (x), uint16 (y), uint16 (z) + GROUP_UPDATE_FLAG_AURAS = 0x00000400, // uint8 (unk), uint64 (mask), uint32 (count), for each bit set: uint32 (spell id) + uint16 (AuraFlags) (if has flags Scalable -> 3x int32 (bps)) + GROUP_UPDATE_FLAG_PET_GUID = 0x00000800, // uint64 (pet guid) + GROUP_UPDATE_FLAG_PET_NAME = 0x00001000, // cstring (name, NULL terminated string) + GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00002000, // uint16 (model id) + GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00004000, // uint32 (HP) + GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00008000, // uint32 (HP) + GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00010000, // uint8 (PowerType) + GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00020000, // uint16 (power value) + GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00040000, // uint16 (power value) + GROUP_UPDATE_FLAG_PET_AURAS = 0x00080000, // [see GROUP_UPDATE_FLAG_AURAS] + GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00100000, // int32 (vehicle seat id) + GROUP_UPDATE_FLAG_PHASE = 0x00200000, // int32 (unk), uint32 (phase count), for (count) uint16(phaseId) + + GROUP_UPDATE_PET = GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | + GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | + GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER | GROUP_UPDATE_FLAG_PET_AURAS, // all pet flags + GROUP_UPDATE_FULL = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | + GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | + GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | + GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_PET | GROUP_UPDATE_FLAG_PHASE, // all known flags, except UNK100 and VEHICLE_SEAT }; -#define GROUP_UPDATE_FLAGS_COUNT 20 - // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 -static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 2, 2, 2, 1, 2, 2, 2, 2, 4, 8, 8, 1, 2, 2, 2, 1, 2, 2, 8}; - class Roll : public LootValidatorRef { public: diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4b193b62b2b..ba9d8610c12 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -99,9 +99,13 @@ inline void Guild::LogHolder::AddEvent(SQLTransaction& trans, LogEntry* entry) // Writes information about all events into packet. inline void Guild::LogHolder::WritePacket(WorldPacket& data) const { - data << uint8(m_log.size()); + ByteBuffer buffer; + data.WriteBits(m_log.size(), 23); for (GuildLog::const_iterator itr = m_log.begin(); itr != m_log.end(); ++itr) - (*itr)->WritePacket(data); + (*itr)->WritePacket(data, buffer); + + data.FlushBits(); + data.append(buffer); } inline uint32 Guild::LogHolder::GetNextGUID() @@ -138,20 +142,56 @@ void Guild::EventLogEntry::SaveToDB(SQLTransaction& trans) const CharacterDatabase.ExecuteOrAppend(trans, stmt); } -void Guild::EventLogEntry::WritePacket(WorldPacket& data) const +void Guild::EventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& content) const { - // Event type - data << uint8(m_eventType); - // Player 1 - data << uint64(MAKE_NEW_GUID(m_playerGuid1, 0, HIGHGUID_PLAYER)); - // Player 2 not for left/join guild events - if (m_eventType != GUILD_EVENT_LOG_JOIN_GUILD && m_eventType != GUILD_EVENT_LOG_LEAVE_GUILD) - data << uint64(MAKE_NEW_GUID(m_playerGuid2, 0, HIGHGUID_PLAYER)); - // New Rank - only for promote/demote guild events - if (m_eventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || m_eventType == GUILD_EVENT_LOG_DEMOTE_PLAYER) - data << uint8(m_newRank); + ObjectGuid guid1 = MAKE_NEW_GUID(m_playerGuid1, 0, HIGHGUID_PLAYER); + ObjectGuid guid2 = MAKE_NEW_GUID(m_playerGuid2, 0, HIGHGUID_PLAYER); + + data.WriteBit(guid1[2]); + data.WriteBit(guid1[4]); + data.WriteBit(guid2[7]); + data.WriteBit(guid2[6]); + data.WriteBit(guid1[3]); + data.WriteBit(guid2[3]); + data.WriteBit(guid2[5]); + data.WriteBit(guid1[7]); + data.WriteBit(guid1[5]); + data.WriteBit(guid1[0]); + data.WriteBit(guid2[4]); + data.WriteBit(guid2[2]); + data.WriteBit(guid2[0]); + data.WriteBit(guid2[1]); + data.WriteBit(guid1[1]); + data.WriteBit(guid1[6]); + + content.WriteByteSeq(guid2[3]); + content.WriteByteSeq(guid2[2]); + content.WriteByteSeq(guid2[5]); + + // New Rank + content << uint8(m_newRank); + + content.WriteByteSeq(guid2[4]); + content.WriteByteSeq(guid1[0]); + content.WriteByteSeq(guid1[4]); + // Event timestamp - data << uint32(::time(NULL) - m_timestamp); + content << uint32(::time(NULL) - m_timestamp); + + content.WriteByteSeq(guid1[7]); + content.WriteByteSeq(guid1[3]); + content.WriteByteSeq(guid2[0]); + content.WriteByteSeq(guid2[6]); + content.WriteByteSeq(guid2[7]); + content.WriteByteSeq(guid1[5]); + + // Event type + content << uint8(m_eventType); + + content.WriteByteSeq(guid2[1]); + content.WriteByteSeq(guid1[2]); + content.WriteByteSeq(guid1[6]); + content.WriteByteSeq(guid1[1]); } /////////////////////////////////////////////////////////////////////////////// @@ -181,20 +221,52 @@ void Guild::BankEventLogEntry::SaveToDB(SQLTransaction& trans) const CharacterDatabase.ExecuteOrAppend(trans, stmt); } -void Guild::BankEventLogEntry::WritePacket(WorldPacket& data) const +void Guild::BankEventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& content) const { - data << uint8(m_eventType); - data << uint64(MAKE_NEW_GUID(m_playerGuid, 0, HIGHGUID_PLAYER)); - data << uint32(m_itemOrMoney); - // if ( m_eventType != 4 || m_eventType != 5 || m_eventType != 6 || m_eventType != 8 || m_eventType != 9 ) - if (m_eventType < GUILD_BANK_LOG_DEPOSIT_MONEY) - { - data << uint32(m_itemStackCount); - if (m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2) - data << uint8(m_destTabId); - } + ObjectGuid logGuid = MAKE_NEW_GUID(m_playerGuid, 0, HIGHGUID_PLAYER); + + bool hasItem = m_eventType == GUILD_BANK_LOG_DEPOSIT_ITEM || m_eventType == GUILD_BANK_LOG_WITHDRAW_ITEM || + m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2; + + bool itemMoved = (m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2); + + bool hasStack = (hasItem && m_itemStackCount > 1) || itemMoved; + + data.WriteBit(IsMoneyEvent()); + data.WriteBit(logGuid[4]); + data.WriteBit(logGuid[1]); + data.WriteBit(hasItem); + data.WriteBit(hasStack); + data.WriteBit(logGuid[2]); + data.WriteBit(logGuid[5]); + data.WriteBit(logGuid[3]); + data.WriteBit(logGuid[6]); + data.WriteBit(logGuid[0]); + data.WriteBit(itemMoved); + data.WriteBit(logGuid[7]); - data << uint32(time(NULL) - m_timestamp); + content.WriteByteSeq(logGuid[6]); + content.WriteByteSeq(logGuid[1]); + content.WriteByteSeq(logGuid[5]); + if (hasStack) + content << uint32(m_itemStackCount); + + content << uint8(m_eventType); + content.WriteByteSeq(logGuid[2]); + content.WriteByteSeq(logGuid[4]); + content.WriteByteSeq(logGuid[0]); + content.WriteByteSeq(logGuid[7]); + content.WriteByteSeq(logGuid[3]); + if (hasItem) + content << uint32(m_itemOrMoney); + + content << uint32(time(NULL) - m_timestamp); + + if (IsMoneyEvent()) + content << uint64(m_itemOrMoney); + + if (itemMoved) + content << uint8(m_destTabId); } /////////////////////////////////////////////////////////////////////////////// @@ -403,12 +475,12 @@ void Guild::BankTab::SetText(const std::string& text) // Sets/removes contents of specified slot. // If pItem == NULL contents are removed. -bool Guild::BankTab::SetItem(SQLTransaction& trans, uint8 slotId, Item* pItem) +bool Guild::BankTab::SetItem(SQLTransaction& trans, uint8 slotId, Item* item) { if (slotId >= GUILD_BANK_MAX_SLOTS) return false; - m_items[slotId] = pItem; + m_items[slotId] = item; PreparedStatement* stmt = NULL; @@ -418,28 +490,29 @@ bool Guild::BankTab::SetItem(SQLTransaction& trans, uint8 slotId, Item* pItem) stmt->setUInt8 (2, slotId); CharacterDatabase.ExecuteOrAppend(trans, stmt); - if (pItem) + if (item) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_BANK_ITEM); stmt->setUInt32(0, m_guildId); stmt->setUInt8 (1, m_tabId); stmt->setUInt8 (2, slotId); - stmt->setUInt32(3, pItem->GetGUIDLow()); + stmt->setUInt32(3, item->GetGUIDLow()); CharacterDatabase.ExecuteOrAppend(trans, stmt); - pItem->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); - pItem->SetUInt64Value(ITEM_FIELD_OWNER, 0); - pItem->FSetState(ITEM_NEW); - pItem->SaveToDB(trans); // Not in inventory and can be saved standalone + item->SetUInt64Value(ITEM_FIELD_CONTAINED, 0); + item->SetUInt64Value(ITEM_FIELD_OWNER, 0); + item->FSetState(ITEM_NEW); + item->SaveToDB(trans); // Not in inventory and can be saved standalone } return true; } -void Guild::BankTab::SendText(const Guild* guild, WorldSession* session) const +void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const { - WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1 + m_text.size() + 1); - data << uint8(m_tabId); - data << m_text; + WorldPacket data(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, 1 + m_text.size() + 1); + data.WriteBits(m_text.length(), 14); + data << uint32(m_tabId); + data.WriteString(m_text); if (session) session->SendPacket(&data); @@ -1119,6 +1192,15 @@ void Guild::Disband() sGuildMgr->RemoveGuild(m_id); } +void Guild::SaveToDB() +{ + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + m_achievementMgr.SaveToDB(trans); + + CharacterDatabase.CommitTransaction(trans); +} + /////////////////////////////////////////////////////////////////////////////// // HANDLE CLIENT COMMANDS void Guild::HandleRoster(WorldSession* session /*= NULL*/) @@ -1833,6 +1915,8 @@ void Guild::HandleMemberLogout(WorldSession* session) member->UpdateLogoutTime(); } _BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName()); + + SaveToDB(); } void Guild::HandleDisband(WorldSession* session) @@ -1871,10 +1955,10 @@ void Guild::HandleGuildPartyRequest(WorldSession* session) // Send data to client void Guild::SendEventLog(WorldSession* session) const { - WorldPacket data(MSG_GUILD_EVENT_LOG_QUERY, 1 + m_eventLog->GetSize() * (1 + 8 + 4)); + WorldPacket data(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, 1 + m_eventLog->GetSize() * (1 + 8 + 4)); m_eventLog->WritePacket(data); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)"); + sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_EVENT_LOG_QUERY_RESULT)"); } void Guild::SendBankLog(WorldSession* session, uint8 tabId) const @@ -1882,12 +1966,15 @@ void Guild::SendBankLog(WorldSession* session, uint8 tabId) const // GUILD_BANK_MAX_TABS send by client for money log if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS) { - const LogHolder* pLog = m_bankEventLog[tabId]; - WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, pLog->GetSize() * (4 * 4 + 1) + 1 + 1); - data << uint8(tabId); - pLog->WritePacket(data); + LogHolder const* log = m_bankEventLog[tabId]; + WorldPacket data(SMSG_GUILD_BANK_LOG_QUERY_RESULT, log->GetSize() * (4 * 4 + 1) + 1 + 1); + data.WriteBit(GetLevel() >= 5 && tabId == GUILD_BANK_MAX_TABS); // has Cash Flow perk + log->WritePacket(data); + data << uint32(tabId); + //if (tabId == GUILD_BANK_MAX_TABS && hasCashFlow) + // data << uint64(cashFlowContribution); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)"); + sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_BANK_LOG_QUERY_RESULT) for tab %u", tabId); } } @@ -1978,8 +2065,8 @@ void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, b void Guild::SendBankTabText(WorldSession* session, uint8 tabId) const { - if (const BankTab* pTab = GetBankTab(tabId)) - pTab->SendText(this, session); + if (BankTab const* tab = GetBankTab(tabId)) + tab->SendText(this, session); } void Guild::SendPermissions(WorldSession* session) const @@ -2758,6 +2845,10 @@ void Guild::_LogBankEvent(SQLTransaction& trans, GuildBankEventLogTypes eventTyp if (tabId > GUILD_BANK_MAX_TABS) return; + // not logging moves within the same tab + if (eventType == GUILD_BANK_LOG_MOVE_ITEM && tabId == destTabId) + return; + uint8 dbTabId = tabId; if (BankEventLogEntry::IsMoneyEvent(eventType)) { diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 67888f636ff..1adf1675c45 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -184,15 +184,16 @@ enum GuildBankRights enum GuildBankEventLogTypes { - GUILD_BANK_LOG_DEPOSIT_ITEM = 1, - GUILD_BANK_LOG_WITHDRAW_ITEM = 2, - GUILD_BANK_LOG_MOVE_ITEM = 3, - GUILD_BANK_LOG_DEPOSIT_MONEY = 4, - GUILD_BANK_LOG_WITHDRAW_MONEY = 5, - GUILD_BANK_LOG_REPAIR_MONEY = 6, - GUILD_BANK_LOG_MOVE_ITEM2 = 7, - GUILD_BANK_LOG_UNK1 = 8, - GUILD_BANK_LOG_BUY_SLOT = 9, + GUILD_BANK_LOG_DEPOSIT_ITEM = 1, + GUILD_BANK_LOG_WITHDRAW_ITEM = 2, + GUILD_BANK_LOG_MOVE_ITEM = 3, + GUILD_BANK_LOG_DEPOSIT_MONEY = 4, + GUILD_BANK_LOG_WITHDRAW_MONEY = 5, + GUILD_BANK_LOG_REPAIR_MONEY = 6, + GUILD_BANK_LOG_MOVE_ITEM2 = 7, + GUILD_BANK_LOG_UNK1 = 8, + GUILD_BANK_LOG_BUY_SLOT = 9, + GUILD_BANK_LOG_CASH_FLOW_DEPOSIT = 10, }; enum GuildEventLogTypes @@ -357,7 +358,7 @@ private: uint32 GetGUID() const { return m_guid; } virtual void SaveToDB(SQLTransaction& trans) const = 0; - virtual void WritePacket(WorldPacket& data) const = 0; + virtual void WritePacket(WorldPacket& data, ByteBuffer& content) const = 0; protected: uint32 m_guildId; @@ -378,7 +379,7 @@ private: ~EventLogEntry() { } void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data) const; + void WritePacket(WorldPacket& data, ByteBuffer& content) const; private: GuildEventLogTypes m_eventType; @@ -396,7 +397,13 @@ private: return eventType == GUILD_BANK_LOG_DEPOSIT_MONEY || eventType == GUILD_BANK_LOG_WITHDRAW_MONEY || - eventType == GUILD_BANK_LOG_REPAIR_MONEY; + eventType == GUILD_BANK_LOG_REPAIR_MONEY || + eventType == GUILD_BANK_LOG_CASH_FLOW_DEPOSIT; + } + + bool IsMoneyEvent() const + { + return IsMoneyEvent(m_eventType); } BankEventLogEntry(uint32 guildId, uint32 guid, GuildBankEventLogTypes eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) : @@ -410,7 +417,7 @@ private: ~BankEventLogEntry() { } void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data) const; + void WritePacket(WorldPacket& data, ByteBuffer& content) const; private: GuildBankEventLogTypes m_eventType; @@ -502,16 +509,16 @@ private: bool LoadItemFromDB(Field* fields); void Delete(SQLTransaction& trans, bool removeItemsFromDB = false); - void SetInfo(const std::string& name, const std::string& icon); - void SetText(const std::string& text); - void SendText(const Guild* guild, WorldSession* session) const; + void SetInfo(std::string const& name, std::string const& icon); + void SetText(std::string const& text); + void SendText(Guild const* guild, WorldSession* session) const; std::string const& GetName() const { return m_name; } std::string const& GetIcon() const { return m_icon; } std::string const& GetText() const { return m_text; } inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : NULL; } - bool SetItem(SQLTransaction& trans, uint8 slotId, Item* pItem); + bool SetItem(SQLTransaction& trans, uint8 slotId, Item* item); private: uint32 m_guildId; @@ -623,6 +630,8 @@ public: bool Create(Player* pLeader, const std::string& name); void Disband(); + void SaveToDB(); + // Getters uint32 GetId() const { return m_id; } uint64 GetGUID() const { return MAKE_NEW_GUID(m_id, 0, HIGHGUID_GUILD); } @@ -699,6 +708,7 @@ public: void DeleteMember(uint64 guid, bool isDisbanding = false, bool isKicked = false); bool ChangeMemberRank(uint64 guid, uint8 newRank); bool IsMember(uint64 guid); + uint32 GetMembersCount() { return m_members.size(); } // Bank void SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount); diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index 473fe32ec27..04b0cfeaa39 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -39,6 +39,12 @@ void GuildMgr::RemoveGuild(uint32 guildId) GuildStore.erase(guildId); } +void GuildMgr::SaveGuilds() +{ + for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) + itr->second->SaveToDB(); +} + uint32 GuildMgr::GenerateGuildId() { if (NextGuildId >= 0xFFFFFFFE) diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index d9c18a8026d..4b999c9231a 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -40,6 +40,8 @@ public: void AddGuild(Guild* guild); void RemoveGuild(uint32 guildId); + void SaveGuilds(); + uint32 GenerateGuildId(); void SetNextGuildId(uint32 Id) { NextGuildId = Id; } diff --git a/src/server/game/Handlers/AddonHandler.cpp b/src/server/game/Handlers/AddonHandler.cpp index f86dacbc55e..c3ffeace3fb 100755 --- a/src/server/game/Handlers/AddonHandler.cpp +++ b/src/server/game/Handlers/AddonHandler.cpp @@ -37,26 +37,6 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) uint32 CurrentPosition; uint32 TempValue; - unsigned char tdata[256] = - { - 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54, - 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75, - 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34, - 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8, - 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8, - 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A, - 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3, - 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9, - 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22, - 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E, - 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB, - 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7, - 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0, - 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6, - 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, - 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 - }; - // broken addon packet, can't be received from real client if (Source->rpos() + 4 > Source->size()) return false; @@ -110,7 +90,28 @@ bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) uint8 unk = (crc != 0x4c1c776d); // If addon is Standard addon CRC *Target << uint8(unk); if (unk) + { + unsigned char tdata[256] = + { + 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54, + 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75, + 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34, + 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8, + 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8, + 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A, + 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3, + 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9, + 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22, + 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E, + 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB, + 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7, + 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0, + 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6, + 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, + 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 + }; Target->append(tdata, sizeof(tdata)); + } *Target << uint32(0); } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index d1da504008e..085b5181913 100755 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -72,17 +72,35 @@ void WorldSession::SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) { - uint64 guid; uint32 bgTypeId_; uint32 instanceId; - uint8 joinAsGroup; + uint8 asGroup; bool isPremade = false; Group* grp = NULL; - - recvData >> guid; // battlemaster guid - recvData >> bgTypeId_; // battleground type id (DBC id) - recvData >> instanceId; // instance id, 0 if First Available selected - recvData >> joinAsGroup; // join as group + ObjectGuid guid; + + recvData >> instanceId; // Instance Id + guid[2] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + asGroup = recvData.ReadBit(); // As Group + guid[4] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[5]); + recvData.ReadByteSeq(guid[1]); + + //extract from guid + bgTypeId_ = GUID_LOPART(guid); if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { @@ -95,10 +113,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; } - BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); + //sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID:"UI64FMTD" TypeId:%u)", guid, bgTypeId_); // can do this, since it's battleground, not arena BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0); @@ -126,13 +143,13 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) GroupJoinBattlegroundResult err; // check queue conditions - if (!joinAsGroup) + if (!asGroup) { if (GetPlayer()->isUsingLfg()) { // player is using dungeon finder or raid finder WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, ERR_LFG_CANT_USE_BATTLEGROUND); GetPlayer()->GetSession()->SendPacket(&data); return; } @@ -141,7 +158,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) if (!_player->CanJoinToBattleground()) { WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data); return; } @@ -150,7 +167,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) { //player is already in random queue WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, ERR_IN_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } @@ -159,7 +176,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) { //player is already in queue, can't start random queue WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, ERR_IN_NON_RANDOM_BG); _player->GetSession()->SendPacket(&data); return; } @@ -173,7 +190,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) if (!_player->HasFreeBattlegroundQueueId()) { WorldPacket data; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, ERR_BATTLEGROUND_TOO_MANY_QUEUES); _player->GetSession()->SendPacket(&data); return; } @@ -187,7 +204,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) WorldPacket data; // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); } @@ -223,7 +240,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) if (err <= 0) { - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, err); member->GetSession()->SendPacket(&data); continue; } @@ -232,9 +249,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); member->GetSession()->SendPacket(&data); - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, err); member->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); } @@ -246,13 +263,14 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recvData*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message"); Battleground* bg = _player->GetBattleground(); if (!bg) // can't be received if player not in battleground return; - uint32 count = 0; + uint32 acount = 0; + uint32 hcount = 0; Player* aplr = NULL; Player* hplr = NULL; @@ -260,31 +278,75 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recvD { aplr = ObjectAccessor::FindPlayer(guid); if (aplr) - ++count; + ++acount; } if (uint64 guid = bg->GetFlagPickerGUID(BG_TEAM_HORDE)) { hplr = ObjectAccessor::FindPlayer(guid); if (hplr) - ++count; + ++hcount; } - WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * count); - data << 0; - data << count; - if (aplr) + ObjectGuid aguid = aplr ? aplr->GetGUID() : 0; + ObjectGuid hguid = hplr ? hplr->GetGUID() : 0; + + WorldPacket data(SMSG_BATTLEFIELD_PLAYER_POSITIONS); + + data.WriteBits(acount, 22); + for (uint8 i = 0; i < acount; i++) { - data << uint64(aplr->GetGUID()); - data << float(aplr->GetPositionX()); - data << float(aplr->GetPositionY()); + data.WriteBit(aguid[3]); + data.WriteBit(aguid[5]); + data.WriteBit(aguid[1]); + data.WriteBit(aguid[6]); + data.WriteBit(aguid[7]); + data.WriteBit(aguid[0]); + data.WriteBit(aguid[2]); + data.WriteBit(aguid[4]); } - if (hplr) + data.WriteBits(hcount, 22); + for (uint8 i = 0; i < hcount; i++) { - data << uint64(hplr->GetGUID()); - data << float(hplr->GetPositionX()); + data.WriteBit(hguid[6]); + data.WriteBit(hguid[5]); + data.WriteBit(hguid[4]); + data.WriteBit(hguid[7]); + data.WriteBit(hguid[2]); + data.WriteBit(hguid[1]); + data.WriteBit(hguid[0]); + data.WriteBit(hguid[3]); + } + + data.FlushBits(); + + for (uint8 i = 0; i < hcount; i++) + { + data.WriteByteSeq(hguid[2]); + data.WriteByteSeq(hguid[1]); data << float(hplr->GetPositionY()); + data.WriteByteSeq(hguid[5]); + data.WriteByteSeq(hguid[4]); + data.WriteByteSeq(hguid[7]); + data.WriteByteSeq(hguid[0]); + data.WriteByteSeq(hguid[6]); + data.WriteByteSeq(hguid[3]); + data << float(hplr->GetPositionX()); + } + + for (uint8 i = 0; i < acount; i++) + { + data.WriteByteSeq(aguid[6]); + data << float(aplr->GetPositionX()); + data.WriteByteSeq(aguid[5]); + data.WriteByteSeq(aguid[3]); + data << float(aplr->GetPositionY()); + data.WriteByteSeq(aguid[1]); + data.WriteByteSeq(aguid[7]); + data.WriteByteSeq(aguid[0]); + data.WriteByteSeq(aguid[2]); + data.WriteByteSeq(aguid[4]); } SendPacket(&data); @@ -292,7 +354,7 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recvD void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_PVP_LOG_DATA Message"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_PVP_LOG_DATA Message"); Battleground* bg = _player->GetBattleground(); if (!bg) @@ -306,7 +368,7 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) sBattlegroundMgr->BuildPvpLogDataPacket(&data, bg); SendPacket(&data); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent MSG_PVP_LOG_DATA Message"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_PVP_LOG_DATA Message"); } void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData) @@ -332,13 +394,35 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); - uint8 type; // arenatype if arena - uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 + uint32 time; + uint32 type; // guessed uint32 bgTypeId_; // type id from dbc - uint16 unk; // 0x1F90 constant? uint8 action; // enter battle 0x1, leave queue 0x0 - - recvData >> type >> unk2 >> bgTypeId_ >> unk >> action; + ObjectGuid guid; + + recvData >> time; + recvData >> type; + recvData >> bgTypeId_; + + guid[0] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[2] = recvData.ReadBit(); + + action = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[5]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[4]); if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { @@ -394,7 +478,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { //send bg command result to show nice message WorldPacket data2; - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, bg, _player, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data2); action = 0; sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); @@ -431,7 +515,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) _player->CleanupAfterTaxiFlight(); } - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr bgQueue.RemovePlayer(_player->GetGUID(), false); @@ -463,7 +547,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } } _player->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_NONE, 0, 0, 0); bgQueue.RemovePlayer(_player->GetGUID(), true); // player left queue, we should update it - do not update Arena Queue if (!ginfo.ArenaType) @@ -477,14 +561,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } } -void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recvData) +void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message"); - - recvData.read_skip<uint8>(); // unk1 - recvData.read_skip<uint8>(); // unk2 - recvData.read_skip<uint32>(); // BattlegroundTypeId - recvData.read_skip<uint16>(); // unk3 + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_LEAVE Message"); // not allow leave battleground in combat if (_player->isInCombat()) @@ -519,7 +598,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // this line is checked, i only don't know if GetStartTime is changing itself after bg end! // send status in Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType); SendPacket(&data); continue; } @@ -537,7 +616,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) continue; uint32 remainingTime = getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime); // send status invited to Battleground - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType); SendPacket(&data); } else @@ -553,7 +632,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId()); // send status in Battleground Queue - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType); SendPacket(&data); } } @@ -696,7 +775,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recvData) if (err <= 0) { - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, err); member->GetSession()->SendPacket(&data); continue; } @@ -705,9 +784,9 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recvData) uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId); // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); member->GetSession()->SendPacket(&data); - sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); + sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, bg, _player, err); member->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName()); } @@ -720,7 +799,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recvData) WorldPacket data; // send status packet (in queue) - sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); + sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); SendPacket(&data); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName()); } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 649f09ad212..c7b66381158 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -740,11 +740,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recvData) { std::string dump; if (PlayerDumpWriter().GetDump(GUID_LOPART(guid), dump)) - { - std::ostringstream ss; - ss << GetAccountId() << '_' << name.c_str(); - sLog->outCharDump(ss.str().c_str(), dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); - } + sLog->outCharDump(dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); } Player::DeleteFromDB(guid, GetAccountId()); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index ae549d76b33..1d6cbf61c68 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -33,6 +33,7 @@ #include "Vehicle.h" #include "DB2Structure.h" #include "DB2Stores.h" +#include "SpellAuraEffects.h" class Aura; @@ -180,7 +181,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recvData) data.WriteBit(invitedGuid[4]); - data.WriteBits(strlen(player->GetName()), 7); // Invited name length + data.WriteBits(strlen(GetPlayer()->GetName()), 7); // Inviter name length data.WriteBits(0, 24); // Count 2 @@ -211,7 +212,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recvData) data.WriteByteSeq(invitedGuid[7]); - data.WriteString(player->GetName()); // invited name + data.WriteString(GetPlayer()->GetName()); // inviter name data << int32(0); @@ -282,7 +283,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recvData) data.WriteBit(invitedGuid[4]); - data.WriteBits(strlen(player->GetName()), 7); // Invited name length + data.WriteBits(strlen(GetPlayer()->GetName()), 7); // Inviter name length data.WriteBits(0, 24); // Count 2 @@ -313,7 +314,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recvData) data.WriteByteSeq(invitedGuid[7]); - data.WriteString(player->GetName()); + data.WriteString(GetPlayer()->GetName()); data << int32(0); @@ -390,9 +391,8 @@ void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) return; // report - std::string name = std::string(GetPlayer()->GetName()); - WorldPacket data(SMSG_GROUP_DECLINE, name.length()); - data << name.c_str(); + WorldPacket data(SMSG_GROUP_DECLINE, strlen(GetPlayer()->GetName())); + data << GetPlayer()->GetName(); leader->GetSession()->SendPacket(&data); } } @@ -510,6 +510,80 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) group->SendUpdate(); } +void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SET_ROLES"); + + uint32 newRole; + ObjectGuid guid1; // Assigner GUID + ObjectGuid guid2; // Target GUID + + guid1 = GetPlayer()->GetGUID(); + + recvData >> newRole; + + guid2[2] = recvData.ReadBit(); + guid2[6] = recvData.ReadBit(); + guid2[3] = recvData.ReadBit(); + guid2[7] = recvData.ReadBit(); + guid2[5] = recvData.ReadBit(); + guid2[1] = recvData.ReadBit(); + guid2[0] = recvData.ReadBit(); + guid2[4] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid2[6]); + recvData.ReadByteSeq(guid2[4]); + recvData.ReadByteSeq(guid2[1]); + recvData.ReadByteSeq(guid2[3]); + recvData.ReadByteSeq(guid2[0]); + recvData.ReadByteSeq(guid2[5]); + recvData.ReadByteSeq(guid2[2]); + recvData.ReadByteSeq(guid2[7]); + + WorldPacket data(SMSG_GROUP_SET_ROLE, 24); + + data.WriteBit(guid1[1]); + data.WriteBit(guid2[0]); + data.WriteBit(guid2[2]); + data.WriteBit(guid2[4]); + data.WriteBit(guid2[7]); + data.WriteBit(guid2[3]); + data.WriteBit(guid1[7]); + data.WriteBit(guid2[5]); + data.WriteBit(guid1[5]); + data.WriteBit(guid1[4]); + data.WriteBit(guid1[3]); + data.WriteBit(guid2[6]); + data.WriteBit(guid1[2]); + data.WriteBit(guid1[6]); + data.WriteBit(guid2[1]); + data.WriteBit(guid1[0]); + + data.WriteByteSeq(guid1[7]); + data.WriteByteSeq(guid2[3]); + data.WriteByteSeq(guid1[6]); + data.WriteByteSeq(guid2[4]); + data.WriteByteSeq(guid2[0]); + data << uint32(newRole); // New Role + data.WriteByteSeq(guid2[6]); + data.WriteByteSeq(guid2[2]); + data.WriteByteSeq(guid1[0]); + data.WriteByteSeq(guid1[4]); + data.WriteByteSeq(guid2[1]); + data.WriteByteSeq(guid1[3]); + data.WriteByteSeq(guid1[5]); + data.WriteByteSeq(guid1[2]); + data.WriteByteSeq(guid2[5]); + data.WriteByteSeq(guid2[7]); + data.WriteByteSeq(guid1[1]); + data << uint32(0); // Old Role + + if (GetPlayer()->GetGroup()) + GetPlayer()->GetGroup()->BroadcastPacket(&data, false); + else + SendPacket(&data); +} + void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_DISBAND"); @@ -857,64 +931,82 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); - uint32 byteCount = 0; - for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) - if (mask & (1 << i)) - byteCount += GroupUpdateLength[i]; - - data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); + data->Initialize(SMSG_PARTY_MEMBER_STATS, 80); // average value data->append(player->GetPackGUID()); - *data << (uint32) mask; + *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { if (player) { if (player->IsPvP()) - *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); + *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else - *data << (uint16) MEMBER_STATUS_ONLINE; + *data << uint16(MEMBER_STATUS_ONLINE); } else - *data << (uint16) MEMBER_STATUS_OFFLINE; + *data << uint16(MEMBER_STATUS_OFFLINE); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) - *data << (uint32) player->GetHealth(); + *data << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) - *data << (uint32) player->GetMaxHealth(); + *data << uint32(player->GetMaxHealth()); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) - *data << (uint8) powerType; + *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) - *data << (uint16) player->GetPower(powerType); + *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) - *data << (uint16) player->GetMaxPower(powerType); + *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) - *data << (uint16) player->getLevel(); + *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) - *data << (uint16) player->GetZoneId(); + *data << uint16(player->GetZoneId()); + + if (mask & GROUP_UPDATE_FLAG_UNK100) + *data << uint16(0); if (mask & GROUP_UPDATE_FLAG_POSITION) - *data << (uint16) player->GetPositionX() << (uint16) player->GetPositionY(); + *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()) << uint16(player->GetPositionZ()); if (mask & GROUP_UPDATE_FLAG_AURAS) { + *data << uint8(0); uint64 auramask = player->GetAuraUpdateMaskForRaid(); *data << uint64(auramask); + *data << uint32(MAX_AURAS); // count for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { AuraApplication const* aurApp = player->GetVisibleAura(i); - *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0); - *data << uint8(1); + if (!aurApp) + { + *data << uint32(0); + *data << uint16(0); + continue; + } + + *data << uint32(aurApp->GetBase()->GetId()); + *data << uint16(aurApp->GetFlags()); + + if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + *data << int32(eff->GetAmount()); + else + *data << int32(0); + } + } } } } @@ -923,9 +1015,9 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke if (mask & GROUP_UPDATE_FLAG_PET_GUID) { if (pet) - *data << (uint64) pet->GetGUID(); + *data << uint64(pet->GetGUID()); else - *data << (uint64) 0; + *data << uint64(0); } if (mask & GROUP_UPDATE_FLAG_PET_NAME) @@ -933,81 +1025,113 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke if (pet) *data << pet->GetName(); else - *data << (uint8) 0; + *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if (pet) - *data << (uint16) pet->GetDisplayId(); + *data << uint16(pet->GetDisplayId()); else - *data << (uint16) 0; + *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if (pet) - *data << (uint32) pet->GetHealth(); + *data << uint32(pet->GetHealth()); else - *data << (uint32) 0; + *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if (pet) - *data << (uint32) pet->GetMaxHealth(); + *data << uint32(pet->GetMaxHealth()); else - *data << (uint32) 0; + *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if (pet) - *data << (uint8) pet->getPowerType(); + *data << uint8(pet->getPowerType()); else - *data << (uint8) 0; + *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if (pet) - *data << (uint16) pet->GetPower(pet->getPowerType()); + *data << uint16(pet->GetPower(pet->getPowerType())); else - *data << (uint16) 0; + *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if (pet) - *data << (uint16) pet->GetMaxPower(pet->getPowerType()); + *data << uint16(pet->GetMaxPower(pet->getPowerType())); else - *data << (uint16) 0; + *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) { if (Vehicle* veh = player->GetVehicle()) - *data << (uint32) veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]; + *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]); + else + *data << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if (pet) { + *data << uint8(0); uint64 auramask = pet->GetAuraUpdateMaskForRaid(); *data << uint64(auramask); + *data << uint32(MAX_AURAS); // count for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { - AuraApplication const* aurApp = player->GetVisibleAura(i); - *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0); - *data << uint8(1); + AuraApplication const* aurApp = pet->GetVisibleAura(i); + if (!aurApp) + { + *data << uint32(0); + *data << uint16(0); + continue; + } + + *data << uint32(aurApp->GetBase()->GetId()); + *data << uint16(aurApp->GetFlags()); + + if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + *data << int32(eff->GetAmount()); + else + *data << int32(0); + } + } } } } else - *data << (uint64) 0; + { + *data << uint8(0); + *data << uint64(0); + } + } + + if (mask & GROUP_UPDATE_FLAG_PHASE) + { + *data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT + *data << uint32(0); // count + // for (count) *data << uint16(phaseId) } } @@ -1015,15 +1139,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); - uint64 Guid; - recvData >> Guid; + uint64 guid; + recvData >> guid; - Player* player = HashMapHolder<Player>::Find(Guid); + Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related - data.appendPackGUID(Guid); + data.appendPackGUID(guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); @@ -1036,84 +1160,113 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); - uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF - if (pet) - mask1 = 0x7FFFFFFF; // for hunters and other classes with pets + uint32 mask1 = GROUP_UPDATE_FULL; - Powers powerType = player->getPowerType(); - data << (uint32) mask1; // group update mask - data << (uint16) MEMBER_STATUS_ONLINE; // member's online status - data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP - data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP - data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE - data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER - data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER - data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL - data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE - data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION - data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION + if (!pet) + mask1 &= ~GROUP_UPDATE_PET; + Powers powerType = player->getPowerType(); + data << uint32(mask1); // group update mask + data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS + data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP + data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP + data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE + data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER + data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER + data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL + data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE + data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION + data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION + data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION + + // GROUP_UPDATE_FLAG_AURAS + data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); - data << (uint64) auramask; // placeholder + data << uint64(auramask); // placeholder + data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { - if (AuraApplication * aurApp = player->GetVisibleAura(i)) + if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); - data << (uint32) aurApp->GetBase()->GetId(); - data << (uint8) 1; + + data << uint32(aurApp->GetBase()->GetId()); + data << uint16(aurApp->GetFlags()); + + if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + data << int32(eff->GetAmount()); + else + data << int32(0); + } + } } } - data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS + data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); - data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID + data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME - data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID - data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP - data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP - data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE - data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER - data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER - + data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID + data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP + data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP + data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE + data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER + data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER + + // GROUP_UPDATE_FLAG_PET_AURAS + data << uint8(1); uint64 petauramask = 0; size_t petMaskPos = data.wpos(); - data << (uint64) petauramask; // placeholder + data << uint64(petauramask); // placeholder + data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { - if (AuraApplication * auraApp = pet->GetVisibleAura(i)) + if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); - data << (uint32) auraApp->GetBase()->GetId(); - data << (uint8) 1; + + data << uint32(aurApp->GetBase()->GetId()); + data << uint16(aurApp->GetFlags()); + + if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + data << int32(eff->GetAmount()); + else + data << int32(0); + } + } } } + data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } - else - { - data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME - data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS - } + // else not needed, flags do not include any PET_ update + + // GROUP_UPDATE_FLAG_PHASE + data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT + data << uint32(0); // count + // for (count) *data << uint16(phaseId) SendPacket(&data); } -/*!*/void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket& /*recvData*/) { // every time the player checks the character screen _player->SendRaidInfo(); } -/*void WorldSession::HandleGroupCancelOpcode(WorldPacket & recvData) -{ - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: got CMSG_GROUP_CANCEL."); -}*/ - -void WorldSession::HandleOptOutOfLootOpcode(WorldPacket & recvData) +void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_OPT_OUT_OF_LOOT"); diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 778ecc2659f..b3c2d4ae030 100755 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -397,7 +397,7 @@ void WorldSession::HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket) void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (MSG_GUILD_EVENT_LOG_QUERY)"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_EVENT_LOG_QUERY)"); if (Guild* guild = _GetPlayerGuild(this)) guild->SendEventLog(this); @@ -613,7 +613,7 @@ void WorldSession::HandleGuildBankLogQuery(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)"); - uint8 tabId; + uint32 tabId; recvData >> tabId; if (Guild* guild = _GetPlayerGuild(this)) @@ -622,7 +622,7 @@ void WorldSession::HandleGuildBankLogQuery(WorldPacket & recvData) void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_QUERY_GUILD_BANK_TEXT"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_BANK_QUERY_TEXT"); uint8 tabId; recvData >> tabId; @@ -635,11 +635,11 @@ void WorldSession::HandleSetGuildBankTabText(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_GUILD_BANK_TEXT"); - uint8 tabId; + uint32 tabId; recvData >> tabId; - std::string text; - recvData >> text; + uint32 textLen = recvData.ReadBits(14); + std::string text = recvData.ReadString(textLen); if (Guild* guild = _GetPlayerGuild(this)) guild->SetBankTabText(tabId, text); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index ad8846ab071..3b38db78d94 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -754,16 +754,14 @@ void WorldSession::SendListInventory(uint64 vendorGuid) if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM) { ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item); - if (!itemTemplate) continue; + if (!itemTemplate) + continue; + uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); if (!_player->isGameMaster()) // ignore conditions if GM on { // Respect allowed class - if (!(itemTemplate->AllowableClass & _player->getClassMask())) - continue; - - // Do not sell BOP items - if (itemTemplate->Bonding == BIND_WHEN_PICKED_UP) + if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP) continue; // Only display items in vendor lists for the team the player is on @@ -772,13 +770,11 @@ void WorldSession::SendListInventory(uint64 vendorGuid) continue; // Items sold out are not displayed in list - uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); if (leftInStock == 0) continue; } int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0; - uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); itemsData << uint32(count++ + 1); // client expects counting to start at 1 itemsData << uint32(itemTemplate->MaxDurability); @@ -803,10 +799,11 @@ void WorldSession::SendListInventory(uint64 vendorGuid) else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY) { CurrencyTypesEntry const* currencyTemplate = sCurrencyTypesStore.LookupEntry(vendorItem->item); + if (!currencyTemplate) + continue; - if (!currencyTemplate) continue; - - if (vendorItem->ExtendedCost == 0) continue; // there's no price defined for currencies, only extendedcost is used + if (vendorItem->ExtendedCost == 0) + continue; // there's no price defined for currencies, only extendedcost is used uint32 precision = (currencyTemplate->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? 100 : 1; @@ -820,6 +817,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid) } else enablers.push_back(1); + enablers.push_back(1); // unk bit itemsData << uint32(vendorItem->item); @@ -833,40 +831,40 @@ void WorldSession::SendListInventory(uint64 vendorGuid) // else error } - uint8* guidBytes = (uint8*)&vendorGuid; + ObjectGuid guid = vendorGuid; WorldPacket data(SMSG_LIST_INVENTORY, 12 + itemsData.size()); - data.WriteBit(guidBytes[1]); - data.WriteBit(guidBytes[0]); + data.WriteBit(guid[1]); + data.WriteBit(guid[0]); data.WriteBits(count, 21); // item count - data.WriteBit(guidBytes[3]); - data.WriteBit(guidBytes[6]); - data.WriteBit(guidBytes[5]); - data.WriteBit(guidBytes[2]); - data.WriteBit(guidBytes[7]); + data.WriteBit(guid[3]); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[2]); + data.WriteBit(guid[7]); for (std::vector<bool>::const_iterator itr = enablers.begin(); itr != enablers.end(); ++itr) data.WriteBit(*itr); - data.WriteBit(guidBytes[4]); + data.WriteBit(guid[4]); data.FlushBits(); data.append(itemsData); - data.WriteByteSeq(guidBytes[5]); - data.WriteByteSeq(guidBytes[4]); - data.WriteByteSeq(guidBytes[1]); - data.WriteByteSeq(guidBytes[0]); - data.WriteByteSeq(guidBytes[6]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[6]); data << uint8(count == 0); // unk byte, item count 0: 1, item count != 0: 0 or some "random" value below 300 - data.WriteByteSeq(guidBytes[2]); - data.WriteByteSeq(guidBytes[3]); - data.WriteByteSeq(guidBytes[7]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[7]); SendPacket(&data); } @@ -1622,6 +1620,9 @@ void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData) itemTransmogrified->SetNotRefundable(player); itemTransmogrified->ClearSoulboundTradeable(player); + if (itemTransmogrifier->GetTemplate()->Bonding == BIND_WHEN_EQUIPED || itemTransmogrifier->GetTemplate()->Bonding == BIND_WHEN_USE) + itemTransmogrifier->SetBinding(true); + itemTransmogrifier->SetOwnerGUID(player->GetGUID()); itemTransmogrifier->SetNotRefundable(player); itemTransmogrifier->ClearSoulboundTradeable(player); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 677b3cccf82..18ec0067623 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -85,7 +85,7 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData) GetPlayer()->RepopAtGraveyard(); } -void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recvData) +void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GOSSIP_SELECT_OPTION"); @@ -170,7 +170,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recvData) } } -void WorldSession::HandleWhoOpcode(WorldPacket & recvData) +void WorldSession::HandleWhoOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_WHO Message"); @@ -367,7 +367,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Send SMSG_WHO Message"); } -void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - %u", GetSecurity()); @@ -420,12 +420,12 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recvData*/) LogoutRequest(time(NULL)); } -void WorldSession::HandlePlayerLogoutOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandlePlayerLogoutOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_PLAYER_LOGOUT Message"); } -void WorldSession::HandleLogoutCancelOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleLogoutCancelOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_CANCEL Message"); @@ -485,7 +485,7 @@ void WorldSession::HandleTogglePvP(WorldPacket& recvData) // pvp->HandlePlayerActivityChanged(_player); } -void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recvData) +void WorldSession::HandleZoneUpdateOpcode(WorldPacket& recvData) { uint32 newZone; recvData >> newZone; @@ -506,7 +506,7 @@ void WorldSession::HandleReturnToGraveyard(WorldPacket& /*recvPacket*/) GetPlayer()->RepopAtGraveyard(); } -void WorldSession::HandleSetSelectionOpcode(WorldPacket & recvData) +void WorldSession::HandleSetSelectionOpcode(WorldPacket& recvData) { uint64 guid; recvData >> guid; @@ -514,9 +514,9 @@ void WorldSession::HandleSetSelectionOpcode(WorldPacket & recvData) _player->SetSelection(guid); } -void WorldSession::HandleStandStateChangeOpcode(WorldPacket & recvData) +void WorldSession::HandleStandStateChangeOpcode(WorldPacket& recvData) { - // sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: Received CMSG_STANDSTATECHANGE"); -- too many spam in log at lags/debug stop + // sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_STANDSTATECHANGE"); -- too many spam in log at lags/debug stop uint32 animstate; recvData >> animstate; @@ -530,7 +530,7 @@ void WorldSession::HandleContactListOpcode(WorldPacket& recvData) _player->GetSocial()->SendSocialList(_player); } -void WorldSession::HandleAddFriendOpcode(WorldPacket & recvData) +void WorldSession::HandleAddFriendOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_FRIEND"); @@ -623,7 +623,7 @@ void WorldSession::HandleDelFriendOpcode(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent motd (SMSG_FRIEND_STATUS)"); } -void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recvData) +void WorldSession::HandleAddIgnoreOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_IGNORE"); @@ -681,7 +681,7 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent (SMSG_FRIEND_STATUS)"); } -void WorldSession::HandleDelIgnoreOpcode(WorldPacket & recvData) +void WorldSession::HandleDelIgnoreOpcode(WorldPacket& recvData) { uint64 IgnoreGUID; @@ -705,7 +705,7 @@ void WorldSession::HandleSetContactNotesOpcode(WorldPacket& recvData) _player->GetSocial()->SetFriendNote(GUID_LOPART(guid), note); } -void WorldSession::HandleBugOpcode(WorldPacket & recvData) +void WorldSession::HandleBugOpcode(WorldPacket& recvData) { uint32 suggestion, contentlen, typelen; std::string content, type; @@ -938,7 +938,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) player->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation, TELE_TO_NOT_LEAVE_TRANSPORT); } -void WorldSession::HandleUpdateAccountData(WorldPacket &recvData) +void WorldSession::HandleUpdateAccountData(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); @@ -1084,12 +1084,12 @@ void WorldSession::HandleCompleteCinematic(WorldPacket& /*recvData*/) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC"); } -void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recvData*/) +void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA"); } -void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recvData) +void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_MOVE_TIME_SKIPPED"); @@ -1132,7 +1132,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recvData) */ } -void WorldSession::HandleFeatherFallAck(WorldPacket &recvData) +void WorldSession::HandleFeatherFallAck(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); @@ -1190,11 +1190,11 @@ void WorldSession::HandleMoveRootAck(WorldPacket& recvData) */ } -void WorldSession::HandleSetActionBarToggles(WorldPacket& recvPacket) +void WorldSession::HandleSetActionBarToggles(WorldPacket& recvData) { uint8 actionBar; - recvPacket >> actionBar; + recvData >> actionBar; if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED) { @@ -1253,29 +1253,61 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData) data << uint64(guild->GetGUID()); data << uint32(guild->GetLevel()); data << uint64(0/*guild->GetXP()*/); - data << uint32(0/*guild->GetMembersCount()*/); // number of members + data << uint32(guild->GetMembersCount()); } SendPacket(&data); } void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recvData) { - uint64 guid; - recvData >> guid; + ObjectGuid guid; + guid[1] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[2] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[5]); + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[3]); Player* player = ObjectAccessor::FindPlayer(guid); if (!player) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid); return; } - WorldPacket data(SMSG_INSPECT_HONOR_STATS, 4+1+4+8); - data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS)); - data << uint8(0); // rank + ObjectGuid playerGuid = player->GetGUID(); + WorldPacket data(SMSG_INSPECT_HONOR_STATS, 8+1+4+4); + data.WriteBit(playerGuid[4]); + data.WriteBit(playerGuid[3]); + data.WriteBit(playerGuid[6]); + data.WriteBit(playerGuid[2]); + data.WriteBit(playerGuid[5]); + data.WriteBit(playerGuid[0]); + data.WriteBit(playerGuid[7]); + data.WriteBit(playerGuid[1]); + data << uint8(0); // rank + data << uint16(player->GetUInt16Value(PLAYER_FIELD_KILLS, 1)); // yesterday kills + data << uint16(player->GetUInt16Value(PLAYER_FIELD_KILLS, 0)); // today kills + data.WriteByteSeq(playerGuid[2]); + data.WriteByteSeq(playerGuid[0]); + data.WriteByteSeq(playerGuid[6]); + data.WriteByteSeq(playerGuid[3]); + data.WriteByteSeq(playerGuid[4]); + data.WriteByteSeq(playerGuid[1]); + data.WriteByteSeq(playerGuid[5]); data << uint32(player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); - data << uint64(player->GetGUID()); + data.WriteByteSeq(playerGuid[7]); SendPacket(&data); } @@ -1371,7 +1403,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "Received whois command from player %s for character %s", GetPlayer()->GetName(), charname.c_str()); } -void WorldSession::HandleComplainOpcode(WorldPacket & recvData) +void WorldSession::HandleComplainOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_COMPLAIN"); @@ -1412,7 +1444,7 @@ void WorldSession::HandleComplainOpcode(WorldPacket & recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "REPORT SPAM: type %u, guid %u, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", spam_type, GUID_LOPART(spammer_guid), unk1, unk2, unk3, unk4, description.c_str()); } -void WorldSession::HandleRealmSplitOpcode(WorldPacket & recvData) +void WorldSession::HandleRealmSplitOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_REALM_SPLIT"); @@ -1512,7 +1544,7 @@ void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recvData*/) _player->ResetInstances(INSTANCE_RESET_ALL, false); } -void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recvData) +void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_SET_DUNGEON_DIFFICULTY"); @@ -1569,7 +1601,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recvData) } } -void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket & recvData) +void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_SET_RAID_DIFFICULTY"); @@ -1626,7 +1658,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket & recvData) } } -void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recvData*/) +void WorldSession::HandleCancelMountAuraOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CANCEL_MOUNT_AURA"); @@ -1647,7 +1679,7 @@ void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recvData*/) _player->RemoveAurasByType(SPELL_AURA_MOUNTED); } -void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket & recvData) +void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData) { // fly mode on/off sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_SET_CAN_FLY_ACK"); @@ -1729,7 +1761,7 @@ void WorldSession::SendSetPhaseShift(uint32 PhaseShift) } // Battlefield and Battleground -void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY"); @@ -1752,7 +1784,7 @@ void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recv_data) bf->SendAreaSpiritHealerQueryOpcode(_player,guid); } -void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket & recv_data) +void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket& recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE"); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 32636d51f49..554030270d9 100755 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -236,13 +236,13 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle) SendPacket(&data); } -void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recvData) +void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) { uint64 guid; - uint32 spellId = 0; - int32 unkInt; + uint32 spellId; + uint32 trainerId; - recvData >> guid >> unkInt >> spellId; + recvData >> guid >> trainerId >> spellId; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u", uint32(GUID_LOPART(guid)), spellId); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); @@ -257,33 +257,48 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recvData) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); if (!unit->isCanTrainingOf(_player, true)) + { + SendTrainerBuyFailed(guid, spellId, 0); return; + } // check present spell in trainer spell list TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); if (!trainer_spells) + { + SendTrainerBuyFailed(guid, spellId, 0); return; + } // not found, cheat? TrainerSpell const* trainer_spell = trainer_spells->Find(spellId); if (!trainer_spell) + { + SendTrainerBuyFailed(guid, spellId, 0); return; + } // can't be learn, cheat? Or double learn with lags... if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN) + { + SendTrainerBuyFailed(guid, spellId, 0); return; + } // apply reputation discount uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit))); // check money requirement if (!_player->HasEnoughMoney(uint64(nSpellCost))) + { + SendTrainerBuyFailed(guid, spellId, 1); return; + } _player->ModifyMoney(-int64(nSpellCost)); - unit->SendPlaySpellVisual(179); // 53 SpellCastDirected - unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute + unit->SendPlaySpellVisualKit(179, 0); // 53 SpellCastDirected + _player->SendPlaySpellVisualKit(362, 1); // 113 EmoteSalute // learn explicitly or cast explicitly if (trainer_spell->IsCastable()) @@ -293,8 +308,16 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recvData) WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(guid); - data << uint32(spellId); // should be same as in packet from client - data << uint32(0); // "Trainer service", 1 = "Not enough money for trainer service <TS>". 0 = "Trainer service <TS> unavailable" + data << uint32(spellId); + SendPacket(&data); +} + +void WorldSession::SendTrainerBuyFailed(uint64 guid, uint32 spellId, uint32 reason) +{ + WorldPacket data(SMSG_TRAINER_BUY_FAILED, 16); + data << uint64(guid); + data << uint32(spellId); // should be same as in packet from client + data << uint32(reason); // 1 == "Not enough money for trainer service." 0 == "Trainer service %d unavailable." SendPacket(&data); } @@ -490,10 +513,9 @@ void WorldSession::SendBindPoint(Creature* npc) // send spell for homebinding (3286) npc->CastSpell(_player, bindspell, true); - WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, (8+4)); + WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(npc->GetGUID()); data << uint32(bindspell); - data << uint32(0); // "Trainer service", 1 = "Not enough money for trainer service <TS>". 0 = "Trainer service <TS> unavailable" SendPacket(&data); _player->PlayerTalkClass->SendCloseGossip(); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 6aeb61b222b..de881e0608d 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -562,8 +562,8 @@ void WorldSession::HandleTotemDestroyed(WorldPacket& recvPacket) return; Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]); - // Don't unsummon sentry totem - if (totem && totem->isTotem() && totem->GetEntry() != SENTRY_TOTEM_ENTRY) + + if (totem && totem->isTotem()) totem->ToTotem()->UnSummon(); } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c1510bef543..6b115878135 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2689,7 +2689,7 @@ uint32 InstanceMap::GetMaxResetDelay() const /* ******* Battleground Instance Maps ******* */ BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent, uint8 spawnMode) - : Map(id, expiry, InstanceId, spawnMode, _parent) + : Map(id, expiry, InstanceId, spawnMode, _parent), m_bg(NULL) { //lets initialize visibility distance for BG/Arenas BattlegroundMap::InitVisibilityDistance(); diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 08e27abf050..7e130a2c143 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -407,10 +407,6 @@ bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32& time_diff if (i_totalFleeTime.Passed()) return false; - i_totalFleeTime.Update(time_diff); - if (i_totalFleeTime.Passed()) - return false; - // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32 &) version // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 4db35d5bc79..5a4d5734929 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -29,8 +29,8 @@ #include "GridNotifiersImpl.h" #include "CellImpl.h" -OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp): -m_capturePointGUID(0), m_capturePoint(NULL), m_maxValue(0), m_maxSpeed(0), +OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp) : +m_capturePointGUID(0), m_capturePoint(NULL), m_minValue(0.0f), m_maxValue(0.0f), m_maxSpeed(0), m_value(0), m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL), m_State(OBJECTIVESTATE_NEUTRAL), m_neutralValuePct(0), m_PvP(pvp) { diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index 6ea13d353c5..d2f1362dc82 100755 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -31,10 +31,9 @@ enum OutdoorPvPTypes OUTDOOR_PVP_TF = 3, OUTDOOR_PVP_ZM = 4, OUTDOOR_PVP_SI = 5, - OUTDOOR_PVP_EP = 6, }; -#define MAX_OUTDOORPVP_TYPES 7 +#define MAX_OUTDOORPVP_TYPES 6 enum ObjectiveStates { diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 2a16756161b..6aa9500b998 100755 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -347,10 +347,11 @@ uint32 Quest::CalculateHonorGain(uint8 level) const /*if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f) { // values stored from 0.. for 1... - TeamContributionPointsEntry const* tc = sTeamContributionPointsStore.LookupEntry(level-1); + TeamContributionPointsEntry const* tc = sTeamContributionPointsStore.LookupEntry(level); if (!tc) return 0; - honor = uint32(tc->value * GetRewHonorMultiplier() * 0.1000000014901161); + + honor = uint32(tc->value * GetRewHonorMultiplier() * 0.1f); honor += GetRewHonorAddition(); }*/ diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 2b4ad24e78f..53ba7ea0d09 100755 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -213,7 +213,7 @@ class Quest int32 GetZoneOrSort() const { return ZoneOrSort; } uint32 GetMinLevel() const { return MinLevel; } uint32 GetMaxLevel() const { return MaxLevel; } - uint32 GetQuestLevel() const { return Level; } + int32 GetQuestLevel() const { return Level; } uint32 GetType() const { return Type; } uint32 GetRequiredClasses() const { return RequiredClasses; } uint32 GetRequiredRaces() const { return RequiredRaces; } diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h index a073845ea73..f950cbb82c2 100755 --- a/src/server/game/Reputation/ReputationMgr.h +++ b/src/server/game/Reputation/ReputationMgr.h @@ -65,7 +65,7 @@ class ReputationMgr { public: // constructors and global modifiers explicit ReputationMgr(Player* owner) : _player(owner), - _visibleFactionCount(0), _honoredFactionCount(0), _reveredFactionCount(0), _exaltedFactionCount(0) {} + _visibleFactionCount(0), _honoredFactionCount(0), _reveredFactionCount(0), _exaltedFactionCount(0), _sendFactionIncreased(false) {} ~ReputationMgr() {} void SaveToDB(SQLTransaction& trans); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 5e6caec1f29..ac0d9466736 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -50,6 +50,7 @@ void AddSC_ban_commandscript(); void AddSC_bf_commandscript(); void AddSC_cast_commandscript(); void AddSC_character_commandscript(); +void AddSC_cheat_commandscript(); void AddSC_debug_commandscript(); void AddSC_disable_commandscript(); void AddSC_event_commandscript(); @@ -318,6 +319,7 @@ void AddSC_bug_trio(); void AddSC_boss_sartura(); void AddSC_boss_skeram(); void AddSC_boss_twinemperors(); +void AddSC_boss_ouro(); void AddSC_mob_anubisath_sentinel(); void AddSC_instance_temple_of_ahnqiraj(); void AddSC_wailing_caverns(); //Wailing caverns @@ -593,7 +595,6 @@ void AddSC_zangarmarsh(); // battlegrounds // outdoor pvp -void AddSC_outdoorpvp_ep(); void AddSC_outdoorpvp_hp(); void AddSC_outdoorpvp_na(); void AddSC_outdoorpvp_si(); @@ -659,6 +660,7 @@ void AddCommandScripts() AddSC_bf_commandscript(); AddSC_cast_commandscript(); AddSC_character_commandscript(); + AddSC_cheat_commandscript(); AddSC_debug_commandscript(); AddSC_disable_commandscript(); AddSC_event_commandscript(); @@ -939,6 +941,7 @@ void AddKalimdorScripts() AddSC_boss_sartura(); AddSC_boss_skeram(); AddSC_boss_twinemperors(); + AddSC_boss_ouro(); AddSC_mob_anubisath_sentinel(); AddSC_instance_temple_of_ahnqiraj(); AddSC_wailing_caverns(); //Wailing caverns @@ -1224,7 +1227,6 @@ void AddNorthrendScripts() void AddOutdoorPvPScripts() { #ifdef SCRIPTS - AddSC_outdoorpvp_ep(); AddSC_outdoorpvp_hp(); AddSC_outdoorpvp_na(); AddSC_outdoorpvp_si(); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index a3c807c09c8..6eeb3661028 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -99,16 +99,16 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode ); DEFINE_OPCODE_HANDLER(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LEAVE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode ); DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse ); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfExitRequest ); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse ); DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_PORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_PORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode ); DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode); + DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinOpcode ); DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN_ARENA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena ); DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN_RATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode ); @@ -236,10 +236,10 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_GROUP_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDisbandOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteResponseOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_GROUP_RAID_CONVERT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GROUP_RAID_CONVERT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GROUP_REQUEST_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_ROLES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_ROLES, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGroupSetRolesOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GROUP_SWAP_SUB_GROUP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSwapSubGroupOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE_GUID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteGuidOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode ); @@ -250,11 +250,10 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankDepositMoney ); - DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab ); - DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TEXT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_SET_TAB_TEXT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankSwapItems ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankUpdateTab ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankWithdrawMoney ); @@ -263,7 +262,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEL_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDelRankOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_DISBAND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode ); - DEFINE_OPCODE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode ); @@ -290,6 +289,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode ); DEFINE_OPCODE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode ); DEFINE_OPCODE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_INSPECT_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectHonorStatsOpcode ); DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_WARNING_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_ITEM_REFUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund ); DEFINE_OPCODE_HANDLER(CMSG_ITEM_REFUND_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest ); @@ -414,7 +414,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_PLAYER_VEHICLE_ENTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEnterPlayerVehicle ); DEFINE_OPCODE_HANDLER(CMSG_PLAY_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_PUSHQUESTTOPARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty ); - DEFINE_OPCODE_HANDLER(CMSG_PVP_LOG_DATA, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePVPLogDataOpcode ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_BATTLEFIELD_STATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -451,10 +451,9 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData ); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_CEMETERY_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_HOTFIX, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix ); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); + DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PVP_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -490,6 +489,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_ATWAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar ); DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_INACTIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText ); DEFINE_OPCODE_HANDLER(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames ); DEFINE_OPCODE_HANDLER(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -541,8 +541,8 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_UNREGISTER_ALL_ADDON_PREFIXES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnregisterAddonPrefixesOpcode); DEFINE_OPCODE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData ); - DEFINE_OPCODE_HANDLER(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); - DEFINE_OPCODE_HANDLER(CMSG_UPDATE_PROJECTILE_POSITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); + DEFINE_OPCODE_HANDLER(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); + DEFINE_OPCODE_HANDLER(CMSG_UPDATE_PROJECTILE_POSITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); DEFINE_OPCODE_HANDLER(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode ); DEFINE_OPCODE_HANDLER(CMSG_VIOLENCE_LEVEL, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleViolenceLevel ); @@ -561,8 +561,8 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_WRAP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode ); DEFINE_OPCODE_HANDLER(CMSG_ZONEUPDATE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleZoneUpdateOpcode ); DEFINE_OPCODE_HANDLER(MSG_AUCTION_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode ); - DEFINE_OPCODE_HANDLER(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(MSG_CHANNEL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(MSG_CHANNEL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(MSG_CORPSE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode ); DEFINE_OPCODE_HANDLER(MSG_INSPECT_ARENA_TEAMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode ); DEFINE_OPCODE_HANDLER(MSG_LIST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode ); @@ -592,7 +592,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_STRAFE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_TURN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); - DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck ); DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(MSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -608,7 +608,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(MSG_QUERY_NEXT_MAIL_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryNextMailTime ); DEFINE_OPCODE_HANDLER(MSG_QUEST_PUSH_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult ); DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode ); - DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_CONFIRM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_CONFIRM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_FINISHED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckFinishedOpcode); DEFINE_OPCODE_HANDLER(MSG_RAID_TARGET_UPDATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode ); DEFINE_OPCODE_HANDLER(MSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomRollOpcode ); @@ -664,26 +664,27 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_AVAILABLE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_AVERAGE_ITEM_LEVEL_INFORM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BARBER_SHOP_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECT_PENDING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_STATE_CHANGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PLAYER_POSITIONS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PLAYER_POSITIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PORT_DENIED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_RATED_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS2, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS3, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS4, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_QUEUED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_ACTIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -838,21 +839,20 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GROUP_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GROUP_JOINED_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_LEADER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_ROLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_ROLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -862,7 +862,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GUILD_INVITE_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -898,7 +898,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_INSPECT_RESULTS_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_INSPECT_TALENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1041,8 +1041,8 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PARTYKILLLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS_FULL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PERIODICAURALOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PETGODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1079,8 +1079,8 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_PLAY_MUSIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PONG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1088,7 +1088,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_PROCRESIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1112,7 +1112,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1244,8 +1244,8 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1422,7 +1422,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse ); //DEFINE_OPCODE_HANDLER(CMSG_LEARN_DANCE_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_LEARN_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(CMSG_LEAVE_BATTLEFIELD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveBattlefieldOpcode ); //DEFINE_OPCODE_HANDLER(CMSG_LEVEL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_LFD_PARTY_LOCK_INFO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPartyLockInfoRequestOpcode); //DEFINE_OPCODE_HANDLER(CMSG_LFD_PLAYER_LOCK_INFO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPlayerLockInfoRequestOpcode); @@ -1507,7 +1506,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(CMSG_SET_GLYPH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_SET_GLYPH_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_SET_GRANTABLE_LEVELS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText ); //DEFINE_OPCODE_HANDLER(CMSG_SET_LFG_COMMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetCommentOpcode ); //DEFINE_OPCODE_HANDLER(CMSG_SET_PAID_SERVICE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_SET_PVP_RANK_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -1551,7 +1549,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(CMSG_WEATHER_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_XP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(MSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode); //DEFINE_OPCODE_HANDLER(MSG_DELAY_GHOST_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_DEV_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_GM_ACCOUNT_ONLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -1562,9 +1559,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(MSG_GM_RESETINSTANCELIMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_GM_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_GM_SUMMON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(MSG_GUILD_BANK_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery ); - //DEFINE_OPCODE_HANDLER(MSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode ); - //DEFINE_OPCODE_HANDLER(MSG_INSPECT_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectHonorStatsOpcode ); //DEFINE_OPCODE_HANDLER(MSG_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_MOVE_GRAVITY_CHNG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_MOVE_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -1592,13 +1586,9 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(MSG_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_NULL_ACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode ); - //DEFINE_OPCODE_HANDLER(MSG_QUERY_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText ); - //DEFINE_OPCODE_HANDLER(MSG_START_MOVE_FORWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_VIEW_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(SMSG_AFK_MONITOR_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS1, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_ACTION_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1672,7 +1662,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_NPC_WONT_TALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_PET_UNLEARN_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_PLAYER_UNK_DEAD_ALIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_IMPACT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_PROFILEDATA_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_PUREMOUNT_CANCELLED_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_PVP_QUEUE_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1690,7 +1679,7 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SETUP_RESEARCH_HISTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_PROC_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -1707,7 +1696,6 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ADJUST_PRIORITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 07cfdf39bb1..b948ce76ca6 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -247,7 +247,6 @@ enum Opcodes CMSG_GUILD_BANK_NOTE = 0x0000, CMSG_GUILD_BANK_QUERY_TAB = 0x2E35, CMSG_GUILD_BANK_QUERY_TEXT = 0x3220, - CMSG_GUILD_BANK_SET_TAB_TEXT = 0x3023, CMSG_GUILD_BANK_SWAP_ITEMS = 0x2315, CMSG_GUILD_BANK_UPDATE_TAB = 0x0106, CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x0037, @@ -285,6 +284,7 @@ enum Opcodes CMSG_IGNORE_TRADE = 0x7112, CMSG_INITIATE_TRADE = 0x7916, CMSG_INSPECT = 0x0927, + CMSG_INSPECT_HONOR_STATS = 0x791E, CMSG_INSTANCE_LOCK_WARNING_RESPONSE = 0x6234, CMSG_ITEM_REFUND = 0x6134, CMSG_ITEM_REFUND_INFO = 0x2206, @@ -294,7 +294,6 @@ enum Opcodes CMSG_LEARN_PREVIEW_TALENTS = 0x2415, CMSG_LEARN_PREVIEW_TALENTS_PET = 0x6E24, CMSG_LEARN_TALENT = 0x0306, - CMSG_LEAVE_BATTLEFIELD = 0x0000, CMSG_LEAVE_CHANNEL = 0x2D56, CMSG_LFG_GET_PLAYER_INFO = 0x0000, CMSG_LFG_GET_STATUS = 0x2581, @@ -464,7 +463,6 @@ enum Opcodes CMSG_REQUEST_ACCOUNT_DATA = 0x6505, CMSG_REQUEST_CATEGORY_COOLDOWNS = 0x7102, CMSG_REQUEST_CEMETERY_LIST = 0x720A, - CMSG_REQUEST_HONOR_STATS = 0x791E, CMSG_REQUEST_HOTFIX = 0x2401, CMSG_REQUEST_INSPECT_RATED_BG_STATS = 0x3010, CMSG_REQUEST_PARTY_MEMBER_STATS = 0x0C04, @@ -509,7 +507,7 @@ enum Opcodes CMSG_SET_FACTION_ATWAR = 0x0706, CMSG_SET_FACTION_CHEAT = 0x0000, CMSG_SET_FACTION_INACTIVE = 0x0E37, - CMSG_SET_GUILD_BANK_TEXT = 0x0000, + CMSG_SET_GUILD_BANK_TEXT = 0x3023, CMSG_SET_LFG_COMMENT = 0x0000, CMSG_SET_PET_SLOT = 0x3A04, CMSG_SET_PLAYER_DECLINED_NAMES = 0x6316, @@ -589,15 +587,12 @@ enum Opcodes CMSG_WRAP_ITEM = 0x4F06, CMSG_ZONEUPDATE = 0x4F37, MSG_AUCTION_HELLO = 0x2307, - MSG_BATTLEGROUND_PLAYER_POSITIONS = 0x0000, MSG_CHANNEL_START = 0x0A15, // SMSG only? MSG_CHANNEL_UPDATE = 0x2417, // SMSG only? MSG_CORPSE_QUERY = 0x4336, MSG_GM_BIND_OTHER = 0x0000, MSG_GM_SHOWLABEL = 0x0000, MSG_GM_SUMMON = 0x0000, - MSG_GUILD_BANK_LOG_QUERY = 0x0000, - MSG_GUILD_EVENT_LOG_QUERY = 0x0000, MSG_INSPECT_ARENA_TEAMS = 0x2704, MSG_LIST_STABLED_PETS = 0x0834, MSG_MINIMAP_PING = 0x6635, @@ -658,7 +653,6 @@ enum Opcodes MSG_PETITION_DECLINE = 0x4905, MSG_PETITION_RENAME = 0x4005, MSG_PVP_LOG_DATA = 0x0000, - MSG_QUERY_GUILD_BANK_TEXT = 0x0000, MSG_QUERY_NEXT_MAIL_TIME = 0x0F04, MSG_QUEST_PUSH_RESULT = 0x4515, MSG_RAID_READY_CHECK = 0x2304, @@ -733,15 +727,14 @@ enum Opcodes SMSG_BATTLEFIELD_PORT_DENIED = 0x35A3, SMSG_BATTLEFIELD_RATED_INFO = 0x54A3, SMSG_BATTLEFIELD_STATUS = 0x7DA1, - SMSG_BATTLEFIELD_STATUS1 = 0x0000, - SMSG_BATTLEFIELD_STATUS2 = 0x74A4, - SMSG_BATTLEFIELD_STATUS3 = 0x59A0, - SMSG_BATTLEFIELD_STATUS4 = 0x75A2, + SMSG_BATTLEFIELD_STATUS_QUEUED = 0x35A1, + SMSG_BATTLEFIELD_STATUS_ACTIVE = 0x74A4, + SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION = 0x59A0, + SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS = 0x75A2, SMSG_BATTLEFIELD_STATUS_FAILED = 0x71A7, SMSG_BATTLEGROUND_INFO_THROTTLED = 0x34B2, SMSG_BATTLEGROUND_PLAYER_JOINED = 0x50B0, SMSG_BATTLEGROUND_PLAYER_LEFT = 0x59A6, - SMSG_BATTLEGROUND_PLAYER_POSITIONS = 0x0000, SMSG_BINDER_CONFIRM = 0x2835, SMSG_BINDPOINTUPDATE = 0x0527, SMSG_BINDZONEREPLY = 0x0000, @@ -912,7 +905,6 @@ enum Opcodes SMSG_GROUP_DECLINE = 0x6835, SMSG_GROUP_DESTROYED = 0x2207, SMSG_GROUP_INVITE = 0x31B2, - SMSG_GROUP_JOINED_BATTLEGROUND = 0x35A1, SMSG_GROUP_LIST = 0x4C24, SMSG_GROUP_SET_LEADER = 0x0526, SMSG_GROUP_SET_ROLE = 0x39A6, @@ -922,9 +914,9 @@ enum Opcodes SMSG_GUILD_ACHIEVEMENT_EARNED = 0x50B5, SMSG_GUILD_ACHIEVEMENT_MEMBERS = 0x38A5, SMSG_GUILD_BANK_LIST = 0x78A5, - SMSG_GUILD_BANK_LOG_QUERY_RESULTS = 0x30B2, + SMSG_GUILD_BANK_LOG_QUERY_RESULT = 0x30B2, SMSG_GUILD_BANK_MONEY_WITHDRAWN = 0x5DB4, - SMSG_GUILD_BANK_QUERY_TEXT_RESULTS = 0x75A3, + SMSG_GUILD_BANK_QUERY_TEXT_RESULT = 0x75A3, SMSG_GUILD_CANCEL = 0x0000, SMSG_GUILD_CHALLENGE_COMPLETED = 0x39A3, SMSG_GUILD_CHALLENGE_UPDATED = 0x18B1, @@ -935,7 +927,7 @@ enum Opcodes SMSG_GUILD_CRITERIA_DELETED = 0x55B1, SMSG_GUILD_DECLINE = 0x2C07, SMSG_GUILD_EVENT = 0x0705, - SMSG_GUILD_EVENT_LOG_QUERY = 0x10B2, + SMSG_GUILD_EVENT_LOG_QUERY_RESULT = 0x10B2, SMSG_GUILD_FLAGGED_FOR_RENAME = 0x30B6, SMSG_GUILD_INVITE = 0x14A2, SMSG_GUILD_INVITE_CANCEL = 0x0606, @@ -1177,7 +1169,6 @@ enum Opcodes SMSG_PLAY_MUSIC = 0x4B06, SMSG_PLAY_OBJECT_SOUND = 0x2635, SMSG_PLAY_SOUND = 0x2134, - SMSG_PLAY_SPELL_IMPACT = 0x0000, SMSG_PLAY_SPELL_VISUAL = 0x10B1, SMSG_PLAY_SPELL_VISUAL_KIT = 0x55A5, SMSG_PLAY_TIME_WARNING = 0x4814, @@ -1349,7 +1340,6 @@ enum Opcodes SMSG_TRADE_STATUS = 0x5CA3, SMSG_TRADE_STATUS_EXTENDED = 0x70A2, SMSG_TRAINER_BUY_FAILED = 0x0004, - SMSG_TRAINER_BUY_RESULT = 0x0000, SMSG_TRAINER_BUY_SUCCEEDED = 0x6A05, SMSG_TRAINER_LIST = 0x4414, SMSG_TRANSFER_ABORTED = 0x0537, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index ac8e48a0c04..0ac7884efe2 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -545,6 +545,7 @@ class WorldSession void HandleGroupUninviteOpcode(WorldPacket& recvPacket); void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket); void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); + void HandleGroupSetRolesOpcode(WorldPacket& recvData); void HandleGroupDisbandOpcode(WorldPacket& recvPacket); void HandleOptOutOfLootOpcode(WorldPacket& recvData); void HandleLootMethodOpcode(WorldPacket& recvPacket); @@ -618,6 +619,7 @@ class WorldSession void HandleStableRevivePet(WorldPacket& recvPacket); void HandleStableSwapPet(WorldPacket& recvPacket); void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId); + void SendTrainerBuyFailed(uint64 guid, uint32 spellId, uint32 reason); void HandleDuelAcceptedOpcode(WorldPacket& recvPacket); void HandleDuelCancelledOpcode(WorldPacket& recvPacket); @@ -787,7 +789,7 @@ class WorldSession void HandlePVPLogDataOpcode(WorldPacket& recvData); void HandleBattleFieldPortOpcode(WorldPacket& recvData); void HandleBattlefieldListOpcode(WorldPacket& recvData); - void HandleLeaveBattlefieldOpcode(WorldPacket& recvData); + void HandleBattlefieldLeaveOpcode(WorldPacket& recvData); void HandleBattlemasterJoinArena(WorldPacket& recvData); void HandleReportPvPAFK(WorldPacket& recvData); @@ -808,14 +810,14 @@ class WorldSession void HandleInstanceLockResponse(WorldPacket& recvPacket); // Battlefield - void SendBfInvitePlayerToWar(uint32 BattleId,uint32 ZoneId,uint32 time); - void SendBfInvitePlayerToQueue(uint32 BattleId); - void SendBfQueueInviteResponse(uint32 BattleId,uint32 ZoneId, bool CanQueue = true, bool Full = false); - void SendBfEntered(uint32 BattleId); - void SendBfLeaveMessage(uint32 BattleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); - void HandleBfQueueInviteResponse(WorldPacket &recv_data); - void HandleBfEntryInviteResponse(WorldPacket &recv_data); - void HandleBfExitRequest(WorldPacket &recv_data); + void SendBfInvitePlayerToWar(uint64 guid, uint32 zoneId, uint32 pTime); + void SendBfInvitePlayerToQueue(uint64 guid); + void SendBfQueueInviteResponse(uint64 guid, uint32 zoneId, bool canQueue = true, bool full = false); + void SendBfEntered(uint64 guid); + void SendBfLeaveMessage(uint64 guid, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); + void HandleBfQueueInviteResponse(WorldPacket& recvData); + void HandleBfEntryInviteResponse(WorldPacket& recvData); + void HandleBfExitRequest(WorldPacket& recvData); // Looking for Dungeon/Raid void HandleLfgSetCommentOpcode(WorldPacket& recvData); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index be18785e76e..30614c655fa 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2913,13 +2913,13 @@ void AuraEffect::HandleForceMoveForward(AuraApplication const* aurApp, uint8 mod Unit* target = aurApp->GetTarget(); if (apply) - target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVEMENT); else { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit if (target->HasAuraType(GetAuraType())) return; - target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE); + target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVEMENT); } } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 98833c3eb41..1655256666f 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -88,7 +88,7 @@ SpellDestination::SpellDestination(WorldObject const& wObj) } -SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0) +SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget() { m_objectTarget = NULL; m_itemTarget = NULL; @@ -97,7 +97,6 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0) m_itemTargetGUID = 0; m_itemTargetEntry = 0; - m_strTarget = ""; m_targetMask = 0; } @@ -3002,7 +3001,13 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail) m_casttime = m_spellInfo->CalcCastTime(m_caster, this); if (m_caster->GetTypeId() == TYPEID_PLAYER) + { m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + + // Set casttime to 0 if .cheat casttime is enabled. + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_CASTTIME)) + m_casttime = 0; + } // don't allow channeled spells / spells with cast time to be casted while moving // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in) @@ -3294,7 +3299,13 @@ void Spell::cast(bool skipCheck) } if (m_caster->GetTypeId() == TYPEID_PLAYER) + { m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + + //Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled. + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) + m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true); + } SetExecutedCurrently(false); } @@ -4029,41 +4040,47 @@ void Spell::SendSpellGo() m_caster->SendMessageToSet(&data, true); } +/// Writes miss and hit targets for a SMSG_SPELL_GO packet void Spell::WriteSpellGoTargets(WorldPacket* data) { // This function also fill data for channeled spells: // m_needAliveTargetMask req for stop channelig if one target die - uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO - uint32 miss = 0; for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { if ((*ihit).effectMask == 0) // No effect apply - all immuned add state - { // possibly SPELL_MISS_IMMUNE2 for this?? ihit->missCondition = SPELL_MISS_IMMUNE2; - ++miss; - } - else if ((*ihit).missCondition == SPELL_MISS_NONE) - ++hit; - else - ++miss; } - *data << (uint8)hit; - for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + // Hit and miss target counts are both uint8, that limits us to 255 targets for each + // sending more than 255 targets crashes the client (since count sent would be wrong) + // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need + // target conditions but we still need to limit the number of targets sent and keeping + // correct count for both hit and miss). + + uint32 hit = 0; + size_t hitPos = data->wpos(); + *data << (uint8)0; // placeholder + for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit <= 255; ++ihit) { if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits { *data << uint64(ihit->targetGUID); m_channelTargetEffectMask |=ihit->effectMask; + ++hit; } } - for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit) + for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit <= 255; ++ighit) + { *data << uint64(ighit->targetGUID); // Always hits + ++hit; + } - *data << (uint8)miss; - for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + uint32 miss = 0; + size_t missPos = data->wpos(); + *data << (uint8)0; // placeholder + for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss <= 255; ++ihit) { if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss { @@ -4071,11 +4088,15 @@ void Spell::WriteSpellGoTargets(WorldPacket* data) *data << uint8(ihit->missCondition); if (ihit->missCondition == SPELL_MISS_REFLECT) *data << uint8(ihit->reflectResult); + ++miss; } } // Reset m_needAliveTargetMask for non channeled spell if (!m_spellInfo->IsChanneled()) m_channelTargetEffectMask = 0; + + data->put<uint8>(hitPos, (uint8)hit); + data->put<uint8>(missPos, (uint8)miss); } void Spell::SendLogExecute() @@ -4334,6 +4355,13 @@ void Spell::TakePower() if (m_CastItem || m_triggeredByAuraSpell) return; + //Don't take power if the spell is cast while .cheat power is enabled. + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_POWER)) + return; + } + Powers powerType = Powers(m_spellInfo->PowerType); bool hit = true; if (m_caster->GetTypeId() == TYPEID_PLAYER) @@ -6788,9 +6816,9 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk 0 : m_caster->ToPlayer()->GetSkillValue(skillId); // skill bonus provided by casting spell (mostly item spells) - // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) + // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.) if (m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET) - skillValue += uint32(CalculateDamage(effIndex, NULL)); + skillValue += m_spellInfo->Effects[effIndex].CalcValue(); if (skillValue < reqSkillValue) return SPELL_FAILED_LOW_CASTLEVEL; @@ -7156,6 +7184,10 @@ void Spell::TriggerGlobalCooldown() if (!gcd) return; + if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (m_caster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) + return; + // Global cooldown can't leave range 1..1.5 secs // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns // but as tests show are not affected by any spell mods. diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index be5d4e3fa74..8369a1b61c5 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -295,6 +295,10 @@ void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/) if (!unitTarget || !unitTarget->isAlive()) return; + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + if (unitTarget->ToPlayer()->GetCommandStatus(CHEAT_GOD)) + return; + if (m_caster == unitTarget) // prevent interrupt message finish(); @@ -330,10 +334,9 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) return; - bool apply_direct_bonus = true; - if (unitTarget && unitTarget->isAlive()) { + bool apply_direct_bonus = true; switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: @@ -4008,17 +4011,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) unitTarget->CastSpell(unitTarget, spellTarget[urand(0, 4)], true); break; } - case 64142: // Upper Deck - Create Foam Sword - if (unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - Player* player = unitTarget->ToPlayer(); - static uint32 const itemId[] = {45061, 45176, 45177, 45178, 45179, 0}; - // player can only have one of these items - for (uint32 const* itr = &itemId[0]; *itr; ++itr) - if (player->HasItemCount(*itr, 1, true)) - return; - DoCreateItem(effIndex, itemId[urand(0, 4)]); - return; } break; } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 5c2b007493c..fe7a0eab229 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1167,6 +1167,26 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 return spellId == 56617; } break; + case 57940: // Essence of Wintergrasp - Northrend + case 58045: // Essence of Wintergrasp - Wintergrasp + { + if (!player) + return false; + + if (Battlefield* battlefieldWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + return battlefieldWG->IsEnabled() && (player->GetTeamId() == battlefieldWG->GetDefenderTeam()) && !battlefieldWG->IsWarTime(); + break; + } + case 74411: // Battleground - Dampening + { + if (!player) + return false; + + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) + return bf->IsWarTime(); + break; + } + } return true; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index dcf3c38fe4f..9c5619ef5f6 100755 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -441,7 +441,7 @@ class PetAura typedef UNORDERED_MAP<uint32, uint32> PetAuraMap; public: - PetAura() + PetAura() : removeOnChangePet(false), damage(0) { auras.clear(); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 936b2d3629b..0a9af095352 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1197,6 +1197,9 @@ void World::LoadConfigSettings(bool reload) // MySQL ping time interval m_int_configs[CONFIG_DB_PING_INTERVAL] = ConfigMgr::GetIntDefault("MaxPingTime", 30); + // Guild save interval + m_int_configs[CONFIG_GUILD_SAVE_INTERVAL] = ConfigMgr::GetIntDefault("GuildSaveInterval", 15); + // misc m_bool_configs[CONFIG_PDUMP_NO_PATHS] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowPaths", true); m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true); @@ -1679,6 +1682,8 @@ void World::SetInitialWorldSettings() m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes + m_timers[WUPDATE_GUILDSAVE].SetInterval(getIntConfig(CONFIG_GUILD_SAVE_INTERVAL) * MINUTE * IN_MILLISECONDS); + //to set mailtimer to return mails every day between 4 and 5 am //mailtimer is increased when updating auctions //one second is 1000 -(tested on win system) @@ -2035,6 +2040,12 @@ void World::Update(uint32 diff) WorldDatabase.KeepAlive(); } + if (m_timers[WUPDATE_GUILDSAVE].Passed()) + { + m_timers[WUPDATE_GUILDSAVE].Reset(); + sGuildMgr->SaveGuilds(); + } + // update the instance reset times sInstanceSaveMgr->Update(); @@ -2926,7 +2937,7 @@ void World::LoadCharacterNameData() QueryResult result = CharacterDatabase.Query("SELECT guid, name, race, gender, class FROM characters WHERE deleteDate IS NULL"); if (!result) { - sLog->outError(LOG_FILTER_SQL, "No character name data loaded, empty query"); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "No character name data loaded, empty query"); return; } diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 841ae2530ca..b25444f4865 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -86,6 +86,7 @@ enum WorldTimers WUPDATE_MAILBOXQUEUE, WUPDATE_DELETECHARS, WUPDATE_PINGDB, + WUPDATE_GUILDSAVE, WUPDATE_COUNT }; @@ -335,6 +336,7 @@ enum WorldIntConfigs CONFIG_WINTERGRASP_BATTLETIME, CONFIG_WINTERGRASP_NOBATTLETIME, CONFIG_WINTERGRASP_RESTART_AFTER_CRASH, + CONFIG_GUILD_SAVE_INTERVAL, INT_CONFIG_VALUE_COUNT }; diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index d5ebeab3b8a..177b3a479f5 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -16,6 +16,7 @@ set(scripts_STAT_SRCS Commands/cs_bf.cpp Commands/cs_cast.cpp Commands/cs_character.cpp + Commands/cs_cheat.cpp Commands/cs_debug.cpp Commands/cs_disable.cpp Commands/cs_event.cpp diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp new file mode 100644 index 00000000000..1911c6d476b --- /dev/null +++ b/src/server/scripts/Commands/cs_cheat.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2008-2012 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: cheat_commandscript +%Complete: 100 +Comment: All cheat related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "ObjectMgr.h" +#include "Chat.h" + +class cheat_commandscript : public CommandScript +{ +public: + cheat_commandscript() : CommandScript("cheat_commandscript") { } + + ChatCommand* GetCommands() const + { + + static ChatCommand cheatCommandTable[] = + { + { "god", SEC_GAMEMASTER, false, &HandleGodModeCheatCommand, "", NULL }, + { "casttime", SEC_GAMEMASTER, false, &HandleCasttimeCheatCommand, "", NULL }, + { "cooldown", SEC_GAMEMASTER, false, &HandleCoolDownCheatCommand, "", NULL }, + { "power", SEC_GAMEMASTER, false, &HandlePowerCheatCommand, "", NULL }, + { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterWalkCheatCommand, "", NULL }, + { "taxi", SEC_GAMEMASTER, false, &HandleTaxiCheatCommand, "", NULL }, + { "explore", SEC_GAMEMASTER, false, &HandleExploreCheatCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + + }; + + static ChatCommand commandTable[] = + { + { "cheat", SEC_GAMEMASTER, false, NULL, "", cheatCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleGodModeCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_GOD)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_GOD); + handler->SendSysMessage("Godmode is OFF. You can take damage."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_GOD); + handler->SendSysMessage("Godmode is ON. You won't take damage."); + return true; + } + + return false; + } + + static bool HandleCasttimeCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_CASTTIME)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_CASTTIME); + handler->SendSysMessage("CastTime Cheat is OFF. Your spells will have a casttime."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_CASTTIME); + handler->SendSysMessage("CastTime Cheat is ON. Your spells won't have a casttime."); + return true; + } + + return false; + } + + static bool HandleCoolDownCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_COOLDOWN)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_COOLDOWN); + handler->SendSysMessage("Cooldown Cheat is OFF. You are on the global cooldown."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_COOLDOWN); + handler->SendSysMessage("Cooldown Cheat is ON. You are not on the global cooldown."); + return true; + } + + return false; + } + + static bool HandlePowerCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_POWER)) ? "off" : "on"; + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_POWER); + handler->SendSysMessage("Power Cheat is OFF. You need mana/rage/energy to use spells."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_POWER); + handler->SendSysMessage("Power Cheat is ON. You don't need mana/rage/energy to use spells."); + return true; + } + + return false; + } + + static bool HandleWaterWalkCheatCommand(ChatHandler* handler, const char* args) + { + if (!handler->GetSession() && !handler->GetSession()->GetPlayer()) + return false; + + std::string argstr = (char*)args; + + if (!*args) + { + argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on"; + if (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) + argstr = "off"; + else + argstr = "on"; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK); + handler->GetSession()->GetPlayer()->SendMovementSetWaterWalking(false); // OFF + handler->SendSysMessage("Waterwalking is OFF. You can't walk on water."); + return true; + } + else if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK); + handler->GetSession()->GetPlayer()->SendMovementSetWaterWalking(true); // ON + handler->SendSysMessage("Waterwalking is ON. You can walk on water."); + return true; + } + + return false; + } + + static bool HandleTaxiCheatCommand(ChatHandler* handler, const char* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argstr = (char*)args; + + Player* chr = handler->getSelectedPlayer(); + + if (!chr) + chr = handler->GetSession()->GetPlayer(); + else if (handler->HasLowerSecurity(chr, 0)) // check online security + return false; + + if (argstr == "on") + { + chr->SetTaxiCheater(true); + handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); + return true; + } + + if (argstr == "off") + { + chr->SetTaxiCheater(false); + handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); + + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleExploreCheatCommand(ChatHandler* handler, const char *args) + { + if (!*args) + return false; + + int flag = atoi((char*)args); + + Player* chr = handler->getSelectedPlayer(); + if (chr == NULL) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); + } + else + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); + } + + for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) + { + if (flag != 0) + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); + else + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); + } + + return true; + } +}; + +void AddSC_cheat_commandscript() +{ + new cheat_commandscript(); +} diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 7ea681170b4..68e68ba7892 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -82,10 +82,8 @@ public: { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, - { "taxicheat", SEC_MODERATOR, false, &HandleTaxiCheatCommand, "", NULL }, { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, - { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, @@ -106,7 +104,6 @@ public: { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, - { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, { "freeze", SEC_MODERATOR, false, &HandleFreezeCommand, "", NULL }, { "unfreeze", SEC_MODERATOR, false, &HandleUnFreezeCommand, "", NULL }, { "listfreeze", SEC_MODERATOR, false, &HandleListFreezeCommand, "", NULL }, @@ -960,49 +957,6 @@ public: player->CastSpell(player, 7355, false); return true; } - // Enable on\off all taxi paths - static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - std::string argStr = (char*)args; - - Player* chr = handler->getSelectedPlayer(); - - if (!chr) - chr = handler->GetSession()->GetPlayer(); - else if (handler->HasLowerSecurity(chr, 0)) // check online security - return false; - - if (argStr == "on") - { - chr->SetTaxiCheater(true); - handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); - return true; - } - - if (argStr == "off") - { - chr->SetTaxiCheater(false); - handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); - - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - - return false; - } static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) { @@ -1123,45 +1077,6 @@ public: return true; } - static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - int32 flag = int32(atoi((char*)args)); - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - if (flag != 0) - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); - } - else - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); - } - - for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) - { - if (flag != 0) - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); - else - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); - } - - return true; - } - static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) { if (!*args) @@ -2193,39 +2108,6 @@ public: return true; } - static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->getSelectedPlayer(); - if (!player) - { - handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(player, 0)) - return false; - - if (strncmp(args, "on", 3) == 0) - player->SendMovementSetWaterWalking(true); - else if (strncmp(args, "off", 4) == 0) - player->SendMovementSetWaterWalking(false); - else - { - handler->SendSysMessage(LANG_USE_BOL); - return false; - } - - handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); - if (handler->needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); - return true; - } - // Send mail by command static bool HandleSendMailCommand(ChatHandler* handler, char const* args) { diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 99ec263b8f9..e3cd185e4a3 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -642,19 +642,13 @@ public: { handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid); - // wpCreature - Creature* wpCreature = NULL; - if (wpGuid != 0) - { - wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); - if (wpCreature) + if (Creature* wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT))) { wpCreature->CombatStop(); wpCreature->DeleteFromDB(); wpCreature->AddObjectToRemoveList(); } - } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA); @@ -681,15 +675,12 @@ public: Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); { - // wpCreature - Creature* wpCreature = NULL; // What to do: // Move the visual spawnpoint // Respawn the owner of the waypoints if (wpGuid != 0) { - wpCreature = map->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); - if (wpCreature) + if (Creature* wpCreature = map->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT))) { wpCreature->CombatStop(); wpCreature->DeleteFromDB(); diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp index 204fbe5223b..25c3f2e41e3 100644 --- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp @@ -243,11 +243,9 @@ public: std::list<HostileReference*> threatlist = me->getThreatManager().getThreatList(); for (std::list<HostileReference*>::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) { - Unit* unit; if ((*i) && (*i)->getSource()) { - unit = Unit::GetUnit(*me, (*i)->getUnitGuid()); - if (unit) + if (Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid())) { //Cast affliction DoCast(unit, RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index 06c1243645c..533a1aac2f0 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -201,12 +201,11 @@ public: { for (uint8 i = 0; i < 4; ++i) { - Creature* Temp = NULL; if (AddGUID[i]) { - Temp = Creature::GetCreature((*me), AddGUID[i]); - if (Temp && Temp->isAlive()) - Temp->DisappearAndDie(); + Creature* temp = Creature::GetCreature((*me), AddGUID[i]); + if (temp && temp->isAlive()) + temp->DisappearAndDie(); } } } @@ -215,14 +214,13 @@ public: { for (uint8 i = 0; i < 4; ++i) { - Creature* Temp = NULL; if (AddGUID[i]) { - Temp = Creature::GetCreature((*me), AddGUID[i]); - if (Temp && Temp->isAlive()) + Creature* temp = Creature::GetCreature((*me), AddGUID[i]); + if (temp && temp->isAlive()) { - Temp->AI()->AttackStart(me->getVictim()); - DoZoneInCombat(Temp); + temp->AI()->AttackStart(me->getVictim()); + DoZoneInCombat(temp); } else EnterEvadeMode(); } @@ -250,13 +248,12 @@ public: { for (uint8 i = 0; i < 4; ++i) { - Creature* Temp = NULL; if (AddGUID[i]) { - Temp = Unit::GetCreature((*me), AddGUID[i]); - if (Temp && Temp->isAlive()) - if (!Temp->getVictim()) - Temp->AI()->AttackStart(me->getVictim()); + Creature* temp = Unit::GetCreature((*me), AddGUID[i]); + if (temp && temp->isAlive()) + if (!temp->getVictim()) + temp->AI()->AttackStart(me->getVictim()); } } CheckAdds_Timer = 5000; diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp index 84e9957a60c..fa99078cedb 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp @@ -77,7 +77,7 @@ class boss_golemagg : public CreatureScript void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - if (HealthBelowPct(10) || me->HasAura(SPELL_ENRAGE)) + if (!HealthBelowPct(10) || me->HasAura(SPELL_ENRAGE)) return; DoCast(me, SPELL_ENRAGE, true); diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp index d4c037d45c3..b405f9eba85 100644 --- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp +++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp @@ -240,7 +240,6 @@ public: return; Creature* pArchmage = instance->GetCreature(uiArchmageArugalGUID); - Creature* summon = NULL; if (!pArchmage || !pArchmage->isAlive()) return; @@ -252,7 +251,8 @@ public: switch (uiPhase) { case 1: - summon = pArchmage->SummonCreature(pArchmage->GetEntry(), SpawnLocation[4], TEMPSUMMON_TIMED_DESPAWN, 10000); + { + Creature* summon = pArchmage->SummonCreature(pArchmage->GetEntry(), SpawnLocation[4], TEMPSUMMON_TIMED_DESPAWN, 10000); summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); summon->SetReactState(REACT_DEFENSIVE); summon->CastSpell(summon, SPELL_ASHCROMBE_TELEPORT, true); @@ -260,13 +260,16 @@ public: uiTimer = 2000; uiPhase = 2; break; + } case 2: + { pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); pArchmage->SummonCreature(NPC_ARUGAL_VOIDWALKER, SpawnLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60000); uiPhase = 0; break; + } } } else uiTimer -= uiDiff; diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp index 3ffb873e4d2..74fad4f94d8 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp @@ -95,14 +95,17 @@ class boss_archaedas : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); } - void ActivateMinion(uint64 uiGuid, bool bFlag) + void ActivateMinion(uint64 uiGuid, bool flag) { - Unit* pMinion = Unit::GetUnit(*me, uiGuid); + Unit* minion = Unit::GetUnit(*me, uiGuid); - if (pMinion && pMinion->isAlive()) + if (minion && minion->isAlive()) { - DoCast(pMinion, SPELL_AWAKEN_VAULT_WALKER, bFlag); - pMinion->CastSpell(pMinion, SPELL_ARCHAEDAS_AWAKEN, true); + DoCast(minion, SPELL_AWAKEN_VAULT_WALKER, flag); + minion->CastSpell(minion, SPELL_ARCHAEDAS_AWAKEN, true); + minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + minion->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE); + minion->setFaction(14); } } diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp index ade07039a23..ee82da668f8 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp @@ -202,6 +202,9 @@ class instance_uldaman : public InstanceMapScript continue; archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true); target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true); + target->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + target->setFaction(14); return; // only want the first one we find } } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp index 1009d3e0a0a..8fb3dd55077 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp @@ -315,14 +315,12 @@ class boss_zuljin : public CreatureScript { for (uint8 i = 0; i < 4; ++i) { - Unit* Temp = NULL; if (SpiritGUID[i]) { - Temp = Unit::GetUnit(*me, SpiritGUID[i]); - if (Temp) + if (Unit* temp = Unit::GetUnit(*me, SpiritGUID[i])) { - Temp->SetVisible(false); - Temp->setDeathState(DEAD); + temp->SetVisible(false); + temp->setDeathState(DEAD); } } SpiritGUID[i] = 0; diff --git a/src/server/scripts/EasternKingdoms/wetlands.cpp b/src/server/scripts/EasternKingdoms/wetlands.cpp index fac8fb51c2d..34e6e7c9ddf 100644 --- a/src/server/scripts/EasternKingdoms/wetlands.cpp +++ b/src/server/scripts/EasternKingdoms/wetlands.cpp @@ -60,12 +60,12 @@ public: { npc_tapoke_slim_jahnAI(Creature* creature) : npc_escortAI(creature) { } - bool m_bFriendSummoned; + bool IsFriendSummoned; void Reset() { if (!HasEscortState(STATE_ESCORT_ESCORTING)) - m_bFriendSummoned = false; + IsFriendSummoned = false; } void WaypointReached(uint32 waypointId) @@ -83,14 +83,12 @@ public: void EnterCombat(Unit* /*who*/) { - Player* player = GetPlayerForEscort(); - - if (HasEscortState(STATE_ESCORT_ESCORTING) && !m_bFriendSummoned && player) + if (HasEscortState(STATE_ESCORT_ESCORTING) && !IsFriendSummoned && GetPlayerForEscort()) { for (uint8 i = 0; i < 3; ++i) DoCast(me, SPELL_CALL_FRIENDS, true); - m_bFriendSummoned = true; + IsFriendSummoned = true; } } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index 5b6dc784113..ee7ef383603 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -222,11 +222,9 @@ public: ItemPosCountVec dest; uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_TEAR_OF_GODDESS, 1); if (msg == EQUIP_ERR_OK) - { - Item* item = player->StoreNewItem(dest, ITEM_TEAR_OF_GODDESS, true); - if (item && player) + if (Item* item = player->StoreNewItem(dest, ITEM_TEAR_OF_GODDESS, true)) player->SendNewItem(item, 1, true, false, true); - } + player->SEND_GOSSIP_MENU(907, creature->GetGUID()); } return true; diff --git a/src/server/scripts/Kalimdor/silithus.cpp b/src/server/scripts/Kalimdor/silithus.cpp index 1636c867b30..1fe945b06d4 100644 --- a/src/server/scripts/Kalimdor/silithus.cpp +++ b/src/server/scripts/Kalimdor/silithus.cpp @@ -224,7 +224,6 @@ public: }; - /*### ## go_wind_stone ###*/ diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index 2ea234775c0..d335d36e112 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -314,15 +314,14 @@ class boss_gothik : public CreatureScript bool CheckGroupSplitted() { - bool checklife = false; - bool checkdead = false; - Map* map = me->GetMap(); if (map && map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) { + bool checklife = false; + bool checkdead = false; for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->getSource() && i->getSource()->isAlive() && diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp index ecc012eb25d..1f1d24453ee 100644 --- a/src/server/scripts/Northrend/dragonblight.cpp +++ b/src/server/scripts/Northrend/dragonblight.cpp @@ -79,16 +79,16 @@ public: enum StrengthenAncientsMisc { - SAY_WALKER_FRIENDLY = 0, - SAY_WALKER_ENEMY = 1, - SAY_LOTHALOR = 0, + SAY_WALKER_FRIENDLY = 0, + SAY_WALKER_ENEMY = 1, + SAY_LOTHALOR = 0, - SPELL_CREATE_ITEM_BARK = 47550, - SPELL_CONFUSED = 47044, + SPELL_CREATE_ITEM_BARK = 47550, + SPELL_CONFUSED = 47044, - NPC_LOTHALOR = 26321, + NPC_LOTHALOR = 26321, - FACTION_WALKER_ENEMY = 14, + FACTION_WALKER_ENEMY = 14, }; class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker @@ -170,9 +170,56 @@ public: } }; +/*###### +## wyrmrest_defender +######*/ + +enum WyrmDefenderEnum +{ + QUEST_DEFENDING_WYRMREST_TEMPLE = 12372, + GOSSIP_TEXTID_DEF1 = 12899, + GOSSIP_TEXTID_DEF2 = 12900, + SPELL_CHARACTER_SCRIPT = 49213 +}; + +#define GOSSIP_ITEM_1 "We need to get into the fight. Are you ready?" + +class npc_wyrmrest_defender : public CreatureScript +{ + public: + npc_wyrmrest_defender() : CreatureScript("npc_wyrmrest_defender") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_DEFENDING_WYRMREST_TEMPLE) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF1, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF2, creature->GetGUID()); + // Makes player cast trigger spell for 49207 on self + player->CastSpell(player, SPELL_CHARACTER_SCRIPT, true); + } + + return true; + } +}; + void AddSC_dragonblight() { new npc_alexstrasza_wr_gate; new spell_q12096_q12092_dummy; new spell_q12096_q12092_bark; + new npc_wyrmrest_defender; } diff --git a/src/server/scripts/Northrend/storm_peaks.cpp b/src/server/scripts/Northrend/storm_peaks.cpp index 6bf342e4643..976a6e5dba5 100644 --- a/src/server/scripts/Northrend/storm_peaks.cpp +++ b/src/server/scripts/Northrend/storm_peaks.cpp @@ -20,6 +20,7 @@ #include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "Vehicle.h" +#include "CombatAI.h" /*###### ## npc_agnetta_tyrsdottar @@ -131,229 +132,6 @@ public: } }; -/*###### -## npc_thorim -######*/ - -#define GOSSIP_HN "Thorim?" -#define GOSSIP_SN1 "Can you tell me what became of Sif?" -#define GOSSIP_SN2 "He did more than that, Thorim. He controls Ulduar now." -#define GOSSIP_SN3 "It needn't end this way." - -enum eThorim -{ - QUEST_SIBLING_RIVALRY = 13064, - NPC_THORIM = 29445, - GOSSIP_TEXTID_THORIM1 = 13799, - GOSSIP_TEXTID_THORIM2 = 13801, - GOSSIP_TEXTID_THORIM3 = 13802, - GOSSIP_TEXTID_THORIM4 = 13803 -}; - -class npc_thorim : public CreatureScript -{ -public: - npc_thorim() : CreatureScript("npc_thorim") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_SIBLING_RIVALRY) == QUEST_STATUS_INCOMPLETE) { - player->ADD_GOSSIP_ITEM(0, GOSSIP_HN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM1, creature->GetGUID()); - return true; - } - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(0, GOSSIP_SN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(0, GOSSIP_SN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM3, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(0, GOSSIP_SN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM4, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->CompleteQuest(QUEST_SIBLING_RIVALRY); - break; - } - return true; - } -}; - -/*###### -## npc_victorious_challenger -######*/ - -#define GOSSIP_CHALLENGER "Let's do this, sister." - -enum eVictoriousChallenger -{ - QUEST_TAKING_ALL_CHALLENGERS = 12971, - QUEST_DEFENDING_YOUR_TITLE = 13423, - - SPELL_SUNDER_ARMOR = 11971, - SPELL_REND_VC = 11977 -}; - -class npc_victorious_challenger : public CreatureScript -{ -public: - npc_victorious_challenger() : CreatureScript("npc_victorious_challenger") { } - - struct npc_victorious_challengerAI : public ScriptedAI - { - npc_victorious_challengerAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 SunderArmorTimer; - uint32 RendTimer; - - void Reset() - { - me->RestoreFaction(); - - SunderArmorTimer = 10000; - RendTimer = 15000; - } - - void UpdateAI(const uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (RendTimer < diff) - { - DoCast(me->getVictim(), SPELL_REND_VC, true); - RendTimer = 15000; - }else RendTimer -= diff; - - if (SunderArmorTimer < diff) - { - DoCast(me->getVictim(), SPELL_SUNDER_ARMOR, true); - SunderArmorTimer = 10000; - }else SunderArmorTimer -= diff; - - DoMeleeAttackIfReady(); - } - - void KilledUnit(Unit* /*victim*/) - { - me->RestoreFaction(); - } - - }; - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_TAKING_ALL_CHALLENGERS) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_DEFENDING_YOUR_TITLE) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CHALLENGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(14); - creature->AI()->AttackStart(player); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_victorious_challengerAI(creature); - } -}; - -/*###### -## npc_loklira_crone -######*/ - -#define GOSSIP_LOKLIRACRONE "Tell me about this proposal" -#define GOSSIP_LOKLIRACRONE1 "What happened then?" -#define GOSSIP_LOKLIRACRONE2 "You want me to take part in the Hyldsmeet to end the war?" -#define GOSSIP_LOKLIRACRONE3 "Very well. I'll take part in this competition." - -enum eLokliraCrone -{ - QUEST_HYLDSMEET = 12970, - - GOSSIP_TEXTID_LOK1 = 13778, - GOSSIP_TEXTID_LOK2 = 13779, - GOSSIP_TEXTID_LOK3 = 13780 -}; - -class npc_loklira_crone : public CreatureScript -{ -public: - npc_loklira_crone() : CreatureScript("npc_loklira_crone") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_HYLDSMEET) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK1, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK3, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->CompleteQuest(QUEST_HYLDSMEET); - break; - } - return true; - } -}; - ///////////////////// ///npc_injured_goblin ///////////////////// @@ -506,14 +284,12 @@ public: ## npc_brunnhildar_prisoner ######*/ -enum brunhildar { - NPC_QUEST_GIVER = 29592, - +enum BrunnhildarPrisoner { SPELL_ICE_PRISON = 54894, - SPELL_KILL_CREDIT_PRISONER = 55144, - SPELL_KILL_CREDIT_DRAKE = 55143, - SPELL_SUMMON_LIBERATED = 55073, - SPELL_ICE_LANCE = 55046 + SPELL_ICE_LANCE = 55046, + SPELL_FREE_PRISONER = 55048, + SPELL_RIDE_DRAKE = 55074, + SPELL_SHARD_IMPACT = 55047 }; class npc_brunnhildar_prisoner : public CreatureScript @@ -525,129 +301,169 @@ public: { npc_brunnhildar_prisonerAI(Creature* creature) : ScriptedAI(creature) {} - uint64 drakeGUID; - uint16 enter_timer; - bool hasEmptySeats; + bool freed; void Reset() { + freed = false; me->CastSpell(me, SPELL_ICE_PRISON, true); - enter_timer = 0; - drakeGUID = 0; - hasEmptySeats = false; } - void UpdateAI(const uint32 diff) + void JustRespawned() + { + Reset(); + } + + void UpdateAI(const uint32 /*diff*/) { - //TODO: not good script - if (!drakeGUID) + if (!freed) return; - Creature* drake = Unit::GetCreature(*me, drakeGUID); - if (!drake) + if (!me->HasUnitState(UNIT_STATE_ONVEHICLE)) { - drakeGUID = 0; - return; + me->DespawnOrUnsummon(); } + } - // drake unsummoned, passengers dropped - if (!me->IsOnVehicle(drake) && !hasEmptySeats) - me->DespawnOrUnsummon(3000); - - if (enter_timer <= 0) + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id != SPELL_ICE_LANCE) return; - if (enter_timer < diff) + if (caster->GetVehicleKit()->GetAvailableSeatCount() != 0) { - enter_timer = 0; - if (hasEmptySeats) - me->JumpTo(drake, 25.0f); - else - Reset(); + me->CastSpell(me, SPELL_FREE_PRISONER, true); + me->CastSpell(caster, SPELL_RIDE_DRAKE, true); + me->CastSpell(me, SPELL_SHARD_IMPACT, true); + freed = true; } - else - enter_timer -= diff; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_brunnhildar_prisonerAI(creature); + } +}; + +/*###### +## npc_freed_protodrake +######*/ + +enum FreedProtoDrake +{ + AREA_VALLEY_OF_ANCIENT_WINTERS = 4437, + TEXT_EMOTE = 0, + SPELL_KILL_CREDIT_PRISONER = 55144, + SPELL_SUMMON_LIBERATED = 55073, + SPELL_KILL_CREDIT_DRAKE = 55143 +}; + +const Position FreedDrakeWaypoints[16] = +{ + {7294.96f, -2418.733f, 823.869f, 0.0f}, + {7315.984f, -2331.46f, 826.3972f, 0.0f}, + {7271.826f, -2271.479f, 833.5917f, 0.0f}, + {7186.253f, -2218.475f, 847.5632f, 0.0f}, + {7113.195f, -2164.288f, 850.2301f, 0.0f}, + {7078.018f, -2063.106f, 854.7581f, 0.0f}, + {7073.221f, -1983.382f, 861.9246f, 0.0f}, + {7061.455f, -1885.899f, 865.119f, 0.0f}, + {7033.32f, -1826.775f, 876.2578f, 0.0f}, + {6999.902f, -1784.012f, 897.4521f, 0.0f}, + {6954.913f, -1747.043f, 897.4521f, 0.0f}, + {6933.856f, -1720.698f, 882.2022f, 0.0f}, + {6932.729f, -1687.306f, 866.1189f, 0.0f}, + {6952.458f, -1663.802f, 849.8133f, 0.0f}, + {7002.819f, -1651.681f, 831.397f, 0.0f}, + {7026.531f, -1649.239f, 828.8406f, 0.0f} +}; + + +class npc_freed_protodrake : public CreatureScript +{ +public: + npc_freed_protodrake() : CreatureScript("npc_freed_protodrake") { } + + struct npc_freed_protodrakeAI : public VehicleAI + { + npc_freed_protodrakeAI(Creature* creature) : VehicleAI(creature) {} + + bool autoMove; + bool wpReached; + uint16 CheckTimer; + uint16 countWP; + + void Reset() + { + autoMove = false; + wpReached = false; + CheckTimer = 5000; + countWP = 0; } - void MoveInLineOfSight(Unit* who) + void MovementInform(uint32 type, uint32 id) { - if (!who || !drakeGUID) + if (type != POINT_MOTION_TYPE) return; - Creature* drake = Unit::GetCreature(*me, drakeGUID); - if (!drake) + if (id < 15) { - drakeGUID = 0; - return; + ++countWP; + wpReached = true; } - - if (!me->IsOnVehicle(drake) && !me->HasAura(SPELL_ICE_PRISON)) + else + // drake reached village { - if (who->IsVehicle() && me->IsWithinDist(who, 25.0f, true) && who->ToCreature() && who->ToCreature()->GetEntry() == 29709) + // get player that rides drake (from seat 0) + Unit* player = me->GetVehicleKit()->GetPassenger(0); + if (player && player->GetTypeId() == TYPEID_PLAYER) { - uint8 seat = who->GetVehicleKit()->GetNextEmptySeat(0, true); - if (seat <= 0) - return; - - me->EnterVehicle(who, seat); - me->SendMovementFlagUpdate(); - hasEmptySeats = false; + // for each prisoner on drake,give credit + for (uint8 i = 1; i < 4; ++i) + if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i)) + { + if (prisoner->GetTypeId() != TYPEID_UNIT) + return; + prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true); + prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true); + prisoner->ExitVehicle(); + } + me->CastSpell(me, SPELL_KILL_CREDIT_DRAKE, true); + player->ExitVehicle(); } } + } - if (who->ToCreature() && me->IsOnVehicle(drake)) + void UpdateAI(const uint32 diff) + { + if (!autoMove) { - if (who->ToCreature()->GetEntry() == NPC_QUEST_GIVER && me->IsWithinDist(who, 15.0f, false)) + if (CheckTimer < diff) { - Unit* rider = drake->GetVehicleKit()->GetPassenger(0); - if (!rider) - return; - - rider->CastSpell(rider, SPELL_KILL_CREDIT_PRISONER, true); - - me->ExitVehicle(); - me->CastSpell(me, SPELL_SUMMON_LIBERATED, true); - me->DespawnOrUnsummon(500); - - // drake is empty now, deliver credit for drake and despawn him - if (drake->GetVehicleKit()->HasEmptySeat(1) && - drake->GetVehicleKit()->HasEmptySeat(2) && - drake->GetVehicleKit()->HasEmptySeat(3)) + CheckTimer = 5000; + if (me->GetAreaId() == AREA_VALLEY_OF_ANCIENT_WINTERS) { - // not working rider->CastSpell(rider, SPELL_KILL_CREDIT_DRAKE, true); - if (rider->ToPlayer()) - rider->ToPlayer()->KilledMonsterCredit(29709, 0); - - drake->DespawnOrUnsummon(0); + Talk(TEXT_EMOTE, me->GetVehicleKit()->GetPassenger(0)->GetGUID()); + autoMove = true; + wpReached = true; } } + else + CheckTimer -= diff; } - } - - void SpellHit(Unit* hitter, const SpellInfo* spell) - { - if (!hitter || !spell) - return; - - if (spell->Id != SPELL_ICE_LANCE) - return; - - me->RemoveAura(SPELL_ICE_PRISON); - enter_timer = 500; - if (hitter->IsVehicle()) - drakeGUID = hitter->GetGUID(); - else - return; - - if (hitter->GetVehicleKit()->GetNextEmptySeat(0, true)) - hasEmptySeats = true; + if (wpReached && autoMove) + { + wpReached = false; + me->GetMotionMaster()->MovePoint(countWP, FreedDrakeWaypoints[countWP]); + } } }; CreatureAI* GetAI(Creature* creature) const { - return new npc_brunnhildar_prisonerAI(creature); + return new npc_freed_protodrakeAI(creature); } }; @@ -752,12 +568,10 @@ void AddSC_storm_peaks() { new npc_agnetta_tyrsdottar(); new npc_frostborn_scout(); - new npc_thorim(); - new npc_victorious_challenger(); - new npc_loklira_crone(); new npc_injured_goblin(); new npc_roxi_ramrocket(); new npc_brunnhildar_prisoner(); + new npc_freed_protodrake(); new npc_icefang(); new npc_hyldsmeet_protodrake(); } diff --git a/src/server/scripts/Northrend/wintergrasp.cpp b/src/server/scripts/Northrend/wintergrasp.cpp index fc967acf9e2..59e9a31c4cf 100644 --- a/src/server/scripts/Northrend/wintergrasp.cpp +++ b/src/server/scripts/Northrend/wintergrasp.cpp @@ -119,8 +119,6 @@ class npc_wg_demolisher_engineer : public CreatureScript if (creature->isQuestGiver()) player->PrepareQuestMenu(creature->GetGUID()); - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (canBuild(creature)) { if (player->HasAura(SPELL_CORPORAL)) @@ -143,8 +141,6 @@ class npc_wg_demolisher_engineer : public CreatureScript { player->CLOSE_GOSSIP_MENU(); - Battlefield* wintergrasp= sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (canBuild(creature)) { switch (action - GOSSIP_ACTION_INFO_DEF) @@ -169,9 +165,9 @@ class npc_wg_demolisher_engineer : public CreatureScript bool canBuild(Creature* creature) { Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!wintergrasp) return false; + switch (creature->GetEntry()) { case NPC_GOBLIN_MECHANIC: @@ -207,7 +203,7 @@ class npc_wg_spirit_guide : public CreatureScript return true; } - bool OnGossipSelect(Player* player, Creature* /*creature*/ , uint32 /*sender */ , uint32 action) + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) { player->CLOSE_GOSSIP_MENU(); @@ -307,15 +303,13 @@ class go_wg_vehicle_teleporter : public GameObjectScript { if (_checkTimer <= diff) { - // Tabulation madness in the hole! - for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++) - if (Creature* vehicleCreature = go->FindNearestCreature(vehiclesList[i], 3.0f, true)) - if (!vehicleCreature->HasAura(SPELL_VEHICLE_TELEPORT)) - if (Vehicle* vehicle = vehicleCreature->GetVehicle()) - if (Unit* passenger = vehicle->GetPassenger(0)) - if (go->GetUInt32Value(GAMEOBJECT_FACTION) == passenger->getFaction()) - if (Creature* teleportTrigger = vehicleCreature->FindNearestCreature(NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC, 100.0f, true)) - teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true); + if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + // Tabulation madness in the hole! + for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++) + if (Creature* vehicleCreature = go->FindNearestCreature(vehiclesList[i], 3.0f, true)) + if (!vehicleCreature->HasAura(SPELL_VEHICLE_TELEPORT) && vehicleCreature->getFaction() == WintergraspFaction[wg->GetDefenderTeam()]) + if (Creature* teleportTrigger = vehicleCreature->FindNearestCreature(NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC, 100.0f, true)) + teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true); _checkTimer = 1000; } @@ -326,7 +320,7 @@ class go_wg_vehicle_teleporter : public GameObjectScript uint32 _checkTimer; }; - GameObjectAI* GetGameObjectAI(GameObject* go) const + GameObjectAI* GetAI(GameObject* go) const { return new go_wg_vehicle_teleporterAI(go); } @@ -508,7 +502,7 @@ class spell_wintergrasp_grab_passenger : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { if (Player* target = GetHitPlayer()) - target->CastSpell(GetCaster(), SPELL_RIDE_WG_VEHICLE, true); + target->CastSpell(GetCaster(), SPELL_RIDE_WG_VEHICLE, false); } void Register() @@ -547,6 +541,36 @@ public: } }; +class spell_wintergrasp_defender_teleport : public SpellScriptLoader +{ +public: + spell_wintergrasp_defender_teleport() : SpellScriptLoader("spell_wintergrasp_defender_teleport") { } + + class spell_wintergrasp_defender_teleport_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wintergrasp_defender_teleport_SpellScript); + + SpellCastResult CheckCast() + { + if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + if (Player* target = GetExplTargetUnit()->ToPlayer()) + if (target->GetTeamId() != wg->GetDefenderTeam()) + return SPELL_FAILED_BAD_TARGETS; + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_wintergrasp_defender_teleport_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wintergrasp_defender_teleport_SpellScript(); + } +}; + void AddSC_wintergrasp() { new npc_wg_queue(); @@ -557,4 +581,5 @@ void AddSC_wintergrasp() new spell_wintergrasp_force_building(); new spell_wintergrasp_grab_passenger(); new achievement_wg_didnt_stand_a_chance(); + new spell_wintergrasp_defender_teleport(); } diff --git a/src/server/scripts/OutdoorPvP/CMakeLists.txt b/src/server/scripts/OutdoorPvP/CMakeLists.txt index 237b974aa9d..15d7dbd7e8d 100644 --- a/src/server/scripts/OutdoorPvP/CMakeLists.txt +++ b/src/server/scripts/OutdoorPvP/CMakeLists.txt @@ -17,8 +17,6 @@ set(scripts_STAT_SRCS OutdoorPvP/OutdoorPvPNA.cpp OutdoorPvP/OutdoorPvPHP.cpp OutdoorPvP/OutdoorPvPTF.h - OutdoorPvP/OutdoorPvPEP.h - OutdoorPvP/OutdoorPvPEP.cpp OutdoorPvP/OutdoorPvPHP.h OutdoorPvP/OutdoorPvPZM.h OutdoorPvP/OutdoorPvPNA.h diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp deleted file mode 100755 index 2a94ddb3134..00000000000 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/* - * Copyright (C) 2008-2012 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 "OutdoorPvPEP.h" -#include "WorldPacket.h" -#include "Player.h" -#include "GameObject.h" -#include "ObjectMgr.h" -#include "ObjectAccessor.h" -#include "OutdoorPvPMgr.h" -#include "Creature.h" -#include "Language.h" -#include "World.h" -#include "GossipDef.h" - -OPvPCapturePointEP_EWT::OPvPCapturePointEP_EWT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_UnitsSummonedSide(0) -{ - SetCapturePointData(EPCapturePoints[EP_EWT].entry, EPCapturePoints[EP_EWT].map, EPCapturePoints[EP_EWT].x, EPCapturePoints[EP_EWT].y, EPCapturePoints[EP_EWT].z, EPCapturePoints[EP_EWT].o, EPCapturePoints[EP_EWT].rot0, EPCapturePoints[EP_EWT].rot1, EPCapturePoints[EP_EWT].rot2, EPCapturePoints[EP_EWT].rot3); - AddObject(EP_EWT_FLAGS, EPTowerFlags[EP_EWT].entry, EPTowerFlags[EP_EWT].map, EPTowerFlags[EP_EWT].x, EPTowerFlags[EP_EWT].y, EPTowerFlags[EP_EWT].z, EPTowerFlags[EP_EWT].o, EPTowerFlags[EP_EWT].rot0, EPTowerFlags[EP_EWT].rot1, EPTowerFlags[EP_EWT].rot2, EPTowerFlags[EP_EWT].rot3); -} - -void OPvPCapturePointEP_EWT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_EWT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_EWT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - artkit = 2; - SummonSupportUnitAtNorthpassTower(ALLIANCE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - artkit = 1; - SummonSupportUnitAtNorthpassTower(HORDE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_EWT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_EWT_CM, 0); -} - -void OPvPCapturePointEP_EWT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_EWT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_EWT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_EWT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_EWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_EWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_EWT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_EWT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_EWT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_EWT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_EWT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_EWT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_EWT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_EWT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_EWT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_EWT::SummonSupportUnitAtNorthpassTower(uint32 team) -{ - if (m_UnitsSummonedSide != team) - { - m_UnitsSummonedSide = team; - const creature_type * ct = NULL; - if (team == ALLIANCE) - ct=EP_EWT_Summons_A; - else - ct=EP_EWT_Summons_H; - - for (uint8 i = 0; i < EP_EWT_NUM_CREATURES; ++i) - { - DelCreature(i); - AddCreature(i, ct[i].entry, ct[i].teamval, ct[i].map, ct[i].x, ct[i].y, ct[i].z, ct[i].o, 1000000); - } - } -} - -// NPT -OPvPCapturePointEP_NPT::OPvPCapturePointEP_NPT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_SummonedGOSide(0) -{ - SetCapturePointData(EPCapturePoints[EP_NPT].entry, EPCapturePoints[EP_NPT].map, EPCapturePoints[EP_NPT].x, EPCapturePoints[EP_NPT].y, EPCapturePoints[EP_NPT].z, EPCapturePoints[EP_NPT].o, EPCapturePoints[EP_NPT].rot0, EPCapturePoints[EP_NPT].rot1, EPCapturePoints[EP_NPT].rot2, EPCapturePoints[EP_NPT].rot3); - AddObject(EP_NPT_FLAGS, EPTowerFlags[EP_NPT].entry, EPTowerFlags[EP_NPT].map, EPTowerFlags[EP_NPT].x, EPTowerFlags[EP_NPT].y, EPTowerFlags[EP_NPT].z, EPTowerFlags[EP_NPT].o, EPTowerFlags[EP_NPT].rot0, EPTowerFlags[EP_NPT].rot1, EPTowerFlags[EP_NPT].rot2, EPTowerFlags[EP_NPT].rot3); -} - -void OPvPCapturePointEP_NPT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_NPT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_NPT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - artkit = 2; - SummonGO(ALLIANCE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - artkit = 1; - SummonGO(HORDE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - m_SummonedGOSide = 0; - DelObject(EP_NPT_BUFF); - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - m_SummonedGOSide = 0; - DelObject(EP_NPT_BUFF); - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - m_SummonedGOSide = 0; - DelObject(EP_NPT_BUFF); - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_NPT_CM, 0); -} - -void OPvPCapturePointEP_NPT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_NPT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_NPT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_NPT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_NPT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_NPT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_NPT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_NPT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_NPT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_NPT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_NPT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_NPT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_NPT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_NPT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_NPT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_NPT::SummonGO(uint32 team) -{ - if (m_SummonedGOSide != team) - { - m_SummonedGOSide = team; - DelObject(EP_NPT_BUFF); - AddObject(EP_NPT_BUFF, EP_NPT_LordaeronShrine.entry, EP_NPT_LordaeronShrine.map, EP_NPT_LordaeronShrine.x, EP_NPT_LordaeronShrine.y, EP_NPT_LordaeronShrine.z, EP_NPT_LordaeronShrine.o, EP_NPT_LordaeronShrine.rot0, EP_NPT_LordaeronShrine.rot1, EP_NPT_LordaeronShrine.rot2, EP_NPT_LordaeronShrine.rot3); - GameObject* go = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_BUFF]); - if (go) - go->SetUInt32Value(GAMEOBJECT_FACTION, (team == ALLIANCE ? 84 : 83)); - } -} - -// CGT -OPvPCapturePointEP_CGT::OPvPCapturePointEP_CGT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_GraveyardSide(0) -{ - SetCapturePointData(EPCapturePoints[EP_CGT].entry, EPCapturePoints[EP_CGT].map, EPCapturePoints[EP_CGT].x, EPCapturePoints[EP_CGT].y, EPCapturePoints[EP_CGT].z, EPCapturePoints[EP_CGT].o, EPCapturePoints[EP_CGT].rot0, EPCapturePoints[EP_CGT].rot1, EPCapturePoints[EP_CGT].rot2, EPCapturePoints[EP_CGT].rot3); - AddObject(EP_CGT_FLAGS, EPTowerFlags[EP_CGT].entry, EPTowerFlags[EP_CGT].map, EPTowerFlags[EP_CGT].x, EPTowerFlags[EP_CGT].y, EPTowerFlags[EP_CGT].z, EPTowerFlags[EP_CGT].o, EPTowerFlags[EP_CGT].rot0, EPTowerFlags[EP_CGT].rot1, EPTowerFlags[EP_CGT].rot2, EPTowerFlags[EP_CGT].rot3); -} - -void OPvPCapturePointEP_CGT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_CGT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_CGT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - artkit = 2; - LinkGraveYard(ALLIANCE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - artkit = 1; - LinkGraveYard(HORDE); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_CGT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_CGT_CM, 0); -} - -void OPvPCapturePointEP_CGT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_CGT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_CGT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_CGT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_CGT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_CGT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_CGT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_CGT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_CGT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_CGT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_CGT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_CGT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_CGT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_CGT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_CGT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_CGT::LinkGraveYard(uint32 team) -{ - if (m_GraveyardSide != team) - { - m_GraveyardSide = team; - sObjectMgr->RemoveGraveYardLink(EP_GraveYardId, EP_GraveYardZone, team, false); - sObjectMgr->AddGraveYardLink(EP_GraveYardId, EP_GraveYardZone, team, false); - } -} - -// PWT -OPvPCapturePointEP_PWT::OPvPCapturePointEP_PWT(OutdoorPvP* pvp) -: OPvPCapturePoint(pvp), m_FlightMasterSpawned(0), m_TowerState(EP_TS_N) -{ - SetCapturePointData(EPCapturePoints[EP_PWT].entry, EPCapturePoints[EP_PWT].map, EPCapturePoints[EP_PWT].x, EPCapturePoints[EP_PWT].y, EPCapturePoints[EP_PWT].z, EPCapturePoints[EP_PWT].o, EPCapturePoints[EP_PWT].rot0, EPCapturePoints[EP_PWT].rot1, EPCapturePoints[EP_PWT].rot2, EPCapturePoints[EP_PWT].rot3); - AddObject(EP_PWT_FLAGS, EPTowerFlags[EP_PWT].entry, EPTowerFlags[EP_PWT].map, EPTowerFlags[EP_PWT].x, EPTowerFlags[EP_PWT].y, EPTowerFlags[EP_PWT].z, EPTowerFlags[EP_PWT].o, EPTowerFlags[EP_PWT].rot0, EPTowerFlags[EP_PWT].rot1, EPTowerFlags[EP_PWT].rot2, EPTowerFlags[EP_PWT].rot3); -} - -void OPvPCapturePointEP_PWT::ChangeState() -{ - // if changing from controlling alliance to horde or vice versa - if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_PWT_A)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, 0); - } - else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State ) - { - sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_PWT_H)); - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, 0); - } - - uint32 artkit = 21; - - switch (m_State) - { - case OBJECTIVESTATE_ALLIANCE: - m_TowerState = EP_TS_A; - SummonFlightMaster(ALLIANCE); - artkit = 2; - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, ALLIANCE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_A)); - break; - case OBJECTIVESTATE_HORDE: - m_TowerState = EP_TS_H; - SummonFlightMaster(HORDE); - artkit = 1; - ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, HORDE); - if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_H)); - break; - case OBJECTIVESTATE_NEUTRAL: - m_TowerState = EP_TS_N; - DelCreature(EP_PWT_FLIGHTMASTER); - m_FlightMasterSpawned = 0; - break; - case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - break; - case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE: - m_TowerState = EP_TS_N_A; - DelCreature(EP_PWT_FLIGHTMASTER); - m_FlightMasterSpawned = 0; - break; - case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - break; - case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE: - m_TowerState = EP_TS_N_H; - DelCreature(EP_PWT_FLIGHTMASTER); - m_FlightMasterSpawned = 0; - break; - } - - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_PWT_FLAGS]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit); - } - - UpdateTowerState(); - - // complete quest objective - if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H) - SendObjectiveComplete(EP_PWT_CM, 0); -} - -void OPvPCapturePointEP_PWT::SendChangePhase() -{ - // send this too, sometimes the slider disappears, dunno why :( - SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - // send these updates to only the ones in this objective - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - // send this too, sometimes it resets :S - SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); -} - -void OPvPCapturePointEP_PWT::FillInitialWorldStates(WorldPacket &data) -{ - data << EP_PWT_A << uint32(bool(m_TowerState & EP_TS_A)); - data << EP_PWT_H << uint32(bool(m_TowerState & EP_TS_H)); - data << EP_PWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A)); - data << EP_PWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H)); - data << EP_PWT_N << uint32(bool(m_TowerState & EP_TS_N)); -} - -void OPvPCapturePointEP_PWT::UpdateTowerState() -{ - m_PvP->SendUpdateWorldState(EP_PWT_A, bool(m_TowerState & EP_TS_A)); - m_PvP->SendUpdateWorldState(EP_PWT_H, bool(m_TowerState & EP_TS_H)); - m_PvP->SendUpdateWorldState(EP_PWT_N_A, bool(m_TowerState & EP_TS_N_A)); - m_PvP->SendUpdateWorldState(EP_PWT_N_H, bool(m_TowerState & EP_TS_N_H)); - m_PvP->SendUpdateWorldState(EP_PWT_N, bool(m_TowerState & EP_TS_N)); -} - -bool OPvPCapturePointEP_PWT::HandlePlayerEnter(Player* player) -{ - if (OPvPCapturePoint::HandlePlayerEnter(player)) - { - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1); - uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct); - return true; - } - return false; -} - -void OPvPCapturePointEP_PWT::HandlePlayerLeave(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - OPvPCapturePoint::HandlePlayerLeave(player); -} - -void OPvPCapturePointEP_PWT::SummonFlightMaster(uint32 team) -{ - if (m_FlightMasterSpawned != team) - { - m_FlightMasterSpawned = team; - DelCreature(EP_PWT_FLIGHTMASTER); - AddCreature(EP_PWT_FLIGHTMASTER, EP_PWT_FlightMaster.entry, team, EP_PWT_FlightMaster.map, EP_PWT_FlightMaster.x, EP_PWT_FlightMaster.y, EP_PWT_FlightMaster.z, EP_PWT_FlightMaster.o); - /* - // sky - we need update gso code - - Creature* c = HashMapHolder<Creature>::Find(m_Creatures[EP_PWT_FLIGHTMASTER]); - //Spawn flight master as friendly to capturing team - c->SetUInt32Value(GAMEOBJECT_FACTION, (team == ALLIANCE ? 55 : 68)); - if (c) - { - GossipOption gso; - gso.Action = GOSSIP_OPTION_OUTDOORPVP; - gso.GossipId = 0; - gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_NPT)); - gso.Id = 50; - gso.Icon = 0; - gso.NpcFlag = 0; - gso.BoxMoney = 0; - gso.Coded = false; - c->addGossipOption(gso); - - gso.Action = GOSSIP_OPTION_OUTDOORPVP; - gso.GossipId = 0; - gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_EWT)); - gso.Id = 50; - gso.Icon = 0; - gso.NpcFlag = 0; - gso.BoxMoney = 0; - gso.Coded = false; - c->addGossipOption(gso); - - gso.Action = GOSSIP_OPTION_OUTDOORPVP; - gso.GossipId = 0; - gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_CGT)); - gso.Id = 50; - gso.Icon = 0; - gso.NpcFlag = 0; - gso.BoxMoney = 0; - gso.Coded = false; - c->addGossipOption(gso); - } - */ - } -} - -// ep -OutdoorPvPEP::OutdoorPvPEP() -{ - m_TypeId = OUTDOOR_PVP_EP; - memset(EP_Controls, 0, sizeof(EP_Controls)); - m_AllianceTowersControlled = 0; - m_HordeTowersControlled = 0; -} - -bool OutdoorPvPEP::SetupOutdoorPvP() -{ - for (uint8 i = 0; i < EPBuffZonesNum; ++i) - RegisterZone(EPBuffZones[i]); - - AddCapturePoint(new OPvPCapturePointEP_EWT(this)); - AddCapturePoint(new OPvPCapturePointEP_PWT(this)); - AddCapturePoint(new OPvPCapturePointEP_CGT(this)); - AddCapturePoint(new OPvPCapturePointEP_NPT(this)); - return true; -} - -bool OutdoorPvPEP::Update(uint32 diff) -{ - if (OutdoorPvP::Update(diff)) - { - m_AllianceTowersControlled = 0; - m_HordeTowersControlled = 0; - for (int i = 0; i < EP_TOWER_NUM; ++i) - { - if (EP_Controls[i] == ALLIANCE) - ++m_AllianceTowersControlled; - else if (EP_Controls[i] == HORDE) - ++m_HordeTowersControlled; - SendUpdateWorldState(EP_UI_TOWER_COUNT_A, m_AllianceTowersControlled); - SendUpdateWorldState(EP_UI_TOWER_COUNT_H, m_HordeTowersControlled); - BuffTeams(); - } - return true; - } - return false; -} - -void OutdoorPvPEP::HandlePlayerEnterZone(Player* player, uint32 zone) -{ - // add buffs - if (player->GetTeam() == ALLIANCE) - { - if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5) - player->CastSpell(player, EP_AllianceBuffs[m_AllianceTowersControlled-1], true); - } - else - { - if (m_HordeTowersControlled && m_HordeTowersControlled < 5) - player->CastSpell(player, EP_HordeBuffs[m_HordeTowersControlled-1], true); - } - OutdoorPvP::HandlePlayerEnterZone(player, zone); -} - -void OutdoorPvPEP::HandlePlayerLeaveZone(Player* player, uint32 zone) -{ - // remove buffs - if (player->GetTeam() == ALLIANCE) - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_AllianceBuffs[i]); - } - else - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_HordeBuffs[i]); - } - OutdoorPvP::HandlePlayerLeaveZone(player, zone); -} - -void OutdoorPvPEP::BuffTeams() -{ - for (PlayerSet::iterator itr = m_players[0].begin(); itr != m_players[0].end(); ++itr) - { - Player* player = *itr; - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_AllianceBuffs[i]); - if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5) - player->CastSpell(player, EP_AllianceBuffs[m_AllianceTowersControlled-1], true); - } - } - for (PlayerSet::iterator itr = m_players[1].begin(); itr != m_players[1].end(); ++itr) - { - Player* player = *itr; - { - for (int i = 0; i < 4; ++i) - player->RemoveAurasDueToSpell(EP_HordeBuffs[i]); - if (m_HordeTowersControlled && m_HordeTowersControlled < 5) - player->CastSpell(player, EP_HordeBuffs[m_HordeTowersControlled-1], true); - } - } -} - -void OutdoorPvPEP::SetControlledState(uint32 index, uint32 state) -{ - EP_Controls[index] = state; -} - -void OutdoorPvPEP::FillInitialWorldStates(WorldPacket & data) -{ - data << EP_UI_TOWER_COUNT_A << m_AllianceTowersControlled; - data << EP_UI_TOWER_COUNT_H << m_HordeTowersControlled; - data << EP_UI_TOWER_SLIDER_DISPLAY << uint32(0); - data << EP_UI_TOWER_SLIDER_POS << uint32(50); - data << EP_UI_TOWER_SLIDER_N << uint32(100); - for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - { - itr->second->FillInitialWorldStates(data); - } -} - -void OutdoorPvPEP::SendRemoveWorldStates(Player* player) -{ - player->SendUpdateWorldState(EP_UI_TOWER_COUNT_A, 0); - player->SendUpdateWorldState(EP_UI_TOWER_COUNT_H, 0); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, 0); - player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, 0); - - player->SendUpdateWorldState(EP_EWT_A, 0); - player->SendUpdateWorldState(EP_EWT_H, 0); - player->SendUpdateWorldState(EP_EWT_N, 0); - player->SendUpdateWorldState(EP_EWT_N_A, 0); - player->SendUpdateWorldState(EP_EWT_N_H, 0); - - player->SendUpdateWorldState(EP_PWT_A, 0); - player->SendUpdateWorldState(EP_PWT_H, 0); - player->SendUpdateWorldState(EP_PWT_N, 0); - player->SendUpdateWorldState(EP_PWT_N_A, 0); - player->SendUpdateWorldState(EP_PWT_N_H, 0); - - player->SendUpdateWorldState(EP_NPT_A, 0); - player->SendUpdateWorldState(EP_NPT_H, 0); - player->SendUpdateWorldState(EP_NPT_N, 0); - player->SendUpdateWorldState(EP_NPT_N_A, 0); - player->SendUpdateWorldState(EP_NPT_N_H, 0); - - player->SendUpdateWorldState(EP_CGT_A, 0); - player->SendUpdateWorldState(EP_CGT_H, 0); - player->SendUpdateWorldState(EP_CGT_N, 0); - player->SendUpdateWorldState(EP_CGT_N_A, 0); - player->SendUpdateWorldState(EP_CGT_N_H, 0); -} - -class OutdoorPvP_eastern_plaguelands : public OutdoorPvPScript -{ - public: - - OutdoorPvP_eastern_plaguelands() - : OutdoorPvPScript("outdoorpvp_ep") - { - } - - OutdoorPvP* GetOutdoorPvP() const - { - return new OutdoorPvPEP(); - } -}; - -void AddSC_outdoorpvp_ep() -{ - new OutdoorPvP_eastern_plaguelands(); -} diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h b/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h deleted file mode 100755 index 14712e0150d..00000000000 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2008-2012 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 OUTDOOR_PVP_EP_ -#define OUTDOOR_PVP_EP_ - -#include "DBCStructure.h" -#include "OutdoorPvP.h" - -const uint32 EP_AllianceBuffs[4] = {11413, 11414, 11415, 1386}; - -const uint32 EP_HordeBuffs[4] = {30880, 30683, 30682, 29520}; - -const uint32 EP_GraveYardZone = 139; - -const uint32 EP_GraveYardId = 927; - -const uint8 EPBuffZonesNum = 3; - -const uint32 EP_EWT_CM = 17690; -const uint32 EP_CGT_CM = 17689; -const uint32 EP_NPT_CM = 17696; -const uint32 EP_PWT_CM = 17698; - -const uint32 EPBuffZones[EPBuffZonesNum] = {139, 2017, 2057}; - -enum EP_TaxiNodes -{ - EP_CGT_Taxi = 87, - EP_EWT_Taxi = 86, - EP_NPT_Taxi = 85, - EP_PWT_Taxi = 84 -}; - -enum EP_EastwallTowerWorldStates -{ - EP_EWT_A = 2354, - EP_EWT_H = 2356, - EP_EWT_N_A = 2359, // ally conquested - EP_EWT_N_H = 2360, - EP_EWT_N = 2361 -}; - -enum EP_NorthpassTowerWorldStates -{ - EP_NPT_N = 2352, - EP_NPT_N_A = 2362, - EP_NPT_N_H = 2363, - EP_NPT_A = 2372, - EP_NPT_H = 2373 -}; - -enum EP_PlagewoodTowerWorldStates -{ - EP_PWT_N_A = 2366, - EP_PWT_N_H = 2353, //2367 not present! use neutral! - EP_PWT_A = 2370, - EP_PWT_H = 2371, - EP_PWT_N = 2353 -}; - -enum EP_CrownGuardTowerWorldStates -{ - EP_CGT_N_A = 2374, - EP_CGT_N_H = 2375, - EP_CGT_A = 2378, - EP_CGT_H = 2379, - EP_CGT_N = 2355 -}; - -enum EP_WorldStates -{ - EP_UI_TOWER_SLIDER_DISPLAY = 2426, - EP_UI_TOWER_SLIDER_POS = 2427, - EP_UI_TOWER_SLIDER_N = 2428, - - EP_UI_TOWER_COUNT_A = 2327, - EP_UI_TOWER_COUNT_H = 2328 -}; - -enum EP_Summons -{ - EP_EWT_COMMANDER = 0, - EP_EWT_SOLDIER1, - EP_EWT_SOLDIER2, - EP_EWT_SOLDIER3, - EP_EWT_SOLDIER4, - EP_PWT_FLIGHTMASTER, -}; - -enum EP_GoSummons -{ - EP_NPT_BUFF = 0, - EP_NPT_FLAGS, - EP_EWT_FLAGS, - EP_CGT_FLAGS, - EP_PWT_FLAGS -}; - -enum EP_Towers -{ - EP_EWT = 0, // plaguelands 03 - EP_NPT, // plaguelands 01 - EP_PWT, // plaguelands 04 - EP_CGT, // plaguelands 02 - EP_TOWER_NUM -}; - -const go_type EPCapturePoints[EP_TOWER_NUM] = -{ - {182097, 0, 2574.51f, -4794.89f, 144.704f, -1.45003f, -0.097056f, 0.095578f, -0.656229f, 0.742165f}, - {181899, 0, 3181.08f, -4379.36f, 174.123f, -2.03472f, -0.065392f, 0.119494f, -0.842275f, 0.521553f}, - {182098, 0, 2962.71f, -3042.31f, 154.789f, 2.08426f, -0.074807f, -0.113837f, 0.855928f, 0.49883f}, - {182096, 0, 1860.85f, -3731.23f, 196.716f, -2.53214f, 0.033967f, -0.131914f, 0.944741f, -0.298177f} -}; - -const go_type EPTowerFlags[EP_TOWER_NUM] = -{ - {182106, 0, 2569.60f, -4772.93f, 115.399f, 2.72271f, 0.0f, 0.0f, 0.978148f, 0.207912f}, - {182106, 0, 3148.17f, -4365.51f, 145.029f, 1.53589f, 0.0f, 0.0f, 0.694658f, 0.71934f}, - {182106, 0, 2992.63f, -3022.95f, 125.593f, 3.03687f, 0.0f, 0.0f, 0.99863f, 0.052336f}, - {182106, 0, 1838.42f, -3703.56f, 167.713f, 0.890118f, 0.0f, 0.0f, 0.430511f, 0.902585f} -}; - -const uint32 EPTowerPlayerEnterEvents[EP_TOWER_NUM] = {10691, 10699, 10701, 10705}; - -const uint32 EPTowerPlayerLeaveEvents[EP_TOWER_NUM] = {10692, 10698, 10700, 10704}; - -const uint8 EP_NUM_CREATURES = 6; -const uint8 EP_EWT_NUM_CREATURES = 5; - -// one lordaeron commander, 4 soldiers -// should be spawned at EWT and follow a path, but trans-grid pathing isn't safe, so summon them directly at NPT -const creature_type EP_EWT_Summons_A[EP_EWT_NUM_CREATURES] = -{ - {17635, 469, 0, 3167.61f, -4352.09f, 138.20f, 4.5811f}, - {17647, 469, 0, 3172.74f, -4352.99f, 139.14f, 4.9873f}, - {17647, 469, 0, 3165.89f, -4354.46f, 138.67f, 3.7244f}, - {17647, 469, 0, 3164.65f, -4350.26f, 138.22f, 2.4794f}, - {17647, 469, 0, 3169.91f, -4349.68f, 138.37f, 0.7444f} -}; - -const creature_type EP_EWT_Summons_H[EP_EWT_NUM_CREATURES] = -{ - {17995, 67, 0, 3167.61f, -4352.09f, 138.20f, 4.5811f}, - {17996, 67, 0, 3172.74f, -4352.99f, 139.14f, 4.9873f}, - {17996, 67, 0, 3165.89f, -4354.46f, 138.67f, 3.7244f}, - {17996, 67, 0, 3164.65f, -4350.26f, 138.22f, 2.4794f}, - {17996, 67, 0, 3169.91f, -4349.68f, 138.37f, 0.7444f} -}; - -enum EP_TowerStates -{ - EP_TS_N = 1, - EP_TS_N_A = 2, - EP_TS_N_H = 4, - EP_TS_A_P = 8, - EP_TS_H_P = 16, - EP_TS_A = 32, - EP_TS_H = 64 -}; - -// when spawning, pay attention at setting the faction manually! -const creature_type EP_PWT_FlightMaster = {17209, 0, 0, 2987.5f, -3049.11f, 120.126f, 5.75959f}; - -// after spawning, modify the faction so that only the controller will be able to use it with SetUInt32Value(GAMEOBJECT_FACTION, faction_id); -const go_type EP_NPT_LordaeronShrine = {181682, 0, 3167.72f, -4355.91f, 138.785f, 1.69297f, 0.0f, 0.0f, 0.748956f, 0.66262f}; - -class OutdoorPvPEP; - -class OPvPCapturePointEP_EWT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_EWT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void SummonSupportUnitAtNorthpassTower(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_TowerState; - - uint32 m_UnitsSummonedSide; -}; - -class OPvPCapturePointEP_NPT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_NPT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void SummonGO(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_TowerState; - - uint32 m_SummonedGOSide; -}; - -class OPvPCapturePointEP_CGT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_CGT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void LinkGraveYard(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_TowerState; - - uint32 m_GraveyardSide; -}; - -class OPvPCapturePointEP_PWT : public OPvPCapturePoint -{ - public: - - OPvPCapturePointEP_PWT(OutdoorPvP* pvp); - - void ChangeState(); - - void SendChangePhase(); - - void FillInitialWorldStates(WorldPacket & data); - - // used when player is activated/inactivated in the area - bool HandlePlayerEnter(Player* player); - void HandlePlayerLeave(Player* player); - - protected: - - void SummonFlightMaster(uint32 team); - - void UpdateTowerState(); - - protected: - - uint32 m_FlightMasterSpawned; - - uint32 m_TowerState; -}; - -class OutdoorPvPEP : public OutdoorPvP -{ - public: - - OutdoorPvPEP(); - - bool SetupOutdoorPvP(); - - void HandlePlayerEnterZone(Player* player, uint32 zone); - void HandlePlayerLeaveZone(Player* player, uint32 zone); - - bool Update(uint32 diff); - - void FillInitialWorldStates(WorldPacket &data); - - void SendRemoveWorldStates(Player* player); - - void BuffTeams(); - - void SetControlledState(uint32 index, uint32 state); - - private: - - // how many towers are controlled - uint32 EP_Controls[EP_TOWER_NUM]; - - uint32 m_AllianceTowersControlled; - uint32 m_HordeTowersControlled; -}; - -#endif diff --git a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp index 1b2fe61e87c..ec25a8f9f60 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -248,11 +248,9 @@ public: { for (uint8 i = 0; i < 3; ++i) { - Unit* unit = NULL; if (TargetGUID[i]) { - unit = Unit::GetUnit(*me, TargetGUID[i]); - if (unit) + if (Unit* unit = Unit::GetUnit(*me, TargetGUID[i])) unit->CastSpell(unit, SPELL_ATTRACTION, true); TargetGUID[i] = 0; } diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index 710f5c82fab..673d4bcc96f 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -299,12 +299,11 @@ public: for (uint8 i = 0; i < 4; ++i) { - Unit* Member = NULL; if (Council[i]) { - Member = Unit::GetUnit(*me, Council[i]); - if (Member && Member->isAlive()) - CAST_CRE(Member)->AI()->AttackStart(target); + Unit* member = Unit::GetUnit(*me, Council[i]); + if (member && member->isAlive()) + CAST_CRE(member)->AI()->AttackStart(target); } } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h index e34e86c16a7..ed8c5351493 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/blood_furnace.h @@ -39,5 +39,9 @@ #define DATA_PRISON_CELL6 18 #define DATA_PRISON_CELL7 19 #define DATA_PRISON_CELL8 20 +#define DATA_BROGGOK_LEVER 21 +#define ACTION_ACTIVATE_BROGGOK 22 +#define ACTION_RESET_BROGGOK 23 +#define ACTION_PREPARE_BROGGOK 24 #endif diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp index 3a2e0834fed..84d292e1fe4 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp @@ -47,9 +47,9 @@ class boss_broggok : public CreatureScript { } - struct boss_broggokAI : public ScriptedAI + struct boss_broggokAI : public BossAI { - boss_broggokAI(Creature* creature) : ScriptedAI(creature) + boss_broggokAI(Creature* creature) : BossAI(creature, DATA_BROGGOK) { instance = creature->GetInstanceScript(); } @@ -59,27 +59,21 @@ class boss_broggok : public CreatureScript uint32 AcidSpray_Timer; uint32 PoisonSpawn_Timer; uint32 PoisonBolt_Timer; + bool canAttack; void Reset() { + _Reset(); AcidSpray_Timer = 10000; PoisonSpawn_Timer = 5000; PoisonBolt_Timer = 7000; - if (instance) - { - instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED); - instance->HandleGameObject(instance->GetData64(DATA_DOOR4), true); - } + DoAction(ACTION_RESET_BROGGOK); + instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) { DoScriptText(SAY_AGGRO, me); - if (instance) - { - instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS); - instance->HandleGameObject(instance->GetData64(DATA_DOOR4), false); - } } void JustSummoned(Creature* summoned) @@ -94,7 +88,8 @@ class boss_broggok : public CreatureScript { if (!UpdateVictim()) return; - + if (!canAttack) + return; if (AcidSpray_Timer <= diff) { DoCast(me->getVictim(), SPELL_SLIME_SPRAY); @@ -132,6 +127,26 @@ class boss_broggok : public CreatureScript } } + void DoAction(int32 const action) + { + switch (action) + { + case ACTION_PREPARE_BROGGOK: + me->SetInCombatWithZone(); + break; + case ACTION_ACTIVATE_BROGGOK: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + canAttack = true; + break; + case ACTION_RESET_BROGGOK: + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + canAttack = false; + break; + } + } + }; CreatureAI* GetAI(Creature* creature) const @@ -140,7 +155,27 @@ class boss_broggok : public CreatureScript } }; +class go_broggok_lever : public GameObjectScript +{ + public: + go_broggok_lever() : GameObjectScript("go_broggok_lever") {} + + bool OnGossipHello(Player* player, GameObject* go) + { + if (InstanceScript* instance = go->GetInstanceScript()) + if (instance->GetData(TYPE_BROGGOK_EVENT) != DONE && instance->GetData(TYPE_BROGGOK_EVENT) != IN_PROGRESS) + { + instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS); + if (Creature* broggok = Creature::GetCreature(*go, instance->GetData64(DATA_BROGGOK))) + broggok->AI()->DoAction(ACTION_PREPARE_BROGGOK); + } + go->UseDoorOrButton(); + return false; + } +}; + void AddSC_boss_broggok() { new boss_broggok(); + new go_broggok_lever(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp index a0bcc396fdb..3c07862e0f6 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp @@ -57,7 +57,9 @@ enum eKelidan SPELL_VORTEX = 37370, ENTRY_KELIDAN = 17377, - ENTRY_CHANNELER = 17653 + ENTRY_CHANNELER = 17653, + + ACTION_ACTIVATE_ADDS = 92 }; const float ShadowmoonChannelers[5][4]= @@ -107,6 +109,8 @@ class boss_kelidan_the_breaker : public CreatureScript Firenova = false; addYell = false; SummonChannelers(); + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); if (instance) instance->SetData(TYPE_KELIDAN_THE_BREAKER_EVENT, NOT_STARTED); } @@ -152,7 +156,8 @@ class boss_kelidan_the_breaker : public CreatureScript if (channeler && channeler->isAlive()) return; } - + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); if (killer) me->AI()->AttackStart(killer); } @@ -269,7 +274,6 @@ class boss_kelidan_the_breaker : public CreatureScript DoMeleeAttackIfReady(); } - }; CreatureAI* GetAI(Creature* creature) const @@ -295,16 +299,11 @@ class mob_shadowmoon_channeler : public CreatureScript { public: - mob_shadowmoon_channeler() - : CreatureScript("mob_shadowmoon_channeler") - { - } + mob_shadowmoon_channeler() : CreatureScript("mob_shadowmoon_channeler") {} struct mob_shadowmoon_channelerAI : public ScriptedAI { - mob_shadowmoon_channelerAI(Creature* creature) : ScriptedAI(creature) - { - } + mob_shadowmoon_channelerAI(Creature* creature) : ScriptedAI(creature){} uint32 ShadowBolt_Timer; uint32 MarkOfShadow_Timer; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp index 4c434feb4ec..893f97fe711 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp @@ -26,6 +26,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "InstanceScript.h" #include "blood_furnace.h" +#include "CreatureAI.h" #define ENTRY_SEWER1 181823 #define ENTRY_SEWER2 181766 @@ -35,9 +36,7 @@ class instance_blood_furnace : public InstanceMapScript { public: instance_blood_furnace() - : InstanceMapScript("instance_blood_furnace", 542) - { - } + : InstanceMapScript("instance_blood_furnace", 542) {} struct instance_blood_furnace_InstanceMapScript : public InstanceScript { @@ -63,6 +62,18 @@ class instance_blood_furnace : public InstanceMapScript uint64 PrisonCell7GUID; uint64 PrisonCell8GUID; + std::set<uint64> PrisonersCell5; + std::set<uint64> PrisonersCell6; + std::set<uint64> PrisonersCell7; + std::set<uint64> PrisonersCell8; + + uint8 PrisonerCounter5; + uint8 PrisonerCounter6; + uint8 PrisonerCounter7; + uint8 PrisonerCounter8; + + uint64 BroggokLeverGUID; + uint32 m_auiEncounter[MAX_ENCOUNTER]; std::string str_data; @@ -89,24 +100,45 @@ class instance_blood_furnace : public InstanceMapScript PrisonCell6GUID = 0; PrisonCell7GUID = 0; PrisonCell8GUID = 0; + + PrisonersCell5.clear(); + PrisonersCell6.clear(); + PrisonersCell7.clear(); + PrisonersCell8.clear(); + + PrisonerCounter5 = 0; + PrisonerCounter6 = 0; + PrisonerCounter7 = 0; + PrisonerCounter8 = 0; + + BroggokLeverGUID = 0; } void OnCreatureCreate(Creature* creature) { switch (creature->GetEntry()) { - case 17381: - The_MakerGUID = creature->GetGUID(); - break; - case 17380: - BroggokGUID = creature->GetGUID(); - break; - case 17377: - Kelidan_The_BreakerGUID = creature->GetGUID(); - break; + case 17381: + The_MakerGUID = creature->GetGUID(); + break; + case 17380: + BroggokGUID = creature->GetGUID(); + break; + case 17377: + Kelidan_The_BreakerGUID = creature->GetGUID(); + break; + case 17398: + StorePrisoner(creature); + break; } } + void OnCreatureDeath(Creature* unit) + { + if (unit && unit->GetTypeId() == TYPEID_UNIT && unit->GetEntry() == 17398) + PrisonerDied(unit->GetGUID()); + } + void OnGameObjectCreate(GameObject* go) { if (go->GetEntry() == 181766) //Final exit door @@ -138,6 +170,9 @@ class instance_blood_furnace : public InstanceMapScript PrisonCell7GUID = go->GetGUID(); if (go->GetEntry() == 181817) //Broggok prison cell back left PrisonCell8GUID = go->GetGUID(); + + if (go->GetEntry() == 181982) + BroggokLeverGUID = go->GetGUID(); //Broggok lever } uint64 GetData64(uint32 data) @@ -161,18 +196,25 @@ class instance_blood_furnace : public InstanceMapScript case DATA_PRISON_CELL6: return PrisonCell6GUID; case DATA_PRISON_CELL7: return PrisonCell7GUID; case DATA_PRISON_CELL8: return PrisonCell8GUID; + case DATA_BROGGOK_LEVER: return BroggokLeverGUID; } - return 0; } - void SetData(uint32 /*type*/, uint32 data) + void SetData(uint32 type, uint32 data) { - switch (data) + switch (type) { - case TYPE_THE_MAKER_EVENT: m_auiEncounter[0] = data; break; - case TYPE_BROGGOK_EVENT: m_auiEncounter[1] = data; break; - case TYPE_KELIDAN_THE_BREAKER_EVENT: m_auiEncounter[2] = data; break; + case TYPE_THE_MAKER_EVENT: + m_auiEncounter[0] = data; + break; + case TYPE_BROGGOK_EVENT: + m_auiEncounter[1] = data; + UpdateBroggokEvent(data); + break; + case TYPE_KELIDAN_THE_BREAKER_EVENT: + m_auiEncounter[2] = data; + break; } if (data == DONE) @@ -189,15 +231,14 @@ class instance_blood_furnace : public InstanceMapScript } } - uint32 GetData(uint32 data) + uint32 GetData(uint32 type) { - switch (data) + switch (type) { case TYPE_THE_MAKER_EVENT: return m_auiEncounter[0]; case TYPE_BROGGOK_EVENT: return m_auiEncounter[1]; case TYPE_KELIDAN_THE_BREAKER_EVENT: return m_auiEncounter[2]; } - return 0; } @@ -225,6 +266,147 @@ class instance_blood_furnace : public InstanceMapScript OUT_LOAD_INST_DATA_COMPLETE; } + + void UpdateBroggokEvent(uint32 data) + { + switch (data) + { + case IN_PROGRESS: + ActivateCell(DATA_PRISON_CELL5); + HandleGameObject(Door4GUID, false); + break; + case NOT_STARTED: + ResetPrisons(); + HandleGameObject(Door5GUID, false); + HandleGameObject(Door4GUID, true); + if (GameObject* lever = instance->GetGameObject(BroggokLeverGUID)) + lever->Respawn(); + break; + } + } + + void ResetPrisons() + { + PrisonerCounter5 = PrisonersCell5.size(); + ResetPrisoners(PrisonersCell5); + HandleGameObject(PrisonCell5GUID, false); + + PrisonerCounter6 = PrisonersCell6.size(); + ResetPrisoners(PrisonersCell6); + HandleGameObject(PrisonCell6GUID, false); + + PrisonerCounter7 = PrisonersCell7.size(); + ResetPrisoners(PrisonersCell7); + HandleGameObject(PrisonCell7GUID, false); + + PrisonerCounter8 = PrisonersCell8.size(); + ResetPrisoners(PrisonersCell8); + HandleGameObject(PrisonCell8GUID, false); + } + + void ResetPrisoners(std::set<uint64> prisoners) + { + for (std::set<uint64>::iterator i = prisoners.begin(); i != prisoners.end(); ++i) + if (Creature* prisoner = instance->GetCreature(*i)) + ResetPrisoner(prisoner); + } + + void ResetPrisoner(Creature* prisoner) + { + if (!prisoner->isAlive()) + prisoner->Respawn(true); + prisoner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + } + + void StorePrisoner(Creature* creature) + { + float posX = creature->GetPositionX(); + float posY = creature->GetPositionY(); + + if (posX >= 405.0f && posX <= 423.0f) + { + if (posY >= 106.0f && posY <= 123.0f) + { + PrisonersCell5.insert(creature->GetGUID()); + ++PrisonerCounter5; + } + else if (posY >= 76.0f && posY <= 91.0f) + { + PrisonersCell6.insert(creature->GetGUID()); + ++PrisonerCounter6; + } + else return; + } + else if (posX >= 490.0f && posX <= 506.0f) + { + if (posY >= 106.0f && posY <= 123.0f) + { + PrisonersCell7.insert(creature->GetGUID()); + ++PrisonerCounter7; + } + else if (posY >= 76.0f && posY <= 91.0f) + { + PrisonersCell8.insert(creature->GetGUID()); + ++PrisonerCounter8; + } + else + return; + } + else + return; + + ResetPrisoner(creature); + } + + void PrisonerDied(uint64 guid) + { + if (PrisonersCell5.find(guid) != PrisonersCell5.end() && --PrisonerCounter5 <= 0) + ActivateCell(DATA_PRISON_CELL6); + else if (PrisonersCell6.find(guid) != PrisonersCell6.end() && --PrisonerCounter6 <= 0) + ActivateCell(DATA_PRISON_CELL7); + else if (PrisonersCell7.find(guid) != PrisonersCell7.end() && --PrisonerCounter7 <= 0) + ActivateCell(DATA_PRISON_CELL8); + else if (PrisonersCell8.find(guid) != PrisonersCell8.end() && --PrisonerCounter8 <= 0) + ActivateCell(DATA_DOOR5); + } + + void ActivateCell(uint8 id) + { + switch (id) + { + case DATA_PRISON_CELL5: + HandleGameObject(PrisonCell5GUID,true); + ActivatePrisoners(PrisonersCell5); + break; + case DATA_PRISON_CELL6: + HandleGameObject(PrisonCell6GUID,true); + ActivatePrisoners(PrisonersCell6); + break; + case DATA_PRISON_CELL7: + HandleGameObject(PrisonCell7GUID,true); + ActivatePrisoners(PrisonersCell7); + break; + case DATA_PRISON_CELL8: + HandleGameObject(PrisonCell8GUID,true); + ActivatePrisoners(PrisonersCell8); + break; + case DATA_DOOR5: + HandleGameObject(Door5GUID,true); + if (Creature* broggok = instance->GetCreature(BroggokGUID)) + broggok->AI()->DoAction(ACTION_ACTIVATE_BROGGOK); + break; + } + } + + void ActivatePrisoners(std::set<uint64> prisoners) + { + for (std::set<uint64>::iterator i = prisoners.begin(); i != prisoners.end(); ++i) + if (Creature* prisoner = instance->GetCreature(*i)) + { + prisoner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE); + prisoner->SetInCombatWithZone(); + } + } }; InstanceScript* GetInstanceScript(InstanceMap* map) const diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp index c79bf74aab6..1656f7221ed 100644 --- a/src/server/scripts/Outland/shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/shadowmoon_valley.cpp @@ -45,6 +45,7 @@ EndContentData */ #include "ScriptedGossip.h" #include "ScriptedEscortAI.h" #include "Group.h" +#include "SpellScript.h" /*##### # mob_mature_netherwing_drake @@ -1868,9 +1869,41 @@ public: }; }; -/*##### -# -######*/ +enum ZuluhedChains +{ + QUEST_ZULUHED = 10866, + NPC_KARYNAKU = 22112, +}; + +class spell_unlocking_zuluheds_chains : public SpellScriptLoader +{ + public: + spell_unlocking_zuluheds_chains() : SpellScriptLoader("spell_unlocking_zuluheds_chains") { } + + class spell_unlocking_zuluheds_chains_SpellScript : public SpellScript + { + PrepareSpellScript(spell_unlocking_zuluheds_chains_SpellScript); + + void HandleOnCast() + { + // FIXME: Hackish solution, a better way to reward killcredit should be found + if (Unit* caster = GetCaster()) + if(Player* player = caster->ToPlayer()) + if (player->GetQuestStatus(QUEST_ZULUHED) == QUEST_STATUS_INCOMPLETE) + player->CastedCreatureOrGO(NPC_KARYNAKU, MAKE_NEW_GUID(0, NPC_KARYNAKU, HIGHGUID_UNIT), 0); + } + + void Register() + { + OnCast += SpellCastFn(spell_unlocking_zuluheds_chains_SpellScript::HandleOnCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_unlocking_zuluheds_chains_SpellScript(); + } +}; void AddSC_shadowmoon_valley() { @@ -1889,4 +1922,5 @@ void AddSC_shadowmoon_valley() new mob_illidari_spawn(); new mob_torloth_the_magnificent(); new npc_enraged_spirit(); + new spell_unlocking_zuluheds_chains(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index a35d243593e..2aed2517975 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -950,14 +950,14 @@ class spell_generic_clone : public SpellScriptLoader enum CloneWeaponSpells { - SPELL_COPY_WEAPON = 41055, - SPELL_COPY_WEAPON_2 = 63416, - SPELL_COPY_WEAPON_3 = 69891, + SPELL_COPY_WEAPON_AURA = 41054, + SPELL_COPY_WEAPON_2_AURA = 63418, + SPELL_COPY_WEAPON_3_AURA = 69893, - SPELL_COPY_OFFHAND = 45206, - SPELL_COPY_OFFHAND_2 = 69892, + SPELL_COPY_OFFHAND_AURA = 45205, + SPELL_COPY_OFFHAND_2_AURA = 69896, - SPELL_COPY_RANGED = 57593 + SPELL_COPY_RANGED_AURA = 57594 }; class spell_generic_clone_weapon : public SpellScriptLoader @@ -969,80 +969,147 @@ class spell_generic_clone_weapon : public SpellScriptLoader { PrepareSpellScript(spell_generic_clone_weapon_SpellScript); - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON) || !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_2) || !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_3) || !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND) - || !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_2) || !sSpellMgr->GetSpellInfo(SPELL_COPY_RANGED)) - return false; - return true; - } - void HandleScriptEffect(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) { uint32 spellId = uint32(GetSpellInfo()->Effects[EFFECT_0].CalcValue()); - target->CastSpell(caster, spellId, true); + caster->CastSpell(target, spellId, true); + } + } - if (target->GetTypeId() == TYPEID_PLAYER) - return; + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_generic_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_generic_clone_weapon_SpellScript(); + } +}; + +class spell_gen_clone_weapon_aura : public SpellScriptLoader +{ + public: + spell_gen_clone_weapon_aura() : SpellScriptLoader("spell_gen_clone_weapon_aura") { } + + class spell_gen_clone_weapon_auraScript : public AuraScript + { + PrepareAuraScript(spell_gen_clone_weapon_auraScript); + + uint32 prevItem; + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_AURA) || !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_2_AURA) || !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_3_AURA) + || !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_AURA) || !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_2_AURA) || !sSpellMgr->GetSpellInfo(SPELL_COPY_RANGED_AURA)) + return false; + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + Unit* target = GetTarget(); + + if (!caster) + return; - switch (GetSpellInfo()->Id) + switch (GetSpellInfo()->Id) + { + case SPELL_COPY_WEAPON_AURA: + case SPELL_COPY_WEAPON_2_AURA: + case SPELL_COPY_WEAPON_3_AURA: { - case SPELL_COPY_WEAPON: - case SPELL_COPY_WEAPON_2: - case SPELL_COPY_WEAPON_3: + prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID); + + if (Player* player = caster->ToPlayer()) { - if (Player* player = caster->ToPlayer()) - { - if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry()); - } - else - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID)); - break; + if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry()); } - case SPELL_COPY_OFFHAND: - case SPELL_COPY_OFFHAND_2: + else + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID)); + break; + } + case SPELL_COPY_OFFHAND_AURA: + case SPELL_COPY_OFFHAND_2_AURA: + { + prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 1; + + if (Player* player = caster->ToPlayer()) { - if (Player* player = caster->ToPlayer()) - { - if (Item* offItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, offItem->GetEntry()); - } - else - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1)); - break; + if (Item* offItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, offItem->GetEntry()); } - case SPELL_COPY_RANGED: + else + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1)); + break; + } + case SPELL_COPY_RANGED_AURA: + { + prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 2; + + if (Player* player = caster->ToPlayer()) { - if (Player* player = caster->ToPlayer()) - { - if (Item* rangedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED)) - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, rangedItem->GetEntry()); - } - else - target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2)); - break; + if (Item* rangedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED)) + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, rangedItem->GetEntry()); } - default: - break; + else + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2)); + break; + } + default: + break; + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + + switch (GetSpellInfo()->Id) + { + case SPELL_COPY_WEAPON_AURA: + case SPELL_COPY_WEAPON_2_AURA: + case SPELL_COPY_WEAPON_3_AURA: + { + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, prevItem); + break; + } + case SPELL_COPY_OFFHAND_AURA: + case SPELL_COPY_OFFHAND_2_AURA: + { + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, prevItem); + break; + } + case SPELL_COPY_RANGED_AURA: + { + target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, prevItem); + break; } + default: + break; } } void Register() { - OnEffectHitTarget += SpellEffectFn(spell_generic_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectApply += AuraEffectApplyFn(spell_gen_clone_weapon_auraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); } + }; - SpellScript* GetSpellScript() const + AuraScript* GetAuraScript() const { - return new spell_generic_clone_weapon_SpellScript(); + return new spell_gen_clone_weapon_auraScript(); } }; @@ -1844,16 +1911,18 @@ class spell_gen_break_shield: public SpellScriptLoader Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - Aura* aura = itr->second->GetBase(); - SpellInfo const* auraInfo = aura->GetSpellInfo(); - if (aura && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + if (Aura* aura = itr->second->GetBase()) { - aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); - // Remove dummys from rider (Necessary for updating visual shields) - if (Unit* rider = target->GetCharmer()) - if (Aura* defend = rider->GetAura(aura->GetId())) - defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); - break; + SpellInfo const* auraInfo = aura->GetSpellInfo(); + if (auraInfo && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + { + aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + // Remove dummys from rider (Necessary for updating visual shields) + if (Unit* rider = target->GetCharmer()) + if (Aura* defend = rider->GetAura(aura->GetId())) + defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + break; + } } } break; @@ -1972,16 +2041,18 @@ class spell_gen_mounted_charge: public SpellScriptLoader Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - Aura* aura = itr->second->GetBase(); - SpellInfo const* auraInfo = aura->GetSpellInfo(); - if (aura && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + if (Aura* aura = itr->second->GetBase()) { - aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); - // Remove dummys from rider (Necessary for updating visual shields) - if (Unit* rider = target->GetCharmer()) - if (Aura* defend = rider->GetAura(aura->GetId())) - defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); - break; + SpellInfo const* auraInfo = aura->GetSpellInfo(); + if (auraInfo && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + { + aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + // Remove dummys from rider (Necessary for updating visual shields) + if (Unit* rider = target->GetCharmer()) + if (Aura* defend = rider->GetAura(aura->GetId())) + defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + break; + } } } break; @@ -3077,6 +3148,96 @@ class spell_gen_mount : public SpellScriptLoader uint32 _mount310; }; +enum FoamSword +{ + ITEM_FOAM_SWORD_GREEN = 45061, + ITEM_FOAM_SWORD_PINK = 45176, + ITEM_FOAM_SWORD_BLUE = 45177, + ITEM_FOAM_SWORD_RED = 45178, + ITEM_FOAM_SWORD_YELLOW = 45179, + + SPELL_BONKED = 62991, + SPELL_FOAM_SWORD_DEFEAT = 62994, + SPELL_ON_GUARD = 62972, +}; + +class spell_gen_upper_deck_create_foam_sword : public SpellScriptLoader +{ + public: + spell_gen_upper_deck_create_foam_sword() : SpellScriptLoader("spell_gen_upper_deck_create_foam_sword") { } + + class spell_gen_upper_deck_create_foam_sword_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_upper_deck_create_foam_sword_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + if (Player* player = GetHitPlayer()) + { + static uint32 const itemId[5] = { ITEM_FOAM_SWORD_GREEN, ITEM_FOAM_SWORD_PINK, ITEM_FOAM_SWORD_BLUE, ITEM_FOAM_SWORD_RED, ITEM_FOAM_SWORD_YELLOW }; + // player can only have one of these items + for (uint8 i = 0; i < 5; ++i) + { + if (player->HasItemCount(itemId[i], 1, true)) + return; + } + + CreateItem(effIndex, itemId[urand(0, 4)]); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_upper_deck_create_foam_sword_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_upper_deck_create_foam_sword_SpellScript(); + } +}; + +class spell_gen_bonked : public SpellScriptLoader +{ + public: + spell_gen_bonked() : SpellScriptLoader("spell_gen_bonked") { } + + class spell_gen_bonked_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_bonked_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* target = GetHitPlayer()) + { + Aura const* aura = GetHitAura(); + if (!(aura && aura->GetStackAmount() == 3)) + return; + + target->CastSpell(target, SPELL_FOAM_SWORD_DEFEAT, true); + target->RemoveAurasDueToSpell(SPELL_BONKED); + + if (Aura const* aura = target->GetAura(SPELL_ON_GUARD)) + { + if (Item* item = target->GetItemByGuid(aura->GetCastItemGUID())) + target->DestroyItemCount(item->GetEntry(), 1, true); + } + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_bonked_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_bonked_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3100,6 +3261,7 @@ void AddSC_generic_spell_scripts() new spell_gen_profession_research(); new spell_generic_clone(); new spell_generic_clone_weapon(); + new spell_gen_clone_weapon_aura(); new spell_gen_seaforium_blast(); new spell_gen_turkey_marker(); new spell_gen_lifeblood(); @@ -3149,4 +3311,6 @@ void AddSC_generic_spell_scripts() new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280); new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310); new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310); + new spell_gen_upper_deck_create_foam_sword(); + new spell_gen_bonked(); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 3d8ca3e729b..be5ec311c39 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -39,6 +39,9 @@ enum PriestSpells PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021, PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874, PRIEST_SHADOW_WORD_DEATH = 32409, + PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH = 107903, + PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH = 107904, + PRIEST_GLYPH_OF_SHADOW = 107906, }; // Guardian Spirit @@ -449,6 +452,46 @@ class spell_pri_shadow_word_death : public SpellScriptLoader } }; +class spell_pri_shadowform : public SpellScriptLoader +{ + public: + spell_pri_shadowform() : SpellScriptLoader("spell_pri_shadowform") { } + + class spell_pri_shadowform_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_shadowform_AuraScript); + + bool Validate(SpellInfo const* /*entry*/) + { + if (!sSpellMgr->GetSpellInfo(PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH) || + !sSpellMgr->GetSpellInfo(PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH)) + return false; + return true; + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), GetTarget()->HasAura(PRIEST_GLYPH_OF_SHADOW) ? PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH, true); + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(GetTarget()->HasAura(PRIEST_GLYPH_OF_SHADOW) ? PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH); + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_pri_shadowform_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + AfterEffectRemove += AuraEffectRemoveFn(spell_pri_shadowform_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pri_shadowform_AuraScript(); + } +}; + void AddSC_priest_spell_scripts() { new spell_pri_guardian_spirit(); @@ -461,4 +504,5 @@ void AddSC_priest_spell_scripts() new spell_pri_vampiric_touch(); new spell_priest_renew(); new spell_pri_shadow_word_death(); + new spell_pri_shadowform(); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 5648c510413..cbf45910495 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1245,6 +1245,75 @@ class spell_q12735_song_of_cleansing : public SpellScriptLoader } }; +enum DefendingWyrmrestTemple +{ + SPELL_SUMMON_WYRMREST_DEFENDER = 49207 +}; + +class spell_q12372_cast_from_gossip_trigger : public SpellScriptLoader +{ + public: + spell_q12372_cast_from_gossip_trigger() : SpellScriptLoader("spell_q12372_cast_from_gossip_trigger") { } + + class spell_q12372_cast_from_gossip_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12372_cast_from_gossip_trigger_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_WYRMREST_DEFENDER, true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12372_cast_from_gossip_trigger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12372_cast_from_gossip_trigger_SpellScript(); + } +}; + +// http://www.wowhead.com/quest=12372 Defending Wyrmrest Temple +// 49370 - Wyrmrest Defender: Destabilize Azure Dragonshrine Effect +enum Quest12372Data +{ + NPC_WYRMREST_TEMPLE_CREDIT = 27698, +}; + +class spell_q12372_destabilize_azure_dragonshrine_dummy : public SpellScriptLoader +{ + public: + spell_q12372_destabilize_azure_dragonshrine_dummy() : SpellScriptLoader("spell_q12372_destabilize_azure_dragonshrine_dummy") { } + + class spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (GetHitCreature()) + if (Unit* caster = GetOriginalCaster()) + if (Vehicle* vehicle = caster->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (Player* player = passenger->ToPlayer()) + player->KilledMonsterCredit(NPC_WYRMREST_TEMPLE_CREDIT, 0); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12372_destabilize_azure_dragonshrine_dummy_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -1274,4 +1343,6 @@ void AddSC_quest_spell_scripts() new spell_q12277_wintergarde_mine_explosion(); new spell_q12066_bunny_kill_credit(); new spell_q12735_song_of_cleansing(); + new spell_q12372_cast_from_gossip_trigger(); + new spell_q12372_destabilize_azure_dragonshrine_dummy(); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index c863c2363af..1c6e6e11f04 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -35,6 +35,8 @@ enum ShamanSpells SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1 = 8349, SHAMAN_SPELL_SATED = 57724, SHAMAN_SPELL_EXHAUSTION = 57723, + HUNTER_SPELL_INSANITY = 95809, + MAGE_SPELL_TEMPORAL_DISPLACEMENT = 80354, SHAMAN_SPELL_STORM_EARTH_AND_FIRE = 51483, EARTHBIND_TOTEM_SPELL_EARTHGRAB = 64695, @@ -319,6 +321,8 @@ class spell_sha_bloodlust : public SpellScriptLoader void RemoveInvalidTargets(std::list<WorldObject*>& targets) { targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED)); + targets.remove_if(Trinity::UnitAuraCheck(true, HUNTER_SPELL_INSANITY)); + targets.remove_if(Trinity::UnitAuraCheck(true, MAGE_SPELL_TEMPORAL_DISPLACEMENT)); } void ApplyDebuff() @@ -361,6 +365,8 @@ class spell_sha_heroism : public SpellScriptLoader void RemoveInvalidTargets(std::list<WorldObject*>& targets) { targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION)); + targets.remove_if(Trinity::UnitAuraCheck(true, HUNTER_SPELL_INSANITY)); + targets.remove_if(Trinity::UnitAuraCheck(true, MAGE_SPELL_TEMPORAL_DISPLACEMENT)); } void ApplyDebuff() diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp index 60572ee3e6a..a6f4f7f64f9 100755 --- a/src/server/scripts/World/achievement_scripts.cpp +++ b/src/server/scripts/World/achievement_scripts.cpp @@ -278,6 +278,9 @@ class achievement_tilted : public AchievementCriteriaScript bool OnCheck(Player* player, Unit* /*target*/) { + if (!player) + return false; + bool checkArea = player->GetAreaId() == AREA_ARGENT_TOURNAMENT_FIELDS || player->GetAreaId() == AREA_RING_OF_ASPIRANTS || player->GetAreaId() == AREA_RING_OF_ARGENT_VALIANTS || @@ -285,7 +288,7 @@ class achievement_tilted : public AchievementCriteriaScript player->GetAreaId() == AREA_RING_OF_HORDE_VALIANTS || player->GetAreaId() == AREA_RING_OF_CHAMPIONS; - return player && checkArea && player->duel && player->duel->isMounted; + return checkArea && player->duel && player->duel->isMounted; } }; diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp index 364ee76ec75..146b2c37ad3 100755 --- a/src/server/shared/Cryptography/BigNumber.cpp +++ b/src/server/shared/Cryptography/BigNumber.cpp @@ -75,7 +75,7 @@ void BigNumber::SetRand(int numbits) BN_rand(_bn, numbits, 0, 1); } -BigNumber BigNumber::operator=(const BigNumber &bn) +BigNumber& BigNumber::operator=(const BigNumber &bn) { if (this == &bn) return *this; diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h index 6646245a6a0..a27d74fb5c7 100755 --- a/src/server/shared/Cryptography/BigNumber.h +++ b/src/server/shared/Cryptography/BigNumber.h @@ -39,7 +39,7 @@ class BigNumber void SetRand(int numbits); - BigNumber operator=(const BigNumber &bn); + BigNumber& operator=(const BigNumber &bn); BigNumber operator+=(const BigNumber &bn); BigNumber operator+(const BigNumber &bn) diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/server/shared/DataStores/DBCFileLoader.cpp index f909c8566bb..85b61c4f143 100755 --- a/src/server/shared/DataStores/DBCFileLoader.cpp +++ b/src/server/shared/DataStores/DBCFileLoader.cpp @@ -23,10 +23,8 @@ #include "DBCFileLoader.h" #include "Errors.h" -DBCFileLoader::DBCFileLoader() +DBCFileLoader::DBCFileLoader() : stringTable(NULL), data(NULL), fieldsOffset(NULL) { - data = NULL; - fieldsOffset = NULL; } bool DBCFileLoader::Load(const char* filename, const char* fmt) diff --git a/src/server/shared/Database/AdhocStatement.cpp b/src/server/shared/Database/AdhocStatement.cpp index 9e795ae853a..95dce77e53c 100755 --- a/src/server/shared/Database/AdhocStatement.cpp +++ b/src/server/shared/Database/AdhocStatement.cpp @@ -44,6 +44,7 @@ bool BasicStatementTask::Execute() ResultSet* result = m_conn->Query(m_sql); if (!result || !result->GetRowCount()) { + delete result; m_result.set(QueryResult(NULL)); return false; } diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 9d6fabb9dfa..001e74fc6c6 100755 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -224,7 +224,10 @@ class DatabaseWorkerPool ResultSet* result = conn->Query(sql); conn->Unlock(); if (!result || !result->GetRowCount()) + { + delete result; return QueryResult(NULL); + } result->NextRow(); return QueryResult(result); @@ -275,7 +278,10 @@ class DatabaseWorkerPool delete stmt; if (!ret || !ret->GetRowCount()) + { + delete ret; return PreparedQueryResult(NULL); + } return PreparedQueryResult(ret); } diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index 74cd57f74c0..95c888249cd 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -78,7 +78,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_INS_CREATURE_TRANSPORT, "INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_TRANSPORT_EMOTE, "UPDATE creature_transport SET emote = ? WHERE transport_entry = ? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH); - PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp index 08b554ff696..76dc7206bd7 100755 --- a/src/server/shared/Database/PreparedStatement.cpp +++ b/src/server/shared/Database/PreparedStatement.cpp @@ -445,6 +445,7 @@ bool PreparedStatementTask::Execute() PreparedResultSet* result = m_conn->Query(m_stmt); if (!result || !result->GetRowCount()) { + delete result; m_result.set(PreparedQueryResult(NULL)); return false; } diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/shared/Database/QueryHolder.cpp index 99772c7e323..0908ad410cd 100755 --- a/src/server/shared/Database/QueryHolder.cpp +++ b/src/server/shared/Database/QueryHolder.cpp @@ -116,6 +116,12 @@ PreparedQueryResult SQLQueryHolder::GetPreparedResult(size_t index) void SQLQueryHolder::SetResult(size_t index, ResultSet* result) { + if (result && !result->GetRowCount()) + { + delete result; + result = NULL; + } + /// store the result in the holder if (index < m_queries.size()) m_queries[index].second.qresult = result; @@ -123,6 +129,12 @@ void SQLQueryHolder::SetResult(size_t index, ResultSet* result) void SQLQueryHolder::SetPreparedResult(size_t index, PreparedResultSet* result) { + if (result && !result->GetRowCount()) + { + delete result; + result = NULL; + } + /// store the result in the holder if (index < m_queries.size()) m_queries[index].second.presult = result; diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 3a24190d8fa..88259831095 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -103,7 +103,7 @@ void Log::CreateAppenderFromConfig(const char* name) LogLevel level = LogLevel(atoi(*iter)); if (level > LOG_LEVEL_FATAL) { - fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %u for appender %s\n", level, name); + fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name); return; } @@ -158,7 +158,7 @@ void Log::CreateAppenderFromConfig(const char* name) break; } default: - fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %u for appender %s\n", type, name); + fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name); break; } } @@ -260,14 +260,9 @@ void Log::ReadLoggersFromConfig() } while (ss); - LoggerMap::const_iterator it = loggers.begin(); - - while (it != loggers.end() && it->first) - ++it; - // root logger must exist. Marking as disabled as its not configured - if (it == loggers.end()) - loggers[0].Create("root", LOG_FILTER_GENERAL, LOG_LEVEL_DISABLED); + if (loggers.find(LOG_FILTER_GENERAL) == loggers.end()) + loggers[LOG_FILTER_GENERAL].Create("root", LOG_FILTER_GENERAL, LOG_LEVEL_DISABLED); } void Log::EnableDBAppenders() @@ -349,10 +344,7 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog bool Log::ShouldLog(LogFilterType type, LogLevel level) const { - LoggerMap::const_iterator it = loggers.begin(); - while (it != loggers.end() && it->second.getType() != type) - ++it; - + LoggerMap::const_iterator it = loggers.find(type); if (it != loggers.end()) { LogLevel loggerLevel = it->second.getLogLevel(); @@ -443,19 +435,20 @@ void Log::outFatal(LogFilterType filter, const char * str, ...) va_end(ap); } -void Log::outCharDump(const char* param, const char * str, ...) +void Log::outCharDump(char const* str, uint32 accountId, uint32 guid, char const* name) { if (!str || !ShouldLog(LOG_FILTER_PLAYER_DUMP, LOG_LEVEL_INFO)) return; - va_list ap; - va_start(ap, str); - char text[MAX_QUERY_LEN]; - vsnprintf(text, MAX_QUERY_LEN, str, ap); - va_end(ap); + std::ostringstream ss; + ss << "== START DUMP == (account: " << accountId << " guid: " << guid << " name: " << name + << ")\n" << str << "\n== END DUMP ==\n"; + + LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, LOG_FILTER_PLAYER_DUMP, ss.str()); + ss.clear(); + ss << guid << '_' << name; - LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, LOG_FILTER_PLAYER_DUMP, text); - msg->param1 = param; + msg->param1 = ss.str(); write(msg); } diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index cd1e9dc80df..7980df0d52a 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -56,7 +56,7 @@ class Log void EnableDBAppenders(); void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4); - void outCharDump(const char* param, const char* str, ...) ATTR_PRINTF(3, 4); + void outCharDump(char const* str, uint32 account_id, uint32 guid, char const* name); static std::string GetTimestampStr(); void SetRealmID(uint32 id); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 0b08b4118d4..e4535378a48 100755 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -189,6 +189,37 @@ class ByteBuffer put(pos, (uint8 *)&value, sizeof(value)); } + /** + * @name PutBits + * @brief Places specified amount of bits of value at specified position in packet. + * To ensure all bits are correctly written, only call this method after + * bit flush has been performed + + * @param pos Position to place the value at, in bits. The entire value must fit in the packet + * It is advised to obtain the position using bitwpos() function. + + * @param value Data to write. + * @param bitCount Number of bits to store the value on. + */ + template <typename T> void PutBits(size_t pos, T value, uint32 bitCount) + { + if (!bitCount) + throw ByteBufferSourceException((pos + bitCount) / 8, size(), 0); + + if (pos + bitCount > size() * 8) + throw ByteBufferPositionException(false, (pos + bitCount) / 8, size(), (bitCount - 1) / 8 + 1); + + for (int32 i = 0; i < bitCount; ++i) + { + size_t wp = (pos + i) / 8; + size_t bit = (pos + i) % 8; + if ((value >> (bitCount - i - 1)) & 1) + _storage[wp] |= 1 << (7 - bit); + else + _storage[wp] &= ~(1 << (7 - bit)); + } + } + ByteBuffer &operator<<(uint8 value) { append<uint8>(value); @@ -382,6 +413,16 @@ class ByteBuffer return _wpos; } + /// Returns position of last written bit + size_t bitwpos() const { return _wpos * 8 + 8 - _bitpos; } + + size_t bitwpos(size_t newPos) + { + _wpos = newPos / 8; + _bitpos = 8 - (newPos % 8); + return _wpos * 8 + 8 - _bitpos; + } + template<typename T> void read_skip() { read_skip(sizeof(T)); } diff --git a/src/server/shared/Utilities/ServiceWin32.cpp b/src/server/shared/Utilities/ServiceWin32.cpp index c6e9d385be3..91a78af1adc 100755 --- a/src/server/shared/Utilities/ServiceWin32.cpp +++ b/src/server/shared/Utilities/ServiceWin32.cpp @@ -52,8 +52,6 @@ typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID); bool WinServiceInstall() { - CSD_T ChangeService_Config2; - HMODULE advapi32; SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); if (serviceControlManager) @@ -79,7 +77,7 @@ bool WinServiceInstall() 0); // no password if (service) { - advapi32 = GetModuleHandle("ADVAPI32.DLL"); + HMODULE advapi32 = GetModuleHandle("ADVAPI32.DLL"); if (!advapi32) { CloseServiceHandle(service); @@ -87,7 +85,7 @@ bool WinServiceInstall() return false; } - ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A"); + CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A"); if (!ChangeService_Config2) { CloseServiceHandle(service); diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index 7bedf9690ca..9917bbb5309 100755 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -217,7 +217,7 @@ uint32 CreatePIDFile(const std::string& filename) pid_t pid = getpid(); #endif - fprintf(pid_file, "%d", pid ); + fprintf(pid_file, "%u", pid ); fclose(pid_file); return (uint32)pid; diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 862ed28f2d3..7e43cf87dfc 100755 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -81,7 +81,7 @@ extern int main(int argc, char **argv) { if (++c >= argc) { - sLog->outError(LOG_FILTER_WORLDSERVER, "Runtime-Error: -c option requires an input argument"); + printf("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } @@ -97,25 +97,25 @@ extern int main(int argc, char **argv) { if (++c >= argc) { - sLog->outError(LOG_FILTER_WORLDSERVER, "Runtime-Error: -s option requires an input argument"); + printf("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if (strcmp(argv[c], "install") == 0) { if (WinServiceInstall()) - sLog->outInfo(LOG_FILTER_WORLDSERVER, "Installing service"); + printf("Installing service"); return 1; } else if (strcmp(argv[c], "uninstall") == 0) { if (WinServiceUninstall()) - sLog->outInfo(LOG_FILTER_WORLDSERVER, "Uninstalling service"); + printf("Uninstalling service"); return 1; } else { - sLog->outError(LOG_FILTER_WORLDSERVER, "Runtime-Error: unsupported option %s", argv[c]); + printf("Runtime-Error: unsupported option %s", argv[c]); usage(argv[0]); return 1; } @@ -131,8 +131,8 @@ extern int main(int argc, char **argv) if (!ConfigMgr::Load(cfg_file)) { - sLog->outError(LOG_FILTER_WORLDSERVER, "Invalid or missing configuration file : %s", cfg_file); - sLog->outError(LOG_FILTER_WORLDSERVER, "Verify that the file exists and has \'[worldserver]' written in the top of the file!"); + printf("Invalid or missing configuration file : %s", cfg_file); + printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!"); return 1; } sLog->outInfo(LOG_FILTER_WORLDSERVER, "Using configuration file %s.", cfg_file); diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h index 285adaaaf4b..51ffb3a91c8 100755 --- a/src/server/worldserver/TCSoap/TCSoap.h +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -51,7 +51,7 @@ class SOAPCommand { public: SOAPCommand(): - pendingCommands(0, USYNC_THREAD, "pendingCommands") + pendingCommands(0, USYNC_THREAD, "pendingCommands"), m_success(false) { } diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index fbd45bec8e1..5a9a1b86866 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -26,6 +26,7 @@ # CONSOLE AND REMOTE ACCESS # CHARACTER DELETE OPTIONS # CUSTOM SERVER OPTIONS +# LOGGING SYSTEM SETTINGS # ################################################################################################### @@ -49,7 +50,7 @@ # # RealmID # Description: ID of the Realm using this config. -# Important: RealmID must match the realmlist inside the realmd database. +# Important: RealmID must match the realmlist inside the auth database. # Default: 1 RealmID = 1 @@ -174,7 +175,7 @@ Compression = 1 # PlayerLimit # Description: Maximum number of players in the world. Excluding Mods, GMs and Admins. # Important: If you want to block players and only allow Mods, GMs or Admins to join the -# server, use the DB field "realmd.realmlist.allowedSecurityLevel". +# server, use the DB field "auth.realmlist.allowedSecurityLevel". # Default: 100 - (Enabled) # 1+ - (Enabled) # 0 - (Disabled, No limit) @@ -392,6 +393,14 @@ CleanCharacterDB = 0 PersistentCharacterCleanFlags = 0 # +# GuildSaveInterval +# Description: Time (in minutes) between guild experience saves +# Default: 15 +# + +GuildSaveInterval = 15 + +# ################################################################################################### ################################################################################################### @@ -2645,7 +2654,7 @@ PlayerDump.DisallowOverwrite = 1 ################################################################################################### # -# Logging system options. +# LOGGING SYSTEM SETTINGS # # Appender config values: Given a appender "name" # Appender.name @@ -2788,7 +2797,7 @@ Appenders=Console Server GM DBErrors Char RA Warden Chat # Logger.Root=0,5,Console Server -Logger.Chat=22,3,Chat +Logger.Chat=22,2,Chat Logger.DBErrors=26,5,Console Server DBErrors Logger.GM=27,3,Console Server GM Logger.RA=28,3,RA @@ -2809,3 +2818,6 @@ Logger.Opcodes=41,6,Console Server # Default: "Root Chat DBErrors GM RA Warden Character Load" Loggers=Root Chat DBErrors GM RA Warden Character Load WorldServer Opcodes + +# +###################################################################################################
\ No newline at end of file diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 448cf2320b2..63132d269b2 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -9,6 +9,7 @@ #include "direct.h" #else #include <sys/stat.h> +#include <unistd.h> #define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND #endif @@ -957,7 +958,7 @@ void ExtractMapsFromMpq(uint32 build) printf("Convert map files\n"); for (uint32 z = 0; z < map_count; ++z) { - printf("Extract %s (%d/%d) \n", map_ids[z].name, z+1, map_count); + printf("Extract %s (%d/%u) \n", map_ids[z].name, z+1, map_count); // Loadup map grid data sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); WDT_file wdt; diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index c53b63ffa5e..d2ad71b8179 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -26,7 +26,7 @@ #define snprintf _snprintf #endif -const char * GetPlainName(const char * FileName) +char const* GetPlainName(char const* FileName) { const char * szTemp; @@ -35,7 +35,7 @@ const char * GetPlainName(const char * FileName) return FileName; } -char * GetPlainName(char * FileName) +char* GetPlainName(char* FileName) { char * szTemp; @@ -44,24 +44,21 @@ char * GetPlainName(char * FileName) return FileName; } -void fixnamen(char *name, size_t len) +void fixnamen(char* name, size_t len) { - for (size_t i=0; i<len-3; i++) + for (size_t i = 0; i < len-3; i++) { - if (i>0 && name[i]>='A' && name[i]<='Z' && isalpha(name[i-1])) - { + if (i > 0 && name[i] >= 'A' && name[i] <= 'Z' && isalpha(name[i-1])) name[i] |= 0x20; - } else if ((i==0 || !isalpha(name[i-1])) && name[i]>='a' && name[i]<='z') - { + else if ((i == 0 || !isalpha(name[i-1])) && name[i]>='a' && name[i]<='z') name[i] &= ~0x20; - } } //extension in lowercase - for(size_t i=len-3; i<len; i++) + for (size_t i = len - 3; i < len; i++) name[i] |= 0x20; } -void fixname2(char *name, size_t len) +void fixname2(char* name, size_t len) { for (size_t i=0; i<len-3; i++) { @@ -70,10 +67,10 @@ void fixname2(char *name, size_t len) } } -char * GetExtension(char * FileName) +char* GetExtension(char* FileName) { - char * szTemp; - if((szTemp = strrchr(FileName, '.')) != NULL) + char* szTemp; + if (szTemp = strrchr(FileName, '.')) return szTemp; return NULL; } @@ -101,7 +98,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) xMap = TempMapNumber.substr(TempMapNumber.find("_")+1,(TempMapNumber.find_last_of("_")-1) - (TempMapNumber.find("_"))); yMap = TempMapNumber.substr(TempMapNumber.find_last_of("_")+1,(TempMapNumber.length()) - (TempMapNumber.find_last_of("_"))); Adtfilename.erase((Adtfilename.length()-xMap.length()-yMap.length()-2), (xMap.length()+yMap.length()+2)); - string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)Adtfilename.c_str()); + //string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)Adtfilename.c_str()); //printf("Processing map %s...\n", AdtMapNumber.c_str()); //printf("MapNumber = %s\n", TempMapNumber.c_str()); //printf("xMap = %s\n", xMap.c_str()); @@ -161,18 +158,17 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) { if (size) { - char *buf = new char[size]; + char* buf = new char[size]; ADT.read(buf, size); - char *p=buf; + char* p=buf; int q = 0; WmoInstansName = new string[size]; while (p<buf+size) { - string path(p); - char* s=GetPlainName(p); - fixnamen(s,strlen(s)); - fixname2(s,strlen(s)); - p=p+strlen(p)+1; + char* s = GetPlainName(p); + fixnamen(s, strlen(s)); + fixname2(s, strlen(s)); + p += strlen(p) + 1; WmoInstansName[q++] = s; } delete[] buf; diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index d98dca9001b..7a03cea23c0 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -28,15 +28,14 @@ extern HANDLE WorldMpq; Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0) { + memset(&header, 0, sizeof(header)); } bool Model::open() { MPQFile f(WorldMpq, filename.c_str()); - ok = !f.isEof(); - - if (!ok) + if (f.isEof()) { f.close(); // Do not show this error on console to avoid confusion, the extractor can continue working even if some models fail to load @@ -54,9 +53,7 @@ bool Model::open() vertices = new Vec3D[header.nBoundingVertices]; f.read(vertices,header.nBoundingVertices*12); for (uint32 i=0; i<header.nBoundingVertices; i++) - { vertices[i] = fixCoordSystem(vertices[i]); - } f.seek(0); f.seekRelative(header.ofsBoundingTriangles); indices = new uint16[header.nBoundingTriangles]; @@ -75,13 +72,13 @@ bool Model::open() bool Model::ConvertToVMAPModel(const char * outfilename) { int N[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; - FILE * output=fopen(outfilename,"wb"); - if(!output) + FILE* output=fopen(outfilename, "wb"); + if (!output) { printf("Can't create the output file '%s'\n",outfilename); return false; } - fwrite(szRawVMAPMagic,8,1,output); + fwrite(szRawVMAPMagic, 8, 1, output); uint32 nVertices = 0; nVertices = header.nBoundingVertices; fwrite(&nVertices, sizeof(int), 1, output); @@ -103,20 +100,18 @@ bool Model::ConvertToVMAPModel(const char * outfilename) wsize = sizeof(uint32) + sizeof(unsigned short) * nIndexes; fwrite(&wsize, sizeof(int), 1, output); fwrite(&nIndexes, sizeof(uint32), 1, output); - if(nIndexes >0) - { + if (nIndexes >0) fwrite(indices, sizeof(unsigned short), nIndexes, output); - } - fwrite("VERT",4, 1, output); + + fwrite("VERT", 4, 1, output); wsize = sizeof(int) + sizeof(float) * 3 * nVertices; fwrite(&wsize, sizeof(int), 1, output); fwrite(&nVertices, sizeof(int), 1, output); - if(nVertices >0) + if (nVertices >0) { for(uint32 vpos=0; vpos <nVertices; ++vpos) - { std::swap(vertices[vpos].y, vertices[vpos].z); - } + fwrite(vertices, sizeof(float)*3, nVertices, output); } @@ -136,24 +131,24 @@ Vec3D fixCoordSystem2(Vec3D v) return Vec3D(v.x, v.z, v.y); } -ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) +ModelInstance::ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) + : model(NULL), d1(0), w(0.0f) { float ff[3]; f.read(&id, 4); - f.read(ff,12); - pos = fixCoords(Vec3D(ff[0],ff[1],ff[2])); - f.read(ff,12); - rot = Vec3D(ff[0],ff[1],ff[2]); - f.read(&scale,4); + f.read(ff, 12); + pos = fixCoords(Vec3D(ff[0], ff[1], ff[2])); + f.read(ff, 12); + rot = Vec3D(ff[0], ff[1], ff[2]); + f.read(&scale, 4); // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float? sc = scale / 1024.0f; char tempname[512]; sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName); - FILE *input; - input = fopen(tempname, "r+b"); + FILE* input = fopen(tempname, "r+b"); - if(!input) + if (!input) { //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname); return; @@ -169,7 +164,9 @@ ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName, uint32 mapID, uint16 adtId = 0;// not used for models uint32 flags = MOD_M2; - if(tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN; + if (tileX == 65 && tileY == 65) + flags |= MOD_WORLDSPAWN; + //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name fwrite(&mapID, sizeof(uint32), 1, pDirfile); fwrite(&tileX, sizeof(uint32), 1, pDirfile); diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h index 9000d7e4822..acd31d58ec9 100644 --- a/src/tools/vmap4_extractor/model.h +++ b/src/tools/vmap4_extractor/model.h @@ -20,12 +20,9 @@ #define MODEL_H #include "vec3d.h" -//#include "mpq.h" #include "modelheaders.h" #include <vector> -class Model; -class WMOInstance; class MPQFile; Vec3D fixCoordSystem(Vec3D v); @@ -34,18 +31,14 @@ class Model { public: ModelHeader header; - uint32 offsBB_vertices, offsBB_indices; - Vec3D *BB_vertices, *vertices; - uint16 *BB_indices, *indices; - size_t nIndices; + Vec3D* vertices; + uint16* indices; bool open(); - bool ConvertToVMAPModel(const char * outfilename); + bool ConvertToVMAPModel(char const* outfilename); - bool ok; - - Model(std::string &filename); - ~Model() {_unload();} + Model(std::string& filename); + ~Model() { _unload(); } private: void _unload() @@ -55,22 +48,22 @@ private: vertices = NULL; indices = NULL; } + std::string filename; - char outfilename; }; class ModelInstance { public: - Model *model; + Model* model; uint32 id; Vec3D pos, rot; unsigned int d1, scale; - float w,sc; + float w, sc; - ModelInstance() {} - ModelInstance(MPQFile &f,const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile); + ModelInstance() : model(NULL), d1(0), scale(0), w(0.0f), sc(0.0f), id(0) {} + ModelInstance(MPQFile& f, char const* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile); }; diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 489655659c3..eebc763f2f2 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -334,12 +334,12 @@ bool ExtractSingleWmo(std::string& fname) int p = 0; //Select root wmo files - const char * rchr = strrchr(plain_name, '_'); + char const* rchr = strrchr(plain_name, '_'); if(rchr != NULL) { char cpy[4]; - strncpy((char*)cpy,rchr,4); - for (int i=0;i < 4; ++i) + strncpy((char*)cpy, rchr, 4); + for (int i = 0; i < 4; ++i) { int m = cpy[i]; if(isdigit(m)) @@ -375,7 +375,7 @@ bool ExtractSingleWmo(std::string& fname) strcpy(temp, fname.c_str()); temp[fname.length()-4] = 0; char groupFileName[1024]; - sprintf(groupFileName,"%s_%03d.wmo",temp, i); + sprintf(groupFileName, "%s_%03u.wmo", temp, i); //printf("Trying to open groupfile %s\n",groupFileName); string s = groupFileName; diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 2dd7396ae7d..9e208dac8dc 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -80,9 +80,8 @@ bool WDTFile::init(char *map_id, unsigned int mapID) char *p=buf; int q = 0; gWmoInstansName = new string[size]; - while (p<buf+size) + while (p < buf + size) { - string path(p); char* s=wdtGetPlainName(p); fixnamen(s,strlen(s)); p=p+strlen(p)+1; @@ -91,23 +90,20 @@ bool WDTFile::init(char *map_id, unsigned int mapID) delete[] buf; } } - else if (!strcmp(fourcc,"MODF")) + else if (!strcmp(fourcc, "MODF")) { // global wmo instance data if (size) { gnWMO = (int)size / 64; - string gWMO_mapname; - string fake_mapname; - fake_mapname = "65 65 "; - //gWMO_mapname = fake_mapname + filename; - gWMO_mapname = fake_mapname + std::string(map_id); - for (int i=0; i<gnWMO; ++i) + + for (int i = 0; i < gnWMO; ++i) { int id; WDT.read(&id, 4); - WMOInstance inst(WDT,gWmoInstansName[id].c_str(),mapID, 65, 65, dirfile); + WMOInstance inst(WDT,gWmoInstansName[id].c_str(), mapID, 65, 65, dirfile); } + delete[] gWmoInstansName; } } diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index ef3ec6db98c..b085965343a 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -13,16 +13,15 @@ class WDTFile public: WDTFile(char* file_name, char* file_name1); ~WDTFile(void); - bool init(char *map_id, unsigned int mapID); + bool init(char* map_id, unsigned int mapID); string* gWmoInstansName; - int gnWMO, nMaps; + int gnWMO; ADTFile* GetMap(int x, int z); private: MPQFile WDT; - bool maps[64][64]; string filename; }; diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 8bba5610c88..85cae02e41c 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -31,8 +31,12 @@ using namespace std; extern uint16 *LiqType; -WMORoot::WMORoot(std::string &filename) : filename(filename) +WMORoot::WMORoot(std::string &filename) + : filename(filename), col(0), nTextures(0), nGroups(0), nP(0), nLights(0), + nModels(0), nDoodads(0), nDoodadSets(0), RootWMOID(0), liquidType(0) { + memset(bbcorn1, 0, sizeof(bbcorn1)); + memset(bbcorn2, 0, sizeof(bbcorn2)); } extern HANDLE WorldMpq; @@ -59,7 +63,7 @@ bool WMORoot::open() size_t nextpos = f.getPos() + size; - if (!strcmp(fourcc,"MOHD"))//header + if (!strcmp(fourcc,"MOHD")) // header { f.read(&nTextures, 4); f.read(&nGroups, 4); @@ -70,8 +74,8 @@ bool WMORoot::open() f.read(&nDoodadSets, 4); f.read(&col, 4); f.read(&RootWMOID, 4); - f.read(bbcorn1,12); - f.read(bbcorn2,12); + f.read(bbcorn1, 12); + f.read(bbcorn2, 12); f.read(&liquidType, 4); break; } @@ -122,15 +126,15 @@ bool WMORoot::open() return true; } -bool WMORoot::ConvertToVMAPRootWmo(FILE *pOutfile) +bool WMORoot::ConvertToVMAPRootWmo(FILE* pOutfile) { //printf("Convert RootWmo...\n"); - fwrite(szRawVMAPMagic,1,8,pOutfile); + fwrite(szRawVMAPMagic, 1, 8, pOutfile); unsigned int nVectors = 0; - fwrite(&nVectors,sizeof(nVectors),1,pOutfile); // will be filled later - fwrite(&nGroups,4,1,pOutfile); - fwrite(&RootWMOID,4,1,pOutfile); + fwrite(&nVectors,sizeof(nVectors), 1, pOutfile); // will be filled later + fwrite(&nGroups, 4, 1, pOutfile); + fwrite(&RootWMOID, 4, 1, pOutfile); return true; } @@ -138,9 +142,13 @@ WMORoot::~WMORoot() { } -WMOGroup::WMOGroup(std::string &filename) : filename(filename), - MOPY(0), MOVI(0), MoviEx(0), MOVT(0), MOBA(0), MobaEx(0), hlq(0), LiquEx(0), LiquBytes(0) +WMOGroup::WMOGroup(const std::string &filename) : + filename(filename), MOPY(0), MOVI(0), MoviEx(0), MOVT(0), MOBA(0), MobaEx(0), + hlq(0), LiquEx(0), LiquBytes(0), groupName(0), descGroupName(0), mogpFlags(0), + mopy_size(0), moba_size(0), LiquEx_size(0), nVertices(0), nTriangles(0) { + memset(bbcorn1, 0, sizeof(bbcorn1)); + memset(bbcorn2, 0, sizeof(bbcorn2)); } bool WMOGroup::open() @@ -239,7 +247,7 @@ bool WMOGroup::open() return true; } -int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPreciseVectorData) +int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool preciseVectorData) { fwrite(&mogpFlags,sizeof(uint32),1,output); fwrite(&groupWMOID,sizeof(uint32),1,output); @@ -248,7 +256,7 @@ int WMOGroup::ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPrecis fwrite(bbcorn2, sizeof(float), 3, output); fwrite(&liquflags,sizeof(uint32),1,output); int nColTriangles = 0; - if(pPreciseVectorData) + if (preciseVectorData) { char GRP[] = "GRP "; fwrite(GRP,1,4,output); @@ -481,10 +489,9 @@ WMOGroup::~WMOGroup() delete [] LiquBytes; } -WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) +WMOInstance::WMOInstance(MPQFile& f, char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile) + : currx(0), curry(0), wmo(NULL), doodadset(0), pos(), indx(0), d3(0) { - pos = Vec3D(0,0,0); - float ff[3]; f.read(&id, 4); f.read(ff,12); diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index 7020bb90f12..02e4be4aa79 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -50,14 +50,13 @@ public: float bbcorn1[3]; float bbcorn2[3]; - WMORoot(std::string &filename); + WMORoot(std::string& filename); ~WMORoot(); bool open(); - bool ConvertToVMAPRootWmo(FILE *output); + bool ConvertToVMAPRootWmo(FILE* output); private: std::string filename; - char outfilename; }; struct WMOLiquidHeader @@ -89,30 +88,29 @@ public: uint16 nBatchB; uint32 nBatchC, fogIdx, liquidType, groupWMOID; - int mopy_size,moba_size; + int mopy_size, moba_size; int LiquEx_size; unsigned int nVertices; // number when loaded int nTriangles; // number when loaded - char *MOPY; - uint16 *MOVI; - uint16 *MoviEx; - float *MOVT; - uint16 *MOBA; - int *MobaEx; - WMOLiquidHeader *hlq; - WMOLiquidVert *LiquEx; - char *LiquBytes; + char* MOPY; + uint16* MOVI; + uint16* MoviEx; + float* MOVT; + uint16* MOBA; + int* MobaEx; + WMOLiquidHeader* hlq; + WMOLiquidVert* LiquEx; + char* LiquBytes; uint32 liquflags; - WMOGroup(std::string &filename); + WMOGroup(std::string const& filename); ~WMOGroup(); bool open(); - int ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool pPreciseVectorData); + int ConvertToVMAPGroupWmo(FILE* output, WMORoot* rootWMO, bool preciseVectorData); private: std::string filename; - char outfilename; }; class WMOInstance @@ -122,13 +120,13 @@ public: std::string MapName; int currx; int curry; - WMOGroup *wmo; + WMOGroup* wmo; Vec3D pos; Vec3D pos2, pos3, rot; - uint32 indx,id, d2, d3; + uint32 indx, id, d2, d3; int doodadset; - WMOInstance(MPQFile &f,const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile); + WMOInstance(MPQFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile); static void reset(); }; |