From 184b82abccfff95b18bed81ded1b5a7e98d2dbd3 Mon Sep 17 00:00:00 2001 From: megamage Date: Wed, 24 Dec 2008 11:18:01 -0600 Subject: [PATCH] Backed out changeset: ad4f100c0a9d --HG-- branch : trunk --- THANKS | 3 - contrib/extractor/System.cpp | 118 +- contrib/extractor/ad.exe | Bin 160768 -> 167936 bytes contrib/extractor/adt.cpp | 530 ++-- contrib/extractor/adt.h | 143 +- .../vmap_assembler.exe | Bin 293888 -> 184320 bytes .../vmapextract_v2.exe | Bin 217088 -> 233472 bytes .../vmap_extractor_v2/vmapextract/model.cpp | 145 +- contrib/vmap_extractor_v2/vmapextract/model.h | 27 +- .../vmapextract/modelheaders.h | 316 ++- .../vmapextract/vmapexport.cpp | 6 - sql/characters.sql | 101 +- .../zone/black_temple/boss_illidan.cpp | 49 +- .../black_temple/instance_black_temple.cpp | 4 +- .../instance_blackrock_depths.cpp | 18 +- .../old_hillsbrad/old_hillsbrad.cpp | 20 +- .../boss_leotheras_the_blind.cpp | 12 +- .../instance_serpent_shrine.cpp | 2 +- .../scripts/zone/deadmines/deadmines.cpp | 4 +- .../gruuls_lair/boss_high_king_maulgar.cpp | 4 +- .../zone/karazhan/boss_prince_malchezaar.cpp | 20 +- .../boss_headless_horseman.cpp | 4 +- .../instance_scarlet_monastery.cpp | 4 +- .../instance_shadowfang_keep.cpp | 2 +- .../scripts/zone/uldaman/instance_uldaman.cpp | 4 +- .../scripts/zone/zulaman/boss_hexlord.cpp | 3 +- .../scripts/zone/zulaman/boss_nalorakk.cpp | 6 +- .../scripts/zone/zulaman/boss_zuljin.cpp | 8 +- .../scripts/zone/zulaman/instance_zulaman.cpp | 2 +- .../scripts/zone/zulgurub/boss_renataki.cpp | 12 +- src/game/AchievementMgr.cpp | 910 ------- src/game/AchievementMgr.h | 101 - src/game/AuctionHouse.cpp | 20 - src/game/Bag.cpp | 2 +- src/game/BattleGround.cpp | 9 +- src/game/BattleGround.h | 7 +- src/game/BattleGroundMgr.cpp | 5 +- src/game/BattleGroundMgr.h | 4 +- src/game/Calendar.cpp | 17 - src/game/Calendar.h | 26 - src/game/CalendarHandler.cpp | 118 - src/game/CharacterHandler.cpp | 349 +-- src/game/Chat.cpp | 3 - src/game/Chat.h | 3 - src/game/Corpse.cpp | 2 +- src/game/Creature.cpp | 25 +- src/game/Creature.h | 7 +- src/game/DynamicObject.cpp | 2 +- src/game/GameObject.cpp | 96 +- src/game/GameObject.h | 31 +- src/game/GossipDef.cpp | 17 +- src/game/GridNotifiers.cpp | 2 +- src/game/Group.h | 13 +- src/game/GroupHandler.cpp | 36 +- src/game/Guild.cpp | 38 +- src/game/Guild.h | 5 +- src/game/Item.cpp | 18 +- src/game/Item.h | 38 +- src/game/ItemHandler.cpp | 11 +- src/game/ItemPrototype.h | 82 +- src/game/Language.h | 2 - src/game/Level2.cpp | 159 +- src/game/Level3.cpp | 77 +- src/game/LootHandler.cpp | 4 +- src/game/LootMgr.cpp | 17 - src/game/LootMgr.h | 3 - src/game/Mail.cpp | 8 +- src/game/Makefile.am | 253 -- src/game/Map.cpp | 6 +- src/game/Map.h | 11 - src/game/MapManager.cpp | 6 +- src/game/MiscHandler.cpp | 150 +- src/game/MovementHandler.cpp | 215 +- src/game/NPCHandler.cpp | 16 +- src/game/Object.cpp | 77 +- src/game/ObjectAccessor.cpp | 11 - src/game/ObjectAccessor.h | 2 - src/game/ObjectDefines.h | 4 - src/game/ObjectGridLoader.cpp | 2 +- src/game/ObjectMgr.cpp | 150 +- src/game/ObjectMgr.h | 11 - src/game/Opcodes.cpp | 2250 ++++++++--------- src/game/Opcodes.h | 396 +-- src/game/Pet.cpp | 395 ++- src/game/Pet.h | 41 +- src/game/PetHandler.cpp | 153 +- src/game/PetitionsHandler.cpp | 8 +- src/game/Player.cpp | 1369 +++------- src/game/Player.h | 158 +- src/game/QueryHandler.cpp | 47 +- src/game/QuestDef.cpp | 92 +- src/game/QuestDef.h | 47 +- src/game/QuestHandler.cpp | 6 + src/game/SharedDefines.h | 309 +-- src/game/SkillHandler.cpp | 4 + src/game/Spell.cpp | 402 +-- src/game/Spell.h | 53 +- src/game/SpellAuraDefines.h | 58 +- src/game/SpellAuras.cpp | 893 ++----- src/game/SpellAuras.h | 32 +- src/game/SpellEffects.cpp | 328 +-- src/game/SpellHandler.cpp | 38 +- src/game/SpellMgr.cpp | 287 +-- src/game/SpellMgr.h | 394 ++- src/game/StatSystem.cpp | 66 +- src/game/TaxiHandler.cpp | 2 +- src/game/Transports.cpp | 11 +- src/game/Unit.cpp | 331 +-- src/game/Unit.h | 141 +- src/game/UpdateData.cpp | 2 +- src/game/UpdateData.h | 5 +- src/game/UpdateFields.h | 531 ++-- src/game/Vehicle.cpp | 102 - src/game/Vehicle.h | 58 - src/game/World.cpp | 89 +- src/game/World.h | 7 +- src/game/WorldSession.cpp | 87 - src/game/WorldSession.h | 51 +- src/game/WorldSocket.cpp | 63 +- src/game/debugcmds.cpp | 51 - src/shared/Auth/AuthCrypt.cpp | 3 +- src/shared/Auth/AuthCrypt.h | 1 + src/shared/Database/DBCEnums.h | 229 +- src/shared/Database/DBCStores.cpp | 67 +- src/shared/Database/DBCStores.h | 13 - src/shared/Database/DBCStructure.h | 1352 +++------- src/shared/Database/DBCfmt.cpp | 58 +- src/shared/Database/Database.h | 2 +- src/shared/Database/SQLStorage.cpp | 8 +- src/shared/MemoryLeaks.h | 48 - src/shared/SystemConfig.h.in | 46 - src/shared/Util.h | 24 +- src/shared/revision_nr.h | 4 - src/shared/vmap/TileAssembler.cpp | 3 +- src/{mangosd => trinitycore}/CliRunnable.cpp | 0 src/{mangosd => trinitycore}/CliRunnable.h | 0 src/{mangosd => trinitycore}/Main.cpp | 2 +- src/{mangosd => trinitycore}/Makefile.am | 0 src/{mangosd => trinitycore}/Master.cpp | 0 src/{mangosd => trinitycore}/Master.h | 0 src/{mangosd => trinitycore}/RASocket.cpp | 0 src/{mangosd => trinitycore}/RASocket.h | 0 src/{mangosd => trinitycore}/TrinityCore.ico | Bin .../mangosd.rc => trinitycore/TrinityCore.rc} | 0 .../WorldRunnable.cpp | 0 src/{mangosd => trinitycore}/WorldRunnable.h | 0 src/{mangosd => trinitycore}/monitor-mangosd | 0 src/{mangosd => trinitycore}/resource.h | 0 src/{mangosd => trinitycore}/run-mangosd | 0 .../trinitycore.conf.dist} | 43 +- src/{realmd => trinityrealm}/AuthCodes.h | 4 +- src/{realmd => trinityrealm}/AuthSocket.cpp | 0 src/{realmd => trinityrealm}/AuthSocket.h | 0 src/{realmd => trinityrealm}/Main.cpp | 2 +- src/{realmd => trinityrealm}/Makefile.am | 0 src/{realmd => trinityrealm}/RealmList.cpp | 0 src/{realmd => trinityrealm}/RealmList.h | 0 src/{realmd => trinityrealm}/TrinityRealm.ico | Bin .../TrinityRealm.rc} | 0 src/{realmd => trinityrealm}/resource.h | 0 .../trinityrealm.conf.dist} | 0 win/TrinityCore&Script VC90.sln | 4 +- .../{mangosd.vcproj => TrinityCore.vcproj} | 10 - .../{realmd.vcproj => TrinityRealm.vcproj} | 8 - win/VC71/game.vcproj | 23 - .../{mangosd.vcproj => TrinityCore.vcproj} | 20 - .../{realmd.vcproj => TrinityRealm.vcproj} | 16 - win/VC80/game.vcproj | 28 - .../{mangosd.vcproj => TrinityCore.vcproj} | 61 +- .../{realmd.vcproj => TrinityRealm.vcproj} | 42 +- win/VC90/game.vcproj | 59 +- 171 files changed, 5085 insertions(+), 11200 deletions(-) delete mode 100644 src/game/AchievementMgr.cpp delete mode 100644 src/game/AchievementMgr.h delete mode 100644 src/game/Calendar.cpp delete mode 100644 src/game/Calendar.h delete mode 100644 src/game/CalendarHandler.cpp delete mode 100644 src/game/Vehicle.cpp delete mode 100644 src/game/Vehicle.h delete mode 100644 src/shared/MemoryLeaks.h delete mode 100644 src/shared/revision_nr.h rename src/{mangosd => trinitycore}/CliRunnable.cpp (100%) rename src/{mangosd => trinitycore}/CliRunnable.h (100%) rename src/{mangosd => trinitycore}/Main.cpp (99%) rename src/{mangosd => trinitycore}/Makefile.am (100%) rename src/{mangosd => trinitycore}/Master.cpp (100%) rename src/{mangosd => trinitycore}/Master.h (100%) rename src/{mangosd => trinitycore}/RASocket.cpp (100%) rename src/{mangosd => trinitycore}/RASocket.h (100%) rename src/{mangosd => trinitycore}/TrinityCore.ico (100%) rename src/{mangosd/mangosd.rc => trinitycore/TrinityCore.rc} (100%) rename src/{mangosd => trinitycore}/WorldRunnable.cpp (100%) rename src/{mangosd => trinitycore}/WorldRunnable.h (100%) rename src/{mangosd => trinitycore}/monitor-mangosd (100%) rename src/{mangosd => trinitycore}/resource.h (100%) rename src/{mangosd => trinitycore}/run-mangosd (100%) rename src/{mangosd/mangosd.conf.dist.in => trinitycore/trinitycore.conf.dist} (97%) rename src/{realmd => trinityrealm}/AuthCodes.h (96%) rename src/{realmd => trinityrealm}/AuthSocket.cpp (100%) rename src/{realmd => trinityrealm}/AuthSocket.h (100%) rename src/{realmd => trinityrealm}/Main.cpp (99%) rename src/{realmd => trinityrealm}/Makefile.am (100%) rename src/{realmd => trinityrealm}/RealmList.cpp (100%) rename src/{realmd => trinityrealm}/RealmList.h (100%) rename src/{realmd => trinityrealm}/TrinityRealm.ico (100%) rename src/{realmd/Realmd.rc => trinityrealm/TrinityRealm.rc} (100%) rename src/{realmd => trinityrealm}/resource.h (100%) rename src/{realmd/realmd.conf.dist.in => trinityrealm/trinityrealm.conf.dist} (100%) rename win/VC71/{mangosd.vcproj => TrinityCore.vcproj} (91%) rename win/VC71/{realmd.vcproj => TrinityRealm.vcproj} (94%) rename win/VC80/{mangosd.vcproj => TrinityCore.vcproj} (91%) rename win/VC80/{realmd.vcproj => TrinityRealm.vcproj} (95%) rename win/VC90/{mangosd.vcproj => TrinityCore.vcproj} (86%) rename win/VC90/{realmd.vcproj => TrinityRealm.vcproj} (90%) diff --git a/THANKS b/THANKS index c48df55dd1f..396ebbceb7f 100644 --- a/THANKS +++ b/THANKS @@ -20,9 +20,6 @@ similar to this one: Thanks to the ScriptDev2 team (http://www.scriptdev2.com) for scripts. - Thanks to WCell team (especially Ralek) for reseach on realm reconnect sequence, - item scaling stats algorithm, gameobject rotation issues. - The easiest policy with this file is to thank everyone who contributes to the project, without judging the value of the contribution. diff --git a/contrib/extractor/System.cpp b/contrib/extractor/System.cpp index 1753f40801a..197c4d35416 100644 --- a/contrib/extractor/System.cpp +++ b/contrib/extractor/System.cpp @@ -16,24 +16,21 @@ extern unsigned int iRes; extern ArchiveSet gOpenArchives; -bool ConvertADT(char*, char*); +bool ConvertADT(char*,char*); -typedef struct -{ +typedef struct{ char name[64]; - uint32 id; -} map_id; + unsigned int id; +}map_id; typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; -map_id *map_ids; -uint16 *areas; -uint16 *LiqType; -char output_path[128] = "."; -char input_path[128] = "."; -uint32 maxAreaId = 0; +map_id * map_ids; +uint16 * areas; +char output_path[128]="."; +char input_path[128]="."; enum Extract { @@ -69,45 +66,46 @@ bool FileExists( const char* FileName ) void Usage(char* prg) { - printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"", prg, prg); + printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"", + prg,prg); exit(1); } void HandleArgs(int argc, char * arg[]) { - for(int c = 1; c < argc; ++c) + for(int c=1;c 0 && extract < 4)) Usage(arg[0]); } @@ -124,12 +122,12 @@ uint32 ReadMapDBC() DBCFile dbc("DBFilesClient\\Map.dbc"); dbc.open(); - size_t map_count = dbc.getRecordCount(); - map_ids = new map_id[map_count]; - for(uint32 x = 0; x < map_count; ++x) + uint32 map_count=dbc.getRecordCount(); + map_ids=new map_id[map_count]; + for(unsigned int x=0;xc_str() + strlen("DBFilesClient\\")); - FILE *output = fopen(filename.c_str(), "wb"); + FILE *output=fopen(filename.c_str(), "wb"); if(!output) { printf("Can't create the output file '%s'\n", filename.c_str()); @@ -283,9 +261,7 @@ void LoadCommonMPQFiles() { char filename[512]; - sprintf(filename,"%s/Data/common-2.MPQ", input_path); - new MPQArchive(filename); - sprintf(filename,"%s/Data/lichking.MPQ", input_path); + sprintf(filename,"%s/Data/common.MPQ", input_path); new MPQArchive(filename); sprintf(filename,"%s/Data/expansion.MPQ", input_path); new MPQArchive(filename); @@ -295,7 +271,7 @@ void LoadCommonMPQFiles() if(i > 1) sprintf(ext, "-%i", i); - sprintf(filename, "%s/Data/patch%s.MPQ", input_path, ext); + sprintf(filename,"%s/Data/patch%s.MPQ", input_path, ext); if(FileExists(filename)) new MPQArchive(filename); } diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe index f483f3892f9135033e8b6e9e4786d983c5c5b8b1..2dc24c0872e709084426117c84055c1e2579e576 100644 GIT binary patch delta 82121 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 Z#3ZDMe<~1G;~rBX>VN+Ie^mxv{~M4^$u9r^ delta 86069 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 Kg{mqQR{bB%X}Q_} diff --git a/contrib/extractor/adt.cpp b/contrib/extractor/adt.cpp index 71cbf88a37b..26adaa28537 100644 --- a/contrib/extractor/adt.cpp +++ b/contrib/extractor/adt.cpp @@ -15,15 +15,16 @@ #include "adt.h" #include "mpq_libmpq.h" -uint32 iRes = 256; -extern uint16 *areas; -extern uint16 *LiqType; -extern uint32 maxAreaId; +//#include +unsigned int iRes=256; +extern uint16*areas; vec wmoc; -Cell *cell; +Cell * cell; +uint32 wmo_count; mcell *mcells; + int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; int holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; @@ -34,84 +35,56 @@ bool LoadADT(char* filename) if(mf.isEof()) { - //printf("No such file %s\n", filename); + //printf("No such file.\n"); return false; } + mcells=new mcell; - MapLiqFlag = new uint8[256]; - for(uint32 j = 0; j < 256; ++j) - MapLiqFlag[j] = 0; // no water - - MapLiqHeight = new float[16384]; - for(uint32 j = 0; j < 16384; ++j) - MapLiqHeight[j] = -999999; // no water - - mcells = new mcell; - - wmoc.x = 65 * TILESIZE; - wmoc.z = 65 * TILESIZE; + wmoc.x =65*TILESIZE; + wmoc.z =65*TILESIZE; size_t mcnk_offsets[256], mcnk_sizes[256]; - chunk_num = 0; - k = 0; - m = 0; + wmo_count=0; + bool found=false; + //uint32 fs=mf.getSize()-3; + //while (mf.getPos()offsData1 != 0) // åñëè äàííûå â Data1 î âîäå åñòü, òî èõ íàäî êîíâåðòèðîâàòü + //printf("Found chunks info\n"); + // mapchunk offsets/sizes + for (int i=0; i<256; i++) { - // ïåðåõîäèì ïî ñìåùåíèþ èç offsData1 ÎÒ ÍÀ×ÀËÀ êóñêà - mf.seek(base_pos + LiqOffsData->offsData1); - mf.read(LiqChunkData1, 0x18); // ñ÷èòûâàåì ñàìè äàííûå â ñòðóêòóðó òèïà MH2O_Data1 - // çàíîñèì äàííûå ôëàãà äëÿ êóñêà - if(LiqType[LiqChunkData1->LiquidTypeId] == 0xffff) - printf("\nCan't find Liquid type for map %s\nchunk %d\n", filename, chunk_num); - else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_WATER || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_OCEAN) - MapLiqFlag[chunk_num] |= 1; // water/ocean - else if(LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_MAGMA || LiqType[LiqChunkData1->LiquidTypeId] == LIQUID_TYPE_SLIME) - MapLiqFlag[chunk_num] |= 2; // magma/slime - // ïðåäâàðèòåëüíî çàïîëíÿåì âåñü êóñîê äàííûìè - íåò âîäû - for(int j = 0; j < 81; ++j) + mf.read(&mcnk_offsets[i],4); + mf.read(&mcnk_sizes[i],4); + mf.seekRelative(8); + } + break; + } + case 0x4d4f4446: // MODF + { + /* + if(size) + { + //printf("\nwmo count %d\n",size/64); + wmo_count =size/64; + for (int i=0; iheight; ++b) ->>>>>>> upstream/master:contrib/extractor/adt.cpp { - for(int c = LiqChunkData1->xOffset; c <= (LiqChunkData1->xOffset + LiqChunkData1->width); ++c) - { - int n = (9 * (LiqChunkData1->yOffset + b)) + c; - ChunkLiqHeight[n] = LiqChunkData1->heightLevel1; - } - } - mf.seek(header_pos); // è íå çàáûòü âåðíóòüñÿ íà èñõîäíóþ ïîçèöèþ èìåííî  ÕÈÄÅÐÅ - } - else // åñëè äàííûõ â Data1 íåò, òî íàäî çàïîëíèòü âåñü êóñîê, íî äàííûìè - íåò âîäû - { - for(int j = 0; j < 81; ++j) - ChunkLiqHeight[j] = -999999; // no liquid/water - } + std::string path(p); + p+=strlen(p)+1; + fixname(path); - if(!(chunk_num % 16)) - m = 1024 * (chunk_num / 16); // ñìåùåíèå ïî ðÿäàì êóñêîâ ñ ïåðåêðûòèåì = 1024 - k = m + (chunk_num % 16) * 8; // óñòàíàâëèâàåìñÿ íà íà÷àëüíûé èíäåêñ äëÿ çàïîëíåíèÿ ðÿäà - // çàíîñèì äàííûå êóñêà â ìàññèâ äëÿ êàðòû, ñ ïåðåêðûòèåì è îáðåçàíèåì êóñêîâ òê äàííûõ 81 - // ýòî àíàëîã ñòàðîãî îáðåçàíèÿ ãðàíè÷íûõ ïðàâûõ-áîêîâûõ è íèæíèõ äàííûõ - for(int p = 0; p < 72; p += 9) // íèæíèå 8 íå çàíîñèì òê îíè äóáëèðóåòñÿ ñëåä êóñêîì - { - for(int s = 0; s < 8; ++s) // 9 çíà÷åíèå â ñòðîêå íå çàíîñèì òê îíî äóáëèðóåòñÿ ñëåä êóñêîì, à â ïðàâûõ-áîêîâûõ îáðåçàåòñÿ äëÿ 128õ128 - { - MapLiqHeight[k] = ChunkLiqHeight[p + s]; - ++k; + wmomanager.add(path); + wmos.push_back(path); } -<<<<<<< HEAD:contrib/extractor/adt.cpp delete[] buf; }*/ break; @@ -177,50 +126,77 @@ bool LoadADT(char* filename) // mf.seekRelative(-3); printf("Unhandled map chunk: %u\n",fourcc); break; -======= - k = k + 120; - } ->>>>>>> upstream/master:contrib/extractor/adt.cpp } - delete LiqOffsData; - delete LiqChunkData1; - delete []ChunkLiqHeight; - } - //case 0x4d434e4b: // MCNK - //case 0x4d46424f: // MFBO new in BC - //case 0x4d545846: // MTXF new in WotLK mf.seek(nextpos); } //printf("Loading chunks info\n"); // read individual map chunks - chunk_num = 0; - k = 0; - m = 0; - for (int j = 0; j < 16; ++j) - { - for (int i = 0; i < 16; ++i) + for (int j=0; j<16; j++) + for (int i=0; i<16; i++) { - mf.seek((int)mcnk_offsets[j * 16 + i]); - LoadMapChunk(mf, &(mcells->ch[i][j])); - ++chunk_num; + mf.seek((int)mcnk_offsets[j*16+i]); + LoadMapChunk(mf,&(mcells->ch[i][j])); } - } + + /* + for(uint32 t=0;t 3) testi = 3; - if(testj > 3) testj = 3; - return (holes & holetab_h[testi] & holetab_v[testj]) != 0; + int testi = i/2; + int testj = j/4; + if(testi>3) testi = 3; + if(testj>3) testj = 3; + return (holes & holetab_h[testi] & holetab_v[testj])!=0; } -inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) +inline +void LoadMapChunk(MPQFile & mf, chunk*_chunk) { float h; uint32 fourcc; @@ -231,267 +207,295 @@ inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) mf.read(&size, 4); size_t lastpos = mf.getPos() + size; - mf.read(&header, 0x80); // what if header size got changed? - _chunk->area_id = header.areaid; + mf.read(&header, 0x80); + _chunk->area_id =header.areaid ; + _chunk->flag =0; float xbase = header.xpos; float ybase = header.ypos; float zbase = header.zpos; - zbase = TILESIZE * 32 - zbase; - xbase = TILESIZE * 32 - xbase; - if(wmoc.x > xbase) wmoc.x = xbase; - if(wmoc.z > zbase) wmoc.z = zbase; + zbase = TILESIZE*32-zbase; + xbase = TILESIZE*32-xbase; + if(wmoc.x >xbase)wmoc.x =xbase; + if(wmoc.z >zbase)wmoc.z =zbase; int chunkflags = header.flags; - //printf("LMC: flags %X\n", chunkflags); - float zmin = 999999999.0f; - float zmax = -999999999.0f; - // must be there, bl!zz uses some crazy format + float zmin=999999999.0f; + float zmax=-999999999.0f; + //must be there, bl!zz uses some crazy format + int nTextures; while (mf.getPos() < lastpos) { - mf.read(&fourcc, 4); + mf.read(&fourcc,4); mf.read(&size, 4); - size_t nextpos = mf.getPos() + size; - if(fourcc == 0x4d435654) // MCVT + //if(size!=580) + // printf("\n sz=%d",size); + size_t nextpos = mf.getPos() + size; + if(fourcc==0x4d435654) // MCVT { - for (int j = 0; j < 17; ++j) - { - for (int i = 0; i < ((j % 2) ? 8 : 9); ++i) + for (int j=0; j<17; j++) + for (int i=0; i<((j%2)?8:9); i++) { - mf.read(&h, 4); - float z = h + ybase; - if (j % 2) + mf.read(&h,4); + float z=h+ybase; + if (j%2) { - if(isHole(header.holes, i, j)) - _chunk->v8[i][j / 2] = -1000; + if(isHole(header.holes,i,j)) + _chunk->v8[i][j/2] = -1000; else - _chunk->v8[i][j / 2] = z; + _chunk->v8[i][j/2] = z; } else { - if(isHole(header.holes, i, j)) - _chunk->v9[i][j / 2] = -1000; + if(isHole(header.holes,i,j)) + _chunk->v9[i][j/2] = -1000; else - _chunk->v9[i][j / 2] = z; + _chunk->v9[i][j/2] = z; } - if(z > zmax) zmax = z; - //if(z < zmin) zmin = z; + if(z>zmax)zmax=z; + //if(zwaterlevel[i][j]=-999999; // no liquid/water } else { float maxheight; mf.read(&maxheight, 4); - for(int j = 0; j < 81; ++j) - { - LiqData liq; - mf.read(&liq, 8); - if(liq.height > maxheight) - ChunkLiqHeight[j] = -999999; - else - ChunkLiqHeight[j] = h; - } + for(int j=0;j<9;j++) + for(int i=0;i<9;i++) + { + mf.read(&h, 4); + mf.read(&h, 4); + if(h > maxheight) + _chunk->waterlevel[i][j]=-999999; + else + _chunk->waterlevel[i][j]=h; + } if(chunkflags & 4 || chunkflags & 8) - MapLiqFlag[chunk_num] |= 1; // water + _chunk->flag |=1; if(chunkflags & 16) -<<<<<<< HEAD:contrib/extractor/adt.cpp _chunk->flag |=2; -======= - MapLiqFlag[chunk_num] |= 2; // magma/slime } - // çàïîëíåì òàê æå êàê â MH2O - if(!(chunk_num % 16)) - m = 1024 * (chunk_num / 16); - k = m + (chunk_num % 16) * 8; - - for(int p = 0; p < 72; p += 9) - { - for(int s = 0; s < 8; ++s) - { - MapLiqHeight[k] = ChunkLiqHeight[p + s]; - ++k; - } - k = k + 120; ->>>>>>> upstream/master:contrib/extractor/adt.cpp - } - delete []ChunkLiqHeight; break; } + else if (fourcc==0x4d434c59) // MCLY + { + // texture info + nTextures = (int)size; + } + else if (fourcc==0x4d43414c) // MCAL + { + if (nTextures<=0) + continue; + } + mf.seek(nextpos); } } double solve (vec *v,vec *p) { - double a = v[0].y * (v[1].z - v[2].z) + v[1].y * (v[2].z - v[0].z) + v[2].y * (v[0].z - v[1].z); - double b = v[0].z * (v[1].x - v[2].x) + v[1].z * (v[2].x - v[0].x) + v[2].z * (v[0].x - v[1].x); - double c = v[0].x * (v[1].y - v[2].y) + v[1].x * (v[2].y - v[0].y) + v[2].x * (v[0].y - v[1].y); - double d = v[0].x * (v[1].y * v[2].z - v[2].y * v[1].z) + v[1].x * (v[2].y * v[0].z - v[0].y * v[2].z) + v[2].x * (v[0].y * v[1].z - v[1].y * v[0].z); - // -d + double a = v[0].y *(v[1].z - v[2].z) + v[1].y *(v[2].z - v[0].z) + v[2].y *(v[0].z - v[1].z); + double b = v[0].z *(v[1].x - v[2].x) + v[1].z *(v[2].x - v[0].x) + v[2].z *(v[0].x - v[1].x); + double c = v[0].x *(v[1].y - v[2].y) + v[1].x *(v[2].y - v[0].y) + v[2].x *(v[0].y - v[1].y); + double d = v[0].x *(v[1].y*v[2].z - v[2].y*v[1].z) + v[1].x* (v[2].y*v[0].z - v[0].y*v[2].z) + v[2].x* (v[0].y*v[1].z - v[1].y*v[0].z); + //-d - // plane equation ax+by+cz+d=0 + //plane equation ax+by+cz+d=0 return ((a*p->x+c*p->z-d)/b); } -inline double GetZ(double x, double z) +inline +double GetZ(double x,double z) { vec v[3]; vec p; + + //bool inWMO=false; + + //if(!inWMO) { - // find out quadrant - int xc = (int)(x / UNITSIZE); - int zc = (int)(z / UNITSIZE); - if(xc > 127) xc = 127; - if(zc > 127) zc = 127; + //find out quadrant + int xc=(int)(x/UNITSIZE); + int zc=(int)(z/UNITSIZE); + if(xc>127)xc=127; + if(zc>127)zc=127; - double lx = x - xc * UNITSIZE; - double lz = z - zc * UNITSIZE; - p.x = lx; - p.z = lz; + double lx=x-xc*UNITSIZE; + double lz=z-zc*UNITSIZE; + p.x=lx; + p.z=lz; - v[0].x = UNITSIZE / 2; - v[0].y = cell->v8[xc][zc]; - v[0].z = UNITSIZE / 2; + v[0].x=UNITSIZE/2; + v[0].y =cell->v8[xc][zc]; + v[0].z=UNITSIZE/2; - if(lx > lz) + if(lx>lz) { - v[1].x = UNITSIZE; - v[1].y = cell->v9[xc + 1][zc]; - v[1].z = 0.0f; + v[1].x=UNITSIZE; + v[1].y =cell->v9[xc+1][zc]; + v[1].z=0; } else { - v[1].x = 0.0f; - v[1].y = cell->v9[xc][zc + 1]; - v[1].z = UNITSIZE; + v[1].x=0.0; + v[1].y =cell->v9[xc][zc+1]; + v[1].z=UNITSIZE; } - if(lz > UNITSIZE - lx) + if(lz>UNITSIZE-lx) { - v[2].x = UNITSIZE; - v[2].y = cell->v9[xc + 1][zc + 1]; - v[2].z = UNITSIZE; + v[2].x=UNITSIZE; + v[2].y =cell->v9[xc+1][zc+1]; + v[2].z=UNITSIZE; } else { - v[2].x = 0.0f; - v[2].y = cell->v9[xc][zc]; - v[2].z = 0.0f; + v[2].x=0; + v[2].y=cell->v9[xc][zc]; + v[2].z=0; } - return -solve(v, &p); + return -solve(v,&p); } } -inline void TransformData() +inline +void TransformWaterData() { - cell = new Cell; + cell= new Cell; - for(uint32 x = 0; x < 128; ++x) + for(int x=0;x<128;x++) + for(int y=0;y<128;y++) + cell->v9[x][y] = mcells->ch[x/8][y/8].waterlevel[x%8][y%8]; + + //and the last 1 + cell->v9[128][128] = mcells->ch[15][15].waterlevel[8][8]; +} + +inline +void TransformData() +{ + cell= new Cell; + + for(int x=0;x<128;x++) { - for(uint32 y = 0; y < 128; ++y) + for(int y=0;y<128;y++) { - cell->v8[x][y] = (float)mcells->ch[x / 8][y / 8].v8[x % 8][y % 8]; - cell->v9[x][y] = (float)mcells->ch[x / 8][y / 8].v9[x % 8][y % 8]; + cell->v8[x][y] = (float)mcells->ch[x/8][y/8].v8[x%8][y%8]; + cell->v9[x][y] = (float)mcells->ch[x/8][y/8].v9[x%8][y%8]; } - // extra 1 point on bounds - cell->v9[x][128] = (float)mcells->ch[x / 8][15].v9[x % 8][8]; - // x == y - cell->v9[128][x] = (float)mcells->ch[15][x / 8].v9[8][x % 8]; + //extra 1 point on bounds + cell->v9[x][128] = (float)mcells->ch[x/8][15].v9[x%8][8]; + //x==y + cell->v9[128][x] = (float)mcells->ch[15][x/8].v9[8][x%8]; } - // and the last 1 + //and the last 1 cell->v9[128][128] = (float)mcells->ch[15][15].v9[8][8]; delete mcells; } -const char MAP_MAGIC[] = "MAP_2.01"; +const char MAP_MAGIC[] = "MAP_2.00"; -bool ConvertADT(char *filename, char *filename2) +bool ConvertADT(char * filename,char * filename2) { + //if(!strstr(filename,"oth_32_48"))return false; if(!LoadADT(filename)) return false; - FILE *output=fopen(filename2, "wb"); + FILE *output=fopen(filename2,"wb"); if(!output) { - printf("Can't create the output file '%s'\n", filename2); - delete [] MapLiqHeight; - delete [] MapLiqFlag; + printf("Can't create the output file '%s'\n",filename2); return false; } // write magic header - fwrite(MAP_MAGIC, 1, 8, output); + fwrite(MAP_MAGIC,1,8,output); - for(uint32 x = 0; x < 16; ++x) + for(unsigned int x=0;x<16;x++) { - for(uint32 y = 0; y < 16; ++y) + for(unsigned int y=0;y<16;y++) { - if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id <= maxAreaId) + if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id < 0x102D) { - if(areas[mcells->ch[y][x].area_id] == 0xffff) - printf("\nCan't find area flag for areaid %u.\n", mcells->ch[y][x].area_id); + if(areas[mcells->ch[y][x].area_id]==0xffff) + printf("\nCan't find area flag for areaid %u.\n",mcells->ch[y][x].area_id); - fwrite(&areas[mcells->ch[y][x].area_id], 1, 2, output); + fwrite(&areas[mcells->ch[y][x].area_id],1,2,output); } else { - uint16 flag = 0xffff; - fwrite(&flag, 1, 2, output); + uint16 flag=0xffff; + fwrite(&flag,1,2,output); } } } - fwrite(MapLiqFlag, 1, 256, output); - delete [] MapLiqFlag; + for(unsigned int x=0;x<16;x++) + for(unsigned int y=0;y<16;y++) + fwrite(&mcells->ch[y][x].flag,1,1,output); - fwrite(MapLiqHeight, sizeof(float), 16384, output); - delete [] MapLiqHeight; + TransformWaterData(); + for(unsigned int x=0;x<128;x++) + for(unsigned int y=0;y<128;y++) + fwrite(&cell->v9[y][x],1,sizeof(float),output); + + delete cell; TransformData(); - for(uint32 x = 0; x < iRes; ++x) + for(unsigned int x=0;x::iterator it = wmos.begin(); it != wmos.end(); ++it) + wmomanager.delbyname(*it); + + wmos.clear(); + wmois.clear(); + + for (std::vector::iterator it = wmomodel.begin(); it != wmomodel.end(); ++it) + { + it->tr.clear(); + + } + //printf("\n %d \n",in); + wmomodel.clear(); + //polygons.clear();*/ return true; } diff --git a/contrib/extractor/adt.h b/contrib/extractor/adt.h index ec607c9d7bc..6e079461a66 100644 --- a/contrib/extractor/adt.h +++ b/contrib/extractor/adt.h @@ -9,121 +9,46 @@ typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; class Liquid; -typedef struct -{ - float x; - float y; - float z; -} svec; +typedef struct { +float x; +float y; +float z; +}svec; -typedef struct -{ - double x; - double y; - double z; -} vec; +typedef struct { +double x; +double y; +double z; +}vec; -typedef struct -{ +typedef struct{ vec v[3]; -} triangle; +}triangle; + +typedef struct{ +float v9[16*8+1][16*8+1]; +float v8[16*8][16*8]; +}Cell; + +typedef struct{ +double v9[9][9]; +double v8[8][8]; +uint16 area_id; +//Liquid *lq; +float waterlevel[9][9]; +uint8 flag; +}chunk; + +class WMO; +class WMOManager; +void fixname(std::string &name); typedef struct { - float v9[16 * 8 + 1][16 * 8 + 1]; - float v8[16 * 8][16 * 8]; -} Cell; - -typedef struct -{ - double v9[9][9]; - double v8[8][8]; - uint16 area_id; -} chunk; - -typedef struct -{ - chunk ch[16][16]; -} mcell; - -struct MapChunkHeader -{ - uint32 flags; - uint32 ix; - uint32 iy; - uint32 nLayers; - uint32 nDoodadRefs; - uint32 ofsHeight; - uint32 ofsNormal; - uint32 ofsLayer; - uint32 ofsRefs; - uint32 ofsAlpha; - uint32 sizeAlpha; - uint32 ofsShadow; - uint32 sizeShadow; - uint32 areaid; - uint32 nMapObjRefs; - uint32 holes; - uint16 s1; - uint16 s2; - uint32 d1; - uint32 d2; - uint32 d3; - uint32 predTex; - uint32 nEffectDoodad; - uint32 ofsSndEmitters; - uint32 nSndEmitters; - uint32 ofsLiquid; // not use in WotLK - uint32 sizeLiquid; // not use in WotLK - float zpos; - float xpos; - float ypos; - uint32 textureId; // new offsColorValues in WotLK - uint32 props; - uint32 effectId; -}; - -typedef struct -{ - uint32 offsData1; - uint32 used; - uint32 offsData2; -} MH2O_offsData; - -typedef struct -{ - uint16 LiquidTypeId; - uint16 type; - float heightLevel1; - float heightLevel2; - uint8 xOffset; - uint8 yOffset; - uint8 width; - uint8 height; - uint32 ofsData2a; - uint32 ofsData2b; -} MH2O_Data1; - -typedef struct -{ - uint16 unk1; - uint16 unk2; - float height; -} LiqData; - -enum LiquidType -{ - LIQUID_TYPE_WATER = 0, - LIQUID_TYPE_OCEAN = 1, - LIQUID_TYPE_MAGMA = 2, - LIQUID_TYPE_SLIME = 3 -}; - +chunk ch[16][16]; +}mcell; class MPQFile; - -float *MapLiqHeight; -uint8 *MapLiqFlag; -uint32 k, m, chunk_num; -void LoadMapChunk(MPQFile &, chunk*); +void LoadMapChunk(MPQFile &,chunk*); +bool LoadWMO(char* filename); #endif diff --git a/contrib/vmap_extract_assembler_bin/vmap_assembler.exe b/contrib/vmap_extract_assembler_bin/vmap_assembler.exe index a6ef74dc086d0d0fade554ece7bf68143becfe7c..5cb08f770aa039d87b8968e658301f1e848ce869 100644 GIT binary patch literal 184320 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⁡Z2k6h~M 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 literal 293888 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�}Rz0xE2IjfTLl8BVBwBEq)V! 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
ne_%+>#Rku;K5U52l^uM|g_LMeWfgiA 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 diff --git a/contrib/vmap_extract_assembler_bin/vmapextract_v2.exe b/contrib/vmap_extract_assembler_bin/vmapextract_v2.exe index 03c76907658990e6657f372ace9b168868599de1..c38b6e64f64b69a6e093c8e7d9b71f7d0b5ad15e 100644 GIT binary patch delta 118322 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 delta 115477 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

FcbfD!>T|*<3xE%nn5in`+&P+QFm*kPV#7F$ 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�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 #include +//int globalTime = 0; + Model::Model(std::string &filename) : filename(filename) { } @@ -20,31 +24,121 @@ bool Model::open() } memcpy(&header, f.getBuffer(), sizeof(ModelHeader)); - if(header.nBoundingTriangles > 0) - { - f.seek(0); - f.seekRelative(header.ofsBoundingVertices); - vertices = new Vec3D[header.nBoundingVertices]; - f.read(vertices,header.nBoundingVertices*12); - for (uint32 i=0; i 0) { + +#if 0 + animated = isAnimated(f); + if(animated) { - vertices[i] = fixCoordSystem(vertices[i]); + f.close(); + return false; + } +#endif + trans = 1.0f; + origVertices = (ModelVertex*)(f.getBuffer() + header.ofsVertices); + + vertices = new Vec3D[header.nVertices]; + normals = new Vec3D[header.nVertices]; + + for (size_t i=0; iofsIndex); + uint16 *triangles = (uint16*)(f.getBuffer() + view->ofsTris); + + nIndices = view->nTris; + indices = new uint16[nIndices]; + for (size_t i = 0; i0) { + ModelBoneDef &bb = bo[verts[i].bones[b]]; + if (bb.translation.type || bb.rotation.type || bb.scaling.type || (bb.flags&8)) { + if (bb.flags&8) { + // if we have billboarding, the model will need per-instance animation + ind = true; + } + animGeometry = true; + break; + } + } + } + } + + if (animGeometry) animBones = true; + else { + for (size_t i=0; i 0; + + bool animMisc = header.nCameras>0 || // why waste time, pretty much all models with cameras need animation + header.nLights>0 || // same here + header.nParticleEmitters>0 || + header.nRibbonEmitters>0; + + if (animMisc) animBones = true; + + // animated colors + if (header.nColors) { + ModelColorDef *cols = (ModelColorDef*)(f.getBuffer() + header.ofsColors); + for (size_t i=0; i0) + fwrite(&nIdexes, sizeof(uint32), 1, output); + if(nIdexes >0) { - fwrite(indices, sizeof(unsigned short), nIndexes, output); + fwrite(indices, sizeof(unsigned short), nIdexes, output); } fwrite("VERT",4, 1, output); wsize = sizeof(int) + sizeof(float) * 3 * nVertices; @@ -86,7 +178,7 @@ bool Model::ConvertToVMAPModel(char * outfilename) fwrite(&nVertices, sizeof(int), 1, output); if(nVertices >0) { - for(uint32 vpos=0; vpos class Model; @@ -17,14 +18,18 @@ Vec3D fixCoordSystem(Vec3D v); class Model { public: - ModelHeader header; + ModelAnimation *anims; + int *globalSequences; public: + bool animGeometry,animTextures,animBones; + bool animated; - uint32 offsBB_vertices, offsBB_indices; - Vec3D *BB_vertices, *vertices; - uint16 *BB_indices, *indices; + bool isAnimated(MPQFile &f); + ModelVertex *origVertices; + Vec3D *vertices, *normals; + uint16 *indices; size_t nIndices; bool open(); @@ -33,6 +38,12 @@ public: public: bool ok; + bool ind; + + float rad; + float trans; + bool animcalc; + int anim, animtime; Model(std::string &filename); ~Model(); @@ -48,9 +59,15 @@ public: Model *model; int id; + Vec3D pos, rot; unsigned int d1, scale; - float w,sc; + + float frot,w,sc; + + int light; + Vec3D ldir; + Vec3D lcol; ModelInstance() {} ModelInstance(MPQFile &f,const char* ModelInstName,const char*MapName, FILE *pDirfile); diff --git a/contrib/vmap_extractor_v2/vmapextract/modelheaders.h b/contrib/vmap_extractor_v2/vmapextract/modelheaders.h index c35b983c19b..7d5e800e796 100644 --- a/contrib/vmap_extractor_v2/vmapextract/modelheaders.h +++ b/contrib/vmap_extractor_v2/vmapextract/modelheaders.h @@ -15,67 +15,289 @@ struct ModelHeader { uint8 version[4]; uint32 nameLength; uint32 nameOfs; - uint32 type; + uint32 type; + uint32 nGlobalSequences; uint32 ofsGlobalSequences; uint32 nAnimations; uint32 ofsAnimations; - uint32 nAnimationLookup; - uint32 ofsAnimationLookup; - uint32 nBones; - uint32 ofsBones; - uint32 nKeyBoneLookup; - uint32 ofsKeyBoneLookup; + uint32 nC; + uint32 ofsC; + uint32 nD; + uint32 ofsD; + uint32 nBones; + uint32 ofsBones; + uint32 nF; + uint32 ofsF; + uint32 nVertices; uint32 ofsVertices; uint32 nViews; + uint32 ofsViews; + uint32 nColors; uint32 ofsColors; + uint32 nTextures; uint32 ofsTextures; - uint32 nTransparency; + + uint32 nTransparency; // H uint32 ofsTransparency; - uint32 nTextureanimations; - uint32 ofsTextureanimations; - uint32 nTexReplace; - uint32 ofsTexReplace; - uint32 nRenderFlags; - uint32 ofsRenderFlags; - uint32 nBoneLookupTable; - uint32 ofsBoneLookupTable; - uint32 nTexLookup; - uint32 ofsTexLookup; - uint32 nTexUnits; - uint32 ofsTexUnits; - uint32 nTransLookup; - uint32 ofsTransLookup; - uint32 nTexAnimLookup; - uint32 ofsTexAnimLookup; - float floats[14]; - uint32 nBoundingTriangles; - uint32 ofsBoundingTriangles; - uint32 nBoundingVertices; - uint32 ofsBoundingVertices; - uint32 nBoundingNormals; - uint32 ofsBoundingNormals; - uint32 nAttachments; - uint32 ofsAttachments; - uint32 nAttachLookup; - uint32 ofsAttachLookup; - uint32 nAttachments_2; - uint32 ofsAttachments_2; - uint32 nLights; - uint32 ofsLights; - uint32 nCameras; - uint32 ofsCameras; - uint32 nCameraLookup; - uint32 ofsCameraLookup; - uint32 nRibbonEmitters; - uint32 ofsRibbonEmitters; - uint32 nParticleEmitters; - uint32 ofsParticleEmitters; + uint32 nI; // always unused ? + uint32 ofsI; + uint32 nTexAnims; // J + uint32 ofsTexAnims; + uint32 nK; + uint32 ofsK; + + uint32 nTexFlags; + uint32 ofsTexFlags; + uint32 nY; + uint32 ofsY; + + uint32 nTexLookup; + uint32 ofsTexLookup; + + uint32 nTexUnitLookup; // L + uint32 ofsTexUnitLookup; + uint32 nTransparencyLookup; // M + uint32 ofsTransparencyLookup; + uint32 nTexAnimLookup; + uint32 ofsTexAnimLookup; + + float floats[14]; + + uint32 nBoundingTriangles; + uint32 ofsBoundingTriangles; + uint32 nBoundingVertices; + uint32 ofsBoundingVertices; + uint32 nBoundingNormals; + uint32 ofsBoundingNormals; + + uint32 nO; + uint32 ofsO; + uint32 nP; + uint32 ofsP; + uint32 nQ; + uint32 ofsQ; + uint32 nLights; // R + uint32 ofsLights; + uint32 nCameras; // S + uint32 ofsCameras; + uint32 nT; + uint32 ofsT; + uint32 nRibbonEmitters; // U + uint32 ofsRibbonEmitters; + uint32 nParticleEmitters; // V + uint32 ofsParticleEmitters; + }; +// block B - animations +struct ModelAnimation { + uint32 animID; + uint32 timeStart; + uint32 timeEnd; + + float moveSpeed; + + uint32 loopType; + uint32 flags; + uint32 d1; + uint32 d2; + uint32 playSpeed; // note: this can't be play speed because it's 0 for some models + + Vec3D boxA, boxB; + float rad; + + int16 s[2]; +}; + + +// sub-block in block E - animation data +struct AnimationBlock { + int16 type; // interpolation type (0=none, 1=linear, 2=hermite) + int16 seq; // global sequence id or -1 + uint32 nRanges; + uint32 ofsRanges; + uint32 nTimes; + uint32 ofsTimes; + uint32 nKeys; + uint32 ofsKeys; +}; + +// block E - bones +struct ModelBoneDef { + int32 animid; + int32 flags; + int16 parent; // parent bone index + int16 geoid; + // new int added to the bone definitions. Added in WoW 2.0 + int32 unknown; + AnimationBlock translation; + AnimationBlock rotation; + AnimationBlock scaling; + Vec3D pivot; +}; + +struct ModelTexAnimDef { + AnimationBlock trans, rot, scale; +}; + +struct ModelVertex { + Vec3D pos; + uint8 weights[4]; + uint8 bones[4]; + Vec3D normal; + Vec2D texcoords; + int unk1, unk2; // always 0,0 so this is probably unused +}; + +struct ModelView { + uint32 nIndex, ofsIndex; // Vertices in this model (index into vertices[]) + uint32 nTris, ofsTris; // indices + uint32 nProps, ofsProps; // additional vtx properties + uint32 nSub, ofsSub; // materials/renderops/submeshes + uint32 nTex, ofsTex; // material properties/textures + int32 lod; // LOD bias? +}; + + +/// One material + render operation +struct ModelGeoset { + uint16 d1; // mesh part id? + uint16 d2; // ? + uint16 vstart; // first vertex + uint16 vcount; // num vertices + uint16 istart; // first index + uint16 icount; // num indices + uint16 d3; // number of bone indices + uint16 d4; // offset into bone index list + uint16 d5; // ? + uint16 d6; // root bone? + Vec3D v; + float unknown[4]; // Added in WoW 2.0? +}; + +/// A texture unit (sub of material) +struct ModelTexUnit{ + // probably the texture units + // size always >=number of materials it seems + uint16 flags; // Flags + uint16 order; // ? + uint16 op; // Material this texture is part of (index into mat) + uint16 op2; // Always same as above? + int16 colorIndex; // color or -1 + uint16 flagsIndex; // more flags... + uint16 texunit; // Texture unit (0 or 1) + uint16 d4; // ? (seems to be always 1) + uint16 textureid; // Texture id (index into global texture list) + uint16 texunit2; // copy of texture unit value? + uint16 transid; // transparency id (index into transparency list) + uint16 texanimid; // texture animation id +}; + +// block X - render flags +struct ModelRenderFlags { + uint16 flags; + uint16 blend; +}; + +// block G - color defs +struct ModelColorDef { + AnimationBlock color; + AnimationBlock opacity; +}; + +// block H - transp defs +struct ModelTransDef { + AnimationBlock trans; +}; + +struct ModelTextureDef { + uint32 type; + uint32 flags; + uint32 nameLen; + uint32 nameOfs; +}; + +struct ModelLightDef { + int16 type; + int16 bone; + Vec3D pos; + AnimationBlock ambColor; + AnimationBlock ambIntensity; + AnimationBlock color; + AnimationBlock intensity; + AnimationBlock attStart; + AnimationBlock attEnd; + AnimationBlock unk1; +}; + +struct ModelCameraDef { + int32 id; + float fov, farclip, nearclip; + AnimationBlock transPos; + Vec3D pos; + AnimationBlock transTarget; + Vec3D target; + AnimationBlock rot; +}; + + +struct ModelParticleParams { + float mid; + uint32 colors[3]; + float sizes[3]; + int16 d[10]; + float unk[3]; + float scales[3]; + float slowdown; + float rotation; + float f2[16]; +}; + +struct ModelParticleEmitterDef { + int32 id; + int32 flags; + Vec3D pos; + int16 bone; + int16 texture; + int32 nZero1; + int32 ofsZero1; + int32 nZero2; + int32 ofsZero2; + int16 blend; + int16 type; + int16 s1; + int16 s2; + int16 cols; + int16 rows; + AnimationBlock params[10]; + ModelParticleParams p; + AnimationBlock unk; +}; + + +struct ModelRibbonEmitterDef { + int32 id; + int32 bone; + Vec3D pos; + int32 nTextures; + int32 ofsTextures; + int32 nUnknown; + int32 ofsUnknown; + AnimationBlock color; + AnimationBlock opacity; + AnimationBlock above; + AnimationBlock below; + float res, length, unk; + int16 s1, s2; + AnimationBlock unk1; + AnimationBlock unk2; +}; + + #pragma pack(pop) diff --git a/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp b/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp index 0d2b39f8d06..dfc7cddcfdd 100644 --- a/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp +++ b/contrib/vmap_extractor_v2/vmapextract/vmapexport.cpp @@ -421,10 +421,6 @@ bool fillArchiveNameVector(std::vector& pArchiveNames) { // open expansion and common files printf("Opening data files from data directory.\n"); - sprintf(path, "%slichking.mpq", input_path); - pArchiveNames.push_back(path); - sprintf(path, "%scommon-2.mpq", input_path); - pArchiveNames.push_back(path); sprintf(path, "%sexpansion.mpq", input_path); pArchiveNames.push_back(path); sprintf(path, "%scommon.mpq", input_path); @@ -436,8 +432,6 @@ bool fillArchiveNameVector(std::vector& pArchiveNames) { for (std::vector::iterator i = locales.begin(); i != locales.end(); i++) { printf("Locale: %s\n", i->c_str()); - sprintf(path, "%s%s\\lichking-locale-%s.mpq", input_path, i->c_str(), i->c_str()); - pArchiveNames.push_back(path); sprintf(path, "%s%s\\expansion-locale-%s.mpq", input_path, i->c_str(), i->c_str()); pArchiveNames.push_back(path); sprintf(path, "%s%s\\locale-%s.mpq", input_path, i->c_str(), i->c_str()); diff --git a/sql/characters.sql b/sql/characters.sql index 1478571f131..4bb56a23297 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -15,13 +15,22 @@ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `saved_variables` +-- + +CREATE TABLE `saved_variables` ( + `NextArenaPointDistributionTime` bigint(40) UNSIGNED NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Variable Saves'; + -- -- Table structure for table `character_db_version` -- DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_2008_12_22_19_characters_item_instance` bit(1) default NULL + `required_2008_12_15_01_character_arenas` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- @@ -35,28 +44,6 @@ INSERT INTO `character_db_version` VALUES /*!40000 ALTER TABLE `character_db_version` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `account_data` --- - -DROP TABLE IF EXISTS `account_data`; -CREATE TABLE `account_data` ( - `account` int(11) unsigned NOT NULL default '0', - `type` int(11) unsigned NOT NULL default '0', - `time` bigint(11) unsigned NOT NULL default '0', - `data` longtext NOT NULL, - PRIMARY KEY (`account`,`type`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- --- Dumping data for table `account_data` --- - -LOCK TABLES `account_data` WRITE; -/*!40000 ALTER TABLE `account_data` DISABLE KEYS */; -/*!40000 ALTER TABLE `account_data` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `arena_team` -- @@ -241,49 +228,6 @@ LOCK TABLES `characters` WRITE; /*!40000 ALTER TABLE `characters` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `character_achievement` --- - -DROP TABLE IF EXISTS `character_achievement`; -CREATE TABLE `character_achievement` ( - `guid` int(11) NOT NULL, - `achievement` int(11) NOT NULL, - `date` int(11) NOT NULL, - PRIMARY KEY (`guid`,`achievement`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `character_achievement` --- - -LOCK TABLES `character_achievement` WRITE; -/*!40000 ALTER TABLE `character_achievement` DISABLE KEYS */; -/*!40000 ALTER TABLE `character_achievement` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `character_achievement_progress` --- - -DROP TABLE IF EXISTS `character_achievement_progress`; -CREATE TABLE `character_achievement_progress` ( - `guid` int(11) NOT NULL, - `criteria` int(11) NOT NULL, - `counter` int(11) NOT NULL, - `date` int(11) NOT NULL, - PRIMARY KEY (`guid`,`criteria`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `character_achievement_progress` --- - -LOCK TABLES `character_achievement_progress` WRITE; -/*!40000 ALTER TABLE `character_achievement_progress` DISABLE KEYS */; -/*!40000 ALTER TABLE `character_achievement_progress` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `character_action` -- @@ -466,7 +410,9 @@ CREATE TABLE `character_pet` ( `level` int(11) unsigned NOT NULL default '1', `exp` int(11) unsigned NOT NULL default '0', `Reactstate` tinyint(1) unsigned NOT NULL default '0', - `talentpoints` int(11) unsigned NOT NULL default '0', + `loyaltypoints` int(11) NOT NULL default '0', + `loyalty` int(11) unsigned NOT NULL default '0', + `trainpoint` int(11) NOT NULL default '0', `name` varchar(100) default 'Pet', `renamed` tinyint(1) unsigned NOT NULL default '0', `slot` int(11) unsigned NOT NULL default '0', @@ -1288,7 +1234,6 @@ CREATE TABLE `petition_sign` ( `type` int(10) unsigned NOT NULL default '0', PRIMARY KEY (`petitionguid`,`playerguid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Guild System'; - -- -- Dumping data for table `petition_sign` -- @@ -1379,26 +1324,6 @@ UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; --- --- Table structure for table `saved_variables` --- - -DROP TABLE IF EXISTS `saved_variables`; -CREATE TABLE `saved_variables` ( - `NextArenaPointDistributionTime` bigint(40) UNSIGNED NOT NULL DEFAULT '0' -) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Variable Saves'; - --- --- Dumping data for table `saved_variables` --- - -LOCK TABLES `saved_variables` WRITE; -/*!40000 ALTER TABLE `saved_variables` DISABLE KEYS */; -/*!40000 ALTER TABLE `saved_variables` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - - /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index f26209d4340..73c3f6121db 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -137,9 +137,6 @@ EndScriptData */ #define FLAME_ENRAGE_DISTANCE 30 #define FLAME_CHARGE_DISTANCE 50 -#define ITEM_ID_MAIN_HAND 32837 -#define ITEM_ID_OFF_HAND 32838 - /**** Creature Summon and Recognition IDs ****/ enum CreatureEntry { @@ -457,7 +454,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI { GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i)); if(Door) - Door->SetGoState(0); // Open Doors + Door->SetUInt32Value(GAMEOBJECT_STATE, 0); // Open Doors } } @@ -490,10 +487,10 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI { if(spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades! { - if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID)) - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); + if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY)) + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); else - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); } } @@ -570,8 +567,8 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI Timer[EVENT_FLIGHT_SEQUENCE] = 700; break; case 4://throw another - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); { uint8 i=0; Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); @@ -656,14 +653,14 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI if(DemonTransformation[TransformCount].equip) { - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Requip warglaives if needed - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); } else { - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+0, 0); // Unequip warglaives if needed - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); } switch(TransformCount) @@ -1009,10 +1006,10 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI DoorGUID[1] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_L); if(GETGO(Gate, GateGUID)) - Gate->SetGoState(1); + Gate->SetUInt32Value(GAMEOBJECT_STATE, 1); for(uint8 i = 0; i < 2; i++) if(GETGO(Door, DoorGUID[i])) - Door->SetGoState(1); + Door->SetUInt32Value(GAMEOBJECT_STATE, 1); } else { @@ -1082,7 +1079,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI for(uint8 i = 0; i < 2; i++) if(GETGO(Door, DoorGUID[i])) - Door->SetGoState(1); + Door->SetUInt32Value(GAMEOBJECT_STATE, 1); if(GETCRE(Illidan, IllidanGUID)) { @@ -1248,7 +1245,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI Spirit[0]->InterruptNonMeleeSpells(true); Spirit[1]->InterruptNonMeleeSpells(true); if(GETGO(Gate, GateGUID)) - Gate->SetGoState(0); + Gate->SetUInt32Value(GAMEOBJECT_STATE, 0); Timer = 2000; break; case 4: @@ -1279,7 +1276,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI case 6: for(uint8 i = 0; i < 2; i++) if(GETGO(Door, DoorGUID[i])) - Door->SetGoState(0); + Door->SetUInt32Value(GAMEOBJECT_STATE, 0); break; case 8: if(Phase == PHASE_WALK) @@ -1389,9 +1386,9 @@ struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI Timer[EVENT_MAIEV_STEALTH] = 0; Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000; Timer[EVENT_MAIEV_SHADOW_STRIKE] = 30000; - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 44850); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, 45738); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 44850); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2, 45738); } void Aggro(Unit *who) {} @@ -1677,7 +1674,7 @@ bool GOHello_cage_trap(Player* plr, GameObject* go) cell_lock->Visit(cell_lock, cSearcher, *(plr->GetMap())); ((cage_trap_triggerAI*)trigger->AI())->Active = true; - go->SetGoState(0); + go->SetUInt32Value(GAMEOBJECT_STATE, 0); return true; } @@ -1862,8 +1859,8 @@ void boss_illidan_stormrageAI::Reset() m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT); m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); @@ -1910,8 +1907,8 @@ void boss_illidan_stormrageAI::HandleTalkSequence() m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); break; case 8: - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Equip our warglaives! - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives! + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); break; diff --git a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp index 30a74c2da15..645a70df9f5 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp @@ -118,13 +118,13 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance void OpenDoor(uint64 DoorGUID, bool open) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(open ? 0 : 1); + Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); } void CloseDoor(uint64 DoorGUID, bool close) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(close ? 1 : 0); + Door->SetUInt32Value(GAMEOBJECT_STATE, close ? 1 : 0); } void OnCreatureCreate(Creature *creature, uint32 creature_entry) diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp index 25f3a4dc079..72002068fa8 100644 --- a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp +++ b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp @@ -89,13 +89,13 @@ struct TRINITY_DLL_DECL instance_blackrock_depths : public ScriptedInstance void OpenGO(uint64 DoorGUID, bool open) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(open ? 0 : 1); + Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); } void CloseGO(uint64 DoorGUID, bool close) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(close ? 1 : 0); + Door->SetUInt32Value(GAMEOBJECT_STATE, close ? 1 : 0); } uint32 GetData(uint32 type) @@ -146,13 +146,13 @@ struct TRINITY_DLL_DECL instance_blackrock_depths : public ScriptedInstance { switch(go->GetEntry()) { - case 170561: SupplyRoomGate = go->GetGUID(); state = go->GetGoState(); break; - case 170562: GateDughal = go->GetGUID(); state = go->GetGoState(); break; - case 170566: GateTobias = go->GetGUID(); state = go->GetGoState(); break; - case 170567: GateCrest = go->GetGUID(); state = go->GetGoState(); break; - case 170568: GateJaz = go->GetGUID(); state = go->GetGoState(); break; - case 170569: GateShill = go->GetGUID(); state = go->GetGoState(); break; - case 166872: SupplyCrate = go->GetGUID(); state = go->GetGoState(); break; + case 170561: SupplyRoomGate = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; + case 170562: GateDughal = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; + case 170566: GateTobias = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; + case 170567: GateCrest = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; + case 170568: GateJaz = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; + case 170569: GateShill = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; + case 166872: SupplyCrate = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; } } diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp index 401651ae221..e442d067bc4 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp @@ -235,12 +235,12 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI case 9: DoScriptText(SAY_TH_ARMORY, m_creature); m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, THRALL_WEAPON_MODEL); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, THRALL_SHIELD_MODEL); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); break; case 10: m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_EQUIPPED); @@ -399,8 +399,12 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI { DoUnmount(); HadMount = false; - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 0); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_UNEQUIPPED); } if( IsBeingEscorted ) diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp index 833bb03bce2..ffa9094b439 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp @@ -198,8 +198,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); m_creature->SetCorpseDelay(1000*60*60); if(pInstance) @@ -305,8 +305,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON); // and removing weapons - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); } } @@ -469,8 +469,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON); DoScriptText(SAY_SWITCH_TO_DEMON, m_creature); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY , 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); DemonForm = true; NeedThreatReset = true; SwitchToDemon_Timer = 45000; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp index 4e7f3d1989c..aaf6abdd3b0 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp @@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance void OpenDoor(uint64 DoorGUID, bool open) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(open ? 0 : 1); + Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); } void OnCreatureCreate(Creature *creature, uint32 creature_entry) diff --git a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp index df7ea54efb0..23d65ce42f7 100644 --- a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp +++ b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp @@ -120,13 +120,13 @@ struct TRINITY_DLL_DECL instance_deadmines : public ScriptedInstance void ShootCannon() { - DefiasCannon->SetGoState(0); + DefiasCannon->SetUInt32Value(GAMEOBJECT_STATE, 0); DoPlaySound(DefiasCannon, SOUND_CANNONFIRE); } void BlastOutDoor() { - IronCladDoor->SetGoState(2); + IronCladDoor->SetUInt32Value(GAMEOBJECT_STATE, 2); DoPlaySound(IronCladDoor, SOUND_DESTROYDOOR); } diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp index d31df82df58..cf1ff7c1eeb 100644 --- a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp +++ b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp @@ -238,8 +238,8 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI DoScriptText(SAY_ENRAGE, m_creature); m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); } if(Phase2) diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp index 08ee10967a1..f20ad6c69a5 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp @@ -289,11 +289,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI void ClearWeapons() { - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0); //damage const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); @@ -433,11 +433,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI m_creature->CastSpell(m_creature, SPELL_THRASH_AURA, true); //models - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, AXE_EQUIP_MODEL); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, AXE_EQUIP_MODEL); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO); //damage const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); @@ -475,8 +475,8 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI Creature *axe = m_creature->SummonCreature(MALCHEZARS_AXE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000); if(axe) { - axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL); - //axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); + axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL); + axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); axe->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); axe->setFaction(m_creature->getFaction()); diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp index d546c5b2d6f..f66e20ed5cd 100644 --- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp +++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp @@ -736,7 +736,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI sprouted = false; DoCast(m_creature,SPELL_PUMPKIN_AURA,true); DoCast(m_creature,SPELL_SPROUTING); - m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED); + m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE); } void Aggro(Unit *who){} @@ -747,7 +747,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI { sprouted = true; m_creature->RemoveAllAuras(); - m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE); DoCast(m_creature,SPELL_SPROUT_BODY,true); m_creature->UpdateEntry(PUMPKIN_FIEND); DoStartMovement(m_creature->getVictim()); diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp index 0db9f283374..86051831fb5 100644 --- a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp +++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp @@ -92,7 +92,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance { GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID); if(Shrine) - Shrine->SetGoState(1); + Shrine->SetUInt32Value(GAMEOBJECT_STATE,1); }break; case DATA_HORSEMAN_EVENT: if (data == DONE) @@ -106,7 +106,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance HorsemanAdds.clear(); GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID); if(Shrine) - Shrine->SetGoState(1); + Shrine->SetUInt32Value(GAMEOBJECT_STATE,1); } break; } diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp index 61aca9df2e3..e9454d713ed 100644 --- a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp +++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp @@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance void OpenDoor(uint64 DoorGUID, bool open) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(open ? 0 : 1); + Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); } void SetData(uint32 type, uint32 data) diff --git a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp index ca231a6bd12..c564088be76 100644 --- a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp +++ b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp @@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance break; case ANCIENT_VAULT_DOOR: - go->SetGoState(1); + go->SetUInt32Value(GAMEOBJECT_STATE,1); go->SetUInt32Value(GAMEOBJECT_FLAGS, 33); ancientVaultDoor = go->GetGUID(); break; @@ -93,7 +93,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance return; go->SetUInt32Value(GAMEOBJECT_FLAGS, 33); - go->SetGoState(0); + go->SetUInt32Value(GAMEOBJECT_STATE, 0); } void ActivateStoneKeepers() diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp index 4c56d230263..82a993c3894 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp @@ -237,7 +237,8 @@ struct TRINITY_DLL_DECL boss_hex_lord_malacrassAI : public ScriptedAI SpawnAdds(); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 46916); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 50268674); m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); } diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp index f9a90809c89..8017033a4bd 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp @@ -149,7 +149,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI TankGUID = 0; inBearForm = false; - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122); } void SendAttacker(Unit* target) @@ -388,7 +388,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI { if(inBearForm) { - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122); DoYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_YELL_TOTROLL); m_creature->RemoveAurasDueToSpell(SPELL_BEARFORM); @@ -400,7 +400,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI } else { - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0); DoYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_YELL_TOBEAR); DoCast(m_creature, SPELL_BEARFORM, true); diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp index 3ace2e79e22..2c50875e4ad 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp @@ -207,9 +207,9 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI Summons.DespawnAll(); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 47174); - //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674); - //m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 47174); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674); + m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); } void Aggro(Unit *who) @@ -341,7 +341,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI m_creature->Relocate(CENTER_X, CENTER_Y, CENTER_Z,0); m_creature->SendMonsterMove(CENTER_X, CENTER_Y, CENTER_Z,0,0,100); DoResetThreat(); - m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); m_creature->RemoveAurasDueToSpell(Transform[Phase].unaura); DoCast(m_creature, Transform[Phase].spell); DoYell(Transform[Phase].text, LANG_UNIVERSAL, NULL); diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp index b510f74bb67..95e62063e26 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp @@ -140,7 +140,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance void OpenDoor(uint64 DoorGUID, bool open) { if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) - Door->SetGoState(open ? 0 : 1); + Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); } void SummonHostage(uint8 num) diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp index 8b993815c00..f79247bbfc0 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp @@ -65,9 +65,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI if (Invisible_Timer < diff) { m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); - m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); - //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3); + m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); + m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); + m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686); Invisible = true; @@ -100,9 +100,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,15268); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 31818); - //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); - //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3); + m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 31818); + m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); + m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + 1, 3); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Invisible = false; diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp deleted file mode 100644 index e4e26dec111..00000000000 --- a/src/game/AchievementMgr.cpp +++ /dev/null @@ -1,910 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "AchievementMgr.h" -#include "Common.h" -#include "Player.h" -#include "WorldPacket.h" -#include "Database/DBCEnums.h" -#include "ObjectMgr.h" -#include "Guild.h" -#include "Database/DatabaseEnv.h" -#include "GameEvent.h" -#include "World.h" -#include "SpellMgr.h" - -const CriteriaCastSpellRequirement AchievementMgr::criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] = - { - {5272, 3057, 0, 0}, - {5273, 2784, 0, 0}, - {5752, 9099, 0, 0}, - {5753, 8403, 0, 0}, - {5772, 0, 0, RACE_GNOME}, - {5774, 0, 0, RACE_BLOODELF}, - {5775, 0, 0, RACE_DRAENEI}, - {5776, 0, 0, RACE_DWARF}, - {5777, 0, 0, RACE_HUMAN}, - {5778, 0, 0, RACE_NIGHTELF}, - {5779, 0, 0, RACE_ORC}, - {5780, 0, 0, RACE_TAUREN}, - {5781, 0, 0, RACE_TROLL}, - {5782, 0, 0, RACE_UNDEAD_PLAYER}, - {6225, 5661, 0, 0}, - {6226, 26044, 0, 0}, - {6228, 739, 0, 0}, - {6229, 927, 0, 0}, - {6230, 1444, 0, 0}, - {6231, 8140, 0, 0}, - {6232, 5489, 0, 0}, - {6233,12336, 0, 0}, - {6234, 1351, 0, 0}, - {6235, 5484, 0, 0}, - {6236, 1182, 0, 0}, - {6237, 0, CLASS_DEATH_KNIGHT, RACE_ORC}, - {6238, 0, CLASS_WARRIOR, RACE_HUMAN}, - {6239, 0, CLASS_SHAMAN, RACE_TAUREN}, - {6240, 0, CLASS_DRUID, RACE_NIGHTELF}, - {6241, 0, CLASS_ROGUE, RACE_UNDEAD_PLAYER}, - {6242, 0, CLASS_HUNTER, RACE_TROLL}, - {6243, 0, CLASS_MAGE, RACE_GNOME}, - {6244, 0, CLASS_PALADIN, RACE_DWARF}, - {6245, 0, CLASS_WARLOCK, RACE_BLOODELF}, - {6246, 0, CLASS_PRIEST, RACE_DRAENEI}, - {6312, 0, CLASS_WARLOCK, RACE_GNOME}, - {6313, 0, CLASS_DEATH_KNIGHT, RACE_HUMAN}, - {6314, 0, CLASS_PRIEST, RACE_NIGHTELF}, - {6315, 0, CLASS_SHAMAN, RACE_ORC}, - {6316, 0, CLASS_DRUID, RACE_TAUREN}, - {6317, 0, CLASS_ROGUE, RACE_TROLL}, - {6318, 0, CLASS_WARRIOR, RACE_UNDEAD_PLAYER}, - {6319, 0, CLASS_MAGE, RACE_BLOODELF}, - {6320, 0, CLASS_PALADIN, RACE_DRAENEI}, - {6321, 0, CLASS_HUNTER, RACE_DWARF}, - {6662, 31261, 0, 0} - }; - -const AchievementReward AchievementMgr::achievementRewards[ACHIEVEMENT_REWARD_COUNT] = - { - // achievementId, horde titleid, alliance titleid, itemid - {45, 0, 0, 43348}, - {46, 78, 78, 0}, - {230, 72, 72, 0}, - {456, 139, 139, 0}, - {614, 0, 0, 44223}, - {619, 0, 0, 44224}, - {714, 47, 47, 0}, - {762, 130, 130, 0}, - {870, 127, 126, 0}, - {871, 144, 144, 0}, - {876, 0, 0, 43349}, - {907, 48, 48, 0}, - {913, 74, 74, 0}, - {942, 79, 79, 0}, - {943, 79, 79, 0}, - {945, 131, 131, 0}, - {948, 130, 130, 0}, - {953, 132, 132, 0}, - {978, 81, 81, 0}, - {1015, 77, 77, 0}, - {1021, 0, 0, 40643}, - {1038, 75, 75, 0}, - {1039, 76, 76, 0}, - {1163, 128, 128, 0}, - {1174, 82, 82, 0}, - {1175, 72, 72, 0}, - {1250, 0, 0, 40653}, - {1400, 120, 120, 0}, - {1402, 122, 122, 0}, - {1516, 83, 83, 0}, - {1563, 84, 84, 0}, - {1656, 124, 124, 0}, - {1657, 124, 124, 0}, - {1658, 129, 129, 0}, - {1681, 125, 125, 43300}, - {1682, 125, 125, 43300}, - {1683, 133, 133, 0}, - {1684, 133, 133, 0}, - {1691, 134, 134, 0}, - {1692, 134, 134, 0}, - {1693, 135, 135, 0}, - {1707, 135, 135, 0}, - {1784, 84, 84, 0}, - {1793, 137, 137, 0}, - {1956, 0, 0, 43824}, - {2051, 140, 140, 0}, - {2054, 121, 121, 0}, - {2096, 0, 0, 44430}, - {2136, 0, 0, 0},// <- TODO: find item for spell 59961 - {2137, 0, 0, 0},// <- TODO: find item for spell 60021 - {2138, 0, 0, 0},// <- TODO: find item for spell 59976 - {2143, 0, 0, 44178}, - {2144, 0, 0, 0},// <- TODO: find item for spell 60024 - {2145, 0, 0, 0},// <- TODO: find item for spell 60024 - {2186, 141, 141, 0}, - {2187, 142, 142, 0}, - {2188, 143, 143, 0} - }; - -AchievementMgr::AchievementMgr(Player *player) -{ - m_player = player; -} - -AchievementMgr::~AchievementMgr() -{ -} - -void AchievementMgr::SaveToDB() -{ - if(!m_completedAchievements.empty()) - { - bool need_execute = false; - std::ostringstream ssdel; - std::ostringstream ssins; - for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); iter++) - { - if(!iter->second.changed) - continue; - - /// first new/changed record prefix - if(!need_execute) - { - ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN ("; - ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES "; - need_execute = true; - } - /// next new/changed record prefix - else - { - ssdel << ", "; - ssins << ", "; - } - - // new/changed record data - ssdel << iter->first; - ssins << "("<GetGUIDLow() << ", " << iter->first << ", " << uint64(iter->second.date) << ")"; - - /// mark as saved in db - iter->second.changed = false; - } - - if(need_execute) - ssdel << ")"; - - if(need_execute) - { - CharacterDatabase.BeginTransaction (); - CharacterDatabase.Execute( ssdel.str().c_str() ); - CharacterDatabase.Execute( ssins.str().c_str() ); - CharacterDatabase.CommitTransaction (); - } - } - - if(!m_criteriaProgress.empty()) - { - /// prepare deleting and insert - bool need_execute = false; - std::ostringstream ssdel; - std::ostringstream ssins; - for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) - { - if(!iter->second.changed) - continue; - - /// first new/changed record prefix - if(!need_execute) - { - ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; - ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES "; - need_execute = true; - } - /// next new/changed record prefix - else - { - ssdel << ", "; - ssins << ", "; - } - - // new/changed record data - ssdel << iter->first; - ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; - - /// mark as saved in db - iter->second.changed = false; - } - - if(need_execute) - ssdel << ")"; - - if(need_execute) - { - CharacterDatabase.BeginTransaction (); - CharacterDatabase.Execute( ssdel.str().c_str() ); - CharacterDatabase.Execute( ssins.str().c_str() ); - CharacterDatabase.CommitTransaction (); - } - } -} - -void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult) -{ - if(achievementResult) - { - do - { - Field *fields = achievementResult->Fetch(); - CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()]; - ca.date = time_t(fields[1].GetUInt64()); - ca.changed = false; - } while(achievementResult->NextRow()); - delete achievementResult; - } - - if(criteriaResult) - { - do - { - Field *fields = criteriaResult->Fetch(); - - uint32 id = fields[0].GetUInt32(); - uint32 counter = fields[1].GetUInt32(); - time_t date = time_t(fields[2].GetUInt64()); - - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); - if(!criteria || criteria->timeLimit && date + criteria->timeLimit < time(NULL)) - continue; - - CriteriaProgress& progress = m_criteriaProgress[id]; - progress.counter = counter; - progress.date = date; - progress.changed = false; - } while(criteriaResult->NextRow()); - delete criteriaResult; - } - -} - -void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) -{ - sLog.outString("AchievementMgr::SendAchievementEarned(%u)", achievement->ID); - - const char *msg = "|Hplayer:$N|h[$N]|h has earned the achievement $a!"; - if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId())) - { - WorldPacket data(SMSG_MESSAGECHAT, 200); - data << uint8(CHAT_MSG_ACHIEVEMENT); - data << uint8(CHAT_MSG_GUILD_ACHIEVEMENT); - data << uint32(LANG_UNIVERSAL); - data << uint64(GetPlayer()->GetGUID()); - data << uint32(5); - data << uint64(GetPlayer()->GetGUID()); - data << uint32(strlen(msg)+1); - data << msg; - data << uint8(0); - data << uint32(achievement->ID); - guild->BroadcastPacket(&data); - } - if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) - { - // broadcast realm first reached - WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4); - data << GetPlayer()->GetName(); - data << uint64(GetPlayer()->GetGUID()); - data << uint32(achievement->ID); - data << uint32(0); // 1=link supplied string as player name, 0=display plain string - sWorld.SendGlobalMessage(&data); - } - else - { - WorldPacket data(SMSG_MESSAGECHAT, 200); - data << uint8(CHAT_MSG_ACHIEVEMENT); - data << uint32(LANG_UNIVERSAL); - data << uint64(GetPlayer()->GetGUID()); - data << uint32(5); - data << uint64(GetPlayer()->GetGUID()); - data << uint32(strlen(msg)+1); - data << msg; - data << uint8(0); - data << uint32(achievement->ID); - GetPlayer()->SendMessageToSet(&data, true); - - } - WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); - data.append(GetPlayer()->GetPackGUID()); - data << uint32(achievement->ID); - data << uint32(secsToTimeBitFields(time(NULL))); - data << uint32(0); - GetPlayer()->SendMessageToSet(&data, true); -} - -void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress) -{ - WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8); - data << uint32(id); - - // the counter is packed like a packed Guid - data.appendPackGUID(progress->counter); - - data.append(GetPlayer()->GetPackGUID()); - data << uint32(0); - data << uint32(secsToTimeBitFields(progress->date)); - data << uint32(0); // timer 1 - data << uint32(0); // timer 2 - GetPlayer()->SendMessageToSet(&data, true); -} - -/** - * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet - */ -void AchievementMgr::CheckAllAchievementCriteria() -{ - // suppress sending packets - for(uint32 i=0; igroupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup()) - continue; - - AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); - if(!achievement) - continue; - - if(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE || - achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE) - continue; - - switch (type) - { - case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: - SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel()); - break; - case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1); - break; - case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - if(achievementCriteria->kill_creature.creatureID != miscvalue1) - continue; - SetCriteriaProgress(achievementCriteria, miscvalue2, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: - if(uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID)) - SetCriteriaProgress(achievementCriteria, skillvalue); - break; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: - { - uint32 counter =0; - for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++) - if(itr->second.m_rewarded) - counter++; - SetCriteriaProgress(achievementCriteria, counter); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: - { - uint32 counter =0; - for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++) - { - Quest const* quest = objmgr.GetQuestTemplate(itr->first); - if(itr->second.m_rewarded && quest->GetZoneOrSort() == achievementCriteria->complete_quests_in_zone.zoneID) - counter++; - } - SetCriteriaProgress(achievementCriteria, counter); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - SetCriteriaProgress(achievementCriteria, miscvalue1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - if(GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID) - continue; - SetCriteriaProgress(achievementCriteria, miscvalue1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: - if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) - SetCriteriaProgress(achievementCriteria, 1); - break; - case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - if(GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID) - continue; - SetCriteriaProgress(achievementCriteria, 1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - if(miscvalue1 != achievementCriteria->killed_by_creature.creatureEntry) - continue; - SetCriteriaProgress(achievementCriteria, 1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - SetCriteriaProgress(achievementCriteria, 1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: - { - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - if(achievement->ID == 1260) - { - if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED) - continue; - // TODO: hardcoding eventid is bad, it can differ from DB to DB - maye implement something using HolidayNames.dbc? - if(!gameeventmgr.IsActiveEvent(26)) - continue; - } - // miscvalue1 is the ingame fallheight*100 as stored in dbc - SetCriteriaProgress(achievementCriteria, miscvalue1); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: - if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) - SetCriteriaProgress(achievementCriteria, 1); - break; - case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: - // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case - if(!miscvalue1) - continue; - if(achievementCriteria->use_item.itemID != miscvalue1) - continue; - SetCriteriaProgress(achievementCriteria, 1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: - // speedup for non-login case - if(miscvalue1 && achievementCriteria->own_item.itemID!=miscvalue1) - continue; - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true)); - break; - case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: - // You _have_ to loot that item, just owning it when logging in does _not_ count! - if(!miscvalue1) - continue; - if(miscvalue1 != achievementCriteria->own_item.itemID) - continue; - SetCriteriaProgress(achievementCriteria, miscvalue2, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: - case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: - if (!miscvalue1 || miscvalue1 != achievementCriteria->be_spell_target.spellID) - continue; - SetCriteriaProgress(achievementCriteria, 1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: - if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID) - continue; - SetCriteriaProgress(achievementCriteria, 1, true); - break; - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: - { - if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID) - continue; - // those requirements couldn't be found in the dbc - - const CriteriaCastSpellRequirement *requirement = NULL; - for (uint32 i=0; iID) - { - requirement = &criteriaCastSpellRequirements[i]; - break; - } - } - - if (requirement) - { - if (!unit) - continue; - - if (requirement->creatureEntry && unit->GetEntry() != requirement->creatureEntry) - continue; - - if (requirement->playerRace && (unit->GetTypeId() != TYPEID_PLAYER || unit->getRace()!=requirement->playerRace)) - continue; - - if (requirement->playerClass && (unit->GetTypeId() != TYPEID_PLAYER || unit->getClass()!=requirement->playerClass)) - continue; - } - SetCriteriaProgress(achievementCriteria, 1, true); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: - { - uint32 spellCount = 0; - for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin(); - spellIter != GetPlayer()->GetSpellMap().end(); - spellIter++) - { - for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first); - skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first); - skillIter++) - { - if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine) - spellCount++; - } - } - SetCriteriaProgress(achievementCriteria, spellCount); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: - { - // skip for login case - if(!miscvalue1) - continue; - SetCriteriaProgress(achievementCriteria, 1); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: - { - int32 reputation = GetPlayer()->GetReputation(achievementCriteria->gain_reputation.factionID); - if (reputation > 0) - SetCriteriaProgress(achievementCriteria, reputation); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: - { - uint32 counter = 0; - const FactionStateList factionStateList = GetPlayer()->GetFactionStateList(); - for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); iter++) - { - if(GetPlayer()->ReputationToRank(iter->second.Standing) >= REP_EXALTED) - ++counter; - } - SetCriteriaProgress(achievementCriteria, counter); - break; - } - case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: - { - WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference); - if(!worldOverlayEntry) - break; - - int32 exploreFlag = GetAreaFlagByAreaID(worldOverlayEntry->areatableID); - if(exploreFlag < 0) - break; - - uint32 playerIndexOffset = uint32(exploreFlag) / 32; - uint32 mask = 1<< (uint32(exploreFlag) % 32); - - if(GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) - SetCriteriaProgress(achievementCriteria, 1); - break; - } - - } - if(IsCompletedCriteria(achievementCriteria)) - CompletedCriteria(achievementCriteria); - } -} - -bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria) -{ - AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); - if(!achievement) - return false; - - // counter can never complete - if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) - return false; - - if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) - { - // someone on this realm has already completed that achievement - if(objmgr.allCompletedAchievements.find(achievement->ID)!=objmgr.allCompletedAchievements.end()) - return false; - } - - CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID); - if(itr == m_criteriaProgress.end()) - return false; - - CriteriaProgress const* progress = &itr->second; - - switch(achievementCriteria->requiredType) - { - case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: - if(achievement->ID == 467 && GetPlayer()->getClass() != CLASS_SHAMAN || - achievement->ID == 466 && GetPlayer()->getClass() != CLASS_DRUID || - achievement->ID == 465 && GetPlayer()->getClass() != CLASS_PALADIN || - achievement->ID == 464 && GetPlayer()->getClass() != CLASS_PRIEST || - achievement->ID == 463 && GetPlayer()->getClass() != CLASS_WARLOCK || - achievement->ID == 462 && GetPlayer()->getClass() != CLASS_HUNTER || - achievement->ID == 461 && GetPlayer()->getClass() != CLASS_DEATH_KNIGHT || - achievement->ID == 460 && GetPlayer()->getClass() != CLASS_MAGE || - achievement->ID == 459 && GetPlayer()->getClass() != CLASS_WARRIOR || - achievement->ID == 458 && GetPlayer()->getClass() != CLASS_ROGUE || - - achievement->ID == 1404 && GetPlayer()->getRace() != RACE_GNOME || - achievement->ID == 1405 && GetPlayer()->getRace() != RACE_BLOODELF || - achievement->ID == 1406 && GetPlayer()->getRace() != RACE_DRAENEI || - achievement->ID == 1407 && GetPlayer()->getRace() != RACE_DWARF || - achievement->ID == 1408 && GetPlayer()->getRace() != RACE_HUMAN || - achievement->ID == 1409 && GetPlayer()->getRace() != RACE_NIGHTELF || - achievement->ID == 1410 && GetPlayer()->getRace() != RACE_ORC || - achievement->ID == 1411 && GetPlayer()->getRace() != RACE_TAUREN || - achievement->ID == 1412 && GetPlayer()->getRace() != RACE_TROLL || - achievement->ID == 1413 && GetPlayer()->getRace() != RACE_UNDEAD_PLAYER ) - return false; - return progress->counter >= achievementCriteria->reach_level.level; - case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: - return progress->counter >= achievementCriteria->buy_bank_slot.numberOfSlots; - case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: - return progress->counter >= achievementCriteria->kill_creature.creatureCount; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: - return m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end(); - case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: - return progress->counter >= achievementCriteria->reach_skill_level.skillLevel; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: - return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: - return progress->counter >= achievementCriteria->complete_daily_quest.questCount; - case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: - return progress->counter >= 1; - case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: - return progress->counter >= achievementCriteria->fall_without_dying.fallHeight; - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: - return progress->counter >= 1; - case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: - return progress->counter >= achievementCriteria->use_item.itemCount; - case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: - return progress->counter >= achievementCriteria->own_item.itemCount; - case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: - return progress->counter >= achievementCriteria->loot_item.itemCount; - case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: - case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: - return progress->counter >= achievementCriteria->be_spell_target.spellCount; - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: - case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: - return progress->counter >= achievementCriteria->cast_spell.castCount; - case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: - return progress->counter >= achievementCriteria->learn_skilline_spell.spellCount; - case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: - return progress->counter >= achievementCriteria->visit_barber.numberOfVisits; - case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: - return progress->counter >= achievementCriteria->gain_reputation.reputationAmount; - case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: - return progress->counter >= achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions; - case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: - return progress->counter >= 1; - - // handle all statistic-only criteria here - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: - case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: - case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: - return false; - } - return false; -} - -void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria) -{ - AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement); - if(!achievement) - return; - // counter can never complete - if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) - return; - - if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL || GetAchievementCompletionState(achievement)==ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED) - { - CompletedAchievement(achievement); - } -} - -// TODO: achievement 705 requires 4 criteria to be fulfilled -AchievementCompletionState AchievementMgr::GetAchievementCompletionState(AchievementEntry const* entry) -{ - if(m_completedAchievements.find(entry->ID)!=m_completedAchievements.end()) - return ACHIEVEMENT_COMPLETED_COMPLETED_STORED; - - bool foundOutstanding = false; - for (uint32 entryId = 0; entryIdreferredAchievement!= entry->ID) - continue; - - if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL) - return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED; - - // found an umcompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL - if(!IsCompletedCriteria(criteria)) - foundOutstanding = true; - } - if(foundOutstanding) - return ACHIEVEMENT_COMPLETED_NONE; - else - return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED; -} - -void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative) -{ - sLog.outString("AchievementMgr::SetCriteriaProgress(%u, %u)", entry->ID, newValue); - CriteriaProgress *progress = NULL; - - CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); - - if(iter == m_criteriaProgress.end()) - { - progress = &m_criteriaProgress[entry->ID]; - progress->counter = 0; - progress->date = time(NULL); - } - else - { - progress = &iter->second; - if(relative) - newValue += progress->counter; - if(progress->counter == newValue) - return; - progress->counter = newValue; - } - - progress->changed = true; - - if(entry->timeLimit) - { - time_t now = time(NULL); - if(progress->date + entry->timeLimit < now) - { - progress->counter = 1; - } - // also it seems illogical, the timeframe will be extended at every criteria update - progress->date = now; - } - SendCriteriaUpdate(entry->ID,progress); -} - -void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) -{ - sLog.outString("AchievementMgr::CompletedAchievement(%u)", achievement->ID); - if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end()) - return; - - SendAchievementEarned(achievement); - CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; - ca.date = time(NULL); - ca.changed = true; - - // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement - // TODO: where do set this instead? - if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) - objmgr.allCompletedAchievements.insert(achievement->ID); - - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); - - // reward items and titles - AchievementReward const* reward = NULL; - for (uint32 i=0; iID) - { - reward = &achievementRewards[i]; - break; - } - } - - if (reward) - { - sLog.outString("achiev %u, title= %u, %u", reward->achievementId, reward->titleId[0], reward->titleId[1]); - uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1]; - if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) - GetPlayer()->SetTitle(titleEntry); - - if (reward->itemId) - { - ItemPrototype const *pProto = objmgr.GetItemPrototype( reward->itemId ); - - if(!pProto) - { - GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); - return; - } - - ItemPosCountVec dest; - uint32 no_space = 0; - uint8 msg = GetPlayer()->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, reward->itemId, 1, &no_space ); - - if( msg != EQUIP_ERR_OK ) - { - GetPlayer()->SendEquipError( msg, NULL, NULL ); - return; - } - Item* pItem = GetPlayer()->StoreNewItem( dest, reward->itemId, true); - - if(!pItem) - { - GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); - return; - } - } - } -} - -void AchievementMgr::SendAllAchievementData() -{ - // since we don't know the exact size of the packed GUIDs this is just an approximation - WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); - BuildAllDataPacket(&data); - GetPlayer()->GetSession()->SendPacket(&data); -} - -void AchievementMgr::SendRespondInspectAchievements(Player* player) -{ - // since we don't know the exact size of the packed GUIDs this is just an approximation - WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); - data.append(GetPlayer()->GetPackGUID()); - BuildAllDataPacket(&data); - player->GetSession()->SendPacket(&data); -} - -/** - * used by both SMSG_ALL_ACHIEVEMENT_DATA and SMSG_RESPOND_INSPECT_ACHIEVEMENT - */ -void AchievementMgr::BuildAllDataPacket(WorldPacket *data) -{ - for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter) - { - *data << uint32(iter->first); - *data << uint32(secsToTimeBitFields(iter->second.date)); - } - *data << int32(-1); - - for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) - { - *data << uint32(iter->first); - data->appendPackGUID(iter->second.counter); - data->append(GetPlayer()->GetPackGUID()); - *data << uint32(0); - *data << uint32(secsToTimeBitFields(iter->second.date)); - *data << uint32(0); - *data << uint32(0); - } - - *data << int32(-1); -} diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h deleted file mode 100644 index 6392a9fc647..00000000000 --- a/src/game/AchievementMgr.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __MANGOS_ACHIEVEMENTMGR_H -#define __MANGOS_ACHIEVEMENTMGR_H - -#include "Common.h" -#include "Database/DBCEnums.h" -#include "Database/DBCStores.h" -#include "Database/DatabaseEnv.h" - -#define CRITERIA_CAST_SPELL_REQ_COUNT 46 -#define ACHIEVEMENT_REWARD_COUNT 57 - -struct CriteriaProgress -{ - uint32 counter; - time_t date; - bool changed; -}; - -struct CriteriaCastSpellRequirement -{ - uint32 achievementCriteriaId; - uint32 creatureEntry; - uint8 playerClass; - uint8 playerRace; -}; - -struct AchievementReward -{ - uint32 achievementId; - uint32 titleId[2]; - uint32 itemId; -}; - -struct CompletedAchievementData -{ - time_t date; - bool changed; -}; - -typedef UNORDERED_MAP CriteriaProgressMap; -typedef UNORDERED_MAP CompletedAchievementMap; - -class Unit; -class Player; -class WorldPacket; - -enum AchievementCompletionState -{ - ACHIEVEMENT_COMPLETED_NONE, - ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED, - ACHIEVEMENT_COMPLETED_COMPLETED_STORED, -}; - -class AchievementMgr -{ - public: - AchievementMgr(Player* pl); - ~AchievementMgr(); - - void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult); - void SaveToDB(); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0); - void CheckAllAchievementCriteria(); - void SendAllAchievementData(); - void SendRespondInspectAchievements(Player* player); - Player* GetPlayer() { return m_player;} - - private: - void SendAchievementEarned(AchievementEntry const* achievement); - void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress); - void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative=false); - void CompletedCriteria(AchievementCriteriaEntry const* entry); - void CompletedAchievement(AchievementEntry const* entry); - bool IsCompletedCriteria(AchievementCriteriaEntry const* entry); - AchievementCompletionState GetAchievementCompletionState(AchievementEntry const* entry); - void BuildAllDataPacket(WorldPacket *data); - - Player* m_player; - CriteriaProgressMap m_criteriaProgress; - CompletedAchievementMap m_completedAchievements; - static const CriteriaCastSpellRequirement criteriaCastSpellRequirements[]; - static const AchievementReward achievementRewards[]; -}; -#endif diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp index a12e8a8f238..71a8bb495b4 100644 --- a/src/game/AuctionHouse.cpp +++ b/src/game/AuctionHouse.cpp @@ -752,23 +752,3 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) data << (uint32) 300; // unk 2.3.0 const? SendPacket(&data); } - -void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data ) -{ - sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES"); - recv_data.hexlike(); - - uint32 count = 0; - - WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4); - data << uint32(count); // count - /*for(uint32 i = 0; i < count; ++i) - { - data << ""; // string - data << ""; // string - data << uint32(0); - data << uint32(0); - data << float(0); - }*/ - SendPacket(&data); -} diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index 5c870bdb2b7..765d40f3962 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.cpp @@ -34,7 +34,7 @@ Bag::Bag( ): Item() m_valuesCount = CONTAINER_END; - memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); + memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); // Maximum 20 Slots } Bag::~Bag() diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index b562517dc08..d392f074600 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -576,7 +576,6 @@ void BattleGround::EndBattleGround(uint32 winner) uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); plr->GetSession()->SendPacket(&data); - plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } if(isArena() && isRated() && winner_arena_team && loser_arena_team) @@ -1406,10 +1405,10 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID()); // aura - pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL); - //pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009); - //pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); - //pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF); + pCreature->SetUInt32Value(UNIT_FIELD_AURA, SPELL_SPIRIT_HEAL_CHANNEL); + pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009); + pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); + pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF); // casting visual effect pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL); // correct cast speed diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 7b93adb7dfb..3c98afe6d17 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -132,6 +132,8 @@ struct BattleGroundObjectInfo uint32 spellid; }; +#define MAX_QUEUED_PLAYERS_MAP 7 + enum BattleGroundTypeId { BATTLEGROUND_AV = 1, @@ -141,10 +143,7 @@ enum BattleGroundTypeId BATTLEGROUND_BE = 5, BATTLEGROUND_AA = 6, BATTLEGROUND_EY = 7, - BATTLEGROUND_RL = 8, - BATTLEGROUND_SA = 9, - BATTLEGROUND_DS = 10, - BATTLEGROUND_RV = 11 + BATTLEGROUND_RL = 8 }; // handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index de525ae209d..4be2320be6a 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -1267,16 +1267,13 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) *data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended; // bases defended break; case BATTLEGROUND_EY: - *data << (uint32)0x00000001; // count of next fields + *data << (uint32)0x00000001; // count of next fields *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures; // flag captures break; case BATTLEGROUND_NA: case BATTLEGROUND_BE: case BATTLEGROUND_AA: case BATTLEGROUND_RL: - case BATTLEGROUND_SA: // wotlk - case BATTLEGROUND_DS: // wotlk - case BATTLEGROUND_RV: // wotlk *data << (int32)0; // 0 break; default: diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 7ca3efed59b..b217c1d692e 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -32,9 +32,9 @@ typedef std::map BattleGroundSet; //typedef std::map BattleGroundQueueSet; typedef std::deque BGFreeSlotQueueType; -#define MAX_BATTLEGROUND_QUEUES 8 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, 80+ +#define MAX_BATTLEGROUND_QUEUES 7 // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+ -#define MAX_BATTLEGROUND_TYPES 12 // each BG type will be in array +#define MAX_BATTLEGROUND_TYPES 9 // each BG type will be in array #define MAX_BATTLEGROUND_QUEUE_TYPES 8 diff --git a/src/game/Calendar.cpp b/src/game/Calendar.cpp deleted file mode 100644 index cebf7252e78..00000000000 --- a/src/game/Calendar.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ diff --git a/src/game/Calendar.h b/src/game/Calendar.h deleted file mode 100644 index 94e4ff103f5..00000000000 --- a/src/game/Calendar.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MANGOS_CALENDAR_H -#define MANGOS_CALENDAR_H - -class Calendar -{ - -}; -#endif diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp deleted file mode 100644 index 9c69e3a91f6..00000000000 --- a/src/game/CalendarHandler.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "Common.h" -#include "Log.h" -#include "Player.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Opcodes.h" - -void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarComplain(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN"); - recv_data.hexlike(); -} - -void WorldSession::HandleCalendarGetNumPending(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING"); - recv_data.hexlike(); - - WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4); - data << uint32(0); // 0 - no pending invites, 1 - some pending invites - SendPacket(&data); -} diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 121a9b0d98d..aa884ddd2df 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -82,9 +82,7 @@ bool LoginQueryHolder::Initialize() res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid)); // in other case still be dummy query res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid)); return res; } @@ -234,16 +232,17 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) if (raceEntry->addon > Expansion()) { data << (uint8)CHAR_CREATE_EXPANSION; - sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_); + sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_); SendPacket( &data ); return; } // prevent character creating Expansion class without Expansion account - if (classEntry->addon > Expansion()) + // TODO: use possible addon field in ChrClassesEntry in next dbc version + if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT) { - data << (uint8)CHAR_CREATE_EXPANSION_CLASS; - sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)",Expansion(),GetAccountId(),classEntry->addon,class_); + data << (uint8)CHAR_CREATE_EXPANSION; + sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_); SendPacket( &data ); return; } @@ -310,77 +309,29 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } } - // speedup check for heroic class disabled case - uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); - if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) - { - data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; - SendPacket( &data ); - return; - } - - // speedup check for heroic class disabled case - uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING); - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; - SendPacket( &data ); - return; - } - bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER; uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS); bool have_same_race = false; - - // if 0 then allowed creating without any characters - bool have_req_level_for_heroic = (req_level_for_heroic==0); - - if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) + if(!AllowTwoSideAccounts || skipCinematics == 1) { - QueryResult *result2 = CharacterDatabase.PQuery("SELECT guid,race,class FROM characters WHERE account = '%u' %s", - GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1"); + QueryResult *result2 = CharacterDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1"); if(result2) { uint32 team_= Player::TeamForRace(race_); Field* field = result2->Fetch(); - uint8 acc_race = field[1].GetUInt32(); - - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) - { - uint8 acc_class = field[2].GetUInt32(); - if(acc_class == CLASS_DEATH_KNIGHT) - { - if(heroic_free_slots > 0) - --heroic_free_slots; - - if(heroic_free_slots==0) - { - data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; - SendPacket( &data ); - return; - } - } - - if(!have_req_level_for_heroic) - { - uint32 acc_guid = field[0].GetUInt32(); - uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid); - if(acc_level >= req_level_for_heroic) - have_req_level_for_heroic = true; - } - } + uint8 race = field[0].GetUInt32(); // need to check team only for first character // TODO: what to if account already has characters of both races? if (!AllowTwoSideAccounts) { - uint32 acc_team=0; - if(acc_race > 0) - acc_team = Player::TeamForRace(acc_race); + uint32 team=0; + if(race > 0) + team = Player::TeamForRace(race); - if(acc_team != team_) + if(team != team_) { data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION; SendPacket( &data ); @@ -389,55 +340,20 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } } - // search same race for cinematic or same class if need - // TODO: check if cinematic already shown? (already logged in?; cinematic field) - while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT) + if (skipCinematics == 1) { - if(!result2->NextRow()) - break; - - field = result2->Fetch(); - acc_race = field[1].GetUInt32(); - - if(!have_same_race) - have_same_race = race_ == acc_race; - - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) + // TODO: check if cinematic already shown? (already logged in?; cinematic field) + while (race_ != race && result2->NextRow()) { - uint8 acc_class = field[2].GetUInt32(); - if(acc_class == CLASS_DEATH_KNIGHT) - { - if(heroic_free_slots > 0) - --heroic_free_slots; - - if(heroic_free_slots==0) - { - data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; - SendPacket( &data ); - return; - } - } - - if(!have_req_level_for_heroic) - { - uint32 acc_guid = field[0].GetUInt32(); - uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid); - if(acc_level >= req_level_for_heroic) - have_req_level_for_heroic = true; - } + field = result2->Fetch(); + race = field[0].GetUInt32(); } + have_same_race = race_ == race; } delete result2; } } - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic) - { - data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; - SendPacket( &data ); - return; - } - // extract other data required for player creating uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId; recv_data >> gender >> skin >> face; @@ -594,11 +510,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) data << pCurrChar->GetOrientation(); SendPacket(&data); - data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 ); // changed in WotLK - data << uint32(time(NULL)); // unix time of something - data << uint8(1); - for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++) - data << uint32(GetAccountData(i)->Time); // also unix time + data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 ); + for(int i = 0; i < 32; i++) + data << uint32(0); SendPacket(&data); data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 @@ -695,20 +609,12 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { pCurrChar->setCinematic(1); - if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass())) + ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()); + if(rEntry) { - if(cEntry->CinematicSequence) - { - data.Initialize(SMSG_TRIGGER_CINEMATIC, 4); - data << uint32(cEntry->CinematicSequence); - SendPacket( &data ); - } - else if(ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) - { - data.Initialize(SMSG_TRIGGER_CINEMATIC, 4); - data << uint32(rEntry->CinematicSequence); - SendPacket( &data ); - } + data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); + data << uint32(rEntry->startmovie); + SendPacket( &data ); } } @@ -752,6 +658,22 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); + //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); + //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); + //if (pCurrChar->getRace() == RACE_NIGHTELF) + //{ + // pCurrChar->SetSpeed(MOVE_RUN, 1.5f*1.2f, true); + // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); + //} + //else + //{ + // pCurrChar->SetSpeed(MOVE_RUN, 1.5f, true); + // pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); + //} pCurrChar->SetMovement(MOVE_WATER_WALK); } @@ -981,11 +903,11 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ ) void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) { - CHECK_PACKET_SIZE(recv_data, 8+1); - uint64 guid; std::string newname; + CHECK_PACKET_SIZE(recv_data, 8+1); + recv_data >> guid; recv_data >> newname; @@ -993,15 +915,15 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(!normalizePlayerName(newname)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_NAME_NO_NAME); + data << (uint8)CHAR_NAME_NO_NAME; SendPacket( &data ); return; } - if(!ObjectMgr::IsValidName(newname, true)) + if(!ObjectMgr::IsValidName(newname,true)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_NAME_INVALID_CHARACTER); + data << (uint8)CHAR_NAME_INVALID_CHARACTER; SendPacket( &data ); return; } @@ -1010,7 +932,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_NAME_RESERVED); + data << (uint8)CHAR_NAME_RESERVED; SendPacket( &data ); return; } @@ -1039,7 +961,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin if (!result) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << uint8(CHAR_CREATE_ERROR); + data << (uint8)CHAR_CREATE_ERROR; session->SendPacket( &data ); return; } @@ -1053,11 +975,11 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow); CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow); - sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str()); + sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str()); - WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1)); - data << uint8(RESPONSE_SUCCESS); - data << uint64(guid); + WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1)); + data << (uint8)RESPONSE_SUCCESS; + data << guid; data << newname; session->SendPacket(&data); } @@ -1151,166 +1073,3 @@ void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data) data << uint64(guid); SendPacket(&data); } - -void WorldSession::HandleAlterAppearance( WorldPacket & recv_data ) -{ - sLog.outDebug("CMSG_ALTER_APPEARANCE"); - - CHECK_PACKET_SIZE(recv_data, 4+4+4); - - uint32 Hair, Color, FacialHair; - recv_data >> Hair >> Color >> FacialHair; - - BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair); - - if(!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender()) - return; - - BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair); - - if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender()) - return; - - uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id); - - // 0 - ok - // 1,3 - not enough money - // 2 - you have to seat on barber chair - if(_player->GetMoney() < Cost) - { - WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); - data << uint32(1); // no money - SendPacket(&data); - return; - } - else - { - WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); - data << uint32(0); // ok - SendPacket(&data); - } - - _player->SetMoney(_player->GetMoney() - Cost); // it isn't free - - _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id)); - _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color)); - _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id)); - - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); - - _player->SetStandState(0); // stand up -} - -void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data ) -{ - CHECK_PACKET_SIZE(recv_data, 4); - - uint32 slot; - recv_data >> slot; - - if(slot > 5) - { - sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot); - return; - } - - if(uint32 glyph = _player->GetGlyph(slot)) - { - if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) - { - _player->RemoveAurasDueToSpell(gp->SpellId); - _player->SetGlyph(slot, 0); - } - } -} - -void WorldSession::HandleCharCustomize(WorldPacket& recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8+1); - - uint64 guid; - std::string newname; - - recv_data >> guid; - recv_data >> newname; - - CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+1+1+1+1); - - uint8 gender, skin, face, hairStyle, hairColor, facialHair; - recv_data >> gender >> skin >> face >> hairStyle >> hairColor >> facialHair; - - QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); - if (!result) - { - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); - data << uint8(CHAR_CREATE_ERROR); - SendPacket( &data ); - return; - } - - Field *fields = result->Fetch(); - uint32 at_loginFlags = fields[0].GetUInt32(); - delete result; - - if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE)) - { - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); - data << uint8(CHAR_CREATE_ERROR); - SendPacket( &data ); - return; - } - - // prevent character rename to invalid name - if(!normalizePlayerName(newname)) - { - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); - data << uint8(CHAR_NAME_NO_NAME); - SendPacket( &data ); - return; - } - - if(!ObjectMgr::IsValidName(newname,true)) - { - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); - data << uint8(CHAR_NAME_INVALID_CHARACTER); - SendPacket( &data ); - return; - } - - // check name limitations - if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) - { - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); - data << uint8(CHAR_NAME_RESERVED); - SendPacket( &data ); - return; - } - - if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist - { - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); - data << uint8(CHAR_CREATE_NAME_IN_USE); - SendPacket( &data ); - return; - } - - CharacterDatabase.escape_string(newname); - Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); - CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid)); - CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); - - std::string IP_str = GetRemoteAddress(); - sLog.outChar("Account: %d (IP: %s), Character guid: %u Customized to: %s", GetAccountId(), IP_str.c_str(), GUID_LOPART(guid), newname.c_str()); - - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6); - data << uint8(RESPONSE_SUCCESS); - data << uint64(guid); - data << newname; - data << uint8(gender); - data << uint8(skin); - data << uint8(face); - data << uint8(hairStyle); - data << uint8(hairColor); - data << uint8(facialHair); - SendPacket(&data); -} diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 2cee426fded..203f8f6c624 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -190,7 +190,6 @@ ChatCommand * ChatHandler::getCommandTable() { "sellerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSellErrorCommand, "", NULL }, { "buyerr", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBuyErrorCommand, "", NULL }, { "sendopcode", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendOpcodeCommand, "", NULL }, - { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSpawnVehicle, "", NULL }, { "uws", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUpdateWorldStateCommand, "", NULL }, { "ps", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlaySound2Command, "", NULL }, { "scn", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSendChannelNotifyCommand, "", NULL }, @@ -264,7 +263,6 @@ ChatCommand * ChatHandler::getCommandTable() { "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL }, { "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL }, - { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL }, { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, { "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL }, { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, @@ -591,7 +589,6 @@ ChatCommand * ChatHandler::getCommandTable() { "sendmail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL }, { "sendmoney", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL }, { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL }, - { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCustomizeCommand, "", NULL }, { "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL }, { "mute", SEC_GAMEMASTER, true, &ChatHandler::HandleMuteCommand, "", NULL }, { "unmute", SEC_GAMEMASTER, true, &ChatHandler::HandleUnmuteCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index b324d2d5f5e..16f764366ac 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -233,7 +233,6 @@ class ChatHandler bool HandleReloadLootTemplatesFishingCommand(const char* args); bool HandleReloadLootTemplatesGameobjectCommand(const char* args); bool HandleReloadLootTemplatesItemCommand(const char* args); - bool HandleReloadLootTemplatesMillingCommand(const char* args); bool HandleReloadLootTemplatesPickpocketingCommand(const char* args); bool HandleReloadLootTemplatesProspectingCommand(const char* args); bool HandleReloadLootTemplatesReferenceCommand(const char* args); @@ -435,7 +434,6 @@ class ChatHandler bool HandleSendChannelNotifyCommand(const char* args); bool HandleSendChatMsgCommand(const char* args); bool HandleRenameCommand(const char * args); - bool HandleCustomizeCommand(const char * args); bool HandleLoadPDumpCommand(const char *args); bool HandleWritePDumpCommand(const char *args); bool HandleCastCommand(const char *args); @@ -469,7 +467,6 @@ class ChatHandler bool HandleUnPossessCommand(const char* args); bool HandleBindSightCommand(const char* args); bool HandleUnbindSightCommand(const char* args); - bool HandleSpawnVehicle(const char * args); Player* getSelectedPlayer(); Creature* getSelectedCreature(); diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp index 77b553f6856..989ccd61151 100644 --- a/src/game/Corpse.cpp +++ b/src/game/Corpse.cpp @@ -36,7 +36,7 @@ Corpse::Corpse(CorpseType type) : WorldObject() m_objectType |= TYPEMASK_CORPSE; m_objectTypeId = TYPEID_CORPSE; // 2.3.2 - 0x58 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); m_valuesCount = CORPSE_END; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 5a3e9512bd0..c0065212207 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -145,12 +145,11 @@ Unit(), i_AI(NULL), i_AI_possessed(NULL), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), m_lootMoney(0), m_lootRecipient(0), m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), -m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_isVehicle(false), m_reactState(REACT_AGGRESSIVE), -m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), +m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_reactState(REACT_AGGRESSIVE), +m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), m_AlreadyCallAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0), m_formationID(0) { - m_regenTimer = 200; m_valuesCount = UNIT_END; for(int i =0; i<4; ++i) @@ -316,6 +315,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) // creatures always have melee weapon ready if any SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_AURAS ); SelectLevel(GetCreatureInfo()); if (team == HORDE) @@ -765,11 +765,8 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const case BATTLEGROUND_NA: case BATTLEGROUND_BE: case BATTLEGROUND_AA: - case BATTLEGROUND_RL: - case BATTLEGROUND_SA: - case BATTLEGROUND_DS: - case BATTLEGROUND_RV: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break; - default: break; + case BATTLEGROUND_RL: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break; + break; } return false; } @@ -1462,7 +1459,11 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force) if (force) { for (uint8 i = 0; i < 3; i++) - SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0); + { + SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, 0); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0); + } m_equipmentId = 0; } return; @@ -1474,7 +1475,11 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force) m_equipmentId = equip_entry; for (uint8 i = 0; i < 3; i++) - SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->equipentry[i]); + { + SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, einfo->equipmodel[i]); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), einfo->equipinfo[i]); + SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, einfo->equipslot[i]); + } } bool Creature::hasQuest(uint32 quest_id) const diff --git a/src/game/Creature.h b/src/game/Creature.h index ff512fb5da0..1ae41b86776 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -244,7 +244,9 @@ struct NpcOptionLocale struct EquipmentInfo { uint32 entry; - uint32 equipentry[3]; + uint32 equipmodel[3]; + uint32 equipinfo[3]; + uint32 equipslot[3]; }; // from `creature` table @@ -421,7 +423,6 @@ class TRINITY_DLL_SPEC Creature : public Unit uint32 GetEquipmentId() const { return m_equipmentId; } bool isPet() const { return m_isPet; } - bool isVehicle() const { return m_isVehicle; } void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; } bool isTotem() const { return m_isTotem; } bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; } @@ -656,11 +657,11 @@ class TRINITY_DLL_SPEC Creature : public Unit uint8 m_emoteState; bool m_isPet; // set only in Pet::Pet - bool m_isVehicle; // set only in Vehicle::Vehicle bool m_isTotem; // set only in Totem::Totem ReactStates m_reactState; // for AI, not charmInfo void RegenerateMana(); void RegenerateHealth(); + uint32 m_regenTimer; MovementGeneratorType m_defaultMovementType; Cell m_currentCell; // store current cell where creature listed uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 0dc69829728..d7badd57892 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -38,7 +38,7 @@ DynamicObject::DynamicObject() : WorldObject() m_objectType |= TYPEMASK_DYNAMICOBJECT; m_objectTypeId = TYPEID_DYNAMICOBJECT; // 2.3.2 - 0x58 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); m_valuesCount = DYNAMICOBJECT_END; } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 53a7d36aef4..28c39ee5bbe 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -46,7 +46,7 @@ GameObject::GameObject() : WorldObject() m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; // 2.3.2 - 0x58 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); m_valuesCount = GAMEOBJECT_END; m_respawnTime = 0; @@ -127,33 +127,17 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float SetFloatValue(GAMEOBJECT_POS_Z, z); SetFloatValue(GAMEOBJECT_FACING, ang); //this is not facing angle - int64 rotation = 0; - - float f_rot1 = sin(ang / 2.0f); - int64 i_rot1 = f_rot1 / atan(pow(2.0f, -20.0f)); - rotation |= (i_rot1 << 43 >> 43) & 0x00000000001FFFFF; - - //float f_rot2 = sin(0.0f / 2.0f); - //int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f)); - //rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000; - - //float f_rot3 = sin(0.0f / 2.0f); - //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f)); - //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000; - - SetUInt64Value(GAMEOBJECT_ROTATION, rotation); - - SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0); - SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1); - SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2); - SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3); + SetFloatValue (GAMEOBJECT_ROTATION, rotation0); + SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1); + SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2); + SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3); SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); - SetEntry(goinfo->id); + SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id); SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); @@ -162,6 +146,8 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float SetGoAnimProgress(animprogress); + SetUInt32Value (GAMEOBJECT_ARTKIT, ArtKit); + // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22) if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER) m_charges = goinfo->spellcaster.charges; @@ -278,7 +264,7 @@ void GameObject::Update(uint32 /*p_time*/) return; } // respawn timer - GetMap()->Add(this); + MapManager::Instance().GetMap(GetMapId(), this)->Add(this); break; } } @@ -428,7 +414,7 @@ void GameObject::Update(uint32 /*p_time*/) //burning flags in some battlegrounds, if you find better condition, just add it if (GetGoAnimProgress() > 0) { - SendObjectDeSpawnAnim(GetGUID()); + SendObjectDeSpawnAnim(this->GetGUID()); //reset flags SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); } @@ -465,7 +451,7 @@ void GameObject::Refresh() return; if(isSpawned()) - GetMap()->Add(this); + MapManager::Instance().GetMap(GetMapId(), this)->Add(this); } void GameObject::AddUniqueUse(Player* player) @@ -518,7 +504,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask) if (!goI) return; - + if (!m_DBTableGuid) m_DBTableGuid = GetGUIDLow(); // update in loaded data (changing data only in this place) @@ -531,33 +517,34 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask) data.posY = GetFloatValue(GAMEOBJECT_POS_Y); data.posZ = GetFloatValue(GAMEOBJECT_POS_Z); data.orientation = GetFloatValue(GAMEOBJECT_FACING); - data.rotation0 = GetFloatValue(GAMEOBJECT_PARENTROTATION+0); - data.rotation1 = GetFloatValue(GAMEOBJECT_PARENTROTATION+1); - data.rotation2 = GetFloatValue(GAMEOBJECT_PARENTROTATION+2); - data.rotation3 = GetFloatValue(GAMEOBJECT_PARENTROTATION+3); + data.rotation0 = GetFloatValue(GAMEOBJECT_ROTATION+0); + data.rotation1 = GetFloatValue(GAMEOBJECT_ROTATION+1); + data.rotation2 = GetFloatValue(GAMEOBJECT_ROTATION+2); + data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3); data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime; data.animprogress = GetGoAnimProgress(); data.go_state = GetGoState(); data.spawnMask = spawnMask; + data.ArtKit = GetUInt32Value (GAMEOBJECT_ARTKIT); // updated in DB std::ostringstream ss; ss << "INSERT INTO gameobject VALUES ( " << m_DBTableGuid << ", " - << GetEntry() << ", " + << GetUInt32Value (OBJECT_FIELD_ENTRY) << ", " << mapid << ", " << (uint32)spawnMask << ", " << GetFloatValue(GAMEOBJECT_POS_X) << ", " << GetFloatValue(GAMEOBJECT_POS_Y) << ", " << GetFloatValue(GAMEOBJECT_POS_Z) << ", " << GetFloatValue(GAMEOBJECT_FACING) << ", " - << GetFloatValue(GAMEOBJECT_PARENTROTATION) << ", " - << GetFloatValue(GAMEOBJECT_PARENTROTATION+1) << ", " - << GetFloatValue(GAMEOBJECT_PARENTROTATION+2) << ", " - << GetFloatValue(GAMEOBJECT_PARENTROTATION+3) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION+1) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION+2) << ", " + << GetFloatValue(GAMEOBJECT_ROTATION+3) << ", " << m_respawnDelayTime << ", " - << (uint32)GetGoAnimProgress() << ", " - << (uint32)GetGoState() << ")"; + << GetGoAnimProgress() << ", " + << GetGoState() << ")"; WorldDatabase.BeginTransaction(); WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); @@ -576,7 +563,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) } uint32 entry = data->id; - //uint32 map_id = data->mapid; // already used before call + uint32 map_id = data->mapid; float x = data->posX; float y = data->posY; float z = data->posZ; @@ -589,11 +576,12 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) uint32 animprogress = data->animprogress; uint32 go_state = data->go_state; + uint32 ArtKit = data->ArtKit; m_DBTableGuid = guid; if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); - if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) ) + if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) ) return false; switch(GetGOInfo()->type) @@ -858,6 +846,14 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore) } +void GameObject::SetGoArtKit(uint32 kit) +{ + SetUInt32Value(GAMEOBJECT_ARTKIT, kit); + GameObjectData *data = const_cast(objmgr.GetGOData(m_DBTableGuid)); + if(data) + data->ArtKit = kit; +} + void GameObject::SwitchDoorOrButton(bool activate) { if(activate) @@ -1213,7 +1209,7 @@ void GameObject::Use(Unit* user) Player* player = (Player*)user; - if( player->isAllowUseBattleGroundObject() ) + if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); @@ -1251,26 +1247,6 @@ void GameObject::Use(Unit* user) } break; } - case GAMEOBJECT_TYPE_BARBER_CHAIR: //32 - { - GameObjectInfo const* info = GetGOInfo(); - if(!info) - return; - - if(user->GetTypeId()!=TYPEID_PLAYER) - return; - - Player* player = (Player*)user; - - // fallback, will always work - player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); - - WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0); - player->GetSession()->SendPacket(&data); - - player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight); - return; - } default: sLog.outDebug("Unknown Object Type %u", GetGoType()); break; diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 9a570eb54da..afeaba98cc9 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -336,12 +336,12 @@ struct GameObjectInfo uint32 mapID; //0 uint32 difficulty; //1 } dungeonDifficulty; - //32 GAMEOBJECT_TYPE_BARBER_CHAIR + //32 GAMEOBJECT_TYPE_DO_NOT_USE_YET struct { - uint32 chairheight; //0 - uint32 heightOffset; //1 - } barberChair; + uint32 mapID; //0 + uint32 difficulty; //1 + } doNotUseYet; //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING struct { @@ -350,13 +350,6 @@ struct GameObjectInfo uint32 state1Name; //2 uint32 state2Name; //3 } destructibleBuilding; - //34 GAMEOBJECT_TYPE_TRAPDOOR - struct - { - uint32 whenToPause; // 0 - uint32 startOpen; // 1 - uint32 autoClose; // 2 - } trapDoor; // not use for specific field access (only for output with loop by all filed), also this determinate max union size struct // GAMEOBJECT_TYPE_SPELLCASTER @@ -511,14 +504,14 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject void SetSpellId(uint32 id) { m_spellId = id;} uint32 GetSpellId() const { return m_spellId;} void getFishLoot(Loot *loot); - GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); } - void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); } - uint8 GetGoState() const { return GetByteValue(GAMEOBJECT_BYTES_1, 0); } - void SetGoState(uint8 state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); } - uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); } - void SetGoArtKit(uint8 artkit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, artkit); } - uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); } - void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); } + GameobjectTypes GetGoType() const { return GameobjectTypes(GetUInt32Value(GAMEOBJECT_TYPE_ID)); } + void SetGoType(GameobjectTypes type) { SetUInt32Value(GAMEOBJECT_TYPE_ID, type); } + uint32 GetGoState() const { return GetUInt32Value(GAMEOBJECT_STATE); } + void SetGoState(uint32 state) { SetUInt32Value(GAMEOBJECT_STATE, state); } + uint32 GetGoArtKit() const { return GetUInt32Value(GAMEOBJECT_ARTKIT); } + void SetGoArtKit(uint32 artkit); + uint32 GetGoAnimProgress() const { return GetUInt32Value(GAMEOBJECT_ANIMPROGRESS); } + void SetGoAnimProgress(uint32 animprogress) { SetUInt32Value(GAMEOBJECT_ANIMPROGRESS, animprogress); } void Use(Unit* user); diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 90aa7304c90..85414fa3372 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -417,14 +417,10 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID } data << uint64(npcGUID); - data << uint64(0); // wotlk, something todo with quest sharing? data << uint32(pQuest->GetQuestId()); - data << Title; - data << Details; - data << Objectives; + data << Title << Details << Objectives; data << uint32(ActivateAccept); data << uint32(pQuest->GetSuggestedPlayers()); - data << uint8(0); // new wotlk if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) { @@ -470,7 +466,6 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) data << uint32(pQuest->GetRewSpellCast()); // casted spell data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) - data << uint32(pQuest->GetBonusTalents()); // bonus talents data << uint32(QUEST_EMOTE_COUNT); for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++) @@ -547,8 +542,6 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) data << uint32(pQuest->GetSrcItemId()); data << uint32(pQuest->GetFlags() & 0xFFFF); data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) - data << uint32(pQuest->GetPlayersSlain()); // players slain - data << uint32(pQuest->GetBonusTalents()); // bonus talents int iI; @@ -597,14 +590,13 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) data << uint32(pQuest->ReqCreatureOrGOCount[iI]); data << uint32(pQuest->ReqItemId[iI]); data << uint32(pQuest->ReqItemCount[iI]); - data << uint32(0); // added in WotLK, dunno if offset if correct } for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++) data << ObjectiveText[iI]; pSession->SendPacket( &data ); - sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId() ); + sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() ); } void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext ) @@ -686,10 +678,9 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, data << uint32(0x08); // unused by client? data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) data << uint32(pQuest->GetRewSpellCast()); // casted spell - data << uint32(0); // unknown - data << uint32(pQuest->GetBonusTalents()); // bonus talents + data << uint32(0x00); // unk, NOT honor pSession->SendPacket( &data ); - sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() ); + sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); } void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel ) diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index b69e185c171..0c952f69649 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -140,7 +140,7 @@ VisibleNotifier::Notify() // send data at target visibility change (adding to client) for(std::set::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr) if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT)) - i_player.SendAurasForTarget((Unit*)(*vItr)); + i_player.SendAuraDurationsForTarget((Unit*)(*vItr)); } void diff --git a/src/game/Group.h b/src/game/Group.h index 5edc99f8c0c..8417a145268 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -66,25 +66,24 @@ enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags - GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32 - GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32 + GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint16 + GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint16 GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // uint16 GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // uint16 GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 GROUP_UPDATE_FLAG_POSITION = 0x00000100, // uint16, uint16 - GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint32 spellid + uint8 unk + GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint16 spellid + uint8 unk GROUP_UPDATE_FLAG_PET_GUID = 0x00000400, // uint64 pet guid GROUP_UPDATE_FLAG_PET_NAME = 0x00000800, // pet name, NULL terminated string GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00001000, // uint16, model id - GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint32 pet cur health - GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint32 pet max health + GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint16 pet cur health + GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint16 pet max health GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00008000, // uint8 pet power type GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power - GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras... - GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint32 vehicle_seat_id (index from VehicleSeat.dbc) + GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint16 spellid + uint8 unk, pet auras... GROUP_UPDATE_PET = 0x0007FC00, // all pet flags GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags }; diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index 7a4f0a2720c..3890a9f77a6 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -688,10 +688,10 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke } if (mask & GROUP_UPDATE_FLAG_CUR_HP) - *data << (uint32) player->GetHealth(); + *data << (uint16) player->GetHealth(); if (mask & GROUP_UPDATE_FLAG_MAX_HP) - *data << (uint32) player->GetMaxHealth(); + *data << (uint16) player->GetMaxHealth(); Powers powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) @@ -720,7 +720,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke { if(auramask & (uint64(1) << i)) { - *data << uint32(player->GetVisibleAura(i)); + *data << uint16(player->GetUInt32Value(UNIT_FIELD_AURA + i)); *data << uint8(1); } } @@ -754,17 +754,17 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if(pet) - *data << (uint32) pet->GetHealth(); + *data << (uint16) pet->GetHealth(); else - *data << (uint32) 0; + *data << (uint16) 0; } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if(pet) - *data << (uint32) pet->GetMaxHealth(); + *data << (uint16) pet->GetMaxHealth(); else - *data << (uint32) 0; + *data << (uint16) 0; } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) @@ -801,7 +801,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke { if(auramask & (uint64(1) << i)) { - *data << uint32(pet->GetVisibleAura(i)); + *data << uint16(pet->GetUInt32Value(UNIT_FIELD_AURA + i)); *data << uint8(1); } } @@ -824,7 +824,6 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); - data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; @@ -835,7 +834,6 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); - data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF @@ -845,8 +843,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status - data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP - data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP + data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP + data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER @@ -860,11 +858,11 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) data << (uint64) auramask; // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { - if(uint32 aura = player->GetVisibleAura(i)) + if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) { auramask |= (uint64(1) << i); - data << (uint32) aura; - data << (uint8) 1; + data << uint16(aura); + data << uint8(1); } } data.put(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS @@ -875,8 +873,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID - data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP - data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP + data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP + data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER @@ -886,10 +884,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) data << (uint64) petauramask; // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { - if(uint32 petaura = pet->GetVisibleAura(i)) + if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) { petauramask |= (uint64(1) << i); - data << (uint32) petaura; + data << (uint16) petaura; data << (uint8) 1; } } diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 55ad071a74b..897110afe55 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -785,7 +785,6 @@ void Guild::Query(WorldSession *session) data << uint32(BorderStyle); data << uint32(BorderColor); data << uint32(BackgroundColor); - data << uint32(0); // something new in WotLK session->SendPacket( &data ); sLog.outDebug( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" ); @@ -1603,21 +1602,7 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) { data << uint8((*itr)->LogEntry); data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); - if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || - (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || - (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || - (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 || - (*itr)->LogEntry == GUILD_BANK_LOG_UNK2) - { - data << uint32((*itr)->ItemOrMoney); - } - else - { - data << uint32((*itr)->ItemOrMoney); - data << uint32((*itr)->ItemStackCount); - if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) - data << uint8((*itr)->DestTabId); // moved tab - } + data << uint32((*itr)->ItemOrMoney); data << uint32(time(NULL)-(*itr)->TimeStamp); } session->SendPacket(&data); @@ -1633,21 +1618,10 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId) { data << uint8((*itr)->LogEntry); data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); - if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY || - (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || - (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || - (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 || - (*itr)->LogEntry == GUILD_BANK_LOG_UNK2) - { - data << uint32((*itr)->ItemOrMoney); - } - else - { - data << uint32((*itr)->ItemOrMoney); - data << uint32((*itr)->ItemStackCount); - if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) - data << uint8((*itr)->DestTabId); // moved tab - } + data << uint32((*itr)->ItemOrMoney); + data << uint8((*itr)->ItemStackCount); + if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) + data << uint8((*itr)->DestTabId); // moved tab data << uint32(time(NULL)-(*itr)->TimeStamp); } session->SendPacket(&data); @@ -1729,7 +1703,7 @@ void Guild::AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *t // SuffixFactor +4 data << (uint32) pItem->GetItemSuffixFactor(); // +12 // ITEM_FIELD_STACK_COUNT - data << uint32(pItem->GetCount()); + data << uint8(pItem->GetCount()); data << uint32(0); // +16 // Unknown value data << uint8(0); // unknown 2.4.2 if (uint32 Enchant0 = pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)) diff --git a/src/game/Guild.h b/src/game/Guild.h index f51ba5a6d27..683ff980e3a 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -56,8 +56,7 @@ enum GuildRankRights GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold - GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk - GR_RIGHT_ALL = 0x001FF1FF + GR_RIGHT_ALL = 0x000FF1FF }; enum Typecommand @@ -157,8 +156,6 @@ enum GuildBankLogEntries GUILD_BANK_LOG_WITHDRAW_MONEY = 5, GUILD_BANK_LOG_REPAIR_MONEY = 6, GUILD_BANK_LOG_MOVE_ITEM2 = 7, - GUILD_BANK_LOG_UNK1 = 8, - GUILD_BANK_LOG_UNK2 = 9, }; enum GuildEventLogEntryTypes diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 8b4b124669e..0c264a76d8b 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -206,10 +206,6 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP)) return false; return true; - case ITEM_SUBCLASS_INSCRIPTION_CONTAINER: - if(!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP)) - return false; - return true; default: return false; } @@ -454,7 +450,7 @@ uint32 Item::GetSkill() const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] = { - 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0,0 + 0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0 }; ItemPrototype const* proto = GetProto(); @@ -769,9 +765,9 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges)) return; - SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); - SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); - SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); SetState(ITEM_CHANGED); } @@ -780,7 +776,7 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration) if(GetEnchantmentDuration(slot) == duration) return; - SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); SetState(ITEM_CHANGED); } @@ -789,7 +785,7 @@ void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges) if(GetEnchantmentCharges(slot) == charges) return; - SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); SetState(ITEM_CHANGED); } @@ -799,7 +795,7 @@ void Item::ClearEnchantment(EnchantmentSlot slot) return; for(uint8 x = 0; x < 3; ++x) - SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + x, 0); + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0); SetState(ITEM_CHANGED); } diff --git a/src/game/Item.h b/src/game/Item.h index 4be1d42a32a..72c09b0c1da 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -148,30 +148,29 @@ enum SellFailure // -1 from client enchantment slot number enum EnchantmentSlot { - PERM_ENCHANTMENT_SLOT = 0, - TEMP_ENCHANTMENT_SLOT = 1, - SOCK_ENCHANTMENT_SLOT = 2, - SOCK_ENCHANTMENT_SLOT_2 = 3, - SOCK_ENCHANTMENT_SLOT_3 = 4, - BONUS_ENCHANTMENT_SLOT = 5, - WOTLK_ENCHANTMENT_SLOT = 6, - MAX_INSPECTED_ENCHANTMENT_SLOT = 7, + PERM_ENCHANTMENT_SLOT = 0, + TEMP_ENCHANTMENT_SLOT = 1, + SOCK_ENCHANTMENT_SLOT = 2, + SOCK_ENCHANTMENT_SLOT_2 = 3, + SOCK_ENCHANTMENT_SLOT_3 = 4, + BONUS_ENCHANTMENT_SLOT = 5, + MAX_INSPECTED_ENCHANTMENT_SLOT = 6, - PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix - PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix - PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty - PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty - PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty - MAX_ENCHANTMENT_SLOT = 12 + PROP_ENCHANTMENT_SLOT_0 = 6, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_1 = 7, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_2 = 8, // used with RandomSuffix and RandomProperty + PROP_ENCHANTMENT_SLOT_3 = 9, // used with RandomProperty + PROP_ENCHANTMENT_SLOT_4 = 10, // used with RandomProperty + MAX_ENCHANTMENT_SLOT = 11 }; -#define MAX_VISIBLE_ITEM_OFFSET 18 // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1)) +#define MAX_VISIBLE_ITEM_OFFSET 16 // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1)) enum EnchantmentOffset { ENCHANTMENT_ID_OFFSET = 0, ENCHANTMENT_DURATION_OFFSET = 1, - ENCHANTMENT_CHARGES_OFFSET = 2 // now here not only charges, but something new in wotlk + ENCHANTMENT_CHARGES_OFFSET = 2 }; #define MAX_ENCHANTMENT_OFFSET 3 @@ -212,7 +211,6 @@ class TRINITY_DLL_SPEC Item : public Object void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); } bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); } - bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); } bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; } bool IsBoundByEnchant() const; virtual void SaveToDB(); @@ -258,9 +256,9 @@ class TRINITY_DLL_SPEC Item : public Object void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration); void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges); void ClearEnchantment(EnchantmentSlot slot); - uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);} - uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);} - uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);} + uint32 GetEnchantmentId(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);} + uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);} + uint32 GetEnchantmentCharges(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);} void SendTimeUpdate(Player* owner); void UpdateDuration(Player* owner, uint32 diff); diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index 3437495bc48..085c9553a30 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -324,7 +324,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->ItemId; data << pProto->Class; data << pProto->SubClass; - data << pProto->Unk0; // new 2.0.3, not exist in wdb cache? + data << uint32(-1); // new 2.0.3, not exist in wdb cache? data << Name; data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); @@ -349,14 +349,11 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->MaxCount; data << pProto->Stackable; data << pProto->ContainerSlots; - data << pProto->StatsCount; // item stats count - for(int i = 0; i < pProto->StatsCount; i++) + for(int i = 0; i < 10; i++) { data << pProto->ItemStat[i].ItemStatType; data << pProto->ItemStat[i].ItemStatValue; } - data << pProto->ScalingStatDistribution; // scaling stats distribution - data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column for(int i = 0; i < 5; i++) { data << pProto->Damage[i].DamageMin; @@ -440,8 +437,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->GemProperties; data << pProto->RequiredDisenchantSkill; data << pProto->ArmorDamageModifier; - data << pProto->Duration; // added in 2.4.2.8209, duration (seconds) - data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory + data << uint32(0); // added in 2.4.2.8209, duration (seconds) SendPacket( &data ); } else @@ -849,7 +845,6 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/) if (_player->GetMoney() < price) return; - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot); _player->SetByteValue(PLAYER_BYTES_2, 2, slot); _player->ModifyMoney(-int32(price)); } diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index 60c92ad2d70..1ca412d246a 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -57,18 +57,10 @@ enum ItemModType ITEM_MOD_CRIT_TAKEN_RATING = 34, ITEM_MOD_RESILIENCE_RATING = 35, ITEM_MOD_HASTE_RATING = 36, - ITEM_MOD_EXPERTISE_RATING = 37, - ITEM_MOD_ATTACK_POWER = 38, - ITEM_MOD_RANGED_ATTACK_POWER = 39, - ITEM_MOD_FERAL_ATTACK_POWER = 40, - ITEM_MOD_SPELL_HEALING_DONE = 41, - ITEM_MOD_SPELL_DAMAGE_DONE = 42, - ITEM_MOD_MANA_REGENERATION = 43, - ITEM_MOD_ARMOR_PENETRATION_RATING = 44, - ITEM_MOD_SPELL_POWER = 45 + ITEM_MOD_EXPERTISE_RATING = 37 }; -#define MAX_ITEM_MOD 46 +#define MAX_ITEM_MOD 38 enum ItemSpelltriggerType { @@ -193,11 +185,10 @@ enum ItemClass ITEM_CLASS_QUEST = 12, ITEM_CLASS_KEY = 13, ITEM_CLASS_PERMANENT = 14, - ITEM_CLASS_MISC = 15, - ITEM_CLASS_GLYPH = 16 + ITEM_CLASS_JUNK = 15 }; -#define MAX_ITEM_CLASS 17 +#define MAX_ITEM_CLASS 16 enum ItemSubclassConsumable { @@ -223,11 +214,10 @@ enum ItemSubclassContainer ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4, ITEM_SUBCLASS_GEM_CONTAINER = 5, ITEM_SUBCLASS_MINING_CONTAINER = 6, - ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7, - ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8 + ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7 }; -#define MAX_ITEM_SUBCLASS_CONTAINER 9 +#define MAX_ITEM_SUBCLASS_CONTAINER 8 enum ItemSubclassWeapon { @@ -282,11 +272,10 @@ enum ItemSubclassArmor ITEM_SUBCLASS_ARMOR_SHIELD = 6, ITEM_SUBCLASS_ARMOR_LIBRAM = 7, ITEM_SUBCLASS_ARMOR_IDOL = 8, - ITEM_SUBCLASS_ARMOR_TOTEM = 9, - ITEM_SUBCLASS_ARMOR_SIGIL = 10 + ITEM_SUBCLASS_ARMOR_TOTEM = 9 }; -#define MAX_ITEM_SUBCLASS_ARMOR 11 +#define MAX_ITEM_SUBCLASS_ARMOR 10 enum ItemSubclassReagent { @@ -321,12 +310,10 @@ enum ItemSubclassTradeGoods ITEM_SUBCLASS_ELEMENTAL = 10, ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11, ITEM_SUBCLASS_ENCHANTING = 12, - ITEM_SUBCLASS_MATERIAL = 13, - ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14, - ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15 + ITEM_SUBCLASS_MATERIAL = 13 // Added in 2.4.2 }; -#define MAX_ITEM_SUBCLASS_TRADE_GOODS 16 +#define MAX_ITEM_SUBCLASS_TRADE_GOODS 14 enum ItemSubclassGeneric { @@ -436,8 +423,7 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = MAX_ITEM_SUBCLASS_QUEST, MAX_ITEM_SUBCLASS_KEY, MAX_ITEM_SUBCLASS_PERMANENT, - MAX_ITEM_SUBCLASS_JUNK, - MAX_ITEM_SUBCLASS_GLYPH + MAX_ITEM_SUBCLASS_JUNK }; inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass) @@ -514,10 +500,7 @@ struct ItemPrototype uint32 MaxCount; uint32 Stackable; uint32 ContainerSlots; - uint32 StatsCount; _ItemStat ItemStat[10]; - uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc - uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc _Damage Damage[5]; uint32 Armor; uint32 HolyRes; @@ -553,13 +536,12 @@ struct ItemPrototype uint32 GemProperties; // id from GemProperties.dbc uint32 RequiredDisenchantSkill; float ArmorDamageModifier; - int32 Duration; // negative = realtime, positive = ingame time - uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc uint32 ScriptId; uint32 DisenchantID; uint32 FoodType; uint32 MinMoneyLoot; uint32 MaxMoneyLoot; + int32 Duration; // negative = realtime, positive = ingame time // helpers bool CanChangeEquipStateInCombat() const @@ -581,46 +563,6 @@ struct ItemPrototype return false; } - - uint32 GetScalingStatValuesColumn() const - { - if(ScalingStatValue & 0x00000001) // stat mod - return 0; - if(ScalingStatValue & 0x00000002) // stat mod - return 1; - if(ScalingStatValue & 0x00000004) // stat mod - return 2; - if(ScalingStatValue & 0x00000008) // stat mod - return 3; - if(ScalingStatValue & 0x00000010) // stat mod - return 4; - if(ScalingStatValue & 0x00000020) // armor mod - return 5; - if(ScalingStatValue & 0x00000040) // armor mod - return 6; - if(ScalingStatValue & 0x00000080) // armor mod - return 7; - if(ScalingStatValue & 0x00000100) // armor mod - return 8; - if(ScalingStatValue & 0x00000200) // damage mod - return 9; - if(ScalingStatValue & 0x00000400) // damage mod - return 10; - if(ScalingStatValue & 0x00000800) // damage mod - return 11; - if(ScalingStatValue & 0x00001000) // damage mod - return 12; - if(ScalingStatValue & 0x00002000) // damage mod - return 13; - if(ScalingStatValue & 0x00004000) // damage mod - return 14; - if(ScalingStatValue & 0x00008000) // spell power - return 15; - if(ScalingStatValue & 0x00020000) // feral AP - return 16; - - return 0; - } }; struct ItemLocale diff --git a/src/game/Language.h b/src/game/Language.h index 68106edf8db..be6401596ea 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -328,8 +328,6 @@ enum TrinityStrings LANG_CREATURE_NOT_FOLLOW_YOU_NOW = 342, LANG_CREATURE_NON_TAMEABLE = 343, LANG_YOU_ALREADY_HAVE_PET = 344, - LANG_CUSTOMIZE_PLAYER = 345, - LANG_CUSTOMIZE_PLAYER_GUID = 346, // Room for more level 2 345-399 not used // level 3 chat diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index db5a0b5c660..2b75b9324c1 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -950,7 +950,7 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args) else unit = getSelectedCreature(); - if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle()) + if(!unit || unit->isPet() || unit->isTotem()) { SendSysMessage(LANG_SELECT_CREATURE); SetSentErrorMessage(true); @@ -1063,8 +1063,8 @@ bool ChatHandler::HandleTurnObjectCommand(const char* args) obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o); obj->SetFloatValue(GAMEOBJECT_FACING, o); - obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rot2); - obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rot3); + obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2); + obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3); map->Add(obj); @@ -3213,59 +3213,6 @@ bool ChatHandler::HandleRenameCommand(const char* args) return true; } -// customize characters -bool ChatHandler::HandleCustomizeCommand(const char* args) -{ - Player* target = NULL; - uint64 targetGUID = 0; - std::string oldname; - - char* px = strtok((char*)args, " "); - - if(px) - { - oldname = px; - - if(!normalizePlayerName(oldname)) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - target = objmgr.GetPlayer(oldname.c_str()); - - if (!target) - targetGUID = objmgr.GetPlayerGUIDByName(oldname); - } - - if(!target && !targetGUID) - { - target = getSelectedPlayer(); - } - - if(!target && !targetGUID) - { - SendSysMessage(LANG_PLAYER_NOT_FOUND); - SetSentErrorMessage(true); - return false; - } - - if(target) - { - PSendSysMessage(LANG_CUSTOMIZE_PLAYER, target->GetName()); - target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow()); - } - else - { - PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID)); - CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); - } - - return true; -} - //spawn go bool ChatHandler::HandleGameObjectCommand(const char* args) { @@ -3893,36 +3840,6 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/) return true; } -bool ChatHandler::HandleWaterwalkCommand(const char* args) -{ - if(!*args) - return false; - - Player *player = getSelectedPlayer(); - - if(!player) - { - PSendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - - if (strncmp(args, "on", 3) == 0) - player->SetMovement(MOVE_WATER_WALK); // ON - else if (strncmp(args, "off", 4) == 0) - player->SetMovement(MOVE_LAND_WALK); // OFF - else - { - SendSysMessage(LANG_USE_BOL); - return false; - } - - PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName()); - if(needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName()); - return true; -} - bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/) { Player *player = m_session->GetPlayer(); @@ -3979,72 +3896,6 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) return true; } -bool ChatHandler::HandleNpcTameCommand(const char* /*args*/) -{ - Creature *creatureTarget = getSelectedCreature (); - if (!creatureTarget || creatureTarget->isPet ()) - { - PSendSysMessage (LANG_SELECT_CREATURE); - SetSentErrorMessage (true); - return false; - } - - Player *player = m_session->GetPlayer (); - - if(player->GetPetGUID ()) - { - SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); - SetSentErrorMessage (true); - return false; - } - - CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); - - if (!cInfo->isTameable ()) - { - PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); - SetSentErrorMessage (true); - return false; - } - - // Everything looks OK, create new pet - Pet* pet = player->CreateTamedPetFrom (creatureTarget); - if (!pet) - { - PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); - SetSentErrorMessage (true); - return false; - } - - // place pet before player - float x,y,z; - player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); - pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); - - // set pet to defensive mode by default (some classes can't control controlled pets in fact). - pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE); - - // calculate proper level - uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); - - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); - - // add to world - pet->GetMap()->Add((Creature*)pet); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); - - // caster have pet now - player->SetPet(pet); - - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - player->PetSpellInitialize(); - - return true; -} - bool ChatHandler::HandleCreatePetCommand(const char* args) { Player *player = m_session->GetPlayer(); @@ -4204,7 +4055,7 @@ bool ChatHandler::HandlePetTpCommand(const char *args) uint32 tp = atol(args); - //pet->SetTP(tp); + pet->SetTP(tp); PSendSysMessage("Pet's tp changed to %u", tp); return true; @@ -4243,4 +4094,4 @@ bool ChatHandler::HandleActivateObjectCommand(const char *args) PSendSysMessage("Object activated!"); return true; -} \ No newline at end of file +} diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 6bdffe0b187..c507df4c858 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -299,15 +299,6 @@ bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*) return true; } -bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*) -{ - sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" ); - LoadLootTemplates_Milling(); - LootTemplates_Milling.CheckLootRefs(); - SendGlobalSysMessage("DB table `milling_loot_template` reloaded."); - return true; -} - bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*) { sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" ); @@ -1750,10 +1741,6 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/) if(!spellInfo) continue; - // skip server-side/triggered spells - if(spellInfo->spellLevel==0) - continue; - // skip wrong class/race skills if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id)) continue; @@ -1762,6 +1749,8 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/) if( spellInfo->SpellFamilyName != family) continue; + //TODO: skip triggered spells + // skip spells with first rank learned as talent (and all talents then also) uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id); if(GetTalentSpellCost(first_rank) > 0 ) @@ -3824,6 +3813,36 @@ bool ChatHandler::HandleHoverCommand(const char* args) return true; } +bool ChatHandler::HandleWaterwalkCommand(const char* args) +{ + if(!args) + return false; + + Player *player = getSelectedPlayer(); + if(!player) + { + PSendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; + } + + if (strncmp(args, "on", 3) == 0) + player->SetMovement(MOVE_WATER_WALK); // ON + else if (strncmp(args, "off", 4) == 0) + player->SetMovement(MOVE_LAND_WALK); // OFF + else + { + SendSysMessage(LANG_USE_BOL); + return false; + } + + PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName()); + if(needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName()); + return true; + +} + bool ChatHandler::HandleLevelUpCommand(const char* args) { char* px = strtok((char*)args, " "); @@ -4439,7 +4458,7 @@ static bool HandleResetStatsOrLevelHelper(Player* player) // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); - player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP ); + player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form); player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); @@ -4484,7 +4503,6 @@ bool ChatHandler::HandleResetLevelCommand(const char * args) player->SetLevel(1); player->InitStatsForLevel(true); player->InitTaxiNodesForLevel(); - player->InitGlyphsForLevel(); player->InitTalentForLevel(); player->SetUInt32Value(PLAYER_XP,0); @@ -4528,7 +4546,6 @@ bool ChatHandler::HandleResetStatsCommand(const char * args) player->InitStatsForLevel(true); player->InitTaxiNodesForLevel(); - player->InitGlyphsForLevel(); player->InitTalentForLevel(); return true; @@ -6591,27 +6608,30 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args) return false; } - PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); - if(!info) - return false; - char const* gender_str = (char*)args; int gender_len = strlen(gender_str); + uint32 displayId = player->GetNativeDisplayId(); + char const* gender_full = NULL; + uint32 new_displayId = displayId; Gender gender; - if(!strncmp(gender_str, "male", gender_len)) // MALE + if(!strncmp(gender_str,"male",gender_len)) // MALE { if(player->getGender() == GENDER_MALE) return true; + gender_full = "male"; + new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1; gender = GENDER_MALE; } - else if (!strncmp(gender_str, "female", gender_len)) // FEMALE + else if (!strncmp(gender_str,"female",gender_len)) // FEMALE { if(player->getGender() == GENDER_FEMALE) return true; + gender_full = "female"; + new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1; gender = GENDER_FEMALE; } else @@ -6623,19 +6643,14 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args) // Set gender player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); - player->SetByteValue(PLAYER_BYTES_3, 0, gender); // Change display ID - player->SetDisplayId(gender ? info->displayId_f : info->displayId_m); - player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m); - - char const* gender_full = gender ? "female" : "male"; - - PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full); + player->SetDisplayId(new_displayId); + player->SetNativeDisplayId(new_displayId); + PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full); if (needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName()); - + ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName()); return true; } diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index f1110ca3853..a4a8a7a1f01 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -154,7 +154,6 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data ) --loot->unlootedCount; player->SendNewItem(newitem, uint32(item->count), false, false, true); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); } else player->SendEquipError( msg, NULL, NULL ); @@ -327,7 +326,7 @@ void WorldSession::DoLootRelease( uint64 lguid ) int32 ReqValue = 175; LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId); if(lockInfo) - ReqValue = lockInfo->Skill[0]; + ReqValue = lockInfo->requiredminingskill; float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25); double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses)); if(roll_chance_f(100*chance+skill)) @@ -496,7 +495,6 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) // not move item from loot to target inventory Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); target->SendNewItem(newitem, uint32(item.count), false, false, true ); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); // mark as looted item.count=0; diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 61c626a544c..4a34f51d672 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -41,7 +41,6 @@ LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenc LootStore LootTemplates_Fishing( "fishing_loot_template", "area id"); LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry"); LootStore LootTemplates_Item( "item_loot_template", "item entry"); -LootStore LootTemplates_Milling( "milling_loot_template", "item entry"); LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid"); LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry"); LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id"); @@ -1139,21 +1138,6 @@ void LoadLootTemplates_Item() LootTemplates_Item.ReportUnusedIds(ids_set); } -void LoadLootTemplates_Milling() -{ - LootIdSet ids_set; - LootTemplates_Milling.LoadAndCollectLootIds(ids_set); - - // remove real entries and check existence loot - for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) - if(ItemPrototype const* proto = sItemStorage.LookupEntry(i)) - if(ids_set.count(proto->ItemId)) - ids_set.erase(proto->ItemId); - - // output error for any still listed (not referenced from appropriate table) ids - LootTemplates_Milling.ReportUnusedIds(ids_set); -} - void LoadLootTemplates_Pickpocketing() { LootIdSet ids_set, ids_setUsed; @@ -1246,7 +1230,6 @@ void LoadLootTemplates_Reference() LootTemplates_Fishing.CheckLootRefs(&ids_set); LootTemplates_Gameobject.CheckLootRefs(&ids_set); LootTemplates_Item.CheckLootRefs(&ids_set); - LootTemplates_Milling.CheckLootRefs(&ids_set); LootTemplates_Pickpocketing.CheckLootRefs(&ids_set); LootTemplates_Skinning.CheckLootRefs(&ids_set); LootTemplates_Disenchant.CheckLootRefs(&ids_set); diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index f9fed651a1c..1cb02c29bfc 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -297,7 +297,6 @@ extern LootStore LootTemplates_Creature; extern LootStore LootTemplates_Fishing; extern LootStore LootTemplates_Gameobject; extern LootStore LootTemplates_Item; -extern LootStore LootTemplates_Milling; extern LootStore LootTemplates_Pickpocketing; extern LootStore LootTemplates_Skinning; extern LootStore LootTemplates_Disenchant; @@ -308,7 +307,6 @@ void LoadLootTemplates_Creature(); void LoadLootTemplates_Fishing(); void LoadLootTemplates_Gameobject(); void LoadLootTemplates_Item(); -void LoadLootTemplates_Milling(); void LoadLootTemplates_Pickpocketing(); void LoadLootTemplates_Skinning(); void LoadLootTemplates_Disenchant(); @@ -322,7 +320,6 @@ inline void LoadLootTables() LoadLootTemplates_Fishing(); LoadLootTemplates_Gameobject(); LoadLootTemplates_Item(); - LoadLootTemplates_Milling(); LoadLootTemplates_Pickpocketing(); LoadLootTemplates_Skinning(); LoadLootTemplates_Disenchant(); diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index 3d4126bd22a..00211094d4e 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.cpp @@ -593,7 +593,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data ) data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3 - data << (uint8) item_count; // client limit is 0x10 + data << (uint8) item_count; for(uint8 i = 0; i < item_count; ++i) { @@ -604,7 +604,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data ) data << (uint32) (item ? item->GetGUIDLow() : 0); // entry data << (uint32) (item ? item->GetEntry() : 0); - for(uint8 j = 0; j < 7; ++j) + for(uint8 j = 0; j < 6; ++j) { // unsure data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); @@ -618,15 +618,13 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data ) // unk data << (uint32) (item ? item->GetItemSuffixFactor() : 0); // stack count - data << (uint32) (item ? item->GetCount() : 0); + data << (uint8) (item ? item->GetCount() : 0); // charges data << (uint32) (item ? item->GetSpellCharges() : 0); // durability data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); // durability data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); - // unknown wotlk - data << (uint8) 0; } mails_count += 1; diff --git a/src/game/Makefile.am b/src/game/Makefile.am index 2aee7919cf0..81259aef1a7 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -28,7 +28,6 @@ AM_CPPFLAGS = # later. noinst_LIBRARIES = libgame.a -<<<<<<< HEAD:src/game/Makefile.am libgame_a_CPPFLAGS = \ $(MYSQL_INCLUDES) \ $(POSTGRE_INCLUDES) \ @@ -37,258 +36,6 @@ $(TRINI_INCLUDES) \ -I$(top_srcdir)/src/framework \ -I$(top_srcdir)/src/shared \ -I$(top_srcdir)/src/shared/vmap -======= -# libmangossgame library will later be reused by ... -libmangosgame_a_SOURCES = \ - AccountMgr.cpp \ - AccountMgr.h \ - AchievementMgr.h \ - AchievementMgr.cpp \ - AddonHandler.cpp \ - AddonHandler.h \ - AggressorAI.cpp \ - AggressorAI.h \ - AnimalRandomMovementGenerator.h \ - ArenaTeam.cpp \ - ArenaTeam.h \ - ArenaTeamHandler.cpp \ - AuctionHouse.cpp \ - AuctionHouseObject.h \ - Bag.cpp \ - Bag.h \ - BattleGround.cpp \ - BattleGroundAA.cpp \ - BattleGroundAB.cpp \ - BattleGroundAV.cpp \ - BattleGroundBE.cpp \ - BattleGroundEY.cpp \ - BattleGroundNA.cpp \ - BattleGroundRL.cpp \ - BattleGroundWS.cpp \ - BattleGround.h \ - BattleGroundAA.h \ - BattleGroundAB.h \ - BattleGroundAV.h \ - BattleGroundBE.h \ - BattleGroundEY.h \ - BattleGroundNA.h \ - BattleGroundRL.h \ - BattleGroundWS.h \ - BattleGroundHandler.cpp \ - BattleGroundMgr.cpp \ - BattleGroundMgr.h \ - Calendar.cpp \ - Calendar.h \ - CalendarHandler.cpp \ - Cell.h \ - CellImpl.h \ - Channel.cpp \ - Channel.h \ - ChannelHandler.cpp \ - ChannelMgr.h \ - CharacterHandler.cpp \ - Chat.cpp \ - Chat.h \ - ChatHandler.cpp \ - CombatHandler.cpp \ - ConfusedMovementGenerator.cpp \ - ConfusedMovementGenerator.h \ - Corpse.cpp \ - Corpse.h \ - CreatureAI.cpp \ - CreatureAI.h \ - CreatureAIImpl.h \ - CreatureAIRegistry.cpp \ - CreatureAIRegistry.h \ - CreatureAISelector.cpp \ - CreatureAISelector.h \ - Creature.cpp \ - Creature.h \ - debugcmds.cpp \ - DestinationHolder.cpp \ - DestinationHolder.h \ - DestinationHolderImp.h \ - DuelHandler.cpp \ - DynamicObject.cpp \ - DynamicObject.h \ - FleeingMovementGenerator.cpp \ - FleeingMovementGenerator.h \ - Formulas.h \ - GameEvent.cpp \ - GameEvent.h \ - GameObject.cpp \ - GameObject.h \ - GlobalEvents.cpp \ - GlobalEvents.h \ - GMTicketHandler.cpp \ - GMTicketMgr.cpp \ - GMTicketMgr.h \ - GossipDef.cpp \ - GossipDef.h \ - GridDefines.h \ - GridNotifiers.cpp \ - GridNotifiers.h \ - GridNotifiersImpl.h \ - GridStates.cpp \ - GridStates.h \ - Group.cpp \ - Group.h \ - GroupHandler.cpp \ - GuardAI.cpp \ - GuardAI.h \ - Guild.cpp \ - Guild.h \ - GuildHandler.cpp \ - HomeMovementGenerator.cpp \ - HomeMovementGenerator.h \ - HostilRefManager.cpp \ - HostilRefManager.h \ - IdleMovementGenerator.cpp \ - IdleMovementGenerator.h \ - InstanceData.cpp \ - InstanceData.h \ - InstanceSaveMgr.cpp \ - InstanceSaveMgr.h \ - Item.cpp \ - Item.h \ - ItemEnchantmentMgr.cpp \ - ItemEnchantmentMgr.h \ - ItemHandler.cpp \ - ItemPrototype.h \ - Language.h \ - Level0.cpp \ - Level1.cpp \ - Level2.cpp \ - Level3.cpp \ - LFGHandler.cpp \ - LootHandler.cpp \ - LootMgr.cpp \ - LootMgr.h \ - Mail.cpp \ - Mail.h \ - Map.cpp \ - Map.h \ - MapInstanced.cpp \ - MapInstanced.h \ - MapManager.cpp \ - MapManager.h \ - MapReference.h \ - MapRefManager.h \ - MiscHandler.cpp \ - MotionMaster.cpp \ - MotionMaster.h \ - MovementGenerator.cpp \ - MovementGenerator.h \ - MovementGeneratorImpl.h \ - MovementHandler.cpp \ - NPCHandler.cpp \ - NPCHandler.h \ - NullCreatureAI.cpp \ - NullCreatureAI.h \ - ObjectAccessor.cpp \ - ObjectAccessor.h \ - Object.cpp \ - ObjectDefines.h \ - ObjectGridLoader.cpp \ - ObjectGridLoader.h \ - Object.h \ - ObjectMgr.cpp \ - ObjectMgr.h \ - ObjectPosSelector.cpp \ - ObjectPosSelector.h \ - Opcodes.cpp \ - Opcodes.h \ - Path.h \ - PetAI.cpp \ - PetAI.h \ - Pet.cpp \ - Pet.h \ - PetHandler.cpp \ - PetitionsHandler.cpp \ - Player.cpp \ - Player.h \ - PlayerDump.cpp \ - PlayerDump.h \ - PointMovementGenerator.cpp \ - PointMovementGenerator.h \ - QueryHandler.cpp \ - QuestDef.cpp \ - QuestDef.h \ - QuestHandler.cpp \ - RandomMovementGenerator.cpp \ - RandomMovementGenerator.h \ - ReactorAI.cpp \ - ReactorAI.h \ - ScriptCalls.cpp \ - ScriptCalls.h \ - SharedDefines.h \ - SkillHandler.cpp \ - SpellAuraDefines.h \ - SpellAuras.cpp \ - SpellAuras.h \ - Spell.cpp \ - SpellEffects.cpp \ - Spell.h \ - SkillDiscovery.cpp \ - SkillDiscovery.h \ - SkillExtraItems.cpp \ - SkillExtraItems.h \ - SpellHandler.cpp \ - SocialMgr.cpp \ - SocialMgr.h \ - SpellMgr.cpp \ - SpellMgr.h \ - StatSystem.cpp \ - TargetedMovementGenerator.cpp \ - TargetedMovementGenerator.h \ - TaxiHandler.cpp \ - TemporarySummon.cpp \ - TemporarySummon.h \ - tools.cpp \ - Tools.h \ - TotemAI.cpp \ - TotemAI.h \ - Totem.cpp \ - Totem.h \ - TradeHandler.cpp \ - Transports.cpp \ - Transports.h \ - ThreatManager.cpp \ - ThreatManager.h \ - Traveller.h \ - Unit.cpp \ - Unit.h \ - UnitEvents.h \ - UpdateData.cpp \ - UpdateData.h \ - UpdateFields.h \ - UpdateMask.h \ - Vehicle.cpp \ - Vehicle.h \ - VoiceChatHandler.cpp \ - WaypointManager.cpp \ - WaypointManager.h \ - WaypointMovementGenerator.cpp \ - WaypointMovementGenerator.h \ - Weather.cpp \ - Weather.h \ - World.cpp \ - World.h \ - WorldLog.cpp \ - WorldLog.h \ - WorldSession.cpp \ - WorldSession.h \ - WorldSocket.cpp \ - WorldSocket.h \ - WorldSocketMgr.cpp \ - WorldSocketMgr.h \ - FollowerReference.cpp \ - FollowerReference.h \ - FollowerRefManager.h \ - GroupReference.cpp \ - GroupReference.h \ - GroupRefManager.h ->>>>>>> upstream/master:src/game/Makefile.am # libmangossgame library will later be reused by ... libgame_a_SOURCES = \ diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 8116510df9b..531f32e75e9 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -45,7 +45,7 @@ #define MAX_GRID_LOAD_TIME 50 // magic *.map header -const char MAP_MAGIC[] = "MAP_2.01"; +const char MAP_MAGIC[] = "MAP_2.00"; GridState* si_GridStates[MAX_GRID_STATE]; @@ -257,7 +257,7 @@ template<> void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell) { // add to world object registry in grid - if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle()) + if(obj->isPet() || obj->isPossessedByPlayer()) { (*grid)(cell.CellX(), cell.CellY()).AddWorldObject(obj, obj->GetGUID()); obj->SetCurrentCell(cell); @@ -301,7 +301,7 @@ template<> void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell) { // remove from world object registry in grid - if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle()) + if(obj->isPet() || obj->isPossessedByPlayer()) { (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject(obj, obj->GetGUID()); } diff --git a/src/game/Map.h b/src/game/Map.h index 43f9326c108..23b2ea1f3fa 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -224,17 +224,6 @@ class TRINITY_DLL_SPEC Map : public GridRefManager, public Trinity::O bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); } bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); } - bool GetEntrancePos(int32 &mapid, float &x, float &y) - { - if(!i_mapEntry) - return false; - if(i_mapEntry->entrance_map < 0) - return false; - mapid = i_mapEntry->entrance_map; - x = i_mapEntry->entrance_x; - y = i_mapEntry->entrance_y; - return true; - } void AddObjectToRemoveList(WorldObject *obj); void DoDelayedMovesAndRemoves(); diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 47be039d415..26279cb76ec 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -175,8 +175,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) //The player has a heroic mode and tries to enter into instance which has no a heroic mode if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC) { - //Send aborted message - player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC); + player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY2); //Send aborted message return false; } @@ -281,8 +280,7 @@ bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y) bool MapManager::IsValidMAP(uint32 mapid) { MapEntry const* mEntry = sMapStore.LookupEntry(mapid); - return mEntry && (!mEntry->IsDungeon() || objmgr.GetInstanceTemplate(mapid)); - // TODO: add check for battleground template + return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid)); } void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload) diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index e52afcb80a9..f5ee5dbcf4c 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -45,7 +45,6 @@ #include "Pet.h" #include "SocialMgr.h" #include "CellImpl.h" -#include "Tools.h" void WorldSession::HandleRepopRequestOpcode( WorldPacket & /*recv_data*/ ) { @@ -313,7 +312,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ ) data.append(GetPlayer()->GetPackGUID()); data << (uint32)2; SendPacket( &data ); - GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); } WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 ); @@ -350,7 +349,7 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ ) GetPlayer()->SetStandState(PLAYER_STATE_NONE); //! DISABLE_ROTATE - GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); } sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" ); @@ -364,12 +363,10 @@ void WorldSession::HandleTogglePvP( WorldPacket & recv_data ) bool newPvPStatus; recv_data >> newPvPStatus; GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus); - GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus); } else { GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP); - GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER); } if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) @@ -885,7 +882,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) if(missingItem) SendAreaTriggerMessage(GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1); else if(missingKey) - GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC); + GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY2); else if(missingQuest) SendAreaTriggerMessage(at->requiredFailedText.c_str()); else if(missingLevel) @@ -897,96 +894,16 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT); } -void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) +void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/) { sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); - - CHECK_PACKET_SIZE(recv_data, 4+4+4); - - uint32 type, timestamp, decompressedSize; - recv_data >> type >> timestamp >> decompressedSize; - - sLog.outDebug("UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize); - - if(type > NUM_ACCOUNT_DATA_TYPES) - return; - - if(decompressedSize == 0) // erase - { - SetAccountData(type, timestamp, ""); - - WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); - data << uint32(type); - data << uint32(0); - SendPacket(&data); - - return; - } - - if(decompressedSize > 0xFFFF) - { - sLog.outError("UAD: Account data packet too big, size %u", decompressedSize); - return; - } - - ByteBuffer dest; - dest.resize(decompressedSize); - - uLongf realSize = decompressedSize; - if(uncompress(const_cast(dest.contents()), &realSize, const_cast(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK) - { - sLog.outError("UAD: Failed to decompress account data"); - return; - } - - std::string adata; - dest >> adata; - - SetAccountData(type, timestamp, adata); - - WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); - data << uint32(type); - data << uint32(0); - SendPacket(&data); + //recv_data.hexlike(); } -void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) +void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/) { sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); - - CHECK_PACKET_SIZE(recv_data, 4); - - uint32 type; - recv_data >> type; - - sLog.outDebug("RAD: type %u", type); - - if(type > NUM_ACCOUNT_DATA_TYPES) - return; - - AccountData *adata = GetAccountData(type); - - uint32 size = adata->Data.size(); - - ByteBuffer dest; - dest.resize(size); - - uLongf destSize = size; - if(compress(const_cast(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK) - { - sLog.outDebug("RAD: Failed to compress account data"); - return; - } - - dest.resize(destSize); - - WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize); - data << uint64(_player->GetGUID()); // player guid - data << uint32(type); // type (0-7) - data << uint32(adata->Time); // unix time - data << uint32(size); // decompressed length - data.append(dest); // compressed data - SendPacket(&data); + //recv_data.hexlike(); } void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) @@ -1517,11 +1434,11 @@ void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data ) GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title); } -void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data ) +void WorldSession::HandleAllowMoveAckOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data, 4+4); - sLog.outDebug("CMSG_TIME_SYNC_RESP"); + sLog.outDebug("CMSG_ALLOW_MOVE_ACK"); uint32 counter, time_; recv_data >> counter >> time_; @@ -1591,6 +1508,26 @@ void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data ) } } +void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("New Unknown Opcode %u", recv_data.GetOpcode()); + recv_data.hexlike(); + /* + New Unknown Opcode 837 + STORAGE_SIZE: 60 + 02 00 00 00 00 00 00 00 | 00 00 00 00 01 20 00 00 + 89 EB 33 01 71 5C 24 C4 | 15 03 35 45 74 47 8B 42 + BA B8 1B 40 00 00 00 00 | 00 00 00 00 77 66 42 BF + 23 91 26 3F 00 00 60 41 | 00 00 00 00 + + New Unknown Opcode 837 + STORAGE_SIZE: 44 + 02 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00 + 7B 80 34 01 84 EA 2B C4 | 5F A1 36 45 C9 39 1C 42 + BA B8 1B 40 CE 06 00 00 | 00 00 80 3F + */ +} + void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA"); @@ -1657,32 +1594,3 @@ void WorldSession::HandleSetTaxiBenchmarkOpcode( WorldPacket & recv_data ) sLog.outDebug("Client used \"/timetest %d\" command", mode); } - -void WorldSession::HandleSpellClick( WorldPacket & recv_data ) -{ - CHECK_PACKET_SIZE(recv_data, 8); - - uint64 guid; - recv_data >> guid; - - Vehicle *vehicle = ObjectAccessor::GetVehicle(guid); - - if(!vehicle) - return; - - _player->EnterVehicle(vehicle); -} - -void WorldSession::HandleInspectAchievements( WorldPacket & recv_data ) -{ - CHECK_PACKET_SIZE(recv_data, 1); - uint64 guid; - if(!readGUID(recv_data, guid)) - return; - - Player *player = objmgr.GetPlayer(guid); - if(!player) - return; - - player->GetAchievementMgr().SendRespondInspectAchievements(_player); -} diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 29f673061b4..0a310cddd96 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -178,12 +178,64 @@ void WorldSession::HandleMoveWorldportAckOpcode() void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { - uint32 opcode = recv_data.GetOpcode(); - sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); + CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4); /* extract packet */ MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + uint32 MovementFlags; + + recv_data >> MovementFlags; + recv_data >> movementInfo.unk1; + recv_data >> movementInfo.time; + recv_data >> movementInfo.x; + recv_data >> movementInfo.y; + recv_data >> movementInfo.z; + recv_data >> movementInfo.o; + + if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); + + recv_data >> movementInfo.t_guid; + recv_data >> movementInfo.t_x; + recv_data >> movementInfo.t_y; + recv_data >> movementInfo.t_z; + recv_data >> movementInfo.t_o; + recv_data >> movementInfo.t_time; + } + + if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.fallTime; // duration of last jump (when in jump duration from jump begin to now) + + if(MovementFlags & MOVEMENTFLAG_JUMPING) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); + + recv_data >> movementInfo.j_unk; // constant, but different when jumping in water and on land? + recv_data >> movementInfo.j_sinAngle; // sin of angle between orientation0 and players orientation + recv_data >> movementInfo.j_cosAngle; // cos of angle between orientation0 and players orientation + recv_data >> movementInfo.j_xyspeed; // speed of xy movement + } + + if(MovementFlags & MOVEMENTFLAG_SPLINE) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.u_unk1; // unknown + } /*----------------*/ if(recv_data.size() != recv_data.rpos()) @@ -200,7 +252,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) Unit* pos_unit = GetPlayer()->GetCharm(); if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed { - HandlePossessedMovement(recv_data, movementInfo, movementInfo.flags); + HandlePossessedMovement(recv_data, movementInfo, MovementFlags); return; } @@ -208,10 +260,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) return; //Save movement flags - GetPlayer()->SetUnitMovementFlags(movementInfo.flags); + GetPlayer()->SetUnitMovementFlags(MovementFlags); /* handle special cases */ - if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) + if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) @@ -230,6 +282,9 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { if ((*iter)->GetGUID() == movementInfo.t_guid) { + // unmount before boarding + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + GetPlayer()->m_transport = (*iter); (*iter)->AddPassenger(GetPlayer()); break; @@ -246,14 +301,13 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) movementInfo.t_z = 0.0f; movementInfo.t_o = 0.0f; movementInfo.t_time = 0; - movementInfo.t_seat = -1; } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). - if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) + if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) GetPlayer()->HandleFallDamage(movementInfo); - if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) + if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) { // now client not include swimming flag in case jumping under water GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); @@ -262,35 +316,14 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) /*----------------------*/ /* process position-change */ - Unit *mover = _player->m_mover; - recv_data.put(6, getMSTime()); // fix time, offset flags(4) + unk(2) - WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size())); - data.append(_player->m_mover->GetPackGUID()); // use mover guid + recv_data.put(5, getMSTime()); // offset flags(4) + unk(1) + WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size())); + data.append(GetPlayer()->GetPackGUID()); data.append(recv_data.contents(), recv_data.size()); GetPlayer()->SendMessageToSet(&data, false); - if(!_player->GetCharmGUID()) // nothing is charmed - { - _player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - _player->m_movementInfo = movementInfo; - _player->SetUnitMovementFlags(movementInfo.flags); - } - else - { - if(mover->GetTypeId() != TYPEID_PLAYER) // unit, creature, pet, vehicle... - { - if(Map *map = mover->GetMap()) - map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - mover->SetUnitMovementFlags(movementInfo.flags); - } - else // player - { - ((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - ((Player*)mover)->m_movementInfo = movementInfo; - ((Player*)mover)->SetUnitMovementFlags(movementInfo.flags); - } - } - + GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + GetPlayer()->m_movementInfo = movementInfo; if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND) GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z); @@ -363,13 +396,20 @@ void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) { - sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode()); - - CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4); + CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4); /* extract packet */ uint64 guid; - uint32 unk1; + uint8 unkB; + uint32 unk1, flags, time, fallTime; + float x, y, z, orientation; + + uint64 t_GUID; + float t_x, t_y, t_z, t_o; + uint32 t_time; + float s_pitch; + float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed; + float u_unk1; float newspeed; recv_data >> guid; @@ -380,10 +420,47 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) // continue parse packet - recv_data >> unk1; // counter or moveEvent + recv_data >> unk1; + recv_data >> flags >> unkB >> time; + recv_data >> x >> y >> z >> orientation; + if (flags & MOVEMENTFLAG_ONTRANSPORT) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); - MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + recv_data >> t_GUID; + recv_data >> t_x >> t_y >> t_z >> t_o >> t_time; + } + if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now) + + if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); + + recv_data >> j_unk1; // ?constant, but different when jumping in water and on land? + recv_data >> j_sinAngle >> j_cosAngle; // sin + cos of angle between orientation0 and players orientation + recv_data >> j_xyspeed; // speed of xy movement + } + + if(flags & MOVEMENTFLAG_SPLINE) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> u_unk1; // unknown + } // recheck CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); @@ -396,7 +473,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) UnitMoveType move_type; UnitMoveType force_move_type; - static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" }; + static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" }; uint16 opcode = recv_data.GetOpcode(); switch(opcode) @@ -409,7 +486,6 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break; case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break; case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break; - case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break; default: sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); return; @@ -444,61 +520,20 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data) { sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); - recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 8); + CHECK_PACKET_SIZE(recv_data,8); uint64 guid; recv_data >> guid; - if(_player->m_mover->GetGUID() != guid) - { - sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid); - return; - } + WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement + data << uint32(0x00000000); // on blizz it increments periodically + SendPacket(&data); } -void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) +void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/) { sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER"); - recv_data.hexlike(); - - CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8); - - uint64 old_mover_guid; - recv_data >> old_mover_guid; - - if(_player->m_mover->GetGUID() == old_mover_guid) - { - sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid); - return; - } - - MovementInfo mi; - ReadMovementInfo(recv_data, &mi); - _player->m_movementInfo = mi; -} - -void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); - recv_data.hexlike(); - - uint64 vehicleGUID = _player->GetCharmGUID(); - - if(!vehicleGUID) // something wrong here... - return; - - MovementInfo mi; - ReadMovementInfo(recv_data, &mi); - _player->m_movementInfo = mi; - - // using charm guid, because we don't have vehicle guid... - if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID)) - { - _player->ExitVehicle(vehicle); - vehicle->Dismiss(); - } } void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/) diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index c6751512e02..6bb916d9fe0 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -524,12 +524,13 @@ void WorldSession::SendStablePet(uint64 guid ) data << uint32(pet->GetEntry()); data << uint32(pet->getLevel()); data << pet->GetName(); // petname - data << uint8(0x01); // flags?, client slot 1 == current pet (0) + data << uint32(pet->GetLoyaltyLevel()); // loyalty + data << uint8(0x01); // client slot 1 == current pet (0) ++num; } - // 0 1 2 3 4 5 - QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow()); + // 0 1 2 3 4 5 6 + QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow()); if(result) { @@ -540,7 +541,8 @@ void WorldSession::SendStablePet(uint64 guid ) data << uint32(fields[2].GetUInt32()); // petnumber data << uint32(fields[3].GetUInt32()); // creature entry data << uint32(fields[4].GetUInt32()); // level - data << fields[5].GetString(); // name + data << fields[6].GetString(); // name + data << uint32(fields[5].GetUInt32()); // loyalty data << uint8(fields[1].GetUInt32()+1); // slot ++num; @@ -590,7 +592,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) uint32 free_slot = 1; - QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5 ORDER BY slot ",_player->GetGUIDLow()); + QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3 ORDER BY slot ",_player->GetGUIDLow()); if(result) { do @@ -654,7 +656,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) Pet *newpet = NULL; - QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow(),petnumber); + QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow(),petnumber); if(result) { Field *fields = result->Fetch(); @@ -698,7 +700,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data ) WorldPacket data(SMSG_STABLE_RESULT, 200); - if(GetPlayer()->m_stableSlots < 4) // max slots amount = 4 + if(GetPlayer()->m_stableSlots < 2) // max slots amount = 2 { StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1); if(_player->GetMoney() >= SlotPrice->Price) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index e4e5230bfb6..efd041f34c2 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -146,9 +146,15 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c /** lower flag1 **/ if(target == this) // building packet for oneself + { flags |= UPDATEFLAG_SELF; - if(flags & UPDATEFLAG_HAS_POSITION) + /*** temporary reverted - until real source of stack corruption will not found + updatetype = UPDATETYPE_CREATE_OBJECT2; + ****/ + } + + if(flags & UPDATEFLAG_HASPOSITION) { // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses... if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER)) @@ -174,12 +180,6 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c break; } } - - if(isType(TYPEMASK_UNIT)) - { - if(((Unit*)this)->getVictim()) - flags |= UPDATEFLAG_HAS_TARGET; - } } //sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2); @@ -251,18 +251,11 @@ void Object::DestroyForPlayer(Player *target) const WorldPacket data(SMSG_DESTROY_OBJECT, 8); data << GetGUID(); - data << uint8(0); // WotLK (bool) target->GetSession()->SendPacket( &data ); } -void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const +void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const { - uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0); - - if(GetTypeId() == TYPEID_UNIT) - if(((Creature*)this)->isVehicle()) - unk_flags |= 0x20; // always allow pitch - *data << (uint8)flags; // update flags // 0x20 @@ -299,12 +292,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) } *data << uint32(flags2); // movement flags - *data << uint16(unk_flags); // unknown 2.3.0 + *data << uint8(0); // unk 2.3.0 *data << uint32(getMSTime()); // time (in milliseconds) } // 0x40 - if (flags & UPDATEFLAG_HAS_POSITION) + if (flags & UPDATEFLAG_HASPOSITION) { // 0x02 if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT) @@ -337,13 +330,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) *data << (float)((Player*)this)->GetTransOffsetZ(); *data << (float)((Player*)this)->GetTransOffsetO(); *data << (uint32)((Player*)this)->GetTransTime(); - *data << (int8)((Player*)this)->GetTransSeat(); } //TrinIty currently not have support for other than player on transport } // 0x02200000 - if((flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (unk_flags & 0x20)) + if(flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) { if(GetTypeId() == TYPEID_PLAYER) *data << (float)((Player*)this)->m_movementInfo.s_pitch; @@ -392,7 +384,6 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) *data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT ); *data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK ); *data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE ); - *data << ((Unit*)this)->GetSpeed( MOVE_PITCH_RATE ); // 0x08000000 if(flags2 & MOVEMENTFLAG_SPLINE2) @@ -494,7 +485,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) break; case TYPEID_PLAYER: if(flags & UPDATEFLAG_SELF) - *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22 + *data << uint32(0x00000015); // unk, can be 0x15 or 0x22 else *data << uint32(0x00000008); // unk, can be 0x7 or 0x8 break; @@ -517,15 +508,6 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) case TYPEID_CORPSE: *data << uint32(GetGUIDHigh()); // GetGUIDHigh() break; - case TYPEID_UNIT: - *data << uint32(0x0000000B); // unk, can be 0xB or 0xC - break; - case TYPEID_PLAYER: - if(flags & UPDATEFLAG_SELF) - *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22 - else - *data << uint32(0x00000008); // unk, can be 0x7 or 0x8 - break; default: *data << uint32(0x00000000); // unk break; @@ -533,12 +515,9 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) } // 0x4 - if(flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid) + if(flags & UPDATEFLAG_FULLGUID) { - if(Unit *victim = ((Unit*)this)->getVictim()) - data->append(victim->GetPackGUID()); - else - *data << uint8(0); + *data << uint8(0); // packed guid (probably target guid) } // 0x2 @@ -546,13 +525,6 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) { *data << uint32(getMSTime()); // ms time } - - // 0x80 - if(flags & UPDATEFLAG_VEHICLE) // unused for now - { - *data << uint32(((Vehicle*)this)->GetVehicleId()); // vehicle id - *data << float(0); // facing adjustment - } } void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const @@ -568,8 +540,10 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster()) { IsActivateToQuest = true; - updateMask->SetBit(GAMEOBJECT_DYNAMIC); + updateMask->SetBit(GAMEOBJECT_DYN_FLAGS); } + if (GetUInt32Value(GAMEOBJECT_ARTKIT)) + updateMask->SetBit(GAMEOBJECT_ARTKIT); } } else //case UPDATETYPE_VALUES @@ -580,8 +554,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask { IsActivateToQuest = true; } - updateMask->SetBit(GAMEOBJECT_DYNAMIC); - updateMask->SetBit(GAMEOBJECT_BYTES_1); + updateMask->SetBit(GAMEOBJECT_DYN_FLAGS); + updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS); } } @@ -598,6 +572,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask if( updateMask->GetBit( index ) ) { // remove custom flag before send + if( index == UNIT_NPC_FLAGS ) *data << uint32(m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP)); // FIXME: Some values at server stored in float format but must be sent to client in uint32 format @@ -666,7 +641,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask if( updateMask->GetBit( index ) ) { // send in current format (float as float, uint32 as uint32) - if ( index == GAMEOBJECT_DYNAMIC ) + if ( index == GAMEOBJECT_DYN_FLAGS ) { if(IsActivateToQuest ) { @@ -1118,7 +1093,7 @@ uint32 WorldObject::GetAreaId() const InstanceData* WorldObject::GetInstanceData() { - Map *map = GetMap(); + Map *map = MapManager::Instance().GetMap(m_mapId, this); return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL; } @@ -1328,7 +1303,7 @@ namespace Trinity { public: MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist) - : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), + : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_targetGUID(targetGUID), i_dist(dist) { } @@ -1473,7 +1448,7 @@ void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const data->Initialize(MSG_MOVE_HEARTBEAT, 32); data->append(GetPackGUID()); *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags - *data << uint16(0); // 2.3.0 + *data << uint8(0); // 2.3.0 *data << getMSTime(); // time *data << m_positionX; *data << m_positionY; @@ -1492,7 +1467,7 @@ void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float data->append(GetPackGUID()); *data << uint32(0); // this value increments every time *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags - *data << uint16(0); // 2.3.0 + *data << uint8(0); // 2.3.0 *data << getMSTime(); // time *data << x; *data << y; @@ -1645,4 +1620,4 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y, z = GetPositionZ(); UpdateGroundPositionZ(x,y,z); -} +} \ No newline at end of file diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 4e876d99418..7d51c4c0291 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -134,9 +134,6 @@ ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid) if(Creature *unit = GetPet(guid)) return unit; - if(Creature *unit = GetVehicle(guid)) - return unit; - return GetCreature(u, guid); } @@ -354,12 +351,6 @@ ObjectAccessor::GetPet(uint64 guid) return GetObjectInWorld(guid, (Pet*)NULL); } -Vehicle* -ObjectAccessor::GetVehicle(uint64 guid) -{ - return GetObjectInWorld(guid, (Vehicle*)NULL); -} - Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) { @@ -611,7 +602,6 @@ template ZThread::FastMutex HashMapHolder::i_lock; template class HashMapHolder; template class HashMapHolder; -template class HashMapHolder; template class HashMapHolder; template class HashMapHolder; template class HashMapHolder; @@ -619,7 +609,6 @@ template class HashMapHolder; template Player* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/); template Pet* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); -template Vehicle* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/); template Creature* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/); template Corpse* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/); template GameObject* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 2202748cd5a..844a6b49e4d 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -33,7 +33,6 @@ #include "GridDefines.h" #include "Object.h" #include "Player.h" -#include "Vehicle.h" #include @@ -151,7 +150,6 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::SingletongetSource(); - assert((!c->isPet() || !c->isVehicle()) && "ObjectGridRespawnMover don't must be called for pets"); + assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets"); Cell const& cur_cell = c->GetCurrentCell(); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index add9fa793af..594cfaf0877 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -116,7 +116,6 @@ ObjectMgr::ObjectMgr() m_hiCharGuid = 1; m_hiCreatureGuid = 1; m_hiPetGuid = 1; - m_hiVehicleGuid = 1; m_hiItemGuid = 1; m_hiGoGuid = 1; m_hiDoGuid = 1; @@ -642,22 +641,6 @@ void ObjectMgr::LoadCreatureLocales() sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() ); } -void ObjectMgr::LoadCompletedAchievements() -{ - QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement"); - - if(!result) - return; - - do - { - Field *fields = result->Fetch(); - allCompletedAchievements.insert(fields[0].GetUInt32()); - } while(result->NextRow()); - - delete result; -} - void ObjectMgr::LoadNpcOptionLocales() { mNpcOptionLocaleMap.clear(); // need for reload case @@ -1020,47 +1003,8 @@ void ObjectMgr::LoadEquipmentTemplates() { sEquipmentStorage.Load(); - for(uint32 i=0; i< sEquipmentStorage.MaxEntry; ++i) - { - EquipmentInfo const* eqInfo = sEquipmentStorage.LookupEntry(i); - - if(!eqInfo) - continue; - - for(uint8 j=0; j<3; j++) - { - if(!eqInfo->equipentry[j]) - continue; - - ItemEntry const *dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]); - - if(!dbcitem) - { - sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j+1, i); - const_cast(eqInfo)->equipentry[j] = 0; - continue; - } - - if(dbcitem->InventoryType != INVTYPE_WEAPON && - dbcitem->InventoryType != INVTYPE_SHIELD && - dbcitem->InventoryType != INVTYPE_RANGED && - dbcitem->InventoryType != INVTYPE_2HWEAPON && - dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND && - dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND && - dbcitem->InventoryType != INVTYPE_HOLDABLE && - dbcitem->InventoryType != INVTYPE_THROWN && - dbcitem->InventoryType != INVTYPE_RANGEDRIGHT) - { - sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i); - const_cast(eqInfo)->equipentry[j] = 0; - } - } - } sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount ); sLog.outString(); - - // This DBC is currently only used for item templates and creature equipments checks. - sItemStore.Clear(); } CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid) @@ -1734,7 +1678,7 @@ void ObjectMgr::LoadItemPrototypes() if(proto->Class >= MAX_ITEM_CLASS) { sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class); - const_cast(proto)->Class = ITEM_CLASS_MISC; + const_cast(proto)->Class = ITEM_CLASS_JUNK; } if(proto->SubClass >= MaxItemSubclassValues[proto->Class]) @@ -1831,7 +1775,7 @@ void ObjectMgr::LoadItemPrototypes() } // special format - if((proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) || (proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN_PET)) + if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) { // spell_1 if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) @@ -1868,7 +1812,7 @@ void ObjectMgr::LoadItemPrototypes() const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; } // allowed only in special format - else if((proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN_PET)) + else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) { sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId); const_cast(proto)->Spells[0].SpellId = 0; @@ -1914,7 +1858,7 @@ void ObjectMgr::LoadItemPrototypes() const_cast(proto)->Spells[j].SpellId = 0; } // allowed only in special format - else if((proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN_PET)) + else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) { sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId); const_cast(proto)->Spells[j].SpellId = 0; @@ -1983,6 +1927,9 @@ void ObjectMgr::LoadItemPrototypes() const_cast(proto)->FoodType = 0; } } + + // this DBC used currently only for check item templates in DB. + sItemStore.Clear(); } void ObjectMgr::LoadAuctionItems() @@ -2972,31 +2919,31 @@ void ObjectMgr::LoadQuests() QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue," // 9 10 11 12 13 14 15 16 "RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime," - // 17 18 19 20 21 22 23 24 25 26 27 28 - "QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell," - // 29 30 31 32 33 34 35 36 37 38 + // 17 18 19 20 21 22 23 24 25 26 + "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell," + // 27 28 29 30 31 32 33 34 35 36 "Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4," - // 39 40 41 42 43 44 45 46 + // 37 38 39 40 41 42 43 44 "ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4," - // 47 48 49 50 51 52 53 54 55 56 57 58 + // 45 46 47 48 49 50 51 52 53 54 54 55 "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4," - // 59 60 61 62 63 64 65 66 + // 57 58 59 60 61 62 63 64 "ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4," - // 67 68 69 70 + // 65 66 67 68 "ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4," - // 71 72 73 74 75 76 + // 69 70 71 72 73 74 "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6," - // 77 78 79 80 81 82 + // 75 76 77 78 79 80 "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6," - // 83 84 85 86 87 88 89 90 + // 81 82 83 84 85 86 87 88 "RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4," - // 91 92 93 94 95 96 97 98 99 100 + // 89 90 91 92 93 94 95 96 97 98 "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5," - // 101 102 103 104 105 106 107 108 109 110 111 + // 99 100 101 102 103 104 105 106 107 108 109 "RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt," - // 112 113 114 115 116 117 118 119 120 121 + // 110 111 112 113 114 115 116 117 118 119 "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4," - // 122 123 + // 120 121 "StartScript, CompleteScript" " FROM quest_template"); if(result == NULL) @@ -4829,19 +4776,17 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team ) TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id); if(node) { - if (team == ALLIANCE) + if (team == ALLIANCE) mount_entry = node->alliance_mount_type; + else mount_entry = node->horde_mount_type; + + CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry); + if (cinfo) { - mount_entry = node->MountCreatureID[1]; - CreatureInfo const *ci = GetCreatureTemplate(mount_entry); - if(ci) - mount_id = ci->Modelid1; - } - if (team == HORDE) - { - mount_entry = node->MountCreatureID[0]; - CreatureInfo const *ci = GetCreatureTemplate(mount_entry); - if(ci) - mount_id = ci->Modelid3; + if(! (mount_id = cinfo->GetRandomValidModelId())) + { + sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry); + return false; + } } } @@ -5320,8 +5265,6 @@ void ObjectMgr::SetHighestGuids() // pet guids are not saved to DB, set to 0 (pet guid != pet id) m_hiPetGuid = 0; - // same for vehicles - m_hiVehicleGuid = 0; result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" ); if( result ) @@ -5475,14 +5418,6 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) World::StopNow(ERROR_EXIT_CODE); } return m_hiPetGuid++; - case HIGHGUID_VEHICLE: - ++m_hiVehicleGuid; - if(m_hiVehicleGuid>=0x00FFFFFF) - { - sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. "); - World::StopNow(ERROR_EXIT_CODE); - } - return m_hiVehicleGuid++; case HIGHGUID_PLAYER: if(m_hiCharGuid>=0xFFFFFFFE) { @@ -6445,23 +6380,6 @@ int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc ) return m_LocalForIndex.size()-1; } -AchievementCriteriaEntryList const& ObjectMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type) -{ - return m_AchievementCriteriasByType[type]; -} - -void ObjectMgr::LoadAchievementCriteriaList() -{ - for (uint32 entryId = 0; entryIdrequiredType].push_back(criteria); - } -} - void ObjectMgr::LoadBattleMastersEntry() { mBattleMastersMap.clear(); // need for reload case @@ -6838,7 +6756,7 @@ bool PlayerCondition::Meets(Player const * player) const { Unit::AuraMap const& auras = player->GetAuras(); for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) - if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580) + if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580) return true; return false; } @@ -7015,7 +6933,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial) return SKILL_RANGE_MONO; case SKILL_CATEGORY_ARMOR: case SKILL_CATEGORY_CLASS: - if(pSkill->id != SKILL_LOCKPICKING) + if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING) return SKILL_RANGE_MONO; else return SKILL_RANGE_LEVEL; @@ -7030,7 +6948,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial) return SKILL_RANGE_MONO; default: case SKILL_CATEGORY_ATTRIBUTES: //not found in dbc - case SKILL_CATEGORY_GENERIC: //only GENERIC(DND) + case SKILL_CATEGORY_NOT_DISPLAYED: //only GENEREC(DND) return SKILL_RANGE_NONE; } } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index ccb3884b163..4a35f98b679 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -264,8 +264,6 @@ typedef std::list CacheNpcOptionList; typedef UNORDERED_MAP CacheVendorItemMap; typedef UNORDERED_MAP CacheTrainerSpellMap; -typedef std::list AchievementCriteriaEntryList; - enum SkillRangeType { SKILL_RANGE_LANGUAGE, // 300..300 @@ -590,7 +588,6 @@ class ObjectMgr void LoadNpcTextId(); void LoadVendors(); void LoadTrainerSpell(); - void LoadCompletedAchievements(); std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint32 level); @@ -804,10 +801,6 @@ class ObjectMgr bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const; - void LoadAchievementCriteriaList(); - AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type); - std::set allCompletedAchievements; - void LoadScriptNames(); ScriptNameMap &GetScriptNames() { return m_scriptNames; } const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; } @@ -826,7 +819,6 @@ class ObjectMgr uint32 m_hiCharGuid; uint32 m_hiCreatureGuid; uint32 m_hiPetGuid; - uint32 m_hiVehicleGuid; uint32 m_hiItemGuid; uint32 m_hiGoGuid; uint32 m_hiDoGuid; @@ -937,9 +929,6 @@ class ObjectMgr CacheNpcTextIdMap m_mCacheNpcTextIdMap; CacheVendorItemMap m_mCacheVendorItemMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap; - - // store achievement criterias by type to speed up lookup - AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; }; #define objmgr Trinity::Singleton::Instance() diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index 2120c5dae70..57c3c0ca879 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -28,1194 +28,1064 @@ /// Correspondence between opcodes and their names OpcodeHandler opcodeTable[NUM_MSG_TYPES] = { - /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode }, - /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL }, - /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x00D*/ { "CMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x00E*/ { "SMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x01E*/ { "SMSG_REFER_A_FRIEND_EXPIRED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode }, - /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode }, - /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode }, - /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode }, - /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode }, - /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode }, - /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode }, - /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode }, - /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery }, - /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode }, - /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode }, - /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode }, - /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode }, - /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode }, - /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode }, - /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode }, - /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode }, - /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode }, - /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode }, - /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode }, - /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode }, - /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode }, - /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode }, - /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode }, - /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated }, - /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode }, - /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode }, - /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode }, - /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode }, - /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode }, - /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode }, - /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode }, - /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode }, - /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode }, - /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode }, - /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode }, - /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode }, - /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode }, - /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode }, - /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode }, - /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode }, - /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode }, - /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode }, - /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode }, - /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode }, - /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode }, - /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin }, - /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave }, - /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList }, - /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword }, - /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner }, - /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner }, - /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator }, - /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator }, - /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute }, - /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute }, - /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite }, - /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick }, - /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan }, - /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban }, - /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce }, - /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate }, - /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode }, - /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode }, - /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem }, - /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode }, - /*0x0B2*/ { "CMSG_DESTROY_ITEMS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode }, - /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck }, - /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING,&WorldSession::HandleMoveWorldportAckOpcode}, - /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck }, - /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck }, - /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck }, - /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck }, - /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera }, - /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema }, - /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag }, - /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear }, - /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset }, - /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode }, - /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode }, - /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode }, - /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode }, - /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode }, - /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode }, - /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem }, - /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode }, - /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode }, - /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode }, - /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode }, - /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode }, - /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode }, - /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode }, - /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode }, - /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode }, - /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode }, - /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode }, - /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode }, - /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode }, - /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode }, - /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode }, - /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar }, - /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat }, - /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode }, - /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode }, - /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode }, - /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode }, - /*0x137*/ { "SMSG_UPDATE_AURA_DURATION_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling }, - /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode }, - /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode }, - /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode }, - /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode }, - /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x152*/ { "SMSG_BREAK_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode }, - /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode }, - /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode }, - /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode }, - /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode }, - /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode }, - /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode }, - /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode }, - /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction }, - /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction }, - /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon }, - /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename }, - /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode }, - /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode }, - /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode }, - /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode}, - /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode }, - /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode}, - /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch }, - /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode}, - /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete }, - /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode}, - /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode}, - /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel }, - /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest }, - /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest }, - /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept }, - /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty }, - /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode }, - /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode }, - /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode }, - /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode }, - /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode }, - /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes }, - /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode }, - /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode }, - /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode }, - /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode }, - /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode }, - /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode }, - /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode }, - /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode }, - /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode }, - /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode }, - /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode }, - /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode }, - /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode }, - /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode }, - /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode }, - /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime }, - /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode }, - /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode }, - /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode }, - /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode }, - /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, - /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode }, - /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, - /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode }, - /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode }, - /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode}, - /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode }, - /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode }, - /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup }, - /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode }, - /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode }, - /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode }, - /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode }, - /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData }, - /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, &WorldSession::HandleUpdateAccountData }, - /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode }, - /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode }, - /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode }, - /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode}, - /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, - /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode }, - /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode }, - /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode }, - /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode }, - /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode }, - /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode }, - /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail }, - /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail }, - /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode }, - /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery }, - /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney }, - /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem }, - /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead }, - /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender }, - /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete }, - /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem }, - /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode }, - /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP }, - /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode }, - /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem }, - /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem }, - /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems }, - /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems }, - /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid }, - /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems }, - /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode }, - /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode }, - /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode }, - /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode}, - /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode }, - /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet }, - /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet }, - /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot }, - /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet }, - /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet }, - /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult }, - /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode }, - /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode }, - /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode }, - /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode}, - /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode }, - /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode }, - /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime }, - /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode }, - /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode }, - /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem }, - /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo }, - /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode }, - /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll }, - /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode }, - /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode }, - /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode }, - /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode }, - /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode }, - /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2B9*/ { "CMSG_SHOWING_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode }, - /*0x2BA*/ { "CMSG_SHOWING_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode }, - /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar }, - /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode }, - /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode }, - /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode }, - /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode }, - /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode }, - /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode }, - /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck }, - /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck }, - /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleMoveNotActiveMover }, - /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode }, - /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode}, - /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode }, - /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode }, - /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode}, - /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode }, - /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, - /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, - /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode }, - /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode}, - /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode }, - /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode }, - /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode }, - /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode }, - /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode }, - /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode}, - /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode}, - /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode }, - /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode }, - /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode }, - /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode }, - /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, &WorldSession::HandleGMSurveySubmit }, - /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode}, - /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode }, - /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode }, - /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode }, - /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode }, - /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode}, - /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode}, - /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode }, - /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode}, - /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode }, - /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode}, - /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin }, - /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode }, - /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode }, - /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode }, - /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode}, - /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode }, - /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode }, - /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode }, - /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode }, - /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode }, - /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode }, - /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode }, - /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode}, - /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, - /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode }, - /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode }, - /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode }, - /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleTimeSyncResp }, - /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide }, - /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, - /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode }, - /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3B2*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3B3*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3B4*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3B5*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3B6*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3B7*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3B8*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3B9*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3BA*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3BB*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3BC*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3BD*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3BE*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3BF*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3C0*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3C1*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3C3*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3C4*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3C5*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3C6*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode}, - /*0x3C7*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode }, - /*0x3C8*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3C9*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3CA*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3CB*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3CD*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3CF*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3D0*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3D1*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3D2*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery }, - /*0x3D3*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery }, - /*0x3D4*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery }, - /*0x3D5*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3D6*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode }, - /*0x3D7*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3D8*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3D9*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3DA*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3DB*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3DC*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3DD*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3DE*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3DF*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3E0*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3E1*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3E4*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK }, - /*0x3E5*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery }, - /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon }, - /*0x3E8*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3E9*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem }, - /*0x3EA*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab }, - /*0x3EB*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab }, - /*0x3EC*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit }, - /*0x3ED*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw }, - /*0x3EE*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog }, - /*0x3EF*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify }, - /*0x3F0*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3F1*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3F2*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3F3*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3F4*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3F5*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3F6*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3F7*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3F8*/ { "CMSG_SPELLCLICK", STATUS_LOGGEDIN, &WorldSession::HandleSpellClick }, - /*0x3F9*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3FA*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3FB*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x3FC*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x3FD*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights }, - /*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount }, - /*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode }, - /*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x406*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x407*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, - /*0x408*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x409*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode }, - /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText }, - /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText }, - /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x411*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x414*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy }, - /*0x415*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x416*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x417*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryMultipleOpcode}, - /*0x418*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x419*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode }, - /*0x41A*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x41B*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x41C*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x41D*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x424*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, &WorldSession::HandleAlterAppearance }, - /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x428*/ { "SMSG_BARBER_SHOP_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetCalendar }, - /*0x42A*/ { "CMSG_CALENDAR_GET_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetEvent }, - /*0x42B*/ { "CMSG_CALENDAR_GUILD_FILTER", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGuildFilter }, - /*0x42C*/ { "CMSG_CALENDAR_ARENA_TEAM", STATUS_LOGGEDIN, &WorldSession::HandleCalendarArenaTeam }, - /*0x42D*/ { "CMSG_CALENDAR_ADD_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarAddEvent }, - /*0x42E*/ { "CMSG_CALENDAR_UPDATE_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarUpdateEvent }, - /*0x42F*/ { "CMSG_CALENDAR_REMOVE_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarRemoveEvent }, - /*0x430*/ { "CMSG_CALENDAR_COPY_EVENT", STATUS_LOGGEDIN, &WorldSession::HandleCalendarCopyEvent }, - /*0x431*/ { "CMSG_CALENDAR_EVENT_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventInvite }, - /*0x432*/ { "CMSG_CALENDAR_EVENT_RSVP", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRsvp }, - /*0x433*/ { "CMSG_CALENDAR_EVENT_REMOVE_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRemoveInvite }, - /*0x434*/ { "CMSG_CALENDAR_EVENT_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventStatus }, - /*0x435*/ { "CMSG_CALENDAR_EVENT_MODERATOR_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventModeratorStatus}, - /*0x436*/ { "SMSG_CALENDAR_SEND_CALENDAR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x437*/ { "SMSG_CALENDAR_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x438*/ { "SMSG_CALENDAR_FILTER_GUILD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x439*/ { "SMSG_CALENDAR_ARENA_TEAM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x43A*/ { "SMSG_CALENDAR_EVENT_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x43B*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x43C*/ { "SMSG_CALENDAR_EVENT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x43D*/ { "SMSG_CALENDAR_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x43E*/ { "SMSG_CALENDAR_RAID_LOCKOUT_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x43F*/ { "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x440*/ { "SMSG_CALENDAR_EVENT_INVITE_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x441*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x442*/ { "SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x443*/ { "SMSG_CALENDAR_EVENT_REMOVED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x444*/ { "SMSG_CALENDAR_EVENT_UPDATED_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x445*/ { "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x446*/ { "CMSG_CALENDAR_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleCalendarComplain }, - /*0x447*/ { "CMSG_CALENDAR_GET_NUM_PENDING", STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetNumPending }, - /*0x448*/ { "SMSG_CALENDAR_SEND_NUM_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x449*/ { "CMSG_SAVE_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x44A*/ { "SMSG_NOTIFY_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x44B*/ { "CMSG_PLAY_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x44C*/ { "SMSG_PLAY_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x44D*/ { "CMSG_LOAD_DANCES", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x44E*/ { "CMSG_STOP_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x44F*/ { "SMSG_STOP_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x450*/ { "CMSG_SYNC_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x451*/ { "CMSG_DANCE_QUERY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x452*/ { "SMSG_DANCE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x453*/ { "SMSG_INVALIDATE_DANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x454*/ { "CMSG_DELETE_DANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x455*/ { "SMSG_LEARNED_DANCE_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x456*/ { "CMSG_LEARN_DANCE_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x457*/ { "CMSG_UNLEARN_DANCE_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x458*/ { "CMSG_SET_RUNE_COUNT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x459*/ { "CMSG_SET_RUNE_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x45A*/ { "MSG_MOVE_SET_PITCH_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x45B*/ { "MSG_MOVE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x45C*/ { "SMSG_FORCE_PITCH_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x466*/ { "CMSG_SET_GLYPH_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x467*/ { "CMSG_SET_GLYPH", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x468*/ { "SMSG_ACHIEVEMENT_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x469*/ { "SMSG_DYNAMIC_DROP_ROLL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x46A*/ { "SMSG_CRITERIA_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x46B*/ { "CMSG_QUERY_INSPECT_ACHIEVEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleInspectAchievements }, - /*0x46C*/ { "SMSG_RESPOND_INSPECT_ACHIEVEMENTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x46D*/ { "CMSG_DISMISS_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, &WorldSession::HandleDismissControlledVehicle }, - /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize }, - /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x47A*/ { "CMSG_PET_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent }, - /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x47C*/ { "SMSG_SET_PHASE_SHIFT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x47D*/ { "SMSG_ALL_ACHIEVEMENT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x47E*/ { "CMSG_FORCE_SAY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x47F*/ { "SMSG_HEALTH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x480*/ { "SMSG_POWER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x481*/ { "CMSG_GAMEOBJ_REPORT_USE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x482*/ { "SMSG_HIGHEST_THREAT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x483*/ { "SMSG_THREAT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x484*/ { "SMSG_THREAT_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x485*/ { "SMSG_THREAT_CLEAR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x486*/ { "SMSG_CONVERT_RUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x487*/ { "SMSG_RESYNC_RUNES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x488*/ { "SMSG_ADD_RUNE_POWER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x489*/ { "CMSG_START_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x48A*/ { "CMSG_REMOVE_GLYPH", STATUS_LOGGEDIN, &WorldSession::HandleRemoveGlyph }, - /*0x48B*/ { "CMSG_DUMP_OBJECTS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x48C*/ { "SMSG_DUMP_OBJECTS_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x48D*/ { "CMSG_DISMISS_CRITTER", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x48E*/ { "SMSG_NOTIFY_DEST_LOC_SPELL_CAST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x48F*/ { "CMSG_AUCTION_LIST_PENDING_SALES", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListPendingSales }, - /*0x490*/ { "SMSG_AUCTION_LIST_PENDING_SALES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x491*/ { "SMSG_MODIFY_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x492*/ { "SMSG_PET_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x493*/ { "CMSG_ENABLETAXI", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes }, - /*0x494*/ { "SMSG_PRE_RESURRECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x495*/ { "SMSG_AURA_UPDATE_ALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x496*/ { "SMSG_AURA_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x497*/ { "CMSG_FLOOD_GRACE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4A0*/ { "CMSG_SERVER_INFO_QUERY", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4A1*/ { "SMSG_SERVER_INFO_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4A2*/ { "CMSG_CHECK_LOGIN_CRITERIA", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4A5*/ { "SMSG_PET_GUIDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode }, + /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL }, + /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00D*/ { "CMSG_EMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00E*/ { "CMSG_UNEMBLAZON_TABARD_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x01E*/ { "SMSG_DEBUGINFOSPELLMISS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x032*/ { "CMSG_PVP_PORT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, &WorldSession::HandleCharCreateOpcode }, + /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, &WorldSession::HandleCharEnumOpcode }, + /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, &WorldSession::HandleCharDeleteOpcode }, + /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, &WorldSession::HandlePlayerLoginOpcode }, + /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode }, + /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode }, + /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode }, + /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode }, + /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery }, + /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, &WorldSession::HandleGuildQueryOpcode }, + /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode }, + /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode }, + /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode }, + /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode }, + /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode }, + /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode }, + /*0x063*/ { "SMSG_WHO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode }, + /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode }, + /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode }, + /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode }, + /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode }, + /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode }, + /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode }, + /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode }, + /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated }, + /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode }, + /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode }, + /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode }, + /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode }, + /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode }, + /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode }, + /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode }, + /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode }, + /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode }, + /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode }, + /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode }, + /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode }, + /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode }, + /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode }, + /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode }, + /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode }, + /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode }, + /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode }, + /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode }, + /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode }, + /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode }, + /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin }, + /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave }, + /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelList }, + /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword }, + /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner }, + /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner }, + /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator }, + /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator }, + /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelMute }, + /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute }, + /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite }, + /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, &WorldSession::HandleChannelKick }, + /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelBan }, + /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban }, + /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce }, + /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate }, + /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode }, + /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode }, + /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleReadItem }, + /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode }, + /*0x0B2*/ { "CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode }, + /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck }, + /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER_PENDING, &WorldSession::HandleMoveWorldportAckOpcode}, + /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck }, + /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck }, + /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck }, + /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck }, + /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera }, + /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema }, + /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag }, + /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear }, + /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset }, + /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode }, + /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode }, + /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode }, + /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode }, + /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode }, + /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode }, + /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapItem }, + /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode }, + /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode }, + /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode }, + /*0x110*/ { "OBSOLETE_DROP_ITEM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode }, + /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode }, + /*0x115*/ { "SMSG_INSPECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode }, + /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode }, + /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode }, + /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode }, + /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode }, + /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode }, + /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_AUTHED, &WorldSession::HandleCancelTradeOpcode }, + /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode }, + /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode }, + /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode }, + /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar }, + /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat }, + /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode }, + /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode }, + /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode }, + /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode }, + /*0x137*/ { "SMSG_UPDATE_AURA_DURATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling }, + /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode }, + /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE", STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode }, + /*0x13F*/ { "CMSG_UNUSED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x140*/ { "CMSG_UNUSED2", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode }, + /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode }, + /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14F*/ { "SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x152*/ { "CMSG_SHEATHE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode }, + /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode }, + /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode }, + /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode }, + /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode }, + /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode }, + /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode }, + /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode }, + /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction }, + /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, &WorldSession::HandlePetAction }, + /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon }, + /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetRename }, + /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode }, + /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode }, + /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode }, + /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode}, + /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode }, + /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode}, + /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch }, + /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode}, + /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete }, + /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode}, + /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode}, + /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel }, + /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest }, + /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest }, + /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept }, + /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty }, + /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode }, + /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode }, + /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode }, + /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode }, + /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode }, + /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodesOpcode}, + /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode }, + /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode }, + /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode }, + /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode }, + /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode }, + /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode }, + /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode }, + /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode }, + /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode }, + /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode }, + /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode }, + /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode }, + /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode }, + /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode }, + /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode }, + /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime }, + /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode }, + /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode }, + /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode }, + /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode }, + /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, + /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode }, + /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, + /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode }, + /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode }, + /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode}, + /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode }, + /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode }, + /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup }, + /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode }, + /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode }, + /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode }, + /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode }, + /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData }, + /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleUpdateAccountData }, + /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode }, + /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode }, + /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode }, + /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode}, + /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, + /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x21E*/ { "SMSG_SET_REST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode }, + /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode }, + /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode }, + /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode }, + /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode }, + /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode }, + /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, &WorldSession::HandleSendMail }, + /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, &WorldSession::HandleGetMail }, + /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode }, + /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery }, + /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney }, + /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleTakeItem }, + /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead }, + /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender }, + /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, &WorldSession::HandleMailDelete }, + /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem }, + /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode }, + /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP }, + /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode }, + /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem }, + /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem }, + /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems }, + /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems }, + /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid }, + /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems }, + /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode }, + /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode }, + /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode }, + /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode}, + /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode }, + /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStablePet }, + /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet }, + /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot }, + /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet }, + /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet }, + /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult }, + /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode }, + /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode }, + /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode }, + /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode}, + /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode }, + /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode }, + /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime }, + /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode }, + /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode }, + /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem }, + /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x292*/ { "CMSG_MEETINGSTONE_JOIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x296*/ { "CMSG_MEETINGSTONE_INFO", STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo }, + /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode }, + /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, &WorldSession::HandleLootRoll }, + /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode }, + /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode }, + /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode }, + /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode }, + /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode }, + /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2B9*/ { "CMSG_TOGGLE_HELM", STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode }, + /*0x2BA*/ { "CMSG_TOGGLE_CLOAK", STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode }, + /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, &WorldSession::HandleSetActionBar }, + /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode }, + /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode }, + /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, &WorldSession::HandleChangePlayerNameOpcode }, + /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode }, + /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode }, + /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode }, + /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck }, + /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck }, + /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, &WorldSession::HandleNotActiveMoverOpcode }, + /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode }, + /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode}, + /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode }, + /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode }, + /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck }, + /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode}, + /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode }, + /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, + /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, + /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode }, + /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS",STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode}, + /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode }, + /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode }, + /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode }, + /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode }, + /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode }, + /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode}, + /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode}, + /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode }, + /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode }, + /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode }, + /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode }, + /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, &WorldSession::HandleGMSurveySubmit }, + /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode}, + /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode }, + /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode }, + /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode }, + /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode }, + /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode}, + /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode}, + /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode }, + /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode}, + /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode }, + /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode}, + /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin }, + /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN", STATUS_AUTHED, &WorldSession::HandleLfgAutoJoinOpcode }, + /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode }, + /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL", STATUS_AUTHED, &WorldSession::HandleLfmAutoAddMembersOpcode }, + /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL", STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode}, + /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x361*/ { "CMSG_DECLINE_LFG_MATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x362*/ { "CMSG_CANCEL_PENDING_LFG", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode }, + /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode }, + /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode }, + /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode }, + /*0x367*/ { "SMSG_LFG_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36C*/ { "SMSG_LFG_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36D*/ { "SMSG_LFG_UPDATE_LFM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36E*/ { "SMSG_LFG_UPDATE_LFG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x370*/ { "SMSG_LFG_PENDING_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x371*/ { "SMSG_LFG_PENDING_MATCH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode }, + /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode }, + /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode }, + /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode}, + /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck }, + /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, &WorldSession::HandleSetTaxiBenchmarkOpcode }, + /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, &WorldSession::HandleRealmStateRequestOpcode }, + /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode }, + /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, &WorldSession::HandleAllowMoveAckOpcode }, + /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide}, + /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes }, + /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, &WorldSession::HandleVoiceSettingsOpcode }, + /*0x3B0*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B1*/ { "CMSG_GM_WHISPER", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B2*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B3*/ { "MSG_GM_GEARRATING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B4*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B5*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B6*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B7*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3B8*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3B9*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3BA*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3BB*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3BC*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3BD*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND",STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3BE*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3BF*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3C0*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C1*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3C3*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C4*/ { "SMSG_KICK_REASON", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C5*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode}, + /*0x3C6*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode }, + /*0x3C7*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C8*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3C9*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CA*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CB*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CD*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3CF*/ { "CMSG_TARGET_CAST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D0*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D1*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery }, + /*0x3D2*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, &WorldSession::HandleChannelVoiceChatQuery }, + /*0x3D3*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery }, + /*0x3D4*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3D5*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode }, + /*0x3D6*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D7*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3D8*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3D9*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3DA*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DB*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DC*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DD*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DE*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3DF*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E0*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E1*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E2*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E3*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK }, + /*0x3E4*/ { "CMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3E5*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery }, + /*0x3E6*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon }, + /*0x3E7*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3E8*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem }, + /*0x3E9*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab }, + /*0x3EA*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab }, + /*0x3EB*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit }, + /*0x3EC*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw }, + /*0x3ED*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog }, + /*0x3EE*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify }, + /*0x3EF*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F0*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F1*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F2*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3F3*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F4*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F5*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F6*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3F7*/ { "CMSG_SPELLCLICK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3F8*/ { "SMSG_LOOT_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3F9*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3FA*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x3FB*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x3FC*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights }, + /*0x3FD*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount }, + /*0x3FE*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode }, + /*0x3FF*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x400*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x401*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x402*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x403*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK",STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x404*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_NULL }, + /*0x405*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x406*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, &WorldSession::Handle_EarlyProccess }, + /*0x407*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x408*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode }, + /*0x409*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText }, + /*0x40A*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText }, + /*0x40B*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40C*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40D*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40E*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x410*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x411*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x412*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x413*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy }, + /*0x414*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x415*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x416*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY",STATUS_LOGGEDIN,&WorldSession::HandleQuestgiverStatusQueryMultipleOpcode}, + /*0x417*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x418*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, &WorldSession::HandleDeclinedPlayerNameOpcode }, + /*0x419*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT",STATUS_NEVER,&WorldSession::Handle_ServerSide }, + /*0x41A*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x41B*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x41C*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x41D*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x41E*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x41F*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x420*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x421*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x422*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x423*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, }; diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index 7bc3a7c0640..202166a57a0 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -49,8 +49,8 @@ enum Opcodes CMSG_ZONE_MAP = 0x00A, SMSG_ZONE_MAP = 0x00B, CMSG_DEBUG_CHANGECELLZONE = 0x00C, - CMSG_MOVE_CHARACTER_CHEAT = 0x00D, - SMSG_MOVE_CHARACTER_CHEAT = 0x00E, + CMSG_EMBLAZON_TABARD_OBSOLETE = 0x00D, + CMSG_UNEMBLAZON_TABARD_OBSOLETE = 0x00E, CMSG_RECHARGE = 0x00F, CMSG_LEARN_SPELL = 0x010, CMSG_CREATEMONSTER = 0x011, @@ -66,7 +66,7 @@ enum Opcodes SMSG_FORCEACTIONSHOW = 0x01B, CMSG_PETGODMODE = 0x01C, SMSG_PETGODMODE = 0x01D, - SMSG_REFER_A_FRIEND_EXPIRED = 0x01E, + SMSG_DEBUGINFOSPELLMISS_OBSOLETE = 0x01E, CMSG_WEATHER_SPEED_CHEAT = 0x01F, CMSG_UNDRESSPLAYER = 0x020, CMSG_BEASTMASTER = 0x021, @@ -86,7 +86,7 @@ enum Opcodes SMSG_DEBUG_AISTATE = 0x02F, CMSG_DISABLE_PVP_CHEAT = 0x030, CMSG_ADVANCE_SPAWN_TIME = 0x031, - SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x032, + CMSG_PVP_PORT_OBSOLETE = 0x032, CMSG_AUTH_SRP6_BEGIN = 0x033, CMSG_AUTH_SRP6_PROOF = 0x034, CMSG_AUTH_SRP6_RECODE = 0x035, @@ -214,7 +214,7 @@ enum Opcodes SMSG_READ_ITEM_FAILED = 0x0AF, SMSG_ITEM_COOLDOWN = 0x0B0, CMSG_GAMEOBJ_USE = 0x0B1, - CMSG_DESTROY_ITEMS = 0x0B2, + CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE = 0x0B2, SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3, CMSG_AREATRIGGER = 0x0B4, MSG_MOVE_START_FORWARD = 0x0B5, @@ -347,7 +347,7 @@ enum Opcodes SMSG_SPELL_COOLDOWN = 0x134, SMSG_COOLDOWN_EVENT = 0x135, CMSG_CANCEL_AURA = 0x136, - SMSG_UPDATE_AURA_DURATION_OBSOLETE = 0x137, + SMSG_UPDATE_AURA_DURATION = 0x137, SMSG_PET_CAST_FAILED = 0x138, MSG_CHANNEL_START = 0x139, MSG_CHANNEL_UPDATE = 0x13A, @@ -371,10 +371,10 @@ enum Opcodes SMSG_DAMAGE_DONE_OBSOLETE = 0x14C, SMSG_DAMAGE_TAKEN_OBSOLETE = 0x14D, SMSG_CANCEL_COMBAT = 0x14E, - SMSG_SPELLBREAKLOG = 0x14F, + SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE = 0x14F, SMSG_SPELLHEALLOG = 0x150, SMSG_SPELLENERGIZELOG = 0x151, - SMSG_BREAK_TARGET = 0x152, + CMSG_SHEATHE_OBSOLETE = 0x152, CMSG_SAVE_PLAYER = 0x153, CMSG_SETDEATHBINDPOINT = 0x154, SMSG_BINDPOINTUPDATE = 0x155, @@ -578,7 +578,7 @@ enum Opcodes SMSG_GMTICKET_SYSTEMSTATUS = 0x21B, CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C, CMSG_SET_STAT_CHEAT = 0x21D, - SMSG_SET_REST_START_OBSOLETE = 0x21E, + SMSG_SET_REST_START = 0x21E, CMSG_SKILL_BUY_STEP = 0x21F, CMSG_SKILL_BUY_RANK = 0x220, CMSG_XP_CHEAT = 0x221, @@ -733,8 +733,8 @@ enum Opcodes SMSG_SCRIPT_MESSAGE = 0x2B6, SMSG_DUEL_COUNTDOWN = 0x2B7, SMSG_AREA_TRIGGER_MESSAGE = 0x2B8, - CMSG_SHOWING_HELM = 0x2B9, - CMSG_SHOWING_CLOAK = 0x2BA, + CMSG_TOGGLE_HELM = 0x2B9, + CMSG_TOGGLE_CLOAK = 0x2BA, SMSG_MEETINGSTONE_JOINFAILED = 0x2BB, SMSG_PLAYER_SKINNED = 0x2BC, SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD, @@ -967,10 +967,10 @@ enum Opcodes SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0, CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1, SMSG_VOICE_SET_TALKER_MUTED = 0x3A2, - SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE = 0x3A3, - SMSG_SET_EXTRA_AURA_INFO_OBSOLETE = 0x3A4, - SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE = 0x3A5, - SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE = 0x3A6, + SMSG_INIT_EXTRA_AURA_INFO = 0x3A3, + SMSG_SET_EXTRA_AURA_INFO = 0x3A4, + SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE = 0x3A5, + SMSG_CLEAR_EXTRA_AURA_INFO = 0x3A6, MSG_MOVE_START_DESCEND = 0x3A7, CMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A8, SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A9, @@ -980,255 +980,127 @@ enum Opcodes MSG_MOVE_UPDATE_CAN_FLY = 0x3AD, MSG_RAID_READY_CHECK_CONFIRM = 0x3AE, CMSG_VOICE_SESSION_ENABLE = 0x3AF, - SMSG_VOICE_SESSION_ENABLE = 0x3B0, - SMSG_VOICE_PARENTAL_CONTROLS = 0x3B1, - CMSG_GM_WHISPER = 0x3B2, - SMSG_GM_MESSAGECHAT = 0x3B3, - MSG_GM_GEARRATING = 0x3B4, - CMSG_COMMENTATOR_ENABLE = 0x3B5, - SMSG_COMMENTATOR_STATE_CHANGED = 0x3B6, - CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B7, - SMSG_COMMENTATOR_MAP_INFO = 0x3B8, - CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9, - SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3BA, - SMSG_COMMENTATOR_PLAYER_INFO = 0x3BB, - CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BC, - CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BD, - CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BE, - SMSG_CLEAR_TARGET = 0x3BF, - CMSG_BOT_DETECTED = 0x3C0, - SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C1, - CMSG_CHEAT_PLAYER_LOGIN = 0x3C2, - CMSG_CHEAT_PLAYER_LOOKUP = 0x3C3, - SMSG_CHEAT_PLAYER_LOOKUP = 0x3C4, - SMSG_KICK_REASON = 0x3C5, - MSG_RAID_READY_CHECK_FINISHED = 0x3C6, - CMSG_COMPLAIN = 0x3C7, - SMSG_COMPLAIN_RESULT = 0x3C8, - SMSG_FEATURE_SYSTEM_STATUS = 0x3C9, - CMSG_GM_SHOW_COMPLAINTS = 0x3CA, - CMSG_GM_UNSQUELCH = 0x3CB, - CMSG_CHANNEL_SILENCE_VOICE = 0x3CC, - CMSG_CHANNEL_SILENCE_ALL = 0x3CD, - CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CE, - CMSG_CHANNEL_UNSILENCE_ALL = 0x3CF, - CMSG_TARGET_CAST = 0x3D0, - CMSG_TARGET_SCRIPT_CAST = 0x3D1, - CMSG_CHANNEL_DISPLAY_LIST = 0x3D2, - CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D3, - CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D4, - SMSG_CHANNEL_MEMBER_COUNT = 0x3D5, - CMSG_CHANNEL_VOICE_ON = 0x3D6, - CMSG_CHANNEL_VOICE_OFF = 0x3D7, - CMSG_DEBUG_LIST_TARGETS = 0x3D8, - SMSG_DEBUG_LIST_TARGETS = 0x3D9, - SMSG_AVAILABLE_VOICE_CHANNEL = 0x3DA, - CMSG_ADD_VOICE_IGNORE = 0x3DB, - CMSG_DEL_VOICE_IGNORE = 0x3DC, - CMSG_PARTY_SILENCE = 0x3DD, - CMSG_PARTY_UNSILENCE = 0x3DE, - MSG_NOTIFY_PARTY_SQUELCH = 0x3DF, - SMSG_COMSAT_RECONNECT_TRY = 0x3E0, - SMSG_COMSAT_DISCONNECT = 0x3E1, - SMSG_COMSAT_CONNECT_FAIL = 0x3E2, - SMSG_VOICE_CHAT_STATUS = 0x3E3, - CMSG_REPORT_PVP_AFK = 0x3E4, - CMSG_REPORT_PVP_AFK_RESULT = 0x3E5, - CMSG_GUILD_BANKER_ACTIVATE = 0x3E6, - CMSG_GUILD_BANK_QUERY_TAB = 0x3E7, - SMSG_GUILD_BANK_LIST = 0x3E8, - CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E9, - CMSG_GUILD_BANK_BUY_TAB = 0x3EA, - CMSG_GUILD_BANK_UPDATE_TAB = 0x3EB, - CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EC, - CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3ED, - MSG_GUILD_BANK_LOG_QUERY = 0x3EE, - CMSG_SET_CHANNEL_WATCH = 0x3EF, - SMSG_USERLIST_ADD = 0x3F0, - SMSG_USERLIST_REMOVE = 0x3F1, - SMSG_USERLIST_UPDATE = 0x3F2, - CMSG_CLEAR_CHANNEL_WATCH = 0x3F3, - SMSG_INSPECT_TALENT = 0x3F4, - SMSG_GOGOGO_OBSOLETE = 0x3F5, - SMSG_ECHO_PARTY_SQUELCH = 0x3F6, - CMSG_SET_TITLE_SUFFIX = 0x3F7, - CMSG_SPELLCLICK = 0x3F8, - SMSG_LOOT_LIST = 0x3F9, - CMSG_GM_CHARACTER_RESTORE = 0x3FA, - CMSG_GM_CHARACTER_SAVE = 0x3FB, - SMSG_VOICESESSION_FULL = 0x3FC, - MSG_GUILD_PERMISSIONS = 0x3FD, - MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FE, - MSG_GUILD_EVENT_LOG_QUERY = 0x3FF, - CMSG_MAELSTROM_RENAME_GUILD = 0x400, - CMSG_GET_MIRRORIMAGE_DATA = 0x401, - SMSG_MIRRORIMAGE_DATA = 0x402, - SMSG_FORCE_DISPLAY_UPDATE = 0x403, - SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x404, - CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405, - SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x406, - CMSG_KEEP_ALIVE = 0x407, - SMSG_RAID_READY_CHECK_ERROR = 0x408, - CMSG_OPT_OUT_OF_LOOT = 0x409, - MSG_QUERY_GUILD_BANK_TEXT = 0x40A, - CMSG_SET_GUILD_BANK_TEXT = 0x40B, - CMSG_SET_GRANTABLE_LEVELS = 0x40C, - CMSG_GRANT_LEVEL = 0x40D, - CMSG_REFER_A_FRIEND = 0x40E, - MSG_GM_CHANGE_ARENA_RATING = 0x40F, - CMSG_DECLINE_CHANNEL_INVITE = 0x410, - CMSG_GROUPACTION_THROTTLED = 0x411, - SMSG_OVERRIDE_LIGHT = 0x412, - SMSG_TOTEM_CREATED = 0x413, - CMSG_TOTEM_DESTROYED = 0x414, - CMSG_EXPIRE_RAID_INSTANCE = 0x415, - CMSG_NO_SPELL_VARIANCE = 0x416, - CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x417, - SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x418, - CMSG_SET_PLAYER_DECLINED_NAMES = 0x419, - SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x41A, - CMSG_QUERY_SERVER_BUCK_DATA = 0x41B, - CMSG_CLEAR_SERVER_BUCK_DATA = 0x41C, - SMSG_SERVER_BUCK_DATA = 0x41D, - SMSG_SEND_UNLEARN_SPELLS = 0x41E, - SMSG_PROPOSE_LEVEL_GRANT = 0x41F, - CMSG_ACCEPT_LEVEL_GRANT = 0x420, - SMSG_REFER_A_FRIEND_FAILURE = 0x421, - SMSG_SPLINE_MOVE_SET_FLYING = 0x422, - SMSG_SPLINE_MOVE_UNSET_FLYING = 0x423, - SMSG_SUMMON_CANCEL = 0x424, - CMSG_CHANGE_PERSONAL_ARENA_RATING = 0x425, - CMSG_ALTER_APPEARANCE = 0x426, - SMSG_ENABLE_BARBER_SHOP = 0x427, - SMSG_BARBER_SHOP_RESULT = 0x428, - CMSG_CALENDAR_GET_CALENDAR = 0x429, - CMSG_CALENDAR_GET_EVENT = 0x42A, - CMSG_CALENDAR_GUILD_FILTER = 0x42B, - CMSG_CALENDAR_ARENA_TEAM = 0x42C, - CMSG_CALENDAR_ADD_EVENT = 0x42D, - CMSG_CALENDAR_UPDATE_EVENT = 0x42E, - CMSG_CALENDAR_REMOVE_EVENT = 0x42F, - CMSG_CALENDAR_COPY_EVENT = 0x430, - CMSG_CALENDAR_EVENT_INVITE = 0x431, - CMSG_CALENDAR_EVENT_RSVP = 0x432, - CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x433, - CMSG_CALENDAR_EVENT_STATUS = 0x434, - CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x435, - SMSG_CALENDAR_SEND_CALENDAR = 0x436, - SMSG_CALENDAR_SEND_EVENT = 0x437, - SMSG_CALENDAR_FILTER_GUILD = 0x438, - SMSG_CALENDAR_ARENA_TEAM = 0x439, - SMSG_CALENDAR_EVENT_INVITE = 0x43A, - SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x43B, - SMSG_CALENDAR_EVENT_STATUS = 0x43C, - SMSG_CALENDAR_COMMAND_RESULT = 0x43D, - SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x43E, - SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x43F, - SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x440, - SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x441, - SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x442, - SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x443, - SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x444, - SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x445, - CMSG_CALENDAR_COMPLAIN = 0x446, - CMSG_CALENDAR_GET_NUM_PENDING = 0x447, - SMSG_CALENDAR_SEND_NUM_PENDING = 0x448, - CMSG_SAVE_DANCE = 0x449, - SMSG_NOTIFY_DANCE = 0x44A, - CMSG_PLAY_DANCE = 0x44B, - SMSG_PLAY_DANCE = 0x44C, - CMSG_LOAD_DANCES = 0x44D, - CMSG_STOP_DANCE = 0x44E, - SMSG_STOP_DANCE = 0x44F, - CMSG_SYNC_DANCE = 0x450, - CMSG_DANCE_QUERY = 0x451, - SMSG_DANCE_QUERY_RESPONSE = 0x452, - SMSG_INVALIDATE_DANCE = 0x453, - CMSG_DELETE_DANCE = 0x454, - SMSG_LEARNED_DANCE_MOVES = 0x455, - CMSG_LEARN_DANCE_MOVE = 0x456, - CMSG_UNLEARN_DANCE_MOVE = 0x457, - CMSG_SET_RUNE_COUNT = 0x458, - CMSG_SET_RUNE_COOLDOWN = 0x459, - MSG_MOVE_SET_PITCH_RATE_CHEAT = 0x45A, - MSG_MOVE_SET_PITCH_RATE = 0x45B, - SMSG_FORCE_PITCH_RATE_CHANGE = 0x45C, - CMSG_FORCE_PITCH_RATE_CHANGE_ACK = 0x45D, - SMSG_SPLINE_SET_PITCH_RATE = 0x45E, - SMSG_MOVE_ABANDON_TRANSPORT = 0x45F, - MSG_MOVE_ABANDON_TRANSPORT = 0x460, - CMSG_MOVE_ABANDON_TRANSPORT_ACK = 0x461, - CMSG_UPDATE_MISSILE_TRAJECTORY = 0x462, - SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x463, - SMSG_TRIGGER_MOVIE = 0x464, - CMSG_COMPLETE_MOVIE = 0x465, - CMSG_SET_GLYPH_SLOT = 0x466, - CMSG_SET_GLYPH = 0x467, - SMSG_ACHIEVEMENT_EARNED = 0x468, - SMSG_DYNAMIC_DROP_ROLL_RESULT = 0x469, - SMSG_CRITERIA_UPDATE = 0x46A, - CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x46B, - SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x46C, - CMSG_DISMISS_CONTROLLED_VEHICLE = 0x46D, - CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x46E, - SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x46F, - CMSG_SET_CRITERIA_CHEAT = 0x470, - SMSG_GROUP_SWAP_FAILED = 0x471, - CMSG_UNITANIMTIER_CHEAT = 0x472, - CMSG_CHAR_CUSTOMIZE = 0x473, - SMSG_CHAR_CUSTOMIZE = 0x474, - SMSG_PET_RENAMEABLE = 0x475, - CMSG_REQUEST_VEHICLE_EXIT = 0x476, - CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x477, - CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x478, - CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x479, - CMSG_PET_LEARN_TALENT = 0x47A, - CMSG_PET_UNLEARN_TALENTS = 0x47B, - SMSG_SET_PHASE_SHIFT = 0x47C, - SMSG_ALL_ACHIEVEMENT_DATA = 0x47D, - CMSG_FORCE_SAY_CHEAT = 0x47E, - SMSG_HEALTH_UPDATE = 0x47F, - SMSG_POWER_UPDATE = 0x480, - CMSG_GAMEOBJ_REPORT_USE = 0x481, - SMSG_HIGHEST_THREAT_UPDATE = 0x482, - SMSG_THREAT_UPDATE = 0x483, - SMSG_THREAT_REMOVE = 0x484, - SMSG_THREAT_CLEAR = 0x485, - SMSG_CONVERT_RUNE = 0x486, - SMSG_RESYNC_RUNES = 0x487, - SMSG_ADD_RUNE_POWER = 0x488, - CMSG_START_QUEST = 0x489, - CMSG_REMOVE_GLYPH = 0x48A, - CMSG_DUMP_OBJECTS = 0x48B, - SMSG_DUMP_OBJECTS_DATA = 0x48C, - CMSG_DISMISS_CRITTER = 0x48D, - SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x48E, - CMSG_AUCTION_LIST_PENDING_SALES = 0x48F, - SMSG_AUCTION_LIST_PENDING_SALES = 0x490, - SMSG_MODIFY_COOLDOWN = 0x491, - SMSG_PET_UPDATE_COMBO_POINTS = 0x492, - CMSG_ENABLETAXI = 0x493, - SMSG_PRE_RESURRECT = 0x494, - SMSG_AURA_UPDATE_ALL = 0x495, - SMSG_AURA_UPDATE = 0x496, - CMSG_FLOOD_GRACE_CHEAT = 0x497, - SMSG_SERVER_FIRST_ACHIEVEMENT = 0x498, - SMSG_PET_LEARNED_SPELL = 0x499, - SMSG_PET_REMOVED_SPELL = 0x49A, - CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x49B, - CMSG_HEARTH_AND_RESURRECT = 0x49C, - SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x49D, - SMSG_CRITERIA_DELETED = 0x49E, - SMSG_ACHIEVEMENT_DELETED = 0x49F, - CMSG_SERVER_INFO_QUERY = 0x4A0, - SMSG_SERVER_INFO_RESPONSE = 0x4A1, - CMSG_CHECK_LOGIN_CRITERIA = 0x4A2, - SMSG_SERVER_BUCK_DATA_START = 0x4A3, - CMSG_QUERY_VEHICLE_STATUS = 0x4A4, - SMSG_PET_GUIDS = 0x4A5, - NUM_MSG_TYPES = 0x4A6 + SMSG_VOICE_PARENTAL_CONTROLS = 0x3B0, + CMSG_GM_WHISPER = 0x3B1, + SMSG_GM_MESSAGECHAT = 0x3B2, + MSG_GM_GEARRATING = 0x3B3, + CMSG_COMMENTATOR_ENABLE = 0x3B4, + SMSG_COMMENTATOR_STATE_CHANGED = 0x3B5, + CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B6, + SMSG_COMMENTATOR_MAP_INFO = 0x3B7, + CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B8, + SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9, + SMSG_COMMENTATOR_PLAYER_INFO = 0x3BA, + CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BB, + CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BC, + CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BD, + SMSG_CLEAR_TARGET = 0x3BE, + CMSG_BOT_DETECTED = 0x3BF, + SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C0, + CMSG_CHEAT_PLAYER_LOGIN = 0x3C1, + CMSG_CHEAT_PLAYER_LOOKUP = 0x3C2, + SMSG_CHEAT_PLAYER_LOOKUP = 0x3C3, + SMSG_KICK_REASON = 0x3C4, + MSG_RAID_READY_CHECK_FINISHED = 0x3C5, + CMSG_COMPLAIN = 0x3C6, + SMSG_COMPLAIN_RESULT = 0x3C7, + SMSG_FEATURE_SYSTEM_STATUS = 0x3C8, + CMSG_GM_SHOW_COMPLAINTS = 0x3C9, + CMSG_GM_UNSQUELCH = 0x3CA, + CMSG_CHANNEL_SILENCE_VOICE = 0x3CB, + CMSG_CHANNEL_SILENCE_ALL = 0x3CC, + CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CD, + CMSG_CHANNEL_UNSILENCE_ALL = 0x3CE, + CMSG_TARGET_CAST = 0x3CF, + CMSG_TARGET_SCRIPT_CAST = 0x3D0, + CMSG_CHANNEL_DISPLAY_LIST = 0x3D1, + CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D2, + CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D3, + SMSG_CHANNEL_MEMBER_COUNT = 0x3D4, + CMSG_CHANNEL_VOICE_ON = 0x3D5, + CMSG_CHANNEL_VOICE_OFF = 0x3D6, + CMSG_DEBUG_LIST_TARGETS = 0x3D7, + SMSG_DEBUG_LIST_TARGETS = 0x3D8, + SMSG_AVAILABLE_VOICE_CHANNEL = 0x3D9, + CMSG_ADD_VOICE_IGNORE = 0x3DA, + CMSG_DEL_VOICE_IGNORE = 0x3DB, + CMSG_PARTY_SILENCE = 0x3DC, + CMSG_PARTY_UNSILENCE = 0x3DD, + MSG_NOTIFY_PARTY_SQUELCH = 0x3DE, + SMSG_COMSAT_RECONNECT_TRY = 0x3DF, + SMSG_COMSAT_DISCONNECT = 0x3E0, + SMSG_COMSAT_CONNECT_FAIL = 0x3E1, + SMSG_VOICE_CHAT_STATUS = 0x3E2, + CMSG_REPORT_PVP_AFK = 0x3E3, + CMSG_REPORT_PVP_AFK_RESULT = 0x3E4, + CMSG_GUILD_BANKER_ACTIVATE = 0x3E5, + CMSG_GUILD_BANK_QUERY_TAB = 0x3E6, + SMSG_GUILD_BANK_LIST = 0x3E7, + CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E8, + CMSG_GUILD_BANK_BUY_TAB = 0x3E9, + CMSG_GUILD_BANK_UPDATE_TAB = 0x3EA, + CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EB, + CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3EC, + MSG_GUILD_BANK_LOG_QUERY = 0x3ED, + CMSG_SET_CHANNEL_WATCH = 0x3EE, + SMSG_USERLIST_ADD = 0x3EF, + SMSG_USERLIST_REMOVE = 0x3F0, + SMSG_USERLIST_UPDATE = 0x3F1, + CMSG_CLEAR_CHANNEL_WATCH = 0x3F2, + SMSG_INSPECT_TALENT = 0x3F3, + SMSG_GOGOGO_OBSOLETE = 0x3F4, + SMSG_ECHO_PARTY_SQUELCH = 0x3F5, + CMSG_SET_TITLE_SUFFIX = 0x3F6, + CMSG_SPELLCLICK = 0x3F7, + SMSG_LOOT_LIST = 0x3F8, + CMSG_GM_CHARACTER_RESTORE = 0x3F9, + CMSG_GM_CHARACTER_SAVE = 0x3FA, + SMSG_VOICESESSION_FULL = 0x3FB, + MSG_GUILD_PERMISSIONS = 0x3FC, + MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FD, + MSG_GUILD_EVENT_LOG_QUERY = 0x3FE, + CMSG_MAELSTROM_RENAME_GUILD = 0x3FF, + CMSG_GET_MIRRORIMAGE_DATA = 0x400, + SMSG_MIRRORIMAGE_DATA = 0x401, + SMSG_FORCE_DISPLAY_UPDATE = 0x402, + SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x403, + CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x404, + SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405, + CMSG_KEEP_ALIVE = 0x406, + SMSG_RAID_READY_CHECK_ERROR = 0x407, + CMSG_OPT_OUT_OF_LOOT = 0x408, + MSG_QUERY_GUILD_BANK_TEXT = 0x409, + CMSG_SET_GUILD_BANK_TEXT = 0x40A, + CMSG_SET_GRANTABLE_LEVELS = 0x40B, + CMSG_GRANT_LEVEL = 0x40C, + CMSG_REFER_A_FRIEND = 0x40D, + MSG_GM_CHANGE_ARENA_RATING = 0x40E, + CMSG_DECLINE_CHANNEL_INVITE = 0x40F, + CMSG_GROUPACTION_THROTTLED = 0x410, + SMSG_OVERRIDE_LIGHT = 0x411, + SMSG_TOTEM_CREATED = 0x412, + CMSG_TOTEM_DESTROYED = 0x413, + CMSG_EXPIRE_RAID_INSTANCE = 0x414, + CMSG_NO_SPELL_VARIANCE = 0x415, + CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x416, + SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x417, + CMSG_SET_PLAYER_DECLINED_NAMES = 0x418, + SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x419, + CMSG_QUERY_SERVER_BUCK_DATA = 0x41A, + CMSG_CLEAR_SERVER_BUCK_DATA = 0x41B, + SMSG_SERVER_BUCK_DATA = 0x41C, + SMSG_SEND_UNLEARN_SPELLS = 0x41D, + SMSG_PROPOSE_LEVEL_GRANT = 0x41E, + CMSG_ACCEPT_LEVEL_GRANT = 0x41F, + SMSG_REFER_A_FRIEND_FAILURE = 0x420, + SMSG_SPLINE_MOVE_SET_FLYING = 0x421, + SMSG_SPLINE_MOVE_UNSET_FLYING = 0x422, + SMSG_SUMMON_CANCEL = 0x423 }; +// Don't forget to change this value and add opcode name to Opcodes.cpp when you add new opcode! +#define NUM_MSG_TYPES 0x424 + /// Player state enum SessionStatus { diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index d56ae59158e..836ee6d8459 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -41,6 +41,27 @@ char const* petTypeSuffix[MAX_PET_TYPE] = "'s Companion" // MINI_PET }; +//numbers represent minutes * 100 while happy (you get 100 loyalty points per min while happy) +uint32 const LevelUpLoyalty[6] = +{ + 5500, + 11500, + 17000, + 23500, + 31000, + 39500, +}; + +uint32 const LevelStartLoyalty[6] = +{ + 2000, + 4500, + 7000, + 10000, + 13500, + 17500, +}; + Pet::Pet(PetType type) : Creature() { m_isPet = true; @@ -50,16 +71,17 @@ Pet::Pet(PetType type) : Creature() m_removed = false; m_regenTimer = 4000; m_happinessTimer = 7500; + m_loyaltyTimer = 12000; m_duration = 0; m_bonusdamage = 0; + m_loyaltyPoints = 0; + m_TrainingPoints = 0; m_resetTalentsCost = 0; m_resetTalentsTime = 0; m_auraUpdateMask = 0; - m_loading = false; - // pets always have a charminfo, even if they are not actually charmed CharmInfo* charmInfo = InitCharmInfo(this); @@ -106,26 +128,24 @@ void Pet::RemoveFromWorld() bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current ) { - m_loading = true; - uint32 ownerid = owner->GetGUIDLow(); QueryResult *result; if(petnumber) - // known petnumber entry 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber); + // known petnumber entry 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber); else if(current) - // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid ); + // current pet (slot 0) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid ); else if(petentry) // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) - // 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry ); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry ); else // any current or other non-stabled pet (for hunter "call pet") - // 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid); if(!result) return false; @@ -140,7 +160,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu return false; } - uint32 summon_spell_id = fields[19].GetUInt32(); + uint32 summon_spell_id = fields[21].GetUInt32(); SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id); bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0; @@ -174,8 +194,8 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu return false; } - setPetType(PetType(fields[20].GetUInt8())); - SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction()); + setPetType(PetType(fields[22].GetUInt8())); + SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id); CreatureInfo const *cinfo = GetCreatureInfo(); @@ -186,67 +206,72 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu delete result; return true; } - - if(getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK)) + if(getPetType()==HUNTER_PET || (getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK)) m_charmInfo->SetPetNumber(pet_number, true); else m_charmInfo->SetPetNumber(pet_number, false); - - SetOwnerGUID(owner->GetGUID()); + SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()); SetDisplayId(fields[3].GetUInt32()); SetNativeDisplayId(fields[3].GetUInt32()); - uint32 petlevel = fields[4].GetUInt32(); - SetUInt32Value(UNIT_NPC_FLAGS, 0); - SetName(fields[9].GetString()); + uint32 petlevel=fields[4].GetUInt32(); + SetUInt32Value(UNIT_NPC_FLAGS , 0); + SetName(fields[11].GetString()); switch(getPetType()) { + case SUMMON_PET: petlevel=owner->getLevel(); - SetUInt32Value(UNIT_FIELD_BYTES_0, 2048); + SetUInt32Value(UNIT_FIELD_BYTES_0,2048); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet dismiss, cancel) break; case HUNTER_PET: SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); - SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32()); - SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED); + SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[8].GetUInt32()); + SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); + + if(fields[12].GetBool()) + SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED); + else + SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet abandon, cancel) - SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); - SetPower(POWER_HAPPINESS, fields[13].GetUInt32()); + SetTP(fields[9].GetInt32()); + SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); + SetPower( POWER_HAPPINESS,fields[15].GetUInt32()); setPowerType(POWER_FOCUS); break; default: - sLog.outError("Pet have incorrect type (%u) for pet loading.", getPetType()); + sLog.outError("Pet have incorrect type (%u) for pet loading.",getPetType()); } - - InitStatsForLevel(petlevel); + InitStatsForLevel( petlevel); SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32()); - SetCreatorGUID(owner->GetGUID()); + SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID()); - m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8())); + m_charmInfo->SetReactState( ReactStates( fields[6].GetUInt8() )); + m_loyaltyPoints = fields[7].GetInt32(); - uint32 savedhealth = fields[11].GetUInt32(); - uint32 savedmana = fields[12].GetUInt32(); + uint32 savedhealth = fields[13].GetUInt32(); + uint32 savedmana = fields[14].GetUInt32(); // set current pet as current - if(fields[8].GetUInt32() != 0) + if(fields[10].GetUInt32() != 0) { CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'", ownerid, m_charmInfo->GetPetNumber()); - CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'", ownerid, m_charmInfo->GetPetNumber()); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'",ownerid, m_charmInfo->GetPetNumber()); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'",ownerid, m_charmInfo->GetPetNumber()); CharacterDatabase.CommitTransaction(); } if(!is_temporary_summoned) { // permanent controlled pets store state in DB - Tokens tokens = StrSplit(fields[14].GetString(), " "); + Tokens tokens = StrSplit(fields[16].GetString(), " "); if(tokens.size() != 20) { @@ -265,11 +290,11 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu // patch for old data where some spells have ACT_DECIDE but should have ACT_CAST // so overwrite old state SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction); - if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_ENABLED; + if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST; } //init teach spells - tokens = StrSplit(fields[15].GetString(), " "); + tokens = StrSplit(fields[17].GetString(), " "); for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index) { uint32 tmp = atol((*iter).c_str()); @@ -284,10 +309,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu } // since last save (in seconds) - uint32 timediff = (time(NULL) - fields[16].GetUInt32()); - - m_resetTalentsCost = fields[17].GetUInt32(); - m_resetTalentsTime = fields[18].GetUInt64(); + uint32 timediff = (time(NULL) - fields[18].GetUInt32()); delete result; @@ -353,7 +375,6 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu } } - m_loading = false; return true; } @@ -396,6 +417,10 @@ void Pet::SavePetToDB(PetSaveMode mode) case PET_SAVE_IN_STABLE_SLOT_2: case PET_SAVE_NOT_IN_SLOT: { + uint32 loyalty =1; + if(getPetType()!=HUNTER_PET) + loyalty = GetLoyaltyLevel(); + uint32 owner = GUID_LOPART(GetOwnerGUID()); std::string name = m_name; CharacterDatabase.escape_string(name); @@ -412,7 +437,7 @@ void Pet::SavePetToDB(PetSaveMode mode) CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner ); // save pet std::ostringstream ss; - ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) " + ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata,TeachSpelldata,savetime,resettalents_cost,resettalents_time,CreatedBySpell,PetType) " << "VALUES (" << m_charmInfo->GetPetNumber() << ", " << GetEntry() << ", " @@ -421,7 +446,9 @@ void Pet::SavePetToDB(PetSaveMode mode) << getLevel() << ", " << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", " << uint32(m_charmInfo->GetReactState()) << ", " - << uint32(GetFreeTalentPoints()) << ", " + << m_loyaltyPoints << ", " + << GetLoyaltyLevel() << ", " + << m_TrainingPoints << ", " << uint32(mode) << ", '" << name.c_str() << "', " << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", " @@ -494,12 +521,12 @@ void Pet::setDeathState(DeathState s) // overwrite virtual if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND)) ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); } } else if(getDeathState()==ALIVE) { - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); CastPetAuras(true); } } @@ -526,7 +553,6 @@ void Pet::Update(uint32 diff) // unsummon pet that lost owner Unit* owner = GetOwner(); if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID()) - //if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID())) { Remove(PET_SAVE_NOT_IN_SLOT, true); return; @@ -572,6 +598,14 @@ void Pet::Update(uint32 diff) else m_happinessTimer -= diff; + if(m_loyaltyTimer <= diff) + { + TickLoyaltyChange(); + m_loyaltyTimer = 12000; + } + else + m_loyaltyTimer -= diff; + break; } default: @@ -603,12 +637,83 @@ void Pet::LooseHappiness() uint32 curValue = GetPower(POWER_HAPPINESS); if (curValue <= 0) return; - int32 addvalue = 670; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs) + int32 addvalue = (140 >> GetLoyaltyLevel()) * 125; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs) if(isInCombat()) //we know in combat happiness fades faster, multiplier guess addvalue = int32(addvalue * 1.5); ModifyPower(POWER_HAPPINESS, -addvalue); } +void Pet::ModifyLoyalty(int32 addvalue) +{ + uint32 loyaltylevel = GetLoyaltyLevel(); + + if(addvalue > 0) //only gain influenced, not loss + addvalue = int32((float)addvalue * sWorld.getRate(RATE_LOYALTY)); + + if(loyaltylevel >= BEST_FRIEND && (addvalue + m_loyaltyPoints) > int32(GetMaxLoyaltyPoints(loyaltylevel))) + return; + + m_loyaltyPoints += addvalue; + + if(m_loyaltyPoints < 0) + { + if(loyaltylevel > REBELLIOUS) + { + //level down + --loyaltylevel; + SetLoyaltyLevel(LoyaltyLevel(loyaltylevel)); + m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel); + SetTP(m_TrainingPoints - int32(getLevel())); + } + else + { + m_loyaltyPoints = 0; + Unit* owner = GetOwner(); + if(owner && owner->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_PET_BROKEN, 0); + ((Player*)owner)->GetSession()->SendPacket(&data); + + //run away + ((Player*)owner)->RemovePet(this,PET_SAVE_AS_DELETED); + } + } + } + //level up + else if(m_loyaltyPoints > int32(GetMaxLoyaltyPoints(loyaltylevel))) + { + ++loyaltylevel; + SetLoyaltyLevel(LoyaltyLevel(loyaltylevel)); + m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel); + SetTP(m_TrainingPoints + getLevel()); + } +} + +void Pet::TickLoyaltyChange() +{ + int32 addvalue; + + switch(GetHappinessState()) + { + case HAPPY: addvalue = 20; break; + case CONTENT: addvalue = 10; break; + case UNHAPPY: addvalue = -20; break; + default: + return; + } + ModifyLoyalty(addvalue); +} + +void Pet::KillLoyaltyBonus(uint32 level) +{ + if(level > 100) + return; + + //at lower levels gain is faster | the lower loyalty the more loyalty is gained + uint32 bonus = uint32(((100 - level) / 10) + (6 - GetLoyaltyLevel())); + ModifyLoyalty(bonus); +} + HappinessState Pet::GetHappinessState() { if(GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE) @@ -619,6 +724,11 @@ HappinessState Pet::GetHappinessState() return CONTENT; } +void Pet::SetLoyaltyLevel(LoyaltyLevel level) +{ + SetByteValue(UNIT_FIELD_BYTES_1, 1, level); +} + bool Pet::CanTakeMoreActiveSpells(uint32 spellid) { uint8 activecount = 1; @@ -655,6 +765,82 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid) return true; } +bool Pet::HasTPForSpell(uint32 spellid) +{ + int32 neededtrainp = GetTPForSpell(spellid); + if((m_TrainingPoints - neededtrainp < 0 || neededtrainp < 0) && neededtrainp != 0) + return false; + return true; +} + +int32 Pet::GetTPForSpell(uint32 spellid) +{ + uint32 basetrainp = 0; + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid); + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + if(!_spell_idx->second->reqtrainpoints) + return 0; + + basetrainp = _spell_idx->second->reqtrainpoints; + break; + } + + uint32 spenttrainp = 0; + uint32 chainstart = spellmgr.GetFirstSpellInChain(spellid); + + for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + + if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) + { + SkillLineAbilityMap::const_iterator _lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first); + SkillLineAbilityMap::const_iterator _upper = spellmgr.GetEndSkillLineAbilityMap(itr->first); + + for(SkillLineAbilityMap::const_iterator _spell_idx2 = _lower; _spell_idx2 != _upper; ++_spell_idx2) + { + if(_spell_idx2->second->reqtrainpoints > spenttrainp) + { + spenttrainp = _spell_idx2->second->reqtrainpoints; + break; + } + } + } + } + + return int32(basetrainp) - int32(spenttrainp); +} + +uint32 Pet::GetMaxLoyaltyPoints(uint32 level) +{ + return LevelUpLoyalty[level - 1]; +} + +uint32 Pet::GetStartLoyaltyPoints(uint32 level) +{ + return LevelStartLoyalty[level - 1]; +} + +void Pet::SetTP(int32 TP) +{ + m_TrainingPoints = TP; + SetUInt32Value(UNIT_TRAINING_POINTS, (uint32)GetDispTP()); +} + +int32 Pet::GetDispTP() +{ + if(getPetType()!= HUNTER_PET) + return(0); + if(m_TrainingPoints < 0) + return -m_TrainingPoints; + else + return -(m_TrainingPoints + 1); +} + void Pet::Remove(PetSaveMode mode, bool returnreagent) { Unit* owner = GetOwner(); @@ -717,6 +903,9 @@ void Pet::GivePetXP(uint32 xp) } SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP); + + if(getPetType() == HUNTER_PET) + KillLoyaltyBonus(level); } void Pet::GivePetLevel(uint32 level) @@ -724,7 +913,9 @@ void Pet::GivePetLevel(uint32 level) if(!level) return; - InitStatsForLevel(level); + InitStatsForLevel( level); + + SetTP(m_TrainingPoints + (GetLoyaltyLevel() - 1)); } bool Pet::CreateBaseAtCreature(Creature* creature) @@ -782,12 +973,16 @@ bool Pet::CreateBaseAtCreature(Creature* creature) else SetName(creature->GetName()); + m_loyaltyPoints = 1000; if(cinfo->type == CREATURE_TYPE_BEAST) { SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); - SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED)); + + SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) ); + SetLoyaltyLevel(REBELLIOUS); } return true; } @@ -917,7 +1112,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel) case HUNTER_PET: { SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(petlevel))/4)); - learnLevelupSpells(); + //these formula may not be correct; however, it is designed to be close to what it should be //this makes dps 0.5 of pets level SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); @@ -1128,6 +1323,10 @@ void Pet::_LoadAuras(uint32 timediff) for (int i = 0; i < TOTAL_AURAS; i++) m_modAuras[i].clear(); + // all aura related fields + for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) + SetUInt32Value(i, 0); + QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); if(result) @@ -1268,7 +1467,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s // same spells don't have autocast option if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) - active = ACT_ENABLED; + active = ACT_CAST; PetSpellMap::iterator itr = m_spells.find(spell_id); if (itr != m_spells.end()) @@ -1320,12 +1519,11 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s ToggleAutocast(itr->first, false); oldspell_id = itr->first; - unlearnSpell(itr->first); - break; + removeSpell(itr->first); } } - uint16 tmpslot = slot_id; + uint16 tmpslot=slot_id; if (tmpslot == 0xffff) { @@ -1359,65 +1557,20 @@ bool Pet::learnSpell(uint16 spell_id) if (!addSpell(spell_id)) return false; - if(GetOwner()->GetTypeId() == TYPEID_PLAYER) - { - if(!m_loading) - { - WorldPacket data(SMSG_PET_LEARNED_SPELL, 2); - data << uint16(spell_id); - ((Player*)GetOwner())->GetSession()->SendPacket(&data); - } - } - Unit* owner = GetOwner(); - if(owner->GetTypeId() == TYPEID_PLAYER) + if(owner->GetTypeId()==TYPEID_PLAYER) ((Player*)owner)->PetSpellInitialize(); return true; } -void Pet::learnLevelupSpells() -{ - PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family); - if(!levelupSpells) - return; - - uint32 level = getLevel(); - - for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr) - { - if(itr->first <= level) - learnSpell(itr->second); - else - unlearnSpell(itr->second); - } -} - -bool Pet::unlearnSpell(uint16 spell_id) -{ - if(removeSpell(spell_id)) - { - if(GetOwner()->GetTypeId() == TYPEID_PLAYER) - { - if(!m_loading) - { - WorldPacket data(SMSG_PET_REMOVED_SPELL, 2); - data << uint16(spell_id); - ((Player*)GetOwner())->GetSession()->SendPacket(&data); - } - } - return true; - } - return false; -} - -bool Pet::removeSpell(uint16 spell_id) +void Pet::removeSpell(uint16 spell_id) { PetSpellMap::iterator itr = m_spells.find(spell_id); if (itr == m_spells.end()) - return false; + return; if(itr->second->state == PETSPELL_REMOVED) - return false; + return; if(itr->second->state == PETSPELL_NEW) { @@ -1428,8 +1581,6 @@ bool Pet::removeSpell(uint16 spell_id) itr->second->state = PETSPELL_REMOVED; RemoveAurasDueToSpell(spell_id); - - return true; } bool Pet::_removeSpell(uint16 spell_id) @@ -1449,7 +1600,7 @@ void Pet::InitPetCreateSpells() m_charmInfo->InitPetActionBar(); m_spells.clear(); - int32 petspellid; + int32 usedtrainpoints = 0, petspellid; PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry()); if(CreateSpells) { @@ -1478,12 +1629,23 @@ void Pet::InitPetCreateSpells() petspellid = learn_spellproto->Id; addSpell(petspellid); + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]); + + for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) + { + usedtrainpoints += _spell_idx->second->reqtrainpoints; + break; + } } } LearnPetPassives(); CastPetAuras(false); + + SetTP(-usedtrainpoints); } void Pet::CheckLearning(uint32 spellid) @@ -1542,9 +1704,7 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) if(apply) { - for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++) - ; // just search - + for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++); if (i == m_autospells.size()) { m_autospells.push_back(spellid); @@ -1555,9 +1715,7 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) else { AutoSpellList::iterator itr2 = m_autospells.begin(); - for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++) - ; // just search - + for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++); if (i < m_autospells.size()) { m_autospells.erase(itr2); @@ -1580,7 +1738,8 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number) if(!InitEntry(Entry)) return false; - SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); + SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); if(getPetType() == MINI_PET) // always non-attackable SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); diff --git a/src/game/Pet.h b/src/game/Pet.h index 0082392400b..1057abc0edf 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -52,6 +52,16 @@ enum HappinessState HAPPY = 3 }; +enum LoyaltyLevel +{ + REBELLIOUS = 1, + UNRULY = 2, + SUBMISSIVE = 3, + DEPENDABLE = 4, + FAITHFUL = 5, + BEST_FRIEND = 6 +}; + enum PetSpellState { PETSPELL_UNCHANGED = 0, @@ -112,6 +122,9 @@ typedef std::vector AutoSpellList; #define HAPPINESS_LEVEL_SIZE 333000 +extern const uint32 LevelUpLoyalty[6]; +extern const uint32 LevelStartLoyalty[6]; + #define ACTIVE_SPELLS_MAX 4 #define OWNER_MAX_DISTANCE 100 @@ -154,7 +167,14 @@ class Pet : public Creature void RegenerateFocus(); void LooseHappiness(); + void TickLoyaltyChange(); + void ModifyLoyalty(int32 addvalue); HappinessState GetHappinessState(); + uint32 GetMaxLoyaltyPoints(uint32 level); + uint32 GetStartLoyaltyPoints(uint32 level); + void KillLoyaltyBonus(uint32 level); + uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } + void SetLoyaltyLevel(LoyaltyLevel level); void GivePetXP(uint32 xp); void GivePetLevel(uint32 level); bool InitStatsForLevel(uint32 level); @@ -174,8 +194,10 @@ class Pet : public Creature void UpdateAttackPowerAndDamage(bool ranged = false); void UpdateDamagePhysical(WeaponAttackType attType); - bool CanTakeMoreActiveSpells(uint32 SpellIconID); - void ToggleAutocast(uint32 spellid, bool apply); + bool CanTakeMoreActiveSpells(uint32 SpellIconID); + void ToggleAutocast(uint32 spellid, bool apply); + bool HasTPForSpell(uint32 spellid); + int32 GetTPForSpell(uint32 spellid); bool HasSpell(uint32 spell) const; void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; } @@ -193,9 +215,7 @@ class Pet : public Creature bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL); bool learnSpell(uint16 spell_id); - void learnLevelupSpells(); - bool unlearnSpell(uint16 spell_id); - bool removeSpell(uint16 spell_id); + void removeSpell(uint16 spell_id); bool _removeSpell(uint16 spell_id); PetSpellMap m_spells; @@ -205,10 +225,11 @@ class Pet : public Creature void InitPetCreateSpells(); void CheckLearning(uint32 spellid); uint32 resetTalentsCost() const; - uint8 GetMaxTalentPointsForLevel(uint32 level) { return (level >= 20) ? ((level - 16) / 4) : 0; } - uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } - void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); } + void SetTP(int32 TP); + int32 GetDispTP(); + + int32 m_TrainingPoints; uint32 m_resetTalentsCost; time_t m_resetTalentsTime; @@ -220,12 +241,14 @@ class Pet : public Creature bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved) protected: + uint32 m_regenTimer; uint32 m_happinessTimer; + uint32 m_loyaltyTimer; PetType m_petType; int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) + int32 m_loyaltyPoints; int32 m_bonusdamage; uint64 m_auraUpdateMask; - bool m_loading; DeclinedName *m_declinedname; diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index f059662987c..e4269ddafd6 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -174,9 +174,9 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) break; } break; - case ACT_DISABLED: // 0x8100 spell (disabled), ignore - case ACT_PASSIVE: // 0x0100 - case ACT_ENABLED: // 0xC100 spell + case ACT_DISABLED: //0x8100 spell (disabled), ignore + case ACT_CAST: //0x0100 + case ACT_ENABLED: //0xc100 spell { Unit* unit_target; if(guid2) @@ -257,7 +257,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) if(pet->isPossessed()) { WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); - data << uint8(0) << uint32(spellid) << uint8(result); + data << uint32(spellid) << uint8(2) << uint8(result); switch (result) { case SPELL_FAILED_REQUIRES_SPELL_FOCUS: @@ -369,7 +369,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state); //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add - if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) + if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id))) { //sign for autocast if(act_state == ACT_ENABLED && spell_id) @@ -542,10 +542,11 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket) { uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell ++itr; - //pet->removeSpell(spell_id); - pet->unlearnSpell(spell_id); + pet->removeSpell(spell_id); } + pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1)); + for(uint8 i = 0; i < 10; i++) { if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) @@ -615,15 +616,11 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) { sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL"); - CHECK_PACKET_SIZE(recvPacket,8+1+4+1); + CHECK_PACKET_SIZE(recvPacket,8+4); uint64 guid; uint32 spellid; - uint8 cast_count; - uint8 unk_flags; // flags (if 0x02 - some additional data are received) - recvPacket >> guid >> cast_count >> spellid >> unk_flags; - - sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags); + recvPacket >> guid >> spellid; // This opcode is also sent from charmed and possessed units (players and creatures) if(!_player->GetPet() && !_player->GetCharm()) @@ -658,7 +655,6 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) caster->clearUnitState(UNIT_STAT_FOLLOW); Spell *spell = new Spell(caster, spellInfo, false); - spell->m_cast_count = cast_count; // probably pending spell cast spell->m_targets = targets; int16 result = spell->PetCanCast(NULL); @@ -717,132 +713,3 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec data << uint8(0); SendPacket(&data); } - -void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data ) -{ - sLog.outDebug("WORLD: CMSG_PET_LEARN_TALENT"); - recv_data.hexlike(); - - CHECK_PACKET_SIZE(recv_data, 8+4+4); - - uint64 guid; - uint32 talent_id, requested_rank; - recv_data >> guid >> talent_id >> requested_rank; - - Pet *pet = _player->GetPet(); - - if(!pet) - return; - - if(guid != pet->GetGUID()) - return; - - uint32 CurTalentPoints = pet->GetFreeTalentPoints(); - - if(CurTalentPoints == 0) - return; - - if (requested_rank > 4) - return; - - TalentEntry const *talentInfo = sTalentStore.LookupEntry(talent_id); - - if(!talentInfo) - return; - - TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); - - if(!talentTabInfo) - return; - - CreatureInfo const *ci = pet->GetCreatureInfo(); - - if(!ci) - return; - - CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); - - if(!pet_family) - return; - - if(pet_family->petTalentType < 0) // not hunter pet - return; - - // prevent learn talent for different family (cheating) - if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)) - return; - - // prevent skip talent ranks (cheating) - if(requested_rank > 0 && !pet->HasSpell(talentInfo->RankID[requested_rank-1])) - return; - - // Check if it requires another talent - if (talentInfo->DependsOn > 0) - { - if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn)) - { - bool hasEnoughRank = false; - for (int i = talentInfo->DependsOnRank; i <= 4; i++) - { - if (depTalentInfo->RankID[i] != 0) - if (pet->HasSpell(depTalentInfo->RankID[i])) - hasEnoughRank = true; - } - if (!hasEnoughRank) - return; - } - } - - // Find out how many points we have in this field - uint32 spentPoints = 0; - - uint32 tTab = talentInfo->TalentTab; - if (talentInfo->Row > 0) - { - unsigned int numRows = sTalentStore.GetNumRows(); - for (unsigned int i = 0; i < numRows; i++) // Loop through all talents. - { - // Someday, someone needs to revamp - const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i); - if (tmpTalent) // the way talents are tracked - { - if (tmpTalent->TalentTab == tTab) - { - for (int j = 0; j <= 4; j++) - { - if (tmpTalent->RankID[j] != 0) - { - if (pet->HasSpell(tmpTalent->RankID[j])) - { - spentPoints += j + 1; - } - } - } - } - } - } - } - - // not have required min points spent in talent tree - if(spentPoints < (talentInfo->Row * 3)) - return; - - // spell not set in talent.dbc - uint32 spellid = talentInfo->RankID[requested_rank]; - if( spellid == 0 ) - { - sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank); - return; - } - - // already known - if(pet->HasSpell(spellid)) - return; - - // learn! (other talent ranks will unlearned at learning) - pet->learnSpell(spellid); - sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid); - - // update free talent points - pet->SetFreeTalentPoints(CurTalentPoints - 1); -} diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp index ad3893ce110..8fc18b1c259 100644 --- a/src/game/PetitionsHandler.cpp +++ b/src/game/PetitionsHandler.cpp @@ -199,9 +199,9 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) if(!charter) return; - charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow()); - // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id - // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item) + charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow()); + // ITEM_FIELD_ENCHANTMENT is guild/arenateam id + // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item) charter->SetState(ITEM_CHANGED, _player); _player->SendNewItem(charter, 1, true, false); @@ -565,7 +565,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) // update signs count on charter, required testing... //Item *item = _player->GetItemByGuid(petitionguid)); //if(item) - // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs); + // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs); // update for owner if online if(Player *owner = objmgr.GetPlayer(ownerguid)) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 712ecbc59ec..4b187023be4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -64,7 +64,6 @@ #include "Spell.h" #include "SocialMgr.h" #include "GameEvent.h" -#include "AchievementMgr.h" #include @@ -133,7 +132,7 @@ PlayerTaxi::PlayerTaxi() memset(m_taximask, 0, sizeof(m_taximask)); } -void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level) +void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level) { // capital and taxi hub masks switch(race) @@ -150,13 +149,6 @@ void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 leve case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei } - - switch(chrClass) - { - case CLASS_DEATH_KNIGHT: // TODO: figure out initial known nodes - break; - } - // new continent starting masks (It will be accessible only at new map) switch(Player::TeamForRace(race)) { @@ -259,7 +251,7 @@ const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3 UpdateMask Player::updateVisualBits; -Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) +Player::Player (WorldSession *session): Unit() { m_transport = 0; @@ -372,7 +364,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_canParry = false; m_canBlock = false; m_canDualWield = false; - m_canTitanGrip = false; m_ammoDPS = 0.0f; m_temporaryUnsummonedPetNumber = 0; @@ -417,9 +408,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_auraBaseMod[i][PCT_MOD] = 1.0f; } - for (int i = 0; i < MAX_COMBAT_RATING; i++) - m_baseRatingValue[i] = 0; - // Honor System m_lastHonorUpdateTime = time(NULL); @@ -433,8 +421,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) //Default movement to run mode m_unit_movement_flags = 0; - m_mover = NULL; - m_miniPet = 0; m_bgAfkReportedTimer = 0; m_contestedPvPTimer = 0; @@ -444,8 +430,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_isActive = true; m_farsightVision = false; - - m_runes = NULL; } Player::~Player () @@ -493,7 +477,6 @@ Player::~Player () RemovePossess(false); delete m_declinedname; - delete m_runes; } void Player::CleanupsBeforeDelete() @@ -539,9 +522,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 uint8 powertype = cEntry->powerType; - //uint32 unitfield; + uint32 unitfield; - /*switch(powertype) + switch(powertype) { case POWER_ENERGY: case POWER_MANA: @@ -550,16 +533,13 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 case POWER_RAGE: unitfield = 0x00110000; break; - case POWER_RUNIC_POWER: - unitfield = 0x0000EE00; //TODO: find correct unitfield here - break; default: sLog.outError("Invalid default powertype %u for player (class %u)",powertype,class_); return false; - }*/ + } - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); - SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); + SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH ); switch(gender) { @@ -582,14 +562,12 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 ); SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) ); - //SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP ); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); - SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER); + SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); + SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); + SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client - SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // default for players in 3.0.3 - // -1 is default value + //-1 is default value SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); @@ -601,35 +579,17 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 ); SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES, 0 ); // 0=disabled - SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES1, 0 ); // 0=disabled SetUInt32Value( PLAYER_CHOSEN_TITLE, 0 ); SetUInt32Value( PLAYER_FIELD_KILLS, 0 ); SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 ); SetUInt32Value( PLAYER_FIELD_TODAY_CONTRIBUTION, 0 ); SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 ); - for(uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i) - { - GlyphSlotEntry const * gs = sGlyphSlotStore.LookupEntry(i); - if(gs && gs->Order) - SetGlyphSlot(gs->Order - 1, gs->Id); - } - // set starting level - uint32 start_level = getClass() != CLASS_DEATH_KNIGHT - ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) - : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); - if (GetSession()->GetSecurity() >= SEC_MODERATOR) - { - uint32 gm_level = sWorld.getConfig(CONFIG_START_GM_LEVEL); - if(gm_level > start_level) - start_level = gm_level; - } - - SetUInt32Value(UNIT_FIELD_LEVEL, start_level); - - InitRunes(); + SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_GM_LEVEL)); + else + SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)); SetUInt32Value (PLAYER_FIELD_COINAGE, sWorld.getConfig(CONFIG_START_PLAYER_MONEY)); SetUInt32Value (PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_START_HONOR_POINTS)); @@ -693,7 +653,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 // base stats and related field values InitStatsForLevel(); InitTaxiNodesForLevel(); - InitGlyphsForLevel(); InitTalentForLevel(); InitPrimaryProffesions(); // to max set before any spell added @@ -706,14 +665,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 SetPower(POWER_MANA,GetMaxPower(POWER_MANA)); } - if(getPowerType() == POWER_RUNIC_POWER) - { - SetPower(POWER_RUNE, 8); - SetMaxPower(POWER_RUNE, 8); - SetPower(POWER_RUNIC_POWER, 0); - SetMaxPower(POWER_RUNIC_POWER, 1000); - } - // original spells learnDefaultSpells(true); @@ -757,11 +708,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 uint32 item_id = oEntry->ItemId[j]; - - // Hack for not existed item id in dbc 3.0.3 - if(item_id==40582) - continue; - ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id); if(!iProto) { @@ -989,29 +935,53 @@ void Player::HandleDrowning() void Player::HandleLava() { + bool ValidArea = false; + if ((m_isunderwater & 0x80) && isAlive()) { - // Single trigger Set BreathTimer + //Single trigger Set BreathTimer if (!(m_isunderwater & 0x80)) { m_isunderwater|= 0x04; m_breathTimer = 1000; } - - // Reset BreathTimer and still in the lava + //Reset BreathTimer and still in the lava if (!m_breathTimer) { uint64 guid = GetGUID(); uint32 damage = urand(600, 700); // TODO: Get more detailed information about lava damage + uint32 dmgZone = GetZoneId(); // TODO: Find correct "lava dealing zone" flag in Area Table - // if not gamemaster then deal damage - if ( !isGameMaster() ) + // Deal lava damage only in lava zones. + switch(dmgZone) + { + case 0x8D: + ValidArea = false; + break; + case 0x94: + ValidArea = false; + break; + case 0x2CE: + ValidArea = false; + break; + case 0x2CF: + ValidArea = false; + break; + default: + if (dmgZone / 5 & 0x408) + ValidArea = true; + } + + // if is valid area and is not gamemaster then deal damage + if ( ValidArea && !isGameMaster() ) EnvironmentalDamage(guid, DAMAGE_LAVA, damage); m_breathTimer = 1000; } + } - else if (m_deathState == DEAD) // Disable breath timer and reset underwater flags + //Death timer disabled and WaterFlags reset + else if (m_deathState == DEAD) { m_breathTimer = 0; m_isunderwater = 0; @@ -1346,7 +1316,6 @@ void Player::Update( uint32 p_time ) Pet* pet = GetPet(); if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed()) - //if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID()))) { RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); return; @@ -1396,7 +1365,6 @@ void Player::setDeathState(DeathState s) // passive spell if(!ressSpellId) ressSpellId = GetResurrectionSpellId(); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); } Unit::setDeathState(s); @@ -1417,15 +1385,13 @@ void Player::setDeathState(DeathState s) void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) { - Field *fields = result->Fetch(); - - *p_data << uint64(GetGUID()); + *p_data << GetGUID(); *p_data << m_name; - *p_data << uint8(getRace()); + *p_data << getRace(); uint8 pClass = getClass(); - *p_data << uint8(pClass); - *p_data << uint8(getGender()); + *p_data << pClass; + *p_data << getGender(); uint32 bytes = GetUInt32Value(PLAYER_BYTES); *p_data << uint8(bytes); @@ -1440,15 +1406,14 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // do not use GetMap! it will spawn a new instance since the bound instances are not loaded uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY()); sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId); - *p_data << uint32(zoneId); - *p_data << uint32(GetMapId()); + *p_data << zoneId; + *p_data << GetMapId(); *p_data << GetPositionX(); *p_data << GetPositionY(); *p_data << GetPositionZ(); - // guild id - *p_data << (result ? fields[13].GetUInt32() : 0); + *p_data << (result ? result->Fetch()[13].GetUInt32() : 0); uint32 char_flags = 0; if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) @@ -1459,13 +1424,14 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_GHOST; if(HasAtLoginFlag(AT_LOGIN_RENAME)) char_flags |= CHARACTER_FLAG_RENAME; - if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != "")) + // always send the flag if declined names aren't used + // to let the client select a default method of declining the name + if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != "")) char_flags |= CHARACTER_FLAG_DECLINED; - *p_data << uint32(char_flags); // character flags - // character customize (flags?) - *p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0); - *p_data << uint8(1); // unknown + *p_data << (uint32)char_flags; // character flags + + *p_data << (uint8)1; // unknown // Pets info { @@ -1476,6 +1442,8 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // show pet at selection character in character list only for non-ghost character if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER)) { + Field* fields = result->Fetch(); + uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(entry); if(cInfo) @@ -1486,11 +1454,36 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) } } - *p_data << uint32(petDisplayId); - *p_data << uint32(petLevel); - *p_data << uint32(petFamily); + *p_data << (uint32)petDisplayId; + *p_data << (uint32)petLevel; + *p_data << (uint32)petFamily; } + /*ItemPrototype const *items[EQUIPMENT_SLOT_END]; + for (int i = 0; i < EQUIPMENT_SLOT_END; i++) + items[i] = NULL; + + QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow()); + if (result) + { + do + { + Field *fields = result->Fetch(); + uint8 slot = fields[0].GetUInt8() & 255; + uint32 item_id = fields[1].GetUInt32(); + if( slot >= EQUIPMENT_SLOT_END ) + continue; + + items[slot] = objmgr.GetItemPrototype(item_id); + if(!items[slot]) + { + sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id ); + continue; + } + } while (result->NextRow()); + delete result; + }*/ + for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++) { uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); @@ -1507,20 +1500,20 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) if (proto != NULL) { - *p_data << uint32(proto->DisplayInfoID); - *p_data << uint8(proto->InventoryType); - *p_data << uint32(enchant ? enchant->aura_id : 0); + *p_data << (uint32)proto->DisplayInfoID; + *p_data << (uint8)proto->InventoryType; + *p_data << (uint32)(enchant?enchant->aura_id:0); } else { - *p_data << uint32(0); - *p_data << uint8(0); - *p_data << uint32(0); // enchant? + *p_data << (uint32)0; + *p_data << (uint8)0; + *p_data << (uint32)0; // enchant? } } - *p_data << uint32(0); // first bag display id - *p_data << uint8(0); // first bag inventory type - *p_data << uint32(0); // enchant? + *p_data << (uint32)0; // first bag display id + *p_data << (uint8)0; // first bag inventory type + *p_data << (uint32)0; // enchant? } bool Player::ToggleAFK() @@ -1592,7 +1585,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if(GetTransport()) RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :) - SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL, mEntry->Expansion()); + SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL1); return false; // normal client can't teleport to this map... } @@ -1901,20 +1894,13 @@ void Player::RegenerateAll() { RegenerateHealth(); if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) - { Regenerate(POWER_RAGE); - if(getClass() == CLASS_DEATH_KNIGHT) - Regenerate(POWER_RUNIC_POWER); - } } Regenerate( POWER_ENERGY ); Regenerate( POWER_MANA ); - if(getClass() == CLASS_DEATH_KNIGHT) - Regenerate( POWER_RUNE ); - m_regenTimer = regenDelay; } @@ -1934,11 +1920,11 @@ void Player::Regenerate(Powers power) if (recentCast) { // Trinity Updates Mana in intervals of 2s, which is correct - addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f; + addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) * ManaIncreaseRate * 2.00f; } else { - addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f; + addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN) * ManaIncreaseRate * 2.00f; } } break; case POWER_RAGE: // Regenerate rage @@ -1949,17 +1935,6 @@ void Player::Regenerate(Powers power) case POWER_ENERGY: // Regenerate energy (rogue) addvalue = 20; break; - case POWER_RUNIC_POWER: - { - float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS); - addvalue = 30 * RunicPowerDecreaseRate; // 3 RunicPower by tick - } break; - case POWER_RUNE: - { - for(uint32 i = 0; i < MAX_RUNES; ++i) - if(uint8 cd = GetRuneCooldown(i)) // if we have cooldown, reduce it... - SetRuneCooldown(i, cd - 1); // ... by 2 sec (because update is every 2 sec) - } break; case POWER_FOCUS: case POWER_HAPPINESS: break; @@ -1975,7 +1950,7 @@ void Player::Regenerate(Powers power) addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f; } - if (power != POWER_RAGE && power != POWER_RUNIC_POWER) + if (power != POWER_RAGE) { curValue += uint32(addvalue); if (curValue > maxValue) @@ -2259,8 +2234,6 @@ void Player::GiveLevel(uint32 level) data << uint32(0); data << uint32(0); data << uint32(0); - data << uint32(0); - data << uint32(0); // end for for(int i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4) data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i))); @@ -2284,7 +2257,6 @@ void Player::GiveLevel(uint32 level) InitTalentForLevel(); InitTaxiNodesForLevel(); - InitGlyphsForLevel(); UpdateAllStats(); @@ -2304,7 +2276,6 @@ void Player::GiveLevel(uint32 level) Pet* pet = GetPet(); if(pet && pet->getPetType()==SUMMON_PET) pet->GivePetLevel(level); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); } void Player::InitTalentForLevel() @@ -2441,9 +2412,6 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f); SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f); } - // Reset no reagent cost field - for(int i = 0; i < 3; i++) - SetUInt32Value(PLAYER_NO_REAGENT_COST_1 + i, 0); // Init data for form but skip reapply item mods for form InitDataForForm(reapplyMods); @@ -2460,7 +2428,7 @@ void Player::InitStatsForLevel(bool reapplyMods) RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_SILENCED | UNIT_FLAG_PACIFIED | - UNIT_FLAG_STUNNED | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | + UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT | UNIT_FLAG_DISARMED | UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_SKINNABLE | UNIT_FLAG_MOUNT | UNIT_FLAG_TAXI_FLIGHT ); SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); // must be set @@ -2484,7 +2452,6 @@ void Player::InitStatsForLevel(bool reapplyMods) SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE)); SetPower(POWER_FOCUS, 0); SetPower(POWER_HAPPINESS, 0); - SetPower(POWER_RUNIC_POWER, 0); } void Player::SendInitialSpells() @@ -2899,6 +2866,8 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, continue; if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || + // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 || // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 ) { @@ -2935,12 +2904,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading, } } - if(!loading) - { - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS); - } - // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell return active && !disabled && !superceded_old; } @@ -3090,6 +3053,8 @@ void Player::removeSpell(uint32 spell_id, bool disabled) continue; if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || + // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL + pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 || // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 ) { @@ -3389,46 +3354,50 @@ void Player::InitVisibleBits() { updateVisualBits.SetCount(PLAYER_END); + // TODO: really implement OWNER_ONLY and GROUP_ONLY. Flags can be found in UpdateFields.h + updateVisualBits.SetBit(OBJECT_FIELD_GUID); updateVisualBits.SetBit(OBJECT_FIELD_TYPE); - updateVisualBits.SetBit(OBJECT_FIELD_ENTRY); updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X); - updateVisualBits.SetBit(UNIT_FIELD_CHARM + 0); - updateVisualBits.SetBit(UNIT_FIELD_CHARM + 1); - updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 0); - updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 1); - updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 0); - updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 1); - updateVisualBits.SetBit(UNIT_FIELD_TARGET + 0); - updateVisualBits.SetBit(UNIT_FIELD_TARGET + 1); - updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 0); - updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 1); - updateVisualBits.SetBit(UNIT_FIELD_BYTES_0); + + updateVisualBits.SetBit(UNIT_FIELD_CHARM); + updateVisualBits.SetBit(UNIT_FIELD_CHARM+1); + + updateVisualBits.SetBit(UNIT_FIELD_SUMMON); + updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1); + + updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY); + updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY+1); + + updateVisualBits.SetBit(UNIT_FIELD_TARGET); + updateVisualBits.SetBit(UNIT_FIELD_TARGET+1); + + updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT); + updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT+1); + updateVisualBits.SetBit(UNIT_FIELD_HEALTH); updateVisualBits.SetBit(UNIT_FIELD_POWER1); updateVisualBits.SetBit(UNIT_FIELD_POWER2); updateVisualBits.SetBit(UNIT_FIELD_POWER3); updateVisualBits.SetBit(UNIT_FIELD_POWER4); updateVisualBits.SetBit(UNIT_FIELD_POWER5); - updateVisualBits.SetBit(UNIT_FIELD_POWER6); - updateVisualBits.SetBit(UNIT_FIELD_POWER7); + updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER3); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER4); updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5); - updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER6); - updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER7); + updateVisualBits.SetBit(UNIT_FIELD_LEVEL); updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE); - updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 0); - updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 1); - updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 2); + updateVisualBits.SetBit(UNIT_FIELD_BYTES_0); updateVisualBits.SetBit(UNIT_FIELD_FLAGS); updateVisualBits.SetBit(UNIT_FIELD_FLAGS_2); + for(uint16 i = UNIT_FIELD_AURA; i < UNIT_FIELD_AURASTATE; ++i) + updateVisualBits.SetBit(i); updateVisualBits.SetBit(UNIT_FIELD_AURASTATE); - updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 0); + updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME); updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1); updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS); updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH); @@ -3441,12 +3410,10 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(UNIT_DYNAMIC_FLAGS); updateVisualBits.SetBit(UNIT_CHANNEL_SPELL); updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED); - updateVisualBits.SetBit(UNIT_FIELD_BASE_MANA); updateVisualBits.SetBit(UNIT_FIELD_BYTES_2); - updateVisualBits.SetBit(UNIT_FIELD_HOVERHEIGHT); - updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 0); - updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 1); + updateVisualBits.SetBit(PLAYER_DUEL_ARBITER); + updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1); updateVisualBits.SetBit(PLAYER_FLAGS); updateVisualBits.SetBit(PLAYER_GUILDID); updateVisualBits.SetBit(PLAYER_GUILDRANK); @@ -3457,29 +3424,29 @@ void Player::InitVisibleBits() updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP); // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)... - for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4) + for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4) updateVisualBits.SetBit(i); - // Players visible items are not inventory stuff - for(uint16 i = 0; i < EQUIPMENT_SLOT_END; ++i) + //Players visible items are not inventory stuff + //431) = 884 (0x374) = main weapon + for(uint16 i = 0; i < EQUIPMENT_SLOT_END; i++) { - uint32 offset = i * MAX_VISIBLE_ITEM_OFFSET; - // item creator - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 0 + offset); - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 1 + offset); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 0); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 1); + + uint16 visual_base = PLAYER_VISIBLE_ITEM_1_0 + (i*MAX_VISIBLE_ITEM_OFFSET); // item entry - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 0 + offset); + updateVisualBits.SetBit(visual_base + 0); - // item enchantments - for(uint8 j = 0; j < MAX_ENCHANTMENT_SLOT; ++j) - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 1 + j + offset); + // item enchantment IDs + for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) + updateVisualBits.SetBit(visual_base + 1 + j); // random properties - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + offset); - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_SEED + offset); - updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PAD + offset); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (i*MAX_VISIBLE_ITEM_OFFSET)); + updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (i*MAX_VISIBLE_ITEM_OFFSET)); } updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE); @@ -3497,6 +3464,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) if(target == this) { + for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++) { if(m_items[i] == NULL) @@ -3504,7 +3472,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) m_items[i]->BuildCreateUpdateBlockForPlayer( data, target ); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { if(m_items[i] == NULL) continue; @@ -3537,7 +3505,7 @@ void Player::DestroyForPlayer( Player *target ) const m_items[i]->DestroyForPlayer( target ); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { if(m_items[i] == NULL) continue; @@ -3767,8 +3735,6 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid); CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid); CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid); - CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u'",guid); - CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid); CharacterDatabase.CommitTransaction(); //loginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID); @@ -3799,10 +3765,6 @@ void Player::SetMovement(PlayerMovementType pType) */ void Player::BuildPlayerRepop() { - WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size()); - data.append(GetPackGUID()); - GetSession()->SendPacket(&data); - if(getRace() == RACE_NIGHTELF) CastSpell(this, 20584, true); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) CastSpell(this, 8326, true); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) @@ -3923,7 +3885,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i)) { Aur->SetAuraDuration(delta*1000); - Aur->SendAuraUpdate(false); + Aur->UpdateAuraDuration(); } } } @@ -4460,7 +4422,7 @@ uint32 Player::GetShieldBlockValue() const { BaseModGroup modGroup = SHIELD_BLOCK_VALUE; - float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH) * 0.5f - 10; + float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH)/20 - 1; value = (value < 0) ? 0 : value; @@ -4649,18 +4611,7 @@ float Player::OCTRegenMPPerSpirit() void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) { - m_baseRatingValue[cr]+=(apply ? value : -value); - - int32 amount = uint32(m_baseRatingValue[cr]); - // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT - // stat used stored in miscValueB for this aura - AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT); - for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i) - if ((*i)->GetMiscValue() & (1<GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f; - if (amount < 0) - amount = 0; - SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount)); + ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply); float RatingCoeffecient = GetRatingCoefficient(cr); float RatingChange = 0.0f; @@ -4683,13 +4634,16 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) UpdateBlockPercentage(); break; case CR_HIT_MELEE: - UpdateMeleeHitChances(); + RatingChange = value / RatingCoeffecient; + m_modMeleeHitChance += apply ? RatingChange : -RatingChange; break; case CR_HIT_RANGED: - UpdateRangedHitChances(); + RatingChange = value / RatingCoeffecient; + m_modRangedHitChance += apply ? RatingChange : -RatingChange; break; case CR_HIT_SPELL: - UpdateSpellHitChances(); + RatingChange = value / RatingCoeffecient; + m_modSpellHitChance += apply ? RatingChange : -RatingChange; break; case CR_CRIT_MELEE: if(affectStats) @@ -4787,7 +4741,6 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step) new_value = max; SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); return true; } @@ -4850,7 +4803,6 @@ bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLeve case SKILL_HERBALISM: case SKILL_LOCKPICKING: case SKILL_JEWELCRAFTING: - case SKILL_INSCRIPTION: return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain); case SKILL_SKINNING: if( sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)==0) @@ -4913,7 +4865,6 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) new_value = MaxValue; SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0); return true; } @@ -5101,10 +5052,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal) if(iReputationListID; @@ -5897,8 +5841,7 @@ bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32 } } } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION); + SendFactionState(&(itr->second)); return true; @@ -5964,8 +5907,6 @@ bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 sta SetFactionAtWar(&itr->second,true); SendFactionState(&(itr->second)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION); return true; } return false; @@ -6676,43 +6617,19 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply) sLog.outDebug("_ApplyItemMods complete."); } -void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool apply) +void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply) { if(slot >= INVENTORY_SLOT_BAG_END || !proto) return; for (int i = 0; i < 10; i++) { - uint32 statType = 0; - int32 val = 0; + float val = float (proto->ItemStat[i].ItemStatValue); - if(proto->ScalingStatDistribution) - { - if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution)) - { - statType = ssd->StatMod[i]; - - if(uint32 modifier = ssd->Modifier[i]) - { - uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); - if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) - { - int multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; - val = (multiplier * modifier) / 10000; - } - } - } - } - else - { - statType = proto->ItemStat[i].ItemStatType; - val = float(proto->ItemStat[i].ItemStatValue); - } - - if(val == 0) + if(val==0) continue; - switch (statType) + switch (proto->ItemStat[i].ItemStatType) { case ITEM_MOD_MANA: HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply); @@ -6830,9 +6747,6 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl case ITEM_MOD_EXPERTISE_RATING: ApplyRatingMod(CR_EXPERTISE, int32(val), apply); break; - case ITEM_MOD_ARMOR_PENETRATION_RATING: - ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply); - break; } } @@ -7448,17 +7362,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type) loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this); } } - else if(loot_type == LOOT_MILLING) - { - loot = &item->loot; - - if(!item->m_lootGenerated) - { - item->m_lootGenerated = true; - loot->clear(); - loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this); - } - } else { loot = &item->loot; @@ -7654,8 +7557,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type) conditional_list = itr->second; } - // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING, LOOT_INSIGNIA and LOOT_MILLING unsupported by client, sending LOOT_SKINNING instead - if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA || loot_type == LOOT_MILLING) + // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING and LOOT_INSIGNIA unsupported by client, sending LOOT_SKINNING instead + if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA) loot_type = LOOT_SKINNING; if(loot_type == LOOT_FISHINGHOLE) @@ -8379,8 +8282,7 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap // (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ... if(CanDualWield()) slots[1] = EQUIPMENT_SLOT_OFFHAND; - break; - }; + };break; case INVTYPE_SHIELD: slots[0] = EQUIPMENT_SLOT_OFFHAND; break; @@ -8389,8 +8291,6 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap break; case INVTYPE_2HWEAPON: slots[0] = EQUIPMENT_SLOT_MAINHAND; - if (CanDualWield() && CanTitanGrip()) - slots[1] = EQUIPMENT_SLOT_OFFHAND; break; case INVTYPE_TABARD: slots[0] = EQUIPMENT_SLOT_TABARD; @@ -8436,10 +8336,6 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap if (pClass == CLASS_WARLOCK) slots[0] = EQUIPMENT_SLOT_RANGED; break; - case ITEM_SUBCLASS_ARMOR_SIGIL: - if (pClass == CLASS_DEATH_KNIGHT) - slots[0] = EQUIPMENT_SLOT_RANGED; - break; } break; } @@ -8465,8 +8361,14 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap { if ( slots[i] != NULL_SLOT && !GetItemByPos( INVENTORY_SLOT_BAG_0, slots[i] ) ) { - // in case 2hand equipped weapon (without titan grip) offhand slot empty but not free - if(slots[i]!=EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed()) + // in case 2hand equipped weapon offhand slot empty but not free + if(slots[i]==EQUIPMENT_SLOT_OFFHAND) + { + Item* mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) + return slots[i]; + } + else return slots[i]; } } @@ -8516,7 +8418,7 @@ uint8 Player::CanUnequipItems( uint32 item, uint32 count ) const return EQUIP_ERR_OK; } } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetEntry() == item ) @@ -8558,7 +8460,7 @@ uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) cons if( pItem && pItem != skipItem && pItem->GetEntry() == item ) count += pItem->GetCount(); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem != skipItem && pItem->GetEntry() == item ) @@ -8618,7 +8520,7 @@ Item* Player::GetItemByGuid( uint64 guid ) const if( pItem && pItem->GetGUID() == guid ) return pItem; } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetGUID() == guid ) @@ -8664,7 +8566,7 @@ Item* Player::GetItemByPos( uint16 pos ) const Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const { - if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) ) + if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) return m_items[slot]; else if(bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END || bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END ) @@ -8742,7 +8644,7 @@ bool Player::IsInventoryPos( uint8 bag, uint8 slot ) return true; if( bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END ) return true; - if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) ) + if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) return true; return false; } @@ -8863,7 +8765,7 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const return true; } } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetEntry() == item ) @@ -8985,7 +8887,7 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) return true; } - for(uint8 i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; ++i) + for(uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) { pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) @@ -9025,18 +8927,6 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS)) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - // vanitypet case - if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - - // currencytoken case - if(slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - - // guestbag case - if(slot >= QUESTBAG_SLOT_START && slot < QUESTBAG_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - // prevent cheating if(slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; @@ -9281,7 +9171,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 { if( bag == INVENTORY_SLOT_BAG_0 ) // inventory { - res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot); + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); if(res!=EQUIP_ERR_OK) { if(no_space_count) @@ -9368,66 +9258,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) - { - res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) - { - res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) - { - res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); if(res!=EQUIP_ERR_OK) @@ -9477,7 +9307,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 // search stack for merge to if( pProto->Stackable > 1 ) { - res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot); + res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); if(res!=EQUIP_ERR_OK) { if(no_space_count) @@ -9575,66 +9405,6 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) - { - res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) - { - res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) - { - res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) - { - if(no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if(count==0) - { - if(no_similar_count==0) - return EQUIP_ERR_OK; - - if(no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { @@ -9705,16 +9475,10 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const int inv_slot_items[INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START]; int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START]; - int inv_pets[VANITYPET_SLOT_END-VANITYPET_SLOT_START]; - int inv_tokens[CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START]; - int inv_quests[QUESTBAG_SLOT_END-QUESTBAG_SLOT_START]; memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START)); memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE); memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START)); - memset(inv_pets,0,sizeof(int)*(VANITYPET_SLOT_END-VANITYPET_SLOT_START)); - memset(inv_tokens,0,sizeof(int)*(CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START)); - memset(inv_quests,0,sizeof(int)*(QUESTBAG_SLOT_END-QUESTBAG_SLOT_START)); for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) { @@ -9736,36 +9500,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const } } - for(int i = VANITYPET_SLOT_START; i < VANITYPET_SLOT_END; i++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - - if (pItem2 && !pItem2->IsInTrade()) - { - inv_pets[i-VANITYPET_SLOT_START] = pItem2->GetCount(); - } - } - - for(int i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - - if (pItem2 && !pItem2->IsInTrade()) - { - inv_tokens[i-CURRENCYTOKEN_SLOT_START] = pItem2->GetCount(); - } - } - - for(int i = QUESTBAG_SLOT_START; i < QUESTBAG_SLOT_END; i++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); - - if (pItem2 && !pItem2->IsInTrade()) - { - inv_quests[i-QUESTBAG_SLOT_START] = pItem2->GetCount(); - } - } - for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) @@ -9825,42 +9559,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const } if (b_found) continue; - for(int t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; t++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); - if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_pets[t-VANITYPET_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) - { - inv_pets[t-VANITYPET_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) continue; - - for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); - if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) - { - inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) continue; - - for(int t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; t++) - { - pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); - if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_quests[t-QUESTBAG_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) - { - inv_quests[t-QUESTBAG_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) continue; - for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++) { pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); @@ -9913,51 +9611,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const if (b_found) continue; - if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) - { - for(uint32 t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; ++t) - { - if( inv_pets[t-VANITYPET_SLOT_START] == 0 ) - { - inv_pets[t-VANITYPET_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) continue; - - if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) - { - for(uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) - { - if( inv_tokens[t-CURRENCYTOKEN_SLOT_START] == 0 ) - { - inv_tokens[t-CURRENCYTOKEN_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) continue; - - if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) - { - for(uint32 t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; ++t) - { - if( inv_quests[t-QUESTBAG_SLOT_START] == 0 ) - { - inv_quests[t-QUESTBAG_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) continue; - for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++) { pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t ); @@ -10143,42 +9796,33 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo if(eslot == EQUIPMENT_SLOT_OFFHAND) { - if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) + if( type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND ) { if(!CanDualWield()) return EQUIP_ERR_CANT_DUAL_WIELD; } - else if (type == INVTYPE_2HWEAPON) - { - if(!CanDualWield() || !CanTitanGrip()) - return EQUIP_ERR_CANT_DUAL_WIELD; - } - if(IsTwoHandUsed()) - return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; + Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + if(mainItem) + { + if(mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON) + return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; + } } // equip two-hand weapon case (with possible unequip 2 items) if( type == INVTYPE_2HWEAPON ) { - if (eslot == EQUIPMENT_SLOT_OFFHAND) - { - if (!CanTitanGrip()) - return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - } - else if (eslot != EQUIPMENT_SLOT_MAINHAND) + if(eslot != EQUIPMENT_SLOT_MAINHAND) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - if (!CanTitanGrip()) - { - // offhand item must can be stored in inventory for offhand item and it also must be unequipped - Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); - ItemPosCountVec off_dest; - if( offItem && (!not_loading || - CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || - CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) - return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; - } + // offhand item must can be stored in inventory for offhand item and it also must be unequipped + Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); + ItemPosCountVec off_dest; + if( offItem && (!not_loading || + CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || + CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) + return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; } dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot); return EQUIP_ERR_OK; @@ -11098,7 +10742,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq } } } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->GetEntry() == item ) @@ -11201,7 +10845,7 @@ void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone ) if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) DestroyItem( INVENTORY_SLOT_BAG_0, i, update); } - for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++) + for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) { Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) @@ -12198,10 +11842,6 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply); sLog.outDebug("+ %u EXPERTISE", enchant_amount); break; - case ITEM_MOD_ARMOR_PENETRATION_RATING: - ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply); - sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount); - break; default: break; } @@ -12924,10 +12564,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver } if(pQuest->IsDaily()) - { SetDailyQuestStatus(quest_id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1); - } if ( !pQuest->IsRepeatable() ) SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE); @@ -12940,8 +12577,6 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver SendQuestReward( pQuest, XP, questGiver ); if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST); } void Player::FailQuest( uint32 quest_id ) @@ -13567,7 +13202,6 @@ void Player::ItemAddedQuestCheck( uint32 entry, uint32 count ) } } UpdateForQuestsGO(); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, entry); } void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count ) @@ -13614,7 +13248,6 @@ void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count ) void Player::KilledMonster( uint32 entry, uint64 guid ) { uint32 addkillcount = 1; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, entry, addkillcount); for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { uint32 questid = GetQuestSlotQuestId(i); @@ -13893,12 +13526,13 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive uint32 questid = pQuest->GetQuestId(); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid ); gameeventmgr.HandleQuestComplete(questid); - WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4) ); - data << uint32(questid); + WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4+4+pQuest->GetRewItemsCount()*8) ); + data << questid; + data << uint32(0x03); if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ) { - data << uint32(XP); + data << XP; data << uint32(pQuest->GetRewOrReqMoney()); } else @@ -13906,9 +13540,16 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive data << uint32(0); data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY))); } + data << uint32(0); // new 2.3.0, HonorPoints? + data << uint32( pQuest->GetRewItemsCount() ); // max is 5 - data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills())); - data << uint32(pQuest->GetBonusTalents()); // bonus talents + for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i) + { + if ( pQuest->RewItemId[i] > 0 ) + data << pQuest->RewItemId[i] << pQuest->RewItemCount[i]; + else + data << uint32(0) << uint32(0); + } GetSession()->SendPacket( &data ); if (pQuest->GetQuestCompleteScript() != 0) @@ -13919,9 +13560,8 @@ void Player::SendQuestFailed( uint32 quest_id ) { if( quest_id ) { - WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4+4 ); + WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 ); data << quest_id; - data << uint32(0); // failed reason (4 for inventory is full) GetSession()->SendPacket( &data ); sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED"); } @@ -13960,10 +13600,10 @@ void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg ) void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count ) { - WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, 0 ); + WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, (4+4) ); sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM" ); - //data << pQuest->ReqItemId[item_idx]; - //data << count; + data << pQuest->ReqItemId[item_idx]; + data << count; GetSession()->SendPacket( &data ); } @@ -14009,7 +13649,7 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) if(!LoadValues( fields[1].GetString())) { - sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid)); + sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); if(delete_result) delete result; return false; } @@ -14079,7 +13719,7 @@ void Player::_LoadArenaTeamInfo(QueryResult *result) ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid); if(!aTeam) { - sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u, week %u, season %u, rating %u", arenateamid, played_week, played_season, personal_rating); + sLog.outError("FATAL: couldn't load arenateam %u", arenateamid); continue; } uint8 arenaSlot = aTeam->GetSlot(); @@ -14481,10 +14121,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) uint32 extraflags = fields[25].GetUInt32(); m_stableSlots = fields[26].GetUInt32(); - if(m_stableSlots > 4) + if(m_stableSlots > 2) { - sLog.outError("Player can have not more 4 stable slots, but have in DB %u",uint32(m_stableSlots)); - m_stableSlots = 4; + sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots)); + m_stableSlots = 2; } m_atLoginFlags = fields[27].GetUInt32(); @@ -14553,8 +14193,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) // reset stats before loading any modifiers InitStatsForLevel(); InitTaxiNodesForLevel(); - InitGlyphsForLevel(); - InitRunes(); // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() @@ -14711,8 +14349,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) _LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES)); - m_achievementMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS)); - m_achievementMgr.CheckAllAchievementCriteria(); return true; } @@ -14766,6 +14402,10 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) for (int i = 0; i < TOTAL_AURAS; i++) m_modAuras[i].clear(); + // all aura related fields + for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) + SetUInt32Value(i, 0); + //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); if(result) @@ -15677,7 +15317,7 @@ void Player::SaveToDB() SetByteValue(UNIT_FIELD_BYTES_1, 0, 0); // stand state SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); // shapeshift SetByteValue(UNIT_FIELD_BYTES_1, 3, 0); // stand flags? - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); SetDisplayId(GetNativeDisplayId()); bool inworld = IsInWorld(); @@ -15828,7 +15468,7 @@ void Player::SaveToDB() pet->SavePetToDB(PET_SAVE_AS_CURRENT); //to prevent access to DB we should cache some data, which is used very often - /*CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow()); + CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow()); if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players { _iter->second->unLevel = getLevel(); @@ -15842,8 +15482,7 @@ void Player::SaveToDB() _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)); _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)); _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)); - }*/ - m_achievementMgr.SaveToDB(); + } } // fast save function for item/money cheating preventing - save only inventory and money state @@ -16305,42 +15944,6 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid) Player::SetUInt32ValueInDB(index, temp, guid); } -void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair) -{ - Tokens tokens; - if(!LoadValuesArrayFromDB(tokens, guid)) - return; - - uint32 unit_bytes0 = GetUInt32ValueFromArray(tokens, UNIT_FIELD_BYTES_0); - uint8 race = unit_bytes0 & 0xFF; - uint8 class_ = (unit_bytes0 >> 8) & 0xFF; - - PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_); - if(!info) - return; - - unit_bytes0 &= ~(0xFF << 16); - unit_bytes0 |= (gender << 16); - SetUInt32ValueInArray(tokens, UNIT_FIELD_BYTES_0, unit_bytes0); - - SetUInt32ValueInArray(tokens, UNIT_FIELD_DISPLAYID, gender ? info->displayId_f : info->displayId_m); - SetUInt32ValueInArray(tokens, UNIT_FIELD_NATIVEDISPLAYID, gender ? info->displayId_f : info->displayId_m); - - SetUInt32ValueInArray(tokens, PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); - - uint32 player_bytes2 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_2); - player_bytes2 &= ~0xFF; - player_bytes2 |= facialHair; - SetUInt32ValueInArray(tokens, PLAYER_BYTES_2, player_bytes2); - - uint32 player_bytes3 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_3); - player_bytes3 &= ~0xFF; - player_bytes3 |= gender; - SetUInt32ValueInArray(tokens, PLAYER_BYTES_3, player_bytes3); - - SaveValuesArrayInDB(tokens, guid); -} - void Player::SendAttackSwingNotStanding() { WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0); @@ -16373,8 +15976,7 @@ void Player::SendAttackSwingBadFacingAttack() void Player::SendAutoRepeatCancel() { - WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, GetPackGUID().size()); - data.append(GetPackGUID()); // may be it's target guid + WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, 0); GetSession()->SendPacket( &data ); } @@ -16603,7 +16205,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) { WorldPacket data(SMSG_PET_SPELLS, 8); data << uint64(0); - data << uint32(0); GetSession()->SendPacket(&data); if(GetGroup()) @@ -16735,79 +16336,65 @@ void Player::PetSpellInitialize() { Pet* pet = GetPet(); - if(!pet) - return; - - sLog.outDebug("Pet Spells Groups"); - - CharmInfo *charmInfo = pet->GetCharmInfo(); - - WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+10*4); - data << uint64(pet->GetGUID()); - data << uint32(pet->GetCreatureInfo()->family); // creature family (required for pet talents) - data << uint32(0); - data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); - - // action bar loop - for(uint32 i = 0; i < 10; i++) + if(pet) { - data << uint32(charmInfo->GetActionBarEntry(i)->Raw); - } + uint8 addlist = 0; - size_t spellsCountPos = data.wpos(); + sLog.outDebug("Pet Spells Groups"); - // spells count - uint8 addlist = 0; - data << uint8(addlist); // placeholder + CreatureInfo const *cinfo = pet->GetCreatureInfo(); - if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK)))) - { - // spells loop - for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) + if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)) { - if(itr->second->state == PETSPELL_REMOVED) - continue; - - data << uint16(itr->first); - data << uint16(itr->second->active); // pet spell active state isn't boolean - ++addlist; + for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + ++addlist; + } } + + // first line + actionbar + spellcount + spells + last adds + WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25); + + CharmInfo *charmInfo = pet->GetCharmInfo(); + + //16 + data << (uint64)pet->GetGUID() << uint32(0x00000000) << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); + + for(uint32 i = 0; i < 10; i++) //40 + { + data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); + } + + data << uint8(addlist); //1 + + if(addlist && pet->isControlled()) + { + for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) + continue; + + data << uint16(itr->first); + data << uint16(itr->second->active); // pet spell active state isn't boolean + } + } + + //data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00); //15 + uint8 count = 3; //1+8+8+8=25 + + // if count = 0, then end of packet... + data << count; + // uint32 value is spell id... + // uint64 value is constant 0, unknown... + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + //data << uint32(0x5fd1) << uint64(0); // if count = 2 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 + + GetSession()->SendPacket(&data); } - - data.put(spellsCountPos, addlist); - - uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size(); - data << uint8(cooldownsCount); - - time_t curTime = time(NULL); - - for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr) - { - time_t cooldown = 0; - - if(itr->second > curTime) - cooldown = (itr->second - curTime) * 1000; - - data << uint16(itr->first); // spellid - data << uint16(0); // spell category? - data << uint32(itr->second); // cooldown - data << uint32(0); // category cooldown - } - - for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr) - { - time_t cooldown = 0; - - if(itr->second > curTime) - cooldown = (itr->second - curTime) * 1000; - - data << uint16(itr->first); // spellid - data << uint16(0); // spell category? - data << uint32(0); // cooldown - data << uint32(itr->second); // category cooldown - } - - GetSession()->SendPacket(&data); } void Player::PossessSpellInitialize() @@ -16829,10 +16416,7 @@ void Player::PossessSpellInitialize() WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds //16 - data << uint64(charm->GetGUID()); - data << uint32(0x00000000); - data << uint32(0); - data << uint8(0) << uint8(0) << uint16(0); + data << (uint64)charm->GetGUID() << uint32(0x00000000) << uint8(0) << uint8(0) << uint16(0); for(uint32 i = 0; i < 10; i++) //40 { @@ -16841,8 +16425,11 @@ void Player::PossessSpellInitialize() data << uint8(addlist); //1 - uint8 count = 0; - data << uint8(count); // cooldowns count + uint8 count = 3; + data << count; + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 GetSession()->SendPacket(&data); } @@ -16879,13 +16466,13 @@ void Player::CharmSpellInitialize() WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds - data << uint64(charm->GetGUID()); - data << uint32(0x00000000); - data << uint32(0); + data << (uint64)charm->GetGUID() << uint32(0x00000000); + if(charm->GetTypeId() != TYPEID_PLAYER) data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()); else data << uint8(0) << uint8(0); + data << uint16(0); for(uint32 i = 0; i < 10; i++) //40 @@ -16908,12 +16495,51 @@ void Player::CharmSpellInitialize() } } - uint8 count = 0; - data << uint8(count); // cooldowns count + uint8 count = 3; + data << count; + data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 + data << uint32(0x8e8c) << uint64(0); // if count = 3 + data << uint32(0x8e8b) << uint64(0); // if count = 3 GetSession()->SendPacket(&data); } +int32 Player::GetTotalFlatMods(uint32 spellId, SpellModOp op) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 total = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod)) + continue; + + if (mod->type == SPELLMOD_FLAT) + total += mod->value; + } + return total; +} + +int32 Player::GetTotalPctMods(uint32 spellId, SpellModOp op) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) return 0; + int32 total = 0; + for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) + { + SpellModifier *mod = *itr; + + if(!IsAffectedBySpellmod(spellInfo,mod)) + continue; + + if (mod->type == SPELLMOD_PCT) + total += mod->value; + } + return total; +} + bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell) { if (!mod || !spellInfo) @@ -16931,25 +16557,22 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo return false; } - return spellmgr.IsAffectedByMod(spellInfo, mod); + return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask); } void Player::AddSpellMod(SpellModifier* mod, bool apply) { uint16 Opcode= (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; - for(int eff=0;eff<96;++eff) + for(int eff=0;eff<64;++eff) { - uint64 _mask = 0; - uint64 _mask2= 0; - if (eff<64) _mask = uint64(1) << (eff- 0); - else _mask2= uint64(1) << (eff-64); - if ( mod->mask & _mask || mod->mask2 & _mask2) + uint64 _mask = uint64(1) << eff; + if ( mod->mask & _mask) { int32 val = 0; for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) { - if ((*itr)->type == mod->type && ((*itr)->mask & _mask || (*itr)->mask2 & _mask2)) + if ((*itr)->type == mod->type && (*itr)->mask & _mask) val += (*itr)->value; } val += apply ? mod->value : -(mod->value); @@ -17097,7 +16720,7 @@ void Player::HandleStealthedUnitsDetection() // send data at target visibility change (adding to client) if((*i)!=this && (*i)->isType(TYPEMASK_UNIT)) { - SendAurasForTarget(*i); + SendAuraDurationsForTarget(*i); //if(((Unit*)(*i))->isAlive()) //should be always alive { if((*i)->GetTypeId()==TYPEID_UNIT) @@ -18091,7 +17714,7 @@ void Player::UpdateVisibilityOf(WorldObject* target) // send data at target visibility change (adding to client) if(target!=this && target->isType(TYPEMASK_UNIT)) { - SendAurasForTarget((Unit*)target); + SendAuraDurationsForTarget((Unit*)target); if(((Unit*)target)->isAlive()) { if(target->GetTypeId()==TYPEID_UNIT) @@ -18270,7 +17893,7 @@ void Player::SetGroup(Group *group, int8 subgroup) void Player::SendInitialPacketsBeforeAddToMap() { - WorldPacket data(SMSG_SET_REST_START_OBSOLETE, 4); + WorldPacket data(SMSG_SET_REST_START, 4); data << uint32(0); // unknown, may be rest state time or experience GetSession()->SendPacket(&data); @@ -18298,7 +17921,6 @@ void Player::SendInitialPacketsBeforeAddToMap() SendInitialActionButtons(); SendInitialReputations(); - m_achievementMgr.SendAllAchievementData(); UpdateZone(GetZoneId()); SendInitWorldStates(); @@ -18309,23 +17931,13 @@ void Player::SendInitialPacketsBeforeAddToMap() data << (float)0.01666667f; // game speed GetSession()->SendPacket( &data ); - data.Initialize(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement - data << uint32(0x00000000); // on blizz it increments periodically - GetSession()->SendPacket(&data); - // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight()) AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); - - m_mover = this; } void Player::SendInitialPacketsAfterAddToMap() { - WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement - data << uint32(0x00000000); // on blizz it increments periodically - GetSession()->SendPacket(&data); - CastSpell(this, 836, true); // LOGINEFFECT // set some aura effects that send packet to player client after add player to map @@ -18356,7 +17968,6 @@ void Player::SendInitialPacketsAfterAddToMap() SendMessageToSet(&data,true); } - SendAurasForTarget(this); SendEnchantmentDurations(); // must be after add to map SendItemDurations(); // must be after add to map } @@ -18374,19 +17985,11 @@ void Player::SendUpdateToOutOfRangeGroupMembers() pet->ResetAuraUpdateMask(); } -void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg) +void Player::SendTransferAborted(uint32 mapid, uint16 reason) { WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2); data << uint32(mapid); - data << uint8(reason); // transfer abort reason - switch(reason) - { - case TRANSFER_ABORT_INSUF_EXPAN_LVL: - case TRANSFER_ABORT_DIFFICULTY: - case TRANSFER_ABORT_UNIQUE_MESSAGE: - data << uint8(arg); - break; - } + data << uint16(reason); // transfer abort reason GetSession()->SendPacket(&data); } @@ -18596,51 +18199,16 @@ void Player::learnSkillRewardedSpells() } } -void Player::SendAurasForTarget(Unit *target) +void Player::SendAuraDurationsForTarget(Unit* target) { - if(target->GetVisibleAuras()->empty()) // speedup things - return; - - WorldPacket data(SMSG_AURA_UPDATE_ALL); - data.append(target->GetPackGUID()); - - Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras(); - for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) + for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) { - for(uint32 j = 0; j < 3; ++j) - { - if(Aura *aura = target->GetAura(itr->second, j)) - { - data << uint8(aura->GetAuraSlot()); - data << uint32(aura->GetId()); + Aura* aura = itr->second; + if(aura->GetAuraSlot() >= MAX_AURAS || aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) + continue; - if(aura->GetId()) - { - uint8 auraFlags = aura->GetAuraFlags(); - // flags - data << uint8(auraFlags); - // level - data << uint8(aura->GetAuraLevel()); - // charges - data << uint8(aura->m_procCharges >= 0 ? aura->m_procCharges : 0 ); - - if(!(auraFlags & AFLAG_NOT_CASTER)) - { - data << uint8(0); // packed GUID of someone (caster?) - } - - if(auraFlags & AFLAG_DURATION) // include aura duration - { - data << uint32(aura->GetAuraMaxDuration()); - data << uint32(aura->GetAuraDuration()); - } - } - break; - } - } + aura->SendAuraDurationForCaster(this); } - - GetSession()->SendPacket(&data); } void Player::SetDailyQuestStatus( uint32 quest_id ) @@ -18702,15 +18270,15 @@ uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id) if(queue_id < 1) return 0; - if(queue_id >=7) - queue_id = 7; + if(queue_id >=6) + queue_id = 6; return 10*(queue_id+1); } uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id) { - if(queue_id >=7) + if(queue_id >=6) return 255; // hardcoded max level return 10*(queue_id+2)-1; @@ -18722,8 +18290,8 @@ uint32 Player::GetBattleGroundQueueIdFromLevel() const uint32 level = getLevel(); if(level <= 19) return 0; - else if (level > 79) - return 7; + else if (level > 69) + return 6; else return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ... /* @@ -18869,8 +18437,9 @@ void Player::AutoUnequipOffhandIfNeed() if(!offItem) return; - // need unequip for 2h-weapon without TitanGrip - if (!IsTwoHandUsed()) + Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); + + if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) return; ItemPosCountVec off_dest; @@ -18936,23 +18505,6 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons return false; } -bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const -{ - // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP - if (spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && - HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) - return true; - - // Check no reagent use mask - uint64 noReagentMask_0_1 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1); - uint32 noReagentMask_2 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1+2); - if (spellInfo->SpellFamilyFlags & noReagentMask_0_1 || - spellInfo->SpellFamilyFlags2 & noReagentMask_2) - return true; - - return false; -} - void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) { AuraMap& auras = GetAuras(); @@ -18998,7 +18550,7 @@ uint32 Player::GetResurrectionSpellId() for(AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) { // Soulstone Resurrection // prio: 3 (max, non death persistent) - if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual[0] == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 ) + if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 ) { switch((*itr)->GetId()) { @@ -19157,9 +18709,6 @@ 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()); - ResurrectPlayer(0.0f,false); if(GetMaxHealth() > m_resurrectHealth) @@ -19177,6 +18726,8 @@ void Player::ResurectUsingRequestData() SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) ); SpawnCorpseBones(); + + TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); } void Player::SetClientControl(Unit* target, uint8 allowMove) @@ -19190,8 +18741,8 @@ void Player::SetClientControl(Unit* target, uint8 allowMove) void Player::UpdateZoneDependentAuras( uint32 newZone ) { // remove new continent flight forms - uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), newZone); - if( !isGameMaster() && v_map != 530 && v_map != 571) + if( !isGameMaster() && + GetVirtualMapForMapAndZone(GetMapId(),newZone) != 530) { RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED); RemoveSpellsCausingAura(SPELL_AURA_FLY); @@ -19411,8 +18962,8 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const void Player::HandleFallDamage(MovementInfo& movementInfo) { - //if(movementInfo.fallTime < 1500) - // return; + if(movementInfo.fallTime < 1500) + return; // calculate total z distance of the fall float z_diff = m_lastFallZ - movementInfo.z; @@ -19718,152 +19269,6 @@ bool Player::isAllowUseBattleGroundObject() ); } -uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair) -{ - uint32 level = getLevel(); - - if(level > GT_MAX_LEVEL) - level = GT_MAX_LEVEL; // max level in this dbc - - uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2); - uint8 haircolor = GetByteValue(PLAYER_BYTES, 3); - uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0); - - if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair)) - return 0; - - GtBarberShopCostBaseEntry const *bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1); - - if(!bsc) // shouldn't happen - return 0xFFFFFFFF; - - float cost = 0; - - if(hairstyle != newhairstyle) - cost += bsc->cost; // full price - - if((haircolor != newhaircolor) && (hairstyle == newhairstyle)) - cost += bsc->cost * 0.5f; // +1/2 of price - - if(facialhair != newfacialhair) - cost += bsc->cost * 0.75f; // +3/4 of price - - return uint32(cost); -} - -void Player::InitGlyphsForLevel() -{ - uint32 level = getLevel(); - uint32 value = 0; - - // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level - if(level >= 15) - value |= (0x01 | 0x02); - if(level >= 30) - value |= 0x04; - if(level >= 50) - value |= 0x08; - if(level >= 70) - value |= 0x10; - if(level >= 80) - value |= 0x20; - - SetUInt32Value(PLAYER_GLYPHS_ENABLED, value); -} - -void Player::EnterVehicle(Vehicle *vehicle) -{ - VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId()); - if(!ve) - return; - - VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]); - if(!veSeat) - return; - - vehicle->SetCharmerGUID(GetGUID()); - vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - vehicle->setFaction(getFaction()); - - SetCharm(vehicle); // charm - SetFarSight(vehicle->GetGUID()); // set view - - SetClientControl(vehicle, 1); // redirect controls to vehicle - - WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - GetSession()->SendPacket(&data); - - data.Initialize(MSG_MOVE_TELEPORT_ACK, 30); - data.append(GetPackGUID()); - data << uint32(0); // counter? - data << uint32(MOVEMENTFLAG_ONTRANSPORT); // transport - data << uint16(0); // special flags - data << uint32(getMSTime()); // time - data << vehicle->GetPositionX(); // x - data << vehicle->GetPositionY(); // y - data << vehicle->GetPositionZ(); // z - data << vehicle->GetOrientation(); // o - // transport part, TODO: load/calculate seat offsets - data << uint64(vehicle->GetGUID()); // transport guid - data << float(veSeat->m_attachmentOffsetX); // transport offsetX - data << float(veSeat->m_attachmentOffsetY); // transport offsetY - data << float(veSeat->m_attachmentOffsetZ); // transport offsetZ - data << float(0); // transport orientation - data << uint32(getMSTime()); // transport time - data << uint8(0); // seat - // end of transport part - data << uint32(0); // fall time - GetSession()->SendPacket(&data); - - data.Initialize(SMSG_PET_SPELLS, 8+4+4+4+4*10+1+1); - data << uint64(vehicle->GetGUID()); - data << uint32(0x00000000); - data << uint32(0x00000000); - data << uint32(0x00000101); - - for(uint32 i = 0; i < 10; ++i) - data << uint16(0) << uint8(0) << uint8(i+8); - - data << uint8(0); - data << uint8(0); - GetSession()->SendPacket(&data); -} - -void Player::ExitVehicle(Vehicle *vehicle) -{ - vehicle->SetCharmerGUID(0); - vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); - - SetCharm(NULL); - SetFarSight(NULL); - - SetClientControl(vehicle, 0); - - WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30); - data.append(GetPackGUID()); - data << uint32(0); // counter? - data << uint32(MOVEMENTFLAG_FLY_UNK1); // fly unk - data << uint16(0x40); // special flags - data << uint32(getMSTime()); // time - data << vehicle->GetPositionX(); // x - data << vehicle->GetPositionY(); // y - data << vehicle->GetPositionZ(); // z - data << vehicle->GetOrientation(); // o - data << uint32(0); // fall time - GetSession()->SendPacket(&data); - - data.Initialize(SMSG_PET_SPELLS, 8+4); - data << uint64(0); - data << uint32(0); - GetSession()->SendPacket(&data); - - // only for flyable vehicles? - CastSpell(this, 45472, true); // Parachute -} - bool Player::HasTitle(uint32 bitIndex) { if (bitIndex > 128) @@ -19881,6 +19286,7 @@ void Player::SetTitle(CharTitlesEntry const* title) SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag); } + /*-----------------------TRINITY--------------------------*/ bool Player::isTotalImmunity() { @@ -19937,52 +19343,3 @@ void Player::UpdateCharmedAI() Attack(target, true); } } - -void Player::ConvertRune(uint8 index, uint8 newType) -{ - SetCurrentRune(index, newType); - - WorldPacket data(SMSG_CONVERT_RUNE, 2); - data << uint8(index); - data << uint8(newType); - GetSession()->SendPacket(&data); -} - -void Player::ResyncRunes(uint8 count) -{ - WorldPacket data(SMSG_RESYNC_RUNES, count * 2); - for(uint32 i = 0; i < count; ++i) - { - data << uint8(GetCurrentRune(i)); // rune type - data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255) - } - GetSession()->SendPacket(&data); -} - -void Player::AddRunePower(uint8 index) -{ - WorldPacket data(SMSG_ADD_RUNE_POWER, 4); - data << uint32(1 << index); // mask (0x00-0x3F probably) - GetSession()->SendPacket(&data); -} - -void Player::InitRunes() -{ - if(getClass() != CLASS_DEATH_KNIGHT) - return; - - m_runes = new Runes; - - m_runes->runeState = 0; - - for(uint32 i = 0; i < MAX_RUNES; ++i) - { - SetBaseRune(i, i / 2); // init base types - SetCurrentRune(i, i / 2); // init current types - SetRuneCooldown(i, 0); // reset cooldowns - m_runes->SetRuneState(i); - } - - for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i) - SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); -} diff --git a/src/game/Player.h b/src/game/Player.h index 3b236c5e4e5..9187ca3968d 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -35,7 +35,6 @@ #include "Pet.h" #include "MapReference.h" #include "Util.h" // for Tokens typedef -#include "AchievementMgr.h" #include #include @@ -50,8 +49,6 @@ class Transport; class UpdateMask; class PlayerSocial; class OutdoorPvP; -class AchievementMgr; -class Vehicle; typedef std::deque PlayerMails; @@ -83,17 +80,15 @@ struct PlayerSpell #define SPELL_WITHOUT_SLOT_ID uint16(-1) -// Spell modifier (used for modify other spells) struct SpellModifier { - SpellModifier() : charges(0), lastAffected(NULL) {} SpellModOp op : 8; SpellModType type : 8; int16 charges : 16; int32 value; uint64 mask; - uint64 mask2; uint32 spellId; + uint32 effectId; Spell const* lastAffected; }; @@ -229,39 +224,6 @@ struct Areas float y2; }; -#define MAX_RUNES 6 -#define RUNE_COOLDOWN 5 // 5*2=10 sec - -enum RuneType -{ - RUNE_BLOOD = 0, - RUNE_UNHOLY = 1, - RUNE_FROST = 2, - RUNE_DEATH = 3, - NUM_RUNE_TYPES = 4 -}; - -struct RuneInfo -{ - uint8 BaseRune; - uint8 CurrentRune; - uint8 Cooldown; -}; - -struct Runes -{ - RuneInfo runes[MAX_RUNES]; - uint8 runeState; // mask of available runes - - void SetRuneState(uint8 index, bool set = true) - { - if(set) - runeState |= (1 << index); // usable - else - runeState &= ~(1 << index); // on cooldown - } -}; - enum FactionFlags { FACTION_FLAG_VISIBLE = 0x01, // makes visible in client (set or can be set at interaction with target of this faction) @@ -430,7 +392,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag PLAYER_FLAGS_SANCTUARY = 0x00010000, // player entered sanctuary PLAYER_FLAGS_UNK4 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1) - PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually) + PLAYER_UNK = 0x00040000, // 2.0.8... }; // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1< QuestStatusMap; @@ -584,7 +544,7 @@ enum PlayerSlots // first slot for item stored (in any way in player m_items data) PLAYER_SLOT_START = 0, // last+1 slot for item stored (in any way in player m_items data) - PLAYER_SLOT_END = 200, + PLAYER_SLOT_END = 118, PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START) }; @@ -712,24 +672,6 @@ enum KeyRingSlots KEYRING_SLOT_END = 118 }; -enum VanityPetSlots -{ - VANITYPET_SLOT_START = 118, - VANITYPET_SLOT_END = 136 -}; - -enum CurrencyTokenSlots -{ - CURRENCYTOKEN_SLOT_START = 136, - CURRENCYTOKEN_SLOT_END = 168 -}; - -enum QuestBagSlots -{ - QUESTBAG_SLOT_START = 168, - QUESTBAG_SLOT_END = 200 -}; - struct ItemPosCount { ItemPosCount(uint16 _pos, uint8 _count) : pos(_pos), count(_count) {} @@ -748,15 +690,14 @@ enum TradeSlots enum TransferAbortReason { - TRANSFER_ABORT_ERROR = 0x00, - TRANSFER_ABORT_MAX_PLAYERS = 0x01, // Transfer Aborted: instance is full - TRANSFER_ABORT_NOT_FOUND = 0x02, // Transfer Aborted: instance not found - TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x03, // You have entered too many instances recently. - TRANSFER_ABORT_ZONE_IN_COMBAT = 0x05, // Unable to zone in while an encounter is in progress. - TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x06, // You must have expansion installed to access this area. - TRANSFER_ABORT_DIFFICULTY = 0x07, // difficulty mode is not available for %s. - TRANSFER_ABORT_UNIQUE_MESSAGE = 0x08, // Until you've escaped TLK's grasp, you cannot leave this place! - TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x09 // Additional instances cannot be launched, please try again later. + TRANSFER_ABORT_MAX_PLAYERS = 0x0001, // Transfer Aborted: instance is full + TRANSFER_ABORT_NOT_FOUND = 0x0002, // Transfer Aborted: instance not found + TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x0003, // You have entered too many instances recently. + TRANSFER_ABORT_ZONE_IN_COMBAT = 0x0005, // Unable to zone in while an encounter is in progress. + TRANSFER_ABORT_INSUF_EXPAN_LVL1 = 0x0106, // You must have TBC expansion installed to access this area. + TRANSFER_ABORT_DIFFICULTY1 = 0x0007, // Normal difficulty mode is not available for %s. + TRANSFER_ABORT_DIFFICULTY2 = 0x0107, // Heroic difficulty mode is not available for %s. + TRANSFER_ABORT_DIFFICULTY3 = 0x0207 // Epic difficulty mode is not available for %s. }; enum InstanceResetWarningType @@ -770,16 +711,15 @@ enum InstanceResetWarningType struct MovementInfo { // common - uint32 flags; - uint16 unk1; + //uint32 flags; + uint8 unk1; uint32 time; float x, y, z, o; // transport uint64 t_guid; float t_x, t_y, t_z, t_o; uint32 t_time; - int8 t_seat; - // swimming and unknown + // swimming and unk float s_pitch; // last fall time uint32 fallTime; @@ -790,17 +730,17 @@ struct MovementInfo MovementInfo() { - flags = 0; + //flags = time = t_time = fallTime = 0; unk1 = 0; x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f; t_guid = 0; } - void SetMovementFlags(uint32 _flags) + /*void SetMovementFlags(uint32 _flags) { flags = _flags; - } + }*/ }; // flags that use in movement check for example at spell casting @@ -873,11 +813,9 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16, PLAYER_LOGIN_QUERY_LOADGUILD = 17, PLAYER_LOGIN_QUERY_LOADARENAINFO = 18, - PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS = 19, - PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS = 20, - MAX_PLAYER_LOGIN_QUERY = 21 -}; + MAX_PLAYER_LOGIN_QUERY +}; // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) @@ -899,7 +837,7 @@ class TRINITY_DLL_SPEC PlayerTaxi PlayerTaxi(); ~PlayerTaxi() {} // Nodes - void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level); + void InitTaxiNodesForLevel(uint32 race, uint32 level); void LoadTaxiMask(const char* data); void SaveTaxiMask(const char* data); @@ -1002,7 +940,7 @@ class TRINITY_DLL_SPEC Player : public Unit void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); - void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0); + void SendTransferAborted(uint32 mapid, uint16 reason); void SendInstanceResetWarning(uint32 mapid, uint32 time); bool CanInteractWithNPCs(bool alive = true) const; @@ -1015,12 +953,10 @@ class TRINITY_DLL_SPEC Player : public Unit std::string afkMsg; std::string dndMsg; - uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair); - PlayerSocial *GetSocial() { return m_social; } PlayerTaxi m_taxi; - void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); } + void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(),getLevel()); } bool ActivateTaxiPathTo(std::vector const& nodes, uint32 mount_id = 0 , Creature* npc = NULL); // mount_id can be used in scripting calls bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); } @@ -1116,7 +1052,6 @@ class TRINITY_DLL_SPEC Player : public Unit bool HasBankBagSlot( uint8 slot ) const; bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const; bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL); - bool CanNoReagentCast(SpellEntry const* spellInfo) const; Item* GetItemOrItemWithGemEquipped( uint32 item ) const; uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); } uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); } @@ -1195,11 +1130,6 @@ class TRINITY_DLL_SPEC Player : public Unit // disarm applied only to mainhand weapon return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) ); } - bool IsTwoHandUsed() const - { - Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); - } void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false ); bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot); @@ -1355,7 +1285,6 @@ class TRINITY_DLL_SPEC Player : public Unit static void SetFloatValueInArray(Tokens& data,uint16 index, float value); static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid); static void SetFloatValueInDB(uint16 index, float value, uint64 guid); - static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair); static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid); bool m_mailsLoaded; @@ -1494,12 +1423,6 @@ class TRINITY_DLL_SPEC Player : public Unit uint32 resetTalentsCost() const; void InitTalentForLevel(); - void InitGlyphsForLevel(); - void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); } - uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } - void SetGlyph(uint8 slot, uint32 glyph) { SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); } - uint32 GetGlyph(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot); } - uint32 GetFreePrimaryProffesionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); } void SetFreePrimaryProffesions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2,profs); } void InitPrimaryProffesions(); @@ -1508,6 +1431,8 @@ class TRINITY_DLL_SPEC Player : public Unit PlayerSpellMap & GetSpellMap() { return m_spells; } void AddSpellMod(SpellModifier* mod, bool apply); + int32 GetTotalFlatMods(uint32 spellId, SpellModOp op); + int32 GetTotalPctMods(uint32 spellId, SpellModOp op); bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL); template T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL); void RemoveSpellMods(Spell const* spell); @@ -1664,10 +1589,6 @@ class TRINITY_DLL_SPEC Player : public Unit void UpdateAllCritPercentages(); void UpdateParryPercentage(); void UpdateDodgePercentage(); - void UpdateMeleeHitChances(); - void UpdateRangedHitChances(); - void UpdateSpellHitChances(); - void UpdateAllSpellCritChances(); void UpdateSpellCritChance(uint32 school); void UpdateExpertise(WeaponAttackType attType); @@ -1838,8 +1759,6 @@ class TRINITY_DLL_SPEC Player : public Unit void SetCanParry(bool value); bool CanBlock() const { return m_canBlock; } void SetCanBlock(bool value); - bool CanTitanGrip() const { return m_canTitanGrip ; } - void SetCanTitanGrip(bool value) { m_canTitanGrip = value; } void SetRegularAttackTime(); void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; } @@ -1873,7 +1792,7 @@ class TRINITY_DLL_SPEC Player : public Unit void SendUpdateWorldState(uint32 Field, uint32 Value); void SendDirectMessage(WorldPacket *data); - void SendAurasForTarget(Unit *target); + void SendAuraDurationsForTarget(Unit* target); PlayerMenu* PlayerTalkClass; std::vector ItemSetEff; @@ -2034,7 +1953,6 @@ class TRINITY_DLL_SPEC Player : public Unit MovementInfo m_movementInfo; uint32 m_lastFallTime; float m_lastFallZ; - Unit *m_mover; void SetFallInformation(uint32 time, float z) { m_lastFallTime = time; @@ -2052,9 +1970,6 @@ class TRINITY_DLL_SPEC Player : public Unit void SetClientControl(Unit* target, uint8 allowMove); - void EnterVehicle(Vehicle *vehicle); - void ExitVehicle(Vehicle *vehicle); - uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); } void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); } @@ -2067,7 +1982,6 @@ class TRINITY_DLL_SPEC Player : public Unit float GetTransOffsetZ() const { return m_movementInfo.t_z; } float GetTransOffsetO() const { return m_movementInfo.t_o; } uint32 GetTransTime() const { return m_movementInfo.t_time; } - int8 GetTransSeat() const { return m_movementInfo.t_seat; } uint32 GetSaveTimer() const { return m_nextSave; } void SetSaveTimer(uint32 timer) { m_nextSave = timer; } @@ -2166,18 +2080,6 @@ class TRINITY_DLL_SPEC Player : public Unit WorldLocation& GetTeleportDest() { return m_teleport_dest; } DeclinedName const* GetDeclinedNames() const { return m_declinedname; } - uint8 GetRunesState() const { return m_runes->runeState; } - uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; } - uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; } - uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } - void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; } - void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; } - void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); } - void ConvertRune(uint8 index, uint8 newType); - void ResyncRunes(uint8 count); - void AddRunePower(uint8 index); - void InitRunes(); - AchievementMgr& GetAchievementMgr() { return m_achievementMgr; } bool HasTitle(uint32 bitIndex); bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); } void SetTitle(CharTitlesEntry const* title); @@ -2314,7 +2216,6 @@ class TRINITY_DLL_SPEC Player : public Unit ActionButtonList m_actionButtons; float m_auraBaseMod[BASEMOD_END][MOD_END]; - int16 m_baseRatingValue[MAX_COMBAT_RATING]; SpellModList m_spellMods[MAX_SPELLMOD]; int32 m_SpellModRemoveCount; @@ -2348,6 +2249,7 @@ class TRINITY_DLL_SPEC Player : public Unit bool m_DailyQuestChanged; time_t m_lastDailyQuestTime; + uint32 m_regenTimer; uint32 m_breathTimer; uint32 m_drunkTimer; uint16 m_drunk; @@ -2366,10 +2268,8 @@ class TRINITY_DLL_SPEC Player : public Unit uint32 m_ArmorProficiency; bool m_canParry; bool m_canBlock; - bool m_canTitanGrip; uint8 m_swingErrorMsg; float m_ammoDPS; - ////////////////////Rest System///////////////////// int time_inn_enter; uint32 inn_pos_mapid; @@ -2416,8 +2316,6 @@ class TRINITY_DLL_SPEC Player : public Unit bool m_farsightVision; DeclinedName *m_declinedname; - Runes *m_runes; - AchievementMgr m_achievementMgr; private: // internal common parts for CanStore/StoreItem functions uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const; diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index 5b5679a81d7..9f9eecc2234 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -33,7 +33,6 @@ #include "NPCHandler.h" #include "ObjectAccessor.h" #include "Pet.h" -#include "MapManager.h" void WorldSession::SendNameQueryOpcode(Player *p) { @@ -186,6 +185,7 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) data << (uint32)ci->type; data << (uint32)ci->family; // family wdbFeild9 data << (uint32)ci->rank; // rank wdbFeild10 + data << (uint32)0; // unknown wdbFeild11 data << (uint32)ci->PetSpellDataId; // Id from CreatureSpellData.dbc wdbField12 data << (uint32)ci->Modelid1; // Modelid1 data << (uint32)ci->Modelid2; // Modelid2 @@ -276,43 +276,20 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) Corpse *corpse = GetPlayer()->GetCorpse(); + uint8 found = 1; if(!corpse) + found = 0; + + WorldPacket data(MSG_CORPSE_QUERY, (1+found*(5*4))); + data << uint8(found); + if(found) { - WorldPacket data(MSG_CORPSE_QUERY, 1); - data << uint8(0); // corpse not found - SendPacket(&data); - return; + data << corpse->GetMapId(); + data << corpse->GetPositionX(); + data << corpse->GetPositionY(); + data << corpse->GetPositionZ(); + data << _player->GetMapId(); } - - int32 mapid = corpse->GetMapId(); - float x = corpse->GetPositionX(); - float y = corpse->GetPositionY(); - float z = corpse->GetPositionZ(); - int32 corpsemapid = _player->GetMapId(); - - if(Map *map = corpse->GetMap()) - { - if(map->IsDungeon()) - { - if(!map->GetEntrancePos(mapid, x, y)) - return; - - Map *entrance_map = MapManager::Instance().GetMap(mapid, _player); - if(!entrance_map) - return; - - z = entrance_map->GetHeight(x, y, MAX_HEIGHT); - corpsemapid = corpse->GetMapId(); - } - } - - WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4)); - data << uint8(1); // corpse found - data << int32(mapid); - data << float(x); - data << float(y); - data << float(z); - data << int32(corpsemapid); SendPacket(&data); } diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp index e56a3a4c982..4dd202bc344 100644 --- a/src/game/QuestDef.cpp +++ b/src/game/QuestDef.cpp @@ -44,90 +44,88 @@ Quest::Quest(Field * questRecord) QuestFlags = questRecord[17].GetUInt16(); uint32 SpecialFlags = questRecord[18].GetUInt16(); CharTitleId = questRecord[19].GetUInt32(); - PlayersSlain = questRecord[20].GetUInt32(); - BonusTalents = questRecord[21].GetUInt32(); - PrevQuestId = questRecord[22].GetInt32(); - NextQuestId = questRecord[23].GetInt32(); - ExclusiveGroup = questRecord[24].GetInt32(); - NextQuestInChain = questRecord[25].GetUInt32(); - SrcItemId = questRecord[26].GetUInt32(); - SrcItemCount = questRecord[27].GetUInt32(); - SrcSpell = questRecord[28].GetUInt32(); - Title = questRecord[29].GetCppString(); - Details = questRecord[30].GetCppString(); - Objectives = questRecord[31].GetCppString(); - OfferRewardText = questRecord[32].GetCppString(); - RequestItemsText = questRecord[33].GetCppString(); - EndText = questRecord[34].GetCppString(); + PrevQuestId = questRecord[20].GetInt32(); + NextQuestId = questRecord[21].GetInt32(); + ExclusiveGroup = questRecord[22].GetInt32(); + NextQuestInChain = questRecord[23].GetUInt32(); + SrcItemId = questRecord[24].GetUInt32(); + SrcItemCount = questRecord[25].GetUInt32(); + SrcSpell = questRecord[26].GetUInt32(); + Title = questRecord[27].GetCppString(); + Details = questRecord[28].GetCppString(); + Objectives = questRecord[29].GetCppString(); + OfferRewardText = questRecord[30].GetCppString(); + RequestItemsText = questRecord[31].GetCppString(); + EndText = questRecord[32].GetCppString(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ObjectiveText[i] = questRecord[35+i].GetCppString(); + ObjectiveText[i] = questRecord[33+i].GetCppString(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ReqItemId[i] = questRecord[39+i].GetUInt32(); + ReqItemId[i] = questRecord[37+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ReqItemCount[i] = questRecord[43+i].GetUInt32(); + ReqItemCount[i] = questRecord[41+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - ReqSourceId[i] = questRecord[47+i].GetUInt32(); + ReqSourceId[i] = questRecord[45+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - ReqSourceCount[i] = questRecord[51+i].GetUInt32(); + ReqSourceCount[i] = questRecord[49+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - ReqSourceRef[i] = questRecord[55+i].GetUInt32(); + ReqSourceRef[i] = questRecord[53+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ReqCreatureOrGOId[i] = questRecord[59+i].GetInt32(); + ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ReqCreatureOrGOCount[i] = questRecord[63+i].GetUInt32(); + ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ReqSpell[i] = questRecord[67+i].GetUInt32(); + ReqSpell[i] = questRecord[65+i].GetUInt32(); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) - RewChoiceItemId[i] = questRecord[71+i].GetUInt32(); + RewChoiceItemId[i] = questRecord[69+i].GetUInt32(); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) - RewChoiceItemCount[i] = questRecord[77+i].GetUInt32(); + RewChoiceItemCount[i] = questRecord[75+i].GetUInt32(); for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) - RewItemId[i] = questRecord[83+i].GetUInt32(); + RewItemId[i] = questRecord[81+i].GetUInt32(); for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) - RewItemCount[i] = questRecord[87+i].GetUInt32(); + RewItemCount[i] = questRecord[85+i].GetUInt32(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - RewRepFaction[i] = questRecord[91+i].GetUInt32(); + RewRepFaction[i] = questRecord[89+i].GetUInt32(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - RewRepValue[i] = questRecord[96+i].GetInt32(); + RewRepValue[i] = questRecord[94+i].GetInt32(); - RewHonorableKills = questRecord[101].GetUInt32(); - RewOrReqMoney = questRecord[102].GetInt32(); - RewMoneyMaxLevel = questRecord[103].GetUInt32(); - RewSpell = questRecord[104].GetUInt32(); - RewSpellCast = questRecord[105].GetUInt32(); - RewMailTemplateId = questRecord[106].GetUInt32(); - RewMailDelaySecs = questRecord[107].GetUInt32(); - PointMapId = questRecord[108].GetUInt32(); - PointX = questRecord[109].GetFloat(); - PointY = questRecord[110].GetFloat(); - PointOpt = questRecord[111].GetUInt32(); + RewHonorableKills = questRecord[99].GetUInt32(); + RewOrReqMoney = questRecord[100].GetInt32(); + RewMoneyMaxLevel = questRecord[101].GetUInt32(); + RewSpell = questRecord[102].GetUInt32(); + RewSpellCast = questRecord[103].GetUInt32(); + RewMailTemplateId = questRecord[104].GetUInt32(); + RewMailDelaySecs = questRecord[105].GetUInt32(); + PointMapId = questRecord[106].GetUInt32(); + PointX = questRecord[107].GetFloat(); + PointY = questRecord[108].GetFloat(); + PointOpt = questRecord[109].GetUInt32(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - DetailsEmote[i] = questRecord[112+i].GetUInt32(); + DetailsEmote[i] = questRecord[110+i].GetUInt32(); - IncompleteEmote = questRecord[116].GetUInt32(); - CompleteEmote = questRecord[117].GetUInt32(); + IncompleteEmote = questRecord[114].GetUInt32(); + CompleteEmote = questRecord[115].GetUInt32(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - OfferRewardEmote[i] = questRecord[118+i].GetInt32(); + OfferRewardEmote[i] = questRecord[116+i].GetInt32(); - QuestStartScript = questRecord[122].GetUInt32(); - QuestCompleteScript = questRecord[123].GetUInt32(); + QuestStartScript = questRecord[120].GetUInt32(); + QuestCompleteScript = questRecord[121].GetUInt32(); QuestFlags |= SpecialFlags << 16; diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index 1904cbe08a8..52f58c2c87e 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -44,33 +44,30 @@ class ObjectMgr; enum QuestFailedReasons { INVALIDREASON_DONT_HAVE_REQ = 0, - INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, // You are not high enough level for that quest. - INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, // That quest is not available to your race. - INVALIDREASON_QUEST_ALREADY_DONE = 7, // You have completed that quest. - INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, // You can only be on one timed quest at a time. - INVALIDREASON_QUEST_ALREADY_ON = 13, // You are already on that quest. - INVALIDREASON_QUEST_FAILED_EXPANSION = 16, // This quest requires an expansion enabled account. - INVALIDREASON_QUEST_ALREADY_ON2 = 18, // You are already on that quest. - INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, // You don't have the required items with you. Check storage. - INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, // You don't have enough money for that quest. - INVALIDREASON_DAILY_QUESTS_REMAINING = 26, // You have already completed 25 daily quests today. - INVALIDREASON_QUEST_FAILED_CAIS = 27, // You cannot complete quests once you have reached tired time. - INVALIDREASON_DAILY_QUEST_COMPLETED_TODAY = 29 // You have completed that daily quest today. + INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest. + INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race. + INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest. + INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time. + INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest + INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account. + INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest + INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage. + INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest. + INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today + INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time }; enum QuestShareMessages { - QUEST_PARTY_MSG_SHARING_QUEST = 0, - QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1, - QUEST_PARTY_MSG_ACCEPT_QUEST = 2, - QUEST_PARTY_MSG_DECLINE_QUEST = 3, - QUEST_PARTY_MSG_BUSY = 4, - QUEST_PARTY_MSG_LOG_FULL = 5, - QUEST_PARTY_MSG_HAVE_QUEST = 6, - QUEST_PARTY_MSG_FINISH_QUEST = 7, - QUEST_PARTY_MSG_CANT_BE_SHARED_TODAY = 8, - QUEST_PARTY_MSG_SHARING_TIMER_EXPIRED = 9, - QUEST_PARTY_MSG_NOT_IN_PARTY = 10 + QUEST_PARTY_MSG_SHARING_QUEST = 0, + QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1, + QUEST_PARTY_MSG_ACCEPT_QUEST = 2, + QUEST_PARTY_MSG_REFUSE_QUEST = 3, + QUEST_PARTY_MSG_TOO_FAR = 4, + QUEST_PARTY_MSG_BUSY = 5, + QUEST_PARTY_MSG_LOG_FULL = 6, + QUEST_PARTY_MSG_HAVE_QUEST = 7, + QUEST_PARTY_MSG_FINISH_QUEST = 8, }; enum __QuestTradeSkill @@ -193,8 +190,6 @@ class Quest int32 GetExclusiveGroup() const { return ExclusiveGroup; } uint32 GetNextQuestInChain() const { return NextQuestInChain; } uint32 GetCharTitleId() const { return CharTitleId; } - uint32 GetPlayersSlain() const { return PlayersSlain; } - uint32 GetBonusTalents() const { return BonusTalents; } uint32 GetSrcItemId() const { return SrcItemId; } uint32 GetSrcItemCount() const { return SrcItemCount; } uint32 GetSrcSpell() const { return SrcSpell; } @@ -282,8 +277,6 @@ class Quest uint32 LimitTime; uint32 QuestFlags; uint32 CharTitleId; - uint32 PlayersSlain; - uint32 BonusTalents; int32 PrevQuestId; int32 NextQuestId; int32 ExclusiveGroup; diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 784a2affbc0..abb285e6dbb 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -451,6 +451,12 @@ void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket) _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); + if( _player->GetDistance( pPlayer ) > 10 ) + { + _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR ); + continue; + } + if( !pPlayer->SatisfyQuestStatus( pQuest, false ) ) { _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST ); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 7a79a54e419..bf23a724520 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -88,8 +88,7 @@ enum Classes #define CLASSMASK_ALL_PLAYABLE \ ((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \ (1<<(CLASS_ROGUE-1)) |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \ - (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \ - (1<<(CLASS_DEATH_KNIGHT-1)) ) + (1<<(CLASS_MAGE-1)) |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) ) #define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1))) @@ -135,12 +134,11 @@ enum Powers POWER_FOCUS = 2, POWER_ENERGY = 3, POWER_HAPPINESS = 4, - POWER_RUNE = 5, - POWER_RUNIC_POWER = 6, + POWER_RUNES = 5, POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) }; -#define MAX_POWERS 7 +#define MAX_POWERS 5 // not count POWER_RUNES for now enum SpellSchools { @@ -201,11 +199,10 @@ enum ItemQualities ITEM_QUALITY_RARE = 3, //BLUE ITEM_QUALITY_EPIC = 4, //PURPLE ITEM_QUALITY_LEGENDARY = 5, //ORANGE - ITEM_QUALITY_ARTIFACT = 6, //LIGHT YELLOW - ITEM_QUALITY_HEIRLOOM = 7 + ITEM_QUALITY_ARTIFACT = 6 //LIGHT YELLOW }; -#define MAX_ITEM_QUALITY 8 +#define MAX_ITEM_QUALITY 7 enum SpellCategory { @@ -220,7 +217,7 @@ enum SpellCategory #define SPELL_ATTR_UNK0 0x00000001 // 0 #define SPELL_ATTR_RANGED 0x00000002 // 1 All ranged abilities have this flag #define SPELL_ATTR_ON_NEXT_SWING_1 0x00000004 // 2 on next swing -#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 3.0.3 +#define SPELL_ATTR_UNK3 0x00000008 // 3 not set in 2.4.2 #define SPELL_ATTR_UNK4 0x00000010 // 4 #define SPELL_ATTR_UNK5 0x00000020 // 5 trade spells? #define SPELL_ATTR_PASSIVE 0x00000040 // 6 Passive spell @@ -275,7 +272,7 @@ enum SpellCategory #define SPELL_ATTR_EX_REQ_COMBO_POINTS2 0x00400000 // 22 Req combo points on target #define SPELL_ATTR_EX_UNK23 0x00800000 // 23 #define SPELL_ATTR_EX_UNK24 0x01000000 // 24 Req fishing pole?? -#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 +#define SPELL_ATTR_EX_UNK25 0x02000000 // 25 not set in 2.4.2 #define SPELL_ATTR_EX_UNK26 0x04000000 // 26 #define SPELL_ATTR_EX_UNK27 0x08000000 // 27 #define SPELL_ATTR_EX_UNK28 0x10000000 // 28 @@ -291,14 +288,14 @@ enum SpellCategory #define SPELL_ATTR_EX2_UNK5 0x00000020 // 5 #define SPELL_ATTR_EX2_UNK6 0x00000040 // 6 #define SPELL_ATTR_EX2_UNK7 0x00000080 // 7 -#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 3.0.3 +#define SPELL_ATTR_EX2_UNK8 0x00000100 // 8 not set in 2.4.2 #define SPELL_ATTR_EX2_UNK9 0x00000200 // 9 #define SPELL_ATTR_EX2_UNK10 0x00000400 // 10 #define SPELL_ATTR_EX2_HEALTH_FUNNEL 0x00000800 // 11 #define SPELL_ATTR_EX2_UNK12 0x00001000 // 12 #define SPELL_ATTR_EX2_UNK13 0x00002000 // 13 #define SPELL_ATTR_EX2_UNK14 0x00004000 // 14 -#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 3.0.3 +#define SPELL_ATTR_EX2_UNK15 0x00008000 // 15 not set in 2.4.2 #define SPELL_ATTR_EX2_TAME_BEAST 0x00010000 // 16 #define SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT 0x00020000 // 17 Hunters Shot and Stings only have this flag #define SPELL_ATTR_EX2_UNK18 0x00040000 // 18 Only Revive pet - possible req dead pet @@ -416,37 +413,37 @@ enum SpellCategory #define SPELL_ATTR_EX5_UNK31 0x80000000 // 31 Forces all nearby enemies to focus attacks caster #define SPELL_ATTR_EX6_UNK0 0x00000001 // 0 Only Move spell have this flag -#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK1 0x00000002 // 1 not set in 2.4.2 #define SPELL_ATTR_EX6_UNK2 0x00000004 // 2 #define SPELL_ATTR_EX6_UNK3 0x00000008 // 3 -#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4 +#define SPELL_ATTR_EX6_UNK4 0x00000010 // 4 not set in 2.4.2 #define SPELL_ATTR_EX6_UNK5 0x00000020 // 5 #define SPELL_ATTR_EX6_UNK6 0x00000040 // 6 #define SPELL_ATTR_EX6_UNK7 0x00000080 // 7 #define SPELL_ATTR_EX6_UNK8 0x00000100 // 8 -#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX6_UNK9 0x00000200 // 9 not set in 2.4.2 #define SPELL_ATTR_EX6_UNK10 0x00000400 // 10 #define SPELL_ATTR_EX6_UNK11 0x00000800 // 11 -#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12 -#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13 -#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14 -#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16 -#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17 -#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18 -#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19 -#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20 -#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21 -#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22 -#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 3.0.3 -#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK12 0x00001000 // 12 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK13 0x00002000 // 13 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK14 0x00004000 // 14 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK15 0x00008000 // 15 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK16 0x00010000 // 16 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK17 0x00020000 // 17 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK18 0x00040000 // 18 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK19 0x00080000 // 19 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK20 0x00100000 // 20 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK21 0x00200000 // 21 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK22 0x00400000 // 22 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK23 0x00800000 // 23 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK24 0x01000000 // 24 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK25 0x02000000 // 25 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK26 0x04000000 // 26 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK27 0x08000000 // 27 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK28 0x10000000 // 28 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK29 0x20000000 // 29 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 2.4.2 enum SheathTypes { @@ -569,7 +566,7 @@ enum SpellEffects SPELL_EFFECT_SUMMON_GUARDIAN = 42, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43, SPELL_EFFECT_SKILL_STEP = 44, - SPELL_EFFECT_ADD_HONOR = 45, + SPELL_EFFECT_UNDEFINED_45 = 45, SPELL_EFFECT_SPAWN = 46, SPELL_EFFECT_TRADE_SKILL = 47, SPELL_EFFECT_STEALTH = 48, @@ -589,16 +586,16 @@ enum SpellEffects SPELL_EFFECT_POWER_BURN = 62, SPELL_EFFECT_THREAT = 63, SPELL_EFFECT_TRIGGER_SPELL = 64, - SPELL_EFFECT_APPLY_AREA_AURA_RAID = 65, - SPELL_EFFECT_CREATE_MANA_GEM = 66, + SPELL_EFFECT_HEALTH_FUNNEL = 65, + SPELL_EFFECT_POWER_FUNNEL = 66, SPELL_EFFECT_HEAL_MAX_HEALTH = 67, SPELL_EFFECT_INTERRUPT_CAST = 68, SPELL_EFFECT_DISTRACT = 69, SPELL_EFFECT_PULL = 70, SPELL_EFFECT_PICKPOCKET = 71, SPELL_EFFECT_ADD_FARSIGHT = 72, - SPELL_EFFECT_UNTRAIN_TALENTS = 73, - SPELL_EFFECT_APPLY_GLYPH = 74, + SPELL_EFFECT_SUMMON_POSSESSED = 73, + SPELL_EFFECT_SUMMON_TOTEM = 74, SPELL_EFFECT_HEAL_MECHANICAL = 75, SPELL_EFFECT_SUMMON_OBJECT_WILD = 76, SPELL_EFFECT_SCRIPT_EFFECT = 77, @@ -611,10 +608,10 @@ enum SpellEffects SPELL_EFFECT_STUCK = 84, SPELL_EFFECT_SUMMON_PLAYER = 85, SPELL_EFFECT_ACTIVATE_OBJECT = 86, - SPELL_EFFECT_WMO_DAMAGE = 87, - SPELL_EFFECT_WMO_REPAIR = 88, - SPELL_EFFECT_WMO_CHANGE = 89, - SPELL_EFFECT_KILL_CREDIT = 90, + SPELL_EFFECT_SUMMON_TOTEM_SLOT1 = 87, + SPELL_EFFECT_SUMMON_TOTEM_SLOT2 = 88, + SPELL_EFFECT_SUMMON_TOTEM_SLOT3 = 89, + SPELL_EFFECT_SUMMON_TOTEM_SLOT4 = 90, SPELL_EFFECT_THREAT_ALL = 91, SPELL_EFFECT_ENCHANT_HELD_ITEM = 92, SPELL_EFFECT_SUMMON_PHANTASM = 93, //unused @@ -658,19 +655,19 @@ enum SpellEffects SPELL_EFFECT_131 = 131, SPELL_EFFECT_132 = 132, SPELL_EFFECT_UNLEARN_SPECIALIZATION = 133, - SPELL_EFFECT_KILL_CREDIT2 = 134, + SPELL_EFFECT_KILL_CREDIT = 134, SPELL_EFFECT_135 = 135, SPELL_EFFECT_HEAL_PCT = 136, SPELL_EFFECT_ENERGIZE_PCT = 137, SPELL_EFFECT_138 = 138, - SPELL_EFFECT_CLEAR_QUEST = 139, + SPELL_EFFECT_139 = 139, SPELL_EFFECT_FORCE_CAST = 140, SPELL_EFFECT_141 = 141, SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE = 142, SPELL_EFFECT_APPLY_AREA_AURA_OWNER = 143, SPELL_EFFECT_144 = 144, SPELL_EFFECT_145 = 145, - SPELL_EFFECT_ACTIVATE_RUNE = 146, + SPELL_EFFECT_146 = 146, SPELL_EFFECT_QUEST_FAIL = 147, SPELL_EFFECT_148 = 148, SPELL_EFFECT_149 = 149, @@ -678,13 +675,7 @@ enum SpellEffects SPELL_EFFECT_TRIGGER_SPELL_2 = 151, SPELL_EFFECT_152 = 152, SPELL_EFFECT_153 = 153, - SPELL_EFFECT_154 = 154, - SPELL_EFFECT_TITAN_GRIP = 155, - SPELL_EFFECT_ADD_SOCKET = 156, - SPELL_EFFECT_157 = 157, - SPELL_EFFECT_MILLING = 158, - SPELL_EFFECT_ALLOW_RENAME_PET = 159, - TOTAL_SPELL_EFFECTS = 160 + TOTAL_SPELL_EFFECTS = 154 }; // Spell aura states @@ -712,8 +703,7 @@ enum AuraState AURA_STATE_DEADLY_POISON = 16, // T | AURA_STATE_FORBEARANCE = 17, // c t| AURA_STATE_WEAKENED_SOUL = 18, // t| - AURA_STATE_HYPOTHERMIA = 19, // c | - AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C | not implemented yet + AURA_STATE_HYPOTHERMIA = 19 // c | }; // Spell mechanics @@ -721,11 +711,11 @@ enum Mechanics { MECHANIC_NONE = 0, MECHANIC_CHARM = 1, - MECHANIC_DISORIENTED = 2, + MECHANIC_CONFUSED = 2, MECHANIC_DISARM = 3, MECHANIC_DISTRACT = 4, MECHANIC_FEAR = 5, - MECHANIC_GRIP = 6, + MECHANIC_FUMBLE = 6, MECHANIC_ROOT = 7, MECHANIC_PACIFY = 8, //0 spells use this mechanic MECHANIC_SILENCE = 9, @@ -741,7 +731,7 @@ enum Mechanics MECHANIC_SHIELD = 19, MECHANIC_SHACKLE = 20, MECHANIC_MOUNT = 21, - MECHANIC_INFECTED = 22, + MECHANIC_PERSUADE = 22, //0 spells use this mechanic MECHANIC_TURN = 23, MECHANIC_HORROR = 24, MECHANIC_INVULNERABILITY = 25, @@ -749,13 +739,12 @@ enum Mechanics MECHANIC_DAZE = 27, MECHANIC_DISCOVERY = 28, MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block - MECHANIC_SAPPED = 30, - MECHANIC_ENRAGED = 31 + MECHANIC_SAPPED = 30 }; // Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6) #define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \ - (1<DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) ) + return; + // Find out how many points we have in this field uint32 spentPoints = 0; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 3061ad3f5fb..ffac28c7c58 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -237,7 +237,7 @@ void SpellCastTargets::write ( WorldPacket * data ) { *data << uint32(m_targetMask); - if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) ) + if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) ) { if(m_targetMask & TARGET_FLAG_UNIT) { @@ -357,7 +357,6 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi gameObjTarget = NULL; focusObject = NULL; m_cast_count = 0; - m_glyphIndex = 0; m_triggeredByAuraSpell = NULL; //Auto Shot & Shoot @@ -366,7 +365,6 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi else m_autoRepeat = false; - m_runesState = 0; m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before. m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before. m_timer = 0; // will set to castime in prepare @@ -504,8 +502,6 @@ void Spell::FillTargetMap() case SPELL_EFFECT_TRIGGER_SPELL: //case SPELL_EFFECT_TRIGGER_MISSILE: ?? case SPELL_EFFECT_SKILL_STEP: - case SPELL_EFFECT_PROFICIENCY: - case SPELL_EFFECT_SUMMON_OBJECT_WILD: case SPELL_EFFECT_SELF_RESURRECT: case SPELL_EFFECT_REPUTATION: if(m_targets.getUnitTarget()) @@ -537,7 +533,6 @@ void Spell::FillTargetMap() break; case SPELL_EFFECT_SUMMON_CHANGE_ITEM: case SPELL_EFFECT_ADD_FARSIGHT: - case SPELL_EFFECT_APPLY_GLYPH: case SPELL_EFFECT_STUCK: case SPELL_EFFECT_DESTROY_ALL_TOTEMS: tmpUnitMap.push_back(m_caster); @@ -551,7 +546,6 @@ void Spell::FillTargetMap() case SPELL_EFFECT_DISENCHANT: case SPELL_EFFECT_FEED_PET: case SPELL_EFFECT_PROSPECTING: - case SPELL_EFFECT_MILLING: if(m_targets.getItemTarget()) AddItemTarget(m_targets.getItemTarget(), i); break; @@ -1116,17 +1110,6 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) return; } - if (unit->GetTypeId() == TYPEID_PLAYER) - { - ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id); - ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); - } - - if(m_caster->GetTypeId() == TYPEID_PLAYER) - { - ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); - } - if( m_caster != unit ) { if( !m_caster->IsFriendlyTo(unit) ) @@ -1337,16 +1320,6 @@ void Spell::SearchChainTarget(std::list &TagUnitMap, Unit* pUnitTarget, f if(!pUnitTarget) return; - // Get spell max affected targets - /*uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; - Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS); - for(Unit::AuraList::const_iterator m = mod.begin(); m != mod.end(); ++m) - { - if (!(*m)->isAffectedOnSpell(m_spellInfo)) - continue; - unMaxTargets+=(*m)->GetModifier()->m_amount; - }*/ - //FIXME: This very like horrible hack and wrong for most spells if(m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE) max_range += unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; @@ -2253,14 +2226,6 @@ void Spell::cast(bool skipCheck) // set to real guid to be sent later to the client m_targets.updateTradeSlotItem(); - if (m_caster->GetTypeId() == TYPEID_PLAYER) - { - if (m_CastItem) - ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); - - ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); - } - // CAST SPELL SendSpellCooldown(); @@ -2703,7 +2668,7 @@ void Spell::finish(bool ok) { SpellEntry const *auraSpellInfo = (*i)->GetSpellProto(); uint32 auraSpellIdx = (*i)->GetEffIndex(); - if (IsAffectedByAura((*i))) + if (IsAffectedBy(auraSpellInfo, auraSpellIdx)) { for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) if( ihit->effectMask & (1<Id); data << uint8(result); // problem + data << uint8(m_cast_count); // single cast or multi 2.3 (0/1) switch (result) { case SPELL_FAILED_REQUIRES_SPELL_FOCUS: @@ -2802,11 +2767,18 @@ void Spell::SendCastResult(uint8 result) case SPELL_FAILED_EQUIPPED_ITEM_CLASS: data << uint32(m_spellInfo->EquippedItemClass); data << uint32(m_spellInfo->EquippedItemSubClassMask); - //data << uint32(m_spellInfo->EquippedItemInventoryTypeMask); + data << uint32(m_spellInfo->EquippedItemInventoryTypeMask); break; } ((Player*)m_caster)->GetSession()->SendPacket(&data); } + else + { + WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4)); + data.append(m_caster->GetPackGUID()); + data << uint32(m_spellInfo->Id); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } } void Spell::SendSpellStart() @@ -2820,9 +2792,6 @@ void Spell::SendSpellStart() if(IsRangedSpell()) castFlags |= CAST_FLAG_AMMO; - if(m_spellInfo->runeCostID) - castFlags |= CAST_FLAG_UNKNOWN10; - Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster; WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2)); @@ -2832,32 +2801,14 @@ void Spell::SendSpellStart() data.append(m_caster->GetPackGUID()); data.append(m_caster->GetPackGUID()); - data << uint8(m_cast_count); // pending spell cast? - data << uint32(m_spellInfo->Id); // spellId - data << uint32(castFlags); // cast flags - data << uint32(m_timer); // delay? + data << uint32(m_spellInfo->Id); + data << uint8(m_cast_count); // single cast or multi 2.3 (0/1) + data << uint16(castFlags); + data << uint32(m_timer); m_targets.write(&data); - if ( castFlags & CAST_FLAG_UNKNOWN6 ) // predicted power? - data << uint32(0); - - if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list - { - uint8 v1 = 0;//m_runesState; - uint8 v2 = 0;//((Player*)m_caster)->GetRunesState(); - data << uint8(v1); // runes state before - data << uint8(v2); // runes state after - for(uint8 i = 0; i < MAX_RUNES; ++i) - { - uint8 m = (1 << i); - if(m & v1) // usable before... - if(!(m & v2)) // ...but on cooldown now... - data << uint8(0); // some unknown byte (time?) - } - } - - if ( castFlags & CAST_FLAG_AMMO ) + if( castFlags & CAST_FLAG_AMMO ) WriteAmmoToPacket(&data); m_caster->SendMessageToSet(&data, true); @@ -2877,13 +2828,6 @@ void Spell::SendSpellGo() if(IsRangedSpell()) castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual - if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID) - { - castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START - castFlags |= CAST_FLAG_UNKNOWN6; // makes cooldowns visible - castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns list - } - WorldPacket data(SMSG_SPELL_GO, 50); // guess size if(m_CastItem) data.append(m_CastItem->GetPackGUID()); @@ -2891,53 +2835,17 @@ void Spell::SendSpellGo() data.append(m_caster->GetPackGUID()); data.append(m_caster->GetPackGUID()); - data << uint8(m_cast_count); // pending spell cast? - data << uint32(m_spellInfo->Id); // spellId - data << uint32(castFlags); // cast flags + data << uint32(m_spellInfo->Id); + data << uint16(castFlags); data << uint32(getMSTime()); // timestamp WriteSpellGoTargets(&data); m_targets.write(&data); - if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk, predicted power? - data << uint32(0); - - if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list - { - uint8 v1 = m_runesState; - uint8 v2 = ((Player*)m_caster)->GetRunesState(); - data << uint8(v1); // runes state before - data << uint8(v2); // runes state after - for(uint8 i = 0; i < MAX_RUNES; ++i) - { - uint8 m = (1 << i); - if(m & v1) // usable before... - if(!(m & v2)) // ...but on cooldown now... - data << uint8(0); // some unknown byte (time?) - } - } - - if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk - { - data << float(0); - data << uint32(0); - } - - if ( castFlags & CAST_FLAG_AMMO ) + if( castFlags & CAST_FLAG_AMMO ) WriteAmmoToPacket(&data); - if ( castFlags & CAST_FLAG_UNKNOWN5 ) // unknown wotlk - { - data << uint32(0); - data << uint32(0); - } - - if ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION ) - { - data << uint8(0); - } - m_caster->SendMessageToSet(&data, true); } @@ -3065,19 +2973,30 @@ void Spell::SendLogExecute() data << uint8(0); break; case SPELL_EFFECT_CREATE_ITEM: - case SPELL_EFFECT_157: data << uint32(m_spellInfo->EffectItemType[0]); break; case SPELL_EFFECT_SUMMON: + case SPELL_EFFECT_SUMMON_WILD: + case SPELL_EFFECT_SUMMON_GUARDIAN: case SPELL_EFFECT_TRANS_DOOR: case SPELL_EFFECT_SUMMON_PET: + case SPELL_EFFECT_SUMMON_POSSESSED: + case SPELL_EFFECT_SUMMON_TOTEM: case SPELL_EFFECT_SUMMON_OBJECT_WILD: case SPELL_EFFECT_CREATE_HOUSE: case SPELL_EFFECT_DUEL: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: + case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: + case SPELL_EFFECT_SUMMON_PHANTASM: + case SPELL_EFFECT_SUMMON_CRITTER: case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: + case SPELL_EFFECT_SUMMON_DEMON: + case SPELL_EFFECT_150: if(Unit *unit = m_targets.getUnitTarget()) data.append(unit->GetPackGUID()); else if(m_targets.getItemTargetGUID()) @@ -3096,13 +3015,6 @@ void Spell::SendLogExecute() else data << uint8(0); break; - case SPELL_EFFECT_RESURRECT: - case SPELL_EFFECT_RESURRECT_NEW: - if(Unit *unit = m_targets.getUnitTarget()) - data.append(unit->GetPackGUID()); - else - data << uint8(0); - break; default: return; } @@ -3116,16 +3028,13 @@ void Spell::SendInterrupted(uint8 result) { WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1)); data.append(m_caster->GetPackGUID()); - data << uint8(m_cast_count); - data << uint32(m_spellInfo->Id); - data << uint8(result); + data << m_spellInfo->Id; + data << result; m_caster->SendMessageToSet(&data, true); data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4)); data.append(m_caster->GetPackGUID()); - data << uint8(m_cast_count); - data << uint32(m_spellInfo->Id); - data << uint8(result); + data << m_spellInfo->Id; m_caster->SendMessageToSet(&data, true); } @@ -3193,19 +3102,10 @@ void Spell::SendChannelStart(uint32 duration) void Spell::SendResurrectRequest(Player* target) { - // Both players and NPCs can resurrect using spells - have a look at creature 28487 for example - // However, the packet structure differs slightly + WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+2+4)); + data << m_caster->GetGUID(); + data << uint32(1) << uint16(0) << uint32(1); - const char* sentName = m_caster->GetTypeId()==TYPEID_PLAYER ?"":m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()); - - WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+strlen(sentName)+1+1+1)); - data << uint64(m_caster->GetGUID()); - data << uint32(strlen(sentName)+1); - - data << sentName; - data << uint8(0); - - data << uint8(m_caster->GetTypeId()==TYPEID_PLAYER ?0:1); target->GetSession()->SendPacket(&data); } @@ -3302,12 +3202,6 @@ void Spell::TakePower() Powers powerType = Powers(m_spellInfo->powerType); - if(powerType == POWER_RUNE) - { - TakeRunePower(); - return; - } - m_caster->ModifyPower(powerType, -(int32)m_powerCost); // Set the five second timer @@ -3315,116 +3209,6 @@ void Spell::TakePower() m_caster->SetLastManaUse(getMSTime()); } -uint8 Spell::CheckRuneCost(uint32 runeCostID) -{ - if(m_caster->GetTypeId() != TYPEID_PLAYER) - return 0; - - Player *plr = (Player*)m_caster; - - if(plr->getClass() != CLASS_DEATH_KNIGHT) - return 0; - - SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(runeCostID); - - if(!src) - return 0; - - if(src->NoRuneCost()) - return 0; - - int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death - - for(uint32 i = 0; i < RUNE_DEATH; ++i) - { - runeCost[i] = src->RuneCost[i]; - } - - runeCost[RUNE_DEATH] = 0; // calculated later - - for(uint32 i = 0; i < MAX_RUNES; ++i) - { - uint8 rune = plr->GetCurrentRune(i); - if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) - { - runeCost[rune]--; - } - } - - for(uint32 i = 0; i < RUNE_DEATH; ++i) - { - if(runeCost[i] > 0) - { - runeCost[RUNE_DEATH] += runeCost[i]; - } - } - - if(runeCost[RUNE_DEATH] > 0) - return SPELL_FAILED_NO_POWER; // not sure if result code is correct - - return 0; -} - -void Spell::TakeRunePower() -{ - if(m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - Player *plr = (Player*)m_caster; - - if(plr->getClass() != CLASS_DEATH_KNIGHT) - return; - - SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID); - - if(!src || (src->NoRuneCost() && src->NoRunicPowerGain())) - return; - - m_runesState = plr->GetRunesState(); // store previous state - - int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death - - for(uint32 i = 0; i < RUNE_DEATH; ++i) - { - runeCost[i] = src->RuneCost[i]; - } - - runeCost[RUNE_DEATH] = 0; // calculated later - - for(uint32 i = 0; i < MAX_RUNES; ++i) - { - uint8 rune = plr->GetCurrentRune(i); - if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) - { - plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec - runeCost[rune]--; - } - } - - runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST]; - - if(runeCost[RUNE_DEATH] > 0) - { - for(uint32 i = 0; i < MAX_RUNES; ++i) - { - uint8 rune = plr->GetCurrentRune(i); - if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH)) - { - plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec - runeCost[rune]--; - plr->ConvertRune(i, plr->GetBaseRune(i)); - if(runeCost[RUNE_DEATH] == 0) - break; - } - } - } - - // you can gain some runic power when use runes - float rp = src->runePowerGain;; - rp *= sWorld.getRate(RATE_POWER_RUNICPOWER_INCOME); - plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp); -} - void Spell::TakeReagents() { if(m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed. @@ -3433,10 +3217,12 @@ void Spell::TakeReagents() if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - Player* p_caster = (Player*)m_caster; - if (p_caster->CanNoReagentCast(m_spellInfo)) + if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && + m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) return; + Player* p_caster = (Player*)m_caster; + for(uint32 x=0;x<8;x++) { if(m_spellInfo->Reagent[x] <= 0) @@ -3558,25 +3344,12 @@ uint8 Spell::CanCast(bool strict) // for now, ignore triggered spells if( strict && !m_IsTriggeredSpell) { - bool checkForm = true; - // Ignore form req aura - Unit::AuraList const& ignore = m_caster->GetAurasByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT); - for(Unit::AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) - { - if (!(*i)->isAffectedOnSpell(m_spellInfo)) - continue; - checkForm = false; - break; - } - if (checkForm) - { - // Cannot be used in this stance/form - if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form)) - return shapeError; + // Cannot be used in this stance/form + if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form)) + return shapeError; - if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) - return SPELL_FAILED_ONLY_STEALTHED; - } + if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) + return SPELL_FAILED_ONLY_STEALTHED; } // caster state requirements @@ -3913,7 +3686,7 @@ uint8 Spell::CanCast(bool strict) case SPELL_EFFECT_SCHOOL_DAMAGE: { // Hammer of Wrath - if(m_spellInfo->SpellVisual[0] == 7250) + if(m_spellInfo->SpellVisual == 7250) { if (!m_targets.getUnitTarget()) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; @@ -3938,9 +3711,15 @@ uint8 Spell::CanCast(bool strict) if(!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; + if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id)) + return SPELL_FAILED_TOO_MANY_SKILLS; + if(m_spellInfo->spellLevel > pet->getLevel()) return SPELL_FAILED_LOWLEVEL; + if(!pet->HasTPForSpell(learn_spellproto->Id)) + return SPELL_FAILED_TRAINING_POINTS; + break; } case SPELL_EFFECT_LEARN_PET_SPELL: @@ -3955,9 +3734,15 @@ uint8 Spell::CanCast(bool strict) if(!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; + if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id)) + return SPELL_FAILED_TOO_MANY_SKILLS; + if(m_spellInfo->spellLevel > pet->getLevel()) return SPELL_FAILED_LOWLEVEL; + if(!pet->HasTPForSpell(learn_spellproto->Id)) + return SPELL_FAILED_TRAINING_POINTS; + break; } case SPELL_EFFECT_FEED_PET: @@ -4060,27 +3845,27 @@ uint8 Spell::CanCast(bool strict) { // check for lock - key pair (checked by client also, just prevent cheating bool ok_key = false; - for(int it = 0; it < 8; ++it) + for(int it = 0; it < 5; ++it) { - switch(lockInfo->Type[it]) + switch(lockInfo->keytype[it]) { case LOCK_KEY_NONE: break; case LOCK_KEY_ITEM: { - if(lockInfo->Index[it]) + if(lockInfo->key[it]) { - if(m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it]) + if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it]) ok_key =true; break; } } case LOCK_KEY_SKILL: { - if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->Index[it]) + if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it]) break; - switch(lockInfo->Index[it]) + switch(lockInfo->key[it]) { case LOCKTYPE_HERBALISM: if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM)) @@ -4137,9 +3922,9 @@ uint8 Spell::CanCast(bool strict) { // check for lock - key pair bool ok = false; - for(int it = 0; it < 8; ++it) + for(int it = 0; it < 5; ++it) { - if(lockInfo->Type[it]==LOCK_KEY_ITEM && lockInfo->Index[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it]) + if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it]) { // if so, we're good to go ok = true; @@ -4150,9 +3935,9 @@ uint8 Spell::CanCast(bool strict) break; if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK) - ReqValue = lockInfo->Skill[1]; + ReqValue = lockInfo->requiredlockskill; else - ReqValue = lockInfo->Skill[0]; + ReqValue = lockInfo->requiredminingskill; } // skill doesn't meet the required value @@ -4201,6 +3986,7 @@ uint8 Spell::CanCast(bool strict) } // Don't make this check for SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN. // These won't show up in m_caster->GetPetGUID() + case SPELL_EFFECT_SUMMON_POSSESSED: case SPELL_EFFECT_SUMMON_PHANTASM: case SPELL_EFFECT_SUMMON_DEMON: { @@ -4357,7 +4143,7 @@ uint8 Spell::CanCast(bool strict) if( form == FORM_CAT || form == FORM_TREE || form == FORM_TRAVEL || form == FORM_AQUA || form == FORM_BEAR || form == FORM_DIREBEAR || form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT || - form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN || form == FORM_METAMORPHOSIS ) + form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN ) return SPELL_FAILED_NOT_SHAPESHIFT; break; @@ -4379,8 +4165,8 @@ uint8 Spell::CanCast(bool strict) // not allow cast fly spells at old maps by players (all spells is self target) if(m_caster->GetTypeId()==TYPEID_PLAYER) { - uint32 v_map = GetVirtualMapForMapAndZone(m_caster->GetMapId(), m_caster->GetZoneId()); - if( !((Player*)m_caster)->isGameMaster() && v_map != 530 && !(v_map == 571 && ((Player*)m_caster)->HasSpell(54197))) + if( !((Player*)m_caster)->isGameMaster() && + GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530) return SPELL_FAILED_NOT_HERE; } @@ -4695,12 +4481,9 @@ int32 Spell::CalculatePowerCost() case POWER_FOCUS: case POWER_ENERGY: case POWER_HAPPINESS: + // case POWER_RUNES: powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100; break; - case POWER_RUNE: - case POWER_RUNIC_POWER: - sLog.outDebug("Spell::CalculateManaCost: Not implemented yet!"); - break; default: sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id); return 0; @@ -4745,11 +4528,6 @@ uint8 Spell::CheckPower() sLog.outError("Spell::CheckMana: Unknown power type '%d'", m_spellInfo->powerType); return SPELL_FAILED_UNKNOWN; } - - uint8 failReason = CheckRuneCost(m_spellInfo->runeCostID); - if(failReason) - return failReason; - // Check power amount Powers powerType = Powers(m_spellInfo->powerType); if(m_caster->GetPower(powerType) < m_powerCost) @@ -4877,7 +4655,8 @@ uint8 Spell::CheckItems() focusObject = ok; // game object found in range } - if (!p_caster->CanNoReagentCast(m_spellInfo)) + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && + m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))) { for(uint32 i=0;i<8;i++) { @@ -5045,36 +4824,13 @@ uint8 Spell::CheckItems() return SPELL_FAILED_LOW_CASTLEVEL; //make sure the player has the required ores in inventory if(m_targets.getItemTarget()->GetCount() < 5) - return SPELL_FAILED_NEED_MORE_ITEMS; + return SPELL_FAILED_PROSPECT_NEED_MORE; if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry())) return SPELL_FAILED_CANT_BE_PROSPECTED; break; } - case SPELL_EFFECT_MILLING: - { - if(!m_targets.getItemTarget()) - return SPELL_FAILED_CANT_BE_MILLED; - //ensure item is a millable herb - if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS) - return SPELL_FAILED_CANT_BE_MILLED; - //prevent milling in trade slot - if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() ) - return SPELL_FAILED_CANT_BE_MILLED; - //Check for enough skill in inscription - uint32 item_millingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank; - if(item_millingskilllevel >p_caster->GetSkillValue(SKILL_INSCRIPTION)) - return SPELL_FAILED_LOW_CASTLEVEL; - //make sure the player has the required herbs in inventory - if(m_targets.getItemTarget()->GetCount() < 5) - return SPELL_FAILED_NEED_MORE_ITEMS; - - if(!LootTemplates_Milling.HaveLootFor(m_targets.getItemTargetEntry())) - return SPELL_FAILED_CANT_BE_MILLED; - - break; - } case SPELL_EFFECT_WEAPON_DAMAGE: case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: { @@ -5247,9 +5003,9 @@ void Spell::UpdatePointers() m_targets.Update(m_caster); } -bool Spell::IsAffectedByAura(Aura *aura) +bool Spell::IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId) { - return spellmgr.IsAffectedByMod(m_spellInfo, aura->getAuraSpellMod()); + return spellmgr.IsAffectedBySpell(m_spellInfo,spellInfo->Id,effectId,spellInfo->EffectItemType[effectId]); } bool Spell::CheckTargetCreatureType(Unit* target) const diff --git a/src/game/Spell.h b/src/game/Spell.h index 093dde6be27..ba5e14b33f2 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -47,51 +47,26 @@ enum SpellCastTargetFlags TARGET_FLAG_RESURRECTABLE = 0x8000*/ TARGET_FLAG_SELF = 0x00000000, - TARGET_FLAG_UNUSED1 = 0x00000001, // not used in any spells as of 3.0.3 (can be set dynamically) TARGET_FLAG_UNIT = 0x00000002, // pguid - TARGET_FLAG_UNUSED2 = 0x00000004, // not used in any spells as of 3.0.3 (can be set dynamically) - TARGET_FLAG_UNUSED3 = 0x00000008, // not used in any spells as of 3.0.3 (can be set dynamically) TARGET_FLAG_ITEM = 0x00000010, // pguid TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float - TARGET_FLAG_OBJECT_UNK = 0x00000080, // used in 7 spells only - TARGET_FLAG_UNIT_UNK = 0x00000100, // looks like self target (480 spells) + TARGET_FLAG_OBJECT_UNK = 0x00000080, // ? TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid - TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions) - TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells - TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 0 spells - TARGET_FLAG_STRING = 0x00002000, // string, 0 spells - TARGET_FLAG_UNK1 = 0x00004000, // 199 spells, opening object/lock - TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells - TARGET_FLAG_UNK2 = 0x00010000, // pguid, not used in any spells as of 3.0.3 (can be set dynamically) - TARGET_FLAG_GLYPH = 0x00020000 // used in glyph spells + TARGET_FLAG_OBJECT = 0x00000800, // pguid + TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid + TARGET_FLAG_STRING = 0x00002000, // string + TARGET_FLAG_UNK1 = 0x00004000, // ? + TARGET_FLAG_CORPSE = 0x00008000, // pguid + TARGET_FLAG_UNK2 = 0x00010000 // pguid }; enum SpellCastFlags { - CAST_FLAG_NONE = 0x00000000, - CAST_FLAG_UNKNOWN0 = 0x00000001, // may be pending spell cast CAST_FLAG_UNKNOWN1 = 0x00000002, - CAST_FLAG_UNKNOWN11 = 0x00000004, - CAST_FLAG_UNKNOWN12 = 0x00000008, CAST_FLAG_UNKNOWN2 = 0x00000010, - CAST_FLAG_AMMO = 0x00000020, // Projectiles visual - CAST_FLAG_UNKNOWN8 = 0x00000040, - CAST_FLAG_UNKNOWN9 = 0x00000080, - CAST_FLAG_UNKNOWN3 = 0x00000100, - CAST_FLAG_UNKNOWN13 = 0x00000200, - CAST_FLAG_UNKNOWN14 = 0x00000400, - CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk, trigger rune cooldown - CAST_FLAG_UNKNOWN15 = 0x00001000, - CAST_FLAG_UNKNOWN16 = 0x00002000, - CAST_FLAG_UNKNOWN17 = 0x00004000, - CAST_FLAG_UNKNOWN18 = 0x00008000, - CAST_FLAG_UNKNOWN19 = 0x00010000, - CAST_FLAG_UNKNOWN4 = 0x00020000, // wotlk - CAST_FLAG_UNKNOWN10 = 0x00040000, - CAST_FLAG_UNKNOWN5 = 0x00080000, // wotlk - CAST_FLAG_UNKNOWN20 = 0x00100000, - CAST_FLAG_UNKNOWN7 = 0x00200000 // wotlk, rune cooldown list + CAST_FLAG_AMMO = 0x00000020, + CAST_FLAG_UNKNOWN3 = 0x00000100 }; enum SpellRangeFlag @@ -300,7 +275,6 @@ class Spell void EffectStuck(uint32 i); void EffectSummonPlayer(uint32 i); void EffectActivateObject(uint32 i); - void EffectApplyGlyph(uint32 i); void EffectSummonTotem(uint32 i); void EffectEnchantHeldItem(uint32 i); void EffectSummonObject(uint32 i); @@ -318,7 +292,6 @@ class Spell void EffectSkinning(uint32 i); void EffectCharge(uint32 i); void EffectProspecting(uint32 i); - void EffectMilling(uint32 i); void EffectSendTaxi(uint32 i); void EffectSummonCritter(uint32 i); void EffectKnockBack(uint32 i); @@ -345,8 +318,6 @@ class Spell void EffectKillCredit(uint32 i); void EffectQuestFail(uint32 i); void EffectRedirectThreat(uint32 i); - void EffectActivateRune(uint32 i); - void EffectTitanGrip(uint32 i); Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL ); ~Spell(); @@ -357,8 +328,6 @@ class Spell void cast(bool skipCheck = false); void finish(bool ok = true); void TakePower(); - uint8 CheckRuneCost(uint32 runeCostID); - void TakeRunePower(); void TakeReagents(); void TakeCastItem(); void TriggerSpell(); @@ -417,7 +386,6 @@ class Spell int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points Item* m_CastItem; uint8 m_cast_count; - uint32 m_glyphIndex; SpellCastTargets m_targets; int32 GetCastTime() const { return m_casttime; } @@ -454,7 +422,7 @@ class Spell void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) - bool IsAffectedByAura(Aura *aura); + bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId); bool CheckTargetCreatureType(Unit* target) const; @@ -481,7 +449,6 @@ class Spell int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare bool m_canReflect; // can reflect this spell? bool m_autoRepeat; - uint8 m_runesState; uint8 m_delayAtDamageCount; int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; } diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 59bb8128e11..cf628515925 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -20,19 +20,14 @@ #ifndef TRINITY_SPELLAURADEFINES_H #define TRINITY_SPELLAURADEFINES_H -#define MAX_AURAS 64 // client support up to 255, but it will cause problems with group auras updating +#define MAX_AURAS 56 +#define MAX_POSITIVE_AURAS 40 enum AURA_FLAGS { - AFLAG_NONE = 0x00, - AFLAG_EFF_INDEX_0 = 0x01, - AFLAG_EFF_INDEX_1 = 0x02, - AFLAG_EFF_INDEX_2 = 0x04, - AFLAG_NOT_CASTER = 0x08, - AFLAG_POSITIVE = 0x10, - AFLAG_DURATION = 0x20, - AFLAG_UNK2 = 0x40, - AFLAG_NEGATIVE = 0x80 + AFLAG_NEGATIVE = 0x09, + AFLAG_POSITIVE = 0x1F, + AFLAG_MASK = 0xFF }; //m_schoolAbsorb @@ -238,7 +233,7 @@ enum AuraType SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191, SPELL_AURA_HASTE_MELEE = 192, SPELL_AURA_MELEE_SLOW = 193, - SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL = 194, + SPELL_AURA_MOD_DEPRICATED_1 = 194, // not used now, old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT SPELL_AURA_MOD_DEPRICATED_2 = 195, // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197, @@ -280,7 +275,7 @@ enum AuraType SPELL_AURA_233 = 233, SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234, SPELL_AURA_MOD_DISPEL_RESIST = 235, - SPELL_AURA_CONTROL_VEHICLE = 236, + SPELL_AURA_236 = 236, SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237, SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238, SPELL_AURA_MOD_SCALE_2 = 239, @@ -290,51 +285,28 @@ enum AuraType SPELL_AURA_243 = 243, SPELL_AURA_COMPREHEND_LANGUAGE = 244, SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245, - SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL = 246, + SPELL_AURA_246 = 246, SPELL_AURA_247 = 247, SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248, - SPELL_AURA_CONVERT_RUNE = 249, + SPELL_AURA_249 = 249, SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250, SPELL_AURA_MOD_ENEMY_DODGE = 251, SPELL_AURA_252 = 252, - SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253, - SPELL_AURA_MOD_DISARM_SHIELD = 254, - SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255, - SPELL_AURA_NO_REAGENT_USE = 256, - SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257, + SPELL_AURA_253 = 253, + SPELL_AURA_254 = 254, + SPELL_AURA_255 = 255, + SPELL_AURA_256 = 256, + SPELL_AURA_257 = 257, SPELL_AURA_258 = 258, SPELL_AURA_259 = 259, SPELL_AURA_260 = 260, SPELL_AURA_261 = 261, - SPELL_AURA_262 = 262, - SPELL_AURA_ALLOW_ONLY_ABILITY = 263, - SPELL_AURA_264 = 264, - SPELL_AURA_265 = 265, - SPELL_AURA_266 = 266, - SPELL_AURA_267 = 267, - SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, - SPELL_AURA_269 = 269, - SPELL_AURA_270 = 270, - SPELL_AURA_271 = 271, - SPELL_AURA_272 = 272, - SPELL_AURA_273 = 273, - SPELL_AURA_274 = 274, - SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275, - SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done - SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277, - SPELL_AURA_MOD_DISARM_RANGED = 278, - SPELL_AURA_279 = 279, - SPELL_AURA_MOD_TARGET_ARMOR_PCT = 280, - SPELL_AURA_MOD_HONOR_GAIN = 281, - SPELL_AURA_MOD_BASE_HEALTH_PCT = 282, - SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells - TOTAL_AURAS = 284 + TOTAL_AURAS=262 }; enum AreaAuraType { AREA_AURA_PARTY, - AREA_AURA_RAID, AREA_AURA_FRIEND, AREA_AURA_ENEMY, AREA_AURA_PET, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 75c78003857..36feb9b9375 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -163,7 +163,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER - &Aura::HandleAddTargetTrigger, //109 SPELL_AURA_ADD_TARGET_TRIGGER + &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT &Aura::HandleNULL, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS @@ -228,7 +228,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK &Aura::HandleUnused, //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell - &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus + &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT) &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end &Aura::HandleNULL, //177 SPELL_AURA_AOE_CHARM @@ -248,7 +248,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) - &Aura::HandleUnused, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL + &Aura::HandleUnused, //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT) &Aura::HandleUnused, //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT) &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance @@ -274,7 +274,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleUnused, //217 unused &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT - &Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT + &Aura::HandleNULL, //220 SPELL_AURA_MOD_RATING_FROM_STAT &Aura::HandleNULL, //221 ignored &Aura::HandleUnused, //222 unused &Aura::HandleNULL, //223 Cold Stare @@ -290,7 +290,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration &Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult - &Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE + &Aura::HandleUnused, //236 unused &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61 @@ -300,44 +300,22 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleUnused, //243 used by two test spells &Aura::HandleComprehendLanguage, //244 Comprehend language &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS - &Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL + &Aura::HandleUnused, //246 unused &Aura::HandleUnused, //247 unused &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst - &Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE + &Aura::HandleNULL, //249 &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2 &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE - &Aura::HandleNULL, //252 haste all? - &Aura::HandleNULL, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE - &Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield - &Aura::HandleNULL, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT - &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select - &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select - &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL - &Aura::HandleNULL, //259 corrupt healing over time spell - &Aura::HandleNULL, //260 - &Aura::HandleNULL, //261 out of phase? - &Aura::HandleNULL, //262 - &Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilites set in SpellClassMask - &Aura::HandleNULL, //264 unused - &Aura::HandleNULL, //265 unused - &Aura::HandleNULL, //266 unused - &Aura::HandleNULL, //267 some immunity? - &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT - &Aura::HandleNULL, //269 ignore DR effects? - &Aura::HandleNULL, //270 - &Aura::HandleNULL, //271 increase damage done? - &Aura::HandleNULL, //272 reduce spell cast time? - &Aura::HandleNULL, //273 - &Aura::HandleNULL, //274 proc free shot? - &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select - &Aura::HandleNULL, //276 mod damage % mechanic? - &Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select - &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon - &Aura::HandleNULL, //279 - &Aura::HandleNULL, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT - &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN - &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT - &Aura::HandleNULL //283 SPD/heal from AP? + &Aura::HandleUnused, //252 unused + &Aura::HandleUnused, //253 unused + &Aura::HandleUnused, //254 unused + &Aura::HandleUnused, //255 unused + &Aura::HandleUnused, //256 unused + &Aura::HandleUnused, //257 unused + &Aura::HandleUnused, //258 unused + &Aura::HandleUnused, //259 unused + &Aura::HandleUnused, //260 unused + &Aura::HandleNULL //261 SPELL_AURA_261 some phased state (44856 spell) }; Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : @@ -456,11 +434,6 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) m_modifier.m_auraname = SPELL_AURA_NONE; break; - case SPELL_EFFECT_APPLY_AREA_AURA_RAID: - m_areaAuraType = AREA_AURA_RAID; - if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) - m_modifier.m_auraname = SPELL_AURA_NONE; - break; case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: m_areaAuraType = AREA_AURA_FRIEND; break; @@ -627,8 +600,8 @@ void AreaAura::Update(uint32 diff) switch(m_areaAuraType) { - case AREA_AURA_RAID: - caster->GetRaidMember(targets, m_radius); + case AREA_AURA_PARTY: + caster->GetPartyMember(targets, m_radius); break; case AREA_AURA_FRIEND: { @@ -711,24 +684,6 @@ void AreaAura::Update(uint32 diff) tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); } } - else if( m_areaAuraType == AREA_AURA_RAID) // TODO: fix me! - { - // not check group if target == owner or target == pet - if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID()) - { - Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); - - Group *pGroup = check ? check->GetGroup() : NULL; - if( pGroup ) - { - Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself(); - if(!checkTarget) - tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); - } - else - tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); - } - } else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER ) { if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() ) @@ -779,6 +734,47 @@ void Aura::ApplyModifier(bool apply, bool Real) m_in_use = false; } +void Aura::UpdateAuraDuration() +{ + if(m_auraSlot >= MAX_AURAS || m_isPassive) + return; + + if( m_target->GetTypeId() == TYPEID_PLAYER) + { + WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5); + data << (uint8)m_auraSlot << (uint32)m_duration; + ((Player*)m_target)->SendDirectMessage(&data); + + data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4)); + data.append(m_target->GetPackGUID()); + data << uint8(m_auraSlot); + data << uint32(GetId()); + data << uint32(GetAuraMaxDuration()); + data << uint32(GetAuraDuration()); + ((Player*)m_target)->SendDirectMessage(&data); + } + + // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code + if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()) + return; + + Unit* caster = GetCaster(); + + if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target) + SendAuraDurationForCaster((Player*)caster); +} + +void Aura::SendAuraDurationForCaster(Player* caster) +{ + WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4)); + data.append(m_target->GetPackGUID()); + data << uint8(m_auraSlot); + data << uint32(GetId()); + data << uint32(GetAuraMaxDuration()); // full + data << uint32(GetAuraDuration()); // remain + caster->GetSession()->SendPacket(&data); +} + void Aura::_AddAura() { if (!GetId()) @@ -844,13 +840,22 @@ void Aura::_AddAura() { if(!secondaura) // new slot need { - if(m_target->GetVisibleAurasCount() < MAX_AURAS) + if (IsPositive()) // empty positive slot { - Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras(); - for(uint8 i = 0; i < MAX_AURAS; ++i) + for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++) { - Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i); - if(itr == visibleAuras->end()) + if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0) + { + slot = i; + break; + } + } + } + else // empty negative slot + { + for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++) + { + if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0) { slot = i; break; @@ -863,12 +868,11 @@ void Aura::_AddAura() // Not update fields for not first spell's aura, all data already in fields if(slot < MAX_AURAS) // slot found { - SetAura(false); - SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE)); - SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); + SetAura(slot, false); + SetAuraFlag(slot, true); + SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); UpdateAuraCharges(); - SendAuraUpdate(false); - + // update for out of range group members m_target->UpdateAuraForGroup(slot); } @@ -926,7 +930,7 @@ void Aura::_RemoveAura() if(slot >= MAX_AURAS) // slot not set return; - if(m_target->GetVisibleAura(slot) == 0) + if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0) return; bool samespell = false; @@ -951,12 +955,11 @@ void Aura::_RemoveAura() // only remove icon when the last aura of the spell is removed (current aura already removed from list) if (!samespell) { - SetAura(true); - SetAuraFlags(AFLAG_NONE); - SetAuraLevel(0); - SetAuraCharges(0); - SendAuraUpdate(true); + SetAura(slot, true); + SetAuraFlag(slot, false); + SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); + SetAuraApplication(slot, 0); // update for out of range group members m_target->UpdateAuraForGroup(slot); @@ -995,36 +998,40 @@ void Aura::_RemoveAura() } } -void Aura::SendAuraUpdate(bool remove) +void Aura::SetAuraFlag(uint32 slot, bool add) { - WorldPacket data(SMSG_AURA_UPDATE); - data.append(m_target->GetPackGUID()); - data << uint8(GetAuraSlot()); - data << uint32(remove ? 0 : GetId()); - - if(remove) + uint32 index = slot / 4; + uint32 byte = (slot % 4) * 8; + uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index); + val &= ~((uint32)AFLAG_MASK << byte); + if(add) { - m_target->SendMessageToSet(&data, true); - return; + if (IsPositive()) + val |= ((uint32)AFLAG_POSITIVE << byte); + else + val |= ((uint32)AFLAG_NEGATIVE << byte); } + m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val); +} - uint8 auraFlags = GetAuraFlags(); - data << uint8(auraFlags); - data << uint8(GetAuraLevel()); - data << uint8(m_procCharges >= 0 ? m_procCharges : 0); +void Aura::SetAuraLevel(uint32 slot,uint32 level) +{ + uint32 index = slot / 4; + uint32 byte = (slot % 4) * 8; + uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index); + val &= ~(0xFF << byte); + val |= (level << byte); + m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val); +} - if(!(auraFlags & AFLAG_NOT_CASTER)) - { - data << uint8(0); // pguid - } - - if(auraFlags & AFLAG_DURATION) - { - data << uint32(GetAuraMaxDuration()); - data << uint32(GetAuraDuration()); - } - - m_target->SendMessageToSet(&data, true); +void Aura::SetAuraApplication(uint32 slot, int8 count) +{ + uint32 index = slot / 4; + uint32 byte = (slot % 4) * 8; + uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index); + val &= ~(0xFF << byte); + val |= ((uint8(count)) << byte); + m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val); } void Aura::UpdateSlotCounterAndDuration() @@ -1037,26 +1044,10 @@ void Aura::UpdateSlotCounterAndDuration() // Charge = 0; Stack >= 0 // Charge = 1; Stack >= 0 // Charge > 1; Stack = 0 - //SetAuraDuration(GetAuraDuration()); if(m_procCharges < 2) - { - SetAuraCharges(m_stackAmount-1); - SendAuraUpdate(false); - } -} + SetAuraApplication(slot, m_stackAmount-1); -bool Aura::isAffectedOnSpell(SpellEntry const *spell) const -{ - // Check family name - if (spell->SpellFamilyName != m_spellProto->SpellFamilyName) - return false; - // Check EffectClassMask - uint32 const *ptr = getAuraSpellClassMask(); - if (((uint64*)ptr)[0] & spell->SpellFamilyFlags) - return true; - if (ptr[2] & spell->SpellFamilyFlags2) - return true; - return false; + UpdateAuraDuration(); } /*********************************************************/ @@ -1067,6 +1058,10 @@ void Aura::HandleAddModifier(bool apply, bool Real) if(m_target->GetTypeId() != TYPEID_PLAYER || !Real) return; + SpellEntry const *spellInfo = GetSpellProto(); + if(!spellInfo) + return; + if(m_modifier.m_miscvalue >= MAX_SPELLMOD) return; @@ -1087,25 +1082,15 @@ void Aura::HandleAddModifier(bool apply, bool Real) mod->value = GetModifierValue(); mod->type = SpellModType(m_modifier.m_auraname); // SpellModType value == spell aura types mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; - uint32 const *ptr; - SpellAffectEntry const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex); - if (spellAffect) - ptr = &spellAffect->SpellClassMask[0]; + uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex); + + if (spellAffectMask) + mod->mask = spellAffectMask; else - { - switch (m_effIndex) - { - case 0: ptr = &m_spellProto->EffectSpellClassMaskA[0]; break; - case 1: ptr = &m_spellProto->EffectSpellClassMaskB[0]; break; - case 2: ptr = &m_spellProto->EffectSpellClassMaskC[0]; break; - default: - return; - } - } - - mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32; - mod->mask2= (uint64)ptr[2]; + mod->mask = spellInfo->EffectItemType[m_effIndex]; if (m_procCharges > 0) mod->charges = m_procCharges; @@ -1120,7 +1105,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(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL)) { m_target->RemoveAurasDueToSpell(45471); @@ -1128,42 +1113,7 @@ void Aura::HandleAddModifier(bool apply, bool Real) m_target->CastSpell(m_target,45471,true); } } -void Aura::HandleAddTargetTrigger(bool apply, bool Real) -{ - // Use SpellModifier structure for check - // used only fields: - // spellId, mask, mask2 - if (apply) - { - SpellModifier *mod = new SpellModifier; - mod->spellId = GetId(); - uint32 const *ptr; - SpellAffectEntry const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex); - if (spellAffect) - ptr = &spellAffect->SpellClassMask[0]; - else - { - switch (m_effIndex) - { - case 0: ptr = &m_spellProto->EffectSpellClassMaskA[0]; break; - case 1: ptr = &m_spellProto->EffectSpellClassMaskB[0]; break; - case 2: ptr = &m_spellProto->EffectSpellClassMaskC[0]; break; - default: - return; - } - } - - mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32; - mod->mask2= (uint64)ptr[2]; - m_spellmod = mod; - } - else - { - delete m_spellmod; - m_spellmod = NULL; - } -} void Aura::TriggerSpell() { Unit* caster = GetCaster(); @@ -2139,8 +2089,10 @@ void Aura::HandleAuraDummy(bool apply, bool Real) mod->value = m_modifier.m_amount/7; mod->type = SPELLMOD_FLAT; mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; mod->mask = 0x001000000000LL; - mod->mask2= 0LL; + mod->charges = 0; m_spellmod = mod; } @@ -2163,8 +2115,10 @@ void Aura::HandleAuraDummy(bool apply, bool Real) mod->value = m_modifier.m_amount; mod->type = SPELLMOD_FLAT; mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; mod->mask = 0x4000000000000LL; - mod->mask2= 0LL; + mod->charges = 0; m_spellmod = mod; } @@ -2186,17 +2140,18 @@ void Aura::HandleAuraDummy(bool apply, bool Real) mod->value = m_modifier.m_amount; mod->type = SPELLMOD_PCT; mod->spellId = GetId(); + mod->effectId = m_effIndex; + mod->lastAffected = NULL; switch (m_effIndex) { case 0: mod->mask = 0x00200000000LL; // Windfury Totem - mod->mask2= 0LL; break; case 1: mod->mask = 0x00400000000LL; // Flametongue Totem - mod->mask2= 0LL; break; } + mod->charges = 0; m_spellmod = mod; } @@ -2243,8 +2198,6 @@ void Aura::HandleAuraPeriodicDummy(bool apply, bool Real) if(!Real) return; - Unit* caster = GetCaster(); - SpellEntry const*spell = GetSpellProto(); switch( spell->SpellFamilyName) { @@ -2268,16 +2221,6 @@ void Aura::HandleAuraPeriodicDummy(bool apply, bool Real) ((Player*)m_target)->UpdateManaRegen(); break; } - // Explosive Shot - if (spell->SpellFamilyFlags & 0x8000000000000000LL) - { - if (apply && caster) - { - int32 damage = m_modifier.m_amount + caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; - caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this); - } - break; - } break; } } @@ -2920,36 +2863,6 @@ void Aura::HandleModPossess(bool apply, bool Real) } else m_target->UnpossessSelf(true); - /*{ - m_target->SetCharmerGUID(0); - - if(m_target->GetTypeId() == TYPEID_PLAYER) - ((Player*)m_target)->setFactionForRace(m_target->getRace()); - else if(m_target->GetTypeId() == TYPEID_UNIT) - { - CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); - m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); - } - - caster->SetCharm(0); - - if(caster->GetTypeId() == TYPEID_PLAYER) - { - WorldPacket data(SMSG_PET_SPELLS, 8); - data << uint64(0); - data << uint32(0); - ((Player*)caster)->GetSession()->SendPacket(&data); - } - if(m_target->GetTypeId() == TYPEID_UNIT) - { - ((Creature*)m_target)->AIM_Initialize(); - - if (((Creature*)m_target)->AI()) - ((Creature*)m_target)->AI()->AttackStart(caster); - } - } - if(caster->GetTypeId() == TYPEID_PLAYER) - ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);*/ } void Aura::HandleModPossessPet(bool apply, bool Real) @@ -2960,20 +2873,9 @@ void Aura::HandleModPossessPet(bool apply, bool Real) Unit* caster = GetCaster(); if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - - Pet *pet = caster->GetPet(); - if(!pet || pet != m_target) + if(caster->GetPet() != m_target) return; - if(apply) - pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - else - pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); - - ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL); - ((Player*)caster)->SetCharm(apply ? pet : NULL); - ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0); - if(apply) { ((Player*)caster)->Possess(m_target); @@ -2981,12 +2883,6 @@ void Aura::HandleModPossessPet(bool apply, bool Real) else { ((Player*)caster)->RemovePossess(false); - /*pet->StopMoving(); - pet->GetMotionMaster()->Clear(); - pet->GetMotionMaster()->MoveIdle();*/ - pet->AttackStop(); - pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE); } } @@ -3093,7 +2989,6 @@ void Aura::HandleModCharm(bool apply, bool Real) { WorldPacket data(SMSG_PET_SPELLS, 8); data << uint64(0); - data << uint32(0); ((Player*)caster)->GetSession()->SendPacket(&data); } } @@ -4042,7 +3937,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) case SPELLFAMILY_ROGUE: { // Deadly poison aura state - if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual[0]==5100) + if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100) { if(apply) m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true); @@ -4054,7 +3949,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { SpellEntry const* itr_spell = (*itr)->GetSpellProto(); - if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual[0]==5100) + if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100) { found = true; break; @@ -4627,11 +4522,6 @@ void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/) m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetModifierValue()), apply); } -void Aura::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/) -{ - m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_modifier.m_amount), apply); -} - /********************************/ /*** FIGHT ***/ /********************************/ @@ -4705,28 +4595,13 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real) void Aura::HandleModHitChance(bool apply, bool Real) { - if(m_target->GetTypeId() == TYPEID_PLAYER) - { - ((Player*)m_target)->UpdateMeleeHitChances(); - ((Player*)m_target)->UpdateRangedHitChances(); - } - else - { - m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount); - m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount); - } + m_target->m_modMeleeHitChance += apply ? GetModifierValue() : -GetModifierValue(); + m_target->m_modRangedHitChance += apply ? GetModifierValue() : -GetModifierValue(); } void Aura::HandleModSpellHitChance(bool apply, bool Real) { - if(m_target->GetTypeId() == TYPEID_PLAYER) - { - ((Player*)m_target)->UpdateSpellHitChances(); - } - else - { - m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount); - } + m_target->m_modSpellHitChance += apply ? GetModifierValue(): -GetModifierValue(); } void Aura::HandleModSpellCritChance(bool apply, bool Real) @@ -4851,23 +4726,17 @@ void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real) if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0) return; + if(m_modifier.m_miscvalue != STAT_INTELLECT) + { + // support required adding UpdateAttackPowerAndDamage calls at stat update + sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intellect stats!"); + return; + } + // Recalculate bonus ((Player*)m_target)->UpdateAttackPowerAndDamage(true); } -void Aura::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real) -{ - // spells required only Real aura add/remove - if(!Real) - return; - - if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0) - return; - - // Recalculate bonus - ((Player*)m_target)->UpdateAttackPowerAndDamage(false); -} - /********************************/ /*** DAMAGE BONUS ***/ /********************************/ @@ -5049,28 +4918,6 @@ void Aura::HandleModPowerCost(bool apply, bool Real) m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,GetModifierValue(),apply); } -void Aura::HandleNoReagentUseAura(bool Apply, bool Real) -{ - // spells required only Real aura add/remove - if(!Real) - return; - if(m_target->GetTypeId() != TYPEID_PLAYER) - return; - uint32 mask[3] = {0, 0, 0}; - Unit::AuraList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE); - for(Unit::AuraList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i) - { - uint32 const *ptr = (*i)->getAuraSpellClassMask(); - mask[0]|=ptr[0]; - mask[1]|=ptr[1]; - mask[2]|=ptr[2]; - } - - m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]); - m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]); - m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]); -} - /*********************************************************/ /*** OTHERS ***/ /*********************************************************/ @@ -5292,20 +5139,6 @@ void Aura::HandleModRating(bool apply, bool Real) ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), GetModifierValue(), apply); } -void Aura::HandleModRatingFromStat(bool apply, bool Real) -{ - // spells required only Real aura add/remove - if(!Real) - return; - - if(m_target->GetTypeId() != TYPEID_PLAYER) - return; - // Just recalculate ratings - for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) - if (m_modifier.m_miscvalue & (1 << rating)) - ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply); -} - void Aura::HandleForceMoveForward(bool apply, bool Real) { if(!Real || m_target->GetTypeId() != TYPEID_PLAYER) @@ -5615,7 +5448,6 @@ void Aura::PeriodicTick() data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x data << (uint32)absorb; data << (uint32)resist; - data << uint32(0); // wotlk m_target->SendMessageToSet(&data,true); Unit* target = m_target; // aura can be deleted in DealDamage @@ -5779,7 +5611,7 @@ void Aura::PeriodicTick() return; // heal for caster damage (must be alive) - if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive()) + if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive()) return; // ignore non positive values (can be result apply spellmods to aura damage @@ -5806,7 +5638,6 @@ void Aura::PeriodicTick() data << uint32(1); data << uint32(m_modifier.m_auraname); data << (uint32)pdamage; - data << uint32(0); // wotlk m_target->SendMessageToSet(&data,true); int32 gain = m_target->ModifyHealth(pdamage); @@ -5826,7 +5657,7 @@ void Aura::PeriodicTick() bool haveCastItem = GetCastItemGUID()!=0; // heal for caster damage - if(m_target!=pCaster && spellProto->SpellVisual[0]==163) + if(m_target!=pCaster && spellProto->SpellVisual==163) { uint32 dmg = spellProto->manaPerSecond; if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER) @@ -6047,136 +5878,114 @@ void Aura::PeriodicTick() void Aura::PeriodicDummyTick() { - Unit *caster = GetCaster(); SpellEntry const* spell = GetSpellProto(); - switch (spell->SpellFamilyName) + switch (spell->Id) { - case SPELLFAMILY_GENERIC: - switch (spell->Id) + // Drink + case 430: + case 431: + case 432: + case 1133: + case 1135: + case 1137: + case 10250: + case 22734: + case 27089: + case 34291: + case 43706: + case 46755: { - // Drink - case 430: - case 431: - case 432: - case 1133: - case 1135: - case 1137: - case 10250: - case 22734: - case 27089: - case 34291: - case 43706: - case 46755: - case 49472: // Drink Coffee - case 61830: + if (m_target->GetTypeId() != TYPEID_PLAYER) + return; + // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus + Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN); + for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i) { - if (m_target->GetTypeId() != TYPEID_PLAYER) - return; - // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus - Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN); - for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i) + if ((*i)->GetId() == GetId()) { - if ((*i)->GetId() == GetId()) + // Get tick number + int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime; + // Default case (not on arenas) + if (tick == 0) { - // Get tick number - int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime; - // Default case (not on arenas) - if (tick == 0) - { - (*i)->GetModifier()->m_amount = m_modifier.m_amount; - ((Player*)m_target)->UpdateManaRegen(); - // Disable continue - m_isPeriodic = false; - } - return; - //********************************************** - // Code commended since arena patch not added - // This feature uses only in arenas - //********************************************** - // Here need increase mana regen per tick (6 second rule) - // on 0 tick - 0 (handled in 2 second) - // on 1 tick - 166% (handled in 4 second) - // on 2 tick - 133% (handled in 6 second) - // Not need update after 3 tick - /* - if (tick > 3) - return; - // Apply bonus for 0 - 3 tick - switch (tick) - { - case 0: // 0% - (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0; - break; - case 1: // 166% - (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3; - break; - case 2: // 133% - (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3; - break; - default: // 100% - normal regen - (*i)->GetModifier()->m_amount = m_modifier.m_amount; - break; - } + (*i)->GetModifier()->m_amount = m_modifier.m_amount; ((Player*)m_target)->UpdateManaRegen(); - return;*/ + // Disable continue + m_isPeriodic = false; } + return; + //********************************************** + // Code commended since arena patch not added + // This feature uses only in arenas + //********************************************** + // Here need increase mana regen per tick (6 second rule) + // on 0 tick - 0 (handled in 2 second) + // on 1 tick - 166% (handled in 4 second) + // on 2 tick - 133% (handled in 6 second) + // Not need update after 3 tick + /* + if (tick > 3) + return; + // Apply bonus for 0 - 3 tick + switch (tick) + { + case 0: // 0% + (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0; + break; + case 1: // 166% + (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3; + break; + case 2: // 133% + (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3; + break; + default: // 100% - normal regen + (*i)->GetModifier()->m_amount = m_modifier.m_amount; + break; + } + ((Player*)m_target)->UpdateManaRegen(); + return;*/ } - return; - } - // Forsaken Skills - case 7054: - { - // Possibly need cast one of them (but - // 7038 Forsaken Skill: Swords - // 7039 Forsaken Skill: Axes - // 7040 Forsaken Skill: Daggers - // 7041 Forsaken Skill: Maces - // 7042 Forsaken Skill: Staves - // 7043 Forsaken Skill: Bows - // 7044 Forsaken Skill: Guns - // 7045 Forsaken Skill: 2H Axes - // 7046 Forsaken Skill: 2H Maces - // 7047 Forsaken Skill: 2H Swords - // 7048 Forsaken Skill: Defense - // 7049 Forsaken Skill: Fire - // 7050 Forsaken Skill: Frost - // 7051 Forsaken Skill: Holy - // 7053 Forsaken Skill: Shadow - return; } + return; + } // // Panda // case 19230: break; +// // Master of Subtlety +// case 31666: break; // // Gossip NPC Periodic - Talk // case 33208: break; // // Gossip NPC Periodic - Despawn // case 33209: break; - - // TODO: now its not periodic dummy - need move out from here - // Aspect of the Viper - case 34074: - { - if (m_target->GetTypeId() != TYPEID_PLAYER) - return; - // Should be manauser - if (m_target->getPowerType()!=POWER_MANA) - return; - if (!caster) - return; - // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell) - int mana = m_target->GetPower(POWER_MANA); - int max_mana = m_target->GetMaxPower(POWER_MANA); - int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target); - float regen_pct = 1.20f - 1.1f * mana / max_mana; - if (regen_pct > 1.0f) regen_pct = 1.0f; - else if (regen_pct < 0.2f) regen_pct = 0.2f; - m_modifier.m_amount = int32 (base_regen * regen_pct); - ((Player*)m_target)->UpdateManaRegen(); +// // Force of Nature +// case 33831: break; + // Aspect of the Viper + case 34074: + { + if (m_target->GetTypeId() != TYPEID_PLAYER) return; - } + // Should be manauser + if (m_target->getPowerType()!=POWER_MANA) + return; + Unit *caster = GetCaster(); + if (!caster) + return; + // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell) + int mana = m_target->GetPower(POWER_MANA); + int max_mana = m_target->GetMaxPower(POWER_MANA); + int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target); + float regen_pct = 1.20f - 1.1f * mana / max_mana; + if (regen_pct > 1.0f) regen_pct = 1.0f; + else if (regen_pct < 0.2f) regen_pct = 0.2f; + m_modifier.m_amount = int32 (base_regen * regen_pct); + ((Player*)m_target)->UpdateManaRegen(); + return; + } // // Steal Weapon // case 36207: break; // // Simon Game START timer, (DND) // case 39993: break; +// // Harpooner's Mark +// case 40084: break; // // Knockdown Fel Cannon: break; The Aggro Burst // case 40119: break; // // Old Mount Spell @@ -6189,8 +5998,6 @@ void Aura::PeriodicDummyTick() // case 40846: break; // // Copy Weapon // case 41054: break; -// // Dementia -// case 41404: break; // // Ethereal Ring Visual, Lightning Aura // case 41477: break; // // Ethereal Ring Visual, Lightning Aura (Fork) @@ -6239,8 +6046,6 @@ void Aura::PeriodicDummyTick() // case 43310: break; // // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17 // case 43884: break; -// // Wretched! -// case 43963: break; // // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17 // case 44000: break; // // Energy Feedback @@ -6307,179 +6112,14 @@ void Aura::PeriodicDummyTick() // case 47407: break; // // Mole Machine Port Schedule // case 47489: break; -// case 47941: break; // Crystal Spike -// case 48200: break; // Healer Aura -// case 48630: break; // Summon Gauntlet Mobs Periodic -// case 49313: break; // Proximity Mine Area Aura // // Mole Machine Portal Schedule // case 49466: break; -// case 49555: break; // Corpse Explode -// case 49592: break; // Temporal Rift -// case 49957: break; // Cutting Laser -// case 50085: break; // Slow Fall +// // Drink Coffee +// case 49472: break; // // Listening to Music // case 50493: break; // // Love Rocket Barrage // case 50530: break; -// Exist more after, need add later - default: - break; - } - break; - case SPELLFAMILY_MAGE: - { - // Mirror Image -// if (spell->Id == 55342) -// return; - break; - } - case SPELLFAMILY_WARRIOR: - { - // Armored to the Teeth - if (spell->SpellIconID == 3516) - { - // Increases your attack power by $s1 for every $s2 armor value you have. - // Calculate AP bonus (from 1 efect of this spell) - int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target); - m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this); - return; - } - break; - } - case SPELLFAMILY_DRUID: - { - switch (spell->Id) - { - // Frenzied Regeneration - case 22842: - { - // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health. - // Should be manauser - if (m_target->getPowerType()!=POWER_RAGE) - return; - uint32 rage = m_target->GetPower(POWER_RAGE); - // Nothing todo - if (rage == 0) - return; - int32 mod = (rage < 100) ? rage : 100; - int32 points = m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target); - int32 regen = m_target->GetMaxHealth() * (mod * points / 10) / 1000; - m_target->CastCustomSpell(m_target, 22845, ®en, 0, 0, true, 0, this); - m_target->SetPower(POWER_RAGE, rage-mod); - return; - } - // Force of Nature - case 33831: - return; - default: - break; - } - break; - } - case SPELLFAMILY_ROGUE: - { -// switch (spell->Id) -// { - // Master of Subtlety -// case 31666: break; - // Killing Spree -// case 51690: break; - // Overkill -// case 58428: break; -// default: -// break; -// } - break; - } - case SPELLFAMILY_HUNTER: - { - // Explosive Shot - if (spell->SpellFamilyFlags & 0x8000000000000000LL) - { - if (!caster) - return; - // Skip 0 tick - if (m_duration < m_modifier.periodictime) - return; - int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target); - damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; - damage/=4; - caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this); - return; - } - switch (spell->Id) - { - // Harpooner's Mark - // case 40084: - // return; - // Feeding Frenzy Rank 1 - case 53511: - if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 ) - m_target->CastSpell(m_target, 60096, true, 0, this); - return; - // Feeding Frenzy Rank 2 - case 53512: - if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 ) - m_target->CastSpell(m_target, 60097, true, 0, this); - return; - default: - break; - } - break; - } - case SPELLFAMILY_SHAMAN: - { - // Astral Shift -// if (spell->Id == 52179) -// return; - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Death and Decay -// if (spell->SpellFamilyFlags & 0x0000000000000020LL) -// return; - // Raise Dead -// if (spell->SpellFamilyFlags & 0x0000000000001000LL) -// return; - // Chains of Ice - if (spell->SpellFamilyFlags & 0x0000400000000000LL) - { - // Get 0 effect aura - Aura *slow = m_target->GetAura(GetId(), 0); - if (slow) - { - slow->ApplyModifier(false, true); - Modifier *mod = slow->GetModifier(); - mod->m_amount+= m_modifier.m_amount; - if (mod->m_amount > 0) mod->m_amount = 0; - slow->ApplyModifier(true, true); - } - return; - } - // Summon Gargoyle -// if (spell->SpellFamilyFlags & 0x0000008000000000LL) -// return; - // Death Rune Mastery -// if (spell->SpellFamilyFlags & 0x0000000000004000LL) -// return; - // Bladed Armor - if (spell->SpellIconID == 2653) - { - // Increases your attack power by $s1 for every $s2 armor value you have. - // Calculate AP bonus (from 1 efect of this spell) - int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target); - m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this); - return; - } - // Reaping -// if (spell->SpellIconID == 22) -// return; - // Blood of the North -// if (spell->SpellIconID == 30412) -// return; - break; - } default: break; } @@ -6545,61 +6185,14 @@ void Aura::HandleArenaPreparation(bool apply, bool Real) m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION); } -void Aura::HandleAuraControlVehicle(bool apply, bool Real) -{ - if(!Real) - return; - - if(m_target->GetTypeId() != TYPEID_PLAYER) - return; - - if(Pet *pet = m_target->GetPet()) - pet->Remove(PET_SAVE_AS_CURRENT); - - WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - ((Player*)m_target)->GetSession()->SendPacket(&data); -} - -void Aura::HandleAuraConvertRune(bool apply, bool Real) -{ - if(!Real) - return; - - if(m_target->GetTypeId() != TYPEID_PLAYER) - return; - - Player *plr = (Player*)m_target; - - if(plr->getClass() != CLASS_DEATH_KNIGHT) - return; - - // how to determine what rune need to be converted? - for(uint32 i = 0; i < MAX_RUNES; ++i) - { - if(apply) - { - if(!plr->GetRuneCooldown(i)) - { - plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]); - break; - } - } - else - { - if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex]) - { - plr->ConvertRune(i, plr->GetBaseRune(i)); - break; - } - } - } -} - void Aura::HandleModAttackerSpellHitChance(bool apply, bool Real) { + if(!Real) + return; + if(GetId() != 31224) return; //cloak of shadows : flare m_target->ApplySpellImmune(31224, IMMUNITY_ID, 1543, apply); -} +} \ No newline at end of file diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 99c170d1139..1e9a8bd8c63 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -100,7 +100,6 @@ class TRINITY_DLL_SPEC Aura void HandleAuraFeatherFall(bool Apply, bool Real); void HandleAuraHover(bool Apply, bool Real); void HandleAddModifier(bool Apply, bool Real); - void HandleAddTargetTrigger(bool Apply, bool Real); void HandleAuraModStun(bool Apply, bool Real); void HandleModDamageDone(bool Apply, bool Real); void HandleAuraUntrackable(bool Apply, bool Real); @@ -185,12 +184,10 @@ class TRINITY_DLL_SPEC Aura void HandleAuraGhost(bool Apply, bool Real); void HandleAuraAllowFlight(bool Apply, bool Real); void HandleModRating(bool apply, bool Real); - void HandleModRatingFromStat(bool apply, bool Real); void HandleModTargetResistance(bool apply, bool Real); void HandleAuraModAttackPowerPercent(bool apply, bool Real); void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real); void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real); - void HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real); void HandleSpiritOfRedemption(bool apply, bool Real); void HandleModManaRegen(bool apply, bool Real); void HandleComprehendLanguage(bool apply, bool Real); @@ -200,7 +197,6 @@ class TRINITY_DLL_SPEC Aura void HandleModSpellDamagePercentFromStat(bool apply, bool Real); void HandleModSpellHealingPercentFromStat(bool apply, bool Real); void HandleAuraModDispelResist(bool apply, bool Real); - void HandleAuraControlVehicle(bool apply, bool Real); void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real); void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real); void HandleAuraModPacifyAndSilence(bool Apply, bool Real); @@ -213,9 +209,6 @@ class TRINITY_DLL_SPEC Aura void HandlePreventFleeing(bool apply, bool Real); void HandleManaShield(bool apply, bool Real); void HandleArenaPreparation(bool apply, bool Real); - void HandleAuraConvertRune(bool apply, bool Real); - void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real); - void HandleNoReagentUseAura(bool Apply, bool Real); void HandleModAttackerSpellHitChance(bool apply, bool Real); virtual ~Aura(); @@ -238,8 +231,6 @@ class TRINITY_DLL_SPEC Aura int32 GetAuraDuration() const { return m_duration; } void SetAuraDuration(int32 duration) { m_duration = duration; } time_t GetAuraApplyTime() { return m_applyTime; } - SpellModifier *getAuraSpellMod() {return m_spellmod; } - void UpdateAuraDuration(); void SendAuraDurationForCaster(Player* caster); void UpdateSlotCounterAndDuration(); @@ -259,19 +250,13 @@ class TRINITY_DLL_SPEC Aura uint8 GetAuraSlot() const { return m_auraSlot; } void SetAuraSlot(uint8 slot) { m_auraSlot = slot; } - uint8 GetAuraFlags() const { return m_auraFlags; } - void SetAuraFlags(uint8 flags) { m_auraFlags = flags; } - uint8 GetAuraLevel() const { return m_auraLevel; } - void SetAuraLevel(uint8 level) { m_auraLevel = level; } - uint8 GetAuraCharges() const { return m_procCharges; } - void SetAuraCharges(uint8 charges) { m_procCharges = charges; } - void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); } - void SendAuraUpdate(bool remove); void UpdateAuraCharges() { + uint8 slot = GetAuraSlot(); + // only aura in slot with charges and without stack limitation - if (m_auraSlot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0) - SendAuraUpdate(false); + if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0) + SetAuraApplication(slot, m_procCharges - 1); } bool IsPositive() { return m_positive; } @@ -315,9 +300,6 @@ class TRINITY_DLL_SPEC Aura void PeriodicTick(); void PeriodicDummyTick(); - uint32 const *getAuraSpellClassMask() const { return m_spellProto->EffectSpellClassMaskA + m_effIndex * 3; } - bool isAffectedOnSpell(SpellEntry const *spell) const; - int32 GetStackAmount() {return m_stackAmount;} void SetStackAmount(int32 amount) {m_stackAmount=amount;} protected: @@ -339,8 +321,6 @@ class TRINITY_DLL_SPEC Aura AuraRemoveMode m_removeMode; uint8 m_auraSlot; - uint8 m_auraFlags; - uint8 m_auraLevel; bool m_positive:1; bool m_permanent:1; @@ -361,6 +341,10 @@ class TRINITY_DLL_SPEC Aura int32 m_stackAmount; private: void CleanupTriggeredSpells(); + void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); } + void SetAuraFlag(uint32 slot, bool add); + void SetAuraLevel(uint32 slot, uint32 level); + void SetAuraApplication(uint32 slot, int8 count); }; class TRINITY_DLL_SPEC AreaAura : public Aura diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 59679dbd435..04a93bfb77c 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -128,16 +128,16 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectPowerBurn, // 62 SPELL_EFFECT_POWER_BURN &Spell::EffectThreat, // 63 SPELL_EFFECT_THREAT &Spell::EffectTriggerSpell, // 64 SPELL_EFFECT_TRIGGER_SPELL - &Spell::EffectApplyAreaAura, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID - &Spell::EffectUnused, // 66 SPELL_EFFECT_CREATE_MANA_GEM (possibly recharge it, misc - is item ID) + &Spell::EffectUnused, // 65 SPELL_EFFECT_HEALTH_FUNNEL unused + &Spell::EffectUnused, // 66 SPELL_EFFECT_POWER_FUNNEL unused &Spell::EffectHealMaxHealth, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH &Spell::EffectInterruptCast, // 68 SPELL_EFFECT_INTERRUPT_CAST &Spell::EffectDistract, // 69 SPELL_EFFECT_DISTRACT &Spell::EffectPull, // 70 SPELL_EFFECT_PULL one spell: Distract Move &Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET &Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT - &Spell::EffectUnused, // 73 SPELL_EFFECT_UNTRAIN_TALENTS - &Spell::EffectApplyGlyph, // 74 SPELL_EFFECT_APPLY_GLYPH + &Spell::EffectSummonPossessed, // 73 SPELL_EFFECT_SUMMON_POSSESSED + &Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM &Spell::EffectHealMechanical, // 75 SPELL_EFFECT_HEAL_MECHANICAL one spell: Mechanical Patch Kit &Spell::EffectSummonObjectWild, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD &Spell::EffectScriptEffect, // 77 SPELL_EFFECT_SCRIPT_EFFECT @@ -150,10 +150,10 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT - &Spell::EffectUnused, // 87 SPELL_EFFECT_WMO_DAMAGE - &Spell::EffectUnused, // 88 SPELL_EFFECT_WMO_REPAIR - &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE - &Spell::EffectUnused, // 90 SPELL_EFFECT_KILL_CREDIT + &Spell::EffectSummonTotem, // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1 + &Spell::EffectSummonTotem, // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2 + &Spell::EffectSummonTotem, // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3 + &Spell::EffectSummonTotem, // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4 &Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash &Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM &Spell::EffectUnused, // 93 SPELL_EFFECT_SUMMON_PHANTASM @@ -195,21 +195,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY &Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT &Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells - &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc) + &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value &Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization &Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry &Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET &Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT &Spell::EffectEnergisePct, //137 SPELL_EFFECT_ENERGIZE_PCT &Spell::EffectNULL, //138 SPELL_EFFECT_138 Leap - &Spell::EffectUnused, //139 SPELL_EFFECT_CLEAR_QUEST (misc - is quest ID) + &Spell::EffectUnused, //139 SPELL_EFFECT_139 unused &Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST &Spell::EffectNULL, //141 SPELL_EFFECT_141 damage and reduce speed? &Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE &Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER &Spell::EffectNULL, //144 SPELL_EFFECT_144 Spectral Blast &Spell::EffectNULL, //145 SPELL_EFFECT_145 Black Hole Effect - &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE + &Spell::EffectUnused, //146 SPELL_EFFECT_146 unused &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail &Spell::EffectUnused, //148 SPELL_EFFECT_148 unused &Spell::EffectNULL, //149 SPELL_EFFECT_149 swoop @@ -217,12 +217,6 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2 &Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend &Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry - &Spell::EffectNULL, //154 unused - &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal. - &Spell::EffectNULL, //156 Add Socket - &Spell::EffectNULL, //157 create/learn random item/spell for profession - &Spell::EffectMilling, //158 milling - &Spell::EffectNULL //159 allow rename pet once again }; void Spell::EffectNULL(uint32 /*i*/) @@ -341,13 +335,6 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) damage = 200; break; } - // Intercept (warrior spell trigger) - case 20253: - case 61491: - { - damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.12f); - break; - } // arcane charge. must only affect demons (also undead?) case 45072: { @@ -397,12 +384,6 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) 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) - damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f); - // Heroic Throw ${$m1+$AP*.50} - else if(m_spellInfo->SpellFamilyFlags & 0x0000000100000000LL) - damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); break; } case SPELLFAMILY_WARLOCK: @@ -412,20 +393,18 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) { // Incinerate does more dmg (dmg*0.25) if the target is Immolated. if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) - damage += int32(damage*0.25f); + damage += int32(damage*0.25); } break; } case SPELLFAMILY_DRUID: { // Ferocious Bite - if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual[0]==6587) + if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587) { - // converts each extra point of energy into ($f1+$AP/410) additional damage - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx]; + // converts each extra point of energy into ($f1+$AP/630) additional damage + float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx]; damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple); - damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100); m_caster->SetPower(POWER_ENERGY,0); } // Rake @@ -501,7 +480,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) { // Deadly poison (only attacker applied) if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) && - (*itr)->GetSpellProto()->SpellVisual[0]==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) + (*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) { --combo; ++doses; @@ -527,47 +506,26 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) { if(uint32 combo = ((Player*)m_caster)->GetComboPoints()) { - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f)); + damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f); // Eviscerate and Envenom Bonus Damage (item set effect) if(m_caster->GetDummyAura(37169)) damage += combo*40; } } - // Gouge - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000008LL) - { - damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.02f); - } - // Instant Poison - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000002000LL) - { - damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f); - } - // Wound Poison - else if(m_spellInfo->SpellFamilyFlags & 0x0000000010000000LL) - { - damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f); - } break; } case SPELLFAMILY_HUNTER: { // Mongoose Bite - if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual[0]==342) + if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342) { - damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); - } - // Counterattack - else if(m_spellInfo->SpellFamilyFlags & 0x0008000000000000LL) - { - damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); + damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2); } // Arcane Shot else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0) { - damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f); + damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15); } // Steady Shot else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) @@ -575,16 +533,16 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) 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 + //Explosive Trap Effect else if(m_spellInfo->SpellFamilyFlags & 0x00000004) { - damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f); + damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1); } break; } case SPELLFAMILY_PALADIN: { - // Judgement of Vengeance + //Judgement of Vengeance if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292) { uint32 stacks = 0; @@ -598,38 +556,6 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) else damage *= stacks; } - // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) - else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL) - { - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); - damage += int32(ap * 0.07f) + int32(holy * 7 / 100); - } - // Exorcism ($m1+0.15*$SPH+0.15*$AP) - else if(m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL) - { - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); - damage += int32(ap * 0.15f) + int32(holy * 15 / 100); - } - // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - else if(m_spellInfo->SpellFamilyFlags & 0x0000008000000000LL) - { - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); - damage += int32(ap * 0.15f) + int32(holy * 15 / 100); - } - // Holy Wrath ($m1+0.07*$SPH+0.07*$AP) - else if(m_spellInfo->SpellFamilyFlags & 0x0020000000000000LL) - { - float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + - m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); - damage += int32(ap * 0.15f) + int32(holy * 15 / 100); - } break; } } @@ -1229,12 +1155,6 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(m_caster, 30452, true, NULL); return; } - case 53341: - case 53343: - { - m_caster->CastSpell(m_caster,54586,true); - return; - } } //All IconID Check in there @@ -1308,7 +1228,7 @@ void Spell::EffectDummy(uint32 i) break; case SPELLFAMILY_WARRIOR: // Charge - if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867) + if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867) { int32 chargeBasePoints0 = damage; m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true); @@ -1595,8 +1515,10 @@ void Spell::EffectDummy(uint32 i) mod->value = -50; mod->type = SPELLMOD_PCT; mod->spellId = m_spellInfo->Id; + mod->effectId = i; + mod->lastAffected = NULL; mod->mask = 0x0000020000000000LL; - mod->mask2= 0LL; + mod->charges = 0; ((Player*)m_caster)->AddSpellMod(mod, true); m_caster->CastSpell(unitTarget,spell_proto,true,NULL); @@ -2955,10 +2877,10 @@ void Spell::EffectOpenLock(uint32 /*i*/) } // check key - for(int i = 0; i < 8; ++i) + for(int i = 0; i < 5; ++i) { - // Type==1 This means lockInfo->Index[i] is an item - if(lockInfo->Type[i]==LOCK_KEY_ITEM && lockInfo->Index[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[i]) + // type==1 This means lockInfo->key[i] is an item + if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i]) { SendLoot(guid, loottype); return; @@ -2976,9 +2898,9 @@ void Spell::EffectOpenLock(uint32 /*i*/) // skill bonus provided by casting spell (mostly item spells) uint32 spellSkillBonus = uint32(m_currentBasePoints[0]/*+1*/); - uint32 reqSkillValue = lockInfo->Skill[0]; + uint32 reqSkillValue = lockInfo->requiredminingskill; - if(lockInfo->Skill[1]) // required pick lock skill applying + if(lockInfo->requiredlockskill) // required pick lock skill applying { if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?) { @@ -2986,7 +2908,7 @@ void Spell::EffectOpenLock(uint32 /*i*/) return; } - reqSkillValue = lockInfo->Skill[1]; + reqSkillValue = lockInfo->requiredlockskill; } else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target { @@ -3313,7 +3235,7 @@ void Spell::EffectLearnSpell(uint32 i) Player *player = (Player*)unitTarget; - uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i]; + uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i]; player->learnSpell(spellToLearn); sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() ); @@ -3955,13 +3877,13 @@ void Spell::EffectEnchantItemTmp(uint32 i) else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN) duration = 1800; // 30 mins // other cases with this SpellVisual already selected - else if(m_spellInfo->SpellVisual[0]==215) + else if(m_spellInfo->SpellVisual==215) duration = 1800; // 30 mins // some fishing pole bonuses - else if(m_spellInfo->SpellVisual[0]==563) + else if(m_spellInfo->SpellVisual==563) duration = 600; // 10 mins // shaman rockbiter enchantments - else if(m_spellInfo->SpellVisual[0]==0) + else if(m_spellInfo->SpellVisual==0) duration = 1800; // 30 mins else if(m_spellInfo->Id==29702) duration = 300; // 5 mins @@ -4024,16 +3946,14 @@ void Spell::EffectTameCreature(uint32 /*i*/) creatureTarget->RemoveCorpse(); creatureTarget->SetHealth(0); // just for nice GM-mode view - uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel(); - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); // add to world pet->GetMap()->Add((Creature*)pet); // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); // caster have pet now m_caster->SetPet(pet); @@ -4232,6 +4152,7 @@ void Spell::EffectLearnPetSpell(uint32 i) if(!learn_spellproto) return; + pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id)); pet->learnSpell(learn_spellproto->Id); pet->SavePetToDB(PET_SAVE_AS_CURRENT); @@ -4291,7 +4212,7 @@ void Spell::EffectWeaponDmg(uint32 i) case SPELLFAMILY_WARRIOR: { // Devastate bonus and sunder armor refresh - if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508) + if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508) { uint32 stack = 0; @@ -4304,7 +4225,7 @@ void Spell::EffectWeaponDmg(uint32 i) { int32 duration = GetSpellDuration(proto); (*itr)->SetAuraDuration(duration); - (*itr)->SendAuraUpdate(false); + (*itr)->UpdateAuraDuration(); stack = (*itr)->GetStackAmount(); break; } @@ -5015,69 +4936,9 @@ void Spell::EffectScriptEffect(uint32 effIndex) ((Player*)unitTarget)->ModifyMoney(50000000); break; } - case 51770: - { - if(!unitTarget) - return; - - unitTarget->CastSpell(unitTarget,51771,false); - break; - } } - if( m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER ) - { - switch(m_spellInfo->Id) - { - // Chimera Shot - case 53209: - { - uint32 spellId = 0; - int32 basePoint = 0; - Unit::AuraMap& Auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) - { - Aura *aura = (*i).second; - if (aura->GetCasterGUID() != m_caster->GetGUID()) - continue; - // Search only Serpent Sting, Viper Sting, Scorpid Sting auras - uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; - if (!(familyFlag & 0x000000800000C000LL)) - continue; - // Refresh aura duration - aura->SetAuraDuration(aura->GetAuraMaxDuration()); - aura->SendAuraUpdate(false); - // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if (familyFlag & 0x0000000000004000LL && 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) - { - 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) - spellId = 53359; // 53359 Chimera Shot - Scorpid - // ?? nothing say in spell desc (possibly need addition check) - //if (familyFlag & 0x0000010000000000LL || // dot - // familyFlag & 0x0000100000000000LL) // stun - //{ - // spellId = 53366; // 53366 Chimera Shot - Wyvern - //} - } - if (spellId) - m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); - return; - } - default: - break; - } - } - else if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) + if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) { switch(m_spellInfo->SpellFamilyFlags) { @@ -5199,8 +5060,7 @@ void Spell::EffectDuel(uint32 i) // Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities) // Don't have to check the target's map since you cannot challenge someone across maps - uint32 mapid = caster->GetMapId(); - if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609) + if( caster->GetMapId() != 0 && caster->GetMapId() != 1 && caster->GetMapId() != 530) { SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here return; @@ -5339,45 +5199,6 @@ void Spell::EffectActivateObject(uint32 effect_idx) sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget); } -void Spell::EffectApplyGlyph(uint32 i) -{ - if(m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - Player *player = (Player*)m_caster; - - // remove old glyph - if(uint32 oldglyph = player->GetGlyph(m_glyphIndex)) - { - if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) - { - player->RemoveAurasDueToSpell(old_gp->SpellId); - player->SetGlyph(m_glyphIndex, 0); - } - } - - // apply new one - if(uint32 glyph = m_spellInfo->EffectMiscValue[i]) - { - if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) - { - if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex))) - { - if(gp->TypeFlags != gs->TypeFlags) - { - SendCastResult(SPELL_FAILED_INVALID_GLYPH); - return; // glyph slot missmatch - } - } - - player->CastSpell(m_caster, gp->SpellId, true); - player->SetGlyph(m_glyphIndex, glyph); - if(m_CastItem) - player->DestroyItemCount(m_CastItem->GetEntry(), 1, true); - } - } -} - void Spell::EffectSummonTotem(uint32 i) { uint8 slot = 0; @@ -5701,14 +5522,18 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/) void Spell::EffectParry(uint32 /*i*/) { - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + { ((Player*)unitTarget)->SetCanParry(true); + } } void Spell::EffectBlock(uint32 /*i*/) { - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - ((Player*)unitTarget)->SetCanBlock(true); + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->SetCanBlock(true); } void Spell::EffectMomentMove(uint32 i) @@ -6258,9 +6083,9 @@ void Spell::EffectTransmitted(uint32 effIndex) { m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID()); // Orientation3 - pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, 0.88431775569915771 ); + pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 ); // Orientation4 - pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, -0.4668855369091033 ); + pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 ); m_caster->AddGameObject(pGameObj); // will removed at spell cancel // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) @@ -6355,28 +6180,6 @@ void Spell::EffectProspecting(uint32 /*i*/) ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING); } -void Spell::EffectMilling(uint32 /*i*/) -{ - if(m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - Player* p_caster = (Player*)m_caster; - if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS)) - return; - - if(itemTarget->GetCount() < 5) - return; - - if( sWorld.getConfig(CONFIG_SKILL_MILLING)) - { - uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION); - uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank; - p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue); - } - - ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_MILLING); -} - void Spell::EffectSkill(uint32 /*i*/) { sLog.outDebug("WORLD: SkillEFFECT"); @@ -6524,31 +6327,6 @@ void Spell::EffectQuestFail(uint32 i) ((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]); } -void Spell::EffectActivateRune(uint32 i) -{ - if(m_caster->GetTypeId() != TYPEID_PLAYER) - return; - - Player *plr = (Player*)m_caster; - - if(plr->getClass() != CLASS_DEATH_KNIGHT) - return; - - for(uint32 j = 0; j < MAX_RUNES; ++j) - { - if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[i]) - { - plr->SetRuneCooldown(j, 0); - } - } -} - -void Spell::EffectTitanGrip(uint32 i) -{ - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - ((Player*)unitTarget)->SetCanTitanGrip(true); -} - void Spell::EffectRedirectThreat(uint32 /*i*/) { if(unitTarget) diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index d31c5610ee8..9b77e19b30b 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -38,17 +38,15 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { // TODO: add targets.read() check - CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1); + CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8); Player* pUser = _player; uint8 bagIndex, slot; - uint8 unk_flags; // flags (if 0x02 - some additional data are received) + uint8 spell_count; // number of spells at item, not used uint8 cast_count; // next cast if exists (single or not) uint64 item_guid; - uint32 glyphIndex; // something to do with glyphs? - uint32 spellid; // casted spell id - recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags; + recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid; Item *pItem = pUser->GetItemByPos(bagIndex, slot); if(!pItem) @@ -63,7 +61,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) return; } - sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, recvPacket.size()); + sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size()); ItemPrototype const *proto = pItem->GetProto(); if(!proto) @@ -130,15 +128,14 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) // no script or script not process request by self // special learning case - if((pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) || (pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET)) + if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) { - uint32 learn_spell_id = pItem->GetProto()->Spells[0].SpellId; uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN); if(!spellInfo) { - sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id); + sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN); pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL); return; } @@ -175,8 +172,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) Spell *spell = new Spell(pUser, spellInfo, (count > 0)); spell->m_CastItem = pItem; - spell->m_cast_count = cast_count; // set count of casts - spell->m_glyphIndex = glyphIndex; // glyph index + spell->m_cast_count = cast_count; //set count of casts spell->prepare(&targets); ++count; @@ -231,7 +227,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) } // required picklocking - if(lockInfo->Skill[1] || lockInfo->Skill[0]) + if(lockInfo->requiredlockskill || lockInfo->requiredminingskill) { pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL ); return; @@ -287,16 +283,15 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { - CHECK_PACKET_SIZE(recvPacket,1+4+1); + CHECK_PACKET_SIZE(recvPacket,4+1+2); uint32 spellId; - uint8 cast_count, unk_flags; - recvPacket >> cast_count; + uint8 cast_count; recvPacket >> spellId; - recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received) + recvPacket >> cast_count; - sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i", - spellId, cast_count, unk_flags, recvPacket.size()); + sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i", + spellId, cast_count, recvPacket.size()); SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); @@ -339,12 +334,9 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket) { - CHECK_PACKET_SIZE(recvPacket,5); + CHECK_PACKET_SIZE(recvPacket,4); - // increments with every CANCEL packet, don't use for now - uint8 counter; uint32 spellId; - recvPacket >> counter; recvPacket >> spellId; //FIXME: hack, ignore unexpected client cancel Deadly Throw cast diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 7b18e595044..432682d618e 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -41,13 +41,13 @@ SpellMgr::SpellMgr() case SPELL_EFFECT_TRANS_DOOR: //50 summon object case SPELL_EFFECT_SUMMON_PET: //56 case SPELL_EFFECT_ADD_FARSIGHT: //72 - //case SPELL_EFFECT_SUMMON_POSSESSED: //73 - //case SPELL_EFFECT_SUMMON_TOTEM: //74 + case SPELL_EFFECT_SUMMON_POSSESSED: //73 + case SPELL_EFFECT_SUMMON_TOTEM: //74 case SPELL_EFFECT_SUMMON_OBJECT_WILD: //76 - //case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87 - //case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88 - //case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89 - //case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90 + case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: //87 + case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: //88 + case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: //89 + case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: //90 case SPELL_EFFECT_SUMMON_CRITTER: //97 case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: //104 case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: //105 @@ -318,10 +318,10 @@ SpellSpecific GetSpellSpecific(uint32 spellId) if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200)) return SPELL_JUDGEMENT; - for (int i = 0; i < 3; i++) // TODO: fix it for WotLK!!! + for (int i = 0; i < 3; i++) { // only paladin auras have this - if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID) + if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY) return SPELL_AURA; } break; @@ -339,7 +339,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId) } // only warlock armor/skin have this (in additional to family cases) - if( spellInfo->SpellVisual[0] == 130 && spellInfo->SpellIconID == 89) + if( spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89) { return SPELL_WARLOCK_ARMOR; } @@ -828,8 +828,8 @@ void SpellMgr::LoadSpellAffects() uint32 count = 0; - // 0 1 2 3 4 - QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellClassMask0, SpellClassMask1, SpellClassMask2 FROM spell_affect"); + // 0 1 2 + QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect"); if( !result ) { @@ -876,29 +876,26 @@ void SpellMgr::LoadSpellAffects() continue; } - SpellAffectEntry affect; - affect.SpellClassMask[0] = fields[2].GetUInt32(); - affect.SpellClassMask[1] = fields[3].GetUInt32(); - affect.SpellClassMask[2] = fields[4].GetUInt32(); + uint64 spellAffectMask = fields[2].GetUInt64(); - // Spell.dbc have own data - uint32 const *ptr = 0; - switch (effectId) + // Spell.dbc have own data for low part of SpellFamilyMask + if( spellInfo->EffectItemType[effectId]) { - case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break; - case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break; - case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break; - default: + if(spellInfo->EffectItemType[effectId] == spellAffectMask) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectItemType%d) data for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId); continue; - } - if(ptr[0] == affect.SpellClassMask[0] || ptr[1] == affect.SpellClassMask[1] || ptr[2] == affect.SpellClassMask[2]) - { - char text[]="ABC"; - sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectSpellClassMask%c) data for effect index (%u) and not needed, skipped.", entry, text[effectId], effectId); - continue; + } + + // 24429 have wrong data in EffectItemType and overwrites by DB, possible bug in client + if(spellInfo->Id!=24429 && spellInfo->EffectItemType[effectId] != spellAffectMask) + { + sLog.outErrorDb("Spell %u listed in `spell_affect` have different low part from EffectItemType%d for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId); + continue; + } } - mSpellAffectMap[(entry<<8) + effectId] = affect; + mSpellAffectMap.insert(SpellAffectMap::value_type((entry<<8) + effectId,spellAffectMask)); ++count; } while( result->NextRow() ); @@ -906,7 +903,7 @@ void SpellMgr::LoadSpellAffects() delete result; sLog.outString(); - sLog.outString( ">> Loaded %u custom spell affect definitions", count ); + sLog.outString( ">> Loaded %u spell affect definitions", count ); for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id) { @@ -922,16 +919,7 @@ void SpellMgr::LoadSpellAffects() spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER) ) continue; - uint32 const *ptr = 0; - switch (effectId) - { - case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break; - case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break; - case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break; - default: - continue; - } - if(ptr[0] || ptr[1] || ptr[2]) + if(spellInfo->EffectItemType[effectId] != 0) continue; if(mSpellAffectMap.find((id<<8) + effectId) != mSpellAffectMap.end()) @@ -942,20 +930,33 @@ void SpellMgr::LoadSpellAffects() } } -bool SpellMgr::IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const +bool SpellMgr::IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const { // false for spellInfo == NULL - if (!spellInfo || !mod) + if (!spellInfo) return false; - SpellEntry const *affect_spell = sSpellStore.LookupEntry(mod->spellId); - // False if affect_spell == NULL or spellFamily not equal - if (!affect_spell || affect_spell->SpellFamilyName != spellInfo->SpellFamilyName) + SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId); + // false for affect_spell == NULL + if (!affect_spell) return false; + // False if spellFamily not equal + if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName) + return false; + + // If familyFlags == 0 + if (!familyFlags) + { + // Get it from spellAffect table + familyFlags = GetSpellAffectMask(spellId,effectId); + // false if familyFlags == 0 + if (!familyFlags) + return false; + } + // true - if (mod->mask & spellInfo->SpellFamilyFlags || - mod->mask2 & spellInfo->SpellFamilyFlags2) + if (familyFlags & spellInfo->SpellFamilyFlags) return true; return false; @@ -1249,7 +1250,7 @@ bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo) { // Paladin aura Spell if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN - && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID) + && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY) return false; // Druid form Spell if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID @@ -1386,8 +1387,7 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell { if( IsPositiveEffect(spellInfo->Id, i) && ( spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID + spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ) ) { needRankSelection = true; @@ -1519,7 +1519,7 @@ void SpellMgr::LoadSpellChains() entry.ProcFlags=SpellInfo->procFlags; entry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags; entry.TargetAuraState=SpellInfo->TargetAuraState; - entry.SpellVisual=SpellInfo->SpellVisual[0]; + entry.SpellVisual=SpellInfo->SpellVisual; entry.ManaCost=SpellInfo->manaCost; value.Id=spell_id; @@ -2042,7 +2042,7 @@ void SpellMgr::LoadSpellCustomAttr() } } - if(spellInfo->SpellVisual[0] == 3879) + if(spellInfo->SpellVisual == 3879) mSpellCustomAttr[i] |= SPELL_ATTR_CU_CONE_BACK; switch(i) @@ -2146,187 +2146,6 @@ void SpellMgr::LoadSpellLinked() } /// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc -void SpellMgr::LoadPetLevelupSpellMap() -{ - CreatureFamilyEntry const *creatureFamily; - SpellEntry const *spell; - uint32 count = 0; - - for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i) - { - creatureFamily = sCreatureFamilyStore.LookupEntry(i); - - if(!creatureFamily) // not exist - continue; - - if(creatureFamily->petTalentType < 0) // not hunter pet family - continue; - - for(uint32 j = 0; j < sSpellStore.GetNumRows(); ++j) - { - spell = sSpellStore.LookupEntry(j); - - // not exist - if(!spell) - continue; - - // not hunter spell - if(spell->SpellFamilyName != SPELLFAMILY_HUNTER) - continue; - - // not pet spell - if(!(spell->SpellFamilyFlags & 0x1000000000000000LL)) - continue; - - // not Growl or Cower (generics) - if(spell->SpellIconID != 201 && spell->SpellIconID != 958) - { - switch(creatureFamily->ID) - { - case CREATURE_FAMILY_BAT: // Bite and Sonic Blast - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1577) - continue; - break; - case CREATURE_FAMILY_BEAR: // Claw and Swipe - if(spell->SpellIconID != 262 && spell->SpellIconID != 1562) - continue; - break; - case CREATURE_FAMILY_BIRD_OF_PREY: // Claw and Snatch - if(spell->SpellIconID != 262 && spell->SpellIconID != 168) - continue; - break; - case CREATURE_FAMILY_BOAR: // Bite and Gore - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1578) - continue; - break; - case CREATURE_FAMILY_CARRION_BIRD: // Bite and Demoralizing Screech - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1579) - continue; - break; - case CREATURE_FAMILY_CAT: // Claw and Prowl and Rake - if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 494) - continue; - break; - case CREATURE_FAMILY_CHIMAERA: // Bite and Froststorm Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) - continue; - break; - case CREATURE_FAMILY_CORE_HOUND: // Bite and Lava Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1197) - continue; - break; - case CREATURE_FAMILY_CRAB: // Claw and Pin - if(spell->SpellIconID != 262 && spell->SpellIconID != 2679) - continue; - break; - case CREATURE_FAMILY_CROCOLISK: // Bite and Bad Attitude - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1581) - continue; - break; - case CREATURE_FAMILY_DEVILSAUR: // Bite and Monstrous Bite - if(spell->SpellIconID != 1680 && spell->SpellIconID != 599) - continue; - break; - case CREATURE_FAMILY_DRAGONHAWK: // Bite and Fire Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 2128) - continue; - break; - case CREATURE_FAMILY_GORILLA: // Smack and Thunderstomp - if(spell->SpellIconID != 473 && spell->SpellIconID != 148) - continue; - break; - case CREATURE_FAMILY_HYENA: // Bite and Tendon Rip - if(spell->SpellIconID != 1680 && spell->SpellIconID != 138) - continue; - break; - case CREATURE_FAMILY_MOTH: // Serenity Dust and Smack - if(spell->SpellIconID != 1714 && spell->SpellIconID != 473) - continue; - break; - case CREATURE_FAMILY_NETHER_RAY: // Bite and Nether Shock - if(spell->SpellIconID != 1680 && spell->SpellIconID != 2027) - continue; - break; - case CREATURE_FAMILY_RAPTOR: // Claw and Savage Rend - if(spell->SpellIconID != 262 && spell->SpellIconID != 245) - continue; - break; - case CREATURE_FAMILY_RAVAGER: // Bite and Ravage - if(spell->SpellIconID != 1680 && spell->SpellIconID != 2253) - continue; - break; - case CREATURE_FAMILY_RHINO: // Smack and Stampede - if(spell->SpellIconID != 473 && spell->SpellIconID != 3066) - continue; - break; - case CREATURE_FAMILY_SCORPID: // Claw and Scorpid Poison - if(spell->SpellIconID != 262 && spell->SpellIconID != 163) - continue; - break; - case CREATURE_FAMILY_SERPENT: // Bite and Poison Spit - if(spell->SpellIconID != 1680 && spell->SpellIconID != 68) - continue; - break; - case CREATURE_FAMILY_SILITHID: // Claw and Venom Web Spray - if(spell->SpellIconID != 262 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 12013)) - continue; - break; - case CREATURE_FAMILY_SPIDER: // Bite and Web - if(spell->SpellIconID != 1680 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 684)) - continue; - break; - case CREATURE_FAMILY_SPIRIT_BEAST: // Claw and Prowl and Spirit Strike - if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 255) - continue; - break; - case CREATURE_FAMILY_SPOREBAT: // Smack and Spore Cloud - if(spell->SpellIconID != 473 && spell->SpellIconID != 2681) - continue; - break; - case CREATURE_FAMILY_TALLSTRIDER: // Claw and Dust Cloud - if(spell->SpellIconID != 262 && (spell->SpellIconID != 157 && !(spell->Attributes & 0x4000000))) - continue; - break; - case CREATURE_FAMILY_TURTLE: // Bite and Shell Shield - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1588) - continue; - break; - case CREATURE_FAMILY_WARP_STALKER: // Bite and Warp - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1952) - continue; - break; - case CREATURE_FAMILY_WASP: // Smack and Sting - if(spell->SpellIconID != 473 && spell->SpellIconID != 110) - continue; - break; - case CREATURE_FAMILY_WIND_SERPENT: // Bite and Lightning Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) - continue; - break; - case CREATURE_FAMILY_WOLF: // Bite and Furious Howl - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1573) - continue; - break; - case CREATURE_FAMILY_WORM: // Acid Spit and Bite - if(spell->SpellIconID != 636 && spell->SpellIconID != 1680) - continue; - break; - default: - sLog.outError("LoadPetLevelupSpellMap: Unhandled creature family %u", creatureFamily->ID); - continue; - } - } - - mPetLevelupSpellMap[creatureFamily->ID][spell->spellLevel] = spell->Id; - count++; - } - } - - sLog.outString(); - sLog.outString( ">> Loaded %u pet levelup spells", count ); -} - -/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) { // not exist @@ -2404,7 +2223,7 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id) { // normal case - if( spellInfo->AreaId > 0 && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id ) + if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id ) return false; // elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup) diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 239c728aa11..51e6fbd1d56 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -29,9 +29,6 @@ #include "Database/SQLStorage.h" #include "Utilities/UnorderedMap.h" - -#include "Player.h" - #include class Player; @@ -41,188 +38,175 @@ extern SQLStorage sSpellThreatStore; enum SpellFailedReason { - SPELL_FAILED_AFFECTING_COMBAT = 0, - SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1, - SPELL_FAILED_ALREADY_AT_FULL_MANA = 2, - SPELL_FAILED_ALREADY_AT_FULL_POWER = 3, - SPELL_FAILED_ALREADY_BEING_TAMED = 4, - SPELL_FAILED_ALREADY_HAVE_CHARM = 5, - SPELL_FAILED_ALREADY_HAVE_SUMMON = 6, - SPELL_FAILED_ALREADY_OPEN = 7, - SPELL_FAILED_AURA_BOUNCED = 8, - SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9, - SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10, - SPELL_FAILED_BAD_TARGETS = 11, - SPELL_FAILED_CANT_BE_CHARMED = 12, - SPELL_FAILED_CANT_BE_DISENCHANTED = 13, - SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14, - SPELL_FAILED_CANT_BE_MILLED = 15, - SPELL_FAILED_CANT_BE_PROSPECTED = 16, - SPELL_FAILED_CANT_CAST_ON_TAPPED = 17, - SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18, - SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19, - SPELL_FAILED_CANT_STEALTH = 20, - SPELL_FAILED_CASTER_AURASTATE = 21, - SPELL_FAILED_CASTER_DEAD = 22, - SPELL_FAILED_CHARMED = 23, - SPELL_FAILED_CHEST_IN_USE = 24, - SPELL_FAILED_CONFUSED = 25, - SPELL_FAILED_DONT_REPORT = 26, - SPELL_FAILED_EQUIPPED_ITEM = 27, - SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30, - SPELL_FAILED_ERROR = 31, - SPELL_FAILED_FIZZLE = 32, - SPELL_FAILED_FLEEING = 33, - SPELL_FAILED_FOOD_LOWLEVEL = 34, - SPELL_FAILED_HIGHLEVEL = 35, - SPELL_FAILED_HUNGER_SATIATED = 36, - SPELL_FAILED_IMMUNE = 37, - SPELL_FAILED_INCORRECT_AREA = 38, - SPELL_FAILED_INTERRUPTED = 39, - SPELL_FAILED_INTERRUPTED_COMBAT = 40, - SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41, - SPELL_FAILED_ITEM_GONE = 42, - SPELL_FAILED_ITEM_NOT_FOUND = 43, - SPELL_FAILED_ITEM_NOT_READY = 44, - SPELL_FAILED_LEVEL_REQUIREMENT = 45, - SPELL_FAILED_LINE_OF_SIGHT = 46, - SPELL_FAILED_LOWLEVEL = 47, - SPELL_FAILED_LOW_CASTLEVEL = 48, - SPELL_FAILED_MAINHAND_EMPTY = 49, - SPELL_FAILED_MOVING = 50, - SPELL_FAILED_NEED_AMMO = 51, - SPELL_FAILED_NEED_AMMO_POUCH = 52, - SPELL_FAILED_NEED_EXOTIC_AMMO = 53, - SPELL_FAILED_NEED_MORE_ITEMS = 54, - SPELL_FAILED_NOPATH = 55, - SPELL_FAILED_NOT_BEHIND = 56, - SPELL_FAILED_NOT_FISHABLE = 57, - SPELL_FAILED_NOT_FLYING = 58, - SPELL_FAILED_NOT_HERE = 59, - SPELL_FAILED_NOT_INFRONT = 60, - SPELL_FAILED_NOT_IN_CONTROL = 61, - SPELL_FAILED_NOT_KNOWN = 62, - SPELL_FAILED_NOT_MOUNTED = 63, - SPELL_FAILED_NOT_ON_TAXI = 64, - SPELL_FAILED_NOT_ON_TRANSPORT = 65, - SPELL_FAILED_NOT_READY = 66, - SPELL_FAILED_NOT_SHAPESHIFT = 67, - SPELL_FAILED_NOT_STANDING = 68, - SPELL_FAILED_NOT_TRADEABLE = 69, - SPELL_FAILED_NOT_TRADING = 70, - SPELL_FAILED_NOT_UNSHEATHED = 71, - SPELL_FAILED_NOT_WHILE_GHOST = 72, - SPELL_FAILED_NOT_WHILE_LOOTING = 73, - SPELL_FAILED_NO_AMMO = 74, - SPELL_FAILED_NO_CHARGES_REMAIN = 75, - SPELL_FAILED_NO_CHAMPION = 76, - SPELL_FAILED_NO_COMBO_POINTS = 77, - SPELL_FAILED_NO_DUELING = 78, - SPELL_FAILED_NO_ENDURANCE = 79, - SPELL_FAILED_NO_FISH = 80, - SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81, - SPELL_FAILED_NO_MOUNTS_ALLOWED = 82, - SPELL_FAILED_NO_PET = 83, - SPELL_FAILED_NO_POWER = 84, - SPELL_FAILED_NOTHING_TO_DISPEL = 85, - SPELL_FAILED_NOTHING_TO_STEAL = 86, - SPELL_FAILED_ONLY_ABOVEWATER = 87, - SPELL_FAILED_ONLY_DAYTIME = 88, - SPELL_FAILED_ONLY_INDOORS = 89, - SPELL_FAILED_ONLY_MOUNTED = 90, - SPELL_FAILED_ONLY_NIGHTTIME = 91, - SPELL_FAILED_ONLY_OUTDOORS = 92, - SPELL_FAILED_ONLY_SHAPESHIFT = 93, - SPELL_FAILED_ONLY_STEALTHED = 94, - SPELL_FAILED_ONLY_UNDERWATER = 95, - SPELL_FAILED_OUT_OF_RANGE = 96, - SPELL_FAILED_PACIFIED = 97, - SPELL_FAILED_POSSESSED = 98, - SPELL_FAILED_REAGENTS = 99, - SPELL_FAILED_REQUIRES_AREA = 100, - SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101, - SPELL_FAILED_ROOTED = 102, - SPELL_FAILED_SILENCED = 103, - SPELL_FAILED_SPELL_IN_PROGRESS = 104, - SPELL_FAILED_SPELL_LEARNED = 105, - SPELL_FAILED_SPELL_UNAVAILABLE = 106, - SPELL_FAILED_STUNNED = 107, - SPELL_FAILED_TARGETS_DEAD = 108, - SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109, - SPELL_FAILED_TARGET_AURASTATE = 110, - SPELL_FAILED_TARGET_DUELING = 111, - SPELL_FAILED_TARGET_ENEMY = 112, - SPELL_FAILED_TARGET_ENRAGED = 113, - SPELL_FAILED_TARGET_FRIENDLY = 114, - SPELL_FAILED_TARGET_IN_COMBAT = 115, - SPELL_FAILED_TARGET_IS_PLAYER = 116, - SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117, - SPELL_FAILED_TARGET_NOT_DEAD = 118, - SPELL_FAILED_TARGET_NOT_IN_PARTY = 119, - SPELL_FAILED_TARGET_NOT_LOOTED = 120, - SPELL_FAILED_TARGET_NOT_PLAYER = 121, - SPELL_FAILED_TARGET_NO_POCKETS = 122, - SPELL_FAILED_TARGET_NO_WEAPONS = 123, - SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124, - SPELL_FAILED_TARGET_UNSKINNABLE = 125, - SPELL_FAILED_THIRST_SATIATED = 126, - SPELL_FAILED_TOO_CLOSE = 127, - SPELL_FAILED_TOO_MANY_OF_ITEM = 128, - SPELL_FAILED_TOTEM_CATEGORY = 129, - SPELL_FAILED_TOTEMS = 130, - SPELL_FAILED_TRY_AGAIN = 131, - SPELL_FAILED_UNIT_NOT_BEHIND = 132, - SPELL_FAILED_UNIT_NOT_INFRONT = 133, - SPELL_FAILED_WRONG_PET_FOOD = 134, - SPELL_FAILED_NOT_WHILE_FATIGUED = 135, - SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136, - SPELL_FAILED_NOT_WHILE_TRADING = 137, - SPELL_FAILED_TARGET_NOT_IN_RAID = 138, - SPELL_FAILED_TARGET_FREEFORALL = 139, - SPELL_FAILED_NO_EDIBLE_CORPSES = 140, - SPELL_FAILED_ONLY_BATTLEGROUNDS = 141, - SPELL_FAILED_TARGET_NOT_GHOST = 142, - SPELL_FAILED_TRANSFORM_UNUSABLE = 143, - SPELL_FAILED_WRONG_WEATHER = 144, - SPELL_FAILED_DAMAGE_IMMUNE = 145, - SPELL_FAILED_PREVENTED_BY_MECHANIC = 146, - SPELL_FAILED_PLAY_TIME = 147, - SPELL_FAILED_REPUTATION = 148, - SPELL_FAILED_MIN_SKILL = 149, - SPELL_FAILED_NOT_IN_ARENA = 150, - SPELL_FAILED_NOT_ON_SHAPESHIFT = 151, - SPELL_FAILED_NOT_ON_STEALTHED = 152, - SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153, - SPELL_FAILED_NOT_ON_MOUNTED = 154, - SPELL_FAILED_TOO_SHALLOW = 155, - SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156, - SPELL_FAILED_TARGET_IS_TRIVIAL = 157, - SPELL_FAILED_BM_OR_INVISGOD = 158, - SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159, - SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160, - SPELL_FAILED_NOT_IDLE = 161, - SPELL_FAILED_NOT_INACTIVE = 162, - SPELL_FAILED_PARTIAL_PLAYTIME = 163, - SPELL_FAILED_NO_PLAYTIME = 164, - SPELL_FAILED_NOT_IN_BATTLEGROUND = 165, - SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166, - SPELL_FAILED_ONLY_IN_ARENA = 167, - SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168, - SPELL_FAILED_ON_USE_ENCHANT = 169, - SPELL_FAILED_NOT_ON_GROUND = 170, - SPELL_FAILED_CUSTOM_ERROR = 171, - SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172, - SPELL_FAILED_TOO_MANY_SOCKETS = 173, - SPELL_FAILED_INVALID_GLYPH = 174, - SPELL_FAILED_UNIQUE_GLYPH = 175, - SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176, - SPELL_FAILED_NO_VALID_TARGETS = 177, - SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178, - SPELL_FAILED_NOT_IN_BARBERSHOP = 179, - SPELL_FAILED_FISHING_TOO_LOW = 180, - SPELL_FAILED_UNKNOWN = 181 + SPELL_FAILED_AFFECTING_COMBAT = 0x00, + SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01, + SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02, + SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03, + SPELL_FAILED_ALREADY_BEING_TAMED = 0x04, + SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05, + SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06, + SPELL_FAILED_ALREADY_OPEN = 0x07, + SPELL_FAILED_AURA_BOUNCED = 0x08, + SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09, + SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A, + SPELL_FAILED_BAD_TARGETS = 0x0B, + SPELL_FAILED_CANT_BE_CHARMED = 0x0C, + SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D, + SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E, + SPELL_FAILED_CANT_BE_PROSPECTED = 0x0F, + SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x10, + SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x11, + SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x12, + SPELL_FAILED_CANT_STEALTH = 0x13, + SPELL_FAILED_CASTER_AURASTATE = 0x14, + SPELL_FAILED_CASTER_DEAD = 0x15, + SPELL_FAILED_CHARMED = 0x16, + SPELL_FAILED_CHEST_IN_USE = 0x17, + SPELL_FAILED_CONFUSED = 0x18, + SPELL_FAILED_DONT_REPORT = 0x19, + SPELL_FAILED_EQUIPPED_ITEM = 0x1A, + SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1B, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1C, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1D, + SPELL_FAILED_ERROR = 0x1E, + SPELL_FAILED_FIZZLE = 0x1F, + SPELL_FAILED_FLEEING = 0x20, + SPELL_FAILED_FOOD_LOWLEVEL = 0x21, + SPELL_FAILED_HIGHLEVEL = 0x22, + SPELL_FAILED_HUNGER_SATIATED = 0x23, + SPELL_FAILED_IMMUNE = 0x24, + SPELL_FAILED_INTERRUPTED = 0x25, + SPELL_FAILED_INTERRUPTED_COMBAT = 0x26, + SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x27, + SPELL_FAILED_ITEM_GONE = 0x28, + SPELL_FAILED_ITEM_NOT_FOUND = 0x29, + SPELL_FAILED_ITEM_NOT_READY = 0x2A, + SPELL_FAILED_LEVEL_REQUIREMENT = 0x2B, + SPELL_FAILED_LINE_OF_SIGHT = 0x2C, + SPELL_FAILED_LOWLEVEL = 0x2D, + SPELL_FAILED_LOW_CASTLEVEL = 0x2E, + SPELL_FAILED_MAINHAND_EMPTY = 0x2F, + SPELL_FAILED_MOVING = 0x30, + SPELL_FAILED_NEED_AMMO = 0x31, + SPELL_FAILED_NEED_AMMO_POUCH = 0x32, + SPELL_FAILED_NEED_EXOTIC_AMMO = 0x33, + SPELL_FAILED_NOPATH = 0x34, + SPELL_FAILED_NOT_BEHIND = 0x35, + SPELL_FAILED_NOT_FISHABLE = 0x36, + SPELL_FAILED_NOT_FLYING = 0x37, + SPELL_FAILED_NOT_HERE = 0x38, + SPELL_FAILED_NOT_INFRONT = 0x39, + SPELL_FAILED_NOT_IN_CONTROL = 0x3A, + SPELL_FAILED_NOT_KNOWN = 0x3B, + SPELL_FAILED_NOT_MOUNTED = 0x3C, + SPELL_FAILED_NOT_ON_TAXI = 0x3D, + SPELL_FAILED_NOT_ON_TRANSPORT = 0x3E, + SPELL_FAILED_NOT_READY = 0x3F, + SPELL_FAILED_NOT_SHAPESHIFT = 0x40, + SPELL_FAILED_NOT_STANDING = 0x41, + SPELL_FAILED_NOT_TRADEABLE = 0x42, + SPELL_FAILED_NOT_TRADING = 0x43, + SPELL_FAILED_NOT_UNSHEATHED = 0x44, + SPELL_FAILED_NOT_WHILE_GHOST = 0x45, + SPELL_FAILED_NO_AMMO = 0x46, + SPELL_FAILED_NO_CHARGES_REMAIN = 0x47, + SPELL_FAILED_NO_CHAMPION = 0x48, + SPELL_FAILED_NO_COMBO_POINTS = 0x49, + SPELL_FAILED_NO_DUELING = 0x4A, + SPELL_FAILED_NO_ENDURANCE = 0x4B, + SPELL_FAILED_NO_FISH = 0x4C, + SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4D, + SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4E, + SPELL_FAILED_NO_PET = 0x4F, + SPELL_FAILED_NO_POWER = 0x50, + SPELL_FAILED_NOTHING_TO_DISPEL = 0x51, + SPELL_FAILED_NOTHING_TO_STEAL = 0x52, + SPELL_FAILED_ONLY_ABOVEWATER = 0x53, + SPELL_FAILED_ONLY_DAYTIME = 0x54, + SPELL_FAILED_ONLY_INDOORS = 0x55, + SPELL_FAILED_ONLY_MOUNTED = 0x56, + SPELL_FAILED_ONLY_NIGHTTIME = 0x57, + SPELL_FAILED_ONLY_OUTDOORS = 0x58, + SPELL_FAILED_ONLY_SHAPESHIFT = 0x59, + SPELL_FAILED_ONLY_STEALTHED = 0x5A, + SPELL_FAILED_ONLY_UNDERWATER = 0x5B, + SPELL_FAILED_OUT_OF_RANGE = 0x5C, + SPELL_FAILED_PACIFIED = 0x5D, + SPELL_FAILED_POSSESSED = 0x5E, + SPELL_FAILED_REAGENTS = 0x5F, + SPELL_FAILED_REQUIRES_AREA = 0x60, + SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x61, + SPELL_FAILED_ROOTED = 0x62, + SPELL_FAILED_SILENCED = 0x63, + SPELL_FAILED_SPELL_IN_PROGRESS = 0x64, + SPELL_FAILED_SPELL_LEARNED = 0x65, + SPELL_FAILED_SPELL_UNAVAILABLE = 0x66, + SPELL_FAILED_STUNNED = 0x67, + SPELL_FAILED_TARGETS_DEAD = 0x68, + SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x69, + SPELL_FAILED_TARGET_AURASTATE = 0x6A, + SPELL_FAILED_TARGET_DUELING = 0x6B, + SPELL_FAILED_TARGET_ENEMY = 0x6C, + SPELL_FAILED_TARGET_ENRAGED = 0x6D, + SPELL_FAILED_TARGET_FRIENDLY = 0x6E, + SPELL_FAILED_TARGET_IN_COMBAT = 0x6F, + SPELL_FAILED_TARGET_IS_PLAYER = 0x70, + SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x71, + SPELL_FAILED_TARGET_NOT_DEAD = 0x72, + SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x73, + SPELL_FAILED_TARGET_NOT_LOOTED = 0x74, + SPELL_FAILED_TARGET_NOT_PLAYER = 0x75, + SPELL_FAILED_TARGET_NO_POCKETS = 0x76, + SPELL_FAILED_TARGET_NO_WEAPONS = 0x77, + SPELL_FAILED_TARGET_UNSKINNABLE = 0x78, + SPELL_FAILED_THIRST_SATIATED = 0x79, + SPELL_FAILED_TOO_CLOSE = 0x7A, + SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7B, + SPELL_FAILED_TOTEM_CATEGORY = 0x7C, + SPELL_FAILED_TOTEMS = 0x7D, + SPELL_FAILED_TRAINING_POINTS = 0x7E, + SPELL_FAILED_TRY_AGAIN = 0x7F, + SPELL_FAILED_UNIT_NOT_BEHIND = 0x80, + SPELL_FAILED_UNIT_NOT_INFRONT = 0x81, + SPELL_FAILED_WRONG_PET_FOOD = 0x82, + SPELL_FAILED_NOT_WHILE_FATIGUED = 0x83, + SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x84, + SPELL_FAILED_NOT_WHILE_TRADING = 0x85, + SPELL_FAILED_TARGET_NOT_IN_RAID = 0x86, + SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x87, + SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x88, + SPELL_FAILED_PROSPECT_NEED_MORE = 0x89, + SPELL_FAILED_TARGET_FREEFORALL = 0x8A, + SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8B, + SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8C, + SPELL_FAILED_TARGET_NOT_GHOST = 0x8D, + SPELL_FAILED_TOO_MANY_SKILLS = 0x8E, + SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F, + SPELL_FAILED_WRONG_WEATHER = 0x90, + SPELL_FAILED_DAMAGE_IMMUNE = 0x91, + SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92, + SPELL_FAILED_PLAY_TIME = 0x93, + SPELL_FAILED_REPUTATION = 0x94, + SPELL_FAILED_MIN_SKILL = 0x95, + SPELL_FAILED_NOT_IN_ARENA = 0x96, + SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97, + SPELL_FAILED_NOT_ON_STEALTHED = 0x98, + SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99, + SPELL_FAILED_NOT_ON_MOUNTED = 0x9A, + SPELL_FAILED_TOO_SHALLOW = 0x9B, + SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C, + SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D, + SPELL_FAILED_BM_OR_INVISGOD = 0x9E, + SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F, + SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0, + SPELL_FAILED_NOT_IDLE = 0xA1, + SPELL_FAILED_NOT_INACTIVE = 0xA2, + SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3, + SPELL_FAILED_NO_PLAYTIME = 0xA4, + SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5, + SPELL_FAILED_ONLY_IN_ARENA = 0xA6, + SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7, + SPELL_FAILED_UNKNOWN = 0xA8, }; enum SpellFamilyNames @@ -239,12 +223,8 @@ enum SpellFamilyNames SPELLFAMILY_HUNTER = 9, SPELLFAMILY_PALADIN = 10, SPELLFAMILY_SHAMAN = 11, - SPELLFAMILY_UNK2 = 12, // 2 spells (silence resistance) - SPELLFAMILY_POTION = 13, - // 14 - unused - SPELLFAMILY_DEATHKNIGHT = 15, - // 16 - unused - SPELLFAMILY_PET = 17 + SPELLFAMILY_UNK2 = 12, + SPELLFAMILY_POTION = 13 }; enum SpellDisableTypes @@ -417,7 +397,6 @@ inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo) inline bool IsAreaAuraEffect(uint32 effect) { if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || - effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID || effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND || effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || effect == SPELL_EFFECT_APPLY_AREA_AURA_PET || @@ -490,11 +469,7 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group); DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group); // Spell affects related declarations (accessed using SpellMgr functions) -struct SpellAffectEntry -{ - uint32 SpellClassMask[3]; -}; -typedef UNORDERED_MAP SpellAffectMap; +typedef std::map SpellAffectMap; // Spell proc event related declarations (accessed using SpellMgr functions) enum ProcFlags @@ -712,9 +687,6 @@ typedef std::multimap SpellLearnSpellMap; typedef std::multimap SkillLineAbilityMap; -typedef std::map PetLevelupSpellSet; -typedef std::map PetLevelupSpellMap; - inline bool IsPrimaryProfessionSkill(uint32 skill) { SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill); @@ -755,15 +727,15 @@ class SpellMgr // Accessors (const or static functions) public: // Spell affects - SpellAffectEntry const*GetSpellAffect(uint16 spellId, uint8 effectId) const + uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const { SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId); if( itr != mSpellAffectMap.end( ) ) - return &itr->second; + return itr->second; return 0; } - bool IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const; + bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const; SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; } @@ -966,6 +938,11 @@ class SpellMgr return 0; else return mSpellCustomAttr[spell_id]; + /*SpellCustomAttrMap::const_iterator itr = mSpellCustomAttrMap.find(spell_id); + if(itr != mSpellCustomAttrMap.end()) + return itr->second; + else + return 0;*/ } const std::vector *GetSpellLinked(int32 spell_id) const @@ -977,15 +954,6 @@ class SpellMgr SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS]; SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS]; - PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const - { - PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily); - if(itr != mPetLevelupSpellMap.end()) - return &itr->second; - else - return NULL; - } - // Modifiers public: static SpellMgr& Instance(); @@ -1005,7 +973,6 @@ class SpellMgr void LoadSpellPetAuras(); void LoadSpellCustomAttr(); void LoadSpellLinked(); - void LoadPetLevelupSpellMap(); private: SpellScriptTarget mSpellScriptTarget; @@ -1022,7 +989,6 @@ class SpellMgr SpellPetAuraMap mSpellPetAuraMap; SpellCustomAttribute mSpellCustomAttr; SpellLinkedMap mSpellLinkedMap; - PetLevelupSpellMap mPetLevelupSpellMap; }; #define spellmgr SpellMgr::Instance() diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index df666d4c71e..3e9ddcf3bef 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -51,17 +51,24 @@ bool Player::UpdateStats(Stats stat) switch(stat) { case STAT_STRENGTH: + UpdateAttackPowerAndDamage(); UpdateShieldBlockValue(); break; case STAT_AGILITY: UpdateArmor(); + UpdateAttackPowerAndDamage(true); + if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT) + UpdateAttackPowerAndDamage(); + UpdateAllCritPercentages(); UpdateDodgePercentage(); break; + case STAT_STAMINA: UpdateMaxHealth(); break; case STAT_INTELLECT: UpdateMaxPower(POWER_MANA); UpdateAllSpellCritChances(); + UpdateAttackPowerAndDamage(true); //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intellect currently UpdateArmor(); //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently break; @@ -71,25 +78,8 @@ bool Player::UpdateStats(Stats stat) default: break; } - // Need update (exist AP from stat auras) - UpdateAttackPowerAndDamage(); - UpdateAttackPowerAndDamage(true); - UpdateSpellDamageAndHealingBonus(); UpdateManaRegen(); - - // Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat - uint32 mask = 0; - AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT); - for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i) - if (Stats((*i)->GetMiscBValue()) == stat) - mask |= (*i)->GetMiscValue(); - if (mask) - { - for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) - if (mask & (1 << rating)) - ApplyRatingMod(CombatRating(rating), 0, true); - } return true; } @@ -265,7 +255,6 @@ void Player::UpdateAttackPowerAndDamage(bool ranged ) { case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; - case CLASS_DEATH_KNIGHT: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; case CLASS_ROGUE: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_HUNTER: val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break; case CLASS_SHAMAN: val2 = level*2.0f + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; @@ -320,20 +309,11 @@ void Player::UpdateAttackPowerAndDamage(bool ranged ) float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); //add dynamic flat mods - if ((getClassMask() & CLASSMASK_WAND_USERS)==0) + if( ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0) { - if( ranged ) - { - AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); - for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) - attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); - } - else - { - AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); - for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) - attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); - } + AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); + for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) + attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifierValue() / 100.0f); } float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; @@ -574,24 +554,6 @@ void Player::UpdateSpellCritChance(uint32 school) SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit); } -void Player::UpdateMeleeHitChances() -{ - m_modMeleeHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); - m_modMeleeHitChance+= GetRatingBonusValue(CR_HIT_MELEE); -} - -void Player::UpdateRangedHitChances() -{ - m_modRangedHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); - m_modRangedHitChance+= GetRatingBonusValue(CR_HIT_RANGED); -} - -void Player::UpdateSpellHitChances() -{ - m_modSpellHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); - m_modSpellHitChance+= GetRatingBonusValue(CR_HIT_SPELL); -} - void Player::UpdateAllSpellCritChances() { for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++) @@ -662,9 +624,9 @@ void Player::UpdateManaRegen() int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); if (modManaRegenInterrupt > 100) modManaRegenInterrupt = 100; - SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f); + SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f); - SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen); + SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN, power_regen_mp5 + power_regen); } void Player::_ApplyAllStatBonuses() @@ -961,7 +923,7 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged) if(getPetType() == HUNTER_PET) //hunter pets benefit from owner's attack power { bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f; - SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f)); + SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.125f)); } //demons benefit from warlocks shadow or fire damage else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK) diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp index fa649e20f6e..640618eaebb 100644 --- a/src/game/TaxiHandler.cpp +++ b/src/game/TaxiHandler.cpp @@ -71,7 +71,7 @@ void WorldSession::SendTaxiStatus( uint64 guid ) sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" ); } -void WorldSession::HandleTaxiQueryAvailableNodes( WorldPacket & recv_data ) +void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index be71fcc3f98..21d3d3b1f27 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -137,7 +137,7 @@ void MapManager::LoadTransports() Transport::Transport() : GameObject() { // 2.3.2 - 0x5A - m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); + m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); } bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) @@ -168,10 +168,9 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); - //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); - SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64)); - SetUInt32Value(GAMEOBJECT_LEVEL, m_period); - SetEntry(goinfo->id); + SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); + + SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id); SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); @@ -180,7 +179,7 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, SetGoAnimProgress(animprogress); if(dynflags) - SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags)); + SetUInt32Value(GAMEOBJECT_DYN_FLAGS, dynflags); return true; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 34156ac661d..e00b2446010 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -60,7 +60,6 @@ float baseMoveSpeed[MAX_MOVE_TYPE] = 3.141594f, // MOVE_TURN_RATE 7.0f, // MOVE_FLIGHT 4.5f, // MOVE_FLIGHT_BACK - 3.14f // MOVE_PITCH_RATE }; void InitTriggerAuraData(); @@ -155,7 +154,7 @@ Unit::Unit() m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; // 2.3.2 - 0x70 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION); + m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION); m_attackTimer[BASE_ATTACK] = 0; m_attackTimer[OFF_ATTACK] = 0; @@ -1632,7 +1631,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss) if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID())) { (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); - (*itr).second->SendAuraUpdate(false); + (*itr).second->UpdateAuraDuration(); } } } @@ -1948,7 +1947,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss) if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID())) { (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); - (*itr).second->SendAuraUpdate(false); + (*itr).second->UpdateAuraDuration(); } } } @@ -2343,7 +2342,9 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama case MELEE_HIT_BLOCK_CRIT: case MELEE_HIT_CRIT: { - *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | HITINFO_UNK2; + //*hitInfo = 0xEA; + // 0xEA + *hitInfo = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8; // Crit bonus calc uint32 crit_bonus; @@ -2580,62 +2581,10 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama } case MELEE_HIT_GLANCING: { -<<<<<<< HEAD:src/game/Unit.cpp int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel()); if (leveldif > 3) leveldif = 3; *damage *= (1 - leveldif * 0.1f); cleanDamage->damage = *damage; -======= - float reducePercent = 1.0f; //damage factor - - // calculate base values and mods - float baseLowEnd = 1.3; - float baseHighEnd = 1.2; - switch(getClass()) // lowering base values for casters - { - case CLASS_SHAMAN: - case CLASS_PRIEST: - case CLASS_MAGE: - case CLASS_WARLOCK: - case CLASS_DRUID: - baseLowEnd -= 0.7; - baseHighEnd -= 0.3; - break; - } - - float maxLowEnd = 0.6; - switch(getClass()) // upper for melee classes - { - case CLASS_WARRIOR: - case CLASS_ROGUE: - case CLASS_DEATH_KNIGHT: - maxLowEnd = 0.91; //If the attacker is a melee class then instead the lower value of 0.91 - } - - // calculate values - int32 diff = int32(pVictim->GetDefenseSkillValue(this)) - int32(GetWeaponSkillValue(attType,pVictim)); - float lowEnd = baseLowEnd - ( 0.05f * diff ); - float highEnd = baseHighEnd - ( 0.03f * diff ); - - // apply max/min bounds - if ( lowEnd < 0.01f ) //the low end must not go bellow 0.01f - lowEnd = 0.01f; - else if ( lowEnd > maxLowEnd ) //the smaller value of this and 0.6 is kept as the low end - lowEnd = maxLowEnd; - - if ( highEnd < 0.2f ) //high end limits - highEnd = 0.2f; - if ( highEnd > 0.99f ) - highEnd = 0.99f; - - if(lowEnd > highEnd) // prevent negative range size - lowEnd = highEnd; - - reducePercent = lowEnd + rand_norm() * ( highEnd - lowEnd ); - - *damage = uint32(reducePercent * *damage); - cleanDamage->damage += *damage; ->>>>>>> upstream/master:src/game/Unit.cpp *hitInfo |= HITINFO_GLANCING; break; } @@ -2684,7 +2633,7 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama ((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) ) { (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); - (*itr).second->SendAuraUpdate(false); + (*itr).second->UpdateAuraDuration(); } } } @@ -2809,20 +2758,21 @@ MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAtt { // Increase from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL aura crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, spellInfo->SchoolMask); - // Ignore combat result aura - AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); - for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) + + if( dodge_chance != 0.0f ) // if dodge chance is already 0, ignore talents for speed { - if (!(*i)->isAffectedOnSpell(spellInfo)) - continue; - switch((*i)->GetModifier()->m_miscvalue) + AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); + for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i) { - case MELEE_HIT_DODGE: dodge_chance = 0.0f; break; - case MELEE_HIT_BLOCK: block_chance = 0.0f; break; - case MELEE_HIT_PARRY: parry_chance = 0.0f; break; - default: - DEBUG_LOG("Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT have unhandled state %d", (*i)->GetId(), (*i)->GetModifier()->m_miscvalue); - break; + // can't be dodged rogue finishing move + if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE) + { + if(spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE)) + { + dodge_chance = 0.0f; + break; + } + } } } } @@ -4788,7 +4738,7 @@ void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime) iter->second->SetAuraDuration(0); else iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime); - iter->second->SendAuraUpdate(false); + iter->second->UpdateAuraDuration(); sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration()); } } @@ -4980,7 +4930,6 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, data.append(GetPackGUID()); data << uint32(SpellID); data << uint32(Damage-AbsorbedDamage-Resist-Blocked); - data << uint32(0); // wotlk data << uint8(damageSchoolMask); // spell school data << uint32(AbsorbedDamage); // AbsorbedDamage data << uint32(Resist); // resist @@ -5045,66 +4994,31 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE"); WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45)); // we guess size - data << uint32(HitInfo); // flags + data << (uint32)HitInfo; data.append(GetPackGUID()); data.append(target->GetPackGUID()); - data << uint32(Damage-AbsorbDamage-Resist-BlockedAmount);// damage - data << uint32(0); // overkill value + data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); data << (uint8)SwingType; // count? // for(i = 0; i < SwingType; ++i) data << (uint32)damageSchoolMask; data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount); + // still need to double check damage data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); + data << (uint32)AbsorbDamage; + data << (uint32)Resist; // end loop - if(HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2)) - { - // for(i = 0; i < SwingType; ++i) - data << uint32(AbsorbDamage); - // end loop - } + data << (uint32)TargetState; - if(HitInfo & (HITINFO_RESIST | HITINFO_RESIST2)) - { - // for(i = 0; i < SwingType; ++i) - data << uint32(Resist); - // end loop - } + if( AbsorbDamage == 0 ) //also 0x3E8 = 0x3E8, check when that happens + data << (uint32)0; + else + data << (uint32)-1; - data << (uint8)TargetState; data << (uint32)0; - data << (uint32)0; - - if(HitInfo & HITINFO_BLOCK) - { - data << uint32(BlockedAmount); - } - - if(HitInfo & HITINFO_UNK3) - { - data << uint32(0); - } - - if(HitInfo & HITINFO_UNK1) - { - data << uint32(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - for(uint8 i = 0; i < 5; ++i) - { - data << float(0); - data << float(0); - } - data << uint32(0); - } + data << (uint32)BlockedAmount; SendMessageToSet( &data, true ); } @@ -5325,7 +5239,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { switch (dummySpell->Id) { - // Eye for an Eye + // Eye of Eye case 9799: case 25988: { @@ -5942,7 +5856,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 39373; break; } - // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus) + // Vestments of Faith (Priest Tier 3) - 4 pieces bonus case 28809: { triggered_spell_id = 28810; @@ -6079,7 +5993,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu } case SPELLFAMILY_PALADIN: { - // TODO: spell list, formula change in 3.0.3 // Seal of Righteousness - melee proc dummy if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0) { @@ -6176,8 +6089,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu } break; } - // TODO: fix basepoint calculation (changed in 3.0.3) - // Seal of Vengeance + //Seal of Vengeance case 31801: { if(effIndex != 0) // effect 1,2 used by seal unleashing code @@ -6186,7 +6098,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 31803; break; } - // Spiritual Attunement + // Spiritual Att. case 31785: case 33776: { @@ -6370,7 +6282,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu } // Earth Shield - if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL) + if(dummySpell->SpellFamilyFlags==0x40000000000LL) { if(GetTypeId() != TYPEID_PLAYER) return false; @@ -6408,8 +6320,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case 15208: spellId = 45294; break; // Rank 10 case 25448: spellId = 45295; break; // Rank 11 case 25449: spellId = 45296; break; // Rank 12 - case 49237: spellId = 49239; break; // Rank 13 - case 49238: spellId = 49240; break; // Rank 14 // Chain Lightning case 421: spellId = 45297; break; // Rank 1 case 930: spellId = 45298; break; // Rank 2 @@ -6417,8 +6327,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case 10605: spellId = 45300; break; // Rank 4 case 25439: spellId = 45301; break; // Rank 5 case 25442: spellId = 45302; break; // Rank 6 - case 49268: spellId = 49270; break; // Rank 7 - case 49269: spellId = 49271; break; // Rank 8 default: sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id); return false; @@ -6429,14 +6337,21 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu mod->value = -100; mod->type = SPELLMOD_PCT; mod->spellId = dummySpell->Id; + mod->effectId = 0; + mod->lastAffected = NULL; mod->mask = 0x0000000000000003LL; - mod->mask2= 0LL; + mod->charges = 0; ((Player*)this)->AddSpellMod(mod, true); // Remove cooldown (Chain Lightning - have Category Recovery time) if (procSpell->SpellFamilyFlags & 0x0000000000000002LL) ((Player*)this)->RemoveSpellCooldown(spellId); + // Hmmm.. in most case spells already set half basepoints but... + // Lightning Bolt (2-10 rank) have full basepoint and half bonus from level + // As on wiki: + // BUG: Rank 2 to 10 (and maybe 11) of Lightning Bolt will proc another Bolt with FULL damage (not halved). This bug is known and will probably be fixed soon. + // So - no add changes :) CastSpell(pVictim, spellId, true, castItem, triggeredByAura); ((Player*)this)->AddSpellMod(mod, false); @@ -6709,7 +6624,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB break; } // Shadowguard - if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual[0]==7958) + if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958) { switch(triggeredByAura->GetSpellProto()->Id) { @@ -7064,14 +6979,14 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB } // Water Shield (we can't set cooldown for main spell - it's player casted spell - if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual[0]==7358) + if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358) { target = this; break; } // Lightning Shield - if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual[0]==37) + if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37) { // overwrite non existing triggered spell call in spell.dbc switch(triggeredByAura->GetSpellProto()->Id) @@ -7398,7 +7313,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB if (auraSpellInfo->Id==37594) trigger_spell_id = 37595; // Shadowguard - else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual[0]==7958) + else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual==7958) { switch(auraSpellInfo->Id) { @@ -7593,7 +7508,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==0x00000400 && auraSpellInfo->SpellVisual[0]==37) + if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual==37) { switch(auraSpellInfo->Id) { @@ -7805,21 +7720,21 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur { case 836: // Improved Blizzard (Rank 1) { - if (!procSpell || procSpell->SpellVisual[0]!=9487) + if (!procSpell || procSpell->SpellVisual!=9487) return false; triggered_spell_id = 12484; break; } case 988: // Improved Blizzard (Rank 2) { - if (!procSpell || procSpell->SpellVisual[0]!=9487) + if (!procSpell || procSpell->SpellVisual!=9487) return false; triggered_spell_id = 12485; break; } case 989: // Improved Blizzard (Rank 3) { - if (!procSpell || procSpell->SpellVisual[0]!=9487) + if (!procSpell || procSpell->SpellVisual!=9487) return false; triggered_spell_id = 12486; break; @@ -8475,9 +8390,6 @@ void Unit::SetPet(Pet* pet) void Unit::SetCharm(Unit* pet) { SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0); - - if(GetTypeId() == TYPEID_PLAYER) - ((Player*)this)->m_mover = pet ? pet : this; } void Unit::AddPlayerToVision(Player* plr) @@ -8556,7 +8468,6 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool c data.append(GetPackGUID()); data << uint32(SpellID); data << uint32(Damage); - data << uint32(0); // over healing? data << uint8(critical ? 1 : 0); data << uint8(0); // unused in client? SendMessageToSet(&data, true); @@ -8737,7 +8648,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 CastingTime = 0; } // Darkmoon Card: Vengeance - 0.1% - else if (spellProto->SpellVisual[0] == 9850 && spellProto->SpellIconID == 2230) + else if (spellProto->SpellVisual == 9850 && spellProto->SpellIconID == 2230) { CastingTime = 3.5; } @@ -9005,8 +8916,14 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) { if((*i)->GetModifier()->m_miscvalue & schoolMask) { - // stat used stored in miscValueB for this aura - Stats usedStat = Stats((*i)->GetMiscBValue()); + SpellEntry const* iSpellProto = (*i)->GetSpellProto(); + uint8 eff = (*i)->GetEffIndex(); + + // stat used dependent from next effect aura SPELL_AURA_MOD_SPELL_HEALING presence and misc value (stat index) + Stats usedStat = STAT_INTELLECT; + if(eff < 2 && iSpellProto->EffectApplyAuraName[eff+1]==SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT) + usedStat = Stats(iSpellProto->EffectMiscValue[eff+1]); + DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f); } } @@ -9177,7 +9094,7 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) { - if((*i)->GetSpellProto()->SpellVisual[0] == 9180) + if((*i)->GetSpellProto()->SpellVisual == 9180) { // Flash of Light if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1) @@ -10193,37 +10110,38 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) propagateSpeedChange(); + // Send speed change packet only for player + if (GetTypeId()!=TYPEID_PLAYER) + return; + WorldPacket data; if(!forced) { switch(mtype) { case MOVE_WALK: - data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_RUN: - data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_RUN_BACK: - data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_SWIM: - data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_SWIM_BACK: - data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_TURN_RATE: - data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_FLIGHT: - data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4); break; case MOVE_FLIGHT_BACK: - data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_PITCH_RATE: - data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); break; default: sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype); @@ -10231,26 +10149,22 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) } data.append(GetPackGUID()); - data << uint32(0); // movement flags - data << uint16(0); // unk flags + data << uint32(0); //movement flags + data << uint8(0); //unk data << uint32(getMSTime()); data << float(GetPositionX()); data << float(GetPositionY()); data << float(GetPositionZ()); data << float(GetOrientation()); - data << uint32(0); // fall time + data << uint32(0); //flag unk data << float(GetSpeed(mtype)); SendMessageToSet( &data, true ); } else { - if(GetTypeId() == TYPEID_PLAYER) - { - // register forced speed changes for WorldSession::HandleForceSpeedChangeAck - // and do it only for real sent packets and use run for run/mounted as client expected - ++((Player*)this)->m_forced_speed_changes[mtype]; - } - + // register forced speed changes for WorldSession::HandleForceSpeedChangeAck + // and do it only for real sent packets and use run for run/mounted as client expected + ++((Player*)this)->m_forced_speed_changes[mtype]; switch(mtype) { case MOVE_WALK: @@ -10277,9 +10191,6 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) case MOVE_FLIGHT_BACK: data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16); break; - case MOVE_PITCH_RATE: - data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16); - break; default: sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype); return; @@ -10369,10 +10280,6 @@ bool Unit::CanHaveThreatList() const if( ((Creature*)this)->isTotem() ) return false; - // vehicles can not have threat list - if( ((Creature*)this)->isVehicle() ) - return false; - // pets can not have a threat list, unless they are controlled by a creature if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) ) return false; @@ -10621,8 +10528,6 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in int32 mechanic = GetEffectMechanic(spellProto, effect_index); // Find total mod value (negative bonus) int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic); - // Modify from SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL aura (stack always ?) - durationMod_always+=target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel); // Find max mod (negative bonus) int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic); @@ -10824,9 +10729,7 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f case UNIT_MOD_RAGE: case UNIT_MOD_FOCUS: case UNIT_MOD_ENERGY: - case UNIT_MOD_HAPPINESS: - case UNIT_MOD_RUNE: - case UNIT_MOD_RUNIC_POWER: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break; + case UNIT_MOD_HAPPINESS: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break; case UNIT_MOD_RESISTANCE_HOLY: case UNIT_MOD_RESISTANCE_FIRE: @@ -10939,18 +10842,21 @@ Stats Unit::GetStatByAuraGroup(UnitMods unitMod) const Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const { + Powers power = POWER_MANA; + switch(unitMod) { - case UNIT_MOD_MANA: return POWER_MANA; - case UNIT_MOD_RAGE: return POWER_RAGE; - case UNIT_MOD_FOCUS: return POWER_FOCUS; - case UNIT_MOD_ENERGY: return POWER_ENERGY; - case UNIT_MOD_HAPPINESS: return POWER_HAPPINESS; - case UNIT_MOD_RUNE: return POWER_RUNE; - case UNIT_MOD_RUNIC_POWER:return POWER_RUNIC_POWER; + case UNIT_MOD_MANA: power = POWER_MANA; break; + case UNIT_MOD_RAGE: power = POWER_RAGE; break; + case UNIT_MOD_FOCUS: power = POWER_FOCUS; break; + case UNIT_MOD_ENERGY: power = POWER_ENERGY; break; + case UNIT_MOD_HAPPINESS: power = POWER_HAPPINESS; break; + + default: + break; } - return POWER_MANA; + return power; } float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const @@ -11049,12 +10955,6 @@ void Unit::SetPower(Powers power, uint32 val) SetStatInt32Value(UNIT_FIELD_POWER1 + power, val); - WorldPacket data(SMSG_POWER_UPDATE); - data.append(GetPackGUID()); - data << uint8(power); - data << uint32(val); - SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? true : false); - // group update if(GetTypeId() == TYPEID_PLAYER) { @@ -11168,7 +11068,6 @@ uint32 Unit::GetCreatePowers( Powers power ) const case POWER_FOCUS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 100); case POWER_ENERGY: return 100; case POWER_HAPPINESS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 1050000); - case POWER_RUNIC_POWER: return 1000; } return 0; @@ -11256,7 +11155,7 @@ void CharmInfo::InitEmptyActionBar(bool withAttack) for(uint32 x = 0; x < 10; ++x) { - PetActionBar[x].Type = ACT_PASSIVE; + PetActionBar[x].Type = ACT_CAST; PetActionBar[x].SpellOrAction = 0; } if (withAttack) @@ -11272,20 +11171,13 @@ void CharmInfo::InitPossessCreateSpells() InitEmptyActionBar(); if(m_unit->GetTypeId() == TYPEID_UNIT) { - /*for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) + for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { uint32 spellid = ((Creature*)m_unit)->m_spells[i]; if(IsPassiveSpell(spellid)) m_unit->CastSpell(m_unit, spellid, true); else AddSpellToAB(0, spellid, ACT_CAST); - }*/ - for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) - { - if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x])) - m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true); - else - AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_PASSIVE); } } } @@ -11329,7 +11221,7 @@ void CharmInfo::InitCharmCreateSpells() if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable newstate = ACT_DISABLED; else - newstate = ACT_PASSIVE; + newstate = ACT_CAST; AddSpellToAB(0, spellId, newstate); } @@ -11340,7 +11232,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate) { for(uint8 i = 0; i < 10; i++) { - if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid) + if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid) { PetActionBar[i].SpellOrAction = newid; if(!oldid) @@ -11955,11 +11847,8 @@ void Unit::SendPetCastFail(uint32 spellid, uint8 msg) return; WorldPacket data(SMSG_PET_CAST_FAILED, (4+1)); - data << uint8(0); // cast count? data << uint32(spellid); data << uint8(msg); - // uint32 for some reason - // uint32 for some reason ((Player*)owner)->GetSession()->SendPacket(&data); } @@ -12513,10 +12402,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction()); pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); - uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel(); - pet->SetFreeTalentPoints(pet->GetMaxTalentPointsForLevel(level)); - - if(!pet->InitStatsForLevel(level)) + if(!pet->InitStatsForLevel(creatureTarget->getLevel())) { sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry()); delete pet; @@ -12647,8 +12533,10 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura ) mod->value = jumps-5; // negative mod->type = SPELLMOD_FLAT; mod->spellId = spellProto->Id; - mod->mask = spellProto->SpellFamilyFlags; - mod->mask2 = spellProto->SpellFamilyFlags2; + mod->effectId = effIdx; + mod->lastAffected = NULL; + mod->mask = spellProto->SpellFamilyFlags; + mod->charges = 0; caster->AddSpellMod(mod, true); CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); @@ -12836,15 +12724,6 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss) bg->HandleKillUnit((Creature*)pVictim, player); } } - - // achievement stuff - if ( pVictim->GetTypeId() == TYPEID_PLAYER) - { - if(GetTypeId() == TYPEID_UNIT) - ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); - else if(GetTypeId() == TYPEID_PLAYER) - ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1); - } } void Unit::SetControlled(bool apply, UnitState state) @@ -12914,7 +12793,7 @@ void Unit::SetStunned(bool apply) if(apply) { SetUInt64Value(UNIT_FIELD_TARGET, 0); - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); CastStop(); // Creature specific @@ -12932,7 +12811,7 @@ void Unit::SetStunned(bool apply) { if(isAlive() && getVictim()) SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID()); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); if(!hasUnitState(UNIT_STAT_ROOT)) // prevent allow move if have also root effect { @@ -13130,4 +13009,4 @@ void Unit::AddAura(uint32 spellId, Unit* target) } } } -} +} \ No newline at end of file diff --git a/src/game/Unit.h b/src/game/Unit.h index e2d1a25e7a2..c3f5be3adb1 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -149,7 +149,6 @@ enum ShapeshiftForm FORM_BERSERKERSTANCE = 0x13, FORM_TEST = 0x14, FORM_ZOMBIE = 0x15, - FORM_METAMORPHOSIS = 0x16, FORM_FLIGHT_EPIC = 0x1B, FORM_SHADOW = 0x1C, FORM_FLIGHT = 0x1D, @@ -169,14 +168,14 @@ enum SheathState // byte (1 from 0..3) of UNIT_FIELD_BYTES_2 enum UnitBytes2_Flags { - UNIT_BYTE2_FLAG_PVP = 0x01, - UNIT_BYTE2_FLAG_UNK1 = 0x02, - UNIT_BYTE2_FLAG_FFA_PVP = 0x04, - UNIT_BYTE2_FLAG_SANCTUARY = 0x08, - UNIT_BYTE2_FLAG_UNK4 = 0x10, - UNIT_BYTE2_FLAG_UNK5 = 0x20, - UNIT_BYTE2_FLAG_UNK6 = 0x40, - UNIT_BYTE2_FLAG_UNK7 = 0x80 + UNIT_BYTE2_FLAG_UNK0 = 0x01, + UNIT_BYTE2_FLAG_UNK1 = 0x02, + UNIT_BYTE2_FLAG_UNK2 = 0x04, + UNIT_BYTE2_FLAG_UNK3 = 0x08, + UNIT_BYTE2_FLAG_AURAS = 0x10, // show possitive auras as positive, and allow its dispel + UNIT_BYTE2_FLAG_UNK5 = 0x20, + UNIT_BYTE2_FLAG_UNK6 = 0x40, + UNIT_BYTE2_FLAG_UNK7 = 0x80 }; // byte (2 from 0..3) of UNIT_FIELD_BYTES_2 @@ -214,27 +213,16 @@ enum HitInfo HITINFO_UNK1 = 0x00000001, // req correct packet structure HITINFO_NORMALSWING2 = 0x00000002, HITINFO_LEFTSWING = 0x00000004, - HITINFO_UNK2 = 0x00000008, HITINFO_MISS = 0x00000010, - HITINFO_ABSORB = 0x00000020, // absorbed damage - HITINFO_ABSORB2 = 0x00000040, // absorbed damage - HITINFO_RESIST = 0x00000080, // resisted atleast some damage - HITINFO_RESIST2 = 0x00000100, // resisted atleast some damage - HITINFO_CRITICALHIT = 0x00000200, // critical hit - // 0x00000400 - // 0x00000800 - // 0x00001000 - HITINFO_BLOCK = 0x00002000, // blocked damage - // 0x00004000 - // 0x00008000 - HITINFO_GLANCING = 0x00010000, - HITINFO_CRUSHING = 0x00020000, - HITINFO_NOACTION = 0x00040000, // guessed - // 0x00080000 - // 0x00100000 - HITINFO_SWINGNOHITSOUND = 0x00200000, // guessed - // 0x00400000 - HITINFO_UNK3 = 0x00800000 + HITINFO_ABSORB = 0x00000020, // plays absorb sound + HITINFO_RESIST = 0x00000040, // resisted at least some damage + HITINFO_CRITICALHIT = 0x00000080, + HITINFO_UNK2 = 0x00000100, // wotlk? + HITINFO_UNK3 = 0x00002000, // wotlk? + HITINFO_GLANCING = 0x00004000, + HITINFO_CRUSHING = 0x00008000, + HITINFO_NOACTION = 0x00010000, + HITINFO_SWINGNOHITSOUND = 0x00080000 }; //i would like to remove this: (it is defined in item.h @@ -306,13 +294,11 @@ enum UnitMods UNIT_MOD_STAT_INTELLECT, UNIT_MOD_STAT_SPIRIT, UNIT_MOD_HEALTH, - UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum. + UNIT_MOD_MANA, // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existed order, it's accessed by index values of Powers enum. UNIT_MOD_RAGE, UNIT_MOD_FOCUS, UNIT_MOD_ENERGY, UNIT_MOD_HAPPINESS, - UNIT_MOD_RUNE, - UNIT_MOD_RUNIC_POWER, UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum. UNIT_MOD_RESISTANCE_HOLY, UNIT_MOD_RESISTANCE_FIRE, @@ -332,7 +318,7 @@ enum UnitMods UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR, UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1, UNIT_MOD_POWER_START = UNIT_MOD_MANA, - UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1 + UNIT_MOD_POWER_END = UNIT_MOD_HAPPINESS + 1 }; enum BaseModGroup @@ -397,10 +383,9 @@ enum UnitMoveType MOVE_TURN_RATE = 5, MOVE_FLIGHT = 6, MOVE_FLIGHT_BACK = 7, - MOVE_PITCH_RATE = 8 }; -#define MAX_MOVE_TYPE 9 +#define MAX_MOVE_TYPE 8 extern float baseMoveSpeed[MAX_MOVE_TYPE]; @@ -438,11 +423,10 @@ enum CombatRating CR_WEAPON_SKILL_MAINHAND = 20, CR_WEAPON_SKILL_OFFHAND = 21, CR_WEAPON_SKILL_RANGED = 22, - CR_EXPERTISE = 23, - CR_ARMOR_PENETRATION = 24 + CR_EXPERTISE = 23 }; -#define MAX_COMBAT_RATING 25 +#define MAX_COMBAT_RATING 24 enum DamageEffectType { @@ -476,19 +460,19 @@ enum UnitFlags UNIT_FLAG_UNKNOWN9 = 0x00000040, UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100, // 2.0.8 - UNIT_FLAG_UNKNOWN11 = 0x00000200, // 3.0.3 - makes you unable to attack everything + UNIT_FLAG_UNKNOWN11 = 0x00000200, UNIT_FLAG_LOOTING = 0x00000400, // loot animation UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 - UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 + UNIT_FLAG_PVP = 0x00001000, UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 UNIT_FLAG_UNKNOWN4 = 0x00004000, // 2.0.8 UNIT_FLAG_UNKNOWN13 = 0x00008000, UNIT_FLAG_UNKNOWN14 = 0x00010000, - UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok - UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok + UNIT_FLAG_PACIFIED = 0x00020000, + UNIT_FLAG_DISABLE_ROTATE = 0x00040000, // stunned, 2.1.1 UNIT_FLAG_IN_COMBAT = 0x00080000, UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag - UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. + UNIT_FLAG_DISARMED = 0x00200000, // disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. UNIT_FLAG_CONFUSED = 0x00400000, UNIT_FLAG_FLEEING = 0x00800000, UNIT_FLAG_UNKNOWN5 = 0x01000000, // used in spell Eyes of the Beast for pet... @@ -503,10 +487,9 @@ enum UnitFlags // Value masks for UNIT_FIELD_FLAGS_2 enum UnitFlags2 { - UNIT_FLAG2_FEIGN_DEATH = 0x00000001, - UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, - UNIT_FLAG2_FORCE_MOVE = 0x00000040, - UNIT_FLAG2_REGENERATE_POWER = 0x00000800 + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_COMPREHEND_LANG= 0x00000008, + UNIT_FLAG2_FORCE_MOVE = 0x00000040 }; /// Non Player Character flags @@ -652,18 +635,8 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC struct UnitActionBarEntry { - union - { - struct - { - uint16 SpellOrAction; - uint16 Type; - }; - struct - { - uint32 Raw; - }; - }; + uint32 Type; + uint32 SpellOrAction; }; #define MAX_DECLINED_NAME_CASES 5 @@ -685,12 +658,13 @@ enum CurrentSpellTypes enum ActiveStates { - ACT_PASSIVE = 0x0100, // 0x0100 - passive - ACT_DISABLED = 0x8100, // 0x8000 - castable - ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable - ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400 - ACT_REACTION = 0x0600, // 0x0200 | 0x0400 - ACT_DECIDE = 0x0001 // what is it? + ACT_ENABLED = 0xC100, + ACT_DISABLED = 0x8100, + ACT_COMMAND = 0x0700, + ACT_REACTION = 0x0600, + ACT_CAST = 0x0100, + ACT_PASSIVE = 0x0000, + ACT_DECIDE = 0x0001 }; enum ReactStates @@ -780,7 +754,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject typedef std::list Diminishing; typedef std::set AuraTypeSet; typedef std::set ComboPointHolderSet; - typedef std::map VisibleAuraMap; virtual ~Unit ( ); @@ -911,14 +884,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject return false; } - bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); } - void SetPvP(bool state) - { - if(state) - SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - else - RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - } + bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); } + void SetPvP(bool state) { if(state) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); } uint32 GetCreatureType() const; uint32 GetCreatureTypeMask() const { @@ -1288,30 +1255,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ } HostilRefManager& getHostilRefManager() { return m_HostilRefManager; } - uint32 GetVisibleAura(uint8 slot) - { - VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); - if(itr != m_visibleAuras.end()) - return itr->second; - return 0; - } - void SetVisibleAura(uint8 slot, uint32 spellid) - { - if(spellid == 0) - { - VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); - if(itr != m_visibleAuras.end()) - { - m_visibleAuras.erase(itr); - return; - } - } - else - m_visibleAuras[slot] = spellid; - } - VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; } - uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); } - Aura* GetAura(uint32 spellId, uint32 effindex); AuraMap & GetAuras() { return m_Auras; } AuraMap const& GetAuras() const { return m_Auras; } @@ -1503,7 +1446,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject float m_weaponDamage[MAX_ATTACK][2]; bool m_canModifyStats; //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem - VisibleAuraMap m_visibleAuras; float m_speed_rate[MAX_MOVE_TYPE]; @@ -1517,7 +1459,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject uint32 m_unit_movement_flags; uint32 m_reactiveTimer[MAX_REACTIVE]; - uint32 m_regenTimer; private: void SendAttackStop(Unit* victim); // only from AttackStop(Unit*) diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp index ce50a326917..2b6282997e8 100644 --- a/src/game/UpdateData.cpp +++ b/src/game/UpdateData.cpp @@ -108,7 +108,7 @@ bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport) ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8); buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount); - //buf << (uint8) (hasTransport ? 1 : 0); + buf << (uint8) (hasTransport ? 1 : 0); if(!m_outOfRangeGUIDs.empty()) { diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h index 48c7fc35efc..8fdcac4b400 100644 --- a/src/game/UpdateData.h +++ b/src/game/UpdateData.h @@ -38,12 +38,11 @@ enum OBJECT_UPDATE_FLAGS UPDATEFLAG_NONE = 0x00, UPDATEFLAG_SELF = 0x01, UPDATEFLAG_TRANSPORT = 0x02, - UPDATEFLAG_HAS_TARGET = 0x04, + UPDATEFLAG_FULLGUID = 0x04, UPDATEFLAG_LOWGUID = 0x08, UPDATEFLAG_HIGHGUID = 0x10, UPDATEFLAG_LIVING = 0x20, - UPDATEFLAG_HAS_POSITION = 0x40, - UPDATEFLAG_VEHICLE = 0x80 + UPDATEFLAG_HASPOSITION = 0x40 }; class UpdateData diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h index 3810cb83429..db64e0bc1dd 100644 --- a/src/game/UpdateFields.h +++ b/src/game/UpdateFields.h @@ -21,7 +21,7 @@ #ifndef _UPDATEFIELDS_AUTO_H #define _UPDATEFIELDS_AUTO_H -// Auto generated for version 3, 0, 3, 9183 +// Auto generated for version 2, 4, 3, 8606 enum EObjectFields { @@ -43,37 +43,13 @@ enum EItemFields ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER_ONLY, UNK2 ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER_ONLY - ITEM_FIELD_DURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 - ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 - ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE - ITEM_END = OBJECT_END + 0x003A, + ITEM_FIELD_ENCHANTMENT = OBJECT_END + 0x0010, // Size: 33, Type: INT, Flags: PUBLIC + ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_ITEM_TEXT_ID = OBJECT_END + 0x0033, // Size: 1, Type: INT, Flags: OWNER_ONLY + ITEM_FIELD_DURABILITY = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 + ITEM_END = OBJECT_END + 0x0036, }; enum EContainerFields @@ -88,94 +64,93 @@ enum EUnitFields { UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE - UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CREATEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_TARGET = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_PERSUADED = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_HEALTH = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER1 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER2 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER3 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER4 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER5 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER6 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER7 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0028, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_LEVEL = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC - UNIT_FIELD_FLAGS = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_AURASTATE = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC - UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE - UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 - UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 - UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 - UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 - UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER_ONLY - UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER_ONLY - UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC - UNIT_CHANNEL_SPELL = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC - UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3 - UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY - UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE - UNIT_END = OBJECT_END + 0x008E, + UNIT_FIELD_HEALTH = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_FIELD_POWER1 = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER2 = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER3 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER4 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER5 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_LEVEL = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BYTES_0 = OBJECT_END + 0x001E, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_SLOT_DISPLAY = OBJECT_END + 0x001F, // Size: 3, Type: INT, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_INFO = OBJECT_END + 0x0022, // Size: 6, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_FLAGS = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_AURA = OBJECT_END + 0x002A, // Size: 56, Type: INT, Flags: PUBLIC + UNIT_FIELD_AURAFLAGS = OBJECT_END + 0x0062, // Size: 14, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_AURALEVELS = OBJECT_END + 0x0070, // Size: 14, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_AURAAPPLICATIONS = OBJECT_END + 0x007E, // Size: 14, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_AURASTATE = OBJECT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x008D, // Size: 2, Type: INT, Flags: PUBLIC + UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x008F, // Size: 1, Type: INT, Flags: PRIVATE + UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0090, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0091, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0095, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0096, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0097, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0098, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0099, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_PETNUMBER = OBJECT_END + 0x009A, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x009C, // Size: 1, Type: INT, Flags: OWNER_ONLY + UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x009D, // Size: 1, Type: INT, Flags: OWNER_ONLY + UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x009E, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_CHANNEL_SPELL = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_MOD_CAST_SPEED = OBJECT_END + 0x00A0, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_CREATED_BY_SPELL = OBJECT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_NPC_FLAGS = OBJECT_END + 0x00A2, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_NPC_EMOTESTATE = OBJECT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_TRAINING_POINTS = OBJECT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: OWNER_ONLY + UNIT_FIELD_STAT0 = OBJECT_END + 0x00A5, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT1 = OBJECT_END + 0x00A6, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT2 = OBJECT_END + 0x00A7, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT3 = OBJECT_END + 0x00A8, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_STAT4 = OBJECT_END + 0x00A9, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x00AA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x00AB, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x00AC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x00AD, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x00AE, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x00AF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x00B0, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x00B1, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x00B2, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x00B3, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RESISTANCES = OBJECT_END + 0x00B4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3 + UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x00BB, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x00C2, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_BASE_MANA = OBJECT_END + 0x00C9, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x00CA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_BYTES_2 = OBJECT_END + 0x00CB, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x00CC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x00CD, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00CE, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x00CF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x00D0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00D1, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x00D2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x00D3, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x00D4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x00DB, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x00E2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY + UNIT_FIELD_PADDING = OBJECT_END + 0x00E3, // Size: 1, Type: INT, Flags: NONE + UNIT_END = OBJECT_END + 0x00E4, PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC @@ -287,184 +262,160 @@ enum EUnitFields PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE PLAYER_QUEST_LOG_25_4 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE PLAYER_VISIBLE_ITEM_1_CREATOR = UNIT_END + 0x006E, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_SEED = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x0080, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0082, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_SEED = UNIT_END + 0x0090, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x0092, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0094, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x00A1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_SEED = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x00A4, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A6, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00B3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_SEED = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00B6, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B8, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00C5, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_SEED = UNIT_END + 0x00C6, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00C7, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00C8, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00CA, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00D7, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_SEED = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00DA, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00DC, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00E9, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_SEED = UNIT_END + 0x00EA, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00EC, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00EE, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00FB, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_SEED = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x0100, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x010D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_SEED = UNIT_END + 0x010E, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x0110, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0112, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x011F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_SEED = UNIT_END + 0x0120, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x0122, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0124, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x0131, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_SEED = UNIT_END + 0x0132, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x0133, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x0134, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0136, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x0143, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_SEED = UNIT_END + 0x0144, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x0145, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x0146, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0148, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x0155, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_SEED = UNIT_END + 0x0156, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x0157, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x0158, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x015A, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x0167, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_SEED = UNIT_END + 0x0168, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x0169, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x016A, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x016C, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x0179, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_SEED = UNIT_END + 0x017A, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x017B, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x017C, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x017E, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x018B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_SEED = UNIT_END + 0x018C, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0190, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x019D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_SEED = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x01A0, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x01A2, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x01AF, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_SEED = UNIT_END + 0x01B0, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x01B1, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x01B2, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x01B4, // Size: 13, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x01C1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_SEED = UNIT_END + 0x01C2, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x01C3, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_CHOSEN_TITLE = UNIT_END + 0x01C4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FIELD_PAD_0 = UNIT_END + 0x01C5, // Size: 1, Type: INT, Flags: NONE - PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01C6, // Size: 46, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01F4, // Size: 32, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x0214, // Size: 56, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x024C, // Size: 14, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x025A, // Size: 24, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x0272, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x02B2, // Size: 36, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x02D6, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_QUESTBAG_SLOT_1 = UNIT_END + 0x0316, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FARSIGHT = UNIT_END + 0x0356, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x0358, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x035A, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x035C, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_XP = UNIT_END + 0x035E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x035F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x0360, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x04E0, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_CREATURES = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_RESOURCES = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x04E4, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x04E5, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x04E6, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPERTISE = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x04E8, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x04E9, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x04EA, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x04EB, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x04EC, // Size: 7, Type: FLOAT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK = UNIT_END + 0x04F3, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x04F4, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x04F5, // Size: 128, Type: BYTES, Flags: PRIVATE - PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0575, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COINAGE = UNIT_END + 0x0576, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x0577, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x057E, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x0585, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x058C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x058D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x058E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES = UNIT_END + 0x058F, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_AMMO_ID = UNIT_END + 0x0590, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SELF_RES_SPELL = UNIT_END + 0x0591, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0592, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0593, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x059F, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_KILLS = UNIT_END + 0x05AB, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x05AC, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x05AD, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x05AE, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES2 = UNIT_END + 0x05AF, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x05B0, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x05B1, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x05CA, // Size: 18, Type: INT, Flags: PRIVATE - PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x05DC, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x05DD, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x05DE, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x05DF, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_RUNE_REGEN_1 = UNIT_END + 0x05F8, // Size: 4, Type: FLOAT, Flags: PRIVATE - PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x05FC, // Size: 3, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x05FF, // Size: 8, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0607, // Size: 8, Type: INT, Flags: PRIVATE - PLAYER_GLYPHS_ENABLED = UNIT_END + 0x060F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_END = UNIT_END + 0x0610, + PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0070, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x007C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x007E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0080, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x008E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0090, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x009E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x00A0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x00AE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x00B0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00BC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00BD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00BE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00C0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00CC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00CE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00D0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00DC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00DE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00E0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00EC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00EE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x00F0, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x00FC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x0100, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x010E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x0110, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x011E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0120, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x012C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x012E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0130, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x013C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x013D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x013E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x0140, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x014C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x014D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x014E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x0150, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x015C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x015D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x015E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x0160, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x016C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x016D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x016E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0170, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x017C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x017D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x017E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x0180, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x018C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x0190, // Size: 12, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x019C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x019D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_CHOSEN_TITLE = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_FIELD_PAD_0 = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: NONE + PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x01A0, // Size: 46, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01CE, // Size: 32, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x01EE, // Size: 56, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0226, // Size: 14, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0234, // Size: 24, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x024C, // Size: 64, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_VANITYPET_SLOT_1 = UNIT_END + 0x028C, // Size: 36, Type: LONG, Flags: PRIVATE + PLAYER_FARSIGHT = UNIT_END + 0x02B0, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x02B2, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER_XP = UNIT_END + 0x02B4, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x02B5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x02B6, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_CREATURES = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_RESOURCES = UNIT_END + 0x0439, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x043A, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x043B, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x043C, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_EXPERTISE = UNIT_END + 0x043D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x043E, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x043F, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0440, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0441, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0442, // Size: 7, Type: FLOAT, Flags: PRIVATE + PLAYER_SHIELD_BLOCK = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x044A, // Size: 128, Type: BYTES, Flags: PRIVATE + PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x04CA, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COINAGE = UNIT_END + 0x04CB, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x04CC, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x04D3, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x04DA, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x04E4, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_AMMO_ID = UNIT_END + 0x04E5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SELF_RES_SPELL = UNIT_END + 0x04E6, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x04E8, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x04F4, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x0500, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0501, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0502, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0503, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0x0504, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0505, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0506, // Size: 24, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x051E, // Size: 18, Type: INT, Flags: PRIVATE + PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0530, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x0531, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x0532, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x0533, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0534, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0535, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_END = UNIT_END + 0x054E, }; enum EGameObjectFields { OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC - GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC - GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0006, // Size: 4, Type: FLOAT, Flags: PUBLIC - GAMEOBJECT_POS_X = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC - GAMEOBJECT_POS_Y = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC - GAMEOBJECT_POS_Z = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC - GAMEOBJECT_FACING = OBJECT_END + 0x000D, // Size: 1, Type: FLOAT, Flags: PUBLIC - GAMEOBJECT_DYNAMIC = OBJECT_END + 0x000E, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC - GAMEOBJECT_FACTION = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_ROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_STATE = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_POS_X = OBJECT_END + 0x0009, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_POS_Y = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_POS_Z = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_FACING = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_DYN_FLAGS = OBJECT_END + 0x000D, // Size: 1, Type: INT, Flags: DYNAMIC + GAMEOBJECT_FACTION = OBJECT_END + 0x000E, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_TYPE_ID = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC GAMEOBJECT_LEVEL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC - GAMEOBJECT_BYTES_1 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC - GAMEOBJECT_END = OBJECT_END + 0x0012, + GAMEOBJECT_ARTKIT = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_ANIMPROGRESS = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: DYNAMIC + GAMEOBJECT_PADDING = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: NONE + GAMEOBJECT_END = OBJECT_END + 0x0014, }; enum EDynamicObjectFields diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp deleted file mode 100644 index 4e1153a166b..00000000000 --- a/src/game/Vehicle.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "Common.h" -#include "Log.h" -#include "WorldSession.h" -#include "WorldPacket.h" -#include "ObjectMgr.h" -#include "SpellMgr.h" -#include "Vehicle.h" -#include "MapManager.h" -#include "SpellAuras.h" -#include "Unit.h" -#include "Util.h" - -Vehicle::Vehicle() : Creature(), m_vehicleId(0) -{ - m_isVehicle = true; - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE); -} - -Vehicle::~Vehicle() -{ - if(m_uint32Values) // only for fully created Object - ObjectAccessor::Instance().RemoveObject(this); -} - -void Vehicle::AddToWorld() -{ - ///- Register the vehicle for guid lookup - if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); - Unit::AddToWorld(); -} - -void Vehicle::RemoveFromWorld() -{ - ///- Remove the vehicle from the accessor - if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); - ///- Don't call the function for Creature, normal mobs + totems go in a different storage - Unit::RemoveFromWorld(); -} - -void Vehicle::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState -{ - Creature::setDeathState(s); -} - -void Vehicle::Update(uint32 diff) -{ - Creature::Update(diff); -} - -bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team) -{ - SetMapId(map->GetId()); - SetInstanceId(map->GetInstanceId()); - - Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE); - - if(!InitEntry(Entry, team)) - return false; - - m_defaultMovementType = IDLE_MOTION_TYPE; - - AIM_Initialize(); - - SetVehicleId(vehicleId); - - SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); - - CreatureInfo const *ci = GetCreatureInfo(); - setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H); - SetMaxHealth(ci->maxhealth); - SelectLevel(ci); - SetHealth(GetMaxHealth()); - - return true; -} - -void Vehicle::Dismiss() -{ - SendObjectDeSpawnAnim(GetGUID()); - CombatStop(); - CleanupsBeforeDelete(); - AddObjectToRemoveList(); -} diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h deleted file mode 100644 index 7fd8b60c40a..00000000000 --- a/src/game/Vehicle.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MANGOSSERVER_VEHICLE_H -#define MANGOSSERVER_VEHICLE_H - -#include "ObjectDefines.h" -#include "Creature.h" -#include "Unit.h" - -class Vehicle : public Creature -{ - public: - explicit Vehicle(); - virtual ~Vehicle(); - - void AddToWorld(); - void RemoveFromWorld(); - - bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team); - - void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState - void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update - - uint32 GetVehicleId() { return m_vehicleId; } - void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; } - - void Dismiss(); - - protected: - uint32 m_vehicleId; - - private: - void SaveToDB(uint32, uint8) // overwrited of Creature::SaveToDB - don't must be called - { - assert(false); - } - void DeleteFromDB() // overwrited of Creature::DeleteFromDB - don't must be called - { - assert(false); - } -}; -#endif diff --git a/src/game/World.cpp b/src/game/World.cpp index a6821c0eaeb..5b36e3d4d9c 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -232,7 +232,7 @@ World::AddSession_ (WorldSession* s) uint32 Sessions = GetActiveAndQueuedSessionCount (); uint32 pLimit = GetPlayerAmountLimit (); - uint32 QueueSize = GetQueueSize (); //number of players in the queue + uint32 QueueSize = GetQueueSize (); //number of players in the queue //so we don't count the user trying to //login as a session and queue the socket that we are using @@ -249,10 +249,10 @@ World::AddSession_ (WorldSession* s) WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); packet << uint8 (AUTH_OK); - packet << uint32 (0); // BillingTimeRemaining - packet << uint8 (0); // BillingPlanFlags - packet << uint32 (0); // BillingTimeRested - packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account + packet << uint32 (0); // unknown random value... + packet << uint8 (0); + packet << uint32 (0); + packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account s->SendPacket (&packet); UpdateMaxSessionCounters (); @@ -260,7 +260,7 @@ World::AddSession_ (WorldSession* s) // Updates the population if (pLimit > 0) { - float popu = GetActiveSessionCount (); //updated number of users on the server + float popu = GetActiveSessionCount (); //updated number of users on the server popu /= pLimit; popu *= 2; loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID); @@ -287,10 +287,10 @@ void World::AddQueuedPlayer(WorldSession* sess) // The 1st SMSG_AUTH_RESPONSE needs to contain other info too. WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); packet << uint8 (AUTH_WAIT_QUEUE); - packet << uint32 (0); // BillingTimeRemaining - packet << uint8 (0); // BillingPlanFlags - packet << uint32 (0); // BillingTimeRested - packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account + packet << uint32 (0); // unknown random value... + packet << uint8 (0); + packet << uint32 (0); + packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account packet << uint32(GetQueuePos (sess)); sess->SendPacket (&packet); @@ -408,30 +408,24 @@ void World::LoadConfigSettings(bool reload) rate_values[RATE_HEALTH] = sConfig.GetFloatDefault("Rate.Health", 1); if(rate_values[RATE_HEALTH] < 0) { - sLog.outError("Rate.Health (%f) must be > 0. Using 1 instead.",rate_values[RATE_HEALTH]); + sLog.outError("Rate.Health (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_HEALTH]); rate_values[RATE_HEALTH] = 1; } rate_values[RATE_POWER_MANA] = sConfig.GetFloatDefault("Rate.Mana", 1); if(rate_values[RATE_POWER_MANA] < 0) { - sLog.outError("Rate.Mana (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]); + sLog.outError("Rate.Mana (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]); rate_values[RATE_POWER_MANA] = 1; } rate_values[RATE_POWER_RAGE_INCOME] = sConfig.GetFloatDefault("Rate.Rage.Income", 1); rate_values[RATE_POWER_RAGE_LOSS] = sConfig.GetFloatDefault("Rate.Rage.Loss", 1); if(rate_values[RATE_POWER_RAGE_LOSS] < 0) { - sLog.outError("Rate.Rage.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]); + sLog.outError("Rate.Rage.Loss (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]); rate_values[RATE_POWER_RAGE_LOSS] = 1; } - rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfig.GetFloatDefault("Rate.RunicPower.Income", 1); - rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfig.GetFloatDefault("Rate.RunicPower.Loss", 1); - if(rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0) - { - sLog.outError("Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RUNICPOWER_LOSS]); - rate_values[RATE_POWER_RUNICPOWER_LOSS] = 1; - } rate_values[RATE_POWER_FOCUS] = sConfig.GetFloatDefault("Rate.Focus", 1.0f); + rate_values[RATE_LOYALTY] = sConfig.GetFloatDefault("Rate.Loyalty", 1.0f); rate_values[RATE_SKILL_DISCOVERY] = sConfig.GetFloatDefault("Rate.Skill.Discovery", 1.0f); rate_values[RATE_DROP_ITEM_POOR] = sConfig.GetFloatDefault("Rate.Drop.Item.Poor", 1.0f); rate_values[RATE_DROP_ITEM_NORMAL] = sConfig.GetFloatDefault("Rate.Drop.Item.Normal", 1.0f); @@ -623,15 +617,6 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_configs[CONFIG_CHARACTERS_PER_REALM]; } - m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("HeroicCharactersPerRealm", 1); - if(m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] < 0 || m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10) - { - sLog.outError("HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.",m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]); - m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1; - } - - m_configs[CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING] = sConfig.GetIntDefault("MinLevelForHeroicCharacterCreating", 55); - m_configs[CONFIG_SKIP_CINEMATICS] = sConfig.GetIntDefault("SkipCinematics", 0); if(m_configs[CONFIG_SKIP_CINEMATICS] < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2) { @@ -666,20 +651,6 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL]; } - m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = sConfig.GetIntDefault("StartHeroicPlayerLevel", 55); - if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] < 1) - { - sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 55.", - m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); - m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = 55; - } - else if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] > m_configs[CONFIG_MAX_PLAYER_LEVEL]) - { - sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.", - m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); - m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL]; - } - m_configs[CONFIG_START_PLAYER_MONEY] = sConfig.GetIntDefault("StartPlayerMoney", 0); if(m_configs[CONFIG_START_PLAYER_MONEY] < 0) { @@ -752,17 +723,17 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9); if(m_configs[CONFIG_MIN_PETITION_SIGNS] > 9) { - sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_configs[CONFIG_MIN_PETITION_SIGNS]); + sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.",m_configs[CONFIG_MIN_PETITION_SIGNS]); m_configs[CONFIG_MIN_PETITION_SIGNS] = 9; } - m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState", 2); - m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets", 2); - m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat", 2); - m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo", 2); + m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState",2); + m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets",2); + m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat",2); + m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo",2); - m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList", false); - m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList", false); + m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList",false); + m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false); m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false); m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1); @@ -803,7 +774,6 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS] = sConfig.GetIntDefault("SkillChance.SkinningSteps",75); m_configs[CONFIG_SKILL_PROSPECTING] = sConfig.GetBoolDefault("SkillChance.Prospecting",false); - m_configs[CONFIG_SKILL_MILLING] = sConfig.GetBoolDefault("SkillChance.Milling",false); m_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfig.GetIntDefault("SkillGain.Crafting", 1); if(m_configs[CONFIG_SKILL_GAIN_CRAFTING] < 0) @@ -1089,18 +1059,12 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading InstanceTemplate" ); objmgr.LoadInstanceTemplate(); - sLog.outString( "Loading AchievementCriteriaList..." ); - objmgr.LoadAchievementCriteriaList(); - - sLog.outString( "Loading completed achievements..." ); - objmgr.LoadCompletedAchievements(); - sLog.outString( "Loading SkillLineAbilityMultiMap Data..." ); spellmgr.LoadSkillLineAbilityMap(); ///- Clean up and pack instances sLog.outString( "Cleaning up instances..." ); - sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables + sInstanceSaveManager.CleanupInstances(); // must be called before `creature_respawn`/`gameobject_respawn` tables sLog.outString( "Packing instances..." ); sInstanceSaveManager.PackInstances(); @@ -1226,9 +1190,6 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading spell pet auras..." ); spellmgr.LoadSpellPetAuras(); - sLog.outString( "Loading pet levelup spells..." ); - spellmgr.LoadPetLevelupSpellMap(); - sLog.outString( "Loading spell extra attributes...(TODO)" ); spellmgr.LoadSpellCustomAttr(); @@ -1708,9 +1669,6 @@ void World::ScriptsProcess() case HIGHGUID_PET: source = HashMapHolder::Find(step.sourceGUID); break; - case HIGHGUID_VEHICLE: - source = HashMapHolder::Find(step.sourceGUID); - break; case HIGHGUID_PLAYER: source = HashMapHolder::Find(step.sourceGUID); break; @@ -1740,9 +1698,6 @@ void World::ScriptsProcess() case HIGHGUID_PET: target = HashMapHolder::Find(step.targetGUID); break; - case HIGHGUID_VEHICLE: - target = HashMapHolder::Find(step.targetGUID); - break; case HIGHGUID_PLAYER: // empty GUID case also target = HashMapHolder::Find(step.targetGUID); break; diff --git a/src/game/World.h b/src/game/World.h index 26118c0c347..edf5e22850b 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -102,12 +102,9 @@ enum WorldConfigs CONFIG_CHARACTERS_CREATING_DISABLED, CONFIG_CHARACTERS_PER_ACCOUNT, CONFIG_CHARACTERS_PER_REALM, - CONFIG_HEROIC_CHARACTERS_PER_REALM, - CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING, CONFIG_SKIP_CINEMATICS, CONFIG_MAX_PLAYER_LEVEL, CONFIG_START_PLAYER_LEVEL, - CONFIG_START_HEROIC_PLAYER_LEVEL, CONFIG_START_PLAYER_MONEY, CONFIG_MAX_HONOR_POINTS, CONFIG_START_HONOR_POINTS, @@ -186,7 +183,6 @@ enum WorldConfigs CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS, CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS, CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER, - CONFIG_SKILL_MILLING, CONFIG_MAX_WHO, CONFIG_BG_START_MUSIC, @@ -211,8 +207,6 @@ enum Rates RATE_POWER_MANA, RATE_POWER_RAGE_INCOME, RATE_POWER_RAGE_LOSS, - RATE_POWER_RUNICPOWER_INCOME, - RATE_POWER_RUNICPOWER_LOSS, RATE_POWER_FOCUS, RATE_SKILL_DISCOVERY, RATE_DROP_ITEM_POOR, @@ -256,6 +250,7 @@ enum Rates RATE_MINING_AMOUNT, RATE_MINING_NEXT, RATE_TALENT, + RATE_LOYALTY, RATE_CORPSE_DECAY_LOOTED, RATE_INSTANCE_RESET_TIME, RATE_TARGET_POS_RECALCULATION_RANGE, diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index d49fe1cda83..47e1334198e 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -525,90 +525,3 @@ void WorldSession::SendAuthWaitQue(uint32 position) SendPacket(&packet); } } - -void WorldSession::LoadAccountData() -{ - for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) - { - AccountData data; - m_accountData[i] = data; - } - - QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId()); - - if(!result) - return; - - do - { - Field *fields = result->Fetch(); - - uint32 type = fields[0].GetUInt32(); - if(type < NUM_ACCOUNT_DATA_TYPES) - { - m_accountData[type].Time = fields[1].GetUInt32(); - m_accountData[type].Data = fields[2].GetCppString(); - } - } while (result->NextRow()); - - delete result; -} - -void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data) -{ - m_accountData[type].Time = time_; - m_accountData[type].Data = data; - - uint32 acc = GetAccountId(); - CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type); - CharacterDatabase.escape_string(data); - CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str()); -} - -void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) -{ - CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4); - data >> mi->flags; - data >> mi->unk1; - data >> mi->time; - data >> mi->x; - data >> mi->y; - data >> mi->z; - data >> mi->o; - - if(mi->flags & MOVEMENTFLAG_ONTRANSPORT) - { - CHECK_PACKET_SIZE(data, data.rpos()+8+4+4+4+4+4+1); - data >> mi->t_guid; - data >> mi->t_x; - data >> mi->t_y; - data >> mi->t_z; - data >> mi->t_o; - data >> mi->t_time; - data >> mi->t_seat; - } - - if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20)) - { - CHECK_PACKET_SIZE(data, data.rpos()+4); - data >> mi->s_pitch; - } - - CHECK_PACKET_SIZE(data, data.rpos()+4); - data >> mi->fallTime; - - if(mi->flags & MOVEMENTFLAG_JUMPING) - { - CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4); - data >> mi->j_unk; - data >> mi->j_sinAngle; - data >> mi->j_cosAngle; - data >> mi->j_xyspeed; - } - - if(mi->flags & MOVEMENTFLAG_SPLINE) - { - CHECK_PACKET_SIZE(data, data.rpos()+4); - data >> mi->u_unk1; - } -} diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 385d37046e2..0ccb8dd9fbb 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -47,16 +47,6 @@ class CharacterHandler; #define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S)); -#define NUM_ACCOUNT_DATA_TYPES 8 - -struct AccountData -{ - AccountData() : Time(NULL), Data("") {} - - time_t Time; - std::string Data; -}; - enum PartyOperation { PARTY_OP_INVITE = 0, @@ -91,8 +81,6 @@ class TRINITY_DLL_SPEC WorldSession void SizeError(WorldPacket const& packet, uint32 size) const; - void ReadMovementInfo(WorldPacket &data, MovementInfo *mi); - void SendPacket(WorldPacket const* packet); void SendNotification(const char *format,...) ATTR_PRINTF(2,3); void SendNotification(int32 string_id,...); @@ -165,11 +153,6 @@ class TRINITY_DLL_SPEC WorldSession //pet void SendPetNameQuery(uint64 guid, uint32 petnumber); - // Account Data - AccountData *GetAccountData(uint32 type) { return &m_accountData[type]; } - void SetAccountData(uint32 type, time_t time_, std::string data); - void LoadAccountData(); - //mail //used with item_page table bool SendItemInfo( uint32 itemid, WorldPacket data ); @@ -341,8 +324,7 @@ class TRINITY_DLL_SPEC WorldSession void HandleMovementOpcodes(WorldPacket& recvPacket); void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags); void HandleSetActiveMoverOpcode(WorldPacket &recv_data); - void HandleMoveNotActiveMover(WorldPacket &recv_data); - void HandleDismissControlledVehicle(WorldPacket &recv_data); + void HandleNotActiveMoverOpcode(WorldPacket &recv_data); void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data); void HandleRequestRaidInfoOpcode( WorldPacket & recv_data ); @@ -403,7 +385,7 @@ class TRINITY_DLL_SPEC WorldSession void HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket); void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket); - void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket); + void HandleTaxiQueryAvailableNodesOpcode(WorldPacket& recvPacket); void HandleActivateTaxiOpcode(WorldPacket& recvPacket); void HandleActivateTaxiFarOpcode(WorldPacket& recvPacket); void HandleTaxiNextDestinationOpcode(WorldPacket& recvPacket); @@ -447,7 +429,6 @@ class TRINITY_DLL_SPEC WorldSession void HandleAuctionRemoveItem( WorldPacket & recv_data ); void HandleAuctionListOwnerItems( WorldPacket & recv_data ); void HandleAuctionPlaceBid( WorldPacket & recv_data ); - void HandleAuctionListPendingSales( WorldPacket & recv_data ); void HandleGetMail( WorldPacket & recv_data ); void HandleSendMail( WorldPacket & recv_data ); @@ -562,7 +543,6 @@ class TRINITY_DLL_SPEC WorldSession void HandlePetUnlearnOpcode( WorldPacket& recvPacket ); void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ); void HandlePetCastSpellOpcode( WorldPacket& recvPacket ); - void HandlePetLearnTalent( WorldPacket& recvPacket ); void HandleSetActionBar(WorldPacket& recv_data); @@ -599,9 +579,10 @@ class TRINITY_DLL_SPEC WorldSession void HandleLfmSetNoneOpcode(WorldPacket& recv_data); void HandleLfmSetOpcode(WorldPacket& recv_data); void HandleLfgSetCommentOpcode(WorldPacket& recv_data); + void HandleNewUnknownOpcode(WorldPacket& recv_data); void HandleChooseTitleOpcode(WorldPacket& recv_data); void HandleRealmStateRequestOpcode(WorldPacket& recv_data); - void HandleTimeSyncResp(WorldPacket& recv_data); + void HandleAllowMoveAckOpcode(WorldPacket& recv_data); void HandleWhoisOpcode(WorldPacket& recv_data); void HandleResetInstancesOpcode(WorldPacket& recv_data); @@ -647,29 +628,6 @@ class TRINITY_DLL_SPEC WorldSession void HandleGuildBankBuyTab(WorldPacket& recv_data); void HandleGuildBankTabText(WorldPacket& recv_data); void HandleGuildBankSetTabText(WorldPacket& recv_data); - - // Calendar - void HandleCalendarGetCalendar(WorldPacket& recv_data); - void HandleCalendarGetEvent(WorldPacket& recv_data); - void HandleCalendarGuildFilter(WorldPacket& recv_data); - void HandleCalendarArenaTeam(WorldPacket& recv_data); - void HandleCalendarAddEvent(WorldPacket& recv_data); - void HandleCalendarUpdateEvent(WorldPacket& recv_data); - void HandleCalendarRemoveEvent(WorldPacket& recv_data); - void HandleCalendarCopyEvent(WorldPacket& recv_data); - void HandleCalendarEventInvite(WorldPacket& recv_data); - void HandleCalendarEventRsvp(WorldPacket& recv_data); - void HandleCalendarEventRemoveInvite(WorldPacket& recv_data); - void HandleCalendarEventStatus(WorldPacket& recv_data); - void HandleCalendarEventModeratorStatus(WorldPacket& recv_data); - void HandleCalendarComplain(WorldPacket& recv_data); - void HandleCalendarGetNumPending(WorldPacket& recv_data); - - void HandleSpellClick(WorldPacket& recv_data); - void HandleAlterAppearance(WorldPacket& recv_data); - void HandleRemoveGlyph(WorldPacket& recv_data); - void HandleCharCustomize(WorldPacket& recv_data); - void HandleInspectAchievements(WorldPacket& recv_data); private: // private trade methods void moveItems(Item* myItems[], Item* hisItems[]); @@ -692,7 +650,6 @@ class TRINITY_DLL_SPEC WorldSession LocaleConstant m_sessionDbcLocale; int m_sessionDbLocaleIndex; uint32 m_latency; - AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; ZThread::LockedQueue _recvQueue; }; diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index 2ae97819116..01d5a0e5490 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -54,48 +54,8 @@ struct ServerPktHeader { - /** - * size is the length of the payload _plus_ the length of the opcode - */ - ServerPktHeader(uint32 size, uint16 cmd) : size(size) - { - uint8 headerIndex=0; - if(isLargePacket()) - { - sLog.outDebug("initializing large server to client packet. Size: %u, cmd: %u", size, cmd); - header= new uint8[5]; - header[headerIndex++] = 0x80|(0xFF &(size>>16)); - } - else - { - header= new uint8[4]; - } - - header[headerIndex++] = 0xFF &(size>>8); - header[headerIndex++] = 0xFF &size; - - header[headerIndex++] = 0xFF & cmd; - header[headerIndex++] = 0xFF & (cmd>>8); - } - - ~ServerPktHeader() - { - delete[] header; - } - - uint8 getHeaderLength() - { - // cmd = 2 bytes, size= 2||3bytes - return 2+(isLargePacket()?3:2); - } - - bool isLargePacket() - { - return size > 0x7FFF; - } - - const uint32 size; - uint8 *header; + uint16 size; + uint16 cmd; }; struct ClientPktHeader @@ -679,7 +639,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed; - uint32 unk2, unk3; + uint32 unk2; uint32 BuiltNumberClient; uint32 id, security; //uint8 expansion = 0; @@ -701,7 +661,6 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) recvPacket >> BuiltNumberClient; // for now no use recvPacket >> unk2; recvPacket >> account; - recvPacket >> unk3; if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20)) { @@ -921,8 +880,6 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) m_Crypt.SetKey (&K); m_Crypt.Init (); - m_Session->LoadAccountData(); - // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec ACE_OS::sleep (ACE_Time_Value (0, 10000)); @@ -1006,17 +963,23 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) int WorldSocket::iSendPacket (const WorldPacket& pct) { - ServerPktHeader header(pct.size()+2, pct.GetOpcode()); - if (m_OutBuffer->space () < pct.size () + header.getHeaderLength()) + if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader)) { errno = ENOBUFS; return -1; } + ServerPktHeader header; - m_Crypt.EncryptSend ( header.header, header.getHeaderLength()); + header.cmd = pct.GetOpcode (); + EndianConvert(header.cmd); - if (m_OutBuffer->copy ((char*) header.header, header.getHeaderLength()) == -1) + header.size = (uint16) pct.size () + 2; + EndianConvertReverse(header.size); + + m_Crypt.EncryptSend ((uint8*) & header, sizeof (header)); + + if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1) ACE_ASSERT (false); if (!pct.empty ()) diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index 8ec580f0c9f..878c4f5a711 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -63,7 +63,6 @@ bool ChatHandler::HandleDebugSpellFailCommand(const char* args) uint8 failnum = (uint8)atoi(px); WorldPacket data(SMSG_CAST_FAILED, 5); - data << uint8(0); data << uint32(133); data << uint8(failnum); m_session->SendPacket(&data); @@ -569,55 +568,5 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/) ref = ref->next(); } SendSysMessage("End of hostil reference list."); - return true; -} - -bool ChatHandler::HandleSpawnVehicle(const char* args) -{ - if(!args) - return false; - - char* e = strtok((char*)args, " "); - char* i = strtok(NULL, " "); - - if (!e || !i) - return false; - - uint32 entry = (uint32)atoi(e); - uint32 id = (uint32)atoi(i); - - CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); - - if(!ci) - return false; - - VehicleEntry const *ve = sVehicleStore.LookupEntry(id); - - if(!ve) - return false; - - Vehicle *v = new Vehicle; - Map *map = m_session->GetPlayer()->GetMap(); - if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam())) - { - delete v; - return false; - } - - float px, py, pz; - m_session->GetPlayer()->GetClosePoint(px, py, pz, m_session->GetPlayer()->GetObjectSize()); - - v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation()); - - if(!v->IsPositionValid()) - { - sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)", - v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY()); - delete v; - return false; - } - - map->Add((Creature*)v); - return true; } \ No newline at end of file diff --git a/src/shared/Auth/AuthCrypt.cpp b/src/shared/Auth/AuthCrypt.cpp index 199e7192537..7941b33ed8c 100644 --- a/src/shared/Auth/AuthCrypt.cpp +++ b/src/shared/Auth/AuthCrypt.cpp @@ -50,8 +50,9 @@ void AuthCrypt::DecryptRecv(uint8 *data, size_t len) void AuthCrypt::EncryptSend(uint8 *data, size_t len) { if (!_initialized) return; + if (len < CRYPTED_SEND_LEN) return; - for (size_t t = 0; t < len; t++) + for (size_t t = 0; t < CRYPTED_SEND_LEN; t++) { _send_i %= _key.size(); uint8 x = (data[t] ^ _key[_send_i]) + _send_j; diff --git a/src/shared/Auth/AuthCrypt.h b/src/shared/Auth/AuthCrypt.h index 366cce5635f..f3a0cac40fa 100644 --- a/src/shared/Auth/AuthCrypt.h +++ b/src/shared/Auth/AuthCrypt.h @@ -32,6 +32,7 @@ class AuthCrypt AuthCrypt(); ~AuthCrypt(); + const static size_t CRYPTED_SEND_LEN = 4; const static size_t CRYPTED_RECV_LEN = 6; void Init(); diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h index 4f406c9cc63..1d54616a2b5 100644 --- a/src/shared/Database/DBCEnums.h +++ b/src/shared/Database/DBCEnums.h @@ -34,190 +34,28 @@ enum AreaTeams AREATEAM_HORDE = 4 }; -enum AchievementFactionFlags -{ - ACHIEVEMENT_FACTION_FLAG_HORDE = 0x00000000, - ACHIEVEMENT_FACTION_FLAG_ALLIANCE = 0x00000001, -}; - -enum AchievementFlags -{ - ACHIEVEMENT_FLAG_COUNTER = 0x00000001, - ACHIEVEMENT_FLAG_REACH_LEVEL = 0x00000004, - ACHIEVEMENT_FLAG_RERERED_MAX = 0x00000010, // displays the maximum criteria of a refered achievement - ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, - ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100, - ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, -}; - -enum AchievementCriteriaCondition -{ - ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0, - ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, - ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days" - ACHIEVEMENT_CRITERIA_CONDITION_MAP = 3, // requires you to be on specific map - ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE = 4, // only used in "Win 10 arenas without losing" - ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk - ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk -}; - -enum AchievementCriteriaCompletionFlags -{ - // some Achievements (like 698) have several criteria but only one has to be fulfilled. These are identified by this flag. - ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL = 2, -}; - -enum AchievementCriteriaGroupFlags -{ - // you mustn't be in a group while fulfilling this achievement - ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2, -}; - -enum AchievementCriteriaTypes -{ - ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0, - ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1, - ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5, - ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9, - // you have to complete a daily quest x times in a row - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, - ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15, - ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16, - // TODO: this can be both arena and total deaths. Where is this difference in the dbc? - ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17, - ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19, - ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20, - ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23, - ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24, - ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27, - ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28, - ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29, - ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30, - ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31, - ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32, - ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34, - // TODO: this criteria has additional conditions which can not be found in the dbcs - ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35, - ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36, - // TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc - ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38, - ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40, - ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42, - ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43, - ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44, - ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47, - // noted: rewarded as soon as the player payed, not at taking place at the seat - ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48, - ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49, - // TODO: itemlevel is mentioned in text but not present in dbc - ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51, - ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52, - ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53, - ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54, - ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55, - // TODO: in some cases map not present, and in some cases need do without die - ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56, - ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57, - ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60, - ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61, - ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67, - ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68, - ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69, - ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70, - ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72, - // TODO: title id is not mentioned in dbc - ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75, - ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76, - ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77, - // TODO: creature type (demon, undead etc.) is not stored in dbc - ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80, - ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83, - ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88, - ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90, - ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH = 95, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR = 99, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102, - ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104, - ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106, - ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107, - ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109, - // TODO: target entry is missing - ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112, - ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, - ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, - // 0..114 => 115 criteria types total - ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115, -}; - enum AreaFlags { AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring) - AREA_FLAG_UNK1 = 0x00000002, // may be necropolis? - AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before) - AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones - AREA_FLAG_UNK3 = 0x00000010, // can't find common meaning + AREA_FLAG_UNK1 = 0x00000002, // unknown, (only Naxxramas and Razorfen Downs) + AREA_FLAG_UNK2 = 0x00000004, // Only used on development map + AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // slave capital city flag? + AREA_FLAG_UNK3 = 0x00000010, // unknown AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag? AREA_FLAG_UNK4 = 0x00000040, // many zones have this flag AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?) - AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag) + AREA_FLAG_OUTLAND = 0x00000400, // outland zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag) AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled) AREA_FLAG_NEED_FLY = 0x00001000, // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway - AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 3.0.3) - AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag) + AREA_FLAG_UNUSED1 = 0x00002000, // not used now (no area/zones with this flag set in 2.4.2) + AREA_FLAG_OUTLAND2 = 0x00004000, // outland zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag) AREA_FLAG_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area) AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only - AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 3.0.3) - AREA_FLAG_UNK5 = 0x00040000, // only used for Amani Pass, Hatchet Hills - AREA_FLAG_UNK6 = 0x00080000, // Valgarde and Acherus: The Ebon Hold - AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <=15 - AREA_FLAG_TOWN = 0x00200000, // small towns with Inn - AREA_FLAG_UNK7 = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn - AREA_FLAG_UNK8 = 0x00800000, // Westguard Inn, Acherus: The Ebon Hold, Valgarde - AREA_FLAG_OUTDOOR_PVP = 0x01000000, // Wintergrasp and it's subzones - AREA_FLAG_UNK9 = 0x02000000, // unknown - AREA_FLAG_UNK10 = 0x04000000, // unknown - AREA_FLAG_OUTDOOR_PVP2 = 0x08000000 // Wintergrasp and it's subzones + AREA_FLAG_UNUSED2 = 0x00020000, // not used now (no area/zones with this flag set in 2.4.2) + AREA_FLAG_UNK5 = 0x00040000, // just used for Amani Pass, Hatchet Hills + AREA_FLAG_LOWLEVEL = 0x00100000 // used for some starting areas with area_level <=15 }; enum FactionTemplateFlags @@ -271,51 +109,4 @@ enum TotemCategoryType TOTEM_CATEGORY_TYPE_SPANNER = 24 }; -// SummonProperties.dbc, col 1 -/*enum SummonGroup -{ - SUMMON_GROUP_UNKNOWN1 = 0, // 1160 spells in 3.0.3 - SUMMON_GROUP_UNKNOWN2 = 1, // 861 spells in 3.0.3 - SUMMON_GROUP_PETS = 2, // 52 spells in 3.0.3, pets mostly - SUMMON_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable - SUMMON_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts -}; - -// SummonProperties.dbc, col 3 -enum SummonType -{ - SUMMON_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3 - SUMMON_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3 - SUMMON_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3 - SUMMON_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3 - SUMMON_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3 - SUMMON_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3 - SUMMON_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3 - SUMMON_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3 - SUMMON_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3 - SUMMON_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3 - SUMMON_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells - SUMMON_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3 -}; - -// SummonProperties.dbc, col 5 -enum SummonFlags -{ - SUMMON_FLAG_NONE = 0x0000, // 1342 spells in 3.0.3 - SUMMON_FLAG_UNK1 = 0x0001, // 75 spells in 3.0.3, something unfriendly - SUMMON_FLAG_UNK2 = 0x0002, // 616 spells in 3.0.3, something friendly - SUMMON_FLAG_UNK3 = 0x0004, // 22 spells in 3.0.3, no idea... - SUMMON_FLAG_UNK4 = 0x0008, // 49 spells in 3.0.3, some mounts - SUMMON_FLAG_UNK5 = 0x0010, // 25 spells in 3.0.3, quest related? - SUMMON_FLAG_UNK6 = 0x0020, // 0 spells in 3.0.3, unused - SUMMON_FLAG_UNK7 = 0x0040, // 12 spells in 3.0.3, no idea - SUMMON_FLAG_UNK8 = 0x0080, // 4 spells in 3.0.3, no idea - SUMMON_FLAG_UNK9 = 0x0100, // 51 spells in 3.0.3, no idea, many quest related - SUMMON_FLAG_UNK10 = 0x0200, // 51 spells in 3.0.3, something defensive - SUMMON_FLAG_UNK11 = 0x0400, // 3 spells, requires something near? - SUMMON_FLAG_UNK12 = 0x0800, // 30 spells in 3.0.3, no idea - SUMMON_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle - SUMMON_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort? -}; -*/ #endif diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index c183f8356b4..fb132c75768 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -35,12 +35,9 @@ DBCStorage sAreaStore(AreaTableEntryfmt); static AreaFlagByAreaID sAreaFlagByAreaID; static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files -DBCStorage sAchievementStore(Achievementfmt); -DBCStorage sAchievementCriteriaStore(AchievementCriteriafmt); DBCStorage sAreaTriggerStore(AreaTriggerEntryfmt); DBCStorage sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); DBCStorage sBattlemasterListStore(BattlemasterListEntryfmt); -DBCStorage sBarberShopStyleStore(BarberShopStyleEntryfmt); DBCStorage sCharStartOutfitStore(CharStartOutfitEntryfmt); DBCStorage sCharTitlesStore(CharTitlesEntryfmt); DBCStorage sChatChannelsStore(ChatChannelsEntryfmt); @@ -61,10 +58,7 @@ DBCStorage sFactionStore(FactionEntryfmt); DBCStorage sFactionTemplateStore(FactionTemplateEntryfmt); DBCStorage sGemPropertiesStore(GemPropertiesEntryfmt); -DBCStorage sGlyphPropertiesStore(GlyphPropertiesfmt); -DBCStorage sGlyphSlotStore(GlyphSlotfmt); -DBCStorage sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt); DBCStorage sGtCombatRatingsStore(GtCombatRatingsfmt); DBCStorage sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt); DBCStorage sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt); @@ -90,8 +84,6 @@ DBCStorage sMapStore(MapEntryfmt); DBCStorage sQuestSortStore(QuestSortEntryfmt); DBCStorage sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); -DBCStorage sScalingStatDistributionStore(ScalingStatDistributionfmt); -DBCStorage sScalingStatValuesStore(ScalingStatValuesfmt); DBCStorage sSkillLineStore(SkillLinefmt); DBCStorage sSkillLineAbilityStore(SkillLineAbilityfmt); @@ -109,10 +101,8 @@ DBCStorage sSpellDurationStore(SpellDurationfmt); DBCStorage sSpellFocusObjectStore(SpellFocusObjectfmt); DBCStorage sSpellRadiusStore(SpellRadiusfmt); DBCStorage sSpellRangeStore(SpellRangefmt); -DBCStorage sSpellRuneCostStore(SpellRuneCostfmt); DBCStorage sSpellShapeshiftStore(SpellShapeshiftfmt); DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); -//DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage sTalentStore(TalentEntryfmt); TalentSpellPosMap sTalentSpellPosMap; DBCStorage sTalentTabStore(TalentTabEntryfmt); @@ -135,11 +125,8 @@ TaxiPathNodesByPath sTaxiPathNodesByPath; static DBCStorage sTaxiPathNodeStore(TaxiPathNodeEntryfmt); DBCStorage sTotemCategoryStore(TotemCategoryEntryfmt); -DBCStorage sVehicleStore(VehicleEntryfmt); -DBCStorage sVehicleSeatStore(VehicleSeatEntryfmt); DBCStorage sWorldMapAreaStore(WorldMapAreaEntryfmt); DBCStorage sWorldSafeLocsStore(WorldSafeLocsEntryfmt); -DBCStorage sWorldMapOverlayStore(WorldMapOverlayEntryfmt); typedef std::list StoreProblemList; @@ -191,7 +178,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 66; + const uint32 DBCFilesCount = 56; barGoLink bar( DBCFilesCount ); @@ -209,19 +196,16 @@ void LoadDBCStores(const std::string& dataPath) sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); // fill MapId->DBC records ( skip sub zones and continents ) - if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 ) + if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 ) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); - + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); @@ -245,10 +229,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); @@ -273,8 +254,6 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore, dbcPath,"Map.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore, dbcPath,"ScalingStatValues.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore, dbcPath,"SkillLine.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore, dbcPath,"SkillLineAbility.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore, dbcPath,"SoundEntries.dbc"); @@ -324,10 +303,8 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore, dbcPath,"SpellRadius.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore, dbcPath,"SpellRange.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); - //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); // create talent spells set @@ -430,10 +407,7 @@ void LoadDBCStores(const std::string& dataPath) pathLength.resize(pathCount); // 0 and some other indexes not used for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) - { - if (pathLength[entry->path] < entry->index + 1) - pathLength[entry->path] = entry->index + 1; - } + ++pathLength[entry->path]; // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) @@ -445,11 +419,8 @@ void LoadDBCStores(const std::string& dataPath) sTaxiPathNodeStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); // error checks if(bad_dbc_files.size() >= DBCFilesCount ) @@ -467,20 +438,20 @@ void LoadDBCStores(const std::string& dataPath) exit(1); } - // check at up-to-date DBC files (54909 is last added spell in 3.0.1) - // check at up-to-date DBC files (19162 is last added spell in abilities in 3.0.1) - // check at up-to-date DBC files (619 is last map added in 3.0.1) - // check at up-to-date DBC files (1361 is last gem property added in 3.0.1) - // check at up-to-date DBC files (2425 is last item extended cost added in 3.0.1) - // check at up-to-date DBC files (76 is last char title added in 3.0.1) - // check at up-to-date DBC files (2311 is last area added in 3.0.1) - if( !sSpellStore.LookupEntry(54909) || - !sSkillLineAbilityStore.LookupEntry(19162) || - !sMapStore.LookupEntry(619) || - !sGemPropertiesStore.LookupEntry(1361) || - !sItemExtendedCostStore.LookupEntry(2425) || - !sCharTitlesStore.LookupEntry(76) || - !sAreaStore.LookupEntry(2311) ) + // check at up-to-date DBC files (53085 is last added spell in 2.4.3) + // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3) + // check at up-to-date DBC files (598 is last map added in 2.4.3) + // check at up-to-date DBC files (1127 is last gem property added in 2.4.3) + // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3) + // check at up-to-date DBC files (71 is last char title added in 2.4.3) + // check at up-to-date DBC files (1768 is last area added in 2.4.3) + if( !sSpellStore.LookupEntry(53085) || + !sSkillLineAbilityStore.LookupEntry(17514) || + !sMapStore.LookupEntry(598) || + !sGemPropertiesStore.LookupEntry(1127) || + !sItemExtendedCostStore.LookupEntry(2425) || + !sCharTitlesStore.LookupEntry(71) || + !sAreaStore.LookupEntry(1768) ) { sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); @@ -566,7 +537,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid) uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { - if(mapid != 530 || mapid != 571) // speed for most cases + if(mapid != 530) // speed for most cases return mapid; if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h index 8f53fef84ef..98a54fbeccf 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -132,12 +132,9 @@ class DBCStorage StringPoolList m_stringPoolList; }; -extern DBCStorage sAchievementStore; -extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAreaStore;// recommend access using functions extern DBCStorage sAreaTriggerStore; extern DBCStorage sBankBagSlotPricesStore; -extern DBCStorage sBarberShopStyleStore; extern DBCStorage sBattlemasterListStore; //extern DBCStorage sChatChannelsStore; -- accessed using function, no usable index extern DBCStorage sCharStartOutfitStore; @@ -153,10 +150,7 @@ extern DBCStorage sEmotesTextStore; extern DBCStorage sFactionStore; extern DBCStorage sFactionTemplateStore; extern DBCStorage sGemPropertiesStore; -extern DBCStorage sGlyphPropertiesStore; -extern DBCStorage sGlyphSlotStore; -extern DBCStorage sGtBarberShopCostBaseStore; extern DBCStorage sGtCombatRatingsStore; extern DBCStorage sGtChanceToMeleeCritBaseStore; extern DBCStorage sGtChanceToMeleeCritStore; @@ -177,8 +171,6 @@ extern DBCStorage sMailTemplateStore; extern DBCStorage sMapStore; extern DBCStorage sQuestSortStore; extern DBCStorage sRandomPropertiesPointsStore; -extern DBCStorage sScalingStatDistributionStore; -extern DBCStorage sScalingStatValuesStore; extern DBCStorage sSkillLineStore; extern DBCStorage sSkillLineAbilityStore; extern DBCStorage sSoundEntriesStore; @@ -191,11 +183,9 @@ extern SpellCategoryStore sSpellCategoryStore; extern PetFamilySpellsStore sPetFamilySpellsStore; extern DBCStorage sSpellRadiusStore; extern DBCStorage sSpellRangeStore; -extern DBCStorage sSpellRuneCostStore; extern DBCStorage sSpellShapeshiftStore; extern DBCStorage sSpellStore; extern DBCStorage sStableSlotPricesStore; -//extern DBCStorage sSummonPropertiesStore; extern DBCStorage sTalentStore; extern DBCStorage sTalentTabStore; extern DBCStorage sTaxiNodesStore; @@ -204,11 +194,8 @@ extern TaxiMask sTaxiNodesMask; extern TaxiPathSetBySource sTaxiPathSetBySource; extern TaxiPathNodesByPath sTaxiPathNodesByPath; extern DBCStorage sTotemCategoryStore; -extern DBCStorage sVehicleStore; -extern DBCStorage sVehicleSeatStore; //extern DBCStorage sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates extern DBCStorage sWorldSafeLocsStore; -extern DBCStorage sWorldMapOverlayStore; void LoadDBCStores(const std::string& dataPath); diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 1b406718f47..99d789f133f 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -37,507 +37,57 @@ #pragma pack(push,1) #endif -struct AchievementEntry -{ - uint32 ID; // 0 - uint32 factionFlag; // 1 -1=all, 0=horde, 1=alliance - uint32 mapID; // 2 -1=none - //uint32 parentAchievement; // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) - //char *name[16]; // 4-19 - //uint32 name_flags; // 20 - //char *description[16]; // 21-36 - //uint32 desc_flags; // 37 - uint32 categoryId; // 38 - uint32 points; // 39 reward points - //uint32 OrderInCategory; // 40 - uint32 flags; // 41 - //uint32 icon; // 42 icon (from SpellIcon.dbc) - //char *titleReward[16]; // 43-58 - //uint32 titleReward_flags; // 59 - //uint32 count; // 60 - need this count Criteria for complete - uint32 refAchievement; // 61 - related achievement? -}; - -struct AchievementCategoryEntry -{ - uint32 ID; // 0 - uint32 parentCategory; // 1 -1 for main category - //char *name[16]; // 2-17 - //uint32 name_flags; // 18 - //uint32 sortOrder; // 19 -}; - -struct AchievementCriteriaEntry -{ - uint32 ID; // 0 - uint32 referredAchievement; // 1 - uint32 requiredType; // 2 - union - { - // ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0 - // TODO: also used for player deaths.. - struct - { - uint32 creatureID; // 3 - uint32 creatureCount; // 4 - } kill_creature; - - // ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1 - // TODO: there are further criterias instead just winning - struct - { - uint32 bgMapID; // 3 - uint32 winCount; // 4 - } win_bg; - - // ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5 - struct - { - uint32 unused; // 3 - uint32 level; // 4 - } reach_level; - - // ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7 - struct - { - uint32 skillID; // 3 - uint32 skillLevel; // 4 - } reach_skill_level; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8 - struct - { - uint32 linkedAchievement; // 3 - } complete_achievement; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9 - struct - { - uint32 unused; // 3 - uint32 totalQuestCount; // 4 - } complete_quest_count; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10 - struct - { - uint32 unused; // 3 - uint32 numberOfDays; // 4 - } complete_daily_quest_daily; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11 - struct - { - uint32 zoneID; // 3 - uint32 questCount; // 4 - } complete_quests_in_zone; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14 - struct - { - uint32 unused; // 3 - uint32 questCount; // 4 - } complete_daily_quest; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15 - struct - { - uint32 mapID; // 3 - } complete_battleground; - - // ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16 - struct - { - uint32 mapID; // 3 - } death_at_map; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19 - struct - { - uint32 groupSize; // 3 can be 5, 10 or 25 - } complete_raid; - - // ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20 - struct - { - uint32 creatureEntry; // 3 - } killed_by_creature; - - // ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24 - struct - { - uint32 unused; // 3 - uint32 fallHeight; // 4 - } fall_without_dying; - - // ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26 - struct - { - uint32 type; // 0 - fatigue, 1 - drowning, 2 - falling, 3 - ??, 5 - fire and lava - } deaths; - - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27 - struct - { - uint32 questID; // 3 - uint32 questCount; // 4 - } complete_quest; - - // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28 - // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69 - struct - { - uint32 spellID; // 3 - uint32 spellCount; // 4 - } be_spell_target; - - // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29 - // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110 - struct - { - uint32 spellID; // 3 - uint32 castCount; // 4 - } cast_spell; - - // ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31 - struct - { - uint32 areaID; // 3 Reference to AreaTable.dbc - uint32 killCount; // 4 - } honorable_kill_at_area; - - // ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32 - struct - { - uint32 mapID; // 3 Reference to Map.dbc - } win_arena; - - // ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33 - struct - { - uint32 mapID; // 3 Reference to Map.dbc - } play_arena; - - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34 - struct - { - uint32 spellID; // 3 Reference to Map.dbc - } learn_spell; - - // ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36 - struct - { - uint32 itemID; // 3 - uint32 itemCount; // 4 - } own_item; - - // ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37 - struct - { - uint32 unused; // 3 - uint32 count; // 4 - uint32 flag; // 5 4=in a row - } win_rated_arena; - - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38 - struct - { - uint32 teamtype; // 3 {2,3,5} - } highest_team_rating; - - // ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39 - struct - { - uint32 teamtype; // 3 {2,3,5} - uint32 teamrating; // 4 - } reach_team_rating; - - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40 - struct - { - uint32 skillID; // 3 - uint32 skillLevel; // 4 apprentice=1, journeyman=2, expert=3, artisan=4, master=5, grand master=6 - } learn_skill_level; - - // ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41 - struct - { - uint32 itemID; // 3 - uint32 itemCount; // 4 - } use_item; - - // ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42 - struct - { - uint32 itemID; // 3 - uint32 itemCount; // 4 - } loot_item; - - // ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43 - struct - { - // TODO: This rank is _NOT_ the index from AreaTable.dbc - uint32 areaReference; // 3 - } explore_area; - - // ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44 - struct - { - // TODO: This rank is _NOT_ the index from CharTitles.dbc - uint32 rank; // 3 - } own_rank; - - // ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45 - struct - { - uint32 unused; // 3 - uint32 numberOfSlots; // 4 - } buy_bank_slot; - - // ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46 - struct - { - uint32 factionID; // 3 - uint32 reputationAmount; // 4 Total reputation amount, so 42000 = exalted - } gain_reputation; - - // ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47 - struct - { - uint32 unused; // 3 - uint32 numberOfExaltedFactions; // 4 - } gain_exalted_reputation; - - // ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48 - struct - { - uint32 unused; // 3 - uint32 numberOfVisits; // 4 - } visit_barber; - - // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49 - // TODO: where is the required itemlevel stored? - struct - { - uint32 itemSlot; // 3 - } equip_epic_item; - - // ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT= 50 - struct - { - uint32 rollValue; // 3 - uint32 count; // 4 - } roll_need_on_loot; - - // ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52 - struct - { - uint32 classID; // 3 - uint32 count; // 4 - } hk_class; - - // ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53 - struct - { - uint32 raceID; // 3 - uint32 count; // 4 - } hk_race; - - // ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54 - // TODO: where is the information about the target stored? - struct - { - uint32 emoteID; // 3 - } do_emote; - // ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13 - // ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55 - // ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56 - struct - { - uint32 unused; // 3 - uint32 count; // 4 - uint32 flag; // 5 =3 for battleground healing - uint32 mapid; // 6 - } healing_done; - - // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57 - struct - { - uint32 itemID; // 3 - } equip_item; - - - // ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67 - struct - { - uint32 unused; // 3 - uint32 goldInCopper; // 4 - } loot_money; - - // ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68 - struct - { - uint32 goEntry; // 3 - uint32 useCount; // 4 - } use_gameobject; - - // ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70 - // TODO: are those special criteria stored in the dbc or do we have to add another sql table? - struct - { - uint32 unused; // 3 - uint32 killCount; // 4 - } special_pvp_kill; - - // ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72 - struct - { - uint32 goEntry; // 3 - uint32 lootCount; // 4 - } fish_in_gameobject; - - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75 - struct - { - uint32 skillLine; // 3 - uint32 spellCount; // 4 - } learn_skilline_spell; - - // ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76 - struct - { - uint32 unused; // 3 - uint32 duelCount; // 4 - } win_duel; - - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96 - struct - { - uint32 powerType; // 3 mana=0, 1=rage, 3=energy, 6=runic power - } highest_power; - - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97 - struct - { - uint32 statType; // 3 4=spirit, 3=int, 2=stamina, 1=agi, 0=strength - } highest_stat; - - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98 - struct - { - uint32 spellSchool; // 3 - } highest_spellpower; - - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100 - struct - { - uint32 ratingType; // 3 - } highest_rating; - - // ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109 - struct - { - uint32 lootType; // 3 3=fishing, 2=pickpocket, 4=disentchant - uint32 lootTypeCount; // 4 - } loot_type; - - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112 - struct - { - uint32 skillLine; // 3 - uint32 spellCount; // 4 - } learn_skill_line; - - // ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113 - struct - { - uint32 unused; // 3 - uint32 killCount; // 4 - } honorable_kill; - - struct - { - uint32 field3; // 3 main requirement - uint32 field4; // 4 main requirement count - uint32 additionalRequirement1_type; // 5 additional requirement 1 type - uint32 additionalRequirement1_value; // 6 additional requirement 1 value - uint32 additionalRequirement2_type; // 7 additional requirement 2 type - uint32 additionalRequirement2_value; // 8 additional requirement 1 value - } raw; - }; - //char* name[16]; // 9-24 - //uint32 name_flags; // 25 - uint32 completionFlag; // 26 - uint32 groupFlag; // 27 - //uint32 unk1; // 28 - uint32 timeLimit; // 29 time limit in seconds - //uint32 showOrder; // 30 show order -}; - struct AreaTableEntry { - uint32 ID; // 0 - uint32 mapid; // 1 - uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area - uint32 exploreFlag; // 3, main index - uint32 flags; // 4, unknown value but 312 for all cities + uint32 ID; // 0 + uint32 mapid; // 1 + uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area + uint32 exploreFlag; // 3, main index + uint32 flags; // 4, unknown value but 312 for all cities // 5-9 unused - int32 area_level; // 10 - char* area_name[16]; // 11-26 + int32 area_level; // 10 + char* area_name[16]; // 11-26 // 27, string flags, unused - uint32 team; // 28 + uint32 team; // 28 }; struct AreaTriggerEntry { - uint32 id; // 0 m_ID - uint32 mapid; // 1 m_ContinentID - float x; // 2 m_x - float y; // 3 m_y - float z; // 4 m_z - float radius; // 5 m_radius - float box_x; // 6 m_box_length - float box_y; // 7 m_box_width - float box_z; // 8 m_box_heigh - float box_orientation; // 9 m_box_yaw + uint32 id; // 0 + uint32 mapid; // 1 + float x; // 2 + float y; // 3 + float z; // 4 + float radius; // 5 + float box_x; // 6 extent x edge + float box_y; // 7 extent y edge + float box_z; // 8 extent z edge + float box_orientation; // 9 extent rotation by about z axis }; struct BankBagSlotPricesEntry { - uint32 ID; - uint32 price; -}; - -struct BarberShopStyleEntry -{ - uint32 Id; // 0 - uint32 type; // 1 value 0 -> hair, value 2 -> facialhair - //char* name[16]; // 2-17 name of hair style - //uint32 name_flags; // 18 - //uint32 unk_name[16]; // 19-34, all empty - //uint32 unk_flags; // 35 - //float CostMultiplier; // 36 values 1 and 0.75 - uint32 race; // 37 race - uint32 gender; // 38 0 -> male, 1 -> female - uint32 hair_id; // 39 real ID to hair/facial hair + uint32 ID; + uint32 price; }; struct BattlemasterListEntry { - uint32 id; // 0 - int32 mapid[8]; // 1-8 mapid - uint32 type; // 9 (3 - BG, 4 - arena) - uint32 minlvl; // 10 - uint32 maxlvl; // 11 - uint32 maxplayersperteam; // 12 - // 13 minplayers - // 14 0 or 9 - // 15 - char* name[16]; // 16-31 - // 32 string flag, unused - // 33 unused + uint32 id; // 0 + uint32 mapid[3]; // 1-3 mapid + // 4-8 unused + uint32 type; // 9 (3 - BG, 4 - arena) + uint32 minlvl; // 10 + uint32 maxlvl; // 11 + uint32 maxplayersperteam; // 12 + // 13-14 unused + char* name[16]; // 15-30 + // 31 string flag, unused + // 32 unused }; -#define MAX_OUTFIT_ITEMS 24 +#define MAX_OUTFIT_ITEMS 12 +// #define MAX_OUTFIT_ITEMS 24 // 12->24 in 3.0.x struct CharStartOutfitEntry { @@ -553,20 +103,20 @@ struct CharStartOutfitEntry struct CharTitlesEntry { - uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() + uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() //uint32 unk1; // 1 flags? //char* name[16]; // 2-17, unused // 18 string flag, unused //char* name2[16]; // 19-34, unused // 35 string flag, unused - uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<