From 4d3e43e8142a9dcd16ffec24a17992dd24c86cc7 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 14 Oct 2009 19:33:10 +0400 Subject: [PATCH 01/13] [8644] Add assert for catch not updated constant at DBC data changes. --- src/game/AchievementMgr.cpp | 2 ++ src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index b21bb0571..a9503f720 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -1808,6 +1808,8 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() if(!criteria) continue; + assert(criteria->requiredType < ACHIEVEMENT_CRITERIA_TYPE_TOTAL && "Not updated ACHIEVEMENT_CRITERIA_TYPE_TOTAL?"); + m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e21c06418..16eb9726e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8643" + #define REVISION_NR "8644" #endif // __REVISION_NR_H__ From aff1a3e59fcecb31e2c0db65469913b4784d2a06 Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Wed, 14 Oct 2009 20:46:22 +0400 Subject: [PATCH 02/13] [8645] Cleanup code for config loading/store/access. Signed-off-by: VladimirMangos --- src/mangosd/Master.cpp | 10 +- src/realmd/Main.cpp | 10 +- src/shared/Config/Config.cpp | 116 ++--- src/shared/Config/Config.h | 13 +- src/shared/Config/dotconfpp/dotconfpp.cpp | 584 +++++++++++++--------- src/shared/Config/dotconfpp/dotconfpp.h | 136 ++--- src/shared/Config/dotconfpp/mempool.cpp | 80 +-- src/shared/Config/dotconfpp/mempool.h | 55 +- src/shared/revision_nr.h | 2 +- 9 files changed, 532 insertions(+), 474 deletions(-) diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp index 1212d94fa..68113ee7d 100644 --- a/src/mangosd/Master.cpp +++ b/src/mangosd/Master.cpp @@ -398,8 +398,8 @@ int Master::Run() bool Master::_StartDB() { ///- Get world database info from configuration file - std::string dbstring; - if(!sConfig.GetString("WorldDatabaseInfo", &dbstring)) + std::string dbstring = sConfig.GetStringDefault("WorldDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Database not specified in configuration file"); return false; @@ -416,7 +416,8 @@ bool Master::_StartDB() if(!WorldDatabase.CheckRequiredField("db_version",REVISION_DB_MANGOS)) return false; - if(!sConfig.GetString("CharacterDatabaseInfo", &dbstring)) + dbstring = sConfig.GetStringDefault("CharacterDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Character Database not specified in configuration file"); return false; @@ -434,7 +435,8 @@ bool Master::_StartDB() return false; ///- Get login database info from configuration file - if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) + dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Login database not specified in configuration file"); return false; diff --git a/src/realmd/Main.cpp b/src/realmd/Main.cpp index 4e53ed7ab..13fdc5747 100644 --- a/src/realmd/Main.cpp +++ b/src/realmd/Main.cpp @@ -50,7 +50,7 @@ char serviceDescription[] = "Massive Network Game Object Server"; int m_ServiceStatus = -1; #endif -bool StartDB(std::string &dbstring); +bool StartDB(); void UnhookSignals(); void HookSignals(); @@ -187,8 +187,7 @@ extern int main(int argc, char **argv) } ///- Initialize the database connection - std::string dbstring; - if(!StartDB(dbstring)) + if(!StartDB()) return 1; ///- Get the list of realms for the server @@ -312,9 +311,10 @@ void OnSignal(int s) } /// Initialize connection to the database -bool StartDB(std::string &dbstring) +bool StartDB() { - if(!sConfig.GetString("LoginDatabaseInfo", &dbstring)) + std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", ""); + if(dbstring.empty()) { sLog.outError("Database not specified"); return false; diff --git a/src/shared/Config/Config.cpp b/src/shared/Config/Config.cpp index 1d27c7775..6efcb6968 100644 --- a/src/shared/Config/Config.cpp +++ b/src/shared/Config/Config.cpp @@ -21,17 +21,16 @@ INSTANTIATE_SINGLETON_1(Config); -Config::Config() : mIgnoreCase(true), mConf(NULL) +Config::Config() +: mIgnoreCase(true), mConf(NULL) { } - Config::~Config() { delete mConf; } - bool Config::SetSource(const char *file, bool ignorecase) { mIgnoreCase = ignorecase; @@ -46,7 +45,7 @@ bool Config::Reload() mConf = new DOTCONFDocument(mIgnoreCase ? DOTCONFDocument::CASEINSENSETIVE : - DOTCONFDocument::CASESENSETIVE); + DOTCONFDocument::CASESENSITIVE); if (mConf->setContent(mFilename.c_str()) == -1) { @@ -58,117 +57,58 @@ bool Config::Reload() return true; } -bool Config::GetString(const char* name, std::string *value) -{ - if(!mConf) - return false; - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; - - *value = node->getValue(); - - return true; -} - -bool Config::GetString(const char* name, char const **value) -{ - if(!mConf) - return false; - - DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; - - *value = node->getValue(); - - return true; -} - - std::string Config::GetStringDefault(const char* name, const char* def) { - if(!mConf) + if (!mConf) return std::string(def); DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) + if (!node || !node->getValue()) return std::string(def); return std::string(node->getValue()); } - -bool Config::GetBool(const char* name, bool *value) +bool Config::GetBoolDefault(const char* name, bool def) { - if(!mConf) - return false; + if (!mConf) + return def; DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; + if (!node || !node->getValue()) + return def; const char* str = node->getValue(); - if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || + if (strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 || strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 || strcmp(str, "1") == 0) - { - *value = true; - } + return true; else - *value = false; - - return true; -} - - -bool Config::GetBoolDefault(const char* name, const bool def) -{ - bool val; - return GetBool(name, &val) ? val : def; -} - - -bool Config::GetInt(const char* name, int *value) -{ - if(!mConf) return false; +} + + +int32 Config::GetIntDefault(const char* name, int32 def) +{ + if (!mConf) + return def; DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; + if (!node || !node->getValue()) + return def; - *value = atoi(node->getValue()); - - return true; + return atoi(node->getValue()); } -bool Config::GetFloat(const char* name, float *value) +float Config::GetFloatDefault(const char* name, float def) { - if(!mConf) - return false; + if (!mConf) + return def; DOTCONFDocumentNode const *node = mConf->findNode(name); - if(!node || !node->getValue()) - return false; + if (!node || !node->getValue()) + return def; - *value = atof(node->getValue()); - - return true; -} - - -int Config::GetIntDefault(const char* name, const int def) -{ - int val; - return GetInt(name, &val) ? val : def; -} - - -float Config::GetFloatDefault(const char* name, const float def) -{ - float val; - return (GetFloat(name, &val) ? val : def); + return atof(node->getValue()); } diff --git a/src/shared/Config/Config.h b/src/shared/Config/Config.h index e09dffe38..989c8e19f 100644 --- a/src/shared/Config/Config.h +++ b/src/shared/Config/Config.h @@ -27,27 +27,22 @@ class DOTCONFDocument; class MANGOS_DLL_SPEC Config { public: + Config(); ~Config(); bool SetSource(const char *file, bool ignorecase = true); bool Reload(); - bool GetString(const char* name, std::string *value); - bool GetString(const char* name, char const **value); std::string GetStringDefault(const char* name, const char* def); - - bool GetBool(const char* name, bool *value); bool GetBoolDefault(const char* name, const bool def = false); - - bool GetInt(const char* name, int *value); - int GetIntDefault(const char* name, const int def); - - bool GetFloat(const char* name, float *value); + int32 GetIntDefault(const char* name, const int32 def); float GetFloatDefault(const char* name, const float def); std::string GetFilename() const { return mFilename; } + private: + std::string mFilename; bool mIgnoreCase; DOTCONFDocument *mConf; diff --git a/src/shared/Config/dotconfpp/dotconfpp.cpp b/src/shared/Config/dotconfpp/dotconfpp.cpp index d6fbc4ea8..24872d5cb 100644 --- a/src/shared/Config/dotconfpp/dotconfpp.cpp +++ b/src/shared/Config/dotconfpp/dotconfpp.cpp @@ -1,64 +1,68 @@ - #include "Common.h" - #include "dotconfpp.h" #ifdef WIN32 -#define PATH_MAX _MAX_PATH -#define strcasecmp stricmp -#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH) -#include +# define PATH_MAX _MAX_PATH +# define strcasecmp stricmp +# define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH) +# include #else -#include -#include -#include -#include +# include +# include +# include +# include #endif #if !defined(R_OK) -#define R_OK 04 +# define R_OK 04 #endif -DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), - values(NULL), valuesCount(0), - name(NULL), lineNum(0), fileName(NULL), closed(true) +DOTCONFDocumentNode::DOTCONFDocumentNode() +: previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL), +values(NULL), valuesCount(0), name(NULL), lineNum(0), +fileName(NULL), closed(true) { } DOTCONFDocumentNode::~DOTCONFDocumentNode() { free(name); - if(values != NULL){ - for(int i = 0 ; i < valuesCount; i++){ + + if (values != NULL) + { + for (int i = 0; i < valuesCount; ++i) free(values[i]); - } + free(values); } } -void DOTCONFDocumentNode::pushValue(char * _value) +void DOTCONFDocumentNode::pushValue(char* _value) { ++valuesCount; - values = (char**)realloc(values, valuesCount*sizeof(char*)); - values[valuesCount-1] = strdup(_value); + values = (char**)realloc(values, valuesCount * sizeof(char*)); + values[valuesCount - 1] = strdup(_value); } const char* DOTCONFDocumentNode::getValue(int index) const { - if(index >= valuesCount){ + if (index >= valuesCount) return NULL; - } + return values[index]; } -DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity): - mempool(NULL), - curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL) +DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity) +: mempool(NULL), curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL) { - if(caseSensitivity == CASESENSETIVE){ - cmp_func = strcmp; - } else { - cmp_func = strcasecmp; + switch (caseSensitivity) + { + case CASESENSITIVE: + cmp_func = strcmp; + break; + case CASEINSENSETIVE: + cmp_func = strcasecmp; + break; } mempool = new AsyncDNSMemPool(1024); @@ -67,195 +71,247 @@ DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity) DOTCONFDocument::~DOTCONFDocument() { - for(std::list::iterator i = nodeTree.begin(); i != nodeTree.end(); i++){ + for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) delete(*i); - } - for(std::list::iterator i = requiredOptions.begin(); i != requiredOptions.end(); i++){ + + for (CharList::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i) free(*i); - } - for(std::list::iterator i = processedFiles.begin(); i != processedFiles.end(); i++){ + + for (CharList::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i) free(*i); - } + free(fileName); delete mempool; } -int DOTCONFDocument::cleanupLine(char * line) +int DOTCONFDocument::cleanupLine(char* line) { - char * start = line; - char * bg = line; + char* start = line; + char* bg = line; bool multiline = false; bool concat = false; - char * word = NULL; + char* word = NULL; - if(!words.empty() && quoted) + if (!words.empty() && quoted) concat = true; - while(*line){ - if((*line == '#' || *line == ';') && !quoted){ + while (*line) + { + if ((*line == '#' || *line == ';') && !quoted) + { *bg = 0; - if(strlen(start)){ - - if(concat){ - word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + if (strlen(start)) + { + if (concat) + { + word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); strcpy(word, words.back()); strcat(word, start); words.pop_back(); concat = false; - } else { - word = mempool->strdup(start); } + else + word = mempool->Strdup(start); + words.push_back(word); } + break; } - if(*line == '=' && !quoted){ - *line = ' ';continue; + + if (*line == '=' && !quoted) + { + *line = ' '; + continue; } // Allowing \" in there causes problems with directory paths // like "C:\MaNGOS\" //if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){ - if(*line == '\\' && (*(line+1) == '\'')) { - *bg++ = *(line+1); - line+=2; continue; + if (*line == '\\' && (*(line + 1) == '\'')) + { + *bg++ = *(line + 1); + line += 2; + continue; } - if(*line == '\\' && *(line+1) == 'n'){ - *bg++ = '\n'; - line+=2; continue; - } - if(*line == '\\' && *(line+1) == 'r'){ - *bg++ = '\r'; - line+=2; continue; - } - if(*line == '\\' && (*(line+1) == '\n' || *(line+1) == '\r')){ - *bg = 0; - if(strlen(start)){ - if(concat){ - word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + if (*line == '\\' && *(line + 1) == 'n') + { + *bg++ = '\n'; + line += 2; + continue; + } + + if (*line == '\\' && *(line + 1) == 'r') + { + *bg++ = '\r'; + line += 2; + continue; + } + + if (*line == '\\' && (*(line + 1) == '\n' || *(line + 1) == '\r')) + { + *bg = 0; + if (strlen(start)) + { + if (concat) + { + word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); strcpy(word, words.back()); strcat(word, start); words.pop_back(); concat = false; - } else { - word = mempool->strdup(start); } + else + word = mempool->Strdup(start); + words.push_back(word); } + multiline = true; break; } - if(*line == '"' || *line == '\''){ - quoted = !quoted; - ++line; continue; - } - if(isspace((unsigned char)*line) && !quoted){ - *bg++ = 0; - if(strlen(start)){ - if(concat){ - word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1); + if (*line == '"' || *line == '\'') + { + quoted = !quoted; + ++line; + continue; + } + + if (isspace((unsigned char)*line) && !quoted) + { + *bg++ = 0; + if (strlen(start)) + { + if (concat) + { + word = (char*)mempool->Alloc(strlen(words.back()) + strlen(start) + 1); strcpy(word, words.back()); strcat(word, start); words.pop_back(); concat = false; - } else { - word = mempool->strdup(start); } + else + word = mempool->Strdup(start); + words.push_back(word); } + start = bg; - while(isspace((unsigned char)*++line)) {} + while (isspace((unsigned char)*++line)) + { + } continue; } + *bg++ = *line++; } - if(quoted && !multiline){ + if (quoted && !multiline) + { error(curLine, fileName, "unterminated quote"); return -1; } - return multiline?1:0; + return multiline ? 1 : 0; } int DOTCONFDocument::parseLine() { - char * word = NULL; - char * nodeName = NULL; - char * nodeValue = NULL; - DOTCONFDocumentNode * tagNode = NULL; + char* word = NULL; + char* nodeName = NULL; + char* nodeValue = NULL; + DOTCONFDocumentNode* tagNode = NULL; bool newNode = false; - for(std::list::iterator i = words.begin(); i != words.end(); i++) { + for (CharList::iterator i = words.begin(); i != words.end(); ++i) + { word = *i; - if(*word == '<'){ + if (*word == '<') newNode = true; - } - if(newNode){ + if (newNode) + { nodeValue = NULL; nodeName = NULL; newNode = false; } size_t wordLen = strlen(word); - if(word[wordLen-1] == '>'){ - word[wordLen-1] = 0; + if (word[wordLen - 1] == '>') + { + word[wordLen - 1] = 0; newNode = true; } - if(nodeName == NULL){ + if (nodeName == NULL) + { nodeName = word; bool closed = true; - if(*nodeName == '<'){ - if(*(nodeName+1) != '/'){ + if (*nodeName == '<') + { + if (*(nodeName + 1) != '/') + { ++nodeName; closed = false; - } else { - nodeName+=2; - std::list::reverse_iterator itr=nodeTree.rbegin(); - for(; itr!=nodeTree.rend(); ++itr){ - if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){ + } + else + { + NodeList::reverse_iterator itr = nodeTree.rbegin(); + nodeName += 2; + for (; itr != nodeTree.rend(); ++itr) + { + if (!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed) + { (*itr)->closed = true; curParent = (*itr)->parentNode; curPrev = *itr; break; } } - if(itr==nodeTree.rend()){ + + if(itr == nodeTree.rend()) + { error(curLine, fileName, "not matched closing tag ", nodeName); return -1; } + continue; } } + tagNode = new DOTCONFDocumentNode; tagNode->name = strdup(nodeName); tagNode->document = this; tagNode->fileName = processedFiles.back(); tagNode->lineNum = curLine; tagNode->closed = closed; - if(!nodeTree.empty()){ - DOTCONFDocumentNode * prev = nodeTree.back(); - if(prev->closed){ + if(!nodeTree.empty()) + { + DOTCONFDocumentNode* prev = nodeTree.back(); + if (prev->closed) + { curPrev->nextNode = tagNode; tagNode->previousNode = curPrev; tagNode->parentNode = curParent; - - } else { + } + else + { prev->childNode = tagNode; tagNode->parentNode = prev; curParent = prev; } } + nodeTree.push_back(tagNode); curPrev = tagNode; - } else { + } + else + { nodeValue = word; tagNode->pushValue(nodeValue); } @@ -263,7 +319,8 @@ int DOTCONFDocument::parseLine() return 0; } -int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) + +int DOTCONFDocument::parseFile(DOTCONFDocumentNode* _parent) { char str[512]; int ret = 0; @@ -273,27 +330,32 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) quoted = false; size_t slen = 0; - while(fgets(str, 511, file)){ + while (fgets(str, 511, file)) + { ++curLine; - slen = strlen(str); - if( slen >= 510 ){ + slen = strlen(str); + if (slen >= 510) error(curLine, fileName, "warning: line too long"); + + if (str[slen - 1] != '\n') + { + str[slen] = '\n'; + str[slen + 1] = 0; } - if(str[slen-1] != '\n'){ - str[slen] = '\n'; - str[slen+1] = 0; - } - if((ret = cleanupLine(str)) == -1){ + + if ((ret = cleanupLine(str)) == -1) break; - } - if(ret == 0){ - if(!words.empty()){ + + if (ret == 0) + { + if (!words.empty()) + { ret = parseLine(); - mempool->free(); + mempool->Free(); words.clear(); - if(ret == -1){ + + if(ret == -1) break; - } } } } @@ -301,46 +363,51 @@ int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent) return ret; } -int DOTCONFDocument::checkConfig(const std::list::iterator & from) +int DOTCONFDocument::checkConfig(const NodeList::iterator& from) { int ret = 0; - DOTCONFDocumentNode * tagNode = NULL; + DOTCONFDocumentNode* tagNode = NULL; int vi = 0; - for(std::list::iterator i = from; i != nodeTree.end(); i++){ + for (NodeList::iterator i = from; i != nodeTree.end(); ++i) + { tagNode = *i; - if(!tagNode->closed){ + if (!tagNode->closed) + { error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name); ret = -1; break; } - vi = 0; - while( vi < tagNode->valuesCount ){ - if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){ - ret = macroSubstitute(tagNode, vi ); - mempool->free(); - if(ret == -1){ + vi = 0; + while (vi < tagNode->valuesCount) + { + if (strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}')) + { + ret = macroSubstitute(tagNode, vi); + mempool->Free(); + if (ret == -1) break; - } } + ++vi; } - if(ret == -1){ + + if (ret == -1) break; - } } return ret; } -int DOTCONFDocument::setContent(const char * _fileName) +int DOTCONFDocument::setContent(const char* _fileName) { int ret = 0; char realpathBuf[PATH_MAX]; - if(realpath(_fileName, realpathBuf) == NULL){ - error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno)); + if (realpath(_fileName, realpathBuf) == NULL) + { + error(0, NULL, "realpath (%s) failed: %s", _fileName, strerror(errno)); return -1; } @@ -348,79 +415,90 @@ int DOTCONFDocument::setContent(const char * _fileName) processedFiles.push_back(strdup(realpathBuf)); - if(( file = fopen(fileName, "r")) == NULL){ + if ((file = fopen(fileName, "r")) == NULL) + { error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno)); return -1; } + // Try read utf8 header and skip it if exist - uint32 utf8header = 0; + unsigned int utf8header = 0; fgets((char*)&utf8header, 4, file); // Try read header - if (utf8header!=0x00BFBBEF) // If not exist + if (utf8header != 0x00BFBBEF) // If not exist fseek(file, 0, SEEK_SET); // Reset read position ret = parseFile(); - (void) fclose(file); + fclose(file); - if(!ret){ - - if( (ret = checkConfig(nodeTree.begin())) == -1){ + if (!ret) + { + if ((ret = checkConfig(nodeTree.begin())) == -1) return -1; - } - std::list::iterator from; - DOTCONFDocumentNode * tagNode = NULL; + NodeList::iterator from; + DOTCONFDocumentNode* tagNode = NULL; int vi = 0; - for(std::list::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ + for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) + { tagNode = *i; - if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){ + if (!cmp_func("DOTCONFPPIncludeFile", tagNode->name)) + { vi = 0; - while( vi < tagNode->valuesCount ){ - if(access(tagNode->values[vi], R_OK) == -1){ + while (vi < tagNode->valuesCount) + { + if (access(tagNode->values[vi], R_OK) == -1) + { error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno)); return -1; } - if(realpath(tagNode->values[vi], realpathBuf) == NULL){ - error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", tagNode->values[vi], strerror(errno)); + + if (realpath(tagNode->values[vi], realpathBuf) == NULL) + { + error(tagNode->lineNum, tagNode->fileName, "realpath (%s) failed: %s", tagNode->values[vi], strerror(errno)); return -1; } bool processed = false; - for(std::list::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); itInode++){ - if(!strcmp(*itInode, realpathBuf)){ + for (CharList::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode) + { + if (!strcmp(*itInode, realpathBuf)) + { processed = true; break; } } - if(processed){ + + if(processed) break; - } processedFiles.push_back(strdup(realpathBuf)); file = fopen(tagNode->values[vi], "r"); - if(file == NULL){ + if(file == NULL) + { error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno)); return -1; } fileName = strdup(realpathBuf); - from = nodeTree.end(); --from; + from = nodeTree.end(); + --from; ret = parseFile(); - (void) fclose(file); - if(ret == -1) + fclose(file); + + if (ret == -1) return -1; - if(checkConfig(++from) == -1){ + if (checkConfig(++from) == -1) return -1; - } + ++vi; } } } - - if(!requiredOptions.empty()) + if (!requiredOptions.empty()) ret = checkRequiredOptions(); } @@ -429,124 +507,150 @@ int DOTCONFDocument::setContent(const char * _fileName) int DOTCONFDocument::checkRequiredOptions() { - for(std::list::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ci++){ + for (CharList::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci) + { bool matched = false; - for(std::list::iterator i = nodeTree.begin(); i!=nodeTree.end(); i++){ - if(!cmp_func((*i)->name, *ci)){ + for (NodeList::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i) + { + if (!cmp_func((*i)->name, *ci)) + { matched = true; break; } } - if(!matched){ + + if(!matched) + { error(0, NULL, "required option '%s' not specified", *ci); return -1; } } + return 0; } -void DOTCONFDocument::error(int lineNum, const char * fileName_, const char * fmt, ...) +void DOTCONFDocument::error(int lineNum, const char* fileName_, const char* fmt, ...) { va_list args; va_start(args, fmt); - size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50; - char * buf = (char*)mempool->alloc(len); + size_t len = (lineNum != 0 ? strlen(fileName_) : 0) + strlen(fmt) + 50; + char* buf = (char*)mempool->Alloc(len); - if(lineNum) - (void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); + if (lineNum) + snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt); else - (void) snprintf(buf, len, "DOTCONF++: %s\n", fmt); + snprintf(buf, len, "DOTCONF++: %s\n", fmt); - (void) vfprintf(stderr, buf, args); + vfprintf(stderr, buf, args); va_end(args); } -char * DOTCONFDocument::getSubstitution(char * macro, int lineNum) +char* DOTCONFDocument::getSubstitution(char* macro, int lineNum) { - char * buf = NULL; - char * variable = macro+2; + char* buf = NULL; + char* variable = macro + 2; - char * endBr = strchr(macro, '}'); + char* endBr = strchr(macro, '}'); - if(!endBr){ + if (!endBr) + { error(lineNum, fileName, "unterminated '{'"); return NULL; } + *endBr = 0; - char * defaultValue = strchr(variable, ':'); + char* defaultValue = strchr(variable, ':'); - if(defaultValue){ + if (defaultValue) + { *defaultValue++ = 0; - if(*defaultValue != '-'){ + if (*defaultValue != '-') + { error(lineNum, fileName, "incorrect macro substitution syntax"); return NULL; } - ++defaultValue; - if(*defaultValue == '"' || *defaultValue == '\''){ - ++defaultValue; - defaultValue[strlen(defaultValue)-1] = 0; - } - } else { - defaultValue = NULL; - } - char * subs = getenv(variable); - if( subs ){ - buf = mempool->strdup(subs); - } else { - std::list::iterator i = nodeTree.begin(); - DOTCONFDocumentNode * tagNode = NULL; - for(; i!=nodeTree.end(); i++){ + ++defaultValue; + if (*defaultValue == '"' || *defaultValue == '\'') + { + ++defaultValue; + defaultValue[strlen(defaultValue) - 1] = 0; + } + } + else + defaultValue = NULL; + + char* subs = getenv(variable); + if (subs) + buf = mempool->Strdup(subs); + else + { + NodeList::iterator i = nodeTree.begin(); + DOTCONFDocumentNode* tagNode = NULL; + for (; i != nodeTree.end(); ++i) + { tagNode = *i; - if(!cmp_func(tagNode->name, variable)){ - if(tagNode->valuesCount != 0){ - buf = mempool->strdup(tagNode->values[0]); + if (!cmp_func(tagNode->name, variable)) + { + if (tagNode->valuesCount != 0) + { + buf = mempool->Strdup(tagNode->values[0]); break; } } } - if( i == nodeTree.end() ){ - if( defaultValue ){ - buf = mempool->strdup(defaultValue); - } else { + + if (i == nodeTree.end()) + { + if (defaultValue) + buf = mempool->Strdup(defaultValue); + else + { error(lineNum, fileName, "substitution not found and default value not given"); return NULL; } } } + return buf; } -int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex) +int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex) { int ret = 0; - char * macro = tagNode->values[valueIndex]; - size_t valueLen = strlen(tagNode->values[valueIndex])+1; - char * value = (char*)mempool->alloc(valueLen); - char * v = value; - char * subs = NULL; + char* macro = tagNode->values[valueIndex]; + size_t valueLen = strlen(tagNode->values[valueIndex]) + 1; + char* value = (char*)mempool->Alloc(valueLen); + char* v = value; + char* subs = NULL; - while(*macro){ - if(*macro == '$' && *(macro+1) == '{'){ - char * m = strchr(macro, '}'); + while (*macro) + { + if (*macro == '$' && *(macro + 1) == '{') + { + char* m = strchr(macro, '}'); subs = getSubstitution(macro, tagNode->lineNum); - if(subs == NULL){ + if(subs == NULL) + { ret = -1; break; } + macro = m + 1; *v = 0; - v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen); + v = (char*)mempool->Alloc(strlen(value) + strlen(subs) + valueLen); strcpy(v, value); value = strcat(v, subs); v = value + strlen(value); continue; } + *v++ = *macro++; } + *v = 0; free(tagNode->values[valueIndex]); @@ -554,47 +658,47 @@ int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueInd return ret; } -const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const +const DOTCONFDocumentNode* DOTCONFDocument::getFirstNode() const { - if ( !nodeTree.empty() ) { + if (!nodeTree.empty()) return *nodeTree.begin(); - } else { + else return NULL; - } } -const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const +const DOTCONFDocumentNode* DOTCONFDocument::findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode, const DOTCONFDocumentNode* startNode) const { + NodeList::const_iterator i = nodeTree.begin(); - - std::list::const_iterator i = nodeTree.begin(); - - if(startNode == NULL) + if (startNode == NULL) startNode = parentNode; - if(startNode != NULL){ - while( i != nodeTree.end() && (*i) != startNode ){ + if (startNode != NULL) + { + while (i != nodeTree.end() && (*i) != startNode) + ++i; + + if (i != nodeTree.end()) ++i; - } - if( i != nodeTree.end() ) ++i; } - for(; i!=nodeTree.end(); i++){ - - if((*i)->parentNode != parentNode){ + for (; i != nodeTree.end(); ++i) + { + if ((*i)->parentNode != parentNode) continue; - } - if(!cmp_func(nodeName, (*i)->name)){ + + if (!cmp_func(nodeName, (*i)->name)) return *i; - } } + return NULL; } -void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames) +void DOTCONFDocument::setRequiredOptionNames(const char** requiredOptionNames) { - while(*requiredOptionNames){ - requiredOptions.push_back(strdup( *requiredOptionNames )); + while (*requiredOptionNames) + { + requiredOptions.push_back(strdup(*requiredOptionNames)); ++requiredOptionNames; } } diff --git a/src/shared/Config/dotconfpp/dotconfpp.h b/src/shared/Config/dotconfpp/dotconfpp.h index 77b6fda98..55e6dd75d 100644 --- a/src/shared/Config/dotconfpp/dotconfpp.h +++ b/src/shared/Config/dotconfpp/dotconfpp.h @@ -1,6 +1,3 @@ - - - #ifndef DOTCONFPP_H #define DOTCONFPP_H @@ -21,77 +18,94 @@ class DOTCONFDocument; class DOTCONFDocumentNode { -friend class DOTCONFDocument; -private: - DOTCONFDocumentNode * previousNode; - DOTCONFDocumentNode * nextNode; - DOTCONFDocumentNode * parentNode; - DOTCONFDocumentNode * childNode; - char ** values; - int valuesCount; - char * name; - const DOTCONFDocument * document; - int lineNum; - char * fileName; - bool closed; + friend class DOTCONFDocument; - void pushValue(char * _value); + private: -public: - DOTCONFDocumentNode(); - ~DOTCONFDocumentNode(); + DOTCONFDocumentNode* previousNode; + DOTCONFDocumentNode* nextNode; + DOTCONFDocumentNode* parentNode; + DOTCONFDocumentNode* childNode; + char** values; + int valuesCount; + char* name; + const DOTCONFDocument* document; + int lineNum; + char* fileName; + bool closed; - const char * getConfigurationFileName()const { return fileName; } - int getConfigurationLineNumber() const { return lineNum; } + void pushValue(char* _value); - const DOTCONFDocumentNode * getNextNode() const { return nextNode; } - const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; } - const DOTCONFDocumentNode * getParentNode() const { return parentNode; } - const DOTCONFDocumentNode * getChildNode() const { return childNode; } - const char* getValue(int index = 0) const; - const char * getName() const { return name; } - const DOTCONFDocument * getDocument() const { return document; } + public: + + DOTCONFDocumentNode(); + ~DOTCONFDocumentNode(); + + const char* getConfigurationFileName() const { return fileName; } + int getConfigurationLineNumber() const { return lineNum; } + + const DOTCONFDocumentNode* getNextNode() const { return nextNode; } + const DOTCONFDocumentNode* getPreviuosNode() const { return previousNode; } + const DOTCONFDocumentNode* getParentNode() const { return parentNode; } + const DOTCONFDocumentNode* getChildNode() const { return childNode; } + const char* getValue(int index = 0) const; + const char* getName() const { return name; } + const DOTCONFDocument * getDocument() const { return document; } }; class DOTCONFDocument { -public: - enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE }; -protected: - AsyncDNSMemPool * mempool; -private: - DOTCONFDocumentNode * curParent; - DOTCONFDocumentNode * curPrev; - int curLine; - bool quoted; - std::list nodeTree; - std::list requiredOptions; - std::list processedFiles; - FILE * file; - char * fileName; - std::list words; - int (*cmp_func)(const char *, const char *); + public: - int checkRequiredOptions(); - int parseLine(); - int parseFile(DOTCONFDocumentNode * _parent = NULL); - int checkConfig(const std::list::iterator & from); - int cleanupLine(char * line); - char * getSubstitution(char * macro, int lineNum); - int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex); + enum CaseSensitive + { + CASESENSITIVE, + CASEINSENSETIVE + }; -protected: - virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5); + protected: -public: - DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE); - virtual ~DOTCONFDocument(); + AsyncDNSMemPool* mempool; - int setContent(const char * _fileName); + private: - void setRequiredOptionNames(const char ** requiredOptionNames); - const DOTCONFDocumentNode * getFirstNode() const; - const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const; + typedef std::list CharList; + typedef std::list NodeList; + + DOTCONFDocumentNode* curParent; + DOTCONFDocumentNode* curPrev; + int curLine; + bool quoted; + NodeList nodeTree; + CharList requiredOptions; + CharList processedFiles; + FILE* file; + char* fileName; + CharList words; + int (*cmp_func)(const char*, const char*); + + int checkRequiredOptions(); + int parseLine(); + int parseFile(DOTCONFDocumentNode* _parent = NULL); + int checkConfig(const NodeList::iterator& from); + int cleanupLine(char* line); + char* getSubstitution(char* macro, int lineNum); + int macroSubstitute(DOTCONFDocumentNode* tagNode, int valueIndex); + + protected: + + virtual void error(int lineNum, const char* fileName, const char* fmt, ...) ATTR_PRINTF(4,5); + + public: + + DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE); + virtual ~DOTCONFDocument(); + + int setContent(const char* _fileName); + + void setRequiredOptionNames(const char** requiredOptionNames); + const DOTCONFDocumentNode * getFirstNode() const; + const DOTCONFDocumentNode * findNode(const char* nodeName, const DOTCONFDocumentNode* parentNode = NULL, const DOTCONFDocumentNode* startNode = NULL) const; }; #endif diff --git a/src/shared/Config/dotconfpp/mempool.cpp b/src/shared/Config/dotconfpp/mempool.cpp index cf589ffb2..45bdee24c 100644 --- a/src/shared/Config/dotconfpp/mempool.cpp +++ b/src/shared/Config/dotconfpp/mempool.cpp @@ -1,12 +1,9 @@ - - - #include "mempool.h" -AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size): - pool(NULL), pos(0), size(_size) +AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size) +: pool(NULL), pos(0), size(_size) { - pool = ::malloc(size); + pool = malloc(size); } AsyncDNSMemPool::PoolChunk::~PoolChunk() @@ -14,87 +11,96 @@ AsyncDNSMemPool::PoolChunk::~PoolChunk() ::free(pool); } -AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize): - chunks(NULL), chunksCount(0), defaultSize(_defaultSize), - poolUsage(0), poolUsageCounter(0) +AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize) +: chunks(NULL), chunksCount(0), defaultSize(_defaultSize), +poolUsage(0), poolUsageCounter(0) { } AsyncDNSMemPool::~AsyncDNSMemPool() { - for(size_t i = 0; isize - chunk->pos) >= size){ + if ((chunk->size - chunk->pos) >= size) + { chunk->pos += size; return ((char*)chunk->pool) + chunk->pos - size; } } + addNewChunk(size); - chunks[chunksCount-1]->pos = size; - return chunks[chunksCount-1]->pool; + chunks[chunksCount - 1]->pos = size; + return chunks[chunksCount - 1]->pool; } -void AsyncDNSMemPool::free() +void AsyncDNSMemPool::Free() { size_t pu = 0; size_t psz = 0; ++poolUsageCounter; - for(size_t i = 0; ipos; psz += chunks[i]->size; chunks[i]->pos = 0; } - poolUsage=(poolUsage>pu)?poolUsage:pu; - if(poolUsageCounter >= 10 && chunksCount > 1){ - psz -= chunks[chunksCount-1]->size; - if(poolUsage < psz){ + poolUsage = poolUsage > pu ? poolUsage : pu; + + if (poolUsageCounter >= 10 && chunksCount > 1) + { + psz -= chunks[chunksCount - 1]->size; + if (poolUsage < psz) + { --chunksCount; delete chunks[chunksCount]; } + poolUsage = 0; poolUsageCounter = 0; } } -void * AsyncDNSMemPool::calloc(size_t size) +void* AsyncDNSMemPool::Calloc(size_t size) { - return ::memset(this->alloc(size), 0, size); + return ::memset(Alloc(size), 0, size); } -char * AsyncDNSMemPool::strdup(const char *str) +char* AsyncDNSMemPool::Strdup(const char *str) { - return ::strcpy((char*)this->alloc(strlen(str)+1), str); + return ::strcpy((char*)Alloc(strlen(str) + 1), str); } diff --git a/src/shared/Config/dotconfpp/mempool.h b/src/shared/Config/dotconfpp/mempool.h index 04bd1e006..44b789551 100644 --- a/src/shared/Config/dotconfpp/mempool.h +++ b/src/shared/Config/dotconfpp/mempool.h @@ -1,6 +1,3 @@ - - - #ifndef ASYNC_DNS_MEMPOOL_H #define ASYNC_DNS_MEMPOOL_H @@ -8,39 +5,39 @@ #include #include -#undef free -#undef calloc -#undef strdup - class AsyncDNSMemPool { -private: - struct PoolChunk { - void * pool; - size_t pos; - size_t size; + private: - PoolChunk(size_t _size); - ~PoolChunk(); - }; - PoolChunk ** chunks; - size_t chunksCount; - size_t defaultSize; + struct PoolChunk + { + void* pool; + size_t pos; + size_t size; - size_t poolUsage; - size_t poolUsageCounter; + PoolChunk(size_t _size); + ~PoolChunk(); + }; - void addNewChunk(size_t size); + PoolChunk** chunks; + size_t chunksCount; + size_t defaultSize; -public: - AsyncDNSMemPool(size_t _defaultSize = 4096); - virtual ~AsyncDNSMemPool(); + size_t poolUsage; + size_t poolUsageCounter; - int initialize(); - void free(); - void * alloc(size_t size); - void * calloc(size_t size); - char * strdup(const char *str); + void addNewChunk(size_t size); + + public: + + AsyncDNSMemPool(size_t _defaultSize = 4096); + virtual ~AsyncDNSMemPool(); + + bool initialize(); + void Free(); + void* Alloc(size_t size); + void* Calloc(size_t size); + char* Strdup(const char *str); }; #endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 16eb9726e..59d75bd20 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8644" + #define REVISION_NR "8645" #endif // __REVISION_NR_H__ From b780e2dd808b9d9f4491969c069cda4ad206f079 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Wed, 14 Oct 2009 19:17:54 +0200 Subject: [PATCH 03/13] [8646] Add basic support for QUEST_FLAGS_PARTY_ACCEPT (2). Signed-off-by: NoFantasy --- src/game/Player.cpp | 27 ++++++++++++++++++++ src/game/Player.h | 1 + src/game/QuestDef.h | 2 +- src/game/QuestHandler.cpp | 53 ++++++++++++++++++++++++++++++++++++++- src/shared/revision_nr.h | 2 +- 5 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 06cae2ef2..8cedbab74 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -13897,6 +13897,33 @@ void Player::SendCanTakeQuestResponse( uint32 msg ) sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID"); } +void Player::SendQuestConfirmAccept(const Quest* pQuest, Player* pReceiver) +{ + if (pReceiver) + { + std::string strTitle = pQuest->GetTitle(); + + int loc_idx = pReceiver->GetSession()->GetSessionDbLocaleIndex(); + + if (loc_idx >= 0) + { + if (const QuestLocale* pLocale = objmgr.GetQuestLocale(pQuest->GetQuestId())) + { + if (pLocale->Title.size() > loc_idx && !pLocale->Title[loc_idx].empty()) + strTitle = pLocale->Title[loc_idx]; + } + } + + WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + strTitle.size() + 8)); + data << uint32(pQuest->GetQuestId()); + data << strTitle; + data << uint64(GetGUID()); + pReceiver->GetSession()->SendPacket(&data); + + sLog.outDebug("WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT"); + } +} + void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg ) { if( pPlayer ) diff --git a/src/game/Player.h b/src/game/Player.h index 39a25e8f0..78aa5d945 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1369,6 +1369,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SendQuestFailed( uint32 quest_id ); void SendQuestTimerFailed( uint32 quest_id ); void SendCanTakeQuestResponse( uint32 msg ); + void SendQuestConfirmAccept(Quest const* pQuest, Player* pReceiver); void SendPushToPartyResponse( Player *pPlayer, uint32 msg ); void SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ); void SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count ); diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index 999e8de7a..02729db1d 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -120,7 +120,7 @@ enum __QuestFlags { // Flags used at server and sent to client QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently - QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT + QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT QUEST_FLAGS_EXPLORATION = 0x00000004, // Not used currently QUEST_FLAGS_SHARABLE = 0x00000008, // Can be shared: Player::CanShareQuest() //QUEST_FLAGS_NONE2 = 0x00000010, // Not used currently diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 1cef7dd22..5f105b411 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -154,6 +154,30 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) { _player->AddQuest( qInfo, pObject ); + if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) + { + if (Group* pGroup = _player->GetGroup()) + { + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* pPlayer = itr->getSource(); + + if (!pPlayer || pPlayer == _player) // not self + continue; + + if (pPlayer->CanTakeQuest(qInfo, true)) + { + pPlayer->SetDivider(_player->GetGUID()); + + //need confirmation that any gossip window will close + pPlayer->PlayerTalkClass->CloseGossip(); + + _player->SendQuestConfirmAccept(qInfo, pPlayer); + } + } + } + } + if ( _player->CanCompleteQuest( quest ) ) _player->CompleteQuest( quest ); @@ -370,7 +394,34 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data) uint32 quest; recv_data >> quest; - sLog.outDebug( "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u",quest ); + sLog.outDebug("WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", quest); + + if (const Quest* pQuest = objmgr.GetQuestTemplate(quest)) + { + if (!pQuest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT)) + return; + + Player* pOriginalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider()); + + if (!pOriginalPlayer) + return; + + if (pQuest->GetType() == QUEST_TYPE_RAID) + { + if (!_player->IsInSameRaidWith(pOriginalPlayer)) + return; + } + else + { + if (!_player->IsInSameGroupWith(pOriginalPlayer)) + return; + } + + if (_player->CanAddQuest(pQuest, true)) + _player->AddQuest(pQuest, NULL); // NULL, this prevent DB script from duplicate running + + _player->SetDivider(0); + } } void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 59d75bd20..f40da81ac 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8645" + #define REVISION_NR "8646" #endif // __REVISION_NR_H__ From 401143391849ceefd8dbe33c90230e51122d0681 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Thu, 15 Oct 2009 00:27:33 +0200 Subject: [PATCH 04/13] [8647] Use correct check in _BuildMovementUpdate, if creature can fly. Signed-off-by: NoFantasy --- src/game/Object.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 4cc1ad9a6..d7260cd8e 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -257,7 +257,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 { case TYPEID_UNIT: { - flags2 = ((Unit*)this)->isInFlight() ? (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_LEVITATING) : MOVEMENTFLAG_NONE; + flags2 = ((Creature*)this)->canFly() ? (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_LEVITATING) : MOVEMENTFLAG_NONE; } break; case TYPEID_PLAYER: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f40da81ac..590cdfcbb 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8646" + #define REVISION_NR "8647" #endif // __REVISION_NR_H__ From 369e50e0683a515d3735df04780c873d8de1531b Mon Sep 17 00:00:00 2001 From: qsa Date: Thu, 15 Oct 2009 15:03:59 +0400 Subject: [PATCH 05/13] [8648] Implement SPELL_AURA_MOD_HONOR_GAIN Signed-off-by: VladimirMangos --- src/game/Player.cpp | 1 + src/game/SpellAuras.cpp | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 8cedbab74..f92bb4cf0 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6106,6 +6106,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor) if (uVictim != NULL) { honor *= sWorld.getRate(RATE_HONOR); + honor *= (GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN) + 100.0f)/100.0f; if(groupsize > 1) honor /= groupsize; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index ec29a8e0e..a142e2423 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -331,7 +331,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon &Aura::HandleNULL, //279 visual effects? 58836 and 57507 &Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT - &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN + &Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN implemented in Player::RewardHonor &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus &Aura::HandleUnused, //284 51 spells diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 590cdfcbb..c221ea49d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8647" + #define REVISION_NR "8648" #endif // __REVISION_NR_H__ From a4d61a69882f63b50aeb6ab23f4e3eaf53fa5d6f Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 15 Oct 2009 20:44:30 +0400 Subject: [PATCH 06/13] [8649] Implement SPELL_AURA_MECHANIC_IMMUNITY_MASK (147) and related cleanups. * Always use machanic masks in form (1 << (mech-1)), fix all cases. * Imppement SPELL_AURA_MECHANIC_IMMUNITY_MASK (mostly boss/elite spells). Note: db stored mechannic masks already stored in proper format so not affected. --- src/game/SharedDefines.h | 31 ++++++++---- src/game/Spell.cpp | 34 +++++++------ src/game/SpellAuraDefines.h | 2 +- src/game/SpellAuras.cpp | 38 ++++++--------- src/game/SpellAuras.h | 1 + src/game/SpellEffects.cpp | 21 +------- src/game/SpellMgr.cpp | 42 ++++++++++------ src/game/SpellMgr.h | 8 +-- src/game/Unit.cpp | 97 ++++++++++++++++++++++++++----------- src/game/Unit.h | 1 + src/shared/revision_nr.h | 2 +- 11 files changed, 158 insertions(+), 119 deletions(-) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 4acc06d20..37c38c742 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -956,18 +956,31 @@ enum Mechanics // Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6) #define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \ - (1<EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) + if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) school_immune |= uint32(m_spellInfo->EffectMiscValue[i]); - else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) - mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]); - else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) + mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]-1); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY_MASK) + mechanic_immune |= uint32(m_spellInfo->EffectMiscValue[i]); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i])); } // immune movement impairment and loss of control - if(m_spellInfo->Id == 42292) + if (m_spellInfo->Id == 42292) mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; } @@ -4889,33 +4891,33 @@ SpellCastResult Spell::CheckCasterAuras() const SpellCastResult prevented_reason = SPELL_CAST_OK; // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS); // Get unit state - if(unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) + if (unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) prevented_reason = SPELL_FAILED_STUNNED; - else if(unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) + else if (unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) prevented_reason = SPELL_FAILED_CONFUSED; - else if(unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) + else if (unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) prevented_reason = SPELL_FAILED_FLEEING; - else if(unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) prevented_reason = SPELL_FAILED_SILENCED; - else if(unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) + else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) prevented_reason = SPELL_FAILED_PACIFIED; // Attr must make flag drop spell totally immune from all effects - if(prevented_reason != SPELL_CAST_OK) + if (prevented_reason != SPELL_CAST_OK) { - if(school_immune || mechanic_immune || dispel_immune) + if (school_immune || mechanic_immune || dispel_immune) { //Checking auras is needed now, because you are prevented by some state but the spell grants immunity. Unit::AuraMap const& auras = m_caster->GetAuras(); for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if(itr->second) + if (itr->second) { - if( GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune ) + if (GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune) continue; - if( GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune ) + if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune) continue; - if( (1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) + if ((1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) continue; // Make a second check for spell failed so the right SPELL_FAILED message is returned. diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 10b4fd3e5..2700d1d2f 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -189,7 +189,7 @@ enum AuraType SPELL_AURA_SAFE_FALL = 144, SPELL_AURA_MOD_PET_TALENT_POINTS = 145, SPELL_AURA_ALLOW_TAME_PET_TYPE = 146, - SPELL_AURA_ADD_CREATURE_IMMUNITY = 147, + SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147, SPELL_AURA_RETAIN_COMBO_POINTS = 148, SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index a142e2423..43f9e5a5c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -197,7 +197,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraSafeFall, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes &Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS &Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE - &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY + &Aura::HandleModMechanicImmunityMask, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY implemented in Unit::IsImmunedToSpell and Unit::IsImmunedToSpellEffect (check part) &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT @@ -2887,7 +2887,8 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real) // If spell that caused this aura has Croud Control or Daze effect if((aurMechMask & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) || // some Daze spells have these parameters instead of MECHANIC_DAZE (skip snare spells) - aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0 && (aurMechMask & (1 << MECHANIC_SNARE))==0) + aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0 && + (aurMechMask & (1 << (MECHANIC_SNARE-1)))==0) { ++iter; continue; @@ -4171,32 +4172,13 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/) if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) { - uint32 mechanic = 1 << misc; + uint32 mechanic = 1 << (misc-1); //immune movement impairment and loss of control if(GetId()==42292 || GetId()==59752) mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK; - Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) - { - next = iter; - ++next; - SpellEntry const *spell = iter->second->GetSpellProto(); - if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) && // spells unaffected by invulnerability - spell->Id != GetId()) - { - //check for mechanic mask - if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic) - { - m_target->RemoveAurasDueToSpell(spell->Id); - if(Auras.empty()) - break; - else - next = Auras.begin(); - } - } - } + m_target->RemoveAurasAtMechanicImmunity(mechanic,GetId()); } m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,misc,apply); @@ -4224,6 +4206,16 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/) } } +void Aura::HandleModMechanicImmunityMask(bool apply, bool /*Real*/) +{ + uint32 mechanic = m_modifier.m_miscvalue; + + if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) + m_target->RemoveAurasAtMechanicImmunity(mechanic,GetId()); + + // check implemented in Unit::IsImmunedToSpell and Unit::IsImmunedToSpellEffect +} + //this method is called whenever we add / remove aura which gives m_target some imunity to some spell effect void Aura::HandleAuraModEffectImmunity(bool apply, bool /*Real*/) { diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 397338227..0695271e7 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -159,6 +159,7 @@ class MANGOS_DLL_SPEC Aura void HandleFarSight(bool Apply, bool Real); void HandleModPossessPet(bool Apply, bool Real); void HandleModMechanicImmunity(bool Apply, bool Real); + void HandleModMechanicImmunityMask(bool Apply, bool Real); void HandleAuraModSkill(bool Apply, bool Real); void HandleModDamagePercentDone(bool Apply, bool Real); void HandleModPercentStat(bool Apply, bool Real); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 96b1e6252..db09186e1 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4989,26 +4989,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) if(!unitTarget) return; // Removes snares and roots. - uint32 mechanic_mask = (1<GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) - { - next = iter; - ++next; - Aura *aur = iter->second; - if (!aur->IsPositive()) //only remove negative spells - { - // check for mechanic mask - if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) - { - unitTarget->RemoveAurasDueToSpell(aur->GetId()); - if(Auras.empty()) - break; - else - next = Auras.begin(); - } - } - } + unitTarget->RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK,30918,true); break; } // Flame Crash diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index a91ca0302..7fc30c697 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -3309,23 +3309,33 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto // Get by mechanic uint32 mechanic = GetAllSpellMechanicMask(spellproto); - if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE; - if (mechanic & ((1<Mechanic) - mask |= 1<Mechanic; + mask |= 1 << (spellInfo->Mechanic - 1); if (spellInfo->EffectMechanic[effect]) - mask |= 1<EffectMechanic[effect]; + mask |= 1 << (spellInfo->EffectMechanic[effect] - 1); return mask; } @@ -398,10 +398,10 @@ inline uint32 GetAllSpellMechanicMask(SpellEntry const* spellInfo) { uint32 mask = 0; if (spellInfo->Mechanic) - mask |= 1<Mechanic; + mask |= 1 << (spellInfo->Mechanic - 1); for (int i=0; i< 3; ++i) if (spellInfo->EffectMechanic[i]) - mask |= 1<EffectMechanic[i]; + mask |= 1 << (spellInfo->EffectMechanic[i]-1); return mask; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 23c0cac95..7e6f7f900 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4078,10 +4078,13 @@ void Unit::RemoveArenaAuras(bool onleave) // used to remove positive visible auras in arenas for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) { - if ( !(iter->second->GetSpellProto()->AttributesEx4 & (1<<21)) // don't remove stances, shadowform, pally/hunter auras - && !iter->second->IsPassive() // don't remove passive auras - && (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable) - && (iter->second->IsPositive() != onleave)) // remove positive buffs on enter, negative buffs on leave + if (!(iter->second->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_UNK21) && + // don't remove stances, shadowform, pally/hunter auras + !iter->second->IsPassive() && // don't remove passive auras + (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || + !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) && + // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable) + (iter->second->IsPositive() != onleave)) // remove positive buffs on enter, negative buffs on leave RemoveAura(iter); else ++iter; @@ -5191,7 +5194,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) return false; // Need stun or root mechanic - if (!(GetAllSpellMechanicMask(procSpell) & ((1<Id) @@ -6355,7 +6358,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) return false; // Need snare or root mechanic - if (!(GetAllSpellMechanicMask(procSpell) & ((1<GetAurasByType(SPELL_AURA_MOD_HEALING); for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i) - if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0) + if ((*i)->GetModifier()->m_miscvalue & schoolMask) AdvertisedBenefit += (*i)->GetModifier()->m_amount; + return AdvertisedBenefit; } @@ -8974,13 +8978,13 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask) //If m_immuneToSchool type contain this school type, IMMUNE damage. SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) - if(itr->type & shoolMask) + if (itr->type & shoolMask) return true; //If m_immuneToDamage type contain magic, IMMUNE damage. SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE]; for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr) - if(itr->type & shoolMask) + if (itr->type & shoolMask) return true; return false; @@ -8996,26 +9000,30 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo) SpellImmuneList const& dispelList = m_spellImmune[IMMUNITY_DISPEL]; for(SpellImmuneList::const_iterator itr = dispelList.begin(); itr != dispelList.end(); ++itr) - if(itr->type == spellInfo->Dispel) + if (itr->type == spellInfo->Dispel) return true; - if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity + if (!(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)) // can remove immune (by dispell or immune it) { SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL]; for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr) - if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) && - (itr->type & GetSpellSchoolMask(spellInfo)) ) + if (!(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) && + (itr->type & GetSpellSchoolMask(spellInfo))) return true; } - SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; - for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + if(uint32 mechanic = spellInfo->Mechanic) { - if(itr->type == spellInfo->Mechanic) - { - return true; - } + SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; + for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + if (itr->type == mechanic) + return true; + + AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MECHANIC_IMMUNITY_MASK); + for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter) + if ((*iter)->GetModifier()->m_miscvalue & (1 << (mechanic-1))) + return true; } return false; @@ -9027,14 +9035,19 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con uint32 effect = spellInfo->Effect[index]; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr) - if(itr->type == effect) + if (itr->type == effect) return true; if(uint32 mechanic = spellInfo->EffectMechanic[index]) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) - if(itr->type == mechanic) + if (itr->type == mechanic) + return true; + + AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MECHANIC_IMMUNITY_MASK); + for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter) + if ((*iter)->GetModifier()->m_miscvalue & (1 << (mechanic-1))) return true; } @@ -9042,8 +9055,9 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con { SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE]; for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) - if(itr->type == aura) + if (itr->type == aura) return true; + // Check for immune to application of harmful magical effects AuraList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL); for(AuraList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter) @@ -9058,13 +9072,13 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const { - if(!spellInfo) + if (!spellInfo) return false; uint32 family = spellInfo->SpellFamilyName; uint64 flags = spellInfo->SpellFamilyFlags; - if((family == 5 && flags == 256) || //Searing Pain + if ((family == 5 && flags == 256) || //Searing Pain (family == 6 && flags == 8192) || //Mind Blast (family == 11 && flags == 1048576)) //Earth Shock return true; @@ -9074,10 +9088,10 @@ bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack) { - if(!pVictim) + if (!pVictim) return pdamage; - if(pdamage == 0) + if (pdamage == 0) return pdamage; // differentiate for weapon damage based spells @@ -9089,7 +9103,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att // Shred also have bonus as MECHANIC_BLEED damages if (spellProto && spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000)) - mechanicMask |= (1 << MECHANIC_BLEED); + mechanicMask |= (1 << (MECHANIC_BLEED-1)); // FLAT damage bonus auras @@ -12416,6 +12430,31 @@ void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) } } +void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive /*= false*/) +{ + Unit::AuraMap& auras = GetAuras(); + for(Unit::AuraMap::iterator iter = auras.begin(); iter != auras.end();) + { + SpellEntry const *spell = iter->second->GetSpellProto(); + if (spell->Id == exceptSpellId) + ++iter; + else if (non_positive && iter->second->IsPositive()) + ++iter; + else if (spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) + ++iter; + else if (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechMask) + { + RemoveAurasDueToSpell(spell->Id); + if(auras.empty()) + break; + else + iter = auras.begin(); + } + else + ++iter; + } +} + void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) { if(newPhaseMask==GetPhaseMask()) diff --git a/src/game/Unit.h b/src/game/Unit.h index 72017fc1b..b1787d6f7 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1214,6 +1214,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void RemoveAurasDueToSpellByCancel(uint32 spellId); void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); + void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false); void RemoveSpellsCausingAura(AuraType auraType); void RemoveRankAurasDueToSpell(uint32 spellId); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c221ea49d..15117dd98 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8648" + #define REVISION_NR "8649" #endif // __REVISION_NR_H__ From adcfd1e078a75d87a137f67436a80d34ade05091 Mon Sep 17 00:00:00 2001 From: laise Date: Fri, 16 Oct 2009 06:08:47 +0400 Subject: [PATCH 07/13] [8650] Allow stacking some paladin spell auras. Signed-off-by: VladimirMangos --- src/game/SpellMgr.cpp | 4 ++++ src/shared/revision_nr.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 7fc30c697..8df296ca2 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1633,6 +1633,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons // Beacon of Light and Light's Beacon if ((spellInfo_1->SpellIconID == 3032) && (spellInfo_2->SpellIconID == 3032)) return false; + + // Concentration Aura and Improved Concentration Aura and Aura Mastery + if ((spellInfo_1->SpellIconID == 1487) && (spellInfo_2->SpellIconID == 1487)) + return false; } // Combustion and Fire Protection Aura (multi-family check) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 15117dd98..d2bc5fe85 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8649" + #define REVISION_NR "8650" #endif // __REVISION_NR_H__ From cf7ec4c4565ac6a243bc5b4aa8ad6c37f0bf4c3c Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 16 Oct 2009 17:49:20 +0400 Subject: [PATCH 08/13] [8651] Not send unexpected reply whisper to sender for addon messages. Thanks to Leo9@mangos.lighthouseapp.com for provided client side testing addons. --- src/game/Player.cpp | 10 +++++++--- src/shared/revision_nr.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f92bb4cf0..18c49c03e 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -16564,9 +16564,13 @@ void Player::Whisper(const std::string& text, uint32 language,uint64 receiver) BuildPlayerChat(&data, CHAT_MSG_WHISPER, text, language); rPlayer->GetSession()->SendPacket(&data); - data.Initialize(SMSG_MESSAGECHAT, 200); - rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language); - GetSession()->SendPacket(&data); + // not send confirmation for addon messages + if (language != LANG_ADDON) + { + data.Initialize(SMSG_MESSAGECHAT, 200); + rPlayer->BuildPlayerChat(&data, CHAT_MSG_REPLY, text, language); + GetSession()->SendPacket(&data); + } } else { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d2bc5fe85..47a0b1968 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8650" + #define REVISION_NR "8651" #endif // __REVISION_NR_H__ From 40b0612dfca2102c584a2b885f395c576f4b2305 Mon Sep 17 00:00:00 2001 From: ApoC Date: Fri, 16 Oct 2009 20:41:39 +0200 Subject: [PATCH 09/13] [8652] Lock typo fixed. Signed-off-by: ApoC --- src/game/ObjectAccessor.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 9604eee8f..0f1d23608 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -175,7 +175,7 @@ ObjectAccessor::FindPlayerByName(const char *name) void ObjectAccessor::SaveAllPlayers() { - Guard guard(*HashMapHolder::GetLock()); + Guard guard(*HashMapHolder::GetLock()); HashMapHolder::MapType& m = HashMapHolder::GetContainer(); HashMapHolder::MapType::iterator itr = m.begin(); for(; itr != m.end(); ++itr) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 47a0b1968..be7649255 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8651" + #define REVISION_NR "8652" #endif // __REVISION_NR_H__ From 45c9c136baf19086d7dee59b186bc0da3498d951 Mon Sep 17 00:00:00 2001 From: ApoC Date: Fri, 16 Oct 2009 20:11:00 +0200 Subject: [PATCH 10/13] [8653] Implemented per map guids store. This patch implements storing guid->object pairs on per map level, this leads to less locking in ObjectAccessor in case of further multithreaded map update. For case of cross map guid looking (auras cases) all maps are linked into ObjectAccessor and can be traversed for this lookup. Signed-off-by: ApoC --- src/framework/GameSystem/TypeContainer.h | 106 +++++++++++++++++++++++ src/game/BattleGroundAB.cpp | 1 + src/game/BattleGroundEY.cpp | 1 + src/game/BattleGroundWS.cpp | 1 + src/game/Creature.cpp | 8 +- src/game/DynamicObject.cpp | 4 +- src/game/GameObject.cpp | 39 ++++----- src/game/GameObject.h | 1 - src/game/GridDefines.h | 2 + src/game/Map.cpp | 75 ++++++++-------- src/game/Map.h | 7 ++ src/game/ObjectAccessor.cpp | 24 +++-- src/game/ObjectAccessor.h | 92 +++++++++++++++----- src/game/Pet.cpp | 11 +-- src/game/Player.cpp | 2 +- src/game/Unit.cpp | 2 +- src/game/Vehicle.cpp | 10 ++- src/shared/revision_nr.h | 2 +- 18 files changed, 272 insertions(+), 116 deletions(-) diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h index 894027c2f..2b46ff67b 100644 --- a/src/framework/GameSystem/TypeContainer.h +++ b/src/framework/GameSystem/TypeContainer.h @@ -28,8 +28,114 @@ #include #include "Platform/Define.h" #include "Utilities/TypeList.h" +#include "Utilities/UnorderedMap.h" #include "GameSystem/GridRefManager.h" +template struct ContainerUnorderedMap +{ + UNORDERED_MAP _element; +}; +template struct ContainerUnorderedMap +{ +}; +template struct ContainerUnorderedMap< TypeList, KEY_TYPE > +{ + ContainerUnorderedMap _elements; + ContainerUnorderedMap _TailElements; +}; + +template +class TypeUnorderedMapContainer +{ + public: + template bool insert(KEY_TYPE handle, SPECIFIC_TYPE* obj) + { + return TypeUnorderedMapContainer::insert(i_elements, handle, obj); + } + template bool erase(KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/) + { + return TypeUnorderedMapContainer::erase(i_elements, handle, (SPECIFIC_TYPE*)NULL); + } + template SPECIFIC_TYPE* find(KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) + { + return TypeUnorderedMapContainer::find(i_elements, hdl, (SPECIFIC_TYPE*)NULL); + } + private: + ContainerUnorderedMap i_elements; + + // Helpers + // Insert helpers + template static bool insert(ContainerUnorderedMap& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj) + { + typename UNORDERED_MAP::iterator i = elements._element.find(handle); + if (i == elements._element.end()) + { + elements._element[handle] = obj; + return true; + } + else + { + assert (i->second == obj && "Object with certain key already in but objects are different!"); + return false; + } + } + template static bool insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool insert(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool insert(ContainerUnorderedMap< TypeList, KEY_TYPE >& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj) + { + bool ret = TypeUnorderedMapContainer::insert(elements._elements, handle, obj); + return ret ? ret : TypeUnorderedMapContainer::insert(elements._TailElements, handle, obj); + } + // Find helpers + template static SPECIFIC_TYPE* find(ContainerUnorderedMap& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) + { + typename UNORDERED_MAP::iterator i = elements._element.find(hdl); + if (i == elements._element.end()) + return NULL; + else + return i->second; + } + template static SPECIFIC_TYPE* find(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/) + { + return NULL; + } + template static SPECIFIC_TYPE* find(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*hdl*/, SPECIFIC_TYPE* /*obj*/) + { + return NULL; + } + template static SPECIFIC_TYPE* find(ContainerUnorderedMap< TypeList, KEY_TYPE >& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/) + { + SPECIFIC_TYPE* ret = TypeUnorderedMapContainer::find(elements._elements, hdl, (SPECIFIC_TYPE*)NULL); + return ret ? ret : TypeUnorderedMapContainer::find(elements._TailElements, hdl, (SPECIFIC_TYPE*)NULL); + } + // Erase helpers + template static bool erase(ContainerUnorderedMap& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/) + { + elements._element.erase(handle); + + return true; + } + template static bool erase(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool erase(ContainerUnorderedMap& /*elements*/, KEY_TYPE /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + template static bool erase(ContainerUnorderedMap< TypeList, KEY_TYPE >& elements, KEY_TYPE handle, SPECIFIC_TYPE* /*obj*/) + { + bool ret = TypeUnorderedMapContainer::erase(elements._elements, handle, (SPECIFIC_TYPE*)NULL); + return ret ? ret : TypeUnorderedMapContainer::erase(elements._TailElements, handle, (SPECIFIC_TYPE*)NULL); + } +}; + /* * @class ContainerMapList is a mulit-type container for map elements * By itself its meaningless but collaborate along with TypeContainers, diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index ad485cdb8..8a7ed49e8 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -26,6 +26,7 @@ #include "Language.h" #include "Util.h" #include "WorldPacket.h" +#include "MapManager.h" BattleGroundAB::BattleGroundAB() { diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index f3ef573f2..cab99dec5 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -26,6 +26,7 @@ #include "Language.h" #include "WorldPacket.h" #include "Util.h" +#include "MapManager.h" BattleGroundEY::BattleGroundEY() { diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp index 296e79875..c4ad4efbd 100644 --- a/src/game/BattleGroundWS.cpp +++ b/src/game/BattleGroundWS.cpp @@ -26,6 +26,7 @@ #include "BattleGroundMgr.h" #include "WorldPacket.h" #include "Language.h" +#include "MapManager.h" BattleGroundWS::BattleGroundWS() { diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index b9ce2442a..fc2ab843b 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -141,14 +141,18 @@ Creature::~Creature() void Creature::AddToWorld() { ///- Register the creature for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (Creature*)this); + Unit::AddToWorld(); } void Creature::RemoveFromWorld() { ///- Remove the creature from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + if(IsInWorld()) + GetMap()->GetObjectsStore().erase(GetGUID(), (Creature*)NULL); + Unit::RemoveFromWorld(); } diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 92db7e25b..f6bbaf742 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -41,7 +41,7 @@ void DynamicObject::AddToWorld() { ///- Register the dynamicObject for guid lookup if(!IsInWorld()) - ObjectAccessor::Instance().AddObject(this); + GetMap()->GetObjectsStore().insert(GetGUID(), (DynamicObject*)this); Object::AddToWorld(); } @@ -50,7 +50,7 @@ void DynamicObject::RemoveFromWorld() { ///- Remove the dynamicObject from the accessor if(IsInWorld()) - ObjectAccessor::Instance().RemoveObject(this); + GetMap()->GetObjectsStore().erase(GetGUID(), (DynamicObject*)NULL); Object::RemoveFromWorld(); } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index c7d1829a7..ac068fef3 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -60,23 +60,26 @@ GameObject::GameObject() : WorldObject() GameObject::~GameObject() { - CleanupsBeforeDelete(); } -void GameObject::CleanupsBeforeDelete() +void GameObject::AddToWorld() { - if(m_uint32Values) // field array can be not exist if GameOBject not loaded + ///- Register the gameobject for guid lookup + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (GameObject*)this); + + Object::AddToWorld(); +} + +void GameObject::RemoveFromWorld() +{ + ///- Remove the gameobject from the accessor + if(IsInWorld()) { - // Possible crash at access to deleted GO in Unit::m_gameobj + // Remove GO from owner if(uint64 owner_guid = GetOwnerGUID()) { - Unit* owner = NULL; - if(IS_PLAYER_GUID(owner_guid)) - owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL); - else - owner = ObjectAccessor::GetUnit(*this,owner_guid); - - if(owner) + if (Unit* owner = IS_PLAYER_GUID(owner_guid) ? ObjectAccessor::FindPlayer(owner_guid) : GetMap()->GetCreatureOrPet(owner_guid)) owner->RemoveGameObject(this,false); else { @@ -90,20 +93,10 @@ void GameObject::CleanupsBeforeDelete() GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType); } } + + GetMap()->GetObjectsStore().erase(GetGUID(), (GameObject*)NULL); } -} -void GameObject::AddToWorld() -{ - ///- Register the gameobject for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); - Object::AddToWorld(); -} - -void GameObject::RemoveFromWorld() -{ - ///- Remove the gameobject from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); Object::RemoveFromWorld(); } diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 06ebfa278..db0a49665 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -559,7 +559,6 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject void AddToWorld(); void RemoveFromWorld(); - void CleanupsBeforeDelete(); bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state); void Update(uint32 p_time); diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h index 7d57814fb..ebfbf20dd 100644 --- a/src/game/GridDefines.h +++ b/src/game/GridDefines.h @@ -26,6 +26,7 @@ // Forward class definitions class Corpse; class Creature; +class Vehicle; class DynamicObject; class GameObject; class Pet; @@ -57,6 +58,7 @@ class Player; // Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) typedef TYPELIST_3(Player, Creature/*pets*/, Corpse/*resurrectable*/) AllWorldObjectTypes; typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes; +typedef TYPELIST_5(Creature, Pet, Vehicle, GameObject, DynamicObject) AllMapStoredObjectTypes; typedef GridRefManager CorpseMapType; typedef GridRefManager CreatureMapType; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 52a57efaf..4abed7b57 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -56,6 +56,7 @@ struct ScriptAction Map::~Map() { + ObjectAccessor::DelinkMap(this); UnloadAll(true); if(!m_scriptSchedule.empty()) @@ -212,6 +213,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par setNGrid(NULL, idx, j); } } + ObjectAccessor::LinkMap(this); //lets initialize visibility distance for map Map::InitVisibilityDistance(); @@ -2761,19 +2763,19 @@ void Map::ScriptsProcess() break; } case HIGHGUID_UNIT: - source = HashMapHolder::Find(step.sourceGUID); + source = GetCreature(step.sourceGUID); break; case HIGHGUID_PET: - source = HashMapHolder::Find(step.sourceGUID); + source = GetPet(step.sourceGUID); break; case HIGHGUID_VEHICLE: - source = HashMapHolder::Find(step.sourceGUID); + source = GetVehicle(step.sourceGUID); break; case HIGHGUID_PLAYER: source = HashMapHolder::Find(step.sourceGUID); break; case HIGHGUID_GAMEOBJECT: - source = HashMapHolder::Find(step.sourceGUID); + source = GetGameObject(step.sourceGUID); break; case HIGHGUID_CORPSE: source = HashMapHolder::Find(step.sourceGUID); @@ -2793,19 +2795,19 @@ void Map::ScriptsProcess() switch(GUID_HIPART(step.targetGUID)) { case HIGHGUID_UNIT: - target = HashMapHolder::Find(step.targetGUID); + target = GetCreature(step.targetGUID); break; case HIGHGUID_PET: - target = HashMapHolder::Find(step.targetGUID); + target = GetPet(step.targetGUID); break; case HIGHGUID_VEHICLE: - target = HashMapHolder::Find(step.targetGUID); + target = GetVehicle(step.targetGUID); break; case HIGHGUID_PLAYER: // empty GUID case also target = HashMapHolder::Find(step.targetGUID); break; case HIGHGUID_GAMEOBJECT: - target = HashMapHolder::Find(step.targetGUID); + target = GetGameObject(step.targetGUID); break; case HIGHGUID_CORPSE: target = HashMapHolder::Find(step.targetGUID); @@ -3381,44 +3383,35 @@ void Map::ScriptsProcess() return; } -Creature* -Map::GetCreature(uint64 guid) +Creature* Map::GetCreature(uint64 guid) { - Creature * ret = ObjectAccessor::GetObjectInWorld(guid, (Creature*)NULL); - if(!ret) - return NULL; - - if(ret->GetMapId() != GetId()) - return NULL; - - if(ret->GetInstanceId() != GetInstanceId()) - return NULL; - - return ret; + return m_objectsStore.find(guid, (Creature*)NULL); } -GameObject* -Map::GetGameObject(uint64 guid) +Vehicle* Map::GetVehicle(uint64 guid) { - GameObject * ret = ObjectAccessor::GetObjectInWorld(guid, (GameObject*)NULL); - if(!ret) - return NULL; - if(ret->GetMapId() != GetId()) - return NULL; - if(ret->GetInstanceId() != GetInstanceId()) - return NULL; - return ret; + return m_objectsStore.find(guid, (Vehicle*)NULL); } -DynamicObject* -Map::GetDynamicObject(uint64 guid) +Pet* Map::GetPet(uint64 guid) { - DynamicObject * ret = ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL); - if(!ret) - return NULL; - if(ret->GetMapId() != GetId()) - return NULL; - if(ret->GetInstanceId() != GetInstanceId()) - return NULL; - return ret; + return m_objectsStore.find(guid, (Pet*)NULL); +} + +Unit* Map::GetCreatureOrPet(uint64 guid) +{ + if (Unit* ret = GetCreature(guid)) + return ret; + + return GetPet(guid); +} + +GameObject* Map::GetGameObject(uint64 guid) +{ + return m_objectsStore.find(guid, (GameObject*)NULL); +} + +DynamicObject* Map::GetDynamicObject(uint64 guid) +{ + return m_objectsStore.find(guid, (DynamicObject*)NULL); } diff --git a/src/game/Map.h b/src/game/Map.h index c867a31d5..a50a3e1f4 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -32,6 +32,7 @@ #include "SharedDefines.h" #include "GameSystem/GridRefManager.h" #include "MapRefManager.h" +#include "Utilities/TypeList.h" #include #include @@ -420,8 +421,13 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj void RemoveFromActive(Creature* obj); Creature* GetCreature(uint64 guid); + Vehicle* GetVehicle(uint64 guid); + Pet* GetPet(uint64 guid); + Unit* GetCreatureOrPet(uint64 guid); GameObject* GetGameObject(uint64 guid); DynamicObject* GetDynamicObject(uint64 guid); + + TypeUnorderedMapContainer& GetObjectsStore() { return m_objectsStore; } private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -484,6 +490,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj typedef std::set ActiveNonPlayers; ActiveNonPlayers m_activeNonPlayers; ActiveNonPlayers::iterator m_activeNonPlayersIter; + TypeUnorderedMapContainer m_objectsStore; private: time_t i_gridExpiry; diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 0f1d23608..1eb61903e 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -53,16 +53,16 @@ ObjectAccessor::~ObjectAccessor() Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) { - if(IS_PLAYER_GUID(guid)) + if(IS_PLAYER_GUID(guid) || !u.IsInWorld()) return NULL; if(IS_PET_GUID(guid)) - return GetPet(guid); + return u.GetMap()->GetPet(guid); if(IS_VEHICLE_GUID(guid)) - return GetVehicle(guid); + return u.GetMap()->GetVehicle(guid); - return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL; + return u.GetMap()->GetCreature(guid); } Unit* @@ -97,8 +97,8 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const &p, uint64 guid) case HIGHGUID_PLAYER: return FindPlayer(guid); case HIGHGUID_GAMEOBJECT: return p.GetMap()->GetGameObject(guid); case HIGHGUID_UNIT: return p.GetMap()->GetCreature(guid); - case HIGHGUID_PET: return GetPet(guid); - case HIGHGUID_VEHICLE: return GetVehicle(guid); + case HIGHGUID_PET: return p.GetMap()->GetPet(guid); + case HIGHGUID_VEHICLE: return p.GetMap()->GetVehicle(guid); case HIGHGUID_DYNAMICOBJECT:return p.GetMap()->GetDynamicObject(guid); case HIGHGUID_TRANSPORT: return NULL; case HIGHGUID_CORPSE: return GetCorpse(p,guid); @@ -131,11 +131,11 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, u break; case HIGHGUID_PET: if(typemask & TYPEMASK_UNIT) - return GetPet(guid); + return p.GetMap()->GetPet(guid); break; case HIGHGUID_VEHICLE: if(typemask & TYPEMASK_UNIT) - return GetVehicle(guid); + return p.GetMap()->GetVehicle(guid); break; case HIGHGUID_DYNAMICOBJECT: if(typemask & TYPEMASK_DYNAMICOBJECT) @@ -416,13 +416,11 @@ template ACE_Thread_Mutex HashMapHolder::i_lock; /// Global definitions for the hashmap storage template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; -template class HashMapHolder; template class HashMapHolder; +/// Define the static member of ObjectAccessor +std::list ObjectAccessor::i_mapList; + template Player* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/); template Pet* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); template Vehicle* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index e77b5abeb..0de531c0d 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -32,6 +32,7 @@ #include "Player.h" #include +#include class Creature; class Corpse; @@ -95,29 +96,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Find(guid); } - static Unit* GetObjectInWorld(uint64 guid, Unit* /*fake*/) - { - if(!guid) - return NULL; - - if (IS_PLAYER_GUID(guid)) - { - Unit * u = (Unit*)HashMapHolder::Find(guid); - if(!u || !u->IsInWorld()) - return NULL; - - return u; - } - - if (IS_PET_GUID(guid)) - return (Unit*)HashMapHolder::Find(guid); - - return (Unit*)HashMapHolder::Find(guid); - } - template static T* GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, T* /*fake*/) { - T* obj = HashMapHolder::Find(guid); + T* obj = GetObjectInWorld(guid, (T*)NULL); if(!obj || obj->GetMapId() != mapid) return NULL; CellPair p = MaNGOS::ComputeCellPair(x,y); @@ -201,6 +182,9 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton void Visit(GridRefManager &) {} }; + // TODO: This methods will need lock in MT environment + // Theoreticaly multiple threads can enter and search in this method but + // in that case linking/delinking other map should be guarded + template static OBJECT* FindHelper(uint64 guid) + { + OBJECT* ret = NULL; + std::list::const_iterator i = i_mapList.begin(); + while (i != i_mapList.end() && !ret) + { + ret = (*i)->GetObjectsStore().find(guid, (OBJECT*)NULL); + ++i; + } + + return ret; + } + + static std::list i_mapList; + friend struct WorldObjectChangeAccumulator; Player2CorpsesMapType i_player2corpse; @@ -223,6 +225,52 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton static inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/) +{ + return FindHelper(guid); +} + +template <> static inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/) +{ + return FindHelper(guid); +} + +template <> static inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/) +{ + return FindHelper(guid); +} + +template <> static inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/) +{ + return FindHelper(guid); +} + +template <> static inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) +{ + return FindHelper(guid); +} + +template <> static inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/) +{ + if(!guid) + return NULL; + + if (IS_PLAYER_GUID(guid)) + { + Unit * u = (Unit*)HashMapHolder::Find(guid); + if(!u || !u->IsInWorld()) + return NULL; + + return u; + } + + if (IS_PET_GUID(guid)) + return (Unit*)GetObjectInWorld(guid, (Pet*)NULL); + + return (Unit*)GetObjectInWorld(guid, (Creature*)NULL); +} + #endif diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 3581c456f..d1765c092 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -57,23 +57,24 @@ m_declinedname(NULL) Pet::~Pet() { - if(m_uint32Values) // only for fully created Object - ObjectAccessor::Instance().RemoveObject(this); - delete m_declinedname; } void Pet::AddToWorld() { ///- Register the pet for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (Pet*)this); + Unit::AddToWorld(); } void Pet::RemoveFromWorld() { ///- Remove the pet from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + if(IsInWorld()) + GetMap()->GetObjectsStore().erase(GetGUID(), (Pet*)NULL); + ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 18c49c03e..e6fd665d1 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18821,7 +18821,7 @@ void Player::UpdateForQuestWorldObjects() { if(IS_GAMEOBJECT_GUID(*itr)) { - GameObject *obj = HashMapHolder::Find(*itr); + GameObject *obj = GetMap()->GetGameObject(*itr); if(obj) obj->BuildValuesUpdateBlockForPlayer(&udata,this); } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 7e6f7f900..b28159b2b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11736,7 +11736,7 @@ void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint3 GetMotionMaster()->Initialize(); // attack caster if can - Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL); + Unit* caster = Unit::GetUnit(*this, casterGUID); if(caster && ((Creature*)this)->AI()) ((Creature*)this)->AI()->AttackedBy(caster); } diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index 5c5fad437..d856d3657 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -31,21 +31,23 @@ Vehicle::Vehicle() : Creature(), m_vehicleId(0) Vehicle::~Vehicle() { - if(m_uint32Values) // only for fully created Object - ObjectAccessor::Instance().RemoveObject(this); } void Vehicle::AddToWorld() { ///- Register the vehicle for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); + if(!IsInWorld()) + GetMap()->GetObjectsStore().insert(GetGUID(), (Vehicle*)this); + Unit::AddToWorld(); } void Vehicle::RemoveFromWorld() { ///- Remove the vehicle from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); + if(IsInWorld()) + GetMap()->GetObjectsStore().erase(GetGUID(), (Vehicle*)NULL); + ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index be7649255..0b9a2b860 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8652" + #define REVISION_NR "8653" #endif // __REVISION_NR_H__ From bc1f6c7d3f1611d679dc2a5ed237308d12c5eccd Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 17 Oct 2009 02:08:41 +0400 Subject: [PATCH 11/13] [8654] Allow loading some type gameobjects without diplay id set. But make its always inviisble for client. --- src/game/GameObject.cpp | 4 ++++ src/game/ObjectMgr.cpp | 15 +++++++++++---- src/shared/revision_nr.h | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index ac068fef3..e5253fae5 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -693,6 +693,10 @@ bool GameObject::isVisibleForInState(Player const* u, WorldObject const* viewPoi if(!IsInWorld() || !u->IsInWorld()) return false; + // invisible at client always + if(!GetGOInfo()->displayId) + return false; + // Transport always visible at this step implementation if(IsTransport() && IsInMap(u)) return true; diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 8c3e089aa..22a46ae1f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1228,11 +1228,18 @@ void ObjectMgr::LoadGameobjects() if(!gInfo->displayId) { - sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) doesn't have displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId); - continue; + switch(gInfo->type) + { + // can be invisible always and then not req. display id in like case + case GAMEOBJECT_TYPE_TRAP: + case GAMEOBJECT_TYPE_SPELL_FOCUS: + break; + default: + sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have displayId == 0 and then will always invisible in game.", guid, entry, gInfo->type); + break; + } } - - if (gInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) + else if (!sGameObjectDisplayInfoStore.LookupEntry(gInfo->displayId)) { sLog.outErrorDb("Gameobject (GUID: %u Entry %u GoType: %u) have invalid displayId (%u), not loaded.", guid, entry, gInfo->type, gInfo->displayId); continue; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0b9a2b860..30f1b2d6f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8653" + #define REVISION_NR "8654" #endif // __REVISION_NR_H__ From 29444467a956ab1a0927ab4b6183eb8a9bc70758 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 17 Oct 2009 01:02:03 +0400 Subject: [PATCH 12/13] [8655] Remove problematic defines from Common.h Its create conflicts with ACE code. More cleanup need (with replace use ACE_OS function versions but stuck for example still used old sockets libarary. --- src/shared/Common.h | 9 --------- src/shared/revision_nr.h | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/shared/Common.h b/src/shared/Common.h index b6b795e16..1b46bf8c5 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -81,12 +81,6 @@ #include #include -#if PLATFORM == PLATFORM_WINDOWS -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #include #include #include @@ -103,7 +97,6 @@ #include #include - #if PLATFORM == PLATFORM_WINDOWS # define FD_SETSIZE 4096 # include @@ -128,9 +121,7 @@ #define I32FMT "%08I32X" #define I64FMT "%016I64X" #define snprintf _snprintf -#define atoll __atoi64 #define vsnprintf _vsnprintf -#define strdup _strdup #define finite(X) _finite(X) #else diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 30f1b2d6f..16b1aaa90 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8654" + #define REVISION_NR "8655" #endif // __REVISION_NR_H__ From aa42097331cbc252b159131fb60ff607ab83ce8d Mon Sep 17 00:00:00 2001 From: ApoC Date: Sat, 17 Oct 2009 00:29:05 +0200 Subject: [PATCH 13/13] [8656] Removed wrong static keyword. Thx Vladimir for pointing it out. Signed-off-by: ApoC --- src/game/ObjectAccessor.h | 12 ++++++------ src/shared/revision_nr.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 0de531c0d..7f6027dc1 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -228,32 +228,32 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton static inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/) +template <> inline Creature* ObjectAccessor::GetObjectInWorld(uint64 guid, Creature* /*fake*/) { return FindHelper(guid); } -template <> static inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/) +template <> inline GameObject* ObjectAccessor::GetObjectInWorld(uint64 guid, GameObject* /*fake*/) { return FindHelper(guid); } -template <> static inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/) +template <> inline DynamicObject* ObjectAccessor::GetObjectInWorld(uint64 guid, DynamicObject* /*fake*/) { return FindHelper(guid); } -template <> static inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/) +template <> inline Pet* ObjectAccessor::GetObjectInWorld(uint64 guid, Pet* /*fake*/) { return FindHelper(guid); } -template <> static inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) +template <> inline Vehicle* ObjectAccessor::GetObjectInWorld(uint64 guid, Vehicle* /*fake*/) { return FindHelper(guid); } -template <> static inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/) +template <> inline Unit* ObjectAccessor::GetObjectInWorld(uint64 guid, Unit* /*fake*/) { if(!guid) return NULL; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 16b1aaa90..1d5d1cedf 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8655" + #define REVISION_NR "8656" #endif // __REVISION_NR_H__