From 81267151ad3e1ac2bb17a0c8043d8d48105e3f29 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 29 May 2009 21:37:03 +0400 Subject: [PATCH 01/17] [7912] Remove unexpected indent from file tail. Note: not code changes, and then binary not updated. --- src/shared/revision_nr.h | 2 +- src/shared/vmap/TileAssembler.cpp | 798 +++++++++++++++--------------- 2 files changed, 400 insertions(+), 400 deletions(-) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 527d62ebb..f7dc3da91 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 "7911" + #define REVISION_NR "7912" #endif // __REVISION_NR_H__ diff --git a/src/shared/vmap/TileAssembler.cpp b/src/shared/vmap/TileAssembler.cpp index 7c4856251..f3b0d1a0d 100644 --- a/src/shared/vmap/TileAssembler.cpp +++ b/src/shared/vmap/TileAssembler.cpp @@ -171,423 +171,423 @@ namespace VMAP { for(int y=28; y<29 && result; ++y) { - #else - // ignore DeeprunTram (369) it is too large for short vector and not important - // ignore test (13), Test (29) , development (451) - if(mapId != 369 && mapId != 13 && mapId != 29 && mapId != 451) - { - for(int x=0; x<66 && result; ++x) - { - for(int y=0; y<66 && result; ++y) - { - #endif - Array mc; - std::string dirname; - char buffer[100]; - if(iCoordModelMapping->isWorldAreaMap(mapId) && x<65 && y<65) - { - sprintf(buffer, "%03u_%d_%d",mapId,y,x); // Let's flip x and y here - dirname = std::string(buffer); - } - else - { - sprintf(buffer, "%03u",mapId); - dirname = std::string(buffer); - } - result = fillModelContainerArray(dirname, mapId, x, y, mc); - emptyArray(mc); - } - } - } - } - #ifdef _ASSEMBLER_DEBUG - if(::g_df) fclose(::g_df); - #endif - - return result; - } - - //================================================================= - - bool TileAssembler::fillModelContainerArray(const std::string& pDirFileName, unsigned int pMapId, int pXPos, int pYPos, Array& pMC) + #else + // ignore DeeprunTram (369) it is too large for short vector and not important + // ignore test (13), Test (29) , development (451) + if(mapId != 369 && mapId != 13 && mapId != 29 && mapId != 451) + { + for(int x=0; x<66 && result; ++x) { - bool result = true; - ModelContainer* modelContainer; - - NameCollection nameCollection = iCoordModelMapping->getFilenamesForCoordinate(pMapId, pXPos, pYPos); - if(nameCollection.size() > 0) + for(int y=0; y<66 && result; ++y) { - result = false; - char dirfilename[500]; - sprintf(dirfilename,"%s/%s.vmdir",iDestDir.c_str(),pDirFileName.c_str()); - FILE *dirfile = fopen(dirfilename, "ab"); - if(dirfile) + #endif + Array mc; + std::string dirname; + char buffer[100]; + if(iCoordModelMapping->isWorldAreaMap(mapId) && x<65 && y<65) { - result = true; - char destnamebuffer[500]; - char fullnamedestnamebuffer[500]; - if(nameCollection.iMainFiles.size() >0) - { - sprintf(destnamebuffer,"%03u_%i_%i.vmap",pMapId, pYPos, pXPos); // flip it here too - std::string checkDoubleStr = std::string(dirfilename); - checkDoubleStr.append("##"); - checkDoubleStr.append(std::string(destnamebuffer)); - // Check, if same file already is in the same dir file - if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) - { - iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); - fprintf(dirfile, "%s\n",destnamebuffer); - sprintf(fullnamedestnamebuffer,"%s/%s",iDestDir.c_str(),destnamebuffer); - modelContainer = processNames(nameCollection.iMainFiles, fullnamedestnamebuffer); - if(modelContainer) - { - pMC.append(modelContainer); - } - else - { - result = false; - } - } - } - // process the large singe files - int pos = 0; - while(result && (pos < nameCollection.iSingeFiles.size())) - { - std::string destFileName = iDestDir; - destFileName.append("/"); - std::string dirEntryName = getDirEntryNameFromModName(pMapId,nameCollection.iSingeFiles[pos]); - std::string checkDoubleStr = std::string(dirfilename); - checkDoubleStr.append("##"); - checkDoubleStr.append(nameCollection.iSingeFiles[pos]); - // Check, if same file already is in the same dir file - if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) - { - iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); - fprintf(dirfile, "%s\n",dirEntryName.c_str()); - destFileName.append(dirEntryName); - - Array positionarray; - positionarray.append(nameCollection.iSingeFiles[pos]); - - if(!iCoordModelMapping->isAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos])) - { - modelContainer = processNames(positionarray, destFileName.c_str()); - iCoordModelMapping->addAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos]); - if(modelContainer) - { - pMC.append(modelContainer); - } - else - { - result = false; - } - } - } - ++pos; - } - fclose(dirfile); - } - } - return(result); - } - - //================================================================= - - void removeEntriesFromTree(AABSPTree* pTree) - { - Array submodelArray; - pTree->getMembers(submodelArray); - int no = submodelArray.size(); - while(no > 0) - { - --no; - delete submodelArray[no]; - } - } - - //================================================================= - - ModelContainer* TileAssembler::processNames(const Array& pPositions, const char* pDestFileName) - { - ModelContainer *modelContainer = 0; - - Vector3 basepos = Vector3(0,0,0); - AABSPTree* mainTree = new AABSPTree(); - - int pos = 0; - - bool result = true; - while(result && (pos < pPositions.size())) - { - std::string modelPosString = pPositions[pos]; - std::string modelFileName = getModNameFromModPosName(modelPosString); - - if(!fillModelIntoTree(mainTree, basepos, modelPosString, modelFileName)) - { - result = false; - break; - } - ++pos; - } - if(result && mainTree->size() > 0) - { - mainTree->balance(); - modelContainer = new ModelContainer(mainTree); - modelContainer->writeFile(pDestFileName); - } - removeEntriesFromTree(mainTree); - - delete mainTree; - - return(modelContainer); - } - - //================================================================= - bool TileAssembler::readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, AABSPTree *pMainTree) - { - bool result = false; - - std::string filename = iSrcDir; - if(filename.length() >0) - filename.append("/"); - filename.append(pModelFilename); - FILE *rf = fopen(filename.c_str(), "rb"); - if(!rf) - { - // depending on the extractor version, the data could be located in the root dir - std::string baseModelFilename = pModelFilename.substr((pModelFilename.find_first_of("/")+1),pModelFilename.length()); - filename = iSrcDir; - if(filename.length() >0) - filename.append("/"); - filename.append(baseModelFilename); - rf = fopen(filename.c_str(), "rb"); - } - char ident[8]; - - int trianglecount =0; - - #ifdef _ASSEMBLER_DEBUG - int startgroup = 0; //2; - int endgroup = INT_MAX; //2; - fprintf(::g_df,"-------------------------------------------------\n"); - fprintf(::g_df,"%s\n", pModelFilename.c_str()); - fprintf(::g_df,"-------------------------------------------------\n"); - #else - int startgroup = 0; - int endgroup = INT_MAX; - #endif - - // temporary use defines to simplify read/check code (close file and return at fail) - #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); return(false); } - #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); return(false); } - - if(rf) - { - READ_OR_RETURN(&ident, 8); - if(strcmp(ident, "VMAP001") == 0) - { - // OK, do nothing - } - else if(strcmp(ident, "VMAP002") == 0) - { - // we have to read one int. This is needed during the export and we have to skip it here - int tempNVectors; - READ_OR_RETURN(&tempNVectors, sizeof(int)); - + sprintf(buffer, "%03u_%d_%d",mapId,y,x); // Let's flip x and y here + dirname = std::string(buffer); } else { - // wrong version - fclose(rf); - return(false); + sprintf(buffer, "%03u",mapId); + dirname = std::string(buffer); } - G3D::uint32 groups; - char blockId[5]; - blockId[4] = 0; - int blocksize; - READ_OR_RETURN(&groups, sizeof(G3D::uint32)); - - for(int g=0;g<(int)groups;g++) - { - // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...) - Array tempIndexArray; - Array tempVertexArray; - - AABSPTree *gtree = new AABSPTree(); - - // add free gtree at fail - #undef READ_OR_RETURN - #undef CMP_OR_RETURN - #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); delete gtree; return(false); } - #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); delete gtree; return(false); } - - G3D::uint32 flags; - READ_OR_RETURN(&flags, sizeof(G3D::uint32)); - - G3D::uint32 branches; - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "GRP "); - READ_OR_RETURN(&blocksize, sizeof(int)); - READ_OR_RETURN(&branches, sizeof(G3D::uint32)); - for(int b=0;b<(int)branches; b++) - { - G3D::uint32 indexes; - // indexes for each branch (not used jet) - READ_OR_RETURN(&indexes, sizeof(G3D::uint32)); - } - - // ---- indexes - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "INDX"); - READ_OR_RETURN(&blocksize, sizeof(int)); - unsigned int nindexes; - READ_OR_RETURN(&nindexes, sizeof(G3D::uint32)); - if(nindexes >0) - { - unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)]; - READ_OR_RETURN(indexarray, sizeof(unsigned short)); - for(int i=0;i<(int)nindexes; i++) - { - unsigned short val = indexarray[i]; - tempIndexArray.append(val); - } - delete[] indexarray; - } - - // ---- vectors - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "VERT"); - READ_OR_RETURN(&blocksize, sizeof(int)); - unsigned int nvectors; - READ_OR_RETURN(&nvectors, sizeof(int)); - - float *vectorarray = 0; - - // add vectorarray free - #undef READ_OR_RETURN - #undef CMP_OR_RETURN - #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); delete gtree; delete[] vectorarray; return(false); } - #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); delete gtree; delete[] vectorarray; return(false); } - - if(nvectors >0) - { - vectorarray = new float[nvectors*sizeof(float)*3]; - READ_OR_RETURN(vectorarray, sizeof(float)*3); - } - // ----- liquit - if(flags & 1) - { - // we have liquit -> not handled yet ... skip - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "LIQU"); - READ_OR_RETURN(&blocksize, sizeof(int)); - fseek(rf, blocksize, SEEK_CUR); - } - - - for(unsigned int i=0, indexNo=0; indexNo= startgroup && g <= endgroup) - { - gtree->insert(t); - } - } - - // drop of temporary use defines - #undef READ_OR_RETURN - #undef CMP_OR_RETURN - - if(vectorarray != 0) - { - delete vectorarray; - } - - if(gtree->size() >0) - { - gtree->balance(); - SubModel *sm = new SubModel(gtree); - #ifdef _ASSEMBLER_DEBUG - if(::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); - if(sm->getNTriangles() != gtree->memberTable.size()) - { - if(::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); - } - #endif - sm->setBasePosition(pModelPosition.iPos); - pMainTree->insert(sm); - } - delete gtree; - } - fclose(rf); - result = true; + result = fillModelContainerArray(dirname, mapId, x, y, mc); + emptyArray(mc); } - return(result); } + } + } + #ifdef _ASSEMBLER_DEBUG + if(::g_df) fclose(::g_df); + #endif - //================================================================= + return result; + } - bool TileAssembler::fillModelIntoTree(AABSPTree *pMainTree, const Vector3& pBasePos, std::string& pPos, std::string& pModelFilename) + //================================================================= + + bool TileAssembler::fillModelContainerArray(const std::string& pDirFileName, unsigned int pMapId, int pXPos, int pYPos, Array& pMC) + { + bool result = true; + ModelContainer* modelContainer; + + NameCollection nameCollection = iCoordModelMapping->getFilenamesForCoordinate(pMapId, pXPos, pYPos); + if(nameCollection.size() > 0) + { + result = false; + char dirfilename[500]; + sprintf(dirfilename,"%s/%s.vmdir",iDestDir.c_str(),pDirFileName.c_str()); + FILE *dirfile = fopen(dirfilename, "ab"); + if(dirfile) + { + result = true; + char destnamebuffer[500]; + char fullnamedestnamebuffer[500]; + if(nameCollection.iMainFiles.size() >0) { - bool result = false; - ModelPosition modelPosition; - getModelPosition(pPos, modelPosition); - // all should be relative to object base position - modelPosition.moveToBasePos(pBasePos); - - modelPosition.init(); - - if(readRawFile(pModelFilename, modelPosition, pMainTree)) + sprintf(destnamebuffer,"%03u_%i_%i.vmap",pMapId, pYPos, pXPos); // flip it here too + std::string checkDoubleStr = std::string(dirfilename); + checkDoubleStr.append("##"); + checkDoubleStr.append(std::string(destnamebuffer)); + // Check, if same file already is in the same dir file + if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) { - result = true; + iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); + fprintf(dirfile, "%s\n",destnamebuffer); + sprintf(fullnamedestnamebuffer,"%s/%s",iDestDir.c_str(),destnamebuffer); + modelContainer = processNames(nameCollection.iMainFiles, fullnamedestnamebuffer); + if(modelContainer) + { + pMC.append(modelContainer); + } + else + { + result = false; + } } - - return result; } - - //================================================================= - void TileAssembler::getModelPosition(std::string& pPosString, ModelPosition& pModelPosition) + // process the large singe files + int pos = 0; + while(result && (pos < nameCollection.iSingeFiles.size())) { - float vposarray[3]; - float vdirarray[3]; - float scale; + std::string destFileName = iDestDir; + destFileName.append("/"); + std::string dirEntryName = getDirEntryNameFromModName(pMapId,nameCollection.iSingeFiles[pos]); + std::string checkDoubleStr = std::string(dirfilename); + checkDoubleStr.append("##"); + checkDoubleStr.append(nameCollection.iSingeFiles[pos]); + // Check, if same file already is in the same dir file + if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) + { + iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); + fprintf(dirfile, "%s\n",dirEntryName.c_str()); + destFileName.append(dirEntryName); - size_t spos = pPosString.find_first_of('#'); - std::string stripedPosString = pPosString.substr(spos+1,pPosString.length()); - - sscanf(stripedPosString.c_str(), "%f,%f,%f_%f,%f,%f_%f", - &vposarray[0],&vposarray[1],&vposarray[2], - &vdirarray[0],&vdirarray[1],&vdirarray[2], - &scale); - - pModelPosition.iPos = Vector3(vposarray[0], vposarray[1], vposarray[2]); - pModelPosition.iDir = Vector3(vdirarray[0], vdirarray[1], vdirarray[2]); - pModelPosition.iScale = scale; + Array positionarray; + positionarray.append(nameCollection.iSingeFiles[pos]); + if(!iCoordModelMapping->isAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos])) + { + modelContainer = processNames(positionarray, destFileName.c_str()); + iCoordModelMapping->addAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos]); + if(modelContainer) + { + pMC.append(modelContainer); + } + else + { + result = false; + } + } + } + ++pos; } - //========================================== + fclose(dirfile); + } + } + return(result); + } - } // VMAP + //================================================================= + + void removeEntriesFromTree(AABSPTree* pTree) + { + Array submodelArray; + pTree->getMembers(submodelArray); + int no = submodelArray.size(); + while(no > 0) + { + --no; + delete submodelArray[no]; + } + } + + //================================================================= + + ModelContainer* TileAssembler::processNames(const Array& pPositions, const char* pDestFileName) + { + ModelContainer *modelContainer = 0; + + Vector3 basepos = Vector3(0,0,0); + AABSPTree* mainTree = new AABSPTree(); + + int pos = 0; + + bool result = true; + while(result && (pos < pPositions.size())) + { + std::string modelPosString = pPositions[pos]; + std::string modelFileName = getModNameFromModPosName(modelPosString); + + if(!fillModelIntoTree(mainTree, basepos, modelPosString, modelFileName)) + { + result = false; + break; + } + ++pos; + } + if(result && mainTree->size() > 0) + { + mainTree->balance(); + modelContainer = new ModelContainer(mainTree); + modelContainer->writeFile(pDestFileName); + } + removeEntriesFromTree(mainTree); + + delete mainTree; + + return(modelContainer); + } + + //================================================================= + bool TileAssembler::readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, AABSPTree *pMainTree) + { + bool result = false; + + std::string filename = iSrcDir; + if(filename.length() >0) + filename.append("/"); + filename.append(pModelFilename); + FILE *rf = fopen(filename.c_str(), "rb"); + if(!rf) + { + // depending on the extractor version, the data could be located in the root dir + std::string baseModelFilename = pModelFilename.substr((pModelFilename.find_first_of("/")+1),pModelFilename.length()); + filename = iSrcDir; + if(filename.length() >0) + filename.append("/"); + filename.append(baseModelFilename); + rf = fopen(filename.c_str(), "rb"); + } + char ident[8]; + + int trianglecount =0; + + #ifdef _ASSEMBLER_DEBUG + int startgroup = 0; //2; + int endgroup = INT_MAX; //2; + fprintf(::g_df,"-------------------------------------------------\n"); + fprintf(::g_df,"%s\n", pModelFilename.c_str()); + fprintf(::g_df,"-------------------------------------------------\n"); + #else + int startgroup = 0; + int endgroup = INT_MAX; + #endif + + // temporary use defines to simplify read/check code (close file and return at fail) + #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); return(false); } + #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); return(false); } + + if(rf) + { + READ_OR_RETURN(&ident, 8); + if(strcmp(ident, "VMAP001") == 0) + { + // OK, do nothing + } + else if(strcmp(ident, "VMAP002") == 0) + { + // we have to read one int. This is needed during the export and we have to skip it here + int tempNVectors; + READ_OR_RETURN(&tempNVectors, sizeof(int)); + + } + else + { + // wrong version + fclose(rf); + return(false); + } + G3D::uint32 groups; + char blockId[5]; + blockId[4] = 0; + int blocksize; + + READ_OR_RETURN(&groups, sizeof(G3D::uint32)); + + for(int g=0;g<(int)groups;g++) + { + // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...) + Array tempIndexArray; + Array tempVertexArray; + + AABSPTree *gtree = new AABSPTree(); + + // add free gtree at fail + #undef READ_OR_RETURN + #undef CMP_OR_RETURN + #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); delete gtree; return(false); } + #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); delete gtree; return(false); } + + G3D::uint32 flags; + READ_OR_RETURN(&flags, sizeof(G3D::uint32)); + + G3D::uint32 branches; + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "GRP "); + READ_OR_RETURN(&blocksize, sizeof(int)); + READ_OR_RETURN(&branches, sizeof(G3D::uint32)); + for(int b=0;b<(int)branches; b++) + { + G3D::uint32 indexes; + // indexes for each branch (not used jet) + READ_OR_RETURN(&indexes, sizeof(G3D::uint32)); + } + + // ---- indexes + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "INDX"); + READ_OR_RETURN(&blocksize, sizeof(int)); + unsigned int nindexes; + READ_OR_RETURN(&nindexes, sizeof(G3D::uint32)); + if(nindexes >0) + { + unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)]; + READ_OR_RETURN(indexarray, sizeof(unsigned short)); + for(int i=0;i<(int)nindexes; i++) + { + unsigned short val = indexarray[i]; + tempIndexArray.append(val); + } + delete[] indexarray; + } + + // ---- vectors + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "VERT"); + READ_OR_RETURN(&blocksize, sizeof(int)); + unsigned int nvectors; + READ_OR_RETURN(&nvectors, sizeof(int)); + + float *vectorarray = 0; + + // add vectorarray free + #undef READ_OR_RETURN + #undef CMP_OR_RETURN + #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); delete gtree; delete[] vectorarray; return(false); } + #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); delete gtree; delete[] vectorarray; return(false); } + + if(nvectors >0) + { + vectorarray = new float[nvectors*sizeof(float)*3]; + READ_OR_RETURN(vectorarray, sizeof(float)*3); + } + // ----- liquit + if(flags & 1) + { + // we have liquit -> not handled yet ... skip + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "LIQU"); + READ_OR_RETURN(&blocksize, sizeof(int)); + fseek(rf, blocksize, SEEK_CUR); + } + + + for(unsigned int i=0, indexNo=0; indexNo= startgroup && g <= endgroup) + { + gtree->insert(t); + } + } + + // drop of temporary use defines + #undef READ_OR_RETURN + #undef CMP_OR_RETURN + + if(vectorarray != 0) + { + delete vectorarray; + } + + if(gtree->size() >0) + { + gtree->balance(); + SubModel *sm = new SubModel(gtree); + #ifdef _ASSEMBLER_DEBUG + if(::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); + if(sm->getNTriangles() != gtree->memberTable.size()) + { + if(::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); + } + #endif + sm->setBasePosition(pModelPosition.iPos); + pMainTree->insert(sm); + } + delete gtree; + } + fclose(rf); + result = true; + } + return(result); + } + + //================================================================= + + bool TileAssembler::fillModelIntoTree(AABSPTree *pMainTree, const Vector3& pBasePos, std::string& pPos, std::string& pModelFilename) + { + bool result = false; + ModelPosition modelPosition; + getModelPosition(pPos, modelPosition); + // all should be relative to object base position + modelPosition.moveToBasePos(pBasePos); + + modelPosition.init(); + + if(readRawFile(pModelFilename, modelPosition, pMainTree)) + { + result = true; + } + + return result; + } + + //================================================================= + void TileAssembler::getModelPosition(std::string& pPosString, ModelPosition& pModelPosition) + { + float vposarray[3]; + float vdirarray[3]; + float scale; + + size_t spos = pPosString.find_first_of('#'); + std::string stripedPosString = pPosString.substr(spos+1,pPosString.length()); + + sscanf(stripedPosString.c_str(), "%f,%f,%f_%f,%f,%f_%f", + &vposarray[0],&vposarray[1],&vposarray[2], + &vdirarray[0],&vdirarray[1],&vdirarray[2], + &scale); + + pModelPosition.iPos = Vector3(vposarray[0], vposarray[1], vposarray[2]); + pModelPosition.iDir = Vector3(vdirarray[0], vdirarray[1], vdirarray[2]); + pModelPosition.iScale = scale; + + } + //========================================== +} // VMAP From 548f47b2b30813fa26c297024d5c203158e63600 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 30 May 2009 04:06:36 +0400 Subject: [PATCH 02/17] [7913] Fixed vmap_assambler sources. Updated binary. * Fixed week ago added bugs into vmap code that break vmap_assambler sources work. Note: vmap_assambler binary not updated from nov 2008 until this commit and it has been correct working. * Add to vmap assambler process show output and add appropriate error messages output. * vmap_assambler binary updated. --- contrib/vmap_assembler/vmap_assembler.cpp | 66 +-- .../vmap_assembler.exe | Bin 293888 -> 295424 bytes src/shared/revision_nr.h | 2 +- src/shared/vmap/CoordModelMapping.cpp | 98 ++-- src/shared/vmap/TileAssembler.cpp | 518 +++++++++--------- 5 files changed, 348 insertions(+), 336 deletions(-) diff --git a/contrib/vmap_assembler/vmap_assembler.cpp b/contrib/vmap_assembler/vmap_assembler.cpp index 233d4ba3c..7da98b599 100644 --- a/contrib/vmap_assembler/vmap_assembler.cpp +++ b/contrib/vmap_assembler/vmap_assembler.cpp @@ -78,41 +78,43 @@ bool readConfigFile(char *pConffile, VMAP::TileAssembler* pTa) //======================================================= int main(int argc, char* argv[]) { - if(argc == 3 || argc == 4) - { - bool ok = true; - char *src = argv[1]; - char *dest = argv[2]; - char *conffile = NULL; - if(argc >= 4) { - conffile = argv[3]; - } - VMAP::TileAssembler* ta = new VMAP::TileAssembler(std::string(src), std::string(dest)); - ta->setModelNameFilterMethod(modelNameFilter); - - /* - All the names in the list are considered to be world maps or huge instances. - These maps will be spilt into tiles in the vmap assemble process - */ - if(conffile != NULL) { - ok = readConfigFile(conffile, ta); - if(!ok) { - printf("Can not open file config file: %s\n", conffile); - } - } - if(ok) { ok = ta->convertWorld(); } - if(ok) { - printf("Ok, all done\n"); - } else { - printf("exit with errors\n"); - return 1; - } - delete ta; - } - else + if(argc != 3 && argc != 4) { printf("\nusage: %s [config file name]\n", argv[0]); return 1; } + + char *src = argv[1]; + char *dest = argv[2]; + char *conffile = NULL; + if(argc >= 4) + conffile = argv[3]; + + VMAP::TileAssembler* ta = new VMAP::TileAssembler(std::string(src), std::string(dest)); + ta->setModelNameFilterMethod(modelNameFilter); + + /* + All the names in the list are considered to be world maps or huge instances. + These maps will be spilt into tiles in the vmap assemble process + */ + if(conffile != NULL) + { + if(!readConfigFile(conffile, ta)) + { + printf("Can not open file config file: %s\n", conffile); + delete ta; + return 1; + } + } + + if(!ta->convertWorld()) + { + printf("exit with errors\n"); + delete ta; + return 1; + } + + delete ta; + printf("Ok, all done\n"); return 0; } diff --git a/contrib/vmap_extract_assembler_bin/vmap_assembler.exe b/contrib/vmap_extract_assembler_bin/vmap_assembler.exe index a6ef74dc086d0d0fade554ece7bf68143becfe7c..9c8b5f2d3fb38604766f1eeee3deae6807a88899 100644 GIT binary patch delta 79635 zcmbTf4O~>k_dmY(g0LwHDDn(~q9BOR&yV=9iRs#cqLyi5 zRej*9oc6iHrHYLs#-_gTpVP0EDTl7P{uh*Wzt(_wLD{Hl6Y#!nF1U6^ZZqhA6$USj=LgVVHMq&yB6vnpV9BNC%tnTU}!T?m%&zq2K2Y z6Sp``b@O)->c>sL8#4KiV-1SQXyN74S#_%}@*5c}z$YRu7F`CiRBVA^L5$N`{7+*e z{~M_edl7<4+pM41?LMK>pDfcSJ|GGi$5Gtre3QyuWH0(e%x#ZE|4)pzzq(`%)&bm( zBzyj2-Sub;q845>RW{g;c{}Wd1UQeL>5AEpp9bD8f@$rq0+Xuvb(AvITDUxwMfyg` zv!<|Nz7f{@JiELec zh;(4H*7k+$$XKh`DHSqM&O0bnAq&xJYwH3LAp8_3B{|F$s0s?BYK0@C1`&`C%wB7& zkhA=3_pbei8YRg_7AiCnQa?%}>pEfm3rLZ zV*Vc#+D}-Qnw1Qmp4sCkkaBH?Af;leahSF#=4}r14qNsPLsswtNy*ru$clM~63}?s zVP8zB19N&4<{I%g6PjqUTP_6XgM54b(pxhv1h=<<>y12zd6SZ{$&s|6~aQ!Z7^)hcG{73obCGv`yo2Q?Ax zm#>)X<~!O_#vRHpvpy?w{bjIwZdotC7{Y$PB}aZGW8c!&10`AdjlI=|$qiqyF@DRW zpV&u!BjlN>>@U9rL^`*fA$M-gR<^xMo|?|iv~_ewLx6eI&p<#klo|*axE$dBNg&9L z5jrHD+1q8x?-<$d?GCix?v{63P2@DvK?nWEb=W%2VEaj0+GFQ@3KdGb=5J;G0U^>> z79TL6rvc(n^%k&KGD;!a!&=Qjsq8?-T&i@Wpd-y#^%Sx%`v+EP_shRVLG}+))i#*38M#@e#4r?nQw?W!Y0eB3GlTs|@ zlf76#U=k1-9vCTmd$BtMKbL>=X0h$3%WaJ+vTz#U>TKGH!kH}LCM zSxWFfL6hzn2Sr|I;Y)6lA?n67KE=e+LZaJT5%GosY3)yJMM#%hNG4Ei!$kHDPH84YvRY$*j*@YPbrUnatVuFCO0G+Ah;m|nre(7>!qpR>{gdL`O#ay4p zCr{Yt9WhLb(PWPLPvV%XMMrxp8G4-E9U10t=$T?z;I+U}Oeiw{A0PJ*%Xmie@;}x+hYH zc|R#6r@4fe{U|0V5+g)02=?2K`0*+Jq_~Uire4VGP#+@dsb0;s{l4UH_hIYeM@gTtFXDSxCw$a`d4!oKS|y69q`;8+^H^d7O?FO5 zGH7Ev;>{m`!H1T;3rv-SZS^fmMy2hjVy4FpC)isM?CN}ZM!?1HWH~rPv zm{|(xCkyhY^Dr0q%YA7G8Xcw@TXv0MX%yuYQch+$%JGDLBD-&X)p!sNGq)wP4#VB) ztbsX}#%K1XY(Fck)SNIBD6p3!ow}*yQOJ>3fu~}pr^8-~=K`6`My>XbFxgPsVXs7n z?JzwX{Wlbm9>^n9Z7aqZvSOTeDs52&_Db5g#?#Q;V*dBf*+FHUmEEcS5y{~s5Ex^< zlspPKb2^Hu{Bf-zFMB21mKZ5bVIL-Twh~Th&OAaYJ+mI2)f?g?gl-FPI;jUJ!KsAP zUj8>x#Q-T%oTUgmH?{qZa(G)&K1dPWaISA9I_GrmKo9uVbJX!%1eH8`I`Y=zN!q|l zM6y%N!mp4SPo{1O;OboV0N`{|dYVQ7l8wi}AZ;LZcZxbXbtrG$4`@rPkm(0xdH+6w zg-RX)N!Nhz`95f0GopeD1Y?M41%go&Qk;T3ibftqYsBe1NO@*kgC~YYxNDZwq+lQ@6 z4!53096Z3f07bDbz!U2NJW0DKc@zRg2pacAYgn!j@tw}KlrrEfsFPi3@Xr|vFl3_a z`UBJ;rSv?MM}etOYn=0i6=bCp`a1(r5F;x_F%?odD}N6PNh#zr0m{O^y#|2C{A~G> z!?Z&&7Yb#VtChF|B^;*R&Wvs8nZ0TBXb|`kEjwHQ_-LR|B#L==l6gm(l2MpW$V}FX zTs_m+=w;eraoTqSdka4>P`0A;ep>0{Ic+J~AR6fJ(LkV9`yEUwsU6eL90dlafooWpVPDl9WCM$5krqiy_gFH4N>>XTvV?50cypW zQ3O#j@~#j&Meq&QwL=6*La7&LkcF^d=5~T+g3;?CFUKG+d%J7$5@3M1*lMz9N`9?Z z#C?NFK25n6z8$MT+p!?0ITte*TnK0%>lNDbv|3vAS5vD0XBNk&?roVk)8ulN!2ZN7EeUgvEd6 z`^HAL^QmyQs*jI#jwisInio5>prb9&?dbksA<{*PxhM^;kBkz*g0ZEVW<{f}vSdK` zX=N$+BU%J9MPO!{Gh;8fUBcU<)^U@SShbh$qypTWAci&d#8m7sy{R#8FYka{mpVXA zZ$uT-o6UGh#>tg#f|pIJK%Eax7as=mkI<&B9kexF8XN{LMsX*zv<{o9GtG}L0RGJi zLz`@IQ!7o^BOXcw`Vh*iGe)e72j*I`zXF)EUw8i&b=l|rIt9Yaaa$L)yvjhPMFb1z z@6)|S@s_q#ttMWz{7E*df2edXJ7S4o?>q(DM3UODv#nc4#zUhJ{zjn+Ng`=E1qtJ3 zUv{Z~w4CkB0tbxsFT^mZE`_PD1g7(?Ic(m5(ehefHu$#ah)yu>1&bTuCBwQ z{Bg>AbzpSp_-`=b^aOUMLM7Fk!~{d1FY#gL28MP}bJ3v;5olZ1kWGzJoC~Ej*pg9Mq?`g|rw5#6K3K z6O!Z_&5-_gPYW?N^0gG;bN$(&K@Uhzvu=YY$|oiE=wJ(bG(S)-yw29-kF;(9&0Ox7 zEX-BaZIz5VWlWsIR99WlH{UHyuL|8-ChgY!Z!st!Y*17j%&Fkr zKw)GFMU~hQ`D9a*rlL8Ba`*t2FeI+;485DFnuIj(W&{86Ya*40LW=1Eg%s7{9%%4p z>9w6HJ?PRGq-{LP&pBaWolZx!hgsPyJ(tQydjUKf6&uX{95PSd{|&oy=&fBA2^Kdb z6)H!nL#zEEjQkEH4KXz=mEo1$4ZXrX8#*F(XR?^Cnmj!&=4eBlgQc;<_Q|PVvhRj1 zZokZvoN;2EIAgeZ!2Pfys?Y9RkJTDl&PXzR#D^`p(zyU1WwRS5zGkieu z3z$SScZ~@vK<{B~*U}0wfL4GMa*Q!n*}x9nTQhuwzJ#0%Nz}YGsD_o{V(+9SMpQaG zMtEx`K$79DF_k#Thl7QqaaczI*bixnXv2|;^02fpWU6KM*@&c0H!L-s5J{j4IVj;f zW!83NviwpJmYw$me=Qbr^;`wrwINc^&wj=BjkLvm@lp16%3%LJZVHmRV}GV}3Rqs)q>M@1J;35dce!y{JAHIF*}9DRn?t0pnL2vB zyx|0tLX`Ys9cvstx$W&&!GoWL+c<6+mbt-f@tCAGs|)n;RezGbGNzaOTOj*>%*ZxR zpCmH`9=F-`EN1Kz-Sic3ox?c^5_a75w;^*mNwkRavBzm_`h>9~W5YuFmXlgg>{L)m zjf8>Ikj{ffvrA(WLdK?$ECtx=r7Uj(B3u?RBUtZo!O}Zy{J3cOKu31}xCGg^BilHx zV_=<|81V2BIS!2LBj+4v{~70y4zn!NbZHGMGL4q*X6MdUYEy?wV_4FJd)j~4VyvfhVB06uw_kT-H}~A;;gi`0pyd9f zx2ux|baE89MI&s>Ru(eR(ux0pB? zy<$HAb{gEmwT{5dIrbDoreSFcBpYtT{z!*0n8xSzWAW*)NS)YM>D_|sKNeaxdn{R= zn3iov68LT#Ydxi#d}s&jJ7s=Ql^dbeHGY_G2&dPl#7eQOXo@1e%w|kYm(!22H>XB~ zcm0Te8(TcI zv~XG|_k-<{VPSrI?62tw-+EN7+7966AgbD)sy?7sH3eYvNC&?Z;L(%-_IL+sHY12B z8Eq`6>q?)9Ml4Pz?Md)Xo!v&8R?7*Ol2XX01-UD%(2}}9AGzv1%`Rk2T67z*(;NG= zJ@q`m3*MywhomPy{{pz25k!eW4#}A}6-{E5D6o4HK%GuX;kGXbuzeiDSORhW4Pc2t zA~N(c53}vlLWlTJ0`_;D_8wGNF~@L5g(>hK=nbs1;6RBH&6wl(_gY>Y|BC%SEnjYX zg1tLET)M=Hrr#DA?iN&i{S!YUUiyUHK4XO3`v}`GW5B>S;BO!|iD`!>W!O4`l3Zn`Y_e~@w6emW~!!EOLd0Apr86}Z@g#m?%; zhRkdypU{G{XSVh&q^w;%*uygun5sndU{_}*T7QSD!ae_7hDaZyfqm?l;C>;00s$QzY>WaOf`uhM|G-tzizcq7 zid(gcm3+)iD^{lQY|n~p$6Z0brG(G)B=+%L{pHvscImF3@})%dwY%}9cYy}aPh{z{ z5+W+7*v7;g@a1=GW_hz>f#XRwU-K~5XmjEi@39$z%CBL` zjNU7?lym~Q!)jUD%n)BrO`Yt{#?S66tKHcXv%AR;cW1k1C&^>Fv*OvoZ3g}=gmIne z@@%%GPsgCA++wo2<`8BJ(of-cM`hFkk`Msl0;AJ($f8S#z}C;6&)&VeqY)X!7XE%5>odP2`{eF+a;_`brWLpF zg-x-(l@@-h22D3J&KqdCJNFQ=)_figfhgL(6|6PwweYYwW}4Gi{-q0hd`_29`LGP# z5<*pX^KxM91j$P9hIE{VutGX&bm`cg#uZm3FSdG42X=9eQNFJWtDh4U5hAt$JX)0? zP_%K}vy0x7Hm!j0E$&!_g;#bKdC%PAC+%e0?ioDb`OBIzu+ISj^*PCQm?DO(1Z~&K zPP?_Vapk1sG~RV5yJhY$IiVffJFg>~Ik%nB_9jW!Z?SC2++OmbSkLBFcMQ!x63c4l zhJ{VX#G>`qKj#JTSZ7~xE{mQQBlrG;rOb;A5qn_vyF}aV6`@ko_{T4@N9PU0r2Edi z;KcY`O$s&UKafj;Xp3!%zdflewSKWb#aDFCWBLLcXo$0*CqIfp8a^V75bD6cjuZuLD4ZJVrf%n`aLpv4I zQi1Mvn)h=<3>r7>R#Iay|L^Aa>;VE!?DmIJdWO+sZaxGvKU^JqfE=cDZ~izq zf^x-ayi;rT>3u__W9+Z{`bqgL`Tj1Qi?AARTBGT^=U6{?ML$vBkH6{79=U&tJm_6k zaQ~T0Ye)xiX%F+cD6v&bCnWq~*4zGr{kH%7 z%?dL+%YR&EHJL;DlF5k$UbxcsAO*?BrU1tvbAFM22C{52vVhMyDjgz$}Z<85e#UC1j*!VCEbyg;rZzF!p0 zC{A~p$|=Eiq#Ms?Z691L-~I;c6dM_NViZJN^ut{ZOb}|1(?u&^)QnzVe4cB9 zm%S_5_QjJ2cvlMN2r>WOH}v)b_?;ps+M=8%-a$@=A4CS&1n@;Hc1e;vr<(onel*** zO4;os2zYa%qfW+M}cf zfC%72z`0r5_($yLtSL>^KKY2HERB+Ty~^%h8Ylh5a+W3puAL|!*lLCYD1U^VeJsKF7hJEXlFr&J3kxX4=tbm|mX>&h^ zt;J7$$=+H%%+LD?Sevzk;!9JzU@r5^NF3EKiVz&yYCW-vhxt!@?rzR>o=hr zIKOi@o4>Mi*T=N{En5B_-c8Hj!=tFab0yOGv+RwPD4%m;;xskoSLW3j6S zPh&L#TqR$(6@@gvtL|j>@G*Z0jtPnM(Uge~|Cmx-nn7qHv3a14pC9(Uv&vT*a?;(Q zo4TDd^OMC<2`uAD0oA7Qpw-xM&QE5)uMU=0F`uXAg-_WoT3&r52Wkb4*J>d?Y&)|( zH9?N6WM4hiQ?4ju*Pn{+5GTeuDS8b}Z_;_T_443KcGwmX-y7NIFP$rWq|Jw+wX*n}xotlKE>4^+ahhxS0k%0ONmAI+oSyPs z+u0vEUEA7!rR-W{SMujroIP3ko2A>QOS{``G+C` zN%>sQqb>@?b2*Pav7{4Qw`P)bEBk)UU2^w4HsI-ga%CQS{gHU%!sk%3kRM~uJ-tRY zZxQMyehaA^xlv{B;Pt)AzJIif{GQ4h@N%jwHY>Hw&kJ;&^ZYBMb7UWt?a7LczOWh4 z{zd70v6)q7rL_rh)%@z^XV=BXMnDylrxv=Oe|lcvvgKzXYvouJ)p3Q5S(g>$li#EU zR@bc6N9q^r9+n>+%7!V!<&;YHxUx(>G=%-343Gy5W!={gpu{=ryUO1WVNb6g81iBr zpyHSxl))wu#4Kv$4py?huk}6*Zl!hs7Nw#5PK3*RN{tjN6#6os->T)Kaws3F=a)a2 zUpA}ARf>1fiU4RR4{?D&OapO{dujQiiL1|QO_V=)uxwWG0)tg6#w(BxG(;zX`_PvRNhY4w!@Z4oWkWnv1AX(79QA_y#?txZJddP(|Vn{Q{6m0v9jDwal#c@WT*2L?D8}HU}nVUJ`5GE<_?h#u~WHsOLwt88$+aVY{JIj zvhOqO>5YSCZ@>nQGoubR5QmC`4V22CNDzvG7rX5mLGFl1gJGYI>7M!p8Cm?p0rQsQ_PQpiUl z3XJ1RM>5B=T?4;*3<4y~M^Ww5$JnRO4(jf7w`Qxksec2fdZ|6uiH+@g4b~v-;s`HZ z9IsyLG4pdmrVJ_UYQIkL`~D}~1*zQk1pAVO$NcDh48 zmyHC90XS2Q^%0KLH%-k(e(q7WI@hL#a>SH7XI!FwBNp;f@>b7X+L8>&aOc;OCV`m_sgo$}o8sGk1MA68xe?f!7vZhHy*1(cb&XBkTn=N|M>fYSf_JIzQ^*w!$e=TXwx6 z%b(<{o|knIVnV0#YQYB_ZNY>MJ{tL`5zK!}i1imwRwZb29+_`A+vKs+?ktDRh{Hs9 z+VbN-bet!EO`#9Q%pB4A5o%W3*6|e-0h# zK!MLhfh2r4fhNd}CYm@TnmA<3J~YPP=`ZpQ>UpMv;?&VWTlPWZT|{-KGX_}lr-zCT z%TDt){x=MKF%r!A9u!@=MW?8LP9C5E`e=WrB0|=K2(Cs@F(1Ni9pu)OZ^8u1`K2fw>OfBcp(~(z%Cz@%c z*eL`~Y~yR1S{8MtBZ^KNmPUejhNZz&WFOKjnUz*Tqr*{wg+@=E3WqT1xrDGLPG5Bh5|pQl2Q9r&Mdz zJ5VEptO`ww6exn`inr}Z$e?TKp_ZcEva>f30xqbO=5(e|DHWw0_WlSedGvJT^~TdmELZFlbb&kHSyy0My&b5h0mXJN zDT+~0su$-|KrM%<#FkxR$ZALPAz7h42SR%V>D|p73^@GwCmQKVJ~fJzEr4v;OVKnC z2E{9drnL?cN&Zf3tQxfb*^U~aX6Ps^|3DR#^~zi%C@a$bh($qB2}8Y-kKF-$iBHbF zMX2J!^UW)wrgsykb`!i{-~fWR%3LhqAfD3Q8MEM26Nuj~QQ6{?%2v72uO#^4{$JCh7x{;TBP0!&l) z?gbc~z2b|8P(GzU*c+z9TthH3mlKaK9CGovm5%={z+VGR^O$G@xG!-!W^LEgkMl~ErOaPQ;xQNZ3)bv*VgsSZkQrrV04+wAy$jyyp@;uA7` zga2u_V$+V1G;>bPgd}o44?T40EwS7&@_=3>q@1sX8p5GsIz{~CNV0#ca6YyY2faW% z&Jzbfc0kZ_#axaL4)K+QZh2MkQ4#F-9TD=}duWR^h{f#m2`Y4>vbts!Mgf_{LwELx z`wgXA0ezHP*2 z*p%0>`bSN$7^oi;(SBhkpUW%8;g|YBm3D({3Yb?W|NzHkOBN-z;^O%YZP&iFfQTep#o|Dle5*9l> zHKTMtp9$e`F%o+%MfZ|Uf2?ihUK;O6pfLiHVW98lw5a8Qbvohfv?BLJ z1nl8_J*NRxEd0|0E;Im?O7bkEiw{=>$G@Xena5Cv4-^>JeCSI|U%FpuxcqWvEoDTB zjF{v0r^zq@Q8Xs+=iO0xok*>^+lr$a`d7ULrV4;StP%ySVwV*A@lMm57GC%Rp(9Ri zC4;wVeA#{>sK@PVTEPBl9>J#6DsOif4Nfh2-ZNWs&!~4GmdghRzO#p zvQh~+P61#Ge|t(J~tj_s`Ymk z2ZB9L;e)B^soU$$OiVwGJUd*(y`TV$9|)8k_T_*G)_dCyQ^=6jL2*)mzYB}XVNZp` z)8``eCZ1vQ6CsCi?4uSwi&%-mjy&=tiM?v-nE0eRjW?FN`sSab(8oE{bN>2!qG9dZ zYJ8WB>WY(|4rdmgw!`!^WOc;yQ6%u^Iuat|bVTS)h#a>+Oyz)s>_qQ?aN11KIalAu zAnGBCyR7#R{isq^8GXgj#Dx+IpWX~p8i$ZPSw~d#&5<`BH5EHO9rjE-ZHMWpBT7Mj z3FnC%_7ojadTWTzqjEI;xG;U~&SscCkEjQxf6pOAsZv!RAez~O#251;Km8+7&PX4I z(TYk?bN0K8a+ z3nZydl@pt;ZffH6M4PjoeAlV@fpxEjsZP#Gs0tN^r^9Z+({`AiIyouGU&g3**az!~ z(py7xB9-$%bQUl})W!G7%@KX)ZlWgYSR1Q;X{RA0MxS<4i_baJ0$CdVZFF44tpE;Z z3R+b1=;_ECho|i@J#}0u$gg2U!s6C(rMHIbC@QDnY868I-i&6*?n2aq_1*$ms#G-; zxE6>b2LuV{rbU?6yM@sJ3T>ZJZ*>RsrQV6ytC+8Z@p*q)_T^D%6V|%%=Bg*JBg@A$9l{L{ny#4Qq^31 zm|E2f&AU}_Njg7U+8kYR9%9Yg8n!wg5>Q>qqo*UU2cEXW^whDXAYTgI=dkzCv8A_$ zZ9MVc6W!$I=teh3*E)-Y29+AC-uJ^0>@Q{zD2i!fqHqsE(i19EJ( zX**0$e4HmV8in~O3~PryLC2Eb8kP}M(1WIqY0YT50#Of|o`s5EXQw(&nI@Vi%sFZN*Y8?jN^``sZ)zkJ_is4t-l&PgpLjZ)Mm%kY>8T@1 zLB1L~2;|lgrMHHt7nSoIe?yvMn%EpuWhRl7Dpei9ffieKj=_J;3>dk%PUKWYzZ2x8 zGhF@2KljMhvNkxbH{w-+r^DWW78UWtl-VTON=DA9pRk;x6pNK#|F%U}NqSy;L+h$O zAnODmdOGa&c-jurQ|~GT`4%V!hdmNOnwROVb@eiZJa}T6+KeZot%!Rt<)u5Rt5m6~ z^cLiZ6H5dMszx}j#mB$ns4wEM(y)x2?7`Z(ChY*!eM->i`y6>GDB*uVc%B{Nt7512 zC9-aTZ0!b!Z!3AJ7=I8mj`kGsB`FMG*yE&%nhY^$fpaA-NJQFr?dw`WU2H1|hWH5D zAwEggzH-({REbQ!3>wB^4@HnjL~r!V3X|bH1wClgYf3X3#UScIqSbd0iKtH10VA}) zaF-UCA?A$cTA=c^W_&C`EqvmOr}mAu?Xb0!8rSR^3i59-XdU(-1PM!eYmEGcLLNve z>CKQ_iKqvX=VlO+RHv!~kaSZMT43Wh9@Mk~x=^aabxd_~7NV+l6%hQJ2-^VhQ2a0@xC%!ne1Y+3#W7Y}%ud zRM!HBP*ZWz)8Wj=({`AiI-(ThHYgW|-48)Rl-?SmA5%!UzjRY^SaVE!G{@9Aok&WR zsy?IRAWgUZ*s@naAIL%uX~2bWDFx=@{}x9|bABJNMZ zF+BgA>Eu!K9LJF@yJV`t{8R9X#!y}IwgHloM^8uI4m@p#>8baLg8Tz$Ca8Y|sZaD4 zeG+uT=kJIsPI{(sgR4s_74qoPl-u<#S+yn6IK(~r^l}FEi7Hi{1tT-Z(HO_auY9GL zm&6zsJRwD7Y>xkWYCn&jj=WqvZHMWp<4-|;6(iDNHy~Ku+FBq2o*h_=3`KlCp2kOO zCMVX=1jC~Pnnr)>kzKAbW`|DsO@eO5S% zxJM_th)z(YsypC=!O9Oi0b&%a5?$~sun)&bp=Jy0gY^*RsXPh`_a6n|HpO$8X_de2 z6O>e(R7c69F_u>5z0Qh@Y7_xS8xv_|<5qi9TAnB;WD04yMx<#QQoI36ZVim>h?hga zbL~ypGl4B|^y9CdML@5hzzK^_1ns@iCO!+aCx~}|*krO&f|e1WX9S82efLXOO<~Ys zRdIy5DW~7*4?zyY)k}`N8A!1mrl$d)l4s;3i4;dhPJx{Y6KNC?8fMDzw;dP#rwnWf z+=UnasT1)(0N!q~3^|5YELsKOTha=B(g|hYvC_)y5M}ZRitVV3ngY=CR0i9hTA7tp z#_3#7HrQUcsKMh_ic?e}ictV}l?nfZl?w+&#maESympwm(%RmcNA=)FUoJ3&35V*~ zHW$!3_)CVWBx?IGanO(zp{YxUeLhK?lb$fZbYa#&^jbuYLH{*QbYD0Jwd7JPBp39z z@Xl9V2AO3fHtOFrhgA>vI|m^$nW9(_14ig&g)dT4gVsfJeyTT#G(n zd&+in5$aQf57`G_oSlLYkO01-BPixvZbdH~&Z(%Q=~e`c{$wK z@9ofhqjV!0j=`?3S&ug1kO9t4jfnSQ%67W$!^4K0$m1y}CidpELZ>iY>g5NLHo}ob zEs701YY^x|0QsB$0S@q;2WY-?-Fg0?+ZAi8xy$W`_3*-)x8Nh!F61O7A0+PAq2QC~ zmj!(na!h;CNP8V=&@Vs^${hCs(ot--W?xXiBvSAAGAW!Y@sHkMukVWP7wM$N7-dU~3vf3}()(;Vg+ zI{$b59%k9!&3XZjTBx`(?>?nQWohlgD}Hod!tdOyN`8{EGHS}k_4USKFIioW-2KQty)R^!x<@}Ngh=*8E0$fSJ|KY zgFBp}ujxI%?q0Q%MZX_9_lTPn|9)7C?tT(yp}cu8xS^9rPMgMSX& zgd|u*2lEeFvn}uU>kzxWMf3SPaF~2{;No%=jV%=^YqzooKGcAo#=^-3w9*skCgw2 zP%WGm+uB_kPKdB}Zv8XY@G&(M7-sy;F8&xd@6Z1M zAiO02i0F5oeb2l>pd99d7-%5*K{}NC+M}%FC%xp>L)Yy*1@Dt;h>C<~ct`KDiHt%=(>Jl6ytXz=7 zPt9P5Kke7c4~H=5&Q#MjhiMCxlNXqx6gloaM5N>w7gO#gO=%tD@APM#^6!-gFJaxj z9yJ_lRkTXC{&GwlM4%{>$s9D0X0eYmPyeN+uk52N9#;2H&Y&LpikkpnfKH6vG zV46iaO_Ad4X#&4C00a}a9OB?56%L_^6>7}<#XU~2XH|rsH zD>rm^XQZw;`YCNikQ4_6bi(lyq-1$NdVc7Qbe^!=t)GxUN-v7-2=aM&`+sYuhu(}y zX)A)%30Vo9u2F3Dj@|%RlDx@K^t>;oS-1IN4d z?c+8W=x)e_bUGIGJW|PM(2jv?dR83zg25Ke{0m|wKh~!pE~39~|Ds9{2qnk>wFv3q zJc=zY=n=af)F91m41@IQR|mWF7?NW!7F6HGKC>Qy^?8}aP(RJt+H)V0}?+xP>hgXPKbKGcX46op37IQMJf0vPT@T4+3 z(slCXG&!4a1|kkh!N}vf!K3_@2h+O%5GJ_}Y}HA>&YN`Jhti^}1@CDN+jfEVJlw^) z_1FI~iM75!1;hjiC@$&IAZXIH1w8g>fhIZ6ep_zR?|e-y=i6FgmV5kOmQmD84xPl- z6!r9N zbuU!w`qjho;CXEGS0iQPL+rb+MzCF9-zwV%?yLT~rzB4qz#>lN2L*zH&FtD*yD)fz z0&$Y9Sw_B|L67hG!5Umj>A)3dV#=%MZBSl=+C}?XwVsC#WNW_ZL>K5Jr3MW%`#lz@WYjBT zg1m6Ayt#hZ=pZ0kh%YO}71MV#<>5+YvJUACdp!>y$|}F<9JP4>n$M{B8UxI(jnFW| zC(Beq8N#}hWXgd9n6sph9NnMgmqf(w#Hjc|gy_-QiDo3rY*u zSc!|vQ&3*NO__o%Zc{$B{=P>i0BwFL z(JJ&47=fxKJS&0ylbS5&^`tv}yq_NhgZ9Nq;Vidnx4=c79Ts1!j4$mY*Cn$RrBUAY z4Jf&_wC|J`6ZEr+E|a>P4@aIhrxkmc)WuCEbus@BDrqLQNF|dx6jw09q&5&-GO0(E zMaetPu-RpiQhWA9*%R`bGpxSsHo0{o8+YcZj@=8JxUsrs3&<%hDLZ?nQ~N)9ioxOk z%r2T4Qh5DJ=65zq9@~p0olTKf_hb*AjgDJ_Q@1#w46T5J5LnDsAE8mS6>7h#BRngp zma&q(b2i;toeWxupR1q&;55IP#@B*_7%>R*bD$U2mnE2A-{cjDD24nlyl|d`kLEPt z>~Z3Dxesti3?f0hn{>qcRYZkFoE>2Be+H+xp)U4VbjQv*oJj>|f?yRCrYixsmo`5E z?N$g=;Gr=rw>(U~Jd(Xp9xKNrv#-iy;@fHMzKVfaW+*cq6Q7q(#P{8(vV$A6T*pY( z@my?MA2f|C3kV<&XJgOB%TM)Si_XQwFGg)3e@hD>;?{yKe6E&TJ%a5!7i-PLF*gOr z>8UR(dlJBHAQ6oHDx5xsVu4R0fnSDmQTvpd+>Fm99X(Y)toF$uB6BGcZ1p}*;!BnQ zbRK#k!0==iAxvaEgJBO$=FzJb--Zg>zON-t#;eTNr_@kBV8;b^=MS;6G?Zok5H)b_ zSfByW&nFXVxDsxUV@xP8fw$On44&c9kvdx4(Kg5n6#L`LlI+^j%3Iu8YNeqqgiK{g7!9{|gf7Fdd}Ndk%sofL6>uNAUuR zh}hGJRlhJnEgWodMLTISvsT0hZFP^@)ip(^N(SOb6`i{6`$-tb z0-6&VfPB~VAqZ~`I}ZILXF9*m8Y@Ct-wIrCngj{jQ2fy%{}#zM{um;coMx~8I7VK7 zfxUe)Zr-W?G0Wds++voeS=^1Et!D5|X7NI8rV-zV;zE_BKPAcQ2eOy&dUyc4yZUJ< ziB13c(U7M)g9ad^$Fv>5%>&qvKM$0<_Ge+0v;K>Y7}K@6j!1n}(-BERN1TddQNKjT z9l`3%#dkYwBwa`JaO;SdAAyeOEJt)?-<<6^d|2EKs-hIOg{~@+G3Pd^irzE<7xD>s zk*e7E1N-fl0numRNOuqY<|BXdaF%i*OddNxjQqu2*pnAx;%C!rS;((~n>QKx7A?1| zKl}VbvK*eo#+~aXpYF^ee~pRHr>U-x-_fF`KHSALTF8g>XY+ndwysPhX}ie~AKO_B zQL~W`L8#dfPe8)I5Aj5;^?i^q_YiNTC2mI|J`)xr9Lv2~$JpH%q-nirm=Eeq-({h_ z=b?iC>o9*j);-M4VeHfo5wazgZRd%7=acd(Uub zqcorI3TJ;;MM?Wv*nb8mpTt%T%ztRZ68<8>kcndc9cgaimi4rjH);0vOsv5%qyM|t z=?gU4%-;V0I}$%c^YCRfA92uP@M$S#mitqH+>k5=>G>Y)>z~%hzb1%L`UkBMTaMDh zJ;W%@OJc9pWO^sT7GQsl93dwrvZ=ofmKPtVNnid6_u~DwLY{V`*^EEUDcB*SmXP_Ttb_J92?nX?NuQ_b_YWCUdKTQUN$%Tz1n?V{D( z)>2|;N_JUmrQ(+`Vj={t5Q0*EEDB_}D=vw=S9F#9&s3 zSHB=O?2jdKZb$a^A5-PqLYVjEx$QUHNU7zQJt#F5?GmNv?MbPJLp4fSwy|F?4@?ek zK`9H0>y)D4|0AVN-hU&d1Y|)e0oYBc>tPzDD7iVM0z%xB+8?GOu1#-#xg9BnILze2(^=V$eeq{R;HyXlSui6~CJu?QD}Tn! z_BqjHgklHkrgIrgq+;kIi~%x=-iP_1Q&*()=Tor5OMU@d-&~LqN|Q4(v|ou~Sywu@ z=?1?nSYODq7h_*5gdMyx(mK+!S-%^a-8mnWp*@K^m9`>C4lN4kE%OWb^n`9Rsx33s zicOGj^@N%-Q;kSCrYCT0)ltHSGf#5rB-RP;Zt0=C92Vl(lntG#MC;UOnK}S92+0~o*Ix2yX#3CDp z%8!+?84Z!`F;OFlP!ylICvcVRJQB`!Gz7`@9oYvBcgWf8g_HQL_H5^0gT1}lLQo!T zGs+8VaQ04{o>*;6zIOYp^B8FuapX~*N;wOb@;Lgz#310tLcI{fE_5UV3DFP26JY8=P9y&htFTx}4O&%S| zEB+?bXcqboAxwM^gElb#Oa1s}`Ye+~>$iovXboeRui_H!Q07yA*Dc{OqWrE-Y+?PN zTfXQdV)Ht&H|lQ<+KPi1nE{C@xN~DcDCRYsr;=E!zdFf#da`bR-61Cj2@=l=A`;79 zx3Go(ERh!nu^;~FBcBUqf!9Y$$;@(nu?P5yOK1Z{Z-HI3IBmwFG(IMco7X-s9<{Q=;0VI90<2)DmYVf zAOv6^teFEL6XkUW0tK7vVD$@GYUV-cHSCTXJqQAX@E`~XE@fN7X9uemFDdCJJ_Kk1 zmk%K*7?);uQ4f1bt>rvfI1<8xFq+^<*z7H(wRxizWJlXkR#*A}op;pjK2mrqIEy!y ztLJ>AEn4igjfwxe-%UhZrc>=0iv$(V^ zB6A(eIWp?1Pxj4c){wAPFcWunRDbi9!b41#gv{4*zhDeWI;{Y2Pw^!+x|P)B&XX9L z3a+0)76wWwmYa3_{@HqkPdXwKKWa!PkzUdY{*5F6D1v#$`F5=!=Xpr2-l}cjXa@pp zbJeY_q&{-)Tf&}^-&AW_Nh{>X-hvyWvo9dRYZt1k zy%tBRCyi3KcEfPjlUrr7PQ&Bd_x!?RLK60nI`|e(8OzdTjNUF8BZKG}FHOc4Zxg?+ zR}79dvxpY!G6su?g3V>@|NQHE)#*3R^8&J%=LKMw=#}#5Ry5Bi#iF_9(|m8)C3>a2 z#9N!@y-W?))z)pKL9_qno>bANk^4O9a^sANpT49^TNYy~&=#MZChH{^J=6qJ`t#qf zs4upWLXGfrVwxKhsV>QoI;uH=QbgP9*GZR(Qtw?+-wc!@2O(*QsU|y-PTJ}FfA<_m z3-m!c?eU4iU)Lk0kRO~0@i{CeE?m13#P;InC>HxkSG?}~=eqhpTPdpjcF!(otliSq zleH^BC{iEv_GE3Z#_Ph?T~4eWm@Kv6>~a*>EjSAPKXO)?d?RNCWWiYh*v;8b3~Ft= z=1N5~b&LNIsDd`7JjQmDZ2evH}WvGgC`Gj zbRN>%lZRHILF<)O+Ir>h>&-{!DmM=)_-{OP|C+*0fBW)m>Ww@UkOdC~U^frj{e4~C z86+j%I6PzO-Ap`o?Yh2R`Qt!XN2#sUKIEi_hSFxi!NHy+Sg(_S-kv0Q=88swwcFHJ zgQfA2dYADVglli;vf4VN`J@+9ZMt#Nqk7tf_kg)NL>k%w2`*Km{R(04Kh>{7q#<6W z->T)OecAJhZkQa7*0=g7F|DEt1QUJaMVd$p^% z&eFO?$}dh*?~agem)=(2iICok-uoIB3$-w{>0;Ggh#cWEehouA#l_SWky29VRh+fg z=LnbE0JCo3MfGr`v_yVeRcn2vV6P8;zpmb5lx~#|SE(DLq?yuU^|vT#ggUg7G|4xZ z)+D9|78MzFATe4Bl+-smNiniitbW-^8X_P6k7|sOx+eerHKs+HCNGph!#oaK6(>XZ z9hjwYoRxxKp#a@7k6R`#t9Qmo$<{oSq#UPKHGt-7gwq~ zQ{HS>QifjtORaDKr`y%4@M#tVr;?UZ1*Q^uQKhmf3~o+W^}yWJ>;~Tm$~aP`wvCm- zYo6!Y2RcYc1Ts5^$?~Nc#jWWqu&p%e@c9Hta1Ai67 z?0I*QPRwa%JcxNhY}5*3jzj^SnDczp>Ml|bYbz9`4*jDoH3E2D6Ezp0qNw(xmgmPq zA(Mz};z{p^vVSOxq+NObi+DHa>{Ag|1a7k^SD2-J=Pn7P7?1n|`zx42|IwncVirNeg z{7Z?6r`2zgq*d1LwP2MK_xtc(qlMj6HVc=F8HMoF@HS1keO$TNJkfJWul(nCQN1>u z*Wz>>=Ag1!v=yvXrvfLm0)YR!s{no$jO?2Lo;Izm%g}WPq_LVNkbF0+h{iJn+KG0N% zxM{JL??J50r%YTQ``94*T?2H0rk-bXO+%Mq*Yed|{imN4KVpWKDvDvd%a4zz`i3$e zA*h3~;f>;=eow8W)(n-5;_5y9rA2Z`y83m0DI$8zMyMnHW-cv!#K9!oIS0LpRgjTy zhRPZseJqEaS3e&heUp;g9bN(B0y^4Z;rAC_Z_E@aUPz&tX-*nXMy~hm}xAo@%f(LSy z0=ZQJY^9Fe=?ZEDF@fAMiiw-Dv=v@uvZkf6RZHhbjr`H%11ASbJ^_r zl>4j}rQuSV!xvD((x!w({0>T}Y)V+pQ-4;c4Uy)K+Cc|yOr>R8wt+l21GgM&4{=-` zekB~F)X#G9S-mj63c1e)q3F?W4pH;fpVX^Eq?y)4+#i+()3b; zlO$1UIllx#>J_!5Mf``BNptu~cM|4WfM3oJdL~)5CSUeUqog_f*`_2o%6Oc%*J0#u ztU_;0rLCwFnvlowr%}{x$-p&ukEbPhvyH?<1*UueFgR7qFzI3IU6V({!B6_ZkDnq= zni_2Rbd)@R9~Eq-)9)A(L42R!bA#<@914f>-H2B8hvm>z1J`r9Y79q>0KVE)BNa7* z_#+f0@Sy-7%I6UP>t&!KhQL%*@#D99RtexKt}4S(C5ZQ-D2+W=6NL8&0Iusl z8Y=qG&Q&8-^r7**UW32~@mh*fVXY58p0{3atj-ch(K#+7L3Wg#tUqXVX!( zLjLPgby-m?HHZ)doAe!e=xWnTn|b;X+X$UCZEn0y3)K zb-91&he`%vKOH17@(tb8#iOOZldheiy7V)O?w_pM;FjSV-S~&F9ML~55J7U|QvjJk6u~LWd(j$cTjrYxd5lHvV21!Lt3%b=c z6%bK$L_ITB8X!HX28@&XO4rn}{9q`NWoyFtCva3>yz3LE9?9&0+oS|8K4My`Zrit%xAC;`f3&OG?Pny1(!S}FFPnhJCLutu4w!c`ZAi#(zzT;~x*VQf=Xx(Xw=1W|8_ ztKJi&ucR~THxr~@((4DjZj(k!@|F|otrMl`@~9IBUYsb+mgMtat9#S29uGB3OXb`3 z$R3J(`jyBzFnF@`vLrVaY31r~m#p%Dh3exLDNY`xCC;0oFD-FD6#Y;zE|Q~*6uq*C zU<-NSX+N)wV*CQ7#}=6PQQAd*c0qklO-h$+a`YDjXl&F2i71B;88S-Cyf>FcuC4y6dcUjamukQin82+Q)u~gY z-g0SobK|;~Zx|{G8 zDk_zFzTcX?4;<~^y&t;I%&b{!&1=n?nYCwT$H}93J7{_W_+~XGRCJlZI3qdZ4wqN$MlvP-4f_m2H_n^FBmT%W)Wq#ef!%6|R)Vff`W z{g}ugiNos4S|kP4O?qT?!eKoNd(~Vmo^qrvZjRquHFXaPCEt>c-kQSjdFgHafb{gw2(sZ=)k>=+lk{l;YZOtgrK_X}pQuYoKk4$0@P5uGfkE-OA zE08|AC9%G(I<;Po7ADo{F*=@H&-6+Ms$E9jAhKajl_Q*FT+PmbNJQQ2fU&l#_<9oS z%u~h+mcrTzx5>;cU<8r2VuRb#yPP;JUE%P_w^!_geEA)%2+4*x&Wqv zM)htNk%riNrJ%A)ONK7MUlofMsYGk)O)drYh=wHnul)r{ewhL@4-H8Q+^WAIHEMZy zqKi%3oXmpw&@RGn3hFSRix@Hmt<@MPGAaCNpeRCk<|~2n@V)a=`KsSj-al?uH|WqJ z?VX7H^n+P_>RxE9Y)P{^<6f|iJgONgI!td;6NzR)J!|RMy#5?M(7v z7Gox1lCyCt^GP}iNL9X3A{*=5sFA8{WwUx|s&+BIQGK3>mwa+uo03;n!Q4YPe?VQMH#AEi1fB zb98mWQS30(>aMi|hRu%{7%NBE)!=^h3PAQ&s%?(0PS{U6omoB6oj=l0WEv;@#IDC! z=&*@U@Rg$*zdNbVvi5eTNiM8twV1V3(xfN!G7SNkEnTjh)f~hGsHt++MV;tn(Pjqo zVQWRm4A#rbjZ!yM&f0}OZ%ceMr_qUu}X(I*-?z1i5DWDbr2h7GH+hiLA*K>Hm|}C;`5nks+k?cpEFqp?-3nZvQ@2BdQ=C| zBb`0Ke@~D(pZ){p^w^bTpCRm=LMdL5z}q;De}KZeZXQojZz8HDpS;M7)Tu86g0gE; zb45$VYKO_fyBTYCjw0fjzT(ex77{p6GKnW9_f&zV{yX`K*jcQ-x3k2GlvvsXM!nWv z%$>#J+8@Nmv*!B7i(R=&exbei=PZY*IFM@OmGelYZZ7y}8SbMIYZ=xX z)K7;QMW1xMVV*vld9d%qg4wLQ?-}e03>LK@7hF7u|w@8phNV6NE-8--0x^cHP0SZM!lL@}YfMt)}i z)6=@yR0*=Xv_@2OCaX1Fcnc+yFj)zn7bz3+;{ zeS-C4uZg~yY`}#7v_)QGo%Al>=OfM9?(78xl8NoW)m7(dc8R(1X+kvUc&-{=ChmZ) zu9>=CeeE7DbppyQV#+KDH0mU;VYeEoAdNK<66?Gg?Q=x~?qRS@!_CB}5UOi-;?TBD z^}UDLB#|_SC1)J*v}<3JT6$R8sWG(!k@|ubgBmueJ1J(E6S^w#Q=ieI4{*pr|_K1y!!Uj2?^E{eoa+ZA4r$-1gQRvBo7B##Zye4%Q}ww zw^`HUM0*K-o%a3l)MuuaRVC2>%F$)j&ZN4vD%15vg}>C@)$#^VQrzO?T&U&OMde)f zuvGaD@PyJf zMX;;cNqR<|E1{zeSr4qpcqu7V)(UXoy<`+;TLN0vR+rZi<$+jW8Ya0 zG^s=*CxO)mNUKOry3UAkpncF?^vYtLx;hGiR35<{bU~m{vmo$0zM^U_>n!$Uv5uWy zLS3M#M zPZP?~<(2cXMv+C9>gA8th%i*YPXTE@xqz>_(OgsS^LN{eOY`vE`P4J5#o>iW_2t&$ zgM}EY*S03<>Ew>F6Y6>o$knN>1zQA>jc6@;E@C0!CXILDW<=^~t|z=kH>5@40R1U* zvYMdZxrw|*ENIO6*GU4F1Jo=5T7I($Ydg^zs^tyTI?uTTw@984COgk`g3fajSHUxI zqU1S6^3=LYU*J=>A?@<;>mqV78#v-kvK7h?9+=dIz4D#cuk_B#W6eg2!D&6h{u(i8 zANw9<822xdx`yu0pGaxGvsaWZW+CZu8i83|f^C>E;yBPat<~d*Xgm=;+KeN^fIF?N zKU7EEU0w_%kJM@x77a{J!TAts;KIFPNH%-eeDyV0FY)%3@?loLGzx1r^W*Or#olZ- zp8ZSQ$!6i^K3M8ln{ZYV`xL9yE=CcP!&b13;=LU9B|A~NVF@3b9F+CUB;@xCzMx? z^oJFq*>thkNz^Z8{%t2n-ZYie#?%BS(cvk;yG!`$=1D|*Co%jf)_KlN>^rQ|CX*nM z6SyA%(v*}@{f45od_Ge)(%VopvSYUKCz)E6{7nh~gliufD} zvMJ)~Q>-1Is0f#*Q8y1MB8*&?w!I zl$j`6#sc^uCJrrQ9lbXJ(Nb>2ZM=xpYAlb5@0PJn-f8wIO>tAPM>FBMoOK#P+x{dK zCb9A}f=0C?rIagp?;J2S1nQt?z*KQSy@eg1l)jxQ zrZ~7M@a|o);u+>2dV`2}G*BvSz0o81^H!CZD`^>Y& zDkC*@ffXj@aaBty=4v^FP^*aFa+y&{$9~v9a+zQ5Fv*Sv4N@vnnj(k}eTcM^ouM2* zI_eRWZ*U}--p(|ZsDIwp=qTg<)%gUY5e*raO1&DP>7z zK9I-!luht_3{P&3q#h`#bwl_Jfb99SQ%4f@BYFho)2mwE8?WaxjG`aVqbZ+()%gU| z^BGLhtr3k`AH2<4rRmR(loWQGp-SvY`4jT@*uR;(5*n@iPqA|)3&<_Trc$gN?bIX> z&jF-q0F%1$MKE$f%TdLs*;CG6PylQIUu+c2$r-Vybfc4)E^0KzQV}=j_rS_FiRD zzeg--sBo%8kTep>N0NlRRlW{m@}}2?$t#q)P6np^=oSg`1e4+4qG}aJ;j{*Ea~12w zm;Nk5EG(Lh5|3Fh^^X#-Td=2dhlQD#6Zv~`yoUPP!s0O``>n=60m8nk*+92R+qCIM z(Z9s<)oi%?3)m&we9}u)tcE3PR+IRBHH!)8rbS^rTjjJ?Zr15QpYy|!1GRONNXloE z`N3P_a6apryY7}&T8evy{7p11x}YwCziPPDd}yx=^bz0b4$(<68s;sh>Up~=+fWSy zXPX*LIC2qkLG7dA6S*2h_^za$G;T$zr;JV2QggOP;{&^uW1OlJw&@(#s=r{@E-5+U z@*Vm041NJWafDKrY3HfsTCBu8dQ-fyhWRB62Wl%($YDU{R$HttaX`o<1k$$E2bR)s zq@iWea5Pp!lT|bHrto`~b(k9J0P~lmblu~D3?h}K+?htC%mMAj4J`$%bmZF$9d9Dx zRUyt^b)Vc2&p*rB2OZU5vPgT0)&<6Yt-w1IiD=Ue@$s{)FZ+k!Ygw#s6D;d?dmvtj z-qz>t?Zl+DSp8%*h+JTq^z93z@Y{-y*RtW=h)&0yY0y?C(y9oQDu|A;idV;AvD&|Y z^$&Hxb-o`r6?(#06=#&#+X~niN9+wY8ou$JaU;{T#8w|ALJT z1i;pK&s&Fc9d=tZ;MDDO3-S=CZ#^vDUB|j~zVMz5KUPB)xh*5ozmL2)iZLtOxq}PU7T7*3NUe*5euW z3}`tKRlo{<2Dc#4js?_7N8Ei!QA;&U(o{NT*FqNLgKG`|x=pWpV9On%Z3WE{lM7jg z5TnjTYYWF?k#YL5NY%NM*jC88vXkPyLe>kH4`}J4j&X&BW4aDGG(E?5Q0wm*m5p2IP3D)ax5TQBXrrut8R(WZ#`wKC~- znkQ~Q$HIb>bjtsl>roq6x8PPf=6}nzNO_Khh~pbrTWZvb4J^d>SsdJV$lAE7IC}f5 z776zv){Q+PB8$+Zetv(~q|X+iNh@%C|9>`VMG@-WpfMks7w?jH`;3g|$jn zvMZruL$LknqSPk5ERZ(QQDWgn76^5+aU<)+-WTN?nU|+7vktQJ(?-@KWj+oY-1T(aoVZt)Zut8ZztqF@v%=uhw1tIt{_$?>Jsu#F>EvI-+UMu z)kf1>aFa}FQ`SPz7bYA|)UMaYevC?W%)9i$khW5eUat;8fc84+H=Ai&)BaNKdh8f$ zPFdDO2YX&n0>NHj-uKr);6IPH)WB1Y^s)wC^A^K5vwl-s%KMkBCut01L0uggNJx|& z^1rGu_lF}?1(hvTa9BN2>QDu5BJjVfAQ~qT@2!F-?2!MG0~AX9xrOx#j6x>REVAt9 zaqCGlD+#&P?*Ejcz*BFvw0?>sm8^pNcCrrtTl0?tgL|5Pz1ka+sW*S6+696CUG{x# z9WpGNzse3l*?s@31P8wIW=qKj*vY8>$dW(aR+i!6{~`ww8UtD6v$(OOx#}e3hPb(n z1>P@xlTIF{g0FXM^p_w{%>{oRf&X1_KgZ-`!5{II`HlWB`SnK9_Ts&6cF3{)!^z80@kpMm5w7knWC zdcnok9V|OR+rKfyh-HU9uonsaJ&~DaHRq)XbyZjFgO(c|Fz7T?j&Atwq}+f935H6( zE5`1`%UmphmhEIo54Ozkq}9}6hUXZ@nZg7;ENnYjkFHuyVlnq2a02e|!u4H_gF%yc zVGxiB0Y!{pD zuQQ|4HgD5NP$_^FbL~5=}#Y}~T`Sfl!2>U0M5;kOt@3(S6gNfvE+;^>D`R?-+ zAfu00IX$N>wol`PnZ&_@+>Uc?DIgPovlTd4Z=F^vG#sqJ?Kqz<6}w8X_iYT0?P+%@ znbfWuu^yjVUX@T@rQ7Q1yn{3w(6J~B*g8l+a|Er^kE*k@*o319%56#VDAm~eX~K=BL>nuk-}Hh)`mE|CLzq8Y?vWqjN(MB&xSw zB>76*RMFi_1ny-)ELFtsWm6uyZIyDT$x_YKCbj2r7+nlC2~FSE)l|NG^K|^vZZ*zE zu&Hld-->*tU+iU@7){(Ce}hHP!ga?RtboGZ_u;7IT0%9}yVN-6HI%09W8RDp&k#@U z$J>oyT3Z$dVr@+4n#3GYx}VK*3!fvm+k72k2|R^`Baj+qf}v`AJF98) zMc_fK0ea6Di3ib(v&6iE?7`_Wb9Ae=lUniw<*35p2##6pqp`K0%b_DeCbc7g)^lnQ z%uR6i<5Vobl10%xDHPZ$B7;Ay5qA!EFSh27i!4B_YapVZ=8V(L;^Fl+h-=0?C?o%kdGSVLQmf=<5 zdboH>v2Z@h9sqIpQ8v>T$m%QDa9}@^K|O(Zh1!axO{k)$aF3=231E8ZPC9A?f=g1HngD+&k;3bK$f?qva!p+e?ss zy z(dIp|SUg?ELbZst(4r0zZ;iXnUPn}JJptYz02ZQ#P*iM3YIH> zy*I<-9p}f8IBwq^lQ9sa>cE!_n?Bv-D~gY?AXmhkLA?0*80*|V@slA2Sz(zN?wbUe`3 z+jgh{Q^n^Wu%6yUE498LKk=}maFkoHI&X^bEN2lT`h!OuneF7&rwL_t-bH|G{-vsy zOlJoU1n#G7P+AN1X#GguwaH?AIm=A=wWUb^=k@3<2NUtR0QFqVJx3Lx27 zvw{VP0_KcYq%)Zush;E)Xds-HD~Sc84_j&3j;ndLPn3g!JbtxdqWJ9;3me9YrABX5 zCn6Hpn#&UyhjAqAf*c9rv}jcwfM}f3!UjEg{XV|f-W{o-@$i|WlDp!u(=56Z=`6J# z)>?q2*7__3Jhl7GFcmv?nnm$*SH;!SY)+rp1#)PtnX2OJA+Y=D6XzawFy7Nww-_JW z3hO`FKF|Iw4WXa58h!@V_x>R9{28340Pj<0*yFif$C2Gr`%sc|nRe<^EyOrN3lTDr z+!wXz@1s(hqi9?lFj}vy2E5Xu8m*iF)3mBh@E7BYJMw^Bd)Y>fDz-csYAWr6$cgcy z{48EZFGv*MpJl_^r+@{itakOD>asqv>loFz@nYaPmhLxj2h9`caJ;V?uK7ndRi$EJ z+acaN#}-0TdY#8j61Fj7?0MFy_ky{!U?S0|80T=(6(2{ST)v6-Hjt7xG$$!ZY(I}J zrweJ2j}Ob7-=OQ$+Ut zwdVkkn{rpprX$n28S4)`W}tkUU}Aqv}V}Mr}foiZq6_im-pOOWPvSU$%u<_A%?& zb9g4@8D>6Ir@i-JYrD|ImvmeRUWID}9?OCg4@EE=zuu? zZBid3E_B_rojXoA5t2bNV$5NqAe$}O2oip#=Fp}NqBK#c4!v;m4j!TQI-sA zUD#Yv`~`o?63J`7X%=Qy3%`>xfGPG^)C^6B@;+gaZYmAPG=&~4PJF@!b+%8z{^s68 z(cx3ptr-caqAX;kB%3FtTf7Wo%%(gyUlCft+Lo^SlpSY$NxT?Q!3OiFcu`Qn2Jst1 z#d&hy9x7UW4tVxZG4gYSBZrE0pR*W#BTk$r_|Z7w_66YCabn~bfJeoNf-eAX93nm< z_|YN4?MsRuB1V1*c*GE4rSSDw@$r|yKN>6CE&{$dR{Y~4;1RLHdXWv}HwKII1V1`h zxP3+RgT+X4BL|ChUjcr7kocIwM+S-3UxQEfATjc5;y*}OzXtqzOzFp8v&X%-+for( z&o+8zw5Y{#mMhsw$tg6>U#iC|>YqB4{$9^s6TwvG4ndug1qtyy?r6vkqx*l zFZ3FHf$p%H=p{}xFrSXc=fu;Cz;Wsy_;{gybduuJyu_~!taGlJ@C%`Nu%E4+oK8UD z849-$1bSz!`V7Juk_*lYtJ@v8XjFGWRX-}D2{KTq-J!i-#{c6f7B;cShcH#7lg=Hj?pfreW3S{Mo@26>qKA%<|THO|ZAt zYc6|c0L;!Dh0r%N|$oi50%b-Eut z#3d(+_Yi*0NI%^}Omas0K_0kb5bz({h)d*_w9z`}tTtNb3~r-!&dcuNTNlLdao0L& zy1Uj%gWR=F`lCr)awU3`)>+d{T4xP1X`S`Q*5ZOlnQ^t;BW;|7aAK$SpAn zKNImcib*DlH;U~higy*4$SrXde(n_SDkiy8ysOymPVp|{61gQVrG9O=Uu^EQ7TL30 zF{3Npdk<*wWs))o+#H3HIt{R~O z$j0YO)0lTJf}wg~hrEFf+Qe3Nu~>XEhIh@?4V-i#iX5V}@DL1Uj$s<+9K+O;Y0SxV zDqD%-shdacaEO>cmYZEAQtC00KbFUI-9z2z%(SV%Jj*Chw+$J#+R)jOtyj;w?71c`kLA5` z4?E&fpze`-@Cc;#1?Xmik!8CktCL{kOVv4N#+U7(j311HMlAy-&6Qq1ddDU+POqe( zmj{42W8yq0ZOr%8WL%1Q!A`d%E&_z-bi#%A5z@*m0Z@~&EG7yTfv zB=Sxir7?};eqIixkwu+aSKun5$MIlKtdFOjk}%XOt%pU{I6j{H&J<_H@lrk^UF1H> zeOyM0R z=f3mBPZRid-haMWmCT@godQ>XZghW;-eJ43Z$ba@@ctN zTXH7L2t#_-t7;%F6+7#)7BYlt*7A&{dc8X`u5O!&+J~vdg95?*w7}2jPu+CB4cTNT z8t|Lb!Qw7M)=$+Es>8>>KpXWZ%4C{%Up{unmN6=o8l*8%eG?{++zXkejHUA-+@r@E z3=!oKHwWYxJ+_obpUDYO2Rw@G80gNpWcpJ-!SHE0?M2sOO;=|jGBa?paw;*CsaZ)# zBDEmrwmJr2z|^*ssI{pO>-J>IabF#tl}8Q&IuIh7xgpfU{wDyuoAhN$W|it}t&aaRNwh?v+T=* zK8b(+DC7XvlS-R+Fnopip;$=4JQ9ciY#yfkOF1yPsxQw+wlms08Om+m{)hsGFC6sl zh)*V~QGeKM=XF_%a@t)QKAA6Ixv%~dXDIQtLgP65yoafA}7gzJc)l`fZ#+OHSQNb>p%WwXwozC^4aw+0JU= zlLo`3hyEoEUJh5UT(HDk*-v()UUJ24v|Mh&6%p4w!kmK7pQ1RCIF;|6n zr%mTRJn(wylIeUp<55$^rDu5u(U8Uq_>upJWsmV#wqG27j7RYJY;pB5-oDes#c>8( zaN+puI71QKN(75C@Ut0D*<#Uc2JcR|V`uQ-q49(i^!YlMwXT*k>|`CcoMo2Zjf>V^ zf5jHOg<=aIF+{@&#S@6f7mpc_5sv{+(_-)B(F9)sm~r$r`9tej%dawb zzscOab?5pkw~@cv9P#B$9?Id~naRULh#LGi!`Xpn51##aj^a6v=QN&ga>S$Q$gh^G z20)td7?;Eu{Fjs-Oy{1?JZgRE$tQTEXYSX}#2L=5iZfhX6KA-wF3ymO@BoAp5T1?j zM=RnCudj?Vyqyoe1#yOl5$=d^H-v{Hyl**5o)>2jt5NZ5kpjZEbCDXtJrFKj7H61; z@KcsJ!;84sb$ z&3NT}aUqXec+-3_ZY7_|eHVy#R`Myl|AJDlRs0m=6Bm?LSs)~Q=>p-G&zJq320fe4 zd;0J03k?CyVkXUEN>YverAkRkfm$qWvxc`~yy<7r;aOhJAM8t#xQCDVOsrhXH}RX1 z!l!^++oAgyJo1O;84Sm8L!zP3J#CFRTEGWCScusvEgCE_Mh)lZTn8Me$={wa7$(uB zKlro6sQX3mIzHG%_O^#auXQ|3Y+1+0=?UBg@-d8FNFZwscDM0iQGZF`MMoSYP_m*W zf#yWAt@kDJla)vIT6zQPTif>UYhQXgpgF_GL4T~ROfwIoO5M8%U+VSr4KZvz4}0h@ z$v=KCx|+4zA$eKAJ?rmF+q=-7_TBr^UJv49*dvGX7E#&-2+OpW6#idn_q!Keja_zs z+7}D&OFQ8?K31>XL|`AoJ9H$rYmIpAIUd3a#V614u7mzk$X}jzKt&y2f65^tRPwRI zAgLQ?1=it0(Q5;bgu0rsflv0@wgBiS0w55xE*q>l#^|WZ{o?Zte5@<9rX}X|tD<`m z?+onWMZB;7t5D^v*O*8{q8q2Gq1S4S!$t6fYF<5PqKc2O7bt3I(nyt0um$Hb%SCjJnd37h!P zt^=Xyn`es@sN4Io<7{!@b#ZJHKf{|Al&;#$gBcIZD&4z}8Ywr=Yxv1KP{F^y`wx~d86Ll8G@KkFJu zQ#DYPv_aX%gUI48E2i#ubOFrY`Y!}Yd255=zN!&l7IV*#@E9zZY{Ltl@j||XwJNd( z#Dk6P%Yrpjrx|$|$#?UvK1K0{On3DFx@9WO<84ba@cyY*4B3soRU{tY%?Fd%+oCGh zhy%NM4_C@uRPb(5vzz;MpnQ#SvK6@0w@Ow&`VR^aaWlo{J*8H7mhfPnwovpd;Y)dV zjCiwzcWn)HNVvyJ8+LtuSHk=f{RJ|N+_n7 zY8TTuc%OMI&QO5Dp)Y~913D!&af#j(9;@kdY}Brz%PZV_I?&X1urX>aE%SzB4iuIg zWb``mq5(26}B8**|GHYr*rgCVXSs9CtVvZ3-IZ$K308&tb>fZ7S@7!G7@4dqP z0+1Q4x+BVC>s{52z>O%MKJ8SdF=OpQas3rO(tR(<#UQ*9wMB*P79(HfJ=}Yj#u?PF zeh1$Yfbw4DPvn;1l5zJ)`t=T{-+(asjS8jTm|*OIELJhqRnI+2m|>$~PPkllEc?dTybx z?Bx+q@TGfsZ+4*c=e>Lxs_MH ztZ=oSDWRB5r$qJH%_wbZiQ%ApPunTeDY+nu;?()~L^x-5oH*@N#24=-f^WSu@`lPY zam&d-%ZE-Yf3H{`}Dtb@A&#-X7>Khj=oasfYN(Qqi=<_s_SA zU5B`rX$vU^>o6lhO3M#n;%eN7rL=2CZIKxC7XPgM0hG2chAvBO=hTz6E{bbvy)!N6 zgOBhOAM+x_8qkv?Yy~TB7bfh0uq~|>&mZA|t{^OkYTPf%j_?N|dA}Ut$*l;+EY5&F za+D8ljfvy(o%Jr(7yvdM<=s0<$;=*T&8d~5X!*JG$)8=6ND|14M=?V_AiUq^ecDN} zwb*RgL-TFfgP~@#YemZ2e4Hy7+Pvpt{Ck^sXZuROd7GbS{PcCPyOj6j=dO#-N?|mq zxGsJpxB9y9DC3W_SHzQLybBLsBwmE8N%d#CRG%&5QJ!dUTjb$nwfZ_5J(Yyr{aqe5 zmgLH*jg&9t%mCl)M>2N7d_~`%4op;)O(d-O_oh{Nuo&62SHF5NJsrR!wxe%t! z+koN_)3xvNscm+B+$;cOkGcLXO*V#K5Vm8yNAx&Ifi0>WrBt{4MC$Z7yw)aEy_%1( zwIMY%`j*Ek>XO#)dVXIx)XCE1wCKqcHEgF?cn_a(oJho1@PzicPe^YSBxF zWDvJv)6xxw7AR^{Mj{DM=2fih*UT3^&-1RvH3*ziXU!KA z&hsFziLW#pGi*^5P)A)B>(BF!X}UQt$C#|{xdKCm`s@y^T-nQ2uiub#d0=!yj#ET= zy@%=~!?6gbVXUw@j|Zb$!%QZO{5fNiQVIv=PXWX-*zleKdvS9Dlhh#=VR?@y^C?%v zrT6&5ywqQ`Kh9_K!vBceVfHA7KEc_RI(Vu$GPJ`XiM z{|l<|7&^-%@ACi%@8j=7F&q$u@AGNiwdl2$T91gE^-d8tBg#EatUhUI+PvOgN=0OPZfRsMV#S_iZ}!R zJkF4YXFr}&Ja_Q){4&m932E40`o?+wJm*syMa%`B&i0Aj7kEFmru5qjJk=Rh3Ad|A z{(^4-TWGI#_C~%hI$-2X(x1hU=8()(qT3H2Nwuk=w;rT z@vcisqkiHZF5EM#bXYxK!^u=OBpE+c-Wxr=!6SN=9yz1MH(Q3pzA{)U5!7=Eub@KSv?E+<6d;8lLajNV|# zR@b%jc;_RJ69tJ@vG5vSLg~X4jtNSnO#j9;{>?q4-(2TA!7`_jNArqB;;lxR{LhUt zdG8ziRn*7v8|VcGM3iUH?KbZO2cPNQ&Knkqf8Cb( z@VO(Wa0zz+1-~C`=;?`t@rIkHotKTOA5rxyc6nBJ_`a6HVKvSp5LN$>BlPJ`I<(V0 zP-BgAf5Mfn*vgbl_ODXL6(eKog`1)*fb+DX^k7@X9z~ghIxssaquJKdX->**76Q^s zQ;pkio-}5gVNki$D-95A&fSi{&6DPAw@ba|7K&UKB{;ym7)q-0RhsG#a3&jXb~4`1 z#Ac5e;Jma@l)ET>U;}AzQ6|CphpRFh&Rebuwg!tyMrARaPmRj^JnM!iY^B(y?;!ip z`KmiLRaNCxKU4>-N0=-+Wlk7A7oV+m-w#0j2Q|){??YT|M^u2gfl*z0Eyd^k}V2_NZ{8$mFkPdxQpWskk9F zwN@TzJwl`C)gM^rS}TE_Vgb13ky?cZci@<3d!+me-ul@dQ$i|C@xsNV984lk0A9oM z5uPuuc}%%A+hcq{t%=|huObYhi8drpi~*Zci|}29ohiX<9@G9!S);UOdrb8I3b}E0 zS5^fjN`TinWYIfK`a?sqq?=j}STD-Kes^VAPraZado?6?B1BGZ+X;~(QV0zIv3RtN z60Dfvd8&=lSwS94x3^IqVXYgGTgp)rnEvLWbZrgp5>N?%zgd|#BhW{3MRwYHhf061 z&ryz#5Dtiy;VJNkdWUOxRkJ<3&aeE?yu=@QG1prDHJI{jMr5ILEi!oWU(U*hvprJ5 zW6CMy)_sJJs5dJ?yun+TJ(Zzt3>u$6)JasWw|LA`S;4b>M6IWiI-{afOI|9aza=jX zGOXpLR>RZtVz@Ui<%leFELfhdDNlu(J5vRjlQDNSE+;Q z_^^YL1P$iXQ5gs)siX2VtdXB~R5pzY?H7NK9`Qw(^vL4KYWM!|*N2_WUxaxHX^R@? z!27VxI`$HmYWMJdr3d_!ldLUGNC)0)L*sQlB@w_ z{!BiBs1pH7*Df2dl&VH3-Z0(jf(cP8%QH?aM@h7OX*pwDc{gx_V4ak9L5Qc9z_i@N zv?!buYU&1Bz6~!}aXI4BfB@KZ`*l)+*mGiXCuK97hE7UnFA!iobFt?TR}%UaTP5tu&FPIk!m(v#Sd81_$=D1oy%3l@ddnlm~BBc^42&O%J>M1Ot zN-lu8E(|Fjs1R!`z)e7t^Rn1l(e(i(jBOBOA5c2@CPKXJ#_DYEj93Kaq+R4apmf0; zW%mQh)ETwd2w}+XkU_4x3vW=!ob4vr5hzui^*T)FML$5Qvhkx9qc_poIwvmUm0<|G zK94Oap@=!_6r4o}Gl5`Z7!( zCxdUqrJ(}?nov}a)&GPD76dfHzb?VNo9sW96(+nh+X*-=z(sja#S3-#RZnGb8?aRm zXJh%@L<@4!HB9N@gItttrmRed1t~RSFNOE~ARY@-0@$k}H%!Un)6gY*DZM;wF+l6M zm=?^zCBYj+OfSVB)i5Hq|6OLtgE%Rq}YJ6bRm9q<&)@E}veBv$3C zrTZRK-eNt01NQHjVAXd5@(Ev5LvqsE0RMd?hEz$#^unkhN_|zVjZo%H2af{znh0uD z!PXAlnt`1I#etx~{*xqRv>b#f5tq=*Pv!K69&3vJGuw35nJ_3z^+B2`)zY*y$1Rgj zETITk9s~D@MrDt)zG(K8 zvWqG4h7%W4L{^j%&?>pCnu66b7=qg08l`mYy9UXmB~x43yeo)0=XOL+lg;}A{1FW{ z?=;;#C*4Avzp#0qt`)yVDM773d+Tc$y4Q$~eW4wM7~NMnjiIe=KTOp(h=Kj^(TQ5| zY(M262xazHB7{qS#ZLhzQP@vO(15e>Vx*$K;@vKbI@DHl0yPBNyR8kyurD_CSE3Og zIY4<9&hY`tKwl&p@y~*U+pxRjt1ufT+Lk!kyf4<4njcmcvUWwp<&TBnQhHO#Ax|XRLjR9{{_=BlB_Wk5pDbC=CCa8k^c)s>!vfRp!Z;?N`^Ij=C!wvHNVo?T!{7`0Di4OV>FCQ&e0@$0oY-Vj^=vrSe>bIrAr zRn?rjt4uw>yhVIISm}nAY8tGBwv|1#ZRQ<1gkwuR>wJ2@cqmp0rm9@h8C6RPzic&ZaTA9qT}*a~x#?`&D)NUYT_K`-hbX7IQ~HkE zm@*YL2Ie-otrlj|2{?vl$f!;d8{?FjZ7wHav#(}WhgDT5LzN}`a*|j!RO#Th6`iPc z(zy3bTg6L5mEIvJ`QmZbb0>dywl=`DP&lyAZ~%4h0ZX)HU>jRblqKfy8gX?f6l$&T ziB}%>B#I>KNqUQL74}5K0r6P8(h;3>dAvf)`W^Ag1gg-*9bx;Z?M$3aU@DXZWdN^O zECwYg_zJ3+l%Py9A*sUn{w8!(LoL3-qxA9x1a|krct${d>gJo#uvj<`QwFy~Z2nD; z)ij?ffYsdTeeg{graVT*ikrinShgROwo|P*Gfe4@G=3eXJm_GB4;`+=06KfP(vSOQ zilAFlM(?HjG7!6R~nGLrYt7I`C-KzFFo6)DzRCx7N-yFM^N>DJ{S zs>yEDHY0s$>n6+hkHe{h0Z9vMMp7mZAfg{QvLZO$`5>wx%B8rC6&Q0 z-)59DvNI%38g!O|O!a#VqXNC0%`wUO!IfI^$peM!y5XIZ5dUCniY=rHNaTEvKv-i)WgN^~WmFsghT@AT#}+k= zOyASK#k1JA`1zxDb94&*sk3l>nNF(l3~8Mex0BQd&xnqbmEIAr z(jeK0yx|1+8TBe?}VYyZE ztbw*Msz;dkY@*_gqWv^c858t6^h~DDv?Tf~2v-L&nJw#?dhBEJEgapTE}S5eQ#dDLCXfb!PvW_$l&3mzt!TlTt6OU4-A(mPv;W<@l zFM_5hDee-%OGgmTPEoQokex;trz(f|>^tJ!sY*Un{orX>My?U_rorqao%W?+(-jkk zb$h^LN-QU}RglnxhH9tH8EC1NsQTdGa%%l&Ey5^v%~bq(Wwtmm6FqdlxII%L8)naR zrJSu3SJF``yV+EP&w?H8s^~Qv!+5Poo2|@)^XY6QoOXc7;Wil?TcZM@=(5LJVzNcN z;Vx!L9}mDXivlExu4OhGCNf#rDBCcOZi6$9BNc>cD~8&~v2g&zJm=e%dCq5e_X=2Y za;7tFrv(X)4PjikjRJzQh@?ny&lV!@aYgPWML`Q^Q$^Bd(rN0U|J=nZ1k9nfiZ>ru zrl7LgWGL66-1!sA6l$03Hnymv5G-|CKdKw&vYt?f4jJne?4egcd3^c%u6Q|Uc2 zovd#!oK2`64^NG2&D7c&1?L!RThDzfG% z1EwV+rBpmK@XW!Jjb{ZOBc1|0*Oq}3o-Oddgy%Ip+A1C^+M}rDk}~=^PCw=Nv9Ix| zLtNP)T<0piJpfiWL{i_+49sYPz|2*Kxd2#vbe|}itHjd`s+c&``|;O@J-^jww_ z$wSZ)vt1L_3jv_B4s(ijcG4loBxDIT-x-DIvRLUdPmfrmp_-$e%{nAogLp+dd+CrF z8pJo+*;j`oY7qZuXMY_sNP`4MI|u5JFbP=_932%b#G%DXUg8>ElN2|ggh|N}m#`-q z1L(uF_K3JSEIEVjq(S#LOO26jEQlh+dikP+#yWjrB!SLgB6727)E0-bm2Kog4RwQ%jJ> zK5?C#S`qZ5vK46@dr~p0)=w!FaH^kDR&w7QG5u*}vX2}n|6w`f zVfh)~OUGA$jnU57{#fy}lHm6$31v9xxXS47b4Cq_k$W8@lGQ;&MEEl0AH08#Sg}kR zT@Ek9n6qD~%alx4olK-IR}!_ro?3BuIaXs>r)GyGs~ZQ4>gAX^){0xpm581apX^5@ z`#H(_mdeOvwZ~vhx;k6#)-L%ZS?w@bOjv;tqE@V4p``G)z7;hql$}P@4|Fk1Nvobw zmg%AXwZb_UuSk9nX}Pe|pbB#FHs*l1l&f51`%4e!DJ~3^R=QI842#0$1xiQp)3eIA zZt;)}>$#rpBZN4=R(X@dMPw}>CB(FKiZI4fygNd7)+xJuwa|FL3jG<3Ms=hbi^mJG zaE#q|0QA+snY*`%;-J zQ+bI43CVc#44FPV4(RRxP+J35W0AaD`Hm*+&{t^%Q)}xdTLX$}MdNPe z-lmnd8K7{tdy%jU_mg+SH1WZ!N|)T=i9qoMiWMI|R1dy+m*$rVYb~|RV>L`T*mb=2 zZsF+ix_FRk5xhC#PT}Z1bv-CFGv6 zM%nXR4XXMBpxQxHYg?$AOH~Ps^MqkY6`Nm!x;~sLK6*`gV07h@+nB2wPu+t#nlP(V z!Rr@%=Ak+L;-z}>c z_a}J)nLD>1Ne(2+Svn=Q9M|ogLM>EQw+n7_4vzx;1)y6;-iB`j5oQr#7zmM_T-6cuC@cBf08LaU9g;0>Z@(e{BhKZjcS#~fHiB6rd}U3nJ7v z$w(=;JCf4c45#|)GKi~PP%Z-VF~ZCu%)9u?MRVhlhpN24%+2Ata7Q|-@*XlRs`Adn zVGnUQelG`{U9L0wp=8YoHUa%A~^Aa zngY81Ey+;btwmMfjG03>yDY0H%dv_^s$e#eSo9|rH*g0E6|s2zcD#n9KD2(jU5Nc1 zgm~v-65@6v+Y;qmqCBKi61Db6#Z*%r@=c}u0n%5tjR>B(mq3i!r}&HxU2HG2S{IfC zF|;>HEoiq8?FFKJh-iy9BWsjJa0uNnCc^%f&kSa^1Nt$S5p?>h&Xzf-bA}3=w7! z;Y<)}=l1KKJlj$$>u?DM$>>f(+)RiM0})s8)Gd^3cO|Mjj^y6McP-Et5c)YnH%WB0 zZYZJKtLq9-MiELQq15dGM|lBwqME4XQGS6gQH|3>bfs9L8hKCt*A3JZt<&DSQy^=X z!SWACSXuZquoPfPgF~AST8bhEg>MLD3ZY~J1@%l~uy?aV-bf7IB&@ZBHD-@s@1us7 z-jA}9P>vExC(1s!Ot>Fq8llt@%AX}vxs9mGy1`z+*6U&2T&;4W2+=ehh+hB^7yH$< za^!`;%5?fv8b?`T5J6p?k9+96W@&HkM5KEv5$w+|G3a%Sz_r})^?sQ-6 z_9r?+8tA^-O~q9$CyjL-Bmum^b#3h4_&UXrmZau3#Hnl`(Y`>m^tJOo=t3B=#|P(X zV?UvNO=uZ}wiswsTgN6KZwVJ1)XfE{ZgvCStdU2OYJHI;b|lqL5pmf;TzW|^#=30c z;wZ)Q2<051xa}TADQ&A82b{vfbVz62F!Dk_4w9gF0!2trSzS-K*8Et29L5O>%3Qfm z5bQ9-j?27|x^9A$m0h8Pw&3<9Vp=_(n4halAA>71ZmHIj7nQTWOR&H%S@GR32H z+a!ykx*~Elx%WmUv)a?q`MAUq`iHs;(k)z1mHC(%JoBeu1W#07krBuVE(f~G?Qca^&t8q0K%_V~GFoPs3Bp-Og}Q%ntv-N|+aly7PTL7NjF9{5$b{dZA>jZ zn3hbB?v4zto6rVrYiCL-VGNOsB9i)@j+(XDUoSto_m?AaBsqOEpp~na>obc}M5bUVpJqa>Ni=xUzb-Ctsteqf2Pbc(p3>H+64u5j0_lQFR z)FG}ygvyGD;yF?Dw&Fdd6d07ixkPop=Cvn)!B0Ix=%)!i@vjLK$Lm!@?qBCw|H%+E zMQS~Rcr+0Yo9O(G62kXt5xD^r5j-0a$F@7w<1`h6=vEV5Vhdfay{@q2OjN&t)Sw>Z2iy|X^D@F0K((8rX7SSQS+mk37iQ?Rgxy>ZS<8=aZ?zPiuh62+o96ZQVmBhS6GS|Ph$puYBb)eI4?0_J zT?mzl{E>AX9f~)S7DN`JEh5^$duU}Ti_`TCliQNv2GIS3=#CSeiu>*KI>BU^diUGI zC_Q*1>)sf4C$}ZDB$@4quz?5 z;r2KUx2W(&=AFlJoXKnR{jI(B*;}4@o@xG`_4x6(_U~=I>~+rB`)u|;)+lK|K2Bk^ z6n3-0HcA{sC0seZm_~`}%qvH!YVHx5okgV&nKpjV&vp#wmq$xF^j5?4QcIxNtrUA2&)k!vYE!L}w4CX)@CPg{UlTbu zC}#xFF=O`%>|pDdu?AlS83&Di7_1!h3E@KyhXgVkVpZ2zqUA%YHj!J{2Dpu&mg%52Yq_mKn%H#mNg|)CBDW2TpmUD( z;k=7}mTt)|W^!T|e-^pqMRlh*h?8`3vT^VKR#v1kYQkG3B z3w=7Cz=4eEiL-)moE?&1mK%PnUy)~r;}YiH;nUf-om^_kW&A5*#&KPED^8{`s7E;GsH@8Cio`29<*G0BtNudteY zo#e7(45cymI)#5oHjf9k_2Qf3njV5fzP_MG#PAc^R9U~UR?Ii+`__t5v%Ybyc-^co zS}V>`9V@i&XKTfu&H5i67Jt#MtsaE+*mq8N+qDN}^%tV6U5gIEX!{OkiErDrv9ccY zuo&(~7SdnH6!XnGzNjxX>l-u0>t=mXra0%Y)sF4q9;YY zN0lpM@UePuWAHOUHBFm2YXg_SZ4k1Bv+-amSO79W8K?t|;9YP6oClwQe!#YJHUj8i z8b}6CkPX~m2Y3}UgQMU>&<*~$mDjM_s6=k#Yzp`}SO7AC3v33pU=P?2TEGc#30wss zPoYte3^IWWJO%cEM(`Fm0y;rA=m$|xa~21tg9T65AP^N7r~=P|2JjX*3O)p%0kibr zA!dEGZnI%Dw{ z=IOZJ?64e`zl(<|9Z%UkF*>$-tG3?JV~4h{h}5ndQNF!VrGZt5dEjL zc%gS_QDF~ln5O5s-MXv1tWbEM8G1Ple@H#q!47!D3mw|(#fvjC9?D48Q}fF1uF}gr zg=KnCiMudapIkYVO?K&%U1(==r9QdHsIt`Z@(Nd_UQ}M8m*#o&$(yE6pFUK4*P%^{ z%}#f+`uPsl1lhI3!TKQ+mpbg-bDq{}2hYrKvfN)f#K)(!Q6bgXz;*4br?sM*jKVyZ zUO)|$l;u?wQUjinvh~ygTas6m=hh1=D#|O8^}aWhUBbJO^GIFSvA-<4IP!tEVp#{K-qGnGccXZV z9E^Dv;_t2S`BGB@<-)KvPR4p2EE6&jaxY{qq$*VL%H`LZdq(pPi|vKIUc>F1ATiU) zTDVaco=>z%V$4NtRGb&;k8@Mle((|Mv3W*)?88pBUe?9hi`vwo3(8X1zmyVU*F`OE zgd6rP<#^^5v7DRza5C%d42RBnNFwhIS zfgclLTi_Dt0L@@0$OTCt67(*_ zjDaTL1(_fLgn_9+3tE><;q60HpGD(qF)dg!8Ec$t{x~e+?R{_kX{Gq_*&j}Itl{|E z1Xhroy)>`1urhm9-s+_ftx+PUs$x^whMdZZ0x@R>UwAj;UMIVT_c623`ys=dO&CZ3 zRJd2XF@ujBLVh~@nb>#CDg`kzIw_-6%A1J4|>XnuR(QiS1aWlXltnS#~#a??dRa0ijvg&Q&_Ht5)r9 z6v}sC?G6ZS#CEgNkzIw_-6&Ltse3?ZAGWV49obc=-Hk$*!KBk0iYheLL~JK19obc= z-Hp5x{t_>y0ij#5?NvImt5CZeg~rz6ZD>HKAKRTuM|LB0w%tvJK7&`5EtD2oDBiN7 zfVt3OpOFh~zTJ;vuOqD!erC~7$;7s6Ks@;c%N;!1?oMG2G{47|f|_r_b_+0@cc|v= zeiWOF*dALfHGhq^@lI)vCqJY4`F3|o;e{y??q;DB4s53lNI`x^idlAd3UlH`@3p0% zJzkIP2BjmrocpNdHZO{#*R1`;N;)6BFWdZRKKikJ6PWYidsgm_8oM9GZYc<6+g-s- zZx3dTXMIbX7KHpxV++7$a1i_lnEoMhfH%N-5OY>zdEfmHxsHWQN8-zrGTNZYie&Fy+@Qw!v? z$4IksB@Y|ni*qmsbY}V2II(#SpE|TB3(FqL_(#QCb9h`$7q-npc`1)y>8`~)q$&GR zBc>R#7Eqy2Gb+?4lJqA$4jiFVp;rMFyKN4ReQ3K!jpJLR-yw2p8pZYp`Gn#6d)8Pk zNmX<%R1{XGOw@HIW~{_)<<8@Lc#AD$rlpVWfu2gAEiTuv%USkWzKf%e8ooLt4gX$9 zYG*biP01oi>Vr$ka!B%f3X-Ote0r?hB5f7dXI+GmN{e##K~hq`l4l_)sea5FbFoNY zg%y$p6_qSyqOd*EG`!yC-D!CHp`t{WZQj?VDJHhfNE8WauEKbFI;8A%i8A?a}=>3B%9&1;6aXQ^c_vzg~#Ak8*?0dvGGrKYHUsTPfM`H=BY)9{OwtWs_o z++x?6U5a?i7M*FSyKHK&R119t9}?bf?al+1_avLT+fpyFsd-MI$#R=I(Ne!;Q)gRh zzfHYUs)d(k8fq#(C^N01LxHFXiGIU87m_As38cB0`z$xNa@(TZcG%qFa|1nYR%*(W z8&Jo5s-n*;Gxeb^V2+47X-$@2szp}{4;>r=x5zv*`2&S;qw)YGHLwtpGOd85ot2^F z6Oc3n3U^uI2cV{M2$I6vASwI|B!z#h`Um$$x@b``IXh;gz)%LxR6h0f0 zLoR|G1i2EDmQ@WTrK6Z@fpmB8SLT0!B-3HFeO$Rysrz>gy>;+B4@>dYX$%MjH9r zI&HNY>oS*z@GQqPIpwyXx0rC7o5xV+&c9Q=HxM1+w|RFO-tyH0HIB@c=4P8Ys@UvWOc&I&<36{Umj%ob`iEAV)lzMIfI>~>ab>19n+>zv1-7Wm zRx-a$9aQh#YvcU$Tq_z5BNor7-(G?{2q zCz@(5=mm$p$5VtvW%$AIVM#?`j_UNG$wk0`riV&WWi|EXf4WqjJaMY?F%J#_(+;ZFi~s z)TuPLToCf@?z}Z6)l!XxV2nL@T&PG+=W#L3Xx>~6KGZ2ir`ste%;zJ+ZSkx$Fs0jU z>S?B$3*F6m&2W5?Nu?MUvuLziA@=}tgml_X#XgFpd?Uv3KiF=oeA!C&BNxT)we`Ud zohrNU87^n`?pp)erE_&E_I4l6PZ0~(@KM_C^(kU*CLb64U&SJM4IdxeUSi0>8>9?6 zA{M3b3BhZ38|ob|iP3P=e*aR6crBBU3W<6-h0TB2Futl}-7Cg6ZYPmB9s8uzO7_d3 z(Sz`{ZB&y?6#ff*l}lwI{Q~*nPkuEyjO(v$50Wd90nb5_P$7J;q`b zJJWe=c-G$=89SR(*o9{C4l)i~_;w0Q1t=mSokuU|#>Qns!M;RysDy1a&eUQd&7DTy zKTt6zkIvLyXpzGSKXWjJ;m_>ka{ct6Se?N~hyV3qOZUoQIh^2! zTaAg_epJrMxbX5eqZi~hw@uv6;3Gr+{eu+tpSb0ic1+M&+3Mh0TsWdk|A=9P{LR<+ z!G^DmS>FGRk#QnR6=T-$aavD^Q5pPwxO_p&#s?3NO=b7Qri!_62_BUwk~6V8FU&U- zTHOj|S-VQSN|yL^r5N^zbd9)>C6iGf*zl}WF@cuRZy!}nr9WnC>gmT**^7@$%czhO zPo%PcdcsJ0xX^G9E_hNZCWUS`lA6=$SJP^4fA>q(zuk34WXz4{Q(5&UF1tbhUE7R$ zkA_3P|L<2ebo~LBE9v3LDAN}%TAQEe%E86M@&ZR?mCNC{!&bPp zpwLrQQeLKP4PT@(Kfq7HELq2=21Aa{=V{{ob-XOFu_K2+wj}qk}~`&4!l z)L%m{LCc?vf@_kCQnH`1lQ3c!W|du=mkjzP_X&M_ztjXyNbvpF(cNC~W93f+ z$zI+Vd`?6@$(=QHBQ}24g3+Db_>Boh_koXrq&u}IK(2(m3(^TW5po_R{n!TG8&1Dy zLbry~4MubyH*T|IVY*Ypn=-FkZipAu9OIOSgO zLh5)@6kCQ0?S`}@d`v>NJb){dkb5DwLDoS&1z8Pw3vw$YeSj51YLImPPX5%{y5+_~ zN)^w$c}~hr+>mZB|MzY2Y8jt2Raj|uF2!`L#C54vPUgTf67XzZ`GHOnkNm+Z%=yiV zjXbDziHDyJ4ytb*QOVYNWZe;xuY-~ea_O`s7pfO@bKR09tv2H7ABWP&uX z5-bBw-~jVL5|{}R!88yLVnO6XxV#&R3I#B5b2To6fnIPKbb$`w2W_AQ>;?5;2se(j sX&Py~(;;s`_P_nVQ=U&3rBo^0%&diXRF3Z+$?f9RL6T delta 77827 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%0Ae%j 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 P{cSs`tz%xyZcq9j_}HFR diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f7dc3da91..26d539c2e 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 "7912" + #define REVISION_NR "7913" #endif // __REVISION_NR_H__ diff --git a/src/shared/vmap/CoordModelMapping.cpp b/src/shared/vmap/CoordModelMapping.cpp index 2ce40dd8f..23b89fefd 100644 --- a/src/shared/vmap/CoordModelMapping.cpp +++ b/src/shared/vmap/CoordModelMapping.cpp @@ -85,63 +85,65 @@ namespace VMAP bool CoordModelMapping::readCoordinateMapping(const std::string& pDirectoryFileName) { FILE *f = fopen(pDirectoryFileName.c_str(), "rb"); - bool result = false; + if(!f) + { + printf("ERROR: Can't open file: %s\n",pDirectoryFileName.c_str()); + return false; + } + char buffer[500+1]; - if(f) + CMappingEntry* cMappingEntry; + while(fgets(buffer, 500, f)) { - result = true; - CMappingEntry* cMappingEntry; - while(fgets(buffer, 500, f)) + //char namebuffer[500]; + char positionbuffer[500]; + int xpos, ypos, noVec; + float scale; + xpos = ypos = noVec = 0; + + //sscanf(buffer, "%d %d %s %s %f %d", &xpos, &ypos, namebuffer,positionbuffer, &scale, &noVec); + + // this is ugly, but the format has no read delimiter and a space could be in the first part of the name + int nameStart = findPosChar(buffer, ' ', 2);// find the 2. space + if(nameStart > -1 && (iFilterMethod == NULL || (*iFilterMethod)(buffer))) { - //char namebuffer[500]; - char positionbuffer[500]; - int xpos, ypos, noVec; - float scale; - xpos = ypos = noVec = 0; + ++nameStart; + // find the 1. / (now a space only can be found at the end of the name) + int nameEnd = nameStart + findPosChar(&buffer[nameStart], '/', 1); + // find the 1. space (after the name) + nameEnd += findPosChar(&buffer[nameEnd], ' ', 1); + buffer[nameEnd] = 0; // terminate the name - //sscanf(buffer, "%d %d %s %s %f %d", &xpos, &ypos, namebuffer,positionbuffer, &scale, &noVec); - - // this is ugly, but the format has no read delimiter and a space could be in the first part of the name - int nameStart = findPosChar(buffer, ' ', 2);// find the 2. space - if(nameStart > -1 && (iFilterMethod == NULL || (*iFilterMethod)(buffer))) + sscanf(buffer, "%d %d", &xpos, &ypos); + sscanf(&buffer[nameEnd+1], "%s %f %d", positionbuffer, &scale, &noVec); + unsigned int mapId = getMapIdFromFilename(std::string(&buffer[nameStart])); + if(!iMapIds.contains(mapId)) { - ++nameStart; - // find the 1. / (now a space only can be found at the end of the name) - int nameEnd = nameStart + findPosChar(&buffer[nameStart], '/', 1); - // find the 1. space (after the name) - nameEnd += findPosChar(&buffer[nameEnd], ' ', 1); - buffer[nameEnd] = 0; // terminate the name - - sscanf(buffer, "%d %d", &xpos, &ypos); - sscanf(&buffer[nameEnd+1], "%s %f %d", positionbuffer, &scale, &noVec); - unsigned int mapId = getMapIdFromFilename(std::string(&buffer[nameStart])); - if(!iMapIds.contains(mapId)) - { - iMapIds.append(mapId); - } - if(!isWorldAreaMap(mapId)) - { - xpos = 0; // store all files under the groupKey - ypos = 0; - } - - std::string key = CMappingEntry::getKeyString(mapId, xpos, ypos); - cMappingEntry = getCMappingEntry(key); - if(cMappingEntry == 0) - { - cMappingEntry = new CMappingEntry(mapId, xpos, ypos); - addCMappingEntry(cMappingEntry); - } - char namebuffer2[500]; - sprintf(namebuffer2, "%d %s#%s_%f", noVec, &buffer[nameStart], positionbuffer, scale); - cMappingEntry->addFilename(namebuffer2); - //break; + iMapIds.append(mapId); + printf("Coords for map %u...\n",mapId); } + if(!isWorldAreaMap(mapId)) + { + xpos = 0; // store all files under the groupKey + ypos = 0; + } + + std::string key = CMappingEntry::getKeyString(mapId, xpos, ypos); + cMappingEntry = getCMappingEntry(key); + if(cMappingEntry == 0) + { + cMappingEntry = new CMappingEntry(mapId, xpos, ypos); + addCMappingEntry(cMappingEntry); + } + char namebuffer2[500]; + sprintf(namebuffer2, "%d %s#%s_%f", noVec, &buffer[nameStart], positionbuffer, scale); + cMappingEntry->addFilename(namebuffer2); + //break; } - fclose(f); } - return result; + fclose(f); + return true; } //============================================================ diff --git a/src/shared/vmap/TileAssembler.cpp b/src/shared/vmap/TileAssembler.cpp index f3b0d1a0d..b8434a7ef 100644 --- a/src/shared/vmap/TileAssembler.cpp +++ b/src/shared/vmap/TileAssembler.cpp @@ -148,37 +148,41 @@ namespace VMAP # endif #endif - bool result = true; std::string fname = iSrcDir; fname.append("/"); fname.append("dir"); iCoordModelMapping->setModelNameFilterMethod(iFilterMethod); - iCoordModelMapping->readCoordinateMapping(fname); + + printf("Read coordinate mapping...\n"); + if(!iCoordModelMapping->readCoordinateMapping(fname)) + return false; Array mapIds = iCoordModelMapping->getMaps(); if(mapIds.size() == 0) { - result = false; + printf("Fatal error: empty map list!\n"); + return false; } - for(int i=0; i mc; @@ -188,15 +192,23 @@ namespace VMAP { sprintf(buffer, "%03u_%d_%d",mapId,y,x); // Let's flip x and y here dirname = std::string(buffer); + printf("%s...\n",dirname.c_str()); } else { sprintf(buffer, "%03u",mapId); dirname = std::string(buffer); + + // prevent spam for small maps + if(x==0 && y==0) + printf("%s...\n",dirname.c_str()); } - result = fillModelContainerArray(dirname, mapId, x, y, mc); + bool result = fillModelContainerArray(dirname, mapId, x, y, mc); emptyArray(mc); + + if(!result) + return false; } } } @@ -205,91 +217,85 @@ namespace VMAP if(::g_df) fclose(::g_df); #endif - return result; + return true; } //================================================================= bool TileAssembler::fillModelContainerArray(const std::string& pDirFileName, unsigned int pMapId, int pXPos, int pYPos, Array& pMC) { - bool result = true; ModelContainer* modelContainer; NameCollection nameCollection = iCoordModelMapping->getFilenamesForCoordinate(pMapId, pXPos, pYPos); - if(nameCollection.size() > 0) + if(nameCollection.size() == 0) + return true; // no data... + + char dirfilename[500]; + sprintf(dirfilename,"%s/%s.vmdir",iDestDir.c_str(),pDirFileName.c_str()); + FILE *dirfile = fopen(dirfilename, "ab"); + if(!dirfile) { - result = false; - char dirfilename[500]; - sprintf(dirfilename,"%s/%s.vmdir",iDestDir.c_str(),pDirFileName.c_str()); - FILE *dirfile = fopen(dirfilename, "ab"); - if(dirfile) + printf("ERROR: Can't create file %s",dirfilename); + return false; + } + + char destnamebuffer[500]; + char fullnamedestnamebuffer[500]; + + if(nameCollection.iMainFiles.size() >0) + { + sprintf(destnamebuffer,"%03u_%i_%i.vmap",pMapId, pYPos, pXPos); // flip it here too + std::string checkDoubleStr = std::string(dirfilename); + checkDoubleStr.append("##"); + checkDoubleStr.append(std::string(destnamebuffer)); + // Check, if same file already is in the same dir file + if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) { - result = true; - char destnamebuffer[500]; - char fullnamedestnamebuffer[500]; - if(nameCollection.iMainFiles.size() >0) - { - sprintf(destnamebuffer,"%03u_%i_%i.vmap",pMapId, pYPos, pXPos); // flip it here too - std::string checkDoubleStr = std::string(dirfilename); - checkDoubleStr.append("##"); - checkDoubleStr.append(std::string(destnamebuffer)); - // Check, if same file already is in the same dir file - if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) - { - iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); - fprintf(dirfile, "%s\n",destnamebuffer); - sprintf(fullnamedestnamebuffer,"%s/%s",iDestDir.c_str(),destnamebuffer); - modelContainer = processNames(nameCollection.iMainFiles, fullnamedestnamebuffer); - if(modelContainer) - { - pMC.append(modelContainer); - } - else - { - result = false; - } - } - } - // process the large singe files - int pos = 0; - while(result && (pos < nameCollection.iSingeFiles.size())) - { - std::string destFileName = iDestDir; - destFileName.append("/"); - std::string dirEntryName = getDirEntryNameFromModName(pMapId,nameCollection.iSingeFiles[pos]); - std::string checkDoubleStr = std::string(dirfilename); - checkDoubleStr.append("##"); - checkDoubleStr.append(nameCollection.iSingeFiles[pos]); - // Check, if same file already is in the same dir file - if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) - { - iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); - fprintf(dirfile, "%s\n",dirEntryName.c_str()); - destFileName.append(dirEntryName); - - Array positionarray; - positionarray.append(nameCollection.iSingeFiles[pos]); - - if(!iCoordModelMapping->isAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos])) - { - modelContainer = processNames(positionarray, destFileName.c_str()); - iCoordModelMapping->addAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos]); - if(modelContainer) - { - pMC.append(modelContainer); - } - else - { - result = false; - } - } - } - ++pos; - } - fclose(dirfile); + iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); + fprintf(dirfile, "%s\n",destnamebuffer); + sprintf(fullnamedestnamebuffer,"%s/%s",iDestDir.c_str(),destnamebuffer); + modelContainer = processNames(nameCollection.iMainFiles, fullnamedestnamebuffer); + if(modelContainer) + pMC.append(modelContainer); + else + printf("warning: (if) problems in processing data for %s\n",destnamebuffer); } } - return(result); + // process the large singe files + int pos = 0; + while(pos < nameCollection.iSingeFiles.size()) + { + std::string destFileName = iDestDir; + destFileName.append("/"); + std::string dirEntryName = getDirEntryNameFromModName(pMapId,nameCollection.iSingeFiles[pos]); + std::string checkDoubleStr = std::string(dirfilename); + checkDoubleStr.append("##"); + checkDoubleStr.append(nameCollection.iSingeFiles[pos]); + // Check, if same file already is in the same dir file + if(!iCoordModelMapping->isAlreadyProcessedSingleFile(checkDoubleStr)) + { + iCoordModelMapping->addAlreadyProcessedSingleFile(checkDoubleStr); + fprintf(dirfile, "%s\n",dirEntryName.c_str()); + destFileName.append(dirEntryName); + + Array positionarray; + positionarray.append(nameCollection.iSingeFiles[pos]); + + if(!iCoordModelMapping->isAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos])) + { + modelContainer = processNames(positionarray, destFileName.c_str()); + iCoordModelMapping->addAlreadyProcessedSingleFile(nameCollection.iSingeFiles[pos]); + if(modelContainer) + pMC.append(modelContainer); + else + printf("warning: (while) problems in processing data for %s\n",destFileName.c_str()); + } + } + ++pos; + } + + fclose(dirfile); + return true; } //================================================================= @@ -346,8 +352,6 @@ namespace VMAP //================================================================= bool TileAssembler::readRawFile(std::string& pModelFilename, ModelPosition& pModelPosition, AABSPTree *pMainTree) { - bool result = false; - std::string filename = iSrcDir; if(filename.length() >0) filename.append("/"); @@ -363,6 +367,14 @@ namespace VMAP filename.append(baseModelFilename); rf = fopen(filename.c_str(), "rb"); } + + if(!rf) + { + printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str()); + printf("... or form: %s",filename ); + return false; + } + char ident[8]; int trianglecount =0; @@ -379,181 +391,182 @@ namespace VMAP #endif // temporary use defines to simplify read/check code (close file and return at fail) - #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); return(false); } - #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); return(false); } + #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \ + fclose(rf); return(false); } + #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \ + fclose(rf); return(false); } - if(rf) + READ_OR_RETURN(&ident, 8); + if(strcmp(ident, "VMAP001") == 0) { - READ_OR_RETURN(&ident, 8); - if(strcmp(ident, "VMAP001") == 0) - { - // OK, do nothing - } - else if(strcmp(ident, "VMAP002") == 0) - { - // we have to read one int. This is needed during the export and we have to skip it here - int tempNVectors; - READ_OR_RETURN(&tempNVectors, sizeof(int)); - - } - else - { - // wrong version - fclose(rf); - return(false); - } - G3D::uint32 groups; - char blockId[5]; - blockId[4] = 0; - int blocksize; - - READ_OR_RETURN(&groups, sizeof(G3D::uint32)); - - for(int g=0;g<(int)groups;g++) - { - // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...) - Array tempIndexArray; - Array tempVertexArray; - - AABSPTree *gtree = new AABSPTree(); - - // add free gtree at fail - #undef READ_OR_RETURN - #undef CMP_OR_RETURN - #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); delete gtree; return(false); } - #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); delete gtree; return(false); } - - G3D::uint32 flags; - READ_OR_RETURN(&flags, sizeof(G3D::uint32)); - - G3D::uint32 branches; - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "GRP "); - READ_OR_RETURN(&blocksize, sizeof(int)); - READ_OR_RETURN(&branches, sizeof(G3D::uint32)); - for(int b=0;b<(int)branches; b++) - { - G3D::uint32 indexes; - // indexes for each branch (not used jet) - READ_OR_RETURN(&indexes, sizeof(G3D::uint32)); - } - - // ---- indexes - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "INDX"); - READ_OR_RETURN(&blocksize, sizeof(int)); - unsigned int nindexes; - READ_OR_RETURN(&nindexes, sizeof(G3D::uint32)); - if(nindexes >0) - { - unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)]; - READ_OR_RETURN(indexarray, sizeof(unsigned short)); - for(int i=0;i<(int)nindexes; i++) - { - unsigned short val = indexarray[i]; - tempIndexArray.append(val); - } - delete[] indexarray; - } - - // ---- vectors - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "VERT"); - READ_OR_RETURN(&blocksize, sizeof(int)); - unsigned int nvectors; - READ_OR_RETURN(&nvectors, sizeof(int)); - - float *vectorarray = 0; - - // add vectorarray free - #undef READ_OR_RETURN - #undef CMP_OR_RETURN - #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { fclose(rf); delete gtree; delete[] vectorarray; return(false); } - #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { fclose(rf); delete gtree; delete[] vectorarray; return(false); } - - if(nvectors >0) - { - vectorarray = new float[nvectors*sizeof(float)*3]; - READ_OR_RETURN(vectorarray, sizeof(float)*3); - } - // ----- liquit - if(flags & 1) - { - // we have liquit -> not handled yet ... skip - READ_OR_RETURN(&blockId, 4); - CMP_OR_RETURN(blockId, "LIQU"); - READ_OR_RETURN(&blocksize, sizeof(int)); - fseek(rf, blocksize, SEEK_CUR); - } - - - for(unsigned int i=0, indexNo=0; indexNo= startgroup && g <= endgroup) - { - gtree->insert(t); - } - } - - // drop of temporary use defines - #undef READ_OR_RETURN - #undef CMP_OR_RETURN - - if(vectorarray != 0) - { - delete vectorarray; - } - - if(gtree->size() >0) - { - gtree->balance(); - SubModel *sm = new SubModel(gtree); - #ifdef _ASSEMBLER_DEBUG - if(::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); - if(sm->getNTriangles() != gtree->memberTable.size()) - { - if(::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); - } - #endif - sm->setBasePosition(pModelPosition.iPos); - pMainTree->insert(sm); - } - delete gtree; - } - fclose(rf); - result = true; + // OK, do nothing } - return(result); + else if(strcmp(ident, "VMAP002") == 0) + { + // we have to read one int. This is needed during the export and we have to skip it here + int tempNVectors; + READ_OR_RETURN(&tempNVectors, sizeof(int)); + + } + else + { + // wrong version + fclose(rf); + return(false); + } + G3D::uint32 groups; + char blockId[5]; + blockId[4] = 0; + int blocksize; + + READ_OR_RETURN(&groups, sizeof(G3D::uint32)); + + for(int g=0;g<(int)groups;g++) + { + // group MUST NOT have more then 65536 indexes !! Array will have a problem with that !! (strange ...) + Array tempIndexArray; + Array tempVertexArray; + + AABSPTree *gtree = new AABSPTree(); + + // add free gtree at fail + #undef READ_OR_RETURN + #undef CMP_OR_RETURN + #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \ + fclose(rf); delete gtree; return(false); } + #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \ + fclose(rf); delete gtree; return(false); } + + G3D::uint32 flags; + READ_OR_RETURN(&flags, sizeof(G3D::uint32)); + + G3D::uint32 branches; + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "GRP "); + READ_OR_RETURN(&blocksize, sizeof(int)); + READ_OR_RETURN(&branches, sizeof(G3D::uint32)); + for(int b=0;b<(int)branches; b++) + { + G3D::uint32 indexes; + // indexes for each branch (not used jet) + READ_OR_RETURN(&indexes, sizeof(G3D::uint32)); + } + + // ---- indexes + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "INDX"); + READ_OR_RETURN(&blocksize, sizeof(int)); + unsigned int nindexes; + READ_OR_RETURN(&nindexes, sizeof(G3D::uint32)); + if(nindexes >0) + { + unsigned short *indexarray = new unsigned short[nindexes*sizeof(unsigned short)]; + READ_OR_RETURN(indexarray, nindexes*sizeof(unsigned short)); + for(int i=0;i<(int)nindexes; i++) + { + unsigned short val = indexarray[i]; + tempIndexArray.append(val); + } + delete[] indexarray; + } + + // ---- vectors + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "VERT"); + READ_OR_RETURN(&blocksize, sizeof(int)); + unsigned int nvectors; + READ_OR_RETURN(&nvectors, sizeof(int)); + + float *vectorarray = 0; + + // add vectorarray free + #undef READ_OR_RETURN + #undef CMP_OR_RETURN + #define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \ + fclose(rf); delete gtree; delete[] vectorarray; return(false); } + #define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \ + fclose(rf); delete gtree; delete[] vectorarray; return(false); } + + if(nvectors >0) + { + vectorarray = new float[nvectors*sizeof(float)*3]; + READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3); + } + // ----- liquit + if(flags & 1) + { + // we have liquit -> not handled yet ... skip + READ_OR_RETURN(&blockId, 4); + CMP_OR_RETURN(blockId, "LIQU"); + READ_OR_RETURN(&blocksize, sizeof(int)); + fseek(rf, blocksize, SEEK_CUR); + } + + + for(unsigned int i=0, indexNo=0; indexNo= startgroup && g <= endgroup) + { + gtree->insert(t); + } + } + + // drop of temporary use defines + #undef READ_OR_RETURN + #undef CMP_OR_RETURN + + if(vectorarray != 0) + { + delete vectorarray; + } + + if(gtree->size() >0) + { + gtree->balance(); + SubModel *sm = new SubModel(gtree); + #ifdef _ASSEMBLER_DEBUG + if(::g_df) fprintf(::g_df,"group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); + if(sm->getNTriangles() != gtree->memberTable.size()) + { + if(::g_df) fprintf(::g_df,"ERROR !!!! group trianglies: %d, Tris: %d, Nodes: %d, gtree.triangles: %d\n", g, sm->getNTriangles(), sm->getNNodes(), gtree->memberTable.size()); + } + #endif + sm->setBasePosition(pModelPosition.iPos); + pMainTree->insert(sm); + } + delete gtree; + } + fclose(rf); + return true; } //================================================================= bool TileAssembler::fillModelIntoTree(AABSPTree *pMainTree, const Vector3& pBasePos, std::string& pPos, std::string& pModelFilename) { - bool result = false; ModelPosition modelPosition; getModelPosition(pPos, modelPosition); // all should be relative to object base position @@ -561,12 +574,7 @@ namespace VMAP modelPosition.init(); - if(readRawFile(pModelFilename, modelPosition, pMainTree)) - { - result = true; - } - - return result; + return readRawFile(pModelFilename, modelPosition, pMainTree); } //================================================================= From c7c480f6ba2c6f3d900dff37a02a8e5893876e93 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sat, 30 May 2009 04:42:31 +0400 Subject: [PATCH 03/17] [7914] Fixed variable name typos in creature event AI code. Signed-off-by: VladimirMangos --- src/game/CreatureEventAI.cpp | 12 ++++++------ src/game/CreatureEventAI.h | 4 ++-- src/game/CreatureEventAIMgr.cpp | 16 ++++++++-------- src/shared/revision_nr.h | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index bb4b5f139..8d01b7687 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -412,12 +412,12 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 } case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: { - if (action.morph.creatireId || action.morph.modelId) + if (action.morph.creatureId || action.morph.modelId) { //set model based on entry from creature_template - if (action.morph.creatireId) + if (action.morph.creatureId) { - if (CreatureInfo const* ci = GetCreatureTemplateStore(action.morph.creatireId)) + if (CreatureInfo const* ci = GetCreatureTemplateStore(action.morph.creatureId)) { //use default display if (ci->DisplayID_A) @@ -521,12 +521,12 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 Creature* pCreature = NULL; if (action.summon.duration) - pCreature = m_creature->SummonCreature(action.summon.creatured, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); + pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); else - pCreature = m_creature->SummonCreature(action.summon.creatured, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); + pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); if (!pCreature) - sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatured, EventId, m_creature->GetEntry()); + sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, EventId, m_creature->GetEntry()); else if (action.summon.target != TARGET_T_SELF && target) pCreature->AI()->AttackStart(target); break; diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index b5b98e0ca..852d47576 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -193,7 +193,7 @@ struct CreatureEventAI_Action // ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3 struct { - uint32 creatireId; // set one from fields (or 0 for both to demorph) + uint32 creatureId; // set one from fields (or 0 for both to demorph) uint32 modelId; } morph; // ACTION_T_SOUND = 4 @@ -230,7 +230,7 @@ struct CreatureEventAI_Action // ACTION_T_SUMMON = 12 struct { - uint32 creatured; + uint32 creatureId; uint32 target; uint32 duration; } summon; diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp index 5caaa2311..ef84ad5f1 100644 --- a/src/game/CreatureEventAIMgr.cpp +++ b/src/game/CreatureEventAIMgr.cpp @@ -438,19 +438,19 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() } break; case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: - if (action.morph.creatireId !=0 || action.morph.modelId !=0) + if (action.morph.creatureId !=0 || action.morph.modelId !=0) { - if (action.morph.creatireId && !sCreatureStorage.LookupEntry(action.morph.creatireId)) + if (action.morph.creatureId && !sCreatureStorage.LookupEntry(action.morph.creatureId)) { - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatireId); - action.morph.creatireId = 0; + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatureId); + action.morph.creatureId = 0; } if (action.morph.modelId) { - if (action.morph.creatireId) + if (action.morph.creatureId) { - sLog.outErrorDb("CreatureEventAI: Event %u Action %u have unused ModelId %u with also set creature id %u.", i, j+1, action.morph.modelId,action.morph.creatireId); + sLog.outErrorDb("CreatureEventAI: Event %u Action %u have unused ModelId %u with also set creature id %u.", i, j+1, action.morph.modelId,action.morph.creatureId); action.morph.modelId = 0; } else if (!sCreatureDisplayInfoStore.LookupEntry(action.morph.modelId)) @@ -512,8 +512,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() break; } case ACTION_T_SUMMON: - if (!sCreatureStorage.LookupEntry(action.summon.creatured)) - sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatured); + if (!sCreatureStorage.LookupEntry(action.summon.creatureId)) + sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatureId); if (action.summon.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 26d539c2e..8e8d0bccf 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 "7913" + #define REVISION_NR "7914" #endif // __REVISION_NR_H__ From 27057843ac9bc24760d5a5ead655ad84aa6109d0 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sat, 30 May 2009 04:47:44 +0400 Subject: [PATCH 04/17] [7915] Implement more stricted checks and limitations at loading creature addon data. Signed-off-by: VladimirMangos --- src/game/Creature.cpp | 27 +++++++++++++++++++++++++-- src/game/ObjectMgr.cpp | 18 ++++++++++++++++++ src/shared/revision_nr.h | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 47ad3e2ae..24e4f8da8 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1869,10 +1869,33 @@ bool Creature::LoadCreaturesAddon(bool reload) Mount(cainfo->mount); if (cainfo->bytes1 != 0) - SetUInt32Value(UNIT_FIELD_BYTES_1, cainfo->bytes1); + { + // 0 StandState + // 1 FreeTalentPoints Pet only, so always 0 for default creature + // 2 StandFlags + // 3 StandMiscFlags + + SetByteValue(UNIT_FIELD_BYTES_1, 0, uint8(cainfo->bytes1 & 0xFF)); + //SetByteValue(UNIT_FIELD_BYTES_1, 1, uint8((cainfo->bytes1 >> 8) & 0xFF)); + SetByteValue(UNIT_FIELD_BYTES_1, 1, 0); + SetByteValue(UNIT_FIELD_BYTES_1, 2, uint8((cainfo->bytes1 >> 16) & 0xFF)); + SetByteValue(UNIT_FIELD_BYTES_1, 3, uint8((cainfo->bytes1 >> 24) & 0xFF)); + } if (cainfo->bytes2 != 0) - SetUInt32Value(UNIT_FIELD_BYTES_2, cainfo->bytes2); + { + // 0 SheathState + // 1 Bytes2Flags + // 2 UnitRename Pet only, so always 0 for default creature + // 3 ShapeshiftForm Must be determined/set by shapeshift spell/aura + + SetByteValue(UNIT_FIELD_BYTES_2, 0, uint8(cainfo->bytes2 & 0xFF)); + SetByteValue(UNIT_FIELD_BYTES_2, 1, uint8((cainfo->bytes2 >> 8) & 0xFF)); + //SetByteValue(UNIT_FIELD_BYTES_2, 2, uint8((cainfo->bytes2 >> 16) & 0xFF)); + SetByteValue(UNIT_FIELD_BYTES_2, 2, 0); + //SetByteValue(UNIT_FIELD_BYTES_2, 3, uint8((cainfo->bytes2 >> 24) & 0xFF)); + SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); + } if (cainfo->emote != 0) SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 20304eb6c..199daef5b 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -723,6 +723,15 @@ void ObjectMgr::LoadCreatureAddons() if(!addon) continue; + if (addon->mount) + { + if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount)) + sLog.outErrorDb("Creature (Entry %u) have invalid displayInfoId for mount (%u) defined in `creature_template_addon`.",addon->guidOrEntry, addon->mount); + } + + if (!sEmotesStore.LookupEntry(addon->emote)) + sLog.outErrorDb("Creature (Entry %u) have invalid emote (%u) defined in `creature_template_addon`.",addon->guidOrEntry, addon->emote); + ConvertCreatureAddonAuras(const_cast(addon), "creature_template_addon", "Entry"); if(!sCreatureStorage.LookupEntry(addon->guidOrEntry)) @@ -741,6 +750,15 @@ void ObjectMgr::LoadCreatureAddons() if(!addon) continue; + if (addon->mount) + { + if (!sCreatureDisplayInfoStore.LookupEntry(addon->mount)) + sLog.outErrorDb("Creature (GUID %u) have invalid displayInfoId for mount (%u) defined in `creature_addon`.",addon->guidOrEntry, addon->mount); + } + + if (!sEmotesStore.LookupEntry(addon->emote)) + sLog.outErrorDb("Creature (GUID %u) have invalid emote (%u) defined in `creature_addon`.",addon->guidOrEntry, addon->emote); + ConvertCreatureAddonAuras(const_cast(addon), "creature_addon", "GUIDLow"); if(mCreatureDataMap.find(addon->guidOrEntry)==mCreatureDataMap.end()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8e8d0bccf..ec8b4faa7 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 "7914" + #define REVISION_NR "7915" #endif // __REVISION_NR_H__ From 902252c1e91b2063f3caf1d32e0199509b17a580 Mon Sep 17 00:00:00 2001 From: daveh Date: Sat, 30 May 2009 06:08:06 +0400 Subject: [PATCH 05/17] [7916] Fixed pet action bar setup. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 4 +++- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 1e15bbe2e..21371820c 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10319,13 +10319,15 @@ CharmInfo::CharmInfo(Unit* unit) void CharmInfo::InitPetActionBar() { // the first 3 SpellOrActions are attack, follow and stay + // last 3 SpellOrActions are reactions for(uint32 i = 0; i < 3; ++i) { SetActionBar(i,COMMAND_ATTACK - i,ACT_COMMAND); SetActionBar(i + 7,COMMAND_ATTACK - i,ACT_REACTION); } + // middle 4 SpellOrActions are spells/special attacks/abilities for(uint32 i = 0; i < 4; ++i) - SetActionBar(i,0,ACT_DISABLED); + SetActionBar(i + 3,0,ACT_DISABLED); } void CharmInfo::InitEmptyActionBar() diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ec8b4faa7..7f5ea538d 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 "7915" + #define REVISION_NR "7916" #endif // __REVISION_NR_H__ From e8cd008005f92f7860eaa0ea59a18396fdaa461a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 30 May 2009 07:39:46 +0400 Subject: [PATCH 06/17] [7917] Spell effect with SPELL_AURA_MOD_SPELL_CRIT_CHANCE always possitive with possitive aura value. --- src/game/SpellMgr.cpp | 6 ++++-- src/shared/revision_nr.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 8626f133d..3f81cac5f 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -339,11 +339,13 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) case SPELL_AURA_MOD_STAT: case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative) case SPELL_AURA_MOD_HEALING_DONE: - { if(spellproto->CalculateSimpleValue(effIndex) < 0) return false; break; - } + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: + if(spellproto->CalculateSimpleValue(effIndex) > 0) + return true; // some expected possitive spells have SPELL_ATTR_EX_NEGATIVE + break; case SPELL_AURA_ADD_TARGET_TRIGGER: return true; case SPELL_AURA_PERIODIC_TRIGGER_SPELL: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7f5ea538d..710f21825 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 "7916" + #define REVISION_NR "7917" #endif // __REVISION_NR_H__ From 2a27a44e2a5de54dbac20060a399fa18af80ef9a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 30 May 2009 22:37:31 +0400 Subject: [PATCH 07/17] [7918] Improve portability in work with uint64 string format specifiers and in code literals. * Replace platform seelction MaNGOS code for select format descriptor for uint64 by using ACE define. I64FMTD renamed to UI64FMTD for more clear name. * Add new define UI64LIT (base at ACE seelction) for build portables uint64 literals. Please always use UI64LIT(0x00001) instead less portable 0x00001LL --- src/game/ArenaTeamHandler.cpp | 2 +- src/game/AuctionHouseHandler.cpp | 3 +- src/game/AuctionHouseMgr.cpp | 2 +- src/game/BattleGround.cpp | 14 ++-- src/game/BattleGroundEY.cpp | 4 +- src/game/BattleGroundHandler.cpp | 4 +- src/game/BattleGroundMgr.cpp | 4 +- src/game/CharacterHandler.cpp | 2 +- src/game/Group.cpp | 2 +- src/game/Guild.cpp | 8 +- src/game/InstanceSaveMgr.cpp | 16 ++-- src/game/Level1.cpp | 2 +- src/game/Level2.cpp | 2 +- src/game/Mail.cpp | 2 +- src/game/Map.cpp | 10 +-- src/game/MiscHandler.cpp | 12 +-- src/game/MovementHandler.cpp | 2 +- src/game/Object.cpp | 2 +- src/game/ObjectAccessor.h | 2 +- src/game/ObjectDefines.h | 10 +-- src/game/ObjectMgr.cpp | 10 +-- src/game/Pet.cpp | 4 +- src/game/PetHandler.cpp | 8 +- src/game/Player.cpp | 22 ++--- src/game/Player.h | 84 +++++++++---------- src/game/Spell.cpp | 35 ++++---- src/game/SpellAuras.cpp | 102 ++++++++++++----------- src/game/SpellEffects.cpp | 134 +++++++++++++++---------------- src/game/SpellMgr.cpp | 70 ++++++++-------- src/game/SpellMgr.h | 18 ++--- src/game/Unit.cpp | 118 +++++++++++++-------------- src/game/World.cpp | 4 +- src/game/WorldSession.cpp | 4 +- src/shared/Common.h | 12 ++- src/shared/Database/Field.h | 2 +- src/shared/revision_nr.h | 2 +- 36 files changed, 372 insertions(+), 362 deletions(-) diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp index f042f2551..1c5ec74eb 100644 --- a/src/game/ArenaTeamHandler.cpp +++ b/src/game/ArenaTeamHandler.cpp @@ -34,7 +34,7 @@ void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data) uint64 guid; recv_data >> guid; - sLog.outDebug("Inspect Arena stats " I64FMTD, guid); + sLog.outDebug("Inspect Arena stats (GUID: %u TypeId: %u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); if(Player *plr = objmgr.GetPlayer(guid)) { diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index d37b1b731..f65b863ad 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -606,7 +606,8 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap( pCreature->getFaction() ); - //sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); + //sLog.outDebug("Auctionhouse search (GUID: %u TypeId: %u)", , list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", + // GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) ); uint32 count = 0; diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index 3fdbcd378..ed8a05963 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -682,6 +682,6 @@ void AuctionEntry::SaveToDB() const { //No SQL injection (no strings) CharacterDatabase.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) " - "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u')", + "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u')", Id, auctioneer, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit); } diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index e2c513700..bc0b7a58e 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -465,7 +465,7 @@ void BattleGround::SendPacketToAll(WorldPacket *packet) if (plr) plr->GetSession()->SendPacket(packet); else - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); } } @@ -477,7 +477,7 @@ void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player * if (!plr) { - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -509,7 +509,7 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID) if (!plr) { - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -532,7 +532,7 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID) if (!plr) { - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -552,7 +552,7 @@ void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID) if (!plr) { - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -577,7 +577,7 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, if (!plr) { - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -676,7 +676,7 @@ void BattleGround::EndBattleGround(uint32 winner) else loser_arena_team->OfflineMemberLost(itr->first, winner_rating); } - sLog.outError("BattleGround: Player " I64FMTD " not found!", itr->first); + sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index efb62e627..7a63b6729 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -143,7 +143,7 @@ void BattleGroundEY::CheckSomeoneJoinedPoint() Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]); if (!plr) { - sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[EY_POINTS_MAX][j]); + sLog.outError("BattleGroundEY: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[EY_POINTS_MAX][j])); ++j; continue; } @@ -183,7 +183,7 @@ void BattleGroundEY::CheckSomeoneLeftPoint() Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[i][j]); if (!plr) { - sLog.outError("BattleGroundEY: Player " I64FMTD " not found!", m_PlayersNearPoint[i][j]); + sLog.outError("BattleGroundEY: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j])); //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]); m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j); diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 3495e5bb6..680d630ad 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -38,7 +38,7 @@ void WorldSession::HandleBattlemasterHelloOpcode( WorldPacket & recv_data ) uint64 guid; recv_data >> guid; - sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from: " I64FMT, guid); + sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) @@ -93,7 +93,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); - sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT, guid); + sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); // can do this, since it's battleground, not arena BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0); diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 2f162bf02..b31a0beb3 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -1188,7 +1188,7 @@ void BattleGroundMgr::Update(uint32 diff) { DistributeArenaPoints(); m_NextAutoDistributionTime = time_t(sWorld.GetGameTime() + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS)); - CharacterDatabase.PExecute("UPDATE saved_variables SET NextArenaPointDistributionTime = '"I64FMTD"'", uint64(m_NextAutoDistributionTime)); + CharacterDatabase.PExecute("UPDATE saved_variables SET NextArenaPointDistributionTime = '"UI64FMTD"'", uint64(m_NextAutoDistributionTime)); } m_AutoDistributionTimeChecker = 600000; // check 10 minutes } @@ -1759,7 +1759,7 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution() { sLog.outDebug("Battleground: Next arena point distribution time not found in SavedVariables, reseting it now."); m_NextAutoDistributionTime = time_t(sWorld.GetGameTime() + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS)); - CharacterDatabase.PExecute("INSERT INTO saved_variables (NextArenaPointDistributionTime) VALUES ('"I64FMTD"')", uint64(m_NextAutoDistributionTime)); + CharacterDatabase.PExecute("INSERT INTO saved_variables (NextArenaPointDistributionTime) VALUES ('"UI64FMTD"')", uint64(m_NextAutoDistributionTime)); } else { diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index c6c0e9ee2..08b4cba3f 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -70,7 +70,7 @@ bool LoginQueryHolder::Initialize() res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" I64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHOMEBIND, "SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(m_guid)); diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 484e5fde7..0e4cb4e87 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -105,7 +105,7 @@ bool Group::Create(const uint64 &guid, const char * name) CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid)); CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid)); CharacterDatabase.PExecute("INSERT INTO groups(leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,isRaid,difficulty) " - "VALUES('%u','%u','%u','%u','%u','%u','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','" I64FMTD "','%u','%u')", + "VALUES('%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u')", GUID_LOPART(m_leaderGuid), GUID_LOPART(m_mainTank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod), GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), m_difficulty); } diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index d97616270..a4c4a2657 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -82,7 +82,7 @@ bool Guild::create(Player* leader, std::string gname) CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid='%u'", Id); CharacterDatabase.PExecute("DELETE FROM guild_member WHERE guildid='%u'", Id); CharacterDatabase.PExecute("INSERT INTO guild (guildid,name,leaderguid,info,motd,createdate,EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor,BankMoney) " - "VALUES('%u','%s','%u', '%s', '%s', NOW(),'%u','%u','%u','%u','%u','" I64FMTD "')", + "VALUES('%u','%s','%u', '%s', '%s', NOW(),'%u','%u','%u','%u','%u','" UI64FMTD "')", Id, gname.c_str(), GUID_LOPART(leaderGuid), dbGINFO.c_str(), dbMOTD.c_str(), EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, guildbank_money); CharacterDatabase.CommitTransaction(); @@ -916,7 +916,7 @@ void Guild::LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid // Add entry to map m_GuildEventlog.push_back(NewEvent); // Add new eventlog entry into DB - CharacterDatabase.PExecute("INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" I64FMTD "')", + CharacterDatabase.PExecute("INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "')", Id, NewEvent->LogGuid, uint32(NewEvent->EventType), NewEvent->PlayerGuid1, NewEvent->PlayerGuid2, uint32(NewEvent->NewRank), NewEvent->TimeStamp); } @@ -1299,7 +1299,7 @@ void Guild::SetBankMoney(int64 money) money = 0; guildbank_money = money; - CharacterDatabase.PExecute("UPDATE guild SET BankMoney='" I64FMTD "' WHERE guildid='%u'", money, Id); + CharacterDatabase.PExecute("UPDATE guild SET BankMoney='" UI64FMTD "' WHERE guildid='%u'", money, Id); } // ************************************************* @@ -1665,7 +1665,7 @@ void Guild::LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint } m_GuildBankEventLog_Item[TabId].push_back(NewEvent); } - CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,LogEntry,TabId,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" I64FMTD "')", + CharacterDatabase.PExecute("INSERT INTO guild_bank_eventlog (guildid,LogGuid,LogEntry,TabId,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')", Id, NewEvent->LogGuid, uint32(NewEvent->LogEntry), uint32(TabId), NewEvent->PlayerGuid, NewEvent->ItemOrMoney, uint32(NewEvent->ItemStackCount), uint32(NewEvent->DestTabId), NewEvent->TimeStamp); } diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index f6f8060b4..193bb8e00 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -130,7 +130,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) { // save the resettime for normal instances only when they get unloaded if(time_t resettime = itr->second->GetResetTimeForDB()) - CharacterDatabase.PExecute("UPDATE instance SET resettime = '"I64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId); + CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId); delete itr->second; m_instanceSaveById.erase(itr); } @@ -168,7 +168,7 @@ void InstanceSave::SaveToDB() } } - CharacterDatabase.PExecute("INSERT INTO instance VALUES ('%u', '%u', '"I64FMTD"', '%u', '%s')", m_instanceid, GetMapId(), (uint64)GetResetTimeForDB(), GetDifficulty(), data.c_str()); + CharacterDatabase.PExecute("INSERT INTO instance VALUES ('%u', '%u', '"UI64FMTD"', '%u', '%s')", m_instanceid, GetMapId(), (uint64)GetResetTimeForDB(), GetDifficulty(), data.c_str()); } time_t InstanceSave::GetResetTimeForDB() @@ -395,7 +395,7 @@ void InstanceSaveManager::LoadResetTimes() ResetTimeMapType::iterator itr = InstResetTime.find(instance); if(itr != InstResetTime.end() && itr->second.second != resettime) { - CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"I64FMTD"' WHERE id = '%u'", uint64(resettime), instance); + CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } @@ -430,7 +430,7 @@ void InstanceSaveManager::LoadResetTimes() uint64 oldresettime = fields[1].GetUInt64(); uint64 newresettime = (oldresettime / DAY) * DAY + diff; if(oldresettime != newresettime) - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"I64FMTD"' WHERE mapid = '%u'", newresettime, mapid); + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u'", newresettime, mapid); m_resetTimeByMapId[mapid] = newresettime; } while(result->NextRow()); @@ -439,7 +439,7 @@ void InstanceSaveManager::LoadResetTimes() // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times - _DelHelper(CharacterDatabase, "id, map, difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map WHERE (instance.resettime < '"I64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"I64FMTD"')", (uint64)now, (uint64)now); + _DelHelper(CharacterDatabase, "id, map, difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map WHERE (instance.resettime < '"UI64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"UI64FMTD"')", (uint64)now, (uint64)now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue @@ -459,7 +459,7 @@ void InstanceSaveManager::LoadResetTimes() { // initialize the reset time t = today + period + diff; - CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','"I64FMTD"')", i, (uint64)t); + CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','"UI64FMTD"')", i, (uint64)t); } if(t < now) @@ -468,7 +468,7 @@ void InstanceSaveManager::LoadResetTimes() // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"I64FMTD"' WHERE mapid = '%u'", (uint64)t, i); + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u'", (uint64)t, i); } m_resetTimeByMapId[temp->map] = t; @@ -611,7 +611,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe uint32 period = temp->reset_delay * DAY; uint64 next_reset = ((now + timeLeft + MINUTE) / DAY * DAY) + period + diff; // update it in the DB - CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"I64FMTD"' WHERE mapid = '%d'", next_reset, mapid); + CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%d'", next_reset, mapid); } MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 699cb275b..dff44d6d0 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -642,7 +642,7 @@ bool ChatHandler::HandleModifyKnownTitlesCommand(const char* args) uint64 titles = 0; - sscanf((char*)args, I64FMTD, &titles); + sscanf((char*)args, UI64FMTD, &titles); Player *chr = getSelectedPlayer(); if (!chr) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index de471e626..03e8e5bcb 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -84,7 +84,7 @@ bool ChatHandler::HandleMuteCommand(const char* args) if (target) target->GetSession()->m_muteTime = mutetime; - loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); + loginDatabase.PExecute("UPDATE account SET mutetime = " UI64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); if(target) ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index 72fe5946a..0d9079269 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.cpp @@ -873,7 +873,7 @@ void WorldSession::SendMailTo(Player* receiver, uint8 messageType, uint8 station CharacterDatabase.BeginTransaction(); CharacterDatabase.escape_string(subject); CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) " - "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" I64FMTD "','" I64FMTD "', '%u', '%u', '%d')", + "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')", mailId, messageType, stationery, mailTemplateId, sender_guidlow_or_entry, receiver_guidlow, subject.c_str(), itemTextId, (mi && !mi->empty() ? 1 : 0), (uint64)expire_time, (uint64)deliver_time, money, COD, checked); if(mi) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 66bf78e35..3882fdcfc 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -428,7 +428,7 @@ Map::Add(T *obj) if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { - sLog.outError("Map::Add: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + sLog.outError("Map::Add: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); return; } @@ -482,7 +482,7 @@ void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg) if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { - sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + sLog.outError("Map::MessageBroadcast: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); return; } @@ -527,7 +527,7 @@ void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist) if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { - sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + sLog.outError("Map::MessageBroadcast: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); return; } @@ -732,7 +732,7 @@ Map::Remove(T *obj, bool remove) CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { - sLog.outError("Map::Remove: Object " I64FMT " have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); + sLog.outError("Map::Remove: Object (GUID: %u TypeId:%u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); return; } @@ -740,7 +740,7 @@ Map::Remove(T *obj, bool remove) if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) return; - DEBUG_LOG("Remove object " I64FMT " from grid[%u,%u]", obj->GetGUID(), cell.data.Part.grid_x, cell.data.Part.grid_y); + DEBUG_LOG("Remove object (GUID: %u TypeId:%u) from grid[%u,%u]", obj->GetGUIDLow(), obj->GetTypeId(), cell.data.Part.grid_x, cell.data.Part.grid_y); NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); assert( grid != NULL ); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index ba3912d0c..8816d25ee 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1076,8 +1076,8 @@ void WorldSession::HandleMoveUnRootAck(WorldPacket&/* recv_data*/) recv_data >> Orientation; // TODO for later may be we can use for anticheat - DEBUG_LOG("Guid " I64FMTD,guid); - DEBUG_LOG("unknown1 " I64FMTD,unknown1); + DEBUG_LOG("Guid " UI64FMTD,guid); + DEBUG_LOG("unknown1 " UI64FMTD,unknown1); DEBUG_LOG("unknown2 %u",unknown2); DEBUG_LOG("X %f",PositionX); DEBUG_LOG("Y %f",PositionY); @@ -1110,8 +1110,8 @@ void WorldSession::HandleMoveRootAck(WorldPacket&/* recv_data*/) recv_data >> Orientation; // for later may be we can use for anticheat - DEBUG_LOG("Guid " I64FMTD,guid); - DEBUG_LOG("unknown1 " I64FMTD,unknown1); + DEBUG_LOG("Guid " UI64FMTD,guid); + DEBUG_LOG("unknown1 " UI64FMTD,unknown1); DEBUG_LOG("unknown1 %u",unknown2); DEBUG_LOG("X %f",PositionX); DEBUG_LOG("Y %f",PositionY); @@ -1166,7 +1166,7 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data) uint64 guid; recv_data >> guid; - DEBUG_LOG("Inspected guid is " I64FMTD, guid); + DEBUG_LOG("Inspected guid is (GUID: %u TypeId: %u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); _player->SetSelection(guid); @@ -1456,7 +1456,7 @@ void WorldSession::HandleFarSightOpcode( WorldPacket & recv_data ) sLog.outDebug("Removed FarSight from player %u", _player->GetGUIDLow()); break; case 1: - sLog.outDebug("Added FarSight " I64FMT " to player %u", _player->GetFarSight(), _player->GetGUIDLow()); + sLog.outDebug("Added FarSight (GUID:%u TypeId:%u) to player %u", GUID_LOPART(_player->GetFarSight()), GuidHigh2TypeId(GUID_HIPART(_player->GetFarSight())), _player->GetGUIDLow()); break; } } diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 3e5f39a0b..de51a1473 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -171,7 +171,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) recv_data >> guid; recv_data >> flags >> time; - DEBUG_LOG("Guid " I64FMTD,guid); + DEBUG_LOG("Guid " UI64FMTD,guid); DEBUG_LOG("Flags %u, time %u",flags, time/IN_MILISECONDS); Unit *mover = _player->m_mover; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 5b3d9ef4f..6256ba5c8 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -89,7 +89,7 @@ Object::~Object( ) if(IsInWorld()) { ///- Do NOT call RemoveFromWorld here, if the object is a player it will crash - sLog.outError("Object::~Object - guid="I64FMTD", typeid=%d deleted but still in world!!", GetGUID(), GetTypeId()); + sLog.outError("Object::~Object (GUID: %u TypeId: %u) deleted but still in world!!", GetGUIDLow(), GetTypeId()); //assert(0); } diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index e034cbf94..60a49cd7c 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -125,7 +125,7 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::SingletonGetPositionX(),obj->GetPositionY()); if(q.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || q.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { - sLog.outError("ObjectAccessor::GetObjecInWorld: object "I64FMTD" has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord); + sLog.outError("ObjectAccessor::GetObjecInWorld: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord); return NULL; } diff --git a/src/game/ObjectDefines.h b/src/game/ObjectDefines.h index ea2392aee..c092f1099 100644 --- a/src/game/ObjectDefines.h +++ b/src/game/ObjectDefines.h @@ -23,8 +23,8 @@ // used for creating values for respawn for example #define MAKE_PAIR64(l, h) uint64( uint32(l) | ( uint64(h) << 32 ) ) -#define PAIR64_HIPART(x) (uint32)((uint64(x) >> 32) & 0x00000000FFFFFFFFLL) -#define PAIR64_LOPART(x) (uint32)(uint64(x) & 0x00000000FFFFFFFFLL) +#define PAIR64_HIPART(x) (uint32)((uint64(x) >> 32) & UI64LIT(0x00000000FFFFFFFF)) +#define PAIR64_LOPART(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF)) #define MAKE_PAIR32(l, h) uint32( uint16(l) | ( uint32(h) << 16 ) ) #define PAIR32_HIPART(x) (uint16)((uint32(x) >> 16) & 0x0000FFFF) @@ -70,9 +70,9 @@ enum HighGuid // We have different low and middle part size for different guid types #define _GUID_ENPART_2(x) 0 -#define _GUID_ENPART_3(x) (uint32)((uint64(x) >> 24) & 0x0000000000FFFFFFLL) -#define _GUID_LOPART_2(x) (uint32)(uint64(x) & 0x00000000FFFFFFFFLL) -#define _GUID_LOPART_3(x) (uint32)(uint64(x) & 0x0000000000FFFFFFLL) +#define _GUID_ENPART_3(x) (uint32)((uint64(x) >> 24) & UI64LIT(0x0000000000FFFFFF)) +#define _GUID_LOPART_2(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF)) +#define _GUID_LOPART_3(x) (uint32)(uint64(x) & UI64LIT(0x0000000000FFFFFF)) inline bool IsGuidHaveEnPart(uint64 const& guid) { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 199daef5b..fa7598956 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -4300,9 +4300,9 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) sLog.outDebug("Returning mails current time: hour: %d, minute: %d, second: %d ", localtime(&basetime)->tm_hour, localtime(&basetime)->tm_min, localtime(&basetime)->tm_sec); //delete all old mails without item and without body immediately, if starting server if (!serverUp) - CharacterDatabase.PExecute("DELETE FROM mail WHERE expire_time < '" I64FMTD "' AND has_items = '0' AND itemTextId = 0", (uint64)basetime); + CharacterDatabase.PExecute("DELETE FROM mail WHERE expire_time < '" UI64FMTD "' AND has_items = '0' AND itemTextId = 0", (uint64)basetime); // 0 1 2 3 4 5 6 7 8 9 - QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" I64FMTD "'", (uint64)basetime); + QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" UI64FMTD "'", (uint64)basetime); if ( !result ) { barGoLink bar(1); @@ -4377,7 +4377,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) else { //mail will be returned: - CharacterDatabase.PExecute("UPDATE mail SET sender = '%u', receiver = '%u', expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',cod = '0', checked = '%u' WHERE id = '%u'", m->receiver, m->sender, (uint64)(basetime + 30*DAY), (uint64)basetime, MAIL_CHECK_MASK_RETURNED, m->messageID); + CharacterDatabase.PExecute("UPDATE mail SET sender = '%u', receiver = '%u', expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',cod = '0', checked = '%u' WHERE id = '%u'", m->receiver, m->sender, (uint64)(basetime + 30*DAY), (uint64)basetime, MAIL_CHECK_MASK_RETURNED, m->messageID); delete m; continue; } @@ -6030,7 +6030,7 @@ void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = t; WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); if(t) - WorldDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance); + WorldDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" UI64FMTD "', '%u' )", loguid, uint64(t), instance); } void ObjectMgr::DeleteCreatureData(uint32 guid) @@ -6048,7 +6048,7 @@ void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t) mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = t; WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); if(t) - WorldDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" I64FMTD "', '%u' )", loguid, uint64(t), instance); + WorldDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" UI64FMTD "', '%u' )", loguid, uint64(t), instance); } void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 078c9c843..1b1905110 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1077,7 +1077,7 @@ void Pet::_SaveSpellCooldowns() m_CreatureSpellCooldowns.erase(itr++); else { - CharacterDatabase.PExecute("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" I64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second)); + CharacterDatabase.PExecute("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" UI64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second)); ++itr; } } @@ -1250,7 +1250,7 @@ void Pet::_SaveAuras() if (i == 3) { CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) " - "VALUES ('%u', '" I64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')", + "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')", m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges())); } } diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 82930fee7..3080f6f13 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -66,7 +66,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { - sLog.outError("WorldSession::HandlePetAction: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } @@ -344,7 +344,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { - sLog.outError("WorldSession::HandlePetSetAction: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + sLog.outError("WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } @@ -515,7 +515,7 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket) CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { - sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + sLog.outError("WorldSession::HandlePetUnlearnOpcode: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } pet->resetTalents(); @@ -553,7 +553,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) CharmInfo *charmInfo = pet->GetCharmInfo(); if(!charmInfo) { - sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); + sLog.outError("WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); return; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 1cacbe52b..86de2cb0b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3352,7 +3352,7 @@ void Player::_SaveSpellCooldowns() m_spellCooldowns.erase(itr++); else if(itr->second.end <= infTime) // not save locked cooldowns, it will be reset or set at reload { - CharacterDatabase.PExecute("INSERT INTO character_spell_cooldown (guid,spell,item,time) VALUES ('%u', '%u', '%u', '" I64FMTD "')", GetGUIDLow(), itr->first, itr->second.itemid, uint64(itr->second.end)); + CharacterDatabase.PExecute("INSERT INTO character_spell_cooldown (guid,spell,item,time) VALUES ('%u', '%u', '%u', '" UI64FMTD "')", GetGUIDLow(), itr->first, itr->second.itemid, uint64(itr->second.end)); ++itr; } else @@ -14790,7 +14790,7 @@ void Player::_LoadMailedItems(Mail *mail) void Player::_LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery) { //set a count of unread mails - //QueryResult *resultMails = CharacterDatabase.PQuery("SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" I64FMTD "'", GUID_LOPART(playerGuid),(uint64)cTime); + //QueryResult *resultMails = CharacterDatabase.PQuery("SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(playerGuid),(uint64)cTime); if (resultUnread) { Field *fieldMail = resultUnread->Fetch(); @@ -15589,7 +15589,7 @@ void Player::_SaveAuras() if (i == 3) { CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) " - "VALUES ('%u', '" I64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')", + "VALUES ('%u', '" UI64FMTD "' ,'%u', '%u', '%u', '%d', '%d', '%d', '%d')", GetGUIDLow(), itr2->second->GetCasterGUID(), (uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges())); } } @@ -15696,7 +15696,7 @@ void Player::_SaveMail() Mail *m = (*itr); if (m->state == MAIL_STATE_CHANGED) { - CharacterDatabase.PExecute("UPDATE mail SET itemTextId = '%u',has_items = '%u',expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'", + CharacterDatabase.PExecute("UPDATE mail SET itemTextId = '%u',has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'", m->itemTextId, m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID); if(m->removedItems.size()) { @@ -15744,11 +15744,11 @@ void Player::_SaveQuestStatus() { case QUEST_NEW : CharacterDatabase.PExecute("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) " - "VALUES ('%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", + "VALUES ('%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILISECONDS+ sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]); break; case QUEST_CHANGED : - CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" I64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ", + CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" UI64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ", i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILISECONDS + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first ); break; case QUEST_UNCHANGED: @@ -15771,7 +15771,7 @@ void Player::_SaveDailyQuestStatus() CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow()); for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) if(GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) - CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" I64FMTD "')", + CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" UI64FMTD "')", GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime)); } @@ -16465,7 +16465,7 @@ void Player::PossessSpellInitialize() if(!charmInfo) { - sLog.outError("Player::PossessSpellInitialize(): charm ("I64FMTD") has no charminfo!", charm->GetGUID()); + sLog.outError("Player::PossessSpellInitialize(): charm (GUID: %u TypeId: %u) has no charminfo!", charm->GetGUIDLow(),charm->GetTypeId()); return; } @@ -16493,7 +16493,7 @@ void Player::CharmSpellInitialize() CharmInfo *charmInfo = charm->GetCharmInfo(); if(!charmInfo) { - sLog.outError("Player::CharmSpellInitialize(): the player's charm ("I64FMTD") has no charminfo!", charm->GetGUID()); + sLog.outError("Player::CharmSpellInitialize(): the player's charm (GUID: %u TypeId: %u) has no charminfo!", charm->GetGUIDLow(),charm->GetTypeId()); return; } @@ -19957,9 +19957,9 @@ void Player::UpdateKnownCurrencies(uint32 itemId, bool apply) if(CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId)) { if(apply) - SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(1LL << (ctEntry->BitIndex-1))); + SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(UI64LIT(1) << (ctEntry->BitIndex-1))); else - RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(1LL << (ctEntry->BitIndex-1))); + RemoveFlag64(PLAYER_FIELD_KNOWN_CURRENCIES,(UI64LIT(1) << (ctEntry->BitIndex-1))); } } diff --git a/src/game/Player.h b/src/game/Player.h index 4d85a3585..21874aa61 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -402,48 +402,48 @@ enum PlayerFlags // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<SpellFamilyName) { case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard triggers need do it - if (m_spellInfo->SpellFamilyFlags & 0x0000000000200080LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000200080)) m_canTrigger = true; break; case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it - if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000800000000060)) m_canTrigger = true; break; case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it - if (m_spellInfo->SpellFamilyFlags & 0x0001800000000000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0001800000000000)) m_canTrigger = true; break; case SPELLFAMILY_ROGUE: // For poisons need do it - if (m_spellInfo->SpellFamilyFlags & 0x000000101001E000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000000101001E000)) m_canTrigger = true; break; case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect/Explosive Shot - if (m_spellInfo->SpellFamilyFlags & 0x0100200000000214LL || + if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0100200000000214)) || m_spellInfo->SpellFamilyFlags2 & 0x200) m_canTrigger = true; break; case SPELLFAMILY_PALADIN: // For Judgements (all) / Holy Shock triggers need do it - if (m_spellInfo->SpellFamilyFlags & 0x0001000900B80400LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0001000900B80400)) m_canTrigger = true; break; default: @@ -837,7 +837,7 @@ void Spell::prepareDataForTriggerSystem() } // Hunter traps spells (for Entrapment trigger) // Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap .... - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->SpellFamilyFlags & 0x000020000000001CLL) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000020000000001C))) m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION; } @@ -894,7 +894,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex) m_delayMoment = target.timeDelay; } else - target.timeDelay = 0LL; + target.timeDelay = UI64LIT(0); // If target reflect spell back to caster if (target.missCondition == SPELL_MISS_REFLECT) @@ -957,7 +957,7 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex) m_delayMoment = target.timeDelay; } else - target.timeDelay = 0LL; + target.timeDelay = UI64LIT(0); // Add target to list m_UniqueGOTargetInfo.push_back(target); @@ -1079,7 +1079,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) caster->DealSpellDamage(&damageInfo, true); // Judgement of Blood - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000800000000)) && m_spellInfo->SpellIconID==153) { int32 damagePoint = damageInfo.damage * 33 / 100; m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true); @@ -1371,7 +1371,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) { case SPELLFAMILY_DRUID: // Starfall - if (m_spellInfo->SpellFamilyFlags2 & 0x00000100LL) + if (m_spellInfo->SpellFamilyFlags2 & UI64LIT(0x00000100)) unMaxTargets = 2; break; default: @@ -2393,7 +2393,8 @@ void Spell::cast(bool skipCheck) } case SPELLFAMILY_MAGE: { - if (m_spellInfo->SpellFamilyFlags&0x0000008000000000LL) // Ice Block + // Ice Block + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000008000000000)) m_preCastSpell = 41425; // Hypothermia break; } @@ -2408,7 +2409,8 @@ void Spell::cast(bool skipCheck) } case SPELLFAMILY_PALADIN: { - if (m_spellInfo->SpellFamilyFlags&0x0000000000400080LL) // Divine Shield, Divine Protection or Hand of Protection + // Divine Shield, Divine Protection or Hand of Protection + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400080)) m_preCastSpell = 25771; // Forbearance break; } @@ -3861,9 +3863,8 @@ SpellCastResult Spell::CheckCast(bool strict) { //Exclusion for Pounce: Facing Limitation was removed in 2.0.1, but it still uses the same, old Ex-Flags //Exclusion for Mutilate:Facing Limitation was removed in 2.0.1 and 3.0.3, but they still use the same, old Ex-Flags - if( (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL) && - (m_spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE || m_spellInfo->SpellFamilyFlags != 0x0020000000000000LL) - ) + if ((m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || (m_spellInfo->SpellFamilyFlags != UI64LIT(0x0000000000020000))) && + (m_spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE || (m_spellInfo->SpellFamilyFlags != UI64LIT(0x0020000000000000)))) { SendInterrupted(2); return SPELL_FAILED_NOT_BEHIND; @@ -5380,7 +5381,7 @@ bool Spell::CheckTargetCreatureType(Unit* target) const uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType; // Curse of Doom : not find another way to fix spell target check :/ - if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags == 0x0200000000LL) + if(m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags == UI64LIT(0x0200000000)) { // not allow cast at player if(target->GetTypeId()==TYPEID_PLAYER) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index fe1fff83a..58e2d36dd 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -983,19 +983,19 @@ void Aura::_AddAura() m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true); // Faerie Fire (druid versions) - if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400))) m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true); // Victorious - if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000))) m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true); // Swiftmend state on Regrowth & Rejuvenation - if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x50 ) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (m_spellProto->SpellFamilyFlags & UI64LIT(0x50))) m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true); // Deadly poison aura state - if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags & 0x10000) + if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellProto->SpellFamilyFlags & UI64LIT(0x10000))) m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true); // Enrage aura state @@ -1083,28 +1083,28 @@ void Aura::_RemoveAura() removeState = AURA_STATE_JUDGEMENT; // Update Seals information break; case SPELLFAMILY_WARLOCK: - if(m_spellProto->SpellFamilyFlags & 4) + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x4)) removeState = AURA_STATE_IMMOLATE; // Conflagrate aura state break; case SPELLFAMILY_DRUID: - if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400)) removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) - else if(m_spellProto->SpellFamilyFlags & 0x50) + else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50)) { removeFamilyFlag = 0x50; removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state } break; case SPELLFAMILY_WARRIOR: - if(m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000)) removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious break; case SPELLFAMILY_ROGUE: - if(m_spellProto->SpellFamilyFlags & 0x10000) + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000)) removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state break; case SPELLFAMILY_HUNTER: - if(m_spellProto->SpellFamilyFlags & 0x1000000000000000LL) + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) } @@ -1295,7 +1295,7 @@ void Aura::HandleAddModifier(bool apply, bool Real) ((Player*)m_target)->AddSpellMod(m_spellmod, apply); // reapply some passive spells after add/remove related spellmods - if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL)) + if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & UI64LIT(0x0000100000000000))) { m_target->RemoveAurasDueToSpell(45471); @@ -1910,7 +1910,7 @@ void Aura::TriggerSpell() { SpellEntry const* spell = itr->second->GetSpellProto(); if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN && - spell->SpellFamilyFlags & 0x0000000000000400L) + (spell->SpellFamilyFlags & UI64LIT(0x0000000000000400))) return; } target->RemoveAurasDueToSpell(28820); @@ -2077,7 +2077,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // Earth Shield - if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & 0x40000000000LL)) + if ( caster && GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) { // prevent double apply bonuses if(m_target->GetTypeId() != TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) @@ -2158,14 +2158,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real) { // Stop caster Arcane Missle chanelling on death if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE && - m_spellProto->SpellFamilyFlags&0x0000000000000800LL) + (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000800))) { caster->InterruptSpell(CURRENT_CHANNELED_SPELL); return; } // Stop caster Penance chanelling on death if (m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && - m_spellProto->SpellFamilyFlags2 & 0x00000080) + (m_spellProto->SpellFamilyFlags2 & UI64LIT(0x00000080))) { caster->InterruptSpell(CURRENT_CHANNELED_SPELL); return; @@ -2291,8 +2291,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real) mod->value = m_modifier.m_amount; mod->type = SPELLMOD_PCT; mod->spellId = GetId(); - mod->mask = 0x0000200000000000LL; - mod->mask2= 0LL; + mod->mask = UI64LIT(0x0000200000000000); + mod->mask2= UI64LIT(0x0); m_spellmod = mod; } ((Player*)m_target)->AddSpellMod(m_spellmod, apply); @@ -2317,8 +2317,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real) mod->value = m_modifier.m_amount/7; mod->type = SPELLMOD_FLAT; mod->spellId = GetId(); - mod->mask = 0x001000000000LL; - mod->mask2= 0LL; + mod->mask = UI64LIT(0x001000000000); + mod->mask2= UI64LIT(0x0); m_spellmod = mod; } @@ -2343,7 +2343,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } // Lifebloom - if ( GetSpellProto()->SpellFamilyFlags & 0x1000000000LL ) + if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x1000000000)) { if ( apply ) { @@ -2362,7 +2362,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) Unit::AuraList auras = m_target->GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::iterator itr = auras.begin(); itr!=auras.end(); ++itr) if((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && - (*itr)->GetSpellProto()->SpellFamilyFlags & 0x1000000000LL) + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x1000000000))) return; // final heal @@ -2400,12 +2400,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real) switch (m_effIndex) { case 0: - mod->mask = 0x00200000000LL; // Windfury Totem - mod->mask2= 0LL; + // Windfury Totem + mod->mask = UI64LIT(0x00200000000); + mod->mask2= UI64LIT(0x0); break; case 1: - mod->mask = 0x00400000000LL; // Flametongue Totem - mod->mask2= 0LL; + // Flametongue Totem + mod->mask = UI64LIT(0x00400000000); + mod->mask2= UI64LIT(0x0); break; } @@ -3268,7 +3270,7 @@ void Aura::HandleModCharm(bool apply, bool Real) if(m_target->GetCharmInfo()) m_target->GetCharmInfo()->SetPetNumber(0, true); else - sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId()); + sLog.outError("Aura::HandleModCharm: target (GUID: %u TypeId: %u) has a charm aura but no charm info!", m_target->GetGUIDLow(), m_target->GetTypeId()); } } @@ -3477,7 +3479,7 @@ void Aura::HandleAuraModStun(bool apply, bool Real) } // Wyvern Sting - if (m_spellProto->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellProto->SpellFamilyFlags & 0x0000100000000000LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellProto->SpellFamilyFlags & UI64LIT(0x0000100000000000)) { Unit* caster = GetCaster(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) @@ -3548,7 +3550,7 @@ void Aura::HandleModStealth(bool apply, bool Real) pTarget->CastCustomSpell(pTarget,31665,&bp,NULL,NULL,true); } // Overkill - else if ((*i)->GetId() == 58426 && pSpellInfo->SpellFamilyFlags & 0x0000000000400000LL) + else if ((*i)->GetId() == 58426 && pSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400000)) { pTarget->RemoveAurasDueToSpell(58428); pTarget->CastSpell(pTarget, 58427, true); @@ -3588,7 +3590,7 @@ void Aura::HandleModStealth(bool apply, bool Real) if ((*i)->GetSpellProto()->SpellIconID == 2114) pTarget->CastSpell(pTarget, 31666, true); // Overkill - else if ((*i)->GetId() == 58426 && pSpellInfo->SpellFamilyFlags & 0x0000000000400000LL) + else if ((*i)->GetId() == 58426 && pSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400000)) pTarget->CastSpell(pTarget, 58428, true); } } @@ -4264,7 +4266,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_WARRIOR: { // Rend - if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000020)) { // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); @@ -4279,21 +4281,21 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_DRUID: { // Rake - if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000001000)) { // $AP*0.06 bonus per tick m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 6 / 100); return; } // Lacerate - if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x000000010000000000)) { // $AP*0.05/5 bonus per tick m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); return; } // Rip - if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x000000000000800000)) { // 0.01*$AP*cp if (caster->GetTypeId() != TYPEID_PLAYER) @@ -4315,7 +4317,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) return; } // Lock Jaw - if (m_spellProto->SpellFamilyFlags & 0x1000000000000000LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) { // 0.15*$AP m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 15 / 100); @@ -4326,7 +4328,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_ROGUE: { // Rupture - if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x000000000000100000)) { if (caster->GetTypeId() != TYPEID_PLAYER) return; @@ -4342,14 +4344,14 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) return; } // Garrote - if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x000000000000000100)) { // $AP*0.07 bonus per tick m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 7 / 100); return; } // Deadly Poison - if (m_spellProto->SpellFamilyFlags & 0x0000000000010000) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000010000)) { // 0.08*$AP / 4 * amount of stack m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 * GetStackAmount() / 100); @@ -4360,14 +4362,14 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_HUNTER: { // Serpent Sting - if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { // $RAP*0.1/5 bonus per tick m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500); return; } // Immolation Trap - if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678) + if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) && m_spellProto->SpellIconID == 678) { // $RAP*0.1/5 bonus per tick m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500); @@ -5591,7 +5593,7 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real ) void Aura::CleanupTriggeredSpells() { - if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0000001000000020LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000001000000020))) { // Blood Frenzy remove m_target->RemoveAurasDueToSpell(30069); @@ -5640,7 +5642,9 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) } break; case SPELLFAMILY_MAGE: - if(m_spellProto->SpellFamilyFlags == 0x80100 || m_spellProto->SpellFamilyFlags == 0x8 || m_spellProto->SpellFamilyFlags == 0x100000000LL) + if (m_spellProto->SpellFamilyFlags == UI64LIT(0x80100) || + m_spellProto->SpellFamilyFlags == UI64LIT(0x8) || + m_spellProto->SpellFamilyFlags == UI64LIT(0x100000000)) { //frost ward, fire ward, ice barrier //+10% from +spd bonus @@ -5747,7 +5751,7 @@ void Aura::PeriodicTick() pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount()); // Curse of Agony damage-per-tick calculation - if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544) + if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && GetSpellProto()->SpellIconID==544) { // 1..4 ticks, 1/2 from normal tick damage if (m_duration >= ((m_maxduration-m_modifier.periodictime) * 2 / 3)) @@ -6458,7 +6462,7 @@ void Aura::PeriodicDummyTick() case SPELLFAMILY_HUNTER: { // Explosive Shot - if (spell->SpellFamilyFlags & 0x8000000000000000LL) + if (spell->SpellFamilyFlags & UI64LIT(0x8000000000000000)) { if (!caster) return; @@ -6508,17 +6512,17 @@ void Aura::PeriodicDummyTick() case SPELLFAMILY_DEATHKNIGHT: { // Death and Decay - if (spell->SpellFamilyFlags & 0x0000000000000020LL) + if (spell->SpellFamilyFlags & UI64LIT(0x0000000000000020)) { if (caster) caster->CastCustomSpell(m_target, 52212, &m_modifier.m_amount, NULL, NULL, true, 0, this); return; } // Raise Dead -// if (spell->SpellFamilyFlags & 0x0000000000001000LL) +// if (spell->SpellFamilyFlags & UI64LIT(0x0000000000001000)) // return; // Chains of Ice - if (spell->SpellFamilyFlags & 0x0000400000000000LL) + if (spell->SpellFamilyFlags & UI64LIT(0x0000400000000000)) { // Get 0 effect aura Aura *slow = m_target->GetAura(GetId(), 0); @@ -6533,10 +6537,10 @@ void Aura::PeriodicDummyTick() return; } // Summon Gargoyle -// if (spell->SpellFamilyFlags & 0x0000008000000000LL) +// if (spell->SpellFamilyFlags & UI64LIT(0x0000008000000000)) // return; // Death Rune Mastery -// if (spell->SpellFamilyFlags & 0x0000000000004000LL) +// if (spell->SpellFamilyFlags & UI64LIT(0x0000000000004000)) // return; // Bladed Armor if (spell->SpellIconID == 2653) @@ -6589,7 +6593,7 @@ void Aura::HandleManaShield(bool apply, bool Real) switch(m_spellProto->SpellFamilyName) { case SPELLFAMILY_MAGE: - if(m_spellProto->SpellFamilyFlags & 0x8000) + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x8000)) { // Mana Shield // +50% from +spd bonus diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 10a1bb827..c96de3c79 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -308,7 +308,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_GENERIC: { //Gore - if(m_spellInfo->SpellIconID == 2269 ) + if (m_spellInfo->SpellIconID == 2269 ) { damage+= rand()%2 ? damage : 0; } @@ -359,7 +359,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_MAGE: { // Arcane Blast - if(m_spellInfo->SpellFamilyFlags & 0x20000000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x20000000)) { m_caster->CastSpell(m_caster, 36032, true); } @@ -368,27 +368,27 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_WARRIOR: { // Bloodthirst - if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x40000000000)) { damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100); } // Shield Slam - else if(m_spellInfo->SpellFamilyFlags & 0x0000020000000000LL && m_spellInfo->Category==1209) + else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->Category==1209) damage += int32(m_caster->GetShieldBlockValue()); // Victory Rush - else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x10000000000)) { damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false); } // Revenge ${$m1+$AP*0.207} to ${$M1+$AP*0.207} - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000400LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f); // Heroic Throw ${$m1+$AP*.50} - else if(m_spellInfo->SpellFamilyFlags & 0x0000000100000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000100000000)) damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); // Shockwave ${$m3/100*$AP} - else if(m_spellInfo->SpellFamilyFlags & 0x0000800000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000800000000000)) { int32 pct = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget); if (pct > 0) @@ -400,7 +400,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_WARLOCK: { // Incinerate Rank 1 & 2 - if((m_spellInfo->SpellFamilyFlags & 0x00004000000000LL) && m_spellInfo->SpellIconID==2128) + if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x00004000000000)) && m_spellInfo->SpellIconID==2128) { // Incinerate does more dmg (dmg*0.25) if the target is Immolated. if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) @@ -411,14 +411,14 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_PRIEST: { // Shadow Word: Death - deals damage equal to damage done to caster - if (m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000200000000)) m_caster->CastCustomSpell(m_caster, 32409, &damage, 0, 0, true); break; } case SPELLFAMILY_DRUID: { // Ferocious Bite - if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual[0]==6587) + if (m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000800000)) && m_spellInfo->SpellVisual[0]==6587) { // converts each extra point of energy into ($f1+$AP/410) additional damage float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); @@ -428,22 +428,22 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) m_caster->SetPower(POWER_ENERGY,0); } // Rake - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000001000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000001000)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); } // Swipe - else if(m_spellInfo->SpellFamilyFlags & 0x0010000000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0010000000000000)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.08f); } //Mangle Bonus for the initial damage of Lacerate and Rake - if((m_spellInfo->SpellFamilyFlags==0x0000000000001000LL && m_spellInfo->SpellIconID==494) || - (m_spellInfo->SpellFamilyFlags==0x0000010000000000LL && m_spellInfo->SpellIconID==2246)) + if ((m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000000000001000) && m_spellInfo->SpellIconID==494) || + (m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000010000000000) && m_spellInfo->SpellIconID==2246)) { Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) - if((*i)->GetSpellProto()->SpellFamilyFlags & 0x0000044000000000LL && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID) + if(((*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000044000000000)) && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID) { damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f); break; @@ -454,7 +454,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_ROGUE: { // Envenom - if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x800000000LL)) + if (m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x800000000))) { // consume from stack dozes not more that have combo-points if(uint32 combo = ((Player*)m_caster)->GetComboPoints()) @@ -464,7 +464,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && - (*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000 && + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x10000)) && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) { poison = *itr; @@ -488,7 +488,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) } } // Eviscerate - else if((m_spellInfo->SpellFamilyFlags & 0x00020000LL) && m_caster->GetTypeId()==TYPEID_PLAYER) + else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x00020000)) && m_caster->GetTypeId()==TYPEID_PLAYER) { if(uint32 combo = ((Player*)m_caster)->GetComboPoints()) { @@ -501,17 +501,17 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) } } // Gouge - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000008LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000008)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.21f); } // Instant Poison - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000002000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000002000)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f); } // Wound Poison - else if(m_spellInfo->SpellFamilyFlags & 0x0000000010000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000010000000)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f); } @@ -520,28 +520,28 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_HUNTER: { // Mongoose Bite - if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual[0]==342) + if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x000000002)) && m_spellInfo->SpellVisual[0]==342) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); } // Counterattack - else if(m_spellInfo->SpellFamilyFlags & 0x0008000000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0008000000000000)) { damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); } // Arcane Shot - else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0) + else if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000800)) && m_spellInfo->maxLevel > 0) { damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f); } // Steady Shot - else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x100000000)) { int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE)); damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f); } // Explosive Trap Effect - else if(m_spellInfo->SpellFamilyFlags & 0x00000004) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000004)) { damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f); } @@ -550,7 +550,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) case SPELLFAMILY_PALADIN: { // Judgement of Vengeance ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance on the target - if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292) + if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x800000000)) && m_spellInfo->SpellIconID==2292) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + @@ -570,7 +570,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) damage += damage * stacks * 10 /100; } // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) - ranged sdb for future - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + @@ -578,7 +578,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) damage += int32(ap * 0.07f) + int32(holy * 7 / 100); } // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - ranged type sdb future fix - else if(m_spellInfo->SpellFamilyFlags & 0x0000008000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000008000000000)) { float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + @@ -586,7 +586,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) damage += int32(ap * 0.15f) + int32(holy * 15 / 100); } // Hammer of the Righteous - else if(m_spellInfo->SpellFamilyFlags&0x0004000000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000)) { // Add main hand dps * effect[2] amount float average = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; @@ -594,7 +594,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) damage += count * int32(average * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); } // Shield of Righteousness - else if(m_spellInfo->SpellFamilyFlags&0x0010000000000000LL) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0010000000000000)) { damage+=int32(m_caster->GetShieldBlockValue()); } @@ -1220,14 +1220,14 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_WARRIOR: // Charge - if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867) + if((m_spellInfo->SpellFamilyFlags & UI64LIT(0x1)) && m_spellInfo->SpellVisual[0] == 867) { int32 chargeBasePoints0 = damage; m_caster->CastCustomSpell(m_caster, 34846, &chargeBasePoints0, NULL, NULL, true); return; } // Execute - if(m_spellInfo->SpellFamilyFlags & 0x20000000) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x20000000)) { if(!unitTarget) return; @@ -1244,7 +1244,7 @@ void Spell::EffectDummy(uint32 i) return; } // Slam - if(m_spellInfo->SpellFamilyFlags & 0x0000000000200000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000200000)) { if(!unitTarget) return; @@ -1253,7 +1253,7 @@ void Spell::EffectDummy(uint32 i) return; } // Concussion Blow - if(m_spellInfo->SpellFamilyFlags & 0x0000000004000000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) { m_damage+= uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); return; @@ -1285,7 +1285,7 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_WARLOCK: // Life Tap - if (m_spellInfo->SpellFamilyFlags & 0x0000000000040000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000040000)) { // In 303 exist spirit depend uint32 spirit = uint32(m_caster->GetStat(STAT_SPIRIT)); @@ -1341,7 +1341,7 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_PRIEST: // Penance - if (m_spellInfo->SpellFamilyFlags & 0x0080000000000000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0080000000000000)) { if (!unitTarget) return; @@ -1367,7 +1367,7 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_DRUID: // Starfall - if (m_spellInfo->SpellFamilyFlags2 & 0x00000100LL) + if (m_spellInfo->SpellFamilyFlags2 & UI64LIT(0x00000100)) { //Shapeshifting into an animal form or mounting cancels the effect. if(m_caster->GetCreatureType() == CREATURE_TYPE_BEAST || m_caster->IsMounted()) @@ -1443,7 +1443,7 @@ void Spell::EffectDummy(uint32 i) uint32 classspell = itr->first; SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); - if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x0000024000000860LL)) + if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & UI64LIT(0x0000024000000860))) ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); } return; @@ -1457,7 +1457,7 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_HUNTER: // Steady Shot - if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x100000000)) { if( !unitTarget || !unitTarget->isAlive()) return; @@ -1562,8 +1562,8 @@ void Spell::EffectDummy(uint32 i) mod->value = -50; mod->type = SPELLMOD_PCT; mod->spellId = m_spellInfo->Id; - mod->mask = 0x0000020000000000LL; - mod->mask2= 0LL; + mod->mask = UI64LIT(0x0000020000000000); + mod->mask2= UI64LIT(0x0); ((Player*)m_caster)->AddSpellMod(mod, true); m_caster->CastSpell(unitTarget, spell_proto, true, NULL); @@ -1693,19 +1693,19 @@ void Spell::EffectDummy(uint32 i) return; } // Cleansing Totem - if(m_spellInfo->SpellFamilyFlags & 0x0000000004000000LL && m_spellInfo->SpellIconID==1673) + if((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) && m_spellInfo->SpellIconID==1673) { m_caster->CastSpell(unitTarget, 52025, true); return; } // Healing Stream Totem - if(m_spellInfo->SpellFamilyFlags & 0x0000000000002000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000002000)) { m_caster->CastCustomSpell(unitTarget, 52042, &damage, 0, 0, true, 0, 0, m_originalCasterGUID); return; } // Mana Spring Totem - if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { if(unitTarget->getPowerType()!=POWER_MANA) return; @@ -1739,7 +1739,7 @@ void Spell::EffectDummy(uint32 i) for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) { if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_SHAMAN && - (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000000000200000LL && + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000200000)) && (*itr)->GetCastItemGUID() == item->GetGUID()) { m_damage += m_damage * damage / 100; @@ -1752,7 +1752,7 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_DEATHKNIGHT: // Death Coil - if(m_spellInfo->SpellFamilyFlags & 0x002000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x002000)) { if(m_caster->IsFriendlyTo(unitTarget)) { @@ -2303,7 +2303,7 @@ void Spell::EffectApplyAura(uint32 i) return; // Prayer of Mending (jump animation), we need formal caster instead original for correct animation - if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL)) + if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00002000000000))) m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID); } @@ -2469,7 +2469,7 @@ void Spell::EffectHeal( uint32 /*i*/ ) if(!targetAura) { - sLog.outError("Target(GUID:" I64FMTD ") has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID()); + sLog.outError("Target (GUID: %u TypeId: %u) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUIDLow(), unitTarget->GetTypeId()); return; } int idx = 0; @@ -4322,7 +4322,7 @@ void Spell::EffectWeaponDmg(uint32 i) case SPELLFAMILY_WARRIOR: { // Whirlwind, single only spell with 2 weapon white damage apply if have - if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x00000400000000LL)) + if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000400000000))) { if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK,true)) spell_bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized); @@ -4337,7 +4337,7 @@ void Spell::EffectWeaponDmg(uint32 i) { SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); if( spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && - spellInfo->SpellFamilyFlags & 0x0000000000004000LL && + (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) && (*itr).second->GetCasterGUID() == m_caster->GetGUID()) { (*itr).second->RefreshAura(); @@ -4352,7 +4352,7 @@ void Spell::EffectWeaponDmg(uint32 i) case SPELLFAMILY_ROGUE: { // Mutilate (for each hand) - if(m_spellInfo->SpellFamilyFlags & 0x600000000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x600000000)) { bool found = false; // fast check @@ -4380,7 +4380,7 @@ void Spell::EffectWeaponDmg(uint32 i) case SPELLFAMILY_PALADIN: { // Seal of Command - receive benefit from Spell Damage and Healing - if(m_spellInfo->SpellFamilyFlags & 0x00000002000000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000002000000)) { spellBonusNeedWeaponDamagePercentMod = true;// apply weaponDamagePercentMod to spell_bonus (and then to all bonus, fixes and weapon already have applied) spell_bonus += int32(0.23f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo))); @@ -4392,7 +4392,7 @@ void Spell::EffectWeaponDmg(uint32 i) { // Skyshatter Harness item set bonus // Stormstrike - if(m_spellInfo->SpellFamilyFlags & 0x001000000000LL) + if(m_spellInfo->SpellFamilyFlags & UI64LIT(0x001000000000)) { Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for(Unit::AuraList::const_iterator citr = m_OverrideClassScript.begin(); citr != m_OverrideClassScript.end(); ++citr) @@ -4469,14 +4469,14 @@ void Spell::EffectWeaponDmg(uint32 i) m_damage+= eff_damage; // Hemorrhage - if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & 0x2000000)) + if (m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x2000000))) { if(m_caster->GetTypeId()==TYPEID_PLAYER) ((Player*)m_caster)->AddComboPoints(unitTarget, 1); } // Mangle (Cat): CP - if(m_spellInfo->SpellFamilyName==SPELLFAMILY_DRUID && (m_spellInfo->SpellFamilyFlags==0x0000040000000000LL)) + if (m_spellInfo->SpellFamilyName==SPELLFAMILY_DRUID && (m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000040000000000))) { if(m_caster->GetTypeId()==TYPEID_PLAYER) ((Player*)m_caster)->AddComboPoints(unitTarget, 1); @@ -5029,7 +5029,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) { SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); if(spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && - spellInfo->SpellFamilyFlags & 0x0000000000000002LL && + (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000002)) && (*itr).second->GetCasterGUID()==m_caster->GetGUID()) (*itr).second->RefreshAura(); } @@ -5052,8 +5052,8 @@ void Spell::EffectScriptEffect(uint32 effIndex) for(Unit::AuraMap::iterator itr = auras.begin(); itr != auras.end(); ++itr) { SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); - if( spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && - spellInfo->SpellFamilyFlags & 0x0000000000008000LL && + if (spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && + (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) && (*itr).second->GetCasterGUID() == m_caster->GetGUID()) { (*itr).second->RefreshAura(); @@ -5084,29 +5084,29 @@ void Spell::EffectScriptEffect(uint32 effIndex) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; - if (!(familyFlag & 0x000000800000C000LL)) + if (!(familyFlag & UI64LIT(0x000000800000C000))) continue; // Refresh aura duration aura->RefreshAura(); // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0) + if ((familyFlag & UI64LIT(0x0000000000004000)) && aura->GetEffIndex() == 0) { spellId = 53353; // 53353 Chimera Shot - Serpent basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. - if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0) + if ((familyFlag & UI64LIT(0x0000008000000000)) && aura->GetEffIndex() == 0) { spellId = 53358; // 53358 Chimera Shot - Viper basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. - if (familyFlag & 0x0000000000008000LL) + if (familyFlag & UI64LIT(0x0000000000008000)) spellId = 53359; // 53359 Chimera Shot - Scorpid // ?? nothing say in spell desc (possibly need addition check) - //if (familyFlag & 0x0000010000000000LL || // dot - // familyFlag & 0x0000100000000000LL) // stun + //if ((familyFlag & UI64LIT(0x0000010000000000)) || // dot + // (familyFlag & UI64LIT(0x0000100000000000))) // stun //{ // spellId = 53366; // 53366 Chimera Shot - Wyvern //} @@ -5123,7 +5123,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) case SPELLFAMILY_PALADIN: { // Judgement - if (m_spellInfo->SpellFamilyFlags & 0x0000000000800000LL) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000800000)) { if(!unitTarget || !unitTarget->isAlive()) return; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 3f81cac5f..f06073ee6 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -138,17 +138,17 @@ SpellSpecific GetSpellSpecific(uint32 spellId) case SPELLFAMILY_MAGE: { // family flags 18(Molten), 25(Frost/Ice), 28(Mage) - if (spellInfo->SpellFamilyFlags & 0x12040000) + if (spellInfo->SpellFamilyFlags & UI64LIT(0x12040000)) return SPELL_MAGE_ARMOR; - if ((spellInfo->SpellFamilyFlags & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE) + if ((spellInfo->SpellFamilyFlags & UI64LIT(0x1000000)) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE) return SPELL_MAGE_POLYMORPH; break; } case SPELLFAMILY_WARRIOR: { - if (spellInfo->SpellFamilyFlags & 0x00008000010000LL) + if (spellInfo->SpellFamilyFlags & UI64LIT(0x00008000010000)) return SPELL_POSITIVE_SHOUT; break; @@ -160,7 +160,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId) return SPELL_CURSE; // Warlock (Demon Armor | Demon Skin | Fel Armor) - if (spellInfo->SpellFamilyFlags & 0x2000002000000000LL || spellInfo->SpellFamilyFlags2 & 0x00000010) + if (spellInfo->SpellFamilyFlags & UI64LIT(0x2000002000000000) || spellInfo->SpellFamilyFlags2 & 0x00000010) return SPELL_WARLOCK_ARMOR; break; @@ -172,7 +172,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId) return SPELL_STING; // only hunter aspects have this (but not all aspects in hunter family) - if( spellInfo->SpellFamilyFlags & 0x0044000000380000LL || spellInfo->SpellFamilyFlags2 & 0x00003010) + if( spellInfo->SpellFamilyFlags & UI64LIT(0x0044000000380000) || spellInfo->SpellFamilyFlags2 & 0x00003010) return SPELL_ASPECT; if( spellInfo->SpellFamilyFlags2 & 0x00000002 ) @@ -185,10 +185,10 @@ SpellSpecific GetSpellSpecific(uint32 spellId) if (IsSealSpell(spellInfo)) return SPELL_SEAL; - if (spellInfo->SpellFamilyFlags & 0x0000000011010002LL) + if (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000011010002)) return SPELL_BLESSING; - if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200)) + if ((spellInfo->SpellFamilyFlags & UI64LIT(0x00000820180400)) && (spellInfo->AttributesEx3 & 0x200)) return SPELL_JUDGEMENT; for (int i = 0; i < 3; ++i) @@ -1191,7 +1191,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Improved Hamstring -> Hamstring (multi-family check) - if( (spellInfo_2->SpellFamilyFlags & 2) && spellInfo_1->Id == 23694 ) + if( (spellInfo_2->SpellFamilyFlags & UI64LIT(0x2)) && spellInfo_1->Id == 23694 ) return false; break; @@ -1223,7 +1223,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return false; // Improved Wing Clip -> Wing Clip (multi-family check) - if( (spellInfo_2->SpellFamilyFlags & 0x40) && spellInfo_1->Id == 19229 ) + if( (spellInfo_2->SpellFamilyFlags & UI64LIT(0x40)) && spellInfo_1->Id == 19229 ) return false; break; } @@ -1248,13 +1248,13 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellInfo_2->SpellFamilyName == SPELLFAMILY_MAGE ) { // Blizzard & Chilled (and some other stacked with blizzard spells - if( (spellInfo_1->SpellFamilyFlags & 0x80) && (spellInfo_2->SpellFamilyFlags & 0x100000) || - (spellInfo_2->SpellFamilyFlags & 0x80) && (spellInfo_1->SpellFamilyFlags & 0x100000) ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x80)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x100000)) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x80)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x100000)) ) return false; // Blink & Improved Blink - if( (spellInfo_1->SpellFamilyFlags & 0x0000000000010000LL) && (spellInfo_2->SpellVisual[0] == 72 && spellInfo_2->SpellIconID == 1499) || - (spellInfo_2->SpellFamilyFlags & 0x0000000000010000LL) && (spellInfo_1->SpellVisual[0] == 72 && spellInfo_1->SpellIconID == 1499) ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_2->SpellVisual[0] == 72 && spellInfo_2->SpellIconID == 1499) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_1->SpellVisual[0] == 72 && spellInfo_1->SpellIconID == 1499) ) return false; } // Detect Invisibility and Mana Shield (multi-family check) @@ -1298,8 +1298,8 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellInfo_2->SpellFamilyName == SPELLFAMILY_WARRIOR ) { // Rend and Deep Wound - if( (spellInfo_1->SpellFamilyFlags & 0x20) && (spellInfo_2->SpellFamilyFlags & 0x1000000000LL) || - (spellInfo_2->SpellFamilyFlags & 0x20) && (spellInfo_1->SpellFamilyFlags & 0x1000000000LL) ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x1000000000)) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x1000000000)) ) return false; // Battle Shout and Rampage @@ -1309,7 +1309,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons } // Hamstring -> Improved Hamstring (multi-family check) - if( (spellInfo_1->SpellFamilyFlags & 2) && spellInfo_2->Id == 23694 ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x2)) && spellInfo_2->Id == 23694 ) return false; // Defensive Stance and Scroll of Protection (multi-family check) @@ -1325,17 +1325,17 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellInfo_2->SpellFamilyName == SPELLFAMILY_PRIEST ) { //Devouring Plague and Shadow Vulnerability - if( (spellInfo_1->SpellFamilyFlags & 0x2000000) && (spellInfo_2->SpellFamilyFlags & 0x800000000LL) || - (spellInfo_2->SpellFamilyFlags & 0x2000000) && (spellInfo_1->SpellFamilyFlags & 0x800000000LL) ) + if ((spellInfo_1->SpellFamilyFlags & UI64LIT(0x2000000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x800000000)) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x2000000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x800000000))) return false; //StarShards and Shadow Word: Pain - if( (spellInfo_1->SpellFamilyFlags & 0x200000) && (spellInfo_2->SpellFamilyFlags & 0x8000) || - (spellInfo_2->SpellFamilyFlags & 0x200000) && (spellInfo_1->SpellFamilyFlags & 0x8000) ) + if ((spellInfo_1->SpellFamilyFlags & UI64LIT(0x200000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x8000)) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x200000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x8000))) return false; // Dispersion - if( (spellInfo_1->Id == 47585 && spellInfo_2->Id == 60069) || - (spellInfo_2->Id == 47585 && spellInfo_1->Id == 60069) ) + if ((spellInfo_1->Id == 47585 && spellInfo_2->Id == 60069) || + (spellInfo_2->Id == 47585 && spellInfo_1->Id == 60069)) return false; } break; @@ -1343,8 +1343,8 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellInfo_2->SpellFamilyName == SPELLFAMILY_DRUID ) { //Omen of Clarity and Blood Frenzy - if( (spellInfo_1->SpellFamilyFlags == 0x0 && spellInfo_1->SpellIconID == 108) && (spellInfo_2->SpellFamilyFlags & 0x20000000000000LL) || - (spellInfo_2->SpellFamilyFlags == 0x0 && spellInfo_2->SpellIconID == 108) && (spellInfo_1->SpellFamilyFlags & 0x20000000000000LL) ) + if( (spellInfo_1->SpellFamilyFlags == UI64LIT(0x0) && spellInfo_1->SpellIconID == 108) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x20000000000000)) || + (spellInfo_2->SpellFamilyFlags == UI64LIT(0x0) && spellInfo_2->SpellIconID == 108) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x20000000000000)) ) return false; // Tree of Life (Shapeshift) and 34123 Tree of Life (Passive) @@ -1398,13 +1398,13 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellInfo_2->SpellFamilyName == SPELLFAMILY_HUNTER ) { // Rapid Fire & Quick Shots - if( (spellInfo_1->SpellFamilyFlags & 0x20) && (spellInfo_2->SpellFamilyFlags & 0x20000000000LL) || - (spellInfo_2->SpellFamilyFlags & 0x20) && (spellInfo_1->SpellFamilyFlags & 0x20000000000LL) ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x20000000000)) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x20)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x20000000000)) ) return false; // Serpent Sting & (Immolation/Explosive Trap Effect) - if( (spellInfo_1->SpellFamilyFlags & 0x4) && (spellInfo_2->SpellFamilyFlags & 0x00000004000LL) || - (spellInfo_2->SpellFamilyFlags & 0x4) && (spellInfo_1->SpellFamilyFlags & 0x00000004000LL) ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x4)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x00000004000)) || + (spellInfo_2->SpellFamilyFlags & UI64LIT(0x4)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x00000004000)) ) return false; // Bestial Wrath @@ -1413,7 +1413,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons } // Wing Clip -> Improved Wing Clip (multi-family check) - if( (spellInfo_1->SpellFamilyFlags & 0x40) && spellInfo_2->Id == 19229 ) + if( (spellInfo_1->SpellFamilyFlags & UI64LIT(0x40)) && spellInfo_2->Id == 19229 ) return false; // Concussive Shot and Imp. Concussive Shot (multi-family check) @@ -2712,34 +2712,34 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto case SPELLFAMILY_ROGUE: { // Kidney Shot - if (spellproto->SpellFamilyFlags & 0x00000200000LL) + if (spellproto->SpellFamilyFlags & UI64LIT(0x00000200000)) return DIMINISHING_KIDNEYSHOT; // Blind - else if (spellproto->SpellFamilyFlags & 0x00001000000LL) + else if (spellproto->SpellFamilyFlags & UI64LIT(0x00001000000)) return DIMINISHING_BLIND_CYCLONE; break; } case SPELLFAMILY_WARLOCK: { // Fear - if (spellproto->SpellFamilyFlags & 0x40840000000LL) + if (spellproto->SpellFamilyFlags & UI64LIT(0x40840000000)) return DIMINISHING_WARLOCK_FEAR; // Curses/etc - else if (spellproto->SpellFamilyFlags & 0x00080000000LL) + else if (spellproto->SpellFamilyFlags & UI64LIT(0x00080000000)) return DIMINISHING_LIMITONLY; break; } case SPELLFAMILY_DRUID: { // Cyclone - if (spellproto->SpellFamilyFlags & 0x02000000000LL) + if (spellproto->SpellFamilyFlags & UI64LIT(0x02000000000)) return DIMINISHING_BLIND_CYCLONE; break; } case SPELLFAMILY_WARRIOR: { // Hamstring - limit duration to 10s in PvP - if (spellproto->SpellFamilyFlags & 0x00000000002LL) + if (spellproto->SpellFamilyFlags & UI64LIT(0x00000000002)) return DIMINISHING_LIMITONLY; break; } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 59915e800..a6d238e0f 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -67,15 +67,15 @@ enum SpellFamilyNames }; //Some SpellFamilyFlags -#define SPELLFAMILYFLAG_ROGUE_VANISH 0x000000800LL -#define SPELLFAMILYFLAG_ROGUE_STEALTH 0x000400000LL -#define SPELLFAMILYFLAG_ROGUE_BACKSTAB 0x000800004LL -#define SPELLFAMILYFLAG_ROGUE_SAP 0x000000080LL -#define SPELLFAMILYFLAG_ROGUE_FEINT 0x008000000LL -#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x000200000LL -#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL +#define SPELLFAMILYFLAG_ROGUE_VANISH UI64LIT(0x000000800) +#define SPELLFAMILYFLAG_ROGUE_STEALTH UI64LIT(0x000400000) +#define SPELLFAMILYFLAG_ROGUE_BACKSTAB UI64LIT(0x000800004) +#define SPELLFAMILYFLAG_ROGUE_SAP UI64LIT(0x000000080) +#define SPELLFAMILYFLAG_ROGUE_FEINT UI64LIT(0x008000000) +#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT UI64LIT(0x000200000) +#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE UI64LIT(0x9003E0000) -#define SPELLFAMILYFLAG_PALADIN_SEALS 0x26000C000A000000LL +#define SPELLFAMILYFLAG_PALADIN_SEALS UI64LIT(0x26000C000A000000) // Spell clasification enum SpellSpecific { @@ -130,7 +130,7 @@ inline bool IsSealSpell(SpellEntry const *spellInfo) inline bool IsElementalShield(SpellEntry const *spellInfo) { // family flags 10 (Lightning), 42 (Earth), 37 (Water), proc shield from T2 8 pieces bonus - return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552; + return (spellInfo->SpellFamilyFlags & UI64LIT(0x42000000400)) || spellInfo->Id == 23552; } inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 21371820c..c6726232f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3737,7 +3737,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit { // Custom dispel case // Unstable Affliction - if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & 0x010000000000LL)) + if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x010000000000))) { int32 damage = aur->GetModifier()->m_amount*9; uint64 caster_guid = aur->GetCasterGUID(); @@ -4547,7 +4547,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { if(SpellEntry const* iterSpellProto = (*iter)->GetSpellProto()) { - if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & 0x10000000)) + if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & UI64LIT(0x10000000))) { found=true; break; @@ -4943,7 +4943,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Incanter's Regalia set (add trigger chance to Mana Shield) - if (dummySpell->SpellFamilyFlags & 0x0000000000008000LL) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) { if(GetTypeId() != TYPEID_PLAYER) return false; @@ -4995,7 +4995,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case SPELLFAMILY_WARRIOR: { // Retaliation - if(dummySpell->SpellFamilyFlags==0x0000000800000000LL) + if (dummySpell->SpellFamilyFlags == UI64LIT(0x0000000800000000)) { // check attack comes not from behind if (!HasInArc(M_PI, pVictim)) @@ -5039,7 +5039,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case SPELLFAMILY_WARLOCK: { // Seed of Corruption - if (dummySpell->SpellFamilyFlags & 0x0000001000000000LL) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) { Modifier* mod = triggeredByAura->GetModifier(); // if damage is more than need or target die from damage deal finish spell @@ -5061,7 +5061,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return true; } // Seed of Corruption (Mobs cast) - no die req - if (dummySpell->SpellFamilyFlags == 0x00LL && dummySpell->SpellIconID == 1932) + if (dummySpell->SpellFamilyFlags == UI64LIT(0x0) && dummySpell->SpellIconID == 1932) { Modifier* mod = triggeredByAura->GetModifier(); // if damage is more than need deal finish spell @@ -5142,7 +5142,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case SPELLFAMILY_PRIEST: { // Vampiric Touch - if( dummySpell->SpellFamilyFlags & 0x0000040000000000LL ) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { if(!pVictim || !pVictim->isAlive()) return false; @@ -5184,10 +5184,10 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case 40438: { // Shadow Word: Pain - if( procSpell->SpellFamilyFlags & 0x0000000000008000LL ) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) triggered_spell_id = 40441; // Renew - else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL ) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) triggered_spell_id = 40440; else return false; @@ -5269,19 +5269,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu float chance; // Starfire - if( procSpell->SpellFamilyFlags & 0x0000000000000004LL ) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) { triggered_spell_id = 40445; chance = 25.0f; } // Rejuvenation - else if( procSpell->SpellFamilyFlags & 0x0000000000000010LL ) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) { triggered_spell_id = 40446; chance = 25.0f; } // Mangle (cat/bear) - else if( procSpell->SpellFamilyFlags & 0x0000044000000000LL ) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000044000000000)) { triggered_spell_id = 40452; chance = 40.0f; @@ -5312,7 +5312,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (effIndex!=0) return true; // Wrath crit - if (procSpell->SpellFamilyFlags & 0x0000000000000001LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { if (!roll_chance_i(60)) return false; @@ -5321,7 +5321,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Starfire crit - if (procSpell->SpellFamilyFlags & 0x0000000000000004LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) { triggered_spell_id = 48517; target = this; @@ -5362,8 +5362,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu for(AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr) { SpellEntry const *spellProto = (*itr)->GetSpellProto(); - if( spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && - spellProto->SpellFamilyFlags & 0x0000000000040000LL) + if (spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && + (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000040000))) { (*itr)->SetAuraMaxDuration(GetSpellMaxDuration(spellProto)); (*itr)->RefreshAura(); @@ -5398,7 +5398,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case SPELLFAMILY_HUNTER: { // Aspect of the Viper - if ( dummySpell->SpellFamilyFlags & 0x4000000000000LL ) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x4000000000000)) { uint32 maxmana = GetMaxPower(POWER_MANA); basepoints0 = maxmana* GetAttackTime(RANGED_ATTACK)/1000.0f/100.0f; @@ -5408,7 +5408,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Thrill of the Hunt - if ( dummySpell->SpellIconID == 2236 ) + if (dummySpell->SpellIconID == 2236) { if(!procSpell) return false; @@ -5444,7 +5444,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if ( dummySpell->SpellIconID == 3560 ) { // This effect only from Rapid Killing (mana regen) - if (!(procSpell->SpellFamilyFlags & 0x0100000000000000LL)) + if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0100000000000000))) return false; triggered_spell_id = 56654; target = this; @@ -5455,7 +5455,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case SPELLFAMILY_PALADIN: { // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) - if (dummySpell->SpellFamilyFlags&0x000000008000000LL && effIndex==0) + if ((dummySpell->SpellFamilyFlags & UI64LIT(0x000000008000000)) && effIndex==0) { triggered_spell_id = 25742; float ap = GetTotalAttackPowerValue(BASE_ATTACK); @@ -5465,7 +5465,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Sacred Shield - if (dummySpell->SpellFamilyFlags&0x0008000000000000LL) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0008000000000000)) { triggered_spell_id = 58597; target = this; @@ -5601,19 +5601,19 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) case 40470: { - if( !procSpell ) + if (!procSpell) return false; float chance; // Flash of light/Holy light - if( procSpell->SpellFamilyFlags & 0x00000000C0000000LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x00000000C0000000)) { triggered_spell_id = 40471; chance = 15.0f; } // Judgement - else if( procSpell->SpellFamilyFlags & 0x0000000000800000LL ) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000800000)) { triggered_spell_id = 40472; chance = 50.0f; @@ -5773,17 +5773,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return false; float chance; - if (procSpell->SpellFamilyFlags & 0x0000000000000001LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) { triggered_spell_id = 40465; // Lightning Bolt chance = 15.0f; } - else if (procSpell->SpellFamilyFlags & 0x0000000000000080LL) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) { triggered_spell_id = 40465; // Lesser Healing Wave chance = 10.0f; } - else if (procSpell->SpellFamilyFlags & 0x0000001000000000LL) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) { triggered_spell_id = 40466; // Stormstrike chance = 50.0f; @@ -5829,7 +5829,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Earth Shield - if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { basepoints0 = triggerAmount; target = this; @@ -5840,14 +5840,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu if (dummySpell->SpellIconID == 2287) { // Lesser Healing Wave need aditional 60% roll - if (procSpell->SpellFamilyFlags & 0x0000000000000080LL && !roll_chance_i(60)) + if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(60)) return false; // lookup water shield AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) { - if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000002000000000LL) + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000002000000000))) { uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; CastSpell(this, spell, true, castItem, triggeredByAura); @@ -5908,12 +5908,12 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu mod->value = -100; mod->type = SPELLMOD_PCT; mod->spellId = dummySpell->Id; - mod->mask = 0x0000000000000003LL; - mod->mask2= 0LL; + mod->mask = UI64LIT(0x0000000000000003); + mod->mask2= UI64LIT(0x0); ((Player*)this)->AddSpellMod(mod, true); // Remove cooldown (Chain Lightning - have Category Recovery time) - if (procSpell->SpellFamilyFlags & 0x0000000000000002LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000002)) ((Player*)this)->RemoveSpellCooldown(spellId); CastSpell(pVictim, spellId, true, castItem, triggeredByAura); @@ -5932,8 +5932,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) { - if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400))) { uint32 spell = 0; switch ((*itr)->GetId()) @@ -6000,7 +6000,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Vendetta - if (dummySpell->SpellFamilyFlags & 0x0000000000010000LL) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000010000)) { basepoints0 = triggerAmount * GetMaxHealth() / 100; triggered_spell_id = 50181; @@ -6263,10 +6263,10 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB uint32 tick = 1; // Default tick = 1 // Hellfire have 15 tick - if (procSpell->SpellFamilyFlags&0x0000000000000040LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000040)) tick = 15; // Rain of Fire have 4 tick - else if (procSpell->SpellFamilyFlags&0x0000000000000020LL) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020)) tick = 4; else return false; @@ -6285,7 +6285,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB trigger_spell_id = 18093; } // Drain Soul - else if (auraSpellInfo->SpellFamilyFlags & 0x0000000000004000LL) + else if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) { Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) @@ -6414,7 +6414,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB // procspell is triggered spell but we need mana cost of original casted spell uint32 originalSpellId = procSpell->Id; // Holy Shock heal - if(procSpell->SpellFamilyFlags & 0x0001000000000000LL) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0001000000000000)) { switch(procSpell->Id) { @@ -6482,7 +6482,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB case SPELLFAMILY_SHAMAN: { // Lightning Shield (overwrite non existing triggered spell call in spell.dbc - if(auraSpellInfo->SpellFamilyFlags & 0x0000000000000400) + if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) { switch(auraSpellInfo->Id) { @@ -6661,7 +6661,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB case 53232: { // This effect only from Rapid Fire (ability cast) - if (!(procSpell->SpellFamilyFlags & 0x0000000000000020LL)) + if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020))) return false; break; } @@ -6719,7 +6719,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB if(!procSpell) return false; // For trigger from Blizzard need exist Improved Blizzard - if (procSpell->SpellFamilyName==SPELLFAMILY_MAGE && procSpell->SpellFamilyFlags & 0x0000000000000080LL) + if (procSpell->SpellFamilyName==SPELLFAMILY_MAGE && (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080))) { bool found = false; AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); @@ -7689,7 +7689,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) { SpellEntry const* m_spell = itr->second->GetSpellProto(); - if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags & 0x0004071B8044C402LL)) + if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags & UI64LIT(0x0004071B8044C402))) continue; modPercent += stepPercent * itr->second->GetStackAmount(); if (modPercent >= maxPercent) @@ -7709,7 +7709,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 break; case 5481: // Starfire Bonus { - if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x0000000000200002LL)) + if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, UI64LIT(0x0000000000200002))) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } @@ -7736,7 +7736,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } else // Tundra Stalker { - if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_DEATHKNIGHT, 0x0400000000000000LL)) + if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_DEATHKNIGHT, UI64LIT(0x0400000000000000))) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } @@ -7744,14 +7744,14 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } case 7293: // Rage of Rivendare { - if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0x0200000000000000LL)) + if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, UI64LIT(0x0200000000000000))) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } // Twisted Faith case 7377: { - if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x0000000000008000LL, 0, GetGUID())) + if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, UI64LIT(0x0000000000008000), 0, GetGUID())) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } @@ -7762,7 +7762,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 case 7601: case 7602: { - if (pVictim->GetAura(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x0000000000000400LL)) + if (pVictim->GetAura(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, UI64LIT(0x0000000000000400))) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } @@ -8038,7 +8038,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM { case SPELLFAMILY_PALADIN: // Sacred Shield - if (spellProto->SpellFamilyFlags & 0x0000000040000000LL) + if (spellProto->SpellFamilyFlags & UI64LIT(0x0000000040000000)) { Aura *aura = pVictim->GetDummyAura(58597); if (aura && aura->GetCasterGUID() == GetGUID()) @@ -8048,9 +8048,9 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM break; case SPELLFAMILY_SHAMAN: // Lava Burst - if (spellProto->SpellFamilyFlags & 0x0000100000000000LL) + if (spellProto->SpellFamilyFlags & UI64LIT(0x0000100000000000)) { - if (Aura *flameShock = pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x0000000010000000LL, 0, GetGUID())) + if (Aura *flameShock = pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, UI64LIT(0x0000000010000000), 0, GetGUID())) { // Consume shock aura if not have Glyph of Flame Shock if (!GetAura(55447, 0)) @@ -8202,7 +8202,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint break; case 7798: // Glyph of Regrowth { - if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x0000000000000040LL)) + if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, UI64LIT(0x0000000000000040))) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } @@ -8216,8 +8216,8 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint if (itr->second->GetCasterGUID()!=GetGUID()) continue; SpellEntry const* m_spell = itr->second->GetSpellProto(); - if ( m_spell->SpellFamilyName != SPELLFAMILY_DRUID || - !(m_spell->SpellFamilyFlags & 0x0000001000000050LL)) + if (m_spell->SpellFamilyName != SPELLFAMILY_DRUID || + !(m_spell->SpellFamilyFlags & UI64LIT(0x0000001000000050))) continue; modPercent += stepPercent * itr->second->GetStackAmount(); } @@ -8226,7 +8226,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint } case 7871: // Glyph of Lesser Healing Wave { - if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x0000040000000000LL, 0, GetGUID())) + if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, UI64LIT(0x0000040000000000), 0, GetGUID())) DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; break; } @@ -8322,7 +8322,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint // Taken mods // Healing Wave cast - if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags & 0x0000000000000040LL) + if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000040))) { // Search for Healing Way on Victim Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY); @@ -8620,7 +8620,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT if(spellProto==NULL) break; // Should increase Shred (initial Damage of Lacerate and Rake handled in Spell::EffectSchoolDMG) - if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags==0x00008000LL)) + if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags == UI64LIT(0x00008000))) TakenTotalMod *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f; break; } diff --git a/src/game/World.cpp b/src/game/World.cpp index 0e1026ea1..c360f3f58 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1372,7 +1372,7 @@ void World::SetInitialWorldSettings() sprintf( isoDate, "%04d-%02d-%02d %02d:%02d:%02d", local.tm_year+1900, local.tm_mon+1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec); - loginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, startstring, uptime) VALUES('%u', " I64FMTD ", '%s', 0)", + loginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, startstring, uptime) VALUES('%u', " UI64FMTD ", '%s', 0)", realmID, uint64(m_startTime), isoDate); m_timers[WUPDATE_OBJECTS].SetInterval(0); @@ -1542,7 +1542,7 @@ void World::Update(uint32 diff) uint32 maxClientsNum = GetMaxActiveSessionCount(); m_timers[WUPDATE_UPTIME].Reset(); - loginDatabase.PExecute("UPDATE uptime SET uptime = %u, maxplayers = %u WHERE realmid = %u AND starttime = " I64FMTD, tmpDiff, maxClientsNum, realmID, uint64(m_startTime)); + loginDatabase.PExecute("UPDATE uptime SET uptime = %u, maxplayers = %u WHERE realmid = %u AND starttime = " UI64FMTD, tmpDiff, maxClientsNum, realmID, uint64(m_startTime)); } ///
  • Handle all other objects diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index eae420be7..8e320bc77 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -118,8 +118,8 @@ void WorldSession::SendPacket(WorldPacket const* packet) { uint64 minTime = uint64(cur_time - lastTime); uint64 fullTime = uint64(lastTime - firstTime); - sLog.outDetail("Send all time packets count: " I64FMTD " bytes: " I64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u",sendPacketCount,sendPacketBytes,float(sendPacketCount)/fullTime,float(sendPacketBytes)/fullTime,uint32(fullTime)); - sLog.outDetail("Send last min packets count: " I64FMTD " bytes: " I64FMTD " avr.count/sec: %f avr.bytes/sec: %f",sendLastPacketCount,sendLastPacketBytes,float(sendLastPacketCount)/minTime,float(sendLastPacketBytes)/minTime); + sLog.outDetail("Send all time packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f time: %u",sendPacketCount,sendPacketBytes,float(sendPacketCount)/fullTime,float(sendPacketBytes)/fullTime,uint32(fullTime)); + sLog.outDetail("Send last min packets count: " UI64FMTD " bytes: " UI64FMTD " avr.count/sec: %f avr.bytes/sec: %f",sendLastPacketCount,sendLastPacketBytes,float(sendLastPacketCount)/minTime,float(sendLastPacketBytes)/minTime); lastTime = cur_time; sendLastPacketCount = 1; diff --git a/src/shared/Common.h b/src/shared/Common.h index d1efba3f9..4edd6e7f8 100644 --- a/src/shared/Common.h +++ b/src/shared/Common.h @@ -98,6 +98,7 @@ #include "LockedQueue.h" #include "Threading.h" +#include #include #include #include @@ -125,8 +126,6 @@ #include #define I64FMT "%016I64X" -#define I64FMTD "%I64u" -#define SI64FMTD "%I64d" #define snprintf _snprintf #define atoll __atoi64 #define vsnprintf _vsnprintf @@ -138,10 +137,15 @@ #define stricmp strcasecmp #define strnicmp strncasecmp #define I64FMT "%016llX" -#define I64FMTD "%llu" -#define SI64FMTD "%lld" + #endif +#define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER +#define UI64LIT(N) ACE_UINT64_LITERAL(N) + +#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER +#define SI64LIT(N) ACE_INT64_LITERAL(N) + inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; } #define atol(a) strtoul( a, NULL, 10) diff --git a/src/shared/Database/Field.h b/src/shared/Database/Field.h index 9235c394f..e0ce21b91 100644 --- a/src/shared/Database/Field.h +++ b/src/shared/Database/Field.h @@ -57,7 +57,7 @@ class Field if(mValue) { uint64 value; - sscanf(mValue,I64FMTD,&value); + sscanf(mValue,UI64FMTD,&value); return value; } else diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 710f21825..db5b0d75e 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 "7917" + #define REVISION_NR "7918" #endif // __REVISION_NR_H__ From d2e0e3c439e7f6d21835c7900d682345ca7e761c Mon Sep 17 00:00:00 2001 From: Den Date: Sun, 31 May 2009 02:29:28 +0400 Subject: [PATCH 08/17] [7919] Aura 50 apply percent to all crit healing amount not only to crit healing bonus. Signed-off-by: VladimirMangos --- src/game/SpellAuraDefines.h | 8 ++++---- src/game/SpellAuras.cpp | 2 +- src/game/Unit.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index f5a0252b2..fb1156747 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -88,11 +88,11 @@ enum AuraType SPELL_AURA_PROC_TRIGGER_DAMAGE = 43, SPELL_AURA_TRACK_CREATURES = 44, SPELL_AURA_TRACK_RESOURCES = 45, - SPELL_AURA_46 = 46, // Ignore all Gear test spells + SPELL_AURA_46 = 46, // Ignore all Gear test spells SPELL_AURA_MOD_PARRY_PERCENT = 47, - SPELL_AURA_48 = 48, // One periodic spell + SPELL_AURA_48 = 48, // One periodic spell SPELL_AURA_MOD_DODGE_PERCENT = 49, - SPELL_AURA_MOD_CRITICAL_HEALING_BONUS = 50, + SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50, SPELL_AURA_MOD_BLOCK_PERCENT = 51, SPELL_AURA_MOD_CRIT_PERCENT = 52, SPELL_AURA_PERIODIC_LEECH = 53, @@ -132,7 +132,7 @@ enum AuraType SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87, SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88, SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89, - SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE + SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE SPELL_AURA_MOD_DETECT_RANGE = 91, SPELL_AURA_PREVENTS_FLEEING = 92, SPELL_AURA_MOD_UNATTACKABLE = 93, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 58e2d36dd..2c1c839f4 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -100,7 +100,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT &Aura::HandleNULL, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect) &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT - &Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_BONUS + &Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c6726232f..b2e29f955 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8137,8 +8137,6 @@ uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 dama break; } - crit_bonus = int32(crit_bonus * GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_BONUS)); - if(pVictim) { uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); @@ -8148,6 +8146,8 @@ uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 dama if(crit_bonus > 0) damage += crit_bonus; + damage = int32(damage * GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT)); + return damage; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index db5b0d75e..21f83c866 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 "7918" + #define REVISION_NR "7919" #endif // __REVISION_NR_H__ From 91157c7eb98b0823a51383b28cfad907dc3449d1 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 31 May 2009 04:23:50 +0400 Subject: [PATCH 09/17] [7920] Ignore racial skill and skills without recipes in .learn all_recipes. Cleanup code. --- src/game/Chat.h | 1 + src/game/DBCStructure.h | 2 +- src/game/DBCfmt.h | 2 +- src/game/Level2.cpp | 115 +++++++++++++++++++-------------------- src/shared/revision_nr.h | 2 +- 5 files changed, 60 insertions(+), 62 deletions(-) diff --git a/src/game/Chat.h b/src/game/Chat.h index d5e5c2619..7ba20206f 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -519,6 +519,7 @@ class ChatHandler bool HandleBanInfoHelper(uint32 accountid, char const* accountname); bool HandleUnBanHelper(BanMode mode,char const* args); void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel); + void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id); void SetSentErrorMessage(bool val){ sentErrorMessage = val;}; private: diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index e554359a0..089d2c189 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1238,7 +1238,7 @@ struct SkillLineEntry uint32 spellIcon; // 37 m_spellIconID //char* alternateVerb[16]; // 38-53 m_alternateVerb_lang // 54 string flags - // 55 m_canLink + uint32 canLink; // 55 m_canLink (prof. with recipes }; struct SkillLineAbilityEntry diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index a86d6685f..a6c99b838 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -77,7 +77,7 @@ const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiii"; -const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxx"; +const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi"; const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellCastTimefmt[]="nixx"; diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 03e8e5bcb..1e3bf8505 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -3899,6 +3899,40 @@ bool ChatHandler::HandleCombatStopCommand(const char* args) return true; } +void ChatHandler::HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id) +{ + uint32 classmask = player->getClassMask(); + + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + { + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); + if (!skillLine) + continue; + + // wrong skill + if( skillLine->skillId != skill_id) + continue; + + // not high rank + if(skillLine->forward_spellid ) + continue; + + // skip racial skills + if (skillLine->racemask != 0) + continue; + + // skip wrong class skills + if( skillLine->classmask && (skillLine->classmask & classmask) == 0) + continue; + + SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); + if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false)) + continue; + + player->learnSpell(skillLine->spellId,false); + } +} + bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/) { uint32 classmask = m_session->GetPlayer()->getClassMask(); @@ -3909,31 +3943,10 @@ bool ChatHandler::HandleLearnAllCraftsCommand(const char* /*args*/) if( !skillInfo ) continue; - if( skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY ) + if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) && + skillInfo->canLink) // only prof. with recipes have { - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) - { - SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); - if( !skillLine ) - continue; - - // skip racial skills - if( skillLine->racemask != 0 ) - continue; - - // skip wrong class skills - if( skillLine->classmask && (skillLine->classmask & classmask) == 0) - continue; - - if( skillLine->skillId != i || skillLine->forward_spellid ) - continue; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) - continue; - - m_session->GetPlayer()->learnSpell(skillLine->spellId,false); - } + HandleLearnSkillRecipesHelper(m_session->GetPlayer(),skillInfo->id); } } @@ -3965,55 +3978,39 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args) wstrToLower( wnamepart ); uint32 classmask = m_session->GetPlayer()->getClassMask(); + std::string name; - for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) + SkillLineEntry const *targetSkillInfo = NULL; + for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i) { SkillLineEntry const *skillInfo = sSkillLineStore.LookupEntry(i); - if( !skillInfo ) + if (!skillInfo) continue; - if( skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && - skillInfo->categoryId != SKILL_CATEGORY_SECONDARY ) + if ((skillInfo->categoryId != SKILL_CATEGORY_PROFESSION && + skillInfo->categoryId != SKILL_CATEGORY_SECONDARY) || + !skillInfo->canLink) // only prof with recipes have set continue; int loc = GetSessionDbcLocale(); - std::string name = skillInfo->name[loc]; + name = skillInfo->name[loc]; if(Utf8FitTo(name, wnamepart)) { - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) - { - SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); - if( !skillLine ) - continue; - - if( skillLine->skillId != i || skillLine->forward_spellid ) - continue; - - // skip racial skills - if( skillLine->racemask != 0 ) - continue; - - // skip wrong class skills - if( skillLine->classmask && (skillLine->classmask & classmask) == 0) - continue; - - SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); - if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false)) - continue; - - if( !target->HasSpell(spellInfo->Id) ) - m_session->GetPlayer()->learnSpell(skillLine->spellId,false); - } - - uint16 maxLevel = target->GetPureMaxSkillValue(skillInfo->id); - target->SetSkill(skillInfo->id, maxLevel, maxLevel); - PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); - return true; + targetSkillInfo = skillInfo; + break; } } - return false; + if(!targetSkillInfo) + return false; + + HandleLearnSkillRecipesHelper(target,targetSkillInfo->id); + + uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->id); + target->SetSkill(targetSkillInfo->id, maxLevel, maxLevel); + PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str()); + return true; } bool ChatHandler::HandleLookupPlayerIpCommand(const char* args) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 21f83c866..6ee113c3d 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 "7919" + #define REVISION_NR "7920" #endif // __REVISION_NR_H__ From c678263bb0945d3b6ce61a7401e15042c0b117eb Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 31 May 2009 04:26:40 +0400 Subject: [PATCH 10/17] [7921] Set pet and for creature owner in Spell::EffectSummon similar other summon effects. --- src/game/SpellEffects.cpp | 3 ++- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c96de3c79..4a60e7620 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3293,9 +3293,10 @@ void Spell::EffectSummon(uint32 i) map->Add((Creature*)spawnCreature); + m_caster->SetPet(spawnCreature); + if(m_caster->GetTypeId() == TYPEID_PLAYER) { - m_caster->SetPet(spawnCreature); spawnCreature->GetCharmInfo()->SetReactState( REACT_DEFENSIVE ); spawnCreature->SavePetToDB(PET_SAVE_AS_CURRENT); ((Player*)m_caster)->PetSpellInitialize(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6ee113c3d..98e81a10d 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 "7920" + #define REVISION_NR "7921" #endif // __REVISION_NR_H__ From 79dab3dae57ba9d655d1c8f2d1d9f05947a184b0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 31 May 2009 04:31:55 +0400 Subject: [PATCH 11/17] [7922] Implement param2 for ACTION_T_COMBAT_MOVEMENT for allow control start/stop melee combat state for creature at start/stop movement in combat. Also small fix for avoid unexpected set pet speed to owner speed for non-player case. In player case this hack speed setting still required. --- doc/EventAI.txt | 2 ++ src/game/CreatureEventAI.cpp | 22 ++++++++++++++++++---- src/game/CreatureEventAI.h | 1 + src/game/Unit.cpp | 12 ++++++------ src/game/Unit.h | 5 ++--- src/shared/revision_nr.h | 2 +- 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/doc/EventAI.txt b/doc/EventAI.txt index 5137c26dd..76e4fa20c 100644 --- a/doc/EventAI.txt +++ b/doc/EventAI.txt @@ -530,10 +530,12 @@ This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVE 21 = ACTION_T_COMBAT_MOVEMENT: ------------------------------ Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before. +Parameter 2: If non-zero, then stop melee combat state (if param1=0) or start melee combat state (if param1!=0) and creature in combat with selected target. This action controls whether or not the creature will always move towards its target. NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values. (0 = Stop Movement, 1 = Start Movement) This is commonly used with EVENT_T_RANGE and ACTION_T_AUTO_ATTACK for NPC's who engage in Ranged Comabt (Either Spells or Ranged Attacks) +Parameter 2 specialy used for ranged combat proper client side visual show ranged weapon in proper state. ------------------------ 22 = ACTION_T_SET_PHASE: diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 8d01b7687..e895595d1 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -578,11 +578,19 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 MeleeEnabled = action.auto_attack.state != 0; break; case ACTION_T_COMBAT_MOVEMENT: + // ignore no affect case + if(CombatMovementEnabled==(action.combat_movement.state!=0)) + return; + CombatMovementEnabled = action.combat_movement.state != 0; //Allow movement (create new targeted movement gen only if idle) if (CombatMovementEnabled) { + if(action.combat_movement.melee && m_creature->isInCombat()) + if(Unit* victim = m_creature->getVictim()) + m_creature->SendMeleeAttackStart(victim); + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE) { m_creature->GetMotionMaster()->Clear(false); @@ -590,11 +598,17 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 } } else - if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) { - m_creature->GetMotionMaster()->Clear(false); - m_creature->GetMotionMaster()->MoveIdle(); - m_creature->StopMoving(); + if(action.combat_movement.melee && m_creature->isInCombat()) + if(Unit* victim = m_creature->getVictim()) + m_creature->SendMeleeAttackStop(victim); + + if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) + { + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + m_creature->StopMoving(); + } } break; case ACTION_T_SET_PHASE: diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index 852d47576..ac97badd8 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -281,6 +281,7 @@ struct CreatureEventAI_Action struct { uint32 state; // 0 = stop combat based movement, anything else continue attacking + uint32 melee; // if set: at stop send melee combat stop if in combat, use for terminate melee fighting state for switch to ranged } combat_movement; // ACTION_T_SET_PHASE = 22 struct diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b2e29f955..c8f19e0f8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2317,7 +2317,7 @@ float Unit::CalculateLevelPenalty(SpellEntry const* spellProto) const return (100.0f - LvlPenalty) * LvlFactor / 100.0f; } -void Unit::SendAttackStart(Unit* pVictim) +void Unit::SendMeleeAttackStart(Unit* pVictim) { WorldPacket data( SMSG_ATTACKSTART, 8 + 8 ); data << uint64(GetGUID()); @@ -2327,7 +2327,7 @@ void Unit::SendAttackStart(Unit* pVictim) DEBUG_LOG( "WORLD: Sent SMSG_ATTACKSTART" ); } -void Unit::SendAttackStop(Unit* victim) +void Unit::SendMeleeAttackStop(Unit* victim) { if(!victim) return; @@ -7244,7 +7244,7 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) if( meleeAttack && !hasUnitState(UNIT_STAT_MELEE_ATTACKING) ) { addUnitState(UNIT_STAT_MELEE_ATTACKING); - SendAttackStart(victim); + SendMeleeAttackStart(victim); return true; } return false; @@ -7285,7 +7285,7 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) resetAttackTimer(OFF_ATTACK); if(meleeAttack) - SendAttackStart(victim); + SendMeleeAttackStart(victim); return true; } @@ -7314,7 +7314,7 @@ bool Unit::AttackStop(bool targetSwitch /*=false*/) ((Creature*)this)->SetNoSearchAssistance(false); } - SendAttackStop(victim); + SendMeleeAttackStop(victim); return true; } @@ -7505,7 +7505,7 @@ void Unit::SetPet(Pet* pet) SetUInt64Value(UNIT_FIELD_SUMMON, pet ? pet->GetGUID() : 0); // FIXME: hack, speed must be set only at follow - if(pet) + if(pet && GetTypeId()==TYPEID_PLAYER) for(int i = 0; i < MAX_MOVE_TYPE; ++i) pet->SetSpeed(UnitMoveType(i), m_speed_rate[i], true); } diff --git a/src/game/Unit.h b/src/game/Unit.h index b54c96317..e5946c6e8 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -921,6 +921,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void CombatStopWithPets(bool includingCast = false); Unit* SelectNearbyTarget() const; bool hasNegativeAuraWithInterruptFlag(uint32 flag); + void SendMeleeAttackStop(Unit* victim); + void SendMeleeAttackStart(Unit* pVictim); void addUnitState(uint32 f) { m_state |= f; } bool hasUnitState(const uint32 f) const { return (m_state & f); } @@ -1548,9 +1550,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject uint32 m_regenTimer; private: - void SendAttackStop(Unit* victim); // only from AttackStop(Unit*) - void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*) - bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ); bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 98e81a10d..eb0538268 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 "7921" + #define REVISION_NR "7922" #endif // __REVISION_NR_H__ From bf4201c0f400c93f883671bc915ea9ab5b815d35 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 31 May 2009 04:56:35 +0400 Subject: [PATCH 12/17] [7923] Search all available locale skill names in .learn all_recipes --- src/game/Level2.cpp | 22 +++++++++++++++++++++- src/shared/revision_nr.h | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 1e3bf8505..7cd09d8ce 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -3978,6 +3978,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args) wstrToLower( wnamepart ); uint32 classmask = m_session->GetPlayer()->getClassMask(); + std::string name; SkillLineEntry const *targetSkillInfo = NULL; @@ -3994,8 +3995,27 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args) int loc = GetSessionDbcLocale(); name = skillInfo->name[loc]; + if(name.empty()) + continue; - if(Utf8FitTo(name, wnamepart)) + if (!Utf8FitTo(name, wnamepart)) + { + loc = 0; + for(; loc < MAX_LOCALE; ++loc) + { + if(loc==GetSessionDbcLocale()) + continue; + + name = skillInfo->name[loc]; + if(name.empty()) + continue; + + if (Utf8FitTo(name, wnamepart)) + break; + } + } + + if(loc < MAX_LOCALE) { targetSkillInfo = skillInfo; break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index eb0538268..1e0822fde 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 "7922" + #define REVISION_NR "7923" #endif // __REVISION_NR_H__ From 6e9339b0931a8eac9cb9b9e1d4e1bc7912aa0600 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 31 May 2009 06:26:58 +0400 Subject: [PATCH 13/17] [7924] Not teleport player to non-player caster at ressurection. --- src/game/Player.cpp | 5 +++-- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 86de2cb0b..a0989e369 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18891,8 +18891,9 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const void Player::ResurectUsingRequestData() { - /// Teleport before resurrecting, otherwise the player might get attacked from creatures near his corpse - TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); + /// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse + if(IS_PLAYER_GUID(m_resurrectGUID)) + TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); ResurrectPlayer(0.0f,false); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1e0822fde..cdd6a99b8 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 "7923" + #define REVISION_NR "7924" #endif // __REVISION_NR_H__ From 60e450166d5b96c8a5c648cc1ad4e36513a22422 Mon Sep 17 00:00:00 2001 From: Naicisum Date: Sun, 31 May 2009 09:32:44 +0400 Subject: [PATCH 14/17] [7925] Correct minor output format error inside ByteBuffer class Signed-off-by: VladimirMangos --- src/shared/ByteBuffer.h | 6 +++--- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h index 645897677..5a13ea788 100644 --- a/src/shared/ByteBuffer.h +++ b/src/shared/ByteBuffer.h @@ -370,7 +370,7 @@ class ByteBuffer { if ((i == (j*8)) && ((i != (k*16)))) { - if (read(i) < 0x0F) + if (read(i) < 0x10) { sLog.outDebugInLine("| 0%X ", read(i) ); } @@ -382,7 +382,7 @@ class ByteBuffer } else if (i == (k*16)) { - if (read(i) < 0x0F) + if (read(i) < 0x10) { sLog.outDebugInLine("\n"); if(sLog.IsIncludeTime()) @@ -404,7 +404,7 @@ class ByteBuffer } else { - if (read(i) < 0x0F) + if (read(i) < 0x10) { sLog.outDebugInLine("0%X ", read(i) ); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cdd6a99b8..d764790aa 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 "7924" + #define REVISION_NR "7925" #endif // __REVISION_NR_H__ From 116c72208f10a0a0e2be16b84bccce437821d72d Mon Sep 17 00:00:00 2001 From: DonTomika Date: Sun, 31 May 2009 10:03:49 +0400 Subject: [PATCH 15/17] [7926] Implement loot roll achievement criteria types used in statistics * ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED * ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: Signed-off-by: VladimirMangos --- src/game/AchievementMgr.cpp | 6 ++++-- src/game/GroupHandler.cpp | 10 ++++++++++ src/shared/revision_nr.h | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index f01f0b835..a639bb7fb 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -589,6 +589,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS: case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: @@ -1202,8 +1204,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: - case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: - case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: case ACHIEVEMENT_CRITERIA_TYPE_TOTAL: break; // Not implemented yet :( } @@ -1360,6 +1360,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION: case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: + case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER: case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR: diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index d16691be7..fc3a1f863 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -391,6 +391,16 @@ void WorldSession::HandleLootRoll( WorldPacket &recv_data ) // everything's fine, do it group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, Choise); + + switch (Choise) + { + case 1: + GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1); + break; + case 2: + GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); + break; + } } void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d764790aa..0377ce940 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 "7925" + #define REVISION_NR "7926" #endif // __REVISION_NR_H__ From af54fbf715be0fbaaf6cc245a7925cec836f7078 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 31 May 2009 10:28:36 +0400 Subject: [PATCH 16/17] [7927] For achievement criteria type ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM check also items equip at loading. --- src/game/AchievementMgr.cpp | 2 +- src/game/Player.cpp | 2 ++ src/shared/revision_nr.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index a639bb7fb..a4598b1a2 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -1065,7 +1065,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(miscvalue1 != achievementCriteria->equip_item.itemID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1); break; case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: // miscvalue1 = go entry diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a0989e369..217f218d6 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -10331,6 +10331,8 @@ void Player::QuickEquipItem( uint16 pos, Item *pItem) pItem->AddToWorld(); pItem->SendUpdateToPlayer( this ); } + + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0377ce940..b84fe8131 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 "7926" + #define REVISION_NR "7927" #endif // __REVISION_NR_H__ From 0bfcc44bb8ac726564eb8fcdf3eab1366a09e021 Mon Sep 17 00:00:00 2001 From: DonTomika Date: Sun, 31 May 2009 10:40:47 +0400 Subject: [PATCH 17/17] [7928] Player must standup at stun (from 1.5 client starting) Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 2c1c839f4..fb07cb479 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3412,7 +3412,10 @@ void Aura::HandleAuraModStun(bool apply, bool Real) if(m_target->GetTypeId() != TYPEID_PLAYER) ((Creature*)m_target)->StopMoving(); else + { m_target->SetUnitMovementFlags(0); // Clear movement flags + m_target->SetStandState(UNIT_STAND_STATE_STAND); + } WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8); data.append(m_target->GetPackGUID()); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b84fe8131..6470b37e5 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 "7927" + #define REVISION_NR "7928" #endif // __REVISION_NR_H__