Index: contrib/map_extractor/adt.cpp =================================================================== --- contrib/map_extractor/adt.cpp (revision 5641) +++ contrib/map_extractor/adt.cpp (working copy) @@ -418,7 +418,7 @@ { for(unsigned int y=0;y<16;y++) { - if(mcells->ch[y][x].area_id && mcells->ch[y][x].area_id < 0xFAA) + 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); Index: sql/updates_4x/characters_characters.sql =================================================================== --- sql/updates_4x/characters_characters.sql (revision 0) +++ sql/updates_4x/characters_characters.sql (revision 0) @@ -0,0 +1,19 @@ +UPDATE characters.characters +SET data = CONCAT( + SUBSTRING_INDEX(data,' ',225+1), + ' 1 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',315+1),' ',225-315), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',621+1),' ',315-621), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',822+1),' ',621-822), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1319+1),' ',822-1319), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1351+1),' ',1319-1351), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1447+1),' ',1351-1447), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(data,' ',-1449+1447+1) +) +WHERE SUBSTRING_INDEX(data,' ',1448)=data; Index: sql/updates_4x/characters_characters.sql =================================================================== --- sql/updates_4x/characters_characters.sql (revision 0) +++ sql/updates_4x/characters_characters.sql (revision 0) @@ -0,0 +1,19 @@ +UPDATE characters.characters +SET data = CONCAT( + SUBSTRING_INDEX(data,' ',225+1), + ' 1 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',315+1),' ',225-315), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',621+1),' ',315-621), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',822+1),' ',621-822), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1319+1),' ',822-1319), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1351+1),' ',1319-1351), + ' 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',1447+1),' ',1351-1447), + ' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ', + SUBSTRING_INDEX(data,' ',-1449+1447+1) +) +WHERE SUBSTRING_INDEX(data,' ',1448)=data; Index: src/game/AccountMgr.cpp =================================================================== --- src/game/AccountMgr.cpp (revision 5641) +++ src/game/AccountMgr.cpp (working copy) @@ -74,7 +74,7 @@ { Field *fields = result->Fetch(); uint32 guidlo = fields[0].GetUInt32(); - uint64 guid = MAKE_GUID(guidlo, HIGHGUID_PLAYER); + uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER); // kick if player currently if(Player* p = objmgr.GetPlayer(guid)) Index: src/game/ArenaTeam.cpp =================================================================== --- src/game/ArenaTeam.cpp (revision 5641) +++ src/game/ArenaTeam.cpp (working copy) @@ -322,7 +322,7 @@ Player *pl = NULL; WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100); - data << uint8(GetSlot()); // slot + data << uint32(GetId()); // arena team id data << uint32(GetMembersSize()); // members count data << uint32(GetType()); // arena team type? Index: src/game/ArenaTeamHandler.cpp =================================================================== --- src/game/ArenaTeamHandler.cpp (revision 5641) +++ src/game/ArenaTeamHandler.cpp (working copy) @@ -24,6 +24,7 @@ #include "ObjectMgr.h" #include "ArenaTeam.h" #include "World.h" +#include "SocialMgr.h" void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data) { @@ -72,12 +73,12 @@ sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" ); //recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 1); + CHECK_PACKET_SIZE(recv_data, 4); - uint8 team_slot; // probably team_size or slot + uint32 team_slot; // probably team_size or slot recv_data >> team_slot; - ArenaTeam *arenateam = objmgr.GetArenaTeamById(_player->GetArenaTeamId(team_slot)); + ArenaTeam *arenateam = objmgr.GetArenaTeamById(_player->GetArenaTeamId(team_slot-1)); if(!arenateam) return; @@ -89,9 +90,9 @@ sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER"); //recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 1+1); + CHECK_PACKET_SIZE(recv_data, 4+1); - uint8 team_slot; // slot? + uint32 team_slot; // slot? std::string Invitedname; Player * player = NULL; @@ -119,7 +120,7 @@ return; } - ArenaTeam *arenateam = objmgr.GetArenaTeamById(_player->GetArenaTeamId(team_slot)); + ArenaTeam *arenateam = objmgr.GetArenaTeamById(_player->GetArenaTeamId(team_slot-1)); if(!arenateam) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM); @@ -127,7 +128,7 @@ } // OK result but not send invite - if(player->HasInIgnoreList(GetPlayer()->GetGUID())) + if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) @@ -136,7 +137,7 @@ return; } - if(player->GetArenaTeamId(team_slot)) + if(player->GetArenaTeamId(team_slot-1)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S); return; @@ -158,7 +159,7 @@ sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str()); - player->SetArenaTeamIdInvited(GetPlayer()->GetArenaTeamId(team_slot)); + player->SetArenaTeamIdInvited(GetPlayer()->GetArenaTeamId(team_slot-1)); WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); data << GetPlayer()->GetName(); @@ -212,12 +213,12 @@ sLog.outDebug("CMSG_ARENA_TEAM_LEAVE"); //recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 1); + CHECK_PACKET_SIZE(recv_data, 4); - uint8 team_slot; // slot? + uint32 team_slot; // slot? recv_data >> team_slot; - uint32 at_id = _player->GetArenaTeamId(team_slot); + uint32 at_id = _player->GetArenaTeamId(team_slot-1); if(!at_id) // not in arena team { // send command result @@ -258,12 +259,12 @@ sLog.outDebug("CMSG_ARENA_TEAM_DISBAND"); //recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 1); + CHECK_PACKET_SIZE(recv_data, 4); - uint8 team_slot; // slot? + uint32 team_slot; // slot? recv_data >> team_slot; - uint32 at_id = _player->GetArenaTeamId(team_slot); + uint32 at_id = _player->GetArenaTeamId(team_slot-1); if(!at_id) { // arena team id not found @@ -292,15 +293,15 @@ sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM"); //recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 1+1); + CHECK_PACKET_SIZE(recv_data, 4+1); - uint8 team_slot; + uint32 team_slot; std::string name; recv_data >> team_slot; recv_data >> name; - uint32 at_id = _player->GetArenaTeamId(team_slot); + uint32 at_id = _player->GetArenaTeamId(team_slot-1); if(!at_id) { // arena team id not found @@ -353,15 +354,15 @@ sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN"); //recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 1+1); + CHECK_PACKET_SIZE(recv_data, 4+1); - uint8 team_slot; + uint32 team_slot; std::string name; recv_data >> team_slot; recv_data >> name; - uint32 at_id = _player->GetArenaTeamId(team_slot); + uint32 at_id = _player->GetArenaTeamId(team_slot-1); if(!at_id) { // arena team id not found @@ -440,8 +441,10 @@ void WorldSession::SendNotInArenaTeamPacket(uint8 type) { WorldPacket data(SMSG_ARENA_NO_TEAM, 4+1); // 886 - You are not in a %uv%u arena team - data << uint32(0); // unk(0) - data << type; // team type (2=2v2,3=3v3,5=5v5), can be used for custom types... + uint32 unk = 0; + data << uint32(unk); // unk(0) + if(!unk) + data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types... SendPacket(&data); } Index: src/game/Bag.cpp =================================================================== --- src/game/Bag.cpp (revision 5641) +++ src/game/Bag.cpp (working copy) @@ -72,7 +72,7 @@ if(!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE) return false; - Object::_Create( guidlow, HIGHGUID_CONTAINER ); + Object::_Create( guidlow, 0, HIGHGUID_CONTAINER ); SetUInt32Value(OBJECT_FIELD_ENTRY, itemid); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); Index: src/game/BattleGround.cpp =================================================================== --- src/game/BattleGround.cpp (revision 5641) +++ src/game/BattleGround.cpp (working copy) @@ -849,7 +849,7 @@ data.go_state = 1; objmgr.AddGameobjectToGrid(guid, &data); - m_BgObjects[type] = MAKE_GUID(guid, HIGHGUID_GAMEOBJECT); + m_BgObjects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT); return true; } Index: src/game/BattleGroundMgr.cpp =================================================================== --- src/game/BattleGroundMgr.cpp (revision 5641) +++ src/game/BattleGroundMgr.cpp (working copy) @@ -426,63 +426,22 @@ { data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3); *data << uint32(QueueSlot); // queue id (0...2) - *data << uint32(1); - *data << uint32(2); + *data << uint64(0); return; } data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4)); *data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time - *data << uint8(bg->GetArenaType()); // team type (0=BG, 2=2x2, 3=3x3, 5=5x5), for arenas - switch(bg->GetTypeID()) // value depends on bg id - { - case BATTLEGROUND_AV: - *data << uint8(1); - break; - case BATTLEGROUND_WS: - *data << uint8(2); - break; - case BATTLEGROUND_AB: - *data << uint8(3); - break; - case BATTLEGROUND_NA: - *data << uint8(4); - break; - case BATTLEGROUND_BE: - *data << uint8(5); - break; - case BATTLEGROUND_AA: - *data << uint8(6); - break; - case BATTLEGROUND_EY: - *data << uint8(7); - break; - case BATTLEGROUND_RL: - *data << uint8(8); - break; - default: // unknown - *data << uint8(0); - break; - } - - if(bg->isArena() && (StatusID == STATUS_WAIT_QUEUE)) - *data << uint32(BATTLEGROUND_AA); // all arenas - else - *data << uint32(bg->GetTypeID()); // BG id from DBC - - *data << uint16(0x1F90); // unk value 8080 - *data << uint32(bg->GetInstanceID()); // instance id - - if(bg->isBattleGround()) - *data << uint8(bg->GetTeamIndexByTeamId(team)); // team - else - *data << uint8(bg->isRated()); // is rated battle - + // uint64 in client + *data << uint64( uint64(bg->GetArenaType()) | (uint64(0x0D) << 8) | (uint64(bg->GetTypeID()) << 16) | (uint64(0x1F90) << 48) ); + *data << uint32(0); // unknown + // alliance/horde for BG and skirmish/rated for Arenas + *data << uint8(bg->isArena() ? (bg->isRated() ? 1 : 0) : bg->GetTeamIndexByTeamId(team)); *data << uint32(StatusID); // status switch(StatusID) { case STATUS_WAIT_QUEUE: // status_in_queue - *data << uint32(Time1); // wait time, milliseconds + *data << uint32(Time1); // average wait time, milliseconds *data << uint32(Time2); // time in queue, updated every minute? break; case STATUS_WAIT_JOIN: // status_invite Index: src/game/Channel.cpp =================================================================== --- src/game/Channel.cpp (revision 5641) +++ src/game/Channel.cpp (working copy) @@ -19,6 +19,7 @@ #include "Channel.h" #include "ObjectMgr.h" #include "World.h" +#include "SocialMgr.h" Channel::Channel(std::string name, uint32 channel_id) : m_name(name), m_announce(true), m_moderate(false), m_channelId(channel_id), m_ownerGUID(0), m_password(""), m_flags(0) @@ -618,7 +619,7 @@ } WorldPacket data; - if(!newp->HasInIgnoreList(p)) + if(!newp->GetSocial()->HasIgnore(GUID_LOPART(p))) { MakeInvite(&data, p); SendToOne(&data, newp->GetGUID()); @@ -663,7 +664,7 @@ Player *plr = objmgr.GetPlayer(i->first); if(plr) { - if(!p || !plr->HasInIgnoreList(p)) + if(!p || !plr->GetSocial()->HasIgnore(GUID_LOPART(p))) plr->GetSession()->SendPacket(data); } } Index: src/game/CharacterHandler.cpp =================================================================== --- src/game/CharacterHandler.cpp (revision 5641) +++ src/game/CharacterHandler.cpp (working copy) @@ -34,6 +34,7 @@ #include "Group.h" #include "Database/DatabaseImpl.h" #include "PlayerDump.h" +#include "SocialMgr.h" // check used symbols in player name at creating and rename std::string notAllowedChars = "\t\v\b\f\a\n\r\\\"\'\? <>[](){}_=+-|/!@#$%^&*~`.,0123456789\0"; @@ -72,8 +73,7 @@ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND checked = 0 AND deliver_time <= '" I64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND checked = 0", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADIGNORELIST, "SELECT friend FROM character_social WHERE guid = '%u' AND flags = 1", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFRIENDLIST, "SELECT friend FROM character_social WHERE guid = '%u' AND flags = 0 LIMIT 255", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADHOMEBIND, "SELECT map,zone,position_x,position_y,position_z FROM character_homebind WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS, "SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'", GUID_LOPART(m_guid)); @@ -82,7 +82,6 @@ // 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_BROADCASTTOFRIENDLISTERS,"SELECT guid FROM character_social WHERE friend = '%u' AND flags = 0", GUID_LOPART(m_guid)); return res; } @@ -413,8 +412,7 @@ data << uint32(0); SendPacket(&data); - pCurrChar->SendFriendlist(); - pCurrChar->SendIgnorelist(); + pCurrChar->GetSocial()->SendSocialList(); // added in 2.2.0 data.Initialize(SMSG_VOICE_SYSTEM_STATUS, 2); @@ -541,14 +539,7 @@ } // friend status - data.Initialize(SMSG_FRIEND_STATUS, 19); - data<GetGUID(); - data<GetAreaId(); - data<getLevel(); - data<getClass(); - pCurrChar->BroadcastPacketToFriendListers(&data, true, holder->GetResult(PLAYER_LOGIN_QUERY_BROADCASTTOFRIENDLISTERS)); + sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), "", true); // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); Index: src/game/Chat.cpp =================================================================== --- src/game/Chat.cpp (revision 5641) +++ src/game/Chat.cpp (working copy) @@ -37,7 +37,6 @@ LanguageDesc lang_description[LANGUAGES_COUNT] = { { LANG_ADDON, 0, 0 }, - { LANG_GLOBAL, 0, 0 }, { LANG_UNIVERSAL, 0, 0 }, { LANG_ORCISH, 669, SKILL_LANG_ORCISH }, { LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN }, @@ -52,7 +51,8 @@ { LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH }, { LANG_TROLL, 7341, SKILL_LANG_TROLL }, { LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK }, - { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI } + { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI }, + { LANG_ZOMBIE, 0, 0 } }; LanguageDesc const* GetLanguageDescByID(uint32 lang) @@ -680,15 +680,24 @@ case CHAT_MSG_MONSTER_YELL: case CHAT_MSG_MONSTER_WHISPER: case CHAT_MSG_MONSTER_EMOTE: - //case CHAT_MSG_RAID_BOSS_WHISPER: + case CHAT_MSG_RAID_BOSS_WHISPER: case CHAT_MSG_RAID_BOSS_EMOTE: *data << uint64(speaker->GetGUID()); *data << uint32(0); // 2.1.0 *data << uint32(strlen(speaker->GetName()) + 1); *data << speaker->GetName(); - break; + *data << uint64(speaker->GetGUID()); + if(speaker->GetGUID() && (GUID_HIPART(speaker->GetGUID() != HIGHGUID_PLAYER))) + { + *data << uint32(1); // string length + *data << uint8(0); // string + } + *data << uint32(messageLength); + *data << message; + *data << uint8(0); + return; default: - if (type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) + if (type != CHAT_MSG_REPLY && type != CHAT_MSG_IGNORED && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid break; } @@ -705,7 +714,7 @@ *data << uint64(target_guid); *data << uint32(messageLength); *data << message; - if(session != 0 && type != CHAT_MSG_WHISPER_INFORM && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) + if(session != 0 && type != CHAT_MSG_REPLY && type != CHAT_MSG_DND && type != CHAT_MSG_AFK) *data << uint8(session->GetPlayer()->chatTag()); else *data << uint8(0); Index: src/game/ChatHandler.cpp =================================================================== --- src/game/ChatHandler.cpp (revision 5641) +++ src/game/ChatHandler.cpp (working copy) @@ -45,6 +45,12 @@ recv_data >> type; recv_data >> lang; + if(type >= MAX_CHAT_MSG_TYPE) + { + sLog.outError("CHAT: Wrong message type received: %u", type); + return; + } + //sLog.outDebug("CHAT: packet received. type %u, lang %u", type, lang ); // prevent talking at unknown language (cheating) @@ -506,12 +512,14 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data ) { - CHECK_PACKET_SIZE(recv_data, 8); + CHECK_PACKET_SIZE(recv_data, 8+1); uint64 iguid; + uint8 unk; //sLog.outDebug("WORLD: Received CMSG_CHAT_IGNORED"); recv_data >> iguid; + recv_data >> unk; // probably related to spam reporting Player *player = objmgr.GetPlayer(iguid); if(!player || !player->GetSession()) Index: src/game/Corpse.cpp =================================================================== --- src/game/Corpse.cpp (revision 5641) +++ src/game/Corpse.cpp (working copy) @@ -64,7 +64,7 @@ bool Corpse::Create( uint32 guidlow ) { - Object::_Create(guidlow, HIGHGUID_CORPSE); + Object::_Create(guidlow, 0, HIGHGUID_CORPSE); return true; } Index: src/game/Creature.cpp =================================================================== --- src/game/Creature.cpp (revision 5641) +++ src/game/Creature.cpp (working copy) @@ -110,29 +110,17 @@ if(!spellinfo) { - sLog.outErrorDb("Trainer (Entry: %u ) have in list non existed spell %u",GetEntry(),spellid); + sLog.outErrorDb("Trainer (Entry: %u ) has non existing spell %u",GetEntry(),spellid); continue; } - if(spellinfo->Effect[0]!=SPELL_EFFECT_LEARN_SPELL) - { - sLog.outErrorDb("LoadTrainerSpells: Trainer (Entry: %u) has not learning spell(%u).", GetEntry(), spellid); - continue; - } - - if(!sSpellStore.LookupEntry(spellinfo->EffectTriggerSpell[0])) - { - sLog.outErrorDb("LoadTrainerSpells: Trainer (Entry: %u) has learning spell(%u) without triggered spell (bad dbc?).", GetEntry(), spellid); - continue; - } - if(!SpellMgr::IsSpellValid(spellinfo)) { sLog.outErrorDb("LoadTrainerSpells: Trainer (Entry: %u) has broken learning spell %u.", GetEntry(), spellid); continue; } - if(SpellMgr::IsProfessionSpell(spellinfo->EffectTriggerSpell[0])) + if(SpellMgr::IsProfessionSpell(spellinfo->Id)) m_trainer_type = 2; TrainerSpell tspell; @@ -1128,7 +1116,7 @@ return false; } - Object::_Create(guidlow, HIGHGUID_UNIT); + Object::_Create(guidlow, Entry, HIGHGUID_UNIT); m_DBTableGuid = guidlow; @@ -1155,8 +1143,8 @@ SetDisplayId(display_id); SetNativeDisplayId(display_id); - SetUInt32Value(UNIT_FIELD_BYTES_2, 1); // let creature use equiped weapon in fight - SetUInt32Value(UNIT_FIELD_BYTES_0, ( minfo->gender << 16 )); + SetByteValue(UNIT_FIELD_BYTES_2, 0, 1); // let creature use equiped weapon in fight + SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); Index: src/game/Creature.h =================================================================== --- src/game/Creature.h (revision 5641) +++ src/game/Creature.h (working copy) @@ -269,7 +269,7 @@ uint32 modelid; float bounding_radius; float combat_reach; - uint32 gender; + uint8 gender; uint32 modelid_other_gender; }; Index: src/game/DynamicObject.cpp =================================================================== --- src/game/DynamicObject.cpp (revision 5641) +++ src/game/DynamicObject.cpp (working copy) @@ -70,6 +70,7 @@ SetFloatValue( DYNAMICOBJECT_POS_X, x ); SetFloatValue( DYNAMICOBJECT_POS_Y, y ); SetFloatValue( DYNAMICOBJECT_POS_Z, z ); + SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0 m_aliveDuration = duration; m_radius = radius; Index: src/game/GameObject.cpp =================================================================== --- src/game/GameObject.cpp (revision 5641) +++ src/game/GameObject.cpp (working copy) @@ -103,7 +103,7 @@ return false; } - Object::_Create(guidlow, HIGHGUID_GAMEOBJECT); + Object::_Create(guidlow, goinfo->id, HIGHGUID_GAMEOBJECT); m_DBTableGuid = guidlow; Index: src/game/GossipDef.cpp =================================================================== --- src/game/GossipDef.cpp (revision 5641) +++ src/game/GossipDef.cpp (working copy) @@ -130,8 +130,9 @@ { WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size data << npcGUID; + data << uint32(0); // new 2.4.0 data << uint32( TitleTextId ); - data << uint32( pGossipMenu->MenuItemCount() ); + data << uint32( pGossipMenu->MenuItemCount() ); // max count 0x0F for ( unsigned int iI = 0; iI < pGossipMenu->MenuItemCount(); iI++ ) { @@ -150,7 +151,7 @@ data << gItem.m_gBoxMessage; // accept text (related to money) pop up box, 2.0.3 } - data << uint32( pQuestMenu->MenuItemCount() ); + data << uint32( pQuestMenu->MenuItemCount() ); // max count 0x20 for ( uint16 iI = 0; iI < pQuestMenu->MenuItemCount(); iI++ ) { @@ -209,13 +210,23 @@ pGossip = objmgr.GetGossipText(textID); WorldPacket data( SMSG_NPC_TEXT_UPDATE, 100 ); // guess size - data << textID; + data << textID; // can be < 0 if (!pGossip) { - data << uint32( 0 ); - data << "Greetings $N"; - data << "Greetings $N"; + for(uint32 i = 0; i < 8; ++i) + { + data << float(0); + data << "Greetings $N"; + data << "Greetings $N"; + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + } } else { @@ -274,10 +285,20 @@ void PlayerMenu::SendTalking( char const * title, char const * text ) { WorldPacket data( SMSG_NPC_TEXT_UPDATE, 50 ); // guess size - data << uint32( 0 ); - data << uint32( 0 ); - data << title; - data << text; + data << uint32(0); + for(uint32 i = 0; i < 8; ++i) + { + data << float(0); + data << title; + data << text; + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + } pSession->SendPacket( &data ); @@ -355,11 +376,11 @@ //sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u, questid-0=%u",npcGUID,fqid); } -void PlayerMenu::SendQuestGiverStatus( uint32 questStatus, uint64 npcGUID ) +void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID ) { - WorldPacket data( SMSG_QUESTGIVER_STATUS, 12 ); + WorldPacket data( SMSG_QUESTGIVER_STATUS, 9 ); data << uint64(npcGUID); - data << uint32(questStatus); + data << uint8(questStatus); pSession->SendPacket( &data ); //sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u",GUID_LOPART(npcGUID),questStatus); @@ -441,6 +462,8 @@ data << uint32(pQuest->GetRewSpell()); // casted spell + data << uint32(0); // new 2.4.0, reward title? + data << uint32(QUEST_EMOTE_COUNT); for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++) { @@ -518,6 +541,7 @@ data << uint32(0); // Honor points reward, not impelmented, and possible depricated data << uint32(pQuest->GetSrcItemId()); data << uint32(pQuest->GetFlags() & 0xFFFF); + data << uint32(0); // new 2.4.0 int iI; @@ -639,7 +663,7 @@ data << uint32(pQuest->GetRewOrReqMoney()); data << uint32(0x00); // new 2.3.0. Honor points - data << uint32(0x08); + data << uint32(0x08); // unused by client? // check if RewSpell is teaching another spell if(pQuest->GetRewSpell()) Index: src/game/GossipDef.h =================================================================== --- src/game/GossipDef.h (revision 5641) +++ src/game/GossipDef.h (working copy) @@ -180,7 +180,7 @@ /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ - void SendQuestGiverStatus( uint32 questStatus, uint64 npcGUID ); + void SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID ); void SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint64 npcGUID ); Index: src/game/Group.cpp =================================================================== --- src/game/Group.cpp (revision 5641) +++ src/game/Group.cpp (working copy) @@ -329,6 +329,7 @@ data << uint32(r.itemRandomPropId); // Item random property ID data << uint8(RollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number data << uint8(RollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll + data << uint8(0); // 2.4.0 for( Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr!=r.playerVote.end(); ++itr) { @@ -785,7 +786,7 @@ data << (uint8)m_groupType; // group type data << (uint8)(isBGGroup() ? 1 : 0); // 2.0.x, isBattleGroundGroup? data << (uint8)(citr->group); // groupid - data << (uint8)(citr->assistant?0x80:0); // 2.1.0 unk, member flags? + data << (uint8)(citr->assistant?0x01:0); // 0x2 main assist, 0x4 main tank data << uint64(0x50000000FFFFFFFELL); // related to voice chat? data << uint32(GetMembersCount()-1); for(member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) @@ -798,15 +799,17 @@ // online-state data << (uint8)(objmgr.GetPlayer(citr2->guid) ? 1 : 0); data << (uint8)(citr2->group); // groupid - data << (uint8)(citr2->assistant?0x80:0); // 2.1.0 unk, member flags? + data << (uint8)(citr2->assistant?0x01:0); // 0x2 main assist, 0x4 main tank } - data << m_leaderGuid; // leader guid - data << (uint8)m_lootMethod; // loot method - data << m_looterGuid; // looter guid - data << (uint8)m_lootThreshold; // loot threshold - data << (uint8)0; // 2.1.0 unk - + data << uint64(m_leaderGuid); // leader guid + if(GetMembersCount()-1) + { + data << (uint8)m_lootMethod; // loot method + data << (uint64)m_looterGuid; // looter guid + data << (uint8)m_lootThreshold; // loot threshold + data << (uint8)0; // 2.1.0 unk + } player->GetSession()->SendPacket( &data ); } } Index: src/game/Group.h =================================================================== --- src/game/Group.h (revision 5641) +++ src/game/Group.h (working copy) @@ -63,7 +63,7 @@ enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing - GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint8, flags + GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint16 GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint16 GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 @@ -88,7 +88,7 @@ #define GROUP_UPDATE_FLAGS_COUNT 20 // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,17,18,19 -static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 1, 2, 2, 1, 2, 2, 2, 2, 4, 8, 8, 1, 2, 2, 2, 1, 2, 2, 8}; +static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 2, 2, 2, 1, 2, 2, 2, 2, 4, 8, 8, 1, 2, 2, 2, 1, 2, 2, 8}; class Roll : public LootValidatorRef { Index: src/game/GroupHandler.cpp =================================================================== --- src/game/GroupHandler.cpp (revision 5641) +++ src/game/GroupHandler.cpp (working copy) @@ -27,6 +27,7 @@ #include "Player.h" #include "Group.h" #include "ObjectAccessor.h" +#include "SocialMgr.h" /* differeces from off: -you can uninvite yourself - is is useful @@ -87,7 +88,7 @@ } // just ignore us - if(player->HasInIgnoreList(GetPlayer()->GetGUID())) + if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); return; @@ -542,15 +543,19 @@ void WorldSession::HandleGroupPromoteOpcode( WorldPacket & recv_data ) { - CHECK_PACKET_SIZE(recv_data, 1+8); + CHECK_PACKET_SIZE(recv_data, 1+1+8); Group *group = GetPlayer()->GetGroup(); if(!group) return; - uint8 flag; + uint8 flag1, flag2; uint64 guid; - recv_data >> flag; + recv_data >> flag1 >> flag2; recv_data >> guid; + // if(flag1) Main Assist + // 0x4 + // if(flag2) Main Tank + // 0x2 /** error handling **/ if(!group->IsLeader(GetPlayer()->GetGUID())) @@ -558,10 +563,10 @@ /********************/ // everything's fine, do it - if(flag == 0) + if(flag1 == 1) + group->SetMainAssistant(guid); + if(flag2 == 1) group->SetMainTank(guid); - else if(flag == 1) - group->SetMainAssistant(guid); } void WorldSession::HandleRaidReadyCheckOpcode( WorldPacket & recv_data ) @@ -627,12 +632,12 @@ if (player) { if (player->IsPvP()) - *data << (uint8) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); + *data << (uint16) (MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else - *data << (uint8) MEMBER_STATUS_ONLINE; + *data << (uint16) MEMBER_STATUS_ONLINE; } else - *data << (uint8) MEMBER_STATUS_OFFLINE; + *data << (uint16) MEMBER_STATUS_OFFLINE; } if (mask & GROUP_UPDATE_FLAG_CUR_HP) @@ -774,7 +779,7 @@ WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 2+4+2); data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; - data << (uint8) MEMBER_STATUS_OFFLINE; + data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } @@ -790,7 +795,7 @@ Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask - data << (uint8) MEMBER_STATUS_ONLINE; // member's online status + data << (uint16) MEMBER_STATUS_ONLINE; // member's online status 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 @@ -873,3 +878,10 @@ { sLog.outDebug( "WORLD: got CMSG_GROUP_CANCEL." ); }*/ + +void WorldSession::HandleGroupPassOnLootOpcode( WorldPacket & recv_data ) +{ + sLog.outDebug("WORLD: Received CMSG_GROUP_PASS_ON_LOOT"); + sLog.outError("Not implemented!"); + recv_data.hexlike(); +} Index: src/game/Guild.cpp =================================================================== --- src/game/Guild.cpp (revision 5641) +++ src/game/Guild.cpp (working copy) @@ -25,6 +25,7 @@ #include "ObjectMgr.h" #include "Guild.h" #include "Chat.h" +#include "SocialMgr.h" Guild::Guild() { @@ -500,7 +501,7 @@ { Player *pl = ObjectAccessor::FindPlayer(MAKE_GUID(itr->first,HIGHGUID_PLAYER)); - if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_GCHATLISTEN) && !pl->HasInIgnoreList(session->GetPlayer()->GetGUID()) ) + if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_GCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()) ) pl->GetSession()->SendPacket(&data); } } @@ -517,7 +518,7 @@ Player *pl = ObjectAccessor::FindPlayer(MAKE_GUID(itr->first,HIGHGUID_PLAYER)); - if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_OFFCHATLISTEN) && !pl->HasInIgnoreList(session->GetPlayer()->GetGUID())) + if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_OFFCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow())) pl->GetSession()->SendPacket(&data); } } @@ -669,6 +670,7 @@ data << (uint32)itr->second.RankId; data << (uint8)pl->getLevel(); data << (uint8)pl->getClass(); + data << (uint8)0; // new 2.4.0 data << (uint32)pl->GetZoneId(); data << itr->second.Pnote; data << itr->second.OFFnote; @@ -681,6 +683,7 @@ data << (uint32)itr->second.RankId; data << (uint8)itr->second.level; data << (uint8)itr->second.Class; + data << (uint8)0; // new 2.4.0 data << (uint32)itr->second.zoneId; data << (float(time(NULL)-itr->second.logout_time) / DAY); data << itr->second.Pnote; @@ -993,8 +996,8 @@ m_bankloaded = true; LoadGuildBankEventLogFromDB(); - // 0 1 2 - QueryResult *result = CharacterDatabase.PQuery("SELECT TabId, TabName, TabIcon FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId", Id); + // 0 1 2 3 + QueryResult *result = CharacterDatabase.PQuery("SELECT TabId, TabName, TabIcon, TabText FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId", Id); if(!result) { purchased_tabs = 0; @@ -1012,6 +1015,7 @@ NewTab->Name = fields[1].GetCppString(); NewTab->Icon = fields[2].GetCppString(); + NewTab->Text = fields[3].GetCppString(); m_TabListMap[TabId] = NewTab; }while( result->NextRow() ); @@ -1745,3 +1749,33 @@ return EQUIP_ERR_BANK_FULL; } + +void Guild::SetGuildBankTabText(uint8 TabId, std::string text) +{ + if (TabId >= GUILD_BANK_MAX_TABS) + return; + if (TabId >= m_TabListMap.size()) + return; + if (!m_TabListMap[TabId]) + return; + + m_TabListMap[TabId]->Text = text; + + CharacterDatabase.escape_string(text); + CharacterDatabase.PExecute("UPDATE guild_bank_tab SET TabText='%s' WHERE guildid='%u' AND TabId='%u'", text.c_str(), Id, uint32(TabId)); +} + +void Guild::SendGuildBankTabText(WorldSession *session, uint8 TabId) +{ + if (TabId > GUILD_BANK_MAX_TABS) + return; + + GuildBankTab const *tab = GetBankTab(TabId); + if (!tab) + return; + + WorldPacket data(MSG_GUILD_BANK_TAB_TEXT, 1+tab->Text.size()+1); + data << uint8(TabId); + data << tab->Text; + session->SendPacket(&data); +} Index: src/game/Guild.h =================================================================== --- src/game/Guild.h (revision 5641) +++ src/game/Guild.h (working copy) @@ -52,6 +52,8 @@ GR_RIGHT_EOFFNOTE = 0x00008040, GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040, GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // Remove money withdraw capacity + // 0x40000 withdraw for repair + // 0x80000 withdraw gold? GR_RIGHT_ALL = 0x0001F1FF }; @@ -137,6 +139,7 @@ { GUILD_BANK_RIGHT_VIEW_TAB = 0x01, GUILD_BANK_RIGHT_PUT_ITEM = 0x02, + GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04, GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM, GUILD_BANK_RIGHT_FULL = 0xFF, @@ -170,6 +173,7 @@ Item* Slots[GUILD_BANK_MAX_SLOTS]; std::string Name; std::string Icon; + std::string Text; }; struct GuildItemPosCount @@ -302,6 +306,8 @@ // Tabs void DisplayGuildBankTabsInfo(WorldSession *session); void CreateNewBankTab(); + void SetGuildBankTabText(uint8 TabId, std::string text); + void SendGuildBankTabText(WorldSession *session, uint8 TabId); void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon); void CreateBankRightForTab(uint32 rankid, uint8 TabId); const GuildBankTab *GetBankTab(uint8 index) { if(index >= m_TabListMap.size()) return NULL; return m_TabListMap[index]; } Index: src/game/GuildHandler.cpp =================================================================== --- src/game/GuildHandler.cpp (revision 5641) +++ src/game/GuildHandler.cpp (working copy) @@ -26,6 +26,7 @@ #include "Guild.h" #include "MapManager.h" #include "GossipDef.h" +#include "SocialMgr.h" void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) { @@ -104,7 +105,7 @@ } // OK result but not send invite - if(player->HasInIgnoreList(GetPlayer()->GetGUID())) + if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; // not let enemies sign guild charter @@ -1758,3 +1759,41 @@ pGuild->DisplayGuildBankLogs(this, TabId); } + +void WorldSession::HandleGuildBankTabText(WorldPacket &recv_data) +{ + sLog.outDebug("WORLD: Received MSG_GUILD_BANK_TAB_INFO"); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint8 TabId; + recv_data >> TabId; + + pGuild->SendGuildBankTabText(this, TabId); +} + +void WorldSession::HandleGuildBankSetTabText(WorldPacket &recv_data) +{ + sLog.outDebug("WORLD: Received CMSG_GUILD_BANK_SET_TAB_INFO"); + + uint32 GuildId = GetPlayer()->GetGuildId(); + if (GuildId == 0) + return; + + Guild *pGuild = objmgr.GetGuildById(GuildId); + if(!pGuild) + return; + + uint8 TabId; + std::string Text; + recv_data >> TabId; + recv_data >> Text; + + pGuild->SetGuildBankTabText(TabId, Text); +} Index: src/game/Item.cpp =================================================================== --- src/game/Item.cpp (revision 5641) +++ src/game/Item.cpp (working copy) @@ -225,7 +225,7 @@ bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner) { - Object::_Create( guidlow, HIGHGUID_ITEM ); + Object::_Create( guidlow, 0, HIGHGUID_ITEM ); SetUInt32Value(OBJECT_FIELD_ENTRY, itemid); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); @@ -329,7 +329,7 @@ Field *fields = result->Fetch(); - Object::_Create(guid, HIGHGUID_ITEM); + Object::_Create(guid, 0, HIGHGUID_ITEM); if(!LoadValues(fields[0].GetString())) { Index: src/game/Item.h =================================================================== --- src/game/Item.h (revision 5641) +++ src/game/Item.h (working copy) @@ -117,6 +117,7 @@ EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78, EQUIP_ERR_CANNOT_TRADE_THAT = 79, EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80 + // probably exist more }; enum BuyFailure Index: src/game/ItemHandler.cpp =================================================================== --- src/game/ItemHandler.cpp (revision 5641) +++ src/game/ItemHandler.cpp (working copy) @@ -374,8 +374,8 @@ } data << pProto->socketBonus; data << pProto->GemProperties; - data << pProto->ExtendedCost; - data << pProto->CondExtendedCost; + //data << pProto->ExtendedCost; deleted in 0.4.0 PTR + //data << pProto->CondExtendedCost; data << pProto->RequiredDisenchantSkill; data << pProto->ArmorDamageModifier; SendPacket( &data ); @@ -655,7 +655,7 @@ uint32 ptime = time(NULL); uint32 diff; - WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*7*4) ); + WorldPacket data( SMSG_LIST_INVENTORY, (8+1+numitems*8*4) ); data << uint64(vendorguid); data << uint8(numitems); @@ -695,11 +695,12 @@ data << uint32(price); data << uint32(pProto->MaxDurability); data << uint32(pProto->BuyCount); + data << uint32(pProto->ExtendedCost); } } } - if ( count == 0 || data.size() != 8 + 1 + size_t(count) * 7 * 4 ) + if ( count == 0 || data.size() != 8 + 1 + size_t(count) * 8 * 4 ) return; data.put(8, count); @@ -757,8 +758,7 @@ { sLog.outDebug("WORLD: CMSG_BUY_BANK_SLOT"); - uint32 bank = _player->GetUInt32Value(PLAYER_BYTES_2); - uint32 slot = (bank & 0x70000) >> 16; + uint32 slot = _player->GetByteValue(PLAYER_BYTES_2, 2); // next slot ++slot; @@ -775,9 +775,7 @@ if (_player->GetMoney() < price) return; - bank = (bank & ~0x70000) + (slot << 16); - - _player->SetUInt32Value(PLAYER_BYTES_2, bank); + _player->SetByteValue(PLAYER_BYTES_2, 2, slot); _player->ModifyMoney(-int32(price)); } @@ -919,6 +917,7 @@ WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+10)); data << uint32(pProto->ItemId); data << Name; + data << uint32(pProto->InventoryType); SendPacket(&data); return; } Index: src/game/ItemPrototype.h =================================================================== --- src/game/ItemPrototype.h (revision 5641) +++ src/game/ItemPrototype.h (working copy) @@ -66,10 +66,11 @@ ITEM_SPELLTRIGGER_ON_EQUIP = 1, ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2, ITEM_SPELLTRIGGER_SOULSTONE = 4, - ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5 // no equip cooldown + ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown + ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1 }; -#define MAX_ITEM_SPELLTRIGGER 6 +#define MAX_ITEM_SPELLTRIGGER 7 enum ItemBondingType { Index: src/game/Level3.cpp =================================================================== --- src/game/Level3.cpp (revision 5641) +++ src/game/Level3.cpp (working copy) @@ -3761,9 +3761,9 @@ } // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value - player->SetUInt32Value(UNIT_FIELD_BYTES_1, player->m_form<<16 | unitfield ); + player->SetUInt32Value(UNIT_FIELD_BYTES_2, player->m_form<<24 | unitfield); - player->SetUInt32Value(UNIT_FIELD_BYTES_2, 0x2800 ); // 0x2800, 0x2801 2.0.8... + player->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0x28); player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN1); //-1 is default value @@ -4073,12 +4073,13 @@ // remove all quest entries for 'entry' from quest log for(uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot ) { - uint32 quest = player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 0); + uint32 quest = player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 0); if(quest==entry) { - player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 0, 0); - player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 1, 0); - player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 2, 0); + player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 0, 0); + player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 1, 0); + player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 2, 0); + player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 3, 0); // we ignore unequippable quest items in this case, its' still be equipped player->TakeQuestSourceItem( quest, false ); Index: src/game/Makefile.am =================================================================== --- src/game/Makefile.am (revision 5641) +++ src/game/Makefile.am (working copy) @@ -212,6 +212,8 @@ SkillExtraItems.cpp \ SkillExtraItems.h \ SpellHandler.cpp \ + SocialMgr.cpp \ + SocialMgr.h \ SpellMgr.cpp \ SpellMgr.h \ StatSystem.cpp \ Index: src/game/MiscHandler.cpp =================================================================== --- src/game/MiscHandler.cpp (revision 5641) +++ src/game/MiscHandler.cpp (working copy) @@ -39,6 +39,7 @@ #include "BattleGround.h" #include "SpellAuras.h" #include "Pet.h" +#include "SocialMgr.h" void WorldSession::HandleRepopRequestOpcode( WorldPacket & /*recv_data*/ ) { @@ -184,6 +185,7 @@ data << uint32( lvl ); // player level data << uint32( class_ ); // player class data << uint32( race ); // player race + data << uint8(0); // new 2.4.0 data << uint32( pzoneid ); // player zone id } } @@ -517,8 +519,7 @@ { sLog.outDebug( "WORLD: Received CMSG_FRIEND_LIST" ); - GetPlayer()->SendFriendlist(); - GetPlayer()->SendIgnorelist(); + _player->GetSocial()->SendSocialList(); } void WorldSession::HandleAddFriendOpcode( WorldPacket & recv_data ) @@ -528,13 +529,9 @@ sLog.outDebug( "WORLD: Received CMSG_ADD_FRIEND" ); std::string friendName = objmgr.GetMangosString(LANG_FRIEND_IGNORE_UNKNOWN,GetSessionLocaleIndex()); - uint8 friendResult = FRIEND_NOT_FOUND; - + FriendsResult friendResult = FRIEND_NOT_FOUND; Player *pFriend = NULL; uint64 friendGuid = 0; - uint32 friendArea = 0; - uint32 friendLevel = 0; - uint32 friendClass = 0; recv_data >> friendName; @@ -556,32 +553,24 @@ friendResult = FRIEND_SELF; else if(GetPlayer()->GetTeam()!=objmgr.GetPlayerTeamByGUID(friendGuid) && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND)) friendResult = FRIEND_ENEMY; - else if(GetPlayer()->HasInFriendList(friendGuid)) + else if(GetPlayer()->GetSocial()->HasFriend(GUID_LOPART(friendGuid))) friendResult = FRIEND_ALREADY; } - WorldPacket data( SMSG_FRIEND_STATUS, (1+8+1+4+4+4) ); // guess size - if (friendGuid && friendResult==FRIEND_NOT_FOUND) { if( pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer())) - { friendResult = FRIEND_ADDED_ONLINE; - friendArea = pFriend->GetZoneId(); - friendLevel = pFriend->getLevel(); - friendClass = pFriend->getClass(); - } else friendResult = FRIEND_ADDED_OFFLINE; - if(!GetPlayer()->AddToFriendList(friendGuid, friendName)) + if(!_player->GetSocial()->AddToSocialList(GUID_LOPART(friendGuid), false)) { friendResult = FRIEND_LIST_FULL; sLog.outDebug( "WORLD: %s's friend list is full.", GetPlayer()->GetName()); } - sLog.outDebug( "WORLD: %s Guid found '%u' area:%u Level:%u Class:%u.", - friendName.c_str(), GUID_LOPART(friendGuid), friendArea, friendLevel, friendClass); + sLog.outDebug( "WORLD: %s Guid found '%u'.", friendName.c_str(), GUID_LOPART(friendGuid)); } else if(friendResult==FRIEND_ALREADY) { @@ -596,12 +585,8 @@ sLog.outDebug( "WORLD: %s Guid not found.", friendName.c_str() ); } - data << (uint8)friendResult << (uint64)friendGuid << (uint8)0; - if(friendResult == FRIEND_ADDED_ONLINE) - data << (uint32)friendArea << (uint32)friendLevel << (uint32)friendClass; + sSocialMgr.SendFriendStatus(GetPlayer(), friendResult, GUID_LOPART(friendGuid), friendName, false); - SendPacket( &data ); - sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" ); } @@ -610,17 +595,14 @@ CHECK_PACKET_SIZE(recv_data, 8); uint64 FriendGUID; - uint8 FriendResult = FRIEND_REMOVED; sLog.outDebug( "WORLD: Received CMSG_DEL_FRIEND" ); recv_data >> FriendGUID; - GetPlayer()->RemoveFromFriendList(FriendGUID); + _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(FriendGUID), false); - WorldPacket data( SMSG_FRIEND_STATUS, 9 ); - data << (uint8)FriendResult << (uint64)FriendGUID; - SendPacket( &data ); + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_REMOVED, GUID_LOPART(FriendGUID), "", false); sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" ); } @@ -632,7 +614,7 @@ sLog.outDebug( "WORLD: Received CMSG_ADD_IGNORE" ); std::string IgnoreName = objmgr.GetMangosString(LANG_FRIEND_IGNORE_UNKNOWN,GetSessionLocaleIndex()); - unsigned char ignoreResult = FRIEND_IGNORE_NOT_FOUND; + FriendsResult ignoreResult = FRIEND_IGNORE_NOT_FOUND; uint64 IgnoreGuid = 0; recv_data >> IgnoreName; @@ -641,6 +623,7 @@ return; normalizePlayerName(IgnoreName); + CharacterDatabase.escape_string(IgnoreName); // prevent SQL injection - normal name don't must changed by this call sLog.outDebug( "WORLD: %s asked to Ignore: '%s'", GetPlayer()->GetName(), IgnoreName.c_str() ); @@ -653,18 +636,16 @@ ignoreResult = FRIEND_IGNORE_SELF; else { - if( GetPlayer()->HasInIgnoreList(IgnoreGuid) ) + if( GetPlayer()->GetSocial()->HasIgnore(GUID_LOPART(IgnoreGuid)) ) ignoreResult = FRIEND_IGNORE_ALREADY; } } - WorldPacket data( SMSG_FRIEND_STATUS, 9 ); - if (IgnoreGuid && ignoreResult == FRIEND_IGNORE_NOT_FOUND) { ignoreResult = FRIEND_IGNORE_ADDED; - GetPlayer()->AddToIgnoreList(IgnoreGuid, IgnoreName); + _player->GetSocial()->AddToSocialList(GUID_LOPART(IgnoreGuid), true); } else if(ignoreResult==FRIEND_IGNORE_ALREADY) { @@ -679,9 +660,8 @@ sLog.outDebug( "WORLD: %s Guid not found.", IgnoreName.c_str() ); } - data << (uint8)ignoreResult << (uint64)IgnoreGuid; + sSocialMgr.SendFriendStatus(GetPlayer(), ignoreResult, GUID_LOPART(IgnoreGuid), "", false); - SendPacket( &data ); sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_STATUS)" ); } @@ -695,19 +675,23 @@ recv_data >> IgnoreGUID; - unsigned char IgnoreResult = FRIEND_IGNORE_REMOVED; + _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(IgnoreGUID), true); - WorldPacket data( SMSG_FRIEND_STATUS, 9 ); + sSocialMgr.SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, GUID_LOPART(IgnoreGUID), "", false); - data << (uint8)IgnoreResult << (uint64)IgnoreGUID; - - GetPlayer()->RemoveFromIgnoreList(IgnoreGUID); - - SendPacket( &data ); - sLog.outDebug( "WORLD: Sent motd (SMSG_FRIEND_STATUS)" ); } +void WorldSession::HandleSetFriendNoteOpcode( WorldPacket & recv_data ) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + uint64 guid; + std::string note; + recv_data >> guid >> note; + CharacterDatabase.escape_string(note); + _player->GetSocial()->SetFriendNote(guid, note); +} + void WorldSession::HandleBugOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,4+4+1+4+1); @@ -1181,7 +1165,9 @@ return; uint32 talent_points = 0x3D; + uint32 guid_size = plr->GetPackGUID().size(); WorldPacket data(SMSG_INSPECT_TALENTS, 4+talent_points); + data.append(plr->GetPackGUID()); data << uint32(talent_points); // fill by 0 talents array @@ -1241,9 +1227,9 @@ uint32 curtalent_rank_offset = curtalent_rank_index2 % 8; // apply mask - uint32 val = data.read(4 + curtalent_rank_slot); + uint32 val = data.read(guid_size + 4 + curtalent_rank_slot); val |= (1 << curtalent_rank_offset); - data.put(4 + curtalent_rank_slot,val & 0xFF); + data.put(guid_size + 4 + curtalent_rank_slot, val & 0xFF); } talentTabPos += GetTalentTabInspectBitSize(talentTabId); Index: src/game/NPCHandler.cpp =================================================================== --- src/game/NPCHandler.cpp (revision 5641) +++ src/game/NPCHandler.cpp (working copy) @@ -160,12 +160,12 @@ uint32 count = 0; for(Creature::SpellsList::const_iterator itr = trainer_spells.begin(); itr != trainer_spells.end(); ++itr) { - if(!_player->IsSpellFitByClassAndRace(itr->spell->EffectTriggerSpell[0])) + if(!_player->IsSpellFitByClassAndRace(itr->spell->Id)) continue; ++count; - bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(itr->spell->EffectTriggerSpell[0]); + bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(itr->spell->Id); data << uint32(itr->spell->Id); data << uint8(_player->GetTrainerSpellState(&*itr)); @@ -176,7 +176,7 @@ data << uint8(itr->reqlevel ? itr->reqlevel : itr->spell->spellLevel); data << uint32(itr->reqskill); data << uint32(itr->reqskillvalue); - data << uint32(spellmgr.GetPrevSpellInChain(itr->spell->EffectTriggerSpell[0])); + data << uint32(spellmgr.GetPrevSpellInChain(itr->spell->Id)); data << uint32(0); data << uint32(0); } @@ -242,31 +242,33 @@ if(_player->GetMoney() < nSpellCost ) return; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(trainer_spell->spell->EffectTriggerSpell[0]); + WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer + data << uint64(guid) << uint32(0xB3); + SendPacket(&data); - WorldPacket data( SMSG_TRAINER_BUY_SUCCEEDED, 12 ); - data << guid << spellId; - SendPacket( &data ); + data.Initialize(SMSG_OBSOLETE, 12); // visual effect on player + data << uint64(_player->GetGUID()) << uint32(0x016A); + SendPacket(&data); _player->ModifyMoney( -int32(nSpellCost) ); - if(spellInfo->powerType == 2) + if(trainer_spell->spell->powerType == 2) { _player->addSpell(spellId,4); // active = 4 for spell book of hunter's pet return; } - // learn explicitly to prevent lost money at lags, learning spell will be only show spell anumation - _player->learnSpell(spellInfo->Id); + // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation + _player->learnSpell(trainer_spell->spell->Id); - Unit* caster = (trainer_spell->spell->SpellVisual == 222) ? (Unit*)_player : (Unit*)unit; + data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12); + data << uint64(guid) << uint32(spellId); + SendPacket(&data); // trainer always see at customer in time of training (part of client functionality) float u_oprientation = unit->GetOrientation(); unit->SetInFront(_player); - caster->CastSpell(_player,trainer_spell->spell,false); - // trainer always return to original orientation unit->Relocate(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),u_oprientation); } Index: src/game/Object.cpp =================================================================== --- src/game/Object.cpp (revision 5641) +++ src/game/Object.cpp (working copy) @@ -109,12 +109,12 @@ m_objectUpdated = false; } -void Object::_Create( uint32 guidlow, HighGuid guidhigh ) +void Object::_Create( uint32 guidlow, uint32 entry, HighGuid guidhigh ) { if(!m_uint32Values) _InitValues(); - SetUInt32Value( OBJECT_FIELD_GUID, guidlow ); - SetUInt32Value( OBJECT_FIELD_GUID+1, guidhigh ); + uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh); // required more changes to make it working + SetUInt64Value( OBJECT_FIELD_GUID, guid ); SetUInt32Value( OBJECT_FIELD_TYPE, m_objectType ); m_PackGUID.clear(); m_PackGUID.appendPackGUID(GetGUID()); @@ -174,6 +174,9 @@ case GAMEOBJECT_TYPE_FLAGDROP: updatetype = UPDATETYPE_CREATE_OBJECT2; break; + case GAMEOBJECT_TYPE_TRANSPORT: + flags |= UPDATEFLAG_TRANSPORT; + break; } } } @@ -301,7 +304,7 @@ if (flags & UPDATEFLAG_HASPOSITION) { // 0x02 - if(flags & UPDATEFLAG_TRANSPORT) + if(flags & UPDATEFLAG_TRANSPORT && m_uint32Values[GAMEOBJECT_TYPE_ID] == GAMEOBJECT_TYPE_MO_TRANSPORT) { *data << (float)0; *data << (float)0; @@ -776,6 +779,32 @@ } } +void Object::SetByteValue( uint16 index, uint8 offset, uint8 value ) +{ + ASSERT( index < m_valuesCount || PrintIndexError( index , true ) ); + + if(offset > 4) + { + sLog.outError("Object::SetByteValue: wrong offset %u", offset); + return; + } + + if(uint8(m_uint32Values[ index ] >> (offset * 8)) != value) + { + m_uint32Values[ index ] &= ~uint32(uint32(0xFF) << (offset * 8)); + m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 8)); + + if(m_inWorld) + { + if(!m_objectUpdated) + { + ObjectAccessor::Instance().AddUpdateObject(this); + m_objectUpdated = true; + } + } + } +} + void Object::SetStatFloatValue( uint16 index, float value) { if(value < 0) @@ -896,7 +925,7 @@ void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, float x, float y, float z, float ang ) { - Object::_Create(guidlow, guidhigh); + Object::_Create(guidlow, 0, guidhigh); m_mapId = mapid; m_positionX = x; Index: src/game/Object.h =================================================================== --- src/game/Object.h (revision 5641) +++ src/game/Object.h (working copy) @@ -115,8 +115,9 @@ } const uint64& GetGUID() const { return GetUInt64Value(0); } - const uint32& GetGUIDLow() const { return GetUInt32Value(0); } - const uint32& GetGUIDHigh() const { return GetUInt32Value(1); } + uint32 GetGUIDLow() const { return GUID_LOPART(GetUInt64Value(0)); } + uint32 GetGUIDMid() const { return GUID_ENPART(GetUInt64Value(0)); } + uint32 GetGUIDHigh() const { return GUID_HIPART(GetUInt64Value(0)); } const ByteBuffer& GetPackGUID() const { return m_PackGUID; } uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); } @@ -157,10 +158,18 @@ return m_floatValues[ index ]; } + const uint8& GetByteValue( uint16 index, uint8 offset) const + { + ASSERT( index < m_valuesCount || PrintIndexError( index , false) ); + ASSERT( offset < 4 ); + return *(((uint8*)&m_uint32Values[ index ])+offset); + } + void SetInt32Value( uint16 index, int32 value ); void SetUInt32Value( uint16 index, uint32 value ); void SetUInt64Value( uint16 index, const uint64 &value ); void SetFloatValue( uint16 index, float value ); + void SetByteValue( uint16 index, uint8 offset, uint8 value ); void SetStatFloatValue( uint16 index, float value); void SetStatInt32Value( uint16 index, int32 value); @@ -215,7 +224,7 @@ Object ( ); void _InitValues(); - void _Create (uint32 guidlow, HighGuid guidhigh); + void _Create (uint32 guidlow, uint32 entry, HighGuid guidhigh); virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const; Index: src/game/ObjectDefines.h =================================================================== --- src/game/ObjectDefines.h (revision 5641) +++ src/game/ObjectDefines.h (working copy) @@ -23,21 +23,28 @@ enum HighGuid { - HIGHGUID_ITEM = 0x40000000, // blizz 40000000 - HIGHGUID_CONTAINER = 0x40000000, // blizz 40000000 - HIGHGUID_PLAYER = 0x00000000, // blizz 00000000 - HIGHGUID_GAMEOBJECT = 0xF0060000, // blizz F0090000 - HIGHGUID_TRANSPORT = 0x1FA70000, // blizz 1FA70000 (type 11) - HIGHGUID_UNIT = 0xF0070000, // blizz F009????, where "????" is unit entry - HIGHGUID_DYNAMICOBJECT = 0xF00A0000, // blizz F0090000, F0320000 - HIGHGUID_CORPSE = 0xF0090000, // blizz F0090000, F0320000 - HIGHGUID_MO_TRANSPORT = 0x1FC00000, // blizz 1FC00000 (type 15) + HIGHGUID_ITEM = 0x4000, // blizz 4000 + HIGHGUID_CONTAINER = 0x4000, // blizz 4000 + HIGHGUID_PLAYER = 0x0000, // blizz 0000 + HIGHGUID_GAMEOBJECT = 0xF110, // blizz F110 + HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) + HIGHGUID_UNIT = 0xF130, // blizz F130 + HIGHGUID_PET = 0xF140, // blizz F140 + HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100 + HIGHGUID_CORPSE = 0xF101, // blizz F100 + HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) }; -#define GUID_HIPART(x) (uint32)(uint64(x) >> 32) -#define GUID_LOPART(x) (uint32)(uint64(x) & 0xFFFFFFFFULL) +#define GUID_HIPART(x) (uint32)((uint64(x) >> 48) & 0x0000FFFF) +#define GUID_ENPART(x) (uint32)((uint64(x) >> 24) & 0x00FFFFFF) +#define GUID_LOPART(x) (uint32)(uint64(x) & 0x00FFFFFF) #define MAKE_GUID(l, h) uint64( uint32(l) | ( uint64(h) << 32 ) ) +// l - OBJECT_FIELD_GUID +// e - OBJECT_FIELD_ENTRY for GO (except GAMEOBJECT_TYPE_MO_TRANSPORT) and creatures or UNIT_FIELD_PETNUMBER for pets +// h - OBJECT_FIELD_GUID + 1 +#define MAKE_NEW_GUID(l, e, h) uint64( uint64(l) | ( uint64(e) << 24 ) | ( uint64(h) << 48 ) ) + #define IS_EMPTY_GUID(Guid) ( Guid == 0 ) #define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT ) Index: src/game/ObjectMgr.cpp =================================================================== --- src/game/ObjectMgr.cpp (revision 5641) +++ src/game/ObjectMgr.cpp (working copy) @@ -1271,26 +1271,92 @@ } } - for (int j = 0; j < 5; j++) + // special format + if(proto->Spells[0].SpellId == SPELL_GENERIC_LEARN) { - if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER) + // spell_1 + if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) { - sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger); - const_cast(proto)->Spells[j].SpellId = 0; - const_cast(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format",i,0+1,proto->Spells[0].SpellTrigger); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; } - else if(proto->Spells[j].SpellId) + + // spell_2 have learning spell + if(proto->Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID) { - SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[j].SpellId); + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.",i,1+1,proto->Spells[1].SpellTrigger); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + else if(!proto->Spells[1].SpellId) + { + sLog.outErrorDb("Item (Entry: %u) not has expected spell in spellid_%d in special learning format.",i,1+1); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + else + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[1].SpellId); if(!spellInfo) { - sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId); + sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId); + const_cast(proto)->Spells[0].SpellId = 0; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + // allowed only in special format + else if(proto->Spells[1].SpellId==SPELL_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; + const_cast(proto)->Spells[1].SpellId = 0; + const_cast(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + } + + // spell_3*,spell_4*,spell_5* is empty + for (int j = 2; j < 5; j++) + { + if(proto->Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) + { + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger); const_cast(proto)->Spells[j].SpellId = 0; + const_cast(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; } - else + else if(proto->Spells[j].SpellId != 0) { - if(!SpellMgr::IsSpellValid(spellInfo)) + sLog.outErrorDb("Item (Entry: %u) has wrong spell in spellid_%d (%u) for learning special format",i,j+1,proto->Spells[j].SpellId); + const_cast(proto)->Spells[j].SpellId = 0; + } + } + } + // normal spell list + else + { + for (int j = 0; j < 5; j++) + { + if(proto->Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID) + { + sLog.outErrorDb("Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)",i,j+1,proto->Spells[j].SpellTrigger); + const_cast(proto)->Spells[j].SpellId = 0; + const_cast(proto)->Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; + } + + if(proto->Spells[j].SpellId) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[j].SpellId); + if(!spellInfo) { + sLog.outErrorDb("Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId); + const_cast(proto)->Spells[j].SpellId = 0; + } + // allowed only in special format + else if(proto->Spells[j].SpellId==SPELL_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; } @@ -1298,6 +1364,7 @@ } } + if(proto->Bonding >= MAX_BIND_TYPE) sLog.outErrorDb("Item (Entry: %u) has wrong Bonding value (%u)",i,proto->Bonding); Index: src/game/Opcodes.cpp =================================================================== --- src/game/Opcodes.cpp (revision 5641) +++ src/game/Opcodes.cpp (working copy) @@ -1053,7 +1053,35 @@ "MSG_GUILD_INFO_LOG", // MSG_GUILD_INFO_LOG "MSG_UNKNOWN_1023", // MSG_UNKNOWN_1023 "CMSG_UNKNOWN_1024", // CMSG_UNKNOWN_1024 - "SMSG_UNKNOWN_1025", // SMSG_UNKNOWN_1025 - //there would be declared new opcode, id 1026 + "SMSG_MIRRORIMAGE_DATA", // SMSG_UNKNOWN_1025 + "SMSG_FORCE_DISPLAY_UPDATE", // SMSG_UNKNOWN_1026 + "UMSG_UNKNOWN_1027", // SMSG_UNKNOWN_1027 + "UMSG_UNKNOWN_1028", // SMSG_UNKNOWN_1028 + "UMSG_UNKNOWN_1029", // SMSG_UNKNOWN_1029 + "UMSG_UNKNOWN_1030", // SMSG_UNKNOWN_1030 + "UMSG_UNKNOWN_1031", // SMSG_UNKNOWN_1031 + "UMSG_UNKNOWN_1032", // SMSG_UNKNOWN_1032 + "UMSG_UNKNOWN_1033", // SMSG_UNKNOWN_1033 + "UMSG_UNKNOWN_1034", // SMSG_UNKNOWN_1034 + "UMSG_UNKNOWN_1035", // SMSG_UNKNOWN_1035 + "UMSG_UNKNOWN_1036", // SMSG_UNKNOWN_1036 + "UMSG_UNKNOWN_1037", // SMSG_UNKNOWN_1037 + "UMSG_UNKNOWN_1038", // SMSG_UNKNOWN_1038 + "UMSG_UNKNOWN_1039", // SMSG_UNKNOWN_1039 + "UMSG_UNKNOWN_1040", // SMSG_UNKNOWN_1040 + "UMSG_UNKNOWN_1041", // SMSG_UNKNOWN_1041 + "UMSG_UNKNOWN_1042", // SMSG_UNKNOWN_1042 + "UMSG_UNKNOWN_1043", // SMSG_UNKNOWN_1043 + "UMSG_UNKNOWN_1044", // SMSG_UNKNOWN_1044 + "UMSG_UNKNOWN_1045", // SMSG_UNKNOWN_1045 + "UMSG_UNKNOWN_1046", // SMSG_UNKNOWN_1046 + "UMSG_UNKNOWN_1047", // SMSG_UNKNOWN_1047 + "UMSG_UNKNOWN_1048", // SMSG_UNKNOWN_1048 + "UMSG_UNKNOWN_1049", // SMSG_UNKNOWN_1049 + "UMSG_UNKNOWN_1050", // SMSG_UNKNOWN_1050 + "UMSG_UNKNOWN_1051", // SMSG_UNKNOWN_1051 + "UMSG_UNKNOWN_1052", // SMSG_UNKNOWN_1052 + "UMSG_UNKNOWN_1053", // SMSG_UNKNOWN_1053 + //there would be declared new opcode, id 1054 //do not forget to change MAX_OPCODE_ID, if you add a line here! }; Index: src/game/Opcodes.h =================================================================== --- src/game/Opcodes.h (revision 5641) +++ src/game/Opcodes.h (working copy) @@ -55,15 +55,15 @@ CMSG_FORCEACTION = 24, CMSG_FORCEACTIONONOTHER = 25, CMSG_FORCEACTIONSHOW = 26, - SMSG_FORCEACTIONSHOW = 27, + SMSG_FORCEACTIONSHOW = 27, // uint32, uint32 SMSG_ATTACKERSTATEUPDATEDEBUGINFO_OBSOLETE = 28, - SMSG_DEBUGINFOSPELL_OBSOLETE = 29, + SMSG_DEBUGINFOSPELL_OBSOLETE = 29, // uint8, pet god mode SMSG_DEBUGINFOSPELLMISS_OBSOLETE = 30, SMSG_DEBUG_PLAYER_RANGE_OBSOLETE = 31, CMSG_UNDRESSPLAYER = 32, CMSG_BEASTMASTER = 33, CMSG_GODMODE = 34, - SMSG_GODMODE = 35, + SMSG_GODMODE = 35, // uint8, god mode CMSG_CHEAT_SETMONEY = 36, CMSG_LEVEL_CHEAT = 37, CMSG_PET_LEVEL_CHEAT = 38, @@ -135,24 +135,24 @@ SMSG_FRIEND_STATUS = 104, CMSG_ADD_FRIEND = 105, CMSG_DEL_FRIEND = 106, - SMSG_IGNORE_LIST = 107, + CMSG_FRIEND_SET_NOTE = 107, CMSG_ADD_IGNORE = 108, CMSG_DEL_IGNORE = 109, CMSG_GROUP_INVITE = 110, - SMSG_GROUP_INVITE = 111, + SMSG_GROUP_INVITE = 111, // string CMSG_GROUP_CANCEL = 112, - SMSG_GROUP_CANCEL = 113, + SMSG_GROUP_CANCEL = 113, // string CMSG_GROUP_ACCEPT = 114, CMSG_GROUP_DECLINE = 115, - SMSG_GROUP_DECLINE = 116, + SMSG_GROUP_DECLINE = 116, // string CMSG_GROUP_UNINVITE = 117, CMSG_GROUP_UNINVITE_GUID = 118, - SMSG_GROUP_UNINVITE = 119, + SMSG_GROUP_UNINVITE = 119, // empty CMSG_GROUP_SET_LEADER = 120, - SMSG_GROUP_SET_LEADER = 121, + SMSG_GROUP_SET_LEADER = 121, // string CMSG_LOOT_METHOD = 122, CMSG_GROUP_DISBAND = 123, - SMSG_GROUP_DESTROYED = 124, + SMSG_GROUP_DESTROYED = 124, // empty SMSG_GROUP_LIST = 125, SMSG_PARTY_MEMBER_STATS = 126, SMSG_PARTY_COMMAND_RESULT = 127, @@ -303,7 +303,7 @@ CMSG_DROP_ITEM = 272, CMSG_DESTROYITEM = 273, SMSG_INVENTORY_CHANGE_FAILURE = 274, - SMSG_OPEN_CONTAINER = 275, + SMSG_OPEN_CONTAINER = 275, // uint64 CMSG_INSPECT = 276, SMSG_INSPECT = 277, CMSG_INITIATE_TRADE = 278, @@ -371,7 +371,7 @@ CMSG_SETDEATHBINDPOINT = 340, SMSG_BINDPOINTUPDATE = 341, CMSG_GETDEATHBINDZONE = 342, - SMSG_BINDZONEREPLY = 343, + SMSG_BINDZONEREPLY = 343, // uint32, uint32 SMSG_PLAYERBOUND = 344, SMSG_DEATH_NOTIFY_OBSOLETE = 345, CMSG_REPOP_REQUEST = 346, @@ -384,7 +384,7 @@ SMSG_LOOT_RELEASE_RESPONSE = 353, SMSG_LOOT_REMOVED = 354, SMSG_LOOT_MONEY_NOTIFY = 355, - SMSG_LOOT_ITEM_NOTIFY = 356, + SMSG_LOOT_ITEM_NOTIFY = 356, // uint64, uint8, uint8, uint32, string SMSG_LOOT_CLEAR_MONEY = 357, SMSG_ITEM_PUSH_RESULT = 358, SMSG_DUEL_REQUESTED = 359, @@ -394,8 +394,8 @@ SMSG_DUEL_WINNER = 363, CMSG_DUEL_ACCEPTED = 364, CMSG_DUEL_CANCELLED = 365, - SMSG_MOUNTRESULT = 366, // 0 - can't mount that unit, 1 - mount too far away, 2 - already mounted, 3 - that unit can't be mounted, 4 - that mount is not our pet, 5 - unknown mount error, 6 - can't mount while looting, 7 - cant mount because your race, 8 - shapeshifted, 9 - you dismount before continuing - SMSG_DISMOUNTRESULT = 367, // 0 - int err, don't have pet to dismount, 1 - not mounted, 2 - int err, dismounting a non-pet + SMSG_MOUNTRESULT = 366, // uint32, 0 - can't mount that unit, 1 - mount too far away, 2 - already mounted, 3 - that unit can't be mounted, 4 - that mount is not our pet, 5 - unknown mount error, 6 - can't mount while looting, 7 - cant mount because your race, 8 - shapeshifted, 9 - you dismount before continuing + SMSG_DISMOUNTRESULT = 367, // uint32, 0 - int err, don't have pet to dismount, 1 - not mounted, 2 - int err, dismounting a non-pet SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 368, CMSG_MOUNTSPECIAL_ANIM = 369, SMSG_MOUNTSPECIAL_ANIM = 370, @@ -434,13 +434,13 @@ CMSG_QUESTLOG_SWAP_QUEST = 403, CMSG_QUESTLOG_REMOVE_QUEST = 404, SMSG_QUESTLOG_FULL = 405, - SMSG_QUESTUPDATE_FAILED = 406, - SMSG_QUESTUPDATE_FAILEDTIMER = 407, - SMSG_QUESTUPDATE_COMPLETE = 408, - SMSG_QUESTUPDATE_ADD_KILL = 409, - SMSG_QUESTUPDATE_ADD_ITEM = 410, + SMSG_QUESTUPDATE_FAILED = 406, // uint32 + SMSG_QUESTUPDATE_FAILEDTIMER = 407, // uint32 + SMSG_QUESTUPDATE_COMPLETE = 408, // uint32 + SMSG_QUESTUPDATE_ADD_KILL = 409, // uint32, uint32, uint32, uint32, uint64 + SMSG_QUESTUPDATE_ADD_ITEM = 410, // unused (client has if(opcode == 410) return; in opcode handler) CMSG_QUEST_CONFIRM_ACCEPT = 411, - SMSG_QUEST_CONFIRM_ACCEPT = 412, + SMSG_QUEST_CONFIRM_ACCEPT = 412, // uint32, string, uint64 CMSG_PUSHQUESTTOPARTY = 413, CMSG_LIST_INVENTORY = 414, SMSG_LIST_INVENTORY = 415, @@ -470,7 +470,7 @@ CMSG_BANKER_ACTIVATE = 439, SMSG_SHOW_BANK = 440, CMSG_BUY_BANK_SLOT = 441, - SMSG_BUY_BANK_SLOT_RESULT = 442, + SMSG_BUY_BANK_SLOT_RESULT = 442, // uint32 CMSG_PETITION_SHOWLIST = 443, SMSG_PETITION_SHOWLIST = 444, CMSG_PETITION_BUY = 445, @@ -565,7 +565,7 @@ MSG_CORPSE_QUERY = 534, CMSG_GMTICKET_DELETETICKET = 535, SMSG_GMTICKET_DELETETICKET = 536, - SMSG_CHAT_WRONG_FACTION = 537, // You can only whisper to the members of your alliance. + SMSG_CHAT_WRONG_FACTION = 537, // empty, You can only whisper to the members of your alliance. CMSG_GMTICKET_SYSTEMSTATUS = 538, SMSG_GMTICKET_SYSTEMSTATUS = 539, CMSG_SPIRIT_HEALER_ACTIVATE = 540, @@ -638,7 +638,7 @@ SMSG_AUCTION_OWNER_NOTIFICATION = 607, SMSG_PROCRESIST = 608, SMSG_STANDSTATE_CHANGE_FAILURE = 609, - SMSG_DISPEL_FAILED = 610, + SMSG_DISPEL_FAILED = 610, // uint64, uint64, uint32, uint32 (for?) SMSG_SPELLORDAMAGE_IMMUNE = 611, CMSG_AUCTION_LIST_BIDDER_ITEMS = 612, SMSG_AUCTION_BIDDER_LIST_RESULT = 613, @@ -663,7 +663,7 @@ SMSG_PLAY_OBJECT_SOUND = 632, CMSG_REQUEST_PET_INFO = 633, CMSG_FAR_SIGHT = 634, - SMSG_SPELLDISPELLOG = 635, + SMSG_SPELLDISPELLOG = 635, // pguid, pguid, uint32, uint8, uint32 count, for(count) { uint32; uint8; } SMSG_DAMAGE_CALC_LOG = 636, CMSG_ENABLE_DAMAGE_LOG = 637, CMSG_GROUP_CHANGE_SUB_GROUP = 638, @@ -704,7 +704,7 @@ SMSG_LOOT_START_ROLL = 673, SMSG_LOOT_ROLL = 674, CMSG_LOOT_MASTER_GIVE = 675, - SMSG_LOOT_MASTER_LIST = 676, + SMSG_LOOT_MASTER_LIST = 676, // uint8 count, for(count) { uint64; } SMSG_SET_FORCED_REACTIONS = 677, SMSG_SPELL_FAILED_OTHER = 678, SMSG_GAMEOBJECT_RESET_STATE = 679, // uint64 guid @@ -715,7 +715,7 @@ CMSG_SUMMON_RESPONSE = 684, MSG_MOVE_TOGGLE_GRAVITY_CHEAT = 685, SMSG_MONSTER_MOVE_TRANSPORT = 686, - SMSG_PET_BROKEN = 687, // Your pet has run away (:D) + SMSG_PET_BROKEN = 687, // empty?, Your pet has run away MSG_MOVE_FEATHER_FALL = 688, MSG_MOVE_WATER_WALK = 689, CMSG_SERVER_BROADCAST = 690, @@ -793,7 +793,7 @@ SMSG_INSTANCE_RESET_SCHEDULED = 762, // WARNING! %s is scheduled to reset in %u minutes! and other messages... SMSG_COMPRESSED_MOVE = 763, CMSG_GUILD_CHANGEINFO = 764, - SMSG_TRIAL_RESTRICTED = 765, // Trial accounts cannot send unlimited tells, you must wait before you can send tells to more players. + SMSG_TRIAL_RESTRICTED = 765, // uint8, Trial accounts cannot send unlimited tells, you must wait before you can send tells to more players. SMSG_SET_MOVE_SPEED = 766, // GUID + float speed, move speed, except swim/turn/fly SMSG_SET_RUN_BACK_SPEED = 767, // GUID + float speed, run back speed SMSG_SET_SWIM_SPEED = 768, // GUID + float speed, swim and swim back speed @@ -830,7 +830,7 @@ SMSG_RESET_INSTANCES_FAILED = 799, // uint32 reason, uint32 mapid SMSG_UNKNOWN_800 = 800, // uint32 mapid, instance related (save?) MSG_RAID_ICON_TARGET = 801, // uint8+uint8+uint64 guid or only uint8(0x01) - MSG_RAID_READY_CHECK = 802, // uint64+uint8 + MSG_RAID_READY_CHECK = 802, // uint64(server) or empty(client) // 803 not exist? SMSG_PET_ACTION_SOUND = 804, // GUID + uint32, looks like SMSG_AI_REACTION (pet action sound?) SMSG_PET_DISMISS_SOUND = 805, // uint32 unk + x, y, z (pet dismiss sound?) @@ -841,11 +841,11 @@ CMSG_GM_SURVEY_RESULTS = 810, // script function named GMSurveySubmit() SMSG_UNKNOWN_811 = 811, // uint32, 0x0, SMSG_INSTANCE_RESET_ACTIVATE ? SMSG_UNKNOWN_812 = 812, - // 813 not exist? + SMSG_UNKNOWN_813 = 813, // string // 814 not exist? SMSG_SPELL_INSTA_KILL_SELF = 815, // spell related, uint64 guid + spellid (You are killed by %s(spell_name)) SMSG_UNKNOWN_816 = 816, // spell related, uint64 guid + spellid + uint32 count + for(count) uint64 guid (target?) - CMSG_UNKNOWN_817 = 817, + CMSG_UNKNOWN_817 = 817, // response to chat message with type 7 in some case SMSG_ANTISPAM = 818, // 2.0.8, received before server MOTD, strange regexp sequence, looks like anti spam filter for chat messages... SMSG_UNKNOWN_819 = 819, // pGUID, pGUID, uint32 unk1, uint8 unk2, uint32 count, for(count) {uint32; if(unk2) {uint32; uint32}} // 820 not exist? @@ -918,7 +918,7 @@ MSG_INSPECT_ARENA_STATS = 887, SMSG_SH_POSITION = 888, // spirit healer position, map/x/y/z, at player death... CMSG_CANCEL_TEMP_ITEM_ENCHANTMENT = 889, // cancel temporary item enchantment - SMSG_UNKNOWN_890 = 890, + SMSG_UNKNOWN_890 = 890, // empty // 891 not exist? // 892 not exist? // 893 not exist? @@ -954,8 +954,8 @@ SMSG_UNKNOWN_923 = 923, // uint8 count, for(count) uint32 // 924 not exist? SMSG_SET_COMBO_POINTS = 925, // set combo points - SMSG_VOICE_SESSION = 926, - SMSG_UNKNOWN_927 = 927, // uint64 guid + uint32 + float?, received after leave voice channel + SMSG_VOICE_SESSION = 926, // VoiceSessionRosterUpdate, uint64, uint16, uint8, string, string, uint32, uin16, uint8 unk, uint64, uint8, uint8, if(unk-1) { for(unk-1) { uint64; uint8; uint8; uint8; } } + SMSG_UNKNOWN_927 = 927, // uint64 guid + uint64, received after leave voice channel // 928 not exist? // 929 not exist? SMSG_UNKNOWN_930 = 930, // uint64 + uint8 @@ -970,9 +970,9 @@ // 939 not exist? SMSG_UNKNOWN_940 = 940, // packed guid (received at spell cast) SMSG_UNKNOWN_941 = 941, // teleport/movement opcode - SMSG_READY_CHECK_ALL_READY = 942, // Everyone is Ready! (message) + SMSG_READY_CHECK_ALL_READY = 942, // uint64, uint8, Everyone is Ready! (message) CMSG_VOICE_SETTINGS = 943, // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled (id correct for 2.3.0) - SMSG_VOICE_CHAT_PARENTAL_DISABLE_ALL = 944, // Voice chat has been disabled by parental control + SMSG_VOICE_CHAT_PARENTAL_DISABLE_ALL = 944, // uint8, uint8, Voice chat has been disabled by parental control // 945 not exist? SMSG_UNKNOWN_946 = 946, // special chat packet? // 947 not exist? @@ -988,14 +988,14 @@ CMSG_COMMENTATOR_ADD_OR_REMOVE_PLAYER = 957, SMSG_UNKNOWN_958 = 958, // uint64 guid, cause client to send CMSG_SET_SELECTION CMSG_UNKNOWN_959 = 959, // uint8, uint8, uint8, string - SMSG_UNKNOWN_960 = 960, // uint64 guid, uint32, uint32 (client sedn CMSG_ITEM_QUERY_SINGLE) + SMSG_UNKNOWN_960 = 960, // uint64 player_guid, uint32 drunk_state (0-3), uint32 itemid // 961 not exist? // 962 not exist? // 963 not exist? - SMSG_UNKNOWN_964 = 964, // uint8? - CMSG_UNKNOWN_965 = 965, // related to raid ready check... + SMSG_UNKNOWN_964 = 964, // uint8, disconnect related? + MSG_UNKNOWN_965 = 965, // empty, related to raid ready check... CMSG_REPORT_SPAM = 966, // Report Spam chat button - SMSG_REPORT_SPAM_RESULT = 967, // Complaint Registered. (message) + SMSG_REPORT_SPAM_RESULT = 967, // uint8, Complaint Registered. (message) SMSG_VOICE_SYSTEM_STATUS = 968, // uint8, uint8 (id correct for 2.3.0) // 969 not exist? // 970 not exist? @@ -1040,8 +1040,8 @@ SMSG_PLAYER_JOINED_CUSTOM_CHANNEL = 1009, // uint64, uint8, uint8, uint32, string CMSG_CLEAR_CHANNEL_WATCH = 1010, SMSG_INSPECT_TALENTS = 1011, // uint32 count, for(count) uint8 unk - SMSG_UNKNOWN_1012 = 1012, // uint8 - SMSG_UNKNOWN_1013 = 1013, // uint64, uint32 + SMSG_UNKNOWN_1012 = 1012, // uint8, toggle run forward + SMSG_UNKNOWN_1013 = 1013, // uint64, uint32 ERR_PLAYER_SILENCED_ECHO/ERR_PLAYER_UNSILENCED_ECHO // 1014 not exist? CMSG_UNKNOWN_1015 = 1015, // uint64, click on NPC with 0x1000000 npc_flag SMSG_UNKNOWN_1016 = 1016, // uint64 @@ -1053,41 +1053,40 @@ MSG_GUILD_EVENT_LOG = 1022, // 1023 not exist? CMSG_UNKNOWN_1024 = 1024, // empty - SMSG_UNKNOWN_1025 = 1025, // empty? + SMSG_MIRRORIMAGE_DATA = 1025, + SMSG_FORCE_DISPLAY_UPDATE = 1026, + SMSG_UNKNOWN_1027 = 1027, // uint32, uint32, uint32 + UMSG_UNKNOWN_1028 = 1028, + SMSG_UNKNOWN_1029 = 1029, // do nothing at client + CMSG_UNKNOWN_1030 = 1030, + SMSG_UNKNOWN_1031 = 1031, // empty?, message You can't do that yet + CMSG_GROUP_PASS_ON_LOOT_TOGGLE = 1032, // uint32 + MSG_GUILD_BANK_TAB_TEXT = 1033, // uint8, GuildBankText + CMSG_GUILD_BANK_SET_TAB_TEXT = 1034, // uint8, string, SetGuildBankText + UMSG_UNKNOWN_1035 = 1035, // not exist? + CMSG_UNKNOWN_1036 = 1036, // lua: GrantLevel + UMSG_UNKNOWN_1037 = 1037, // not exist? + UMSG_UNKNOWN_1038 = 1038, // not exist? + CMSG_UNKNOWN_1039 = 1039, // string, DeclineInvite + SMSG_GROUP_ACTION_THROTTLED = 1040, // empty + SMSG_UNKNOWN_1041 = 1041, // uint32, uint32, uint32 + SMSG_UNKNOWN_1042 = 1042, // uint8, uint64, uint32, uint32 + CMSG_UNKNOWN_1043 = 1043, // lua: DestroyTotem(slot) + UMSG_UNKNOWN_1044 = 1044, // not exist? + UMSG_UNKNOWN_1045 = 1045, // not exist? + CMSG_QUESTGIVER_STATUS_QUERY_MULTIPLE = 1046, // quest giver query status multiple (all visible) + SMSG_QUESTGIVER_STATUS_QUERY_MULTIPLE_RESPONSE = 1047, // response to 1046, uint32 count; for(count) { uint64; uint8; } + CMSG_UNKNOWN_1048 = 1048, // lua: DeclineCharacter + SMSG_UNKNOWN_1049 = 1049, // uint32 result, if(!result) uint64, CharacterDeclineResult + UMSG_UNKNOWN_1050 = 1050, // not exist? + UMSG_UNKNOWN_1051 = 1051, // not exist? + UMSG_UNKNOWN_1052 = 1052, // not exist? + SMSG_UNKNOWN_1053 = 1053, // uint32 count; for(count) { uint32; } }; //if you add new opcode .. Do NOT forget to change the following define MAX_OPCODE_ID and also add new opcode to table in opcodes.cpp -#define MAX_OPCODE_ID 1026 +#define MAX_OPCODE_ID 1054 -/// Results of friend related commands -enum FriendsResult -{ - FRIEND_DB_ERROR = 0x00, - FRIEND_LIST_FULL = 0x01, - FRIEND_ONLINE = 0x02, - FRIEND_OFFLINE = 0x03, - FRIEND_NOT_FOUND = 0x04, - FRIEND_REMOVED = 0x05, - FRIEND_ADDED_ONLINE = 0x06, - FRIEND_ADDED_OFFLINE = 0x07, - FRIEND_ALREADY = 0x08, - FRIEND_SELF = 0x09, - FRIEND_ENEMY = 0x0A, - FRIEND_IGNORE_FULL = 0x0B, - FRIEND_IGNORE_SELF = 0x0C, - FRIEND_IGNORE_NOT_FOUND = 0x0D, - FRIEND_IGNORE_ALREADY = 0x0E, - FRIEND_IGNORE_ADDED = 0x0F, - FRIEND_IGNORE_REMOVED = 0x10, - // 0x11 - // 0x12 - // 0x13 - // 0x14 - // 0x15 - FRIEND_MUTE_ADDED = 0x16, - FRIEND_MUTE_REMOVED = 0x17 -}; - extern const char* g_worldOpcodeNames[]; /// Lookup opcode name for human understandable logging Index: src/game/Pet.cpp =================================================================== --- src/game/Pet.cpp (revision 5641) +++ src/game/Pet.cpp (working copy) @@ -175,7 +175,8 @@ float px, py, pz; owner->GetClosePoint(px, py, pz,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE); uint32 guid=objmgr.GenerateLowGuid(HIGHGUID_UNIT); - if(!Create(guid, owner->GetMapId(), px, py, pz, owner->GetOrientation(), petentry)) + uint32 pet_number = fields[0].GetUInt32(); + if(!Create(guid, owner->GetMapId(), px, py, pz, owner->GetOrientation(), petentry, pet_number)) { delete result; return false; @@ -194,9 +195,9 @@ return true; } if(getPetType()==HUNTER_PET || getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK) - m_charmInfo->SetPetNumber(fields[0].GetUInt32(), true); + m_charmInfo->SetPetNumber(pet_number, true); else - m_charmInfo->SetPetNumber(fields[0].GetUInt32(), false); + m_charmInfo->SetPetNumber(pet_number, false); SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()); SetDisplayId(fields[3].GetUInt32()); SetNativeDisplayId(fields[3].GetUInt32()); @@ -216,7 +217,7 @@ break; case HUNTER_PET: SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); - SetUInt32Value(UNIT_FIELD_BYTES_1,(fields[9].GetUInt32()<<8)); + SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[9].GetUInt32()); if(fields[13].GetBool()) SetUInt32Value(UNIT_FIELD_BYTES_2, 0x00022801); // can't be renamed (byte 0x02) @@ -409,7 +410,7 @@ << m_TrainingPoints << ", " << uint32(mode) << ", '" << name.c_str() << "', " - << uint32(((GetUInt32Value(UNIT_FIELD_BYTES_2) >> 16) == 3)?0:1) << ", " + << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == 0x03)?0:1) << ", " << (curhealth<1?1:curhealth) << ", " << curmana << ", " << GetPower(POWER_HAPPINESS) << ", '"; @@ -606,8 +607,7 @@ Unit* owner = GetOwner(); if(owner && owner->GetTypeId() == TYPEID_PLAYER) { - WorldPacket data(SMSG_PET_BROKEN, 8); - data << GetGUID(); + WorldPacket data(SMSG_PET_BROKEN, 0); ((Player*)owner)->GetSession()->SendPacket(&data); //run away @@ -662,10 +662,7 @@ void Pet::SetLoyaltyLevel(LoyaltyLevel level) { - uint32 curvalue = GetUInt32Value(UNIT_FIELD_BYTES_1); - curvalue &= 0xFFFF00FF; - curvalue |= (level << 8); - SetUInt32Value(UNIT_FIELD_BYTES_1, curvalue); + SetByteValue(UNIT_FIELD_BYTES_1, 1, level); } bool Pet::CanTakeMoreActiveSpells(uint32 spellid) @@ -853,7 +850,8 @@ SetInstanceId(creature->GetInstanceId()); sLog.outBasic("Create pet"); - Create(guid, creature->GetMapId(), creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation(), creature->GetEntry()); + uint32 pet_number = objmgr.GeneratePetNumber(); + Create(guid, creature->GetMapId(), creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation(), creature->GetEntry(), pet_number); CreatureInfo const *cinfo = GetCreatureInfo(); if(!cinfo) @@ -1543,7 +1541,7 @@ } } -bool Pet::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 Entry) +bool Pet::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 Entry, uint32 pet_number) { respawn_cord[0] = x; respawn_cord[1] = y; @@ -1560,7 +1558,7 @@ SetOrientation(ang); //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; - Object::_Create(guidlow, HIGHGUID_UNIT); + Object::_Create(guidlow, pet_number, HIGHGUID_PET); m_DBTableGuid = guidlow; @@ -1584,7 +1582,7 @@ SetDisplayId(minfo->modelid); SetNativeDisplayId(minfo->modelid); - SetUInt32Value(UNIT_FIELD_BYTES_2, 1); // let creature used equiped weapon in fight + SetByteValue(UNIT_FIELD_BYTES_2, 0, 0x01); // let creature used equiped weapon in fight if(getPetType() == MINI_PET) // always non-attackable SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE); Index: src/game/Pet.h =================================================================== --- src/game/Pet.h (revision 5641) +++ src/game/Pet.h (working copy) @@ -119,7 +119,7 @@ bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; } bool isTemporarySummoned() const { return m_duration > 0; } - bool Create (uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 Entry); + bool Create (uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 Entry, uint32 pet_number); bool CreateBaseAtCreature( Creature* creature ); bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false ); void SavePetToDB(PetSaveMode mode); @@ -145,7 +145,7 @@ uint32 GetMaxLoyaltyPoints(uint32 level); uint32 GetStartLoyaltyPoints(uint32 level); void KillLoyaltyBonus(uint32 level); - uint32 GetLoyaltyLevel(){ return ((GetUInt32Value(UNIT_FIELD_BYTES_1) >> 8) & 0xFF);}; + uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } void SetLoyaltyLevel(LoyaltyLevel level); void GivePetXP(uint32 xp); void GivePetLevel(uint32 level); Index: src/game/PetHandler.cpp =================================================================== --- src/game/PetHandler.cpp (revision 5641) +++ src/game/PetHandler.cpp (working copy) @@ -289,6 +289,8 @@ data << uint32(petnumber); data << name.c_str(); data << uint32(pet->GetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP)); + data << uint8(0); + // for(5) string _player->GetSession()->SendPacket(&data); } @@ -376,7 +378,7 @@ Pet* pet = ObjectAccessor::GetPet(petguid); // check it! - if(!pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || (pet->GetUInt32Value(UNIT_FIELD_BYTES_2) >> 16) != 3 || pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo()) + if(!pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || pet->GetByteValue(UNIT_FIELD_BYTES_2, 2) != 3 || pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo()) return; pet->SetName(name); @@ -385,7 +387,7 @@ if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup()) ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); - pet->SetUInt32Value(UNIT_FIELD_BYTES_2, uint32(2 << 16)); + pet->SetByteValue(UNIT_FIELD_BYTES_2, 2, 0x02); CharacterDatabase.escape_string(name); CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(),_player->GetGUIDLow(),pet->GetCharmInfo()->GetPetNumber() ); Index: src/game/PetitionsHandler.cpp =================================================================== --- src/game/PetitionsHandler.cpp (revision 5641) +++ src/game/PetitionsHandler.cpp (working copy) @@ -28,6 +28,7 @@ #include "ArenaTeam.h" #include "MapManager.h" #include "GossipDef.h" +#include "SocialMgr.h" /*enum PetitionType // dbc data { @@ -586,7 +587,7 @@ sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", petitiontype, GUID_LOPART(petitionguid), GUID_LOPART(plguid)); player = ObjectAccessor::FindPlayer(plguid); - if(!player || player->HasInIgnoreList(GetPlayer()->GetGUID())) + if(!player || player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; // not let offer to enemies Index: src/game/Player.cpp =================================================================== --- src/game/Player.cpp (revision 5641) +++ src/game/Player.cpp (working copy) @@ -57,6 +57,7 @@ #include "Chat.h" #include "Database/DatabaseImpl.h" #include "Spell.h" +#include "SocialMgr.h" #include @@ -132,6 +133,8 @@ memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT); + m_social = NULL; + // group is initialized in the reference constructor SetGroupInvite(NULL); m_groupUpdateMask = 0; @@ -255,7 +258,10 @@ Player::~Player () { if(m_uint32Values) // only for fully created Object + { DuelComplete(DUEL_INTERUPTED); + sSocialMgr.RemovePlayerSocial(GetGUIDLow()); + } CleanupsBeforeDelete(); @@ -296,7 +302,7 @@ int i; uint8 race,class_,gender,skin,face,hairStyle,hairColor,facialHair,outfitId; - Object::_Create(guidlow, HIGHGUID_PLAYER); + Object::_Create(guidlow, 0, HIGHGUID_PLAYER); data >> m_name; @@ -414,7 +420,7 @@ SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( race ) | ( class_ << 8 ) | ( gender << 16 ) | ( powertype << 24 ) ) ); SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield ); - SetUInt32Value(UNIT_FIELD_BYTES_2, ( 0x28 << 8 ) ); // players - 0x2800, 0x2801, units - 0x1001 + SetByteValue(UNIT_FIELD_BYTES_2, 1, 0x28); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN1 ); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client @@ -423,7 +429,7 @@ SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); SetUInt32Value(PLAYER_BYTES_2, (facialHair | (0x00 << 8) | (0x00 << 16) | (0x02 << 24))); - SetUInt32Value(PLAYER_BYTES_3, gender); + SetByteValue(PLAYER_BYTES_3, 0, gender); SetUInt32Value( PLAYER_GUILDID, 0 ); SetUInt32Value( PLAYER_GUILDRANK, 0 ); @@ -1224,15 +1230,18 @@ { *p_data << (uint32)proto->DisplayInfoID; *p_data << (uint8)proto->InventoryType; + *p_data << (uint32)0; // enchant? } else { *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? } bool Player::ToggleAFK() @@ -1257,6 +1266,11 @@ uint8 Player::chatTag() { + // it's bitmask + // 0x8 - ?? + // 0x4 - gm + // 0x2 - dnd + // 0x1 - afk if(isGameMaster()) return 4; else if(isDND()) @@ -1267,165 +1281,6 @@ return 0; } -void Player::GetFriendInfo(uint64 friendGUID, FriendInfo &friendInfo) -{ - Player *pFriend = ObjectAccessor::FindPlayer(friendGUID); - - uint32 team = GetTeam(); - uint32 security = GetSession()->GetSecurity(); - bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); - bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER; - - // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters - // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if( pFriend && pFriend->GetName() && - ( security > SEC_PLAYER || - ( pFriend->GetTeam() == team || allowTwoSideWhoList ) && - ( pFriend->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && pFriend->IsVisibleGloballyFor(this) ))) - { - if(pFriend->isAFK()) - friendInfo.Status = FRIEND_STATUS_AFK; - else if(pFriend->isDND()) - friendInfo.Status = FRIEND_STATUS_DND; - else - friendInfo.Status = FRIEND_STATUS_ONLINE; - friendInfo.Area = pFriend->GetZoneId(); - friendInfo.Level = pFriend->getLevel(); - friendInfo.Class = pFriend->getClass(); - } - else - { - friendInfo.Status = FRIEND_STATUS_OFFLINE; - friendInfo.Area = 0; - friendInfo.Level = 0; - friendInfo.Class = 0; - } -} - -bool Player::AddToFriendList(uint64 guid, std::string name) -{ - // prevent list (client-side) overflow - if(m_friendlist.size() >= (255-1)) - return false; - - CharacterDatabase.PExecute("INSERT INTO character_social (guid,name,friend,flags) " - "VALUES ('%u', '%s', '%u', 0)", GetGUIDLow(), name.c_str(), GUID_LOPART(guid)); - m_friendlist.insert(GUID_LOPART(guid)); - return true; -} - -void Player::RemoveFromFriendList(uint64 guid) -{ - CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u' AND flags = 0", GetGUIDLow(), GUID_LOPART(guid)); - m_friendlist.erase(GUID_LOPART(guid)); -} - -void Player::_LoadFriendList(QueryResult *result) -{ - //QueryResult *result = CharacterDatabase.PQuery("SELECT friend FROM character_social WHERE guid = '%u' AND flags = 0 LIMIT 255",GetGUIDLow()); - if(!result) return; - - do - { - Field *fields = result->Fetch(); - - m_friendlist.insert(fields[0].GetUInt64()); - - // prevent list (client-side) overflow - if(m_ignorelist.size() >= 255) - break; - } - while( result->NextRow() ); - delete result; -} - -void Player::SendFriendlist() -{ - FriendInfo info; - uint8 size = (uint8)m_friendlist.size(); - - WorldPacket data(SMSG_FRIEND_LIST, (1+size*15)); // just can guess size - data << size; - - for (FriendList::iterator itr = m_friendlist.begin(); itr != m_friendlist.end(); ++itr) - { - GetFriendInfo(*itr, info); - sLog.outDetail( "WORLD: Adding Friend Guid: %u, Status:%u, Area:%u, Level:%u Class:%u", - GUID_LOPART(*itr), info.Status, info.Area, info.Level, info.Class); - - data << *itr << info.Status; - if (info.Status != 0) - data << info.Area << info.Level << info.Class; - } - - GetSession()->SendPacket( &data ); - sLog.outDebug( "WORLD: Sent (SMSG_FRIEND_LIST)" ); -} - -bool Player::AddToIgnoreList(uint64 guid, std::string name) -{ - // prevent list (client-side) overflow - if(m_ignorelist.size() >= (255-1)) - return false; - - CharacterDatabase.escape_string(name); // prevent SQL injection - normal name don't must changed by this call - CharacterDatabase.PExecute("INSERT INTO character_social (guid,name,friend,flags) " - "VALUES ('%u', '%s', '%u', 1)", GetGUIDLow(), name.c_str(), GUID_LOPART(guid)); - m_ignorelist.insert(GUID_LOPART(guid)); - return true; -} - -void Player::RemoveFromIgnoreList(uint64 guid) -{ - CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u' AND flags = 1",GetGUIDLow(), GUID_LOPART(guid)); - m_ignorelist.erase(GUID_LOPART(guid)); -} - -void Player::_LoadIgnoreList(QueryResult *result) -{ - //QueryResult *result = CharacterDatabase.PQuery("SELECT friend FROM character_social WHERE guid = '%u' AND flags = 1", GetGUIDLow()); - - if(!result) return; - - do - { - Field *fields = result->Fetch(); - m_ignorelist.insert(fields[0].GetUInt32()); - - // prevent list (client-side) overflow - if(m_ignorelist.size() >= 255) - break; - } - while( result->NextRow() ); - - delete result; -} - -void Player::SendIgnorelist() -{ - if(m_ignorelist.empty() && m_mutelist.empty()) - return; - - WorldPacket data(SMSG_IGNORE_LIST, (1+m_ignorelist.size()*8+1+m_mutelist.size()*8)); - data << uint8(m_ignorelist.size()); - - for(IgnoreList::iterator iter = m_ignorelist.begin(); iter != m_ignorelist.end(); ++iter) - { - data << uint64(MAKE_GUID(*iter,HIGHGUID_PLAYER)); - } - - data << uint8(0); // 0 muted players for now - /*data << uint8(m_mutelist.size()); - - for(MuteList::iterator iter = m_mutelist.begin(); iter != m_mutelist.end(); ++iter) - { - data << uint64(MAKE_GUID(*iter,HIGHGUID_PLAYER)); - }*/ - - GetSession()->SendPacket( &data ); - sLog.outDebug( "WORLD: Sent (SMSG_IGNORE_LIST)" ); -} - void Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, bool outofrange, bool ignore_transport, bool is_gm_command) { // preparing unsummon pet if lost (we must get pet before teleportation or will not find it later) @@ -1977,8 +1832,12 @@ data << uint64(victim ? victim->GetGUID() : 0); // guid data << uint32(GivenXP+RestXP); // given experience data << uint8(victim ? 0 : 1); // 00-kill_xp type, 01-non_kill_xp type + if(victim) + { data << uint32(GivenXP); // experience without rested bonus data << float(1); // 1 - none 0 - 100% group bonus output + } + data << uint8(0); // new 2.4.0 GetSession()->SendPacket(&data); } @@ -2608,7 +2467,7 @@ (spell_id == 21156 && m_form == FORM_BATTLESTANCE)|| (spell_id == 21178 && (m_form == FORM_BEAR || m_form == FORM_DIREBEAR) ) || (spell_id == 33948 && m_form == FORM_FLIGHT) || - (spell_id == 40121 && m_form == FORM_SWIFT_FLIGHT) ) + (spell_id == 40121 && m_form == FORM_FLIGHT_EPIC) ) //Check CasterAuraStates if (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState))) CastSpell(this, spell_id, true); @@ -3119,7 +2978,7 @@ updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1); // 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+=3) + for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4) updateVisualBits.SetBit(i); for(uint16 i = 0; i < INVENTORY_SLOT_BAG_END; i++) @@ -3232,27 +3091,23 @@ if (!trainer_spell) return TRAINER_SPELL_RED; - uint32 learned_spell_id = trainer_spell->spell->EffectTriggerSpell[0]; - - // get learned spell info - SpellEntry const *spellInfo = sSpellStore.LookupEntry(learned_spell_id); - if (!spellInfo) + if (!trainer_spell->spell) return TRAINER_SPELL_RED; // known spell - if(HasSpell(learned_spell_id)) + if(HasSpell(trainer_spell->spell->Id)) return TRAINER_SPELL_GRAY; // check race/class requirement - if(!IsSpellFitByClassAndRace(spellInfo->Id)) + if(!IsSpellFitByClassAndRace(trainer_spell->spell->Id)) return TRAINER_SPELL_RED; // check level requirement - if(getLevel() < ( trainer_spell->reqlevel ? trainer_spell->reqlevel : spellInfo->spellLevel)) + if(getLevel() < ( trainer_spell->reqlevel ? trainer_spell->reqlevel : trainer_spell->spell->spellLevel)) return TRAINER_SPELL_RED; // check prev.rank requirement - uint32 prev_id = spellmgr.GetPrevSpellInChain(learned_spell_id); + uint32 prev_id = spellmgr.GetPrevSpellInChain(trainer_spell->spell->Id); if(prev_id && !HasSpell(prev_id)) return TRAINER_SPELL_RED; @@ -3261,13 +3116,13 @@ return TRAINER_SPELL_RED; // secondary prof. or not prof. spell - uint32 skill = spellInfo->EffectMiscValue[1]; + uint32 skill = trainer_spell->spell->EffectMiscValue[1]; - if(spellInfo->Effect[1] != SPELL_EFFECT_SKILL || !IsPrimaryProfessionSkill(skill)) + if(trainer_spell->spell->Effect[1] != SPELL_EFFECT_SKILL || !IsPrimaryProfessionSkill(skill)) return TRAINER_SPELL_GREEN; // check primary prof. limit - if(spellmgr.IsPrimaryProfessionFirstRankSpell(learned_spell_id) && GetFreePrimaryProffesionPoints() == 0) + if(spellmgr.IsPrimaryProfessionFirstRankSpell(trainer_spell->spell->Id) && GetFreePrimaryProffesionPoints() == 0) return TRAINER_SPELL_RED; return TRAINER_SPELL_GREEN; @@ -3465,7 +3320,7 @@ SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, (float)1.0); //see radius of death player? - SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_ALWAYS_STAND); + SetByteValue(UNIT_FIELD_BYTES_1, 3, PLAYER_STATE_FLAG_ALWAYS_STAND); } void Player::SendDelayResponse(const uint32 ml_seconds) @@ -3488,7 +3343,7 @@ // speed change, land walk // remove death flag + set aura - RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_ALL); + SetByteValue(UNIT_FIELD_BYTES_1, 3, 0x00); if(getRace() == RACE_NIGHTELF) RemoveAurasDueToSpell(20584); // speed bonuses RemoveAurasDueToSpell(8326); // SPELL_AURA_GHOST @@ -3917,40 +3772,6 @@ } } -void Player::BroadcastPacketToFriendListers(WorldPacket *packet, bool extern_result, QueryResult *result) -{ - /// this is sent out to those that have the player in their friendlist - /// (not necessarily those that are in the player's friendlist) - if(!extern_result) - result = CharacterDatabase.PQuery("SELECT guid FROM character_social WHERE friend = '%u' AND flags = 0", GetGUIDLow()); - - if(!result) return; - - uint32 team = GetTeam(); - uint32 security = GetSession()->GetSecurity(); - bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST); - bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST); - - do - { - Field *fields = result->Fetch(); - Player *pFriend = ObjectAccessor::FindPlayer(fields[0].GetUInt64()); - - // PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters - // MODERATOR, GAME MASTER, ADMINISTRATOR can see all - if( pFriend && pFriend->IsInWorld() && - ( pFriend->GetSession()->GetSecurity() > SEC_PLAYER || - ( pFriend->GetTeam() == team || allowTwoSideWhoList ) && - (security == SEC_PLAYER || gmInWhoList && IsVisibleGloballyFor(pFriend) ))) - { - pFriend->GetSession()->SendPacket(packet); - } - }while( result->NextRow() ); - - // note: always deletes the result, even if it was external, use accordingly - delete result; -} - void Player::UpdateDefense() { if(UpdateSkill(SKILL_DEFENSE)) @@ -5102,7 +4923,8 @@ { if(faction->Flags & FACTION_FLAG_VISIBLE) //If faction is visible then update it { - WorldPacket data(SMSG_SET_FACTION_STANDING, (12)); // last check 2.0.10 + WorldPacket data(SMSG_SET_FACTION_STANDING, (16)); // last check 2.4.0 + data << (float) 0; // unk 2.4.0 data << (uint32) 1; // count // for data << (uint32) faction->ReputationListID; @@ -7586,7 +7408,7 @@ SetVirtualItemSlot(2,NULL); break; } - SetUInt32Value(UNIT_FIELD_BYTES_2, 0x2800+sheathed); // this must visualize Sheath changing for other players... + SetByteValue(UNIT_FIELD_BYTES_2, 0, sheathed); // this must visualize Sheath changing for other players... } uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap ) const @@ -7963,7 +7785,7 @@ bool Player::HasBankBagSlot( uint8 slot ) const { - uint32 maxslot = ((GetUInt32Value(PLAYER_BYTES_2) & 0x70000) >> 16) + BANK_SLOT_BAG_START; + uint32 maxslot = GetByteValue(PLAYER_BYTES_2, 2) + BANK_SLOT_BAG_START; if( slot < maxslot ) return true; return false; @@ -10514,11 +10336,13 @@ sLog.outDebug( "WORLD: Sent SMSG_INVENTORY_CHANGE_FAILURE" ); WorldPacket data( SMSG_INVENTORY_CHANGE_FAILURE, ((msg == EQUIP_ERR_CANT_EQUIP_LEVEL_I)?22:18) ); data << uint8(msg); - if( msg == EQUIP_ERR_CANT_EQUIP_LEVEL_I ) - data << (pItem && pItem->GetProto() ? pItem->GetProto()->RequiredLevel : uint32(0)); + if(msg) + { data << uint64(pItem ? pItem->GetGUID() : 0); data << uint64(pItem2 ? pItem2->GetGUID() : 0); data << uint8(0); // not 0 there... + data << uint32(0); // new 2.4.0 + } GetSession()->SendPacket(&data); } @@ -11476,6 +11300,7 @@ SetUInt32Value(log_slot + 0, quest_id); SetUInt32Value(log_slot + 1, 0); + SetUInt32Value(log_slot + 2, 0); if( pQuest->HasFlag( QUEST_MANGOS_FLAGS_TIMED ) ) { @@ -11483,12 +11308,12 @@ AddTimedQuest( quest_id ); mQuestStatus[quest_id].m_timer = limittime * 1000; uint32 qtime = static_cast(time(NULL)) + limittime; - SetUInt32Value( log_slot + 2, qtime ); + SetUInt32Value( log_slot + 3, qtime ); } else { questStatusData.m_timer = 0; - SetUInt32Value( log_slot + 2, 0 ); + SetUInt32Value( log_slot + 3, 0 ); } //starting initial quest script @@ -11508,7 +11333,7 @@ if( log_slot ) { uint32 state = GetUInt32Value( log_slot + 1 ); - state |= 1 << 24; + state |= 1 << 0; // can be wrong, need check SetUInt32Value( log_slot + 1, state ); } @@ -11526,7 +11351,7 @@ if( log_slot ) { uint32 state = GetUInt32Value( log_slot + 1 ); - state &= ~(1 << 24); + state &= ~(1 << 0); // can be wrong, need check SetUInt32Value( log_slot + 1, state ); } } @@ -11586,6 +11411,7 @@ SetUInt32Value(log_slot + 0, 0); SetUInt32Value(log_slot + 1, 0); SetUInt32Value(log_slot + 2, 0); + SetUInt32Value(log_slot + 3, 0); } // Not give XP in case already completed once repeatable quest @@ -11621,10 +11447,10 @@ uint16 log_slot = GetQuestSlot( quest_id ); if( log_slot ) { - SetUInt32Value( log_slot + 2, 1 ); + SetUInt32Value( log_slot + 3, 1 ); uint32 state = GetUInt32Value( log_slot + 1 ); - state |= 1 << 25; + state |= 1 << 1; // can be wrong, need check SetUInt32Value( log_slot + 1, state ); } SendQuestFailed( quest_id ); @@ -11643,10 +11469,10 @@ uint16 log_slot = GetQuestSlot( quest_id ); if( log_slot ) { - SetUInt32Value( log_slot + 2, 1 ); + SetUInt32Value( log_slot + 3, 1 ); uint32 state = GetUInt32Value( log_slot + 1 ); - state |= 1 << 25; + state |= 1 << 1; // can be wrong, need check SetUInt32Value( log_slot + 1, state ); } SendQuestTimerFailed( quest_id ); @@ -11972,7 +11798,7 @@ return true; bool have_slot = false; - for(uint32 quest_daily_idx = 0; quest_daily_idx < 10; ++quest_daily_idx) + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) { uint32 id = GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx); if(qInfo->GetQuestId()==id) @@ -12152,8 +11978,8 @@ { for ( uint16 i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - if ( GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i) == quest_id ) - return PLAYER_QUEST_LOG_1_1 + 3*i; + if ( GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i) == quest_id ) + return PLAYER_QUEST_LOG_1_1 + 4*i; } return 0; } @@ -12182,7 +12008,7 @@ uint32 additemcount; for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i); + questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i); if ( questid != 0 && mQuestStatus[questid].m_status == QUEST_STATUS_INCOMPLETE ) { Quest const* qInfo = objmgr.GetQuestTemplate(questid); @@ -12223,7 +12049,7 @@ uint32 remitemcount; for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i); + questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i); Quest const* qInfo = objmgr.GetQuestTemplate(questid); if ( qInfo ) { @@ -12265,7 +12091,7 @@ uint32 addkillcount = 1; for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i); + questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i); if(!questid) continue; @@ -12319,7 +12145,7 @@ uint32 addCastCount = 1; for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i); + questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i); if(!questid) continue; @@ -12383,7 +12209,7 @@ uint32 addTalkCount = 1; for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i); + questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i); if(!questid) continue; @@ -12435,7 +12261,7 @@ uint32 questid; for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ ) { - questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i); + questid = GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i); if ( questid != 0 ) { Quest const* qInfo = objmgr.GetQuestTemplate(questid); @@ -12545,14 +12371,15 @@ data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY))); } data << uint32(0); // new 2.3.0, HonorPoints? - data << uint32( pQuest->GetRewItemsCount() ); + data << uint32( pQuest->GetRewItemsCount() ); // max is 5 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); } - data << uint32(0); GetSession()->SendPacket( &data ); if (pQuest->GetQuestCompleteScript() != 0) @@ -12593,10 +12420,9 @@ { if( pPlayer ) { - WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1+1) ); + WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1) ); data << uint64(pPlayer->GetGUID()); - data << uint8(msg); - data << uint8(0); + data << uint8(msg); // valid values: 0-8 GetSession()->SendPacket( &data ); sLog.outDebug("WORLD: Sent MSG_QUEST_PUSH_RESULT"); } @@ -12613,7 +12439,7 @@ void Player::SendQuestUpdateAddCreatureOrGo( Quest const* pQuest, uint64 guid, uint32 creatureOrGO_idx, uint32 old_count, uint32 add_count ) { - assert(old_count + add_count < 64 && "mob/GO count store in 6 bits 2^6 = 64 (0..63)"); + assert(old_count + add_count < 256 && "mob/GO count store in 6 bits 2^8 = 256 (0..256)"); int32 entry = pQuest->ReqCreatureOrGOId[ creatureOrGO_idx ]; if (entry < 0) @@ -12630,9 +12456,9 @@ GetSession()->SendPacket(&data); uint16 log_slot = GetQuestSlot( pQuest->GetQuestId() ); - uint32 kills = GetUInt32Value( log_slot + 1 ); - kills = kills + (add_count << ( 6 * creatureOrGO_idx )); - SetUInt32Value( log_slot + 1, kills ); + uint32 kills = GetUInt32Value( log_slot + 2 ); + kills = kills + (add_count << ( 8 * creatureOrGO_idx )); + SetUInt32Value( log_slot + 2, kills ); } /*********************************************************/ @@ -12782,7 +12608,7 @@ return false; } - Object::_Create( guid, HIGHGUID_PLAYER ); + Object::_Create( guid, 0, HIGHGUID_PLAYER ); if(!LoadValues( fields[2].GetString())) { @@ -13014,8 +12840,7 @@ // unread mails and next delivery time, actual mails not loaded _LoadMailInit(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILCOUNT), holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILDATE)); - _LoadIgnoreList(holder->GetResult(PLAYER_LOGIN_QUERY_LOADIGNORELIST)); - _LoadFriendList(holder->GetResult(PLAYER_LOGIN_QUERY_LOADFRIENDLIST)); + m_social = sSocialMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSOCIALLIST), GetGUIDLow()); if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND))) return false; @@ -13619,17 +13444,19 @@ { uint32 state = 0; if(questStatusData.m_status == QUEST_STATUS_COMPLETE) - state |= 1 << 24; + state |= 1 << 0; + uint32 stateCounter = 0; for(uint8 idx = 0; idx < QUEST_OBJECTIVES_COUNT; ++idx) { if(questStatusData.m_creatureOrGOcount[idx]) - state += (questStatusData.m_creatureOrGOcount[idx] << ( 6 * idx )); + stateCounter += (questStatusData.m_creatureOrGOcount[idx] << ( 8 * idx )); } - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot+0,quest_id); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot+1,state); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot+2,quest_time); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot+0,quest_id); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot+1,state); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot+2,stateCounter); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot+3,quest_time); ++slot; } @@ -13645,15 +13472,16 @@ // clear quest log tail for ( uint16 i = slot; i < MAX_QUEST_LOG_SIZE; ++i ) { - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i+0,0); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i+1,0); - SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*i+2,0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i+0,0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i+1,0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i+2,0); + SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*i+3,0); } } void Player::_LoadDailyQuestStatus(QueryResult *result) { - for(uint32 quest_daily_idx = 0; quest_daily_idx < 10; ++quest_daily_idx) + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx,0); //QueryResult *result = CharacterDatabase.PQuery("SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GetGUIDLow()); @@ -13664,9 +13492,9 @@ do { - if(quest_daily_idx >= 10) // max amount with exist data in query + if(quest_daily_idx >= PLAYER_MAX_DAILY_QUESTS) // max amount with exist data in query { - sLog.outError("Player (GUID: %u) have more 10 daily quest records in charcter_queststatus_daily",GetGUIDLow()); + sLog.outError("Player (GUID: %u) have more 25 daily quest records in `charcter_queststatus_daily`",GetGUIDLow()); break; } @@ -13900,7 +13728,9 @@ uint32 tmp_displayid = GetDisplayId(); // Set player sit state to standing on save, also stealth and shifted form - RemoveFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT | PLAYER_STATE_FORM_ALL | PLAYER_STATE_FLAG_CREEP); + 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_DISABLE_ROTATE); SetDisplayId(GetNativeDisplayId()); @@ -14253,7 +14083,7 @@ // we don't need transactions here. CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow()); - for(uint32 quest_daily_idx = 0; quest_daily_idx < 10; ++quest_daily_idx) + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) if(GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" I64FMTD "')", GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime)); @@ -14718,7 +14548,7 @@ rPlayer->GetSession()->SendPacket(&data); data.Initialize(SMSG_MESSAGECHAT, 200); - data << (uint8)CHAT_MSG_WHISPER_INFORM; + data << (uint8)CHAT_MSG_REPLY; data << (uint32)language; data << (uint64)rPlayer->GetGUID(); data << (uint32)0; @@ -15118,15 +14948,9 @@ // update data for client if(m_rest_bonus>10) - { - SetFlag(PLAYER_BYTES_2, 0x1000000); // Set Reststate = Rested - RemoveFlag(PLAYER_BYTES_2, 0x2000000); // Remove Reststate = Normal - } + SetByteValue(PLAYER_BYTES_2, 3, 0x01); // Set Reststate = Rested else if(m_rest_bonus<=1) - { - SetFlag(PLAYER_BYTES_2, 0x2000000); // Set Reststate = Normal - RemoveFlag(PLAYER_BYTES_2, 0x1000000); // Remove Reststate = Rested - } + SetByteValue(PLAYER_BYTES_2, 3, 0x02); // Set Reststate = Normal //RestTickUpdate SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, uint32(m_rest_bonus)); @@ -16167,6 +15991,11 @@ GetSession()->SendPacket(&data); SendInitialSpells(); + + data.Initialize(SMSG_UNKNOWN_1053, 4); + data << uint32(0); // count, for(count) uint32; + GetSession()->SendPacket(&data); + SendInitialActionButtons(); SendInitialReputations(); UpdateZone(GetZoneId()); @@ -16353,7 +16182,7 @@ void Player::SetDailyQuestStatus( uint32 quest_id ) { - for(uint32 quest_daily_idx = 0; quest_daily_idx < 10; ++quest_daily_idx) + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) { if(!GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) { @@ -16367,7 +16196,7 @@ void Player::ResetDailyQuestStatus() { - for(uint32 quest_daily_idx = 0; quest_daily_idx < 10; ++quest_daily_idx) + for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx,0); // DB data deleted in caller Index: src/game/Player.h =================================================================== --- src/game/Player.h (revision 5641) +++ src/game/Player.h (working copy) @@ -44,10 +44,12 @@ class PlayerMenu; class Transport; class UpdateMask; +class PlayerSocial; typedef std::deque PlayerMails; #define PLAYER_MAX_SKILLS 127 +#define PLAYER_MAX_DAILY_QUESTS 25 // Note: SPELLMOD_* values is aura types in fact enum SpellModType @@ -337,7 +339,7 @@ PLAYER_STATE_FORM_ALL = 0x00FF0000, - PLAYER_STATE_FLAG_ALWAYS_STAND = 0x01000000, + PLAYER_STATE_FLAG_ALWAYS_STAND = 0x01, // byte 4 PLAYER_STATE_FLAG_CREEP = 0x02000000, PLAYER_STATE_FLAG_UNTRACKABLE = 0x04000000, PLAYER_STATE_FLAG_ALL = 0xFF000000, @@ -505,29 +507,6 @@ AT_LOGIN_RESET_TALENTS = 4 }; -// Social : friends/ignores - -enum FriendStatus -{ - FRIEND_STATUS_OFFLINE = 0, - FRIEND_STATUS_ONLINE = 1, - FRIEND_STATUS_AFK = 2, - //FRIEND_STATUS_UNK3 - FRIEND_STATUS_DND = 4 -}; - -struct FriendInfo -{ - uint8 Status; - uint32 Area; - uint32 Level; - uint32 Class; -}; - -typedef std::set IgnoreList; -typedef std::set MuteList; -typedef std::set FriendList; - typedef std::map QuestStatusMap; #define IS_BACK_SLOT(s) (s == 0xFF) @@ -850,16 +829,14 @@ PLAYER_LOGIN_QUERY_LOADACTIONS = 10, PLAYER_LOGIN_QUERY_LOADMAILCOUNT = 11, PLAYER_LOGIN_QUERY_LOADMAILDATE = 12, - PLAYER_LOGIN_QUERY_LOADIGNORELIST = 13, - PLAYER_LOGIN_QUERY_LOADFRIENDLIST = 14, - PLAYER_LOGIN_QUERY_LOADHOMEBIND = 15, - PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 16, - PLAYER_LOGIN_QUERY_LOADHONOR = 17, - PLAYER_LOGIN_QUERY_LOADGUILD = 18, - PLAYER_LOGIN_QUERY_BROADCASTTOFRIENDLISTERS = 19 + PLAYER_LOGIN_QUERY_LOADSOCIALLIST = 13, + PLAYER_LOGIN_QUERY_LOADHOMEBIND = 14, + PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 15, + PLAYER_LOGIN_QUERY_LOADHONOR = 16, + PLAYER_LOGIN_QUERY_LOADGUILD = 17, }; -#define MAX_PLAYER_LOGIN_QUERY 20 +#define MAX_PLAYER_LOGIN_QUERY 18 // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) @@ -918,15 +895,7 @@ std::string afkMsg; std::string dndMsg; - void SendFriendlist(); - void SendIgnorelist(); - bool AddToIgnoreList(uint64 guid, std::string name); - bool AddToFriendList(uint64 guid, std::string name); - void RemoveFromFriendList(uint64 guid); - void RemoveFromIgnoreList(uint64 guid); - bool HasInIgnoreList(uint64 guid) const { return m_ignorelist.find(GUID_LOPART(guid)) != m_ignorelist.end(); } - bool HasInFriendList(uint64 guid) const { return m_friendlist.find(GUID_LOPART(guid)) != m_friendlist.end(); } - void GetFriendInfo(uint64 friendGUID, FriendInfo &friendInfo); + PlayerSocial *GetSocial() { return m_social; } uint32 GetTaximask( uint8 index ) const { return m_taximask[index]; } void SetTaximask( uint8 index, uint32 value ) { m_taximask[index] = value; } @@ -1575,8 +1544,6 @@ void UpdateLocalChannels( uint32 newZone ); void LeaveLFGChannel(); - void BroadcastPacketToFriendListers(WorldPacket *packet, bool extern_result = false, QueryResult *result = NULL); - void UpdateDefense(); void UpdateWeaponSkill (WeaponAttackType attType); void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, MeleeHitOutcome outcome, bool defence); @@ -1960,7 +1927,6 @@ void _LoadSpells(QueryResult *result); void _LoadTaxiMask(const char* data); void _LoadTutorials(QueryResult *result); - void _LoadIgnoreList(QueryResult *result); void _LoadFriendList(QueryResult *result); bool _LoadHomeBind(QueryResult *result); void _LoadHonor(QueryResult *result); @@ -2118,9 +2084,8 @@ time_t m_resetTalentsTime; uint32 m_usedTalentCount; - IgnoreList m_ignorelist; - MuteList m_mutelist; - FriendList m_friendlist; + // Social + PlayerSocial *m_social; // Groups GroupReference m_group; Index: src/game/QueryHandler.cpp =================================================================== --- src/game/QueryHandler.cpp (revision 5641) +++ src/game/QueryHandler.cpp (working copy) @@ -44,6 +44,11 @@ data << uint32(p->getRace()); data << uint32(p->getGender()); data << uint32(p->getClass()); + data << uint8(0); // unk 2.4.0 + /*for(5) + { + // string + }*/ SendPacket(&data); } @@ -67,6 +72,11 @@ data << (uint32)(field & 0xFF); data << (uint32)((field >> 16) & 0xFF); data << (uint32)((field >> 8) & 0xFF); + data << (uint8)0; + /*for(5) + { + // string + }*/ SendPacket( &data ); } @@ -263,9 +273,19 @@ if (!pGossip) { - data << uint32( 0 ); - data << "Greetings $N"; - data << "Greetings $N"; + for(uint32 i = 0; i < 8; ++i) + { + data << float(0); + data << "Greetings $N"; + data << "Greetings $N"; + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); + } } else { Index: src/game/QuestHandler.cpp =================================================================== --- src/game/QuestHandler.cpp (revision 5641) +++ src/game/QuestHandler.cpp (working copy) @@ -36,8 +36,8 @@ uint64 guid; recv_data >> guid; - uint32 questStatus = DIALOG_STATUS_NONE; - uint32 defstatus = DIALOG_STATUS_NONE; + uint8 questStatus = DIALOG_STATUS_NONE; + uint8 defstatus = DIALOG_STATUS_NONE; Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPE_UNIT|TYPE_GAMEOBJECT); if(!questgiver) @@ -338,13 +338,13 @@ uint32 temp1; uint32 temp2; - for (int i = 0; i < 3; i++ ) + for (int i = 0; i < 4; i++ ) { - temp1 = _player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot1 + i); - temp2 = _player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot2 + i); + temp1 = _player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot1 + i); + temp2 = _player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot2 + i); - _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot1 + i, temp2); - _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot2 + i, temp1); + _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot1 + i, temp2); + _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot2 + i, temp1); } } @@ -360,7 +360,7 @@ if( slot < MAX_QUEST_LOG_SIZE ) { - quest = _player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 0); + quest = _player->GetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 0); if( quest ) { @@ -369,9 +369,10 @@ _player->SetQuestStatus( quest, QUEST_STATUS_NONE); } - _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 0, 0); - _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 1, 0); - _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 3*slot + 2, 0); + _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 0, 0); + _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 1, 0); + _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 2, 0); + _player->SetUInt32Value(PLAYER_QUEST_LOG_1_1 + 4*slot + 3, 0); } } @@ -502,10 +503,9 @@ Player *pPlayer = ObjectAccessor::FindPlayer( _player->GetDivider() ); if( pPlayer ) { - WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+4+1) ); + WorldPacket data( MSG_QUEST_PUSH_RESULT, (8+1) ); data << uint64(guid); - data << uint32(msg); - data << uint8(0); + data << uint8(msg); // valid values: 0-8 pPlayer->GetSession()->SendPacket(&data); _player->SetDivider( 0 ); } @@ -598,3 +598,51 @@ return result; } + +void WorldSession::HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& recvPacket) +{ + sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY_MULTIPLE"); + + uint32 count = 0; + ByteBuffer buf; + for(Player::ClientGUIDs::iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) + { + uint8 questStatus = DIALOG_STATUS_NONE; + uint8 defstatus = DIALOG_STATUS_NONE; + + if(IS_CREATURE_GUID(*itr)) + { + Creature *questgiver = ObjectAccessor::GetCreature(*_player, *itr); + if(!questgiver || questgiver->IsHostileTo(_player)) + continue; + questStatus = Script->NPCDialogStatus(_player, questgiver); + if( questStatus > 6 ) + questStatus = getDialogStatus(_player, questgiver, defstatus); + + buf << uint64(questgiver->GetGUID()); + buf << uint8(questStatus); + ++count; + } + else if(IS_GAMEOBJECT_GUID(*itr)) + { + GameObject *questgiver = ObjectAccessor::GetGameObject(*_player, *itr); + if(!questgiver) + continue; + questStatus = Script->GODialogStatus(_player, questgiver); + if( questStatus > 6 ) + questStatus = getDialogStatus(_player, questgiver, defstatus); + + buf << uint64(questgiver->GetGUID()); + buf << uint8(questStatus); + ++count; + } + } + + if(count) + { + WorldPacket data(SMSG_QUESTGIVER_STATUS_QUERY_MULTIPLE_RESPONSE, 4+buf.size()); + data << uint32(count); + data.append(buf); + SendPacket(&data); + } +} Index: src/game/SharedDefines.h =================================================================== --- src/game/SharedDefines.h (revision 5641) +++ src/game/SharedDefines.h (working copy) @@ -130,10 +130,11 @@ POWER_RAGE = 1, POWER_FOCUS = 2, POWER_ENERGY = 3, - POWER_HAPPINESS = 4 + POWER_HAPPINESS = 4, + POWER_RUNES = 5 }; -#define MAX_POWERS 5 +#define MAX_POWERS 5 // not count POWER_RUNES for now enum SpellSchools { @@ -147,6 +148,7 @@ }; #define MAX_SPELL_SCHOOL 7 +#define SPELL_GENERIC_LEARN 483 enum SpellSchoolMask { @@ -222,7 +224,6 @@ enum Language { - LANG_GLOBAL = 0, LANG_UNIVERSAL = 0, LANG_ORCISH = 1, LANG_DARNASSIAN = 2, @@ -238,7 +239,8 @@ LANG_TROLL = 14, LANG_GUTTERSPEAK = 33, LANG_DRAENEI = 35, - LANG_ADDON = 0xFFFFFFFF // used by addons + LANG_ZOMBIE = 36, + LANG_ADDON = 0xFFFFFFFF // used by addons, in 2.4.0 not exit, replaced by messagetype? }; #define LANGUAGES_COUNT 17 @@ -404,7 +406,11 @@ SPELL_EFFECT_147 = 147, SPELL_EFFECT_148 = 148, SPELL_EFFECT_149 = 149, - TOTAL_SPELL_EFFECTS = 150 + SPELL_EFFECT_150 = 150, + SPELL_EFFECT_151 = 151, + SPELL_EFFECT_152 = 152, + SPELL_EFFECT_153 = 153, + TOTAL_SPELL_EFFECTS = 154 }; // Spell aura states @@ -1579,104 +1585,58 @@ enum ChatMsg { - CHAT_MSG_SAY = 0x00, - CHAT_MSG_PARTY = 0x01, - CHAT_MSG_RAID = 0x02, - CHAT_MSG_GUILD = 0x03, - CHAT_MSG_OFFICER = 0x04, - CHAT_MSG_YELL = 0x05, - CHAT_MSG_WHISPER = 0x06, - CHAT_MSG_WHISPER_INFORM = 0x07, - CHAT_MSG_EMOTE = 0x08, - CHAT_MSG_TEXT_EMOTE = 0x09, - CHAT_MSG_SYSTEM = 0x0A, - CHAT_MSG_MONSTER_SAY = 0x0B, - CHAT_MSG_MONSTER_YELL = 0x0C, - CHAT_MSG_MONSTER_EMOTE = 0x0D, - CHAT_MSG_CHANNEL = 0x0E, - CHAT_MSG_CHANNEL_JOIN = 0x0F, - CHAT_MSG_CHANNEL_LEAVE = 0x10, - CHAT_MSG_CHANNEL_LIST = 0x11, - CHAT_MSG_CHANNEL_NOTICE = 0x12, - CHAT_MSG_CHANNEL_NOTICE_USER = 0x13, - CHAT_MSG_AFK = 0x14, - CHAT_MSG_DND = 0x15, - CHAT_MSG_IGNORED = 0x16, - CHAT_MSG_SKILL = 0x17, - CHAT_MSG_LOOT = 0x18, - CHAT_MSG_COMBAT_MISC_INFO = 0x19, - CHAT_MSG_MONSTER_WHISPER = 0x1A, - CHAT_MSG_COMBAT_SELF_HITS = 0x1B, - CHAT_MSG_COMBAT_SELF_MISSES = 0x1C, - CHAT_MSG_COMBAT_PET_HITS = 0x1D, - CHAT_MSG_COMBAT_PET_MISSES = 0x1E, - CHAT_MSG_COMBAT_PARTY_HITS = 0x1F, - CHAT_MSG_COMBAT_PARTY_MISSES = 0x20, - CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS = 0x21, - CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES = 0x22, - CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS = 0x23, - CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES = 0x24, - CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS = 0x25, - CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES = 0x26, - CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS = 0x27, - CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES = 0x28, - CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS = 0x29, - CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES = 0x2A, - CHAT_MSG_COMBAT_FRIENDLY_DEATH = 0x2B, - CHAT_MSG_COMBAT_HOSTILE_DEATH = 0x2C, - CHAT_MSG_COMBAT_XP_GAIN = 0x2D, - CHAT_MSG_SPELL_SELF_DAMAGE = 0x2E, - CHAT_MSG_SPELL_SELF_BUFF = 0x2F, - CHAT_MSG_SPELL_PET_DAMAGE = 0x30, - CHAT_MSG_SPELL_PET_BUFF = 0x31, - CHAT_MSG_SPELL_PARTY_DAMAGE = 0x32, - CHAT_MSG_SPELL_PARTY_BUFF = 0x33, - CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE = 0x34, - CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF = 0x35, - CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE = 0x36, - CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF = 0x37, - CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE = 0x38, - CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF = 0x39, - CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE = 0x3A, - CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF = 0x3B, - CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE = 0x3C, - CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF = 0x3D, - CHAT_MSG_SPELL_TRADESKILLS = 0x3E, - CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF = 0x3F, - CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS = 0x40, - CHAT_MSG_SPELL_AURA_GONE_SELF = 0x41, - CHAT_MSG_SPELL_AURA_GONE_PARTY = 0x42, - CHAT_MSG_SPELL_AURA_GONE_OTHER = 0x43, - CHAT_MSG_SPELL_ITEM_ENCHANTMENTS = 0x44, - CHAT_MSG_SPELL_BREAK_AURA = 0x45, - CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE = 0x46, - CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS = 0x47, - CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE = 0x48, - CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS = 0x49, - CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE = 0x4A, - CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS = 0x4B, - CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE = 0x4C, - CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS = 0x4D, - CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE = 0x4E, - CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS = 0x4F, - CHAT_MSG_SPELL_FAILED_LOCALPLAYER = 0x50, - CHAT_MSG_COMBAT_HONOR_GAIN = 0x51, - CHAT_MSG_BG_SYSTEM_NEUTRAL = 0x52, - CHAT_MSG_BG_SYSTEM_ALLIANCE = 0x53, - CHAT_MSG_BG_SYSTEM_HORDE = 0x54, - CHAT_MSG_COMBAT_FACTION_CHANGE = 0x55, - CHAT_MSG_MONEY = 0x56, - CHAT_MSG_RAID_LEADER = 0x57, - CHAT_MSG_RAID_WARNING = 0x58, - CHAT_MSG_FOREIGN_TELL = 0x59, - CHAT_MSG_RAID_BOSS_EMOTE = 0x5A, - CHAT_MSG_FILTERED = 0x5B, - CHAT_MSG_BATTLEGROUND = 0x5C, - CHAT_MSG_BATTLEGROUND_LEADER = 0x5D, - CHAT_MSG_MONSTER_PARTY = 0x5E, - CHAT_MSG_RESTRICTED = 0x5F, + CHAT_MSG_ADDON = 0xFFFFFFFF, + CHAT_MSG_SYSTEM = 0x00, + CHAT_MSG_SAY = 0x01, + CHAT_MSG_PARTY = 0x02, + CHAT_MSG_RAID = 0x03, + CHAT_MSG_GUILD = 0x04, + CHAT_MSG_OFFICER = 0x05, + CHAT_MSG_YELL = 0x06, + CHAT_MSG_WHISPER = 0x07, + CHAT_MSG_WHISPER_INFORM = 0x08, + CHAT_MSG_REPLY = 0x09, + CHAT_MSG_EMOTE = 0x0A, + CHAT_MSG_TEXT_EMOTE = 0x0B, + CHAT_MSG_MONSTER_SAY = 0x0C, + CHAT_MSG_MONSTER_PARTY = 0x0D, + CHAT_MSG_MONSTER_YELL = 0x0E, + CHAT_MSG_MONSTER_WHISPER = 0x0F, + CHAT_MSG_MONSTER_EMOTE = 0x10, + CHAT_MSG_CHANNEL = 0x11, + CHAT_MSG_CHANNEL_JOIN = 0x12, + CHAT_MSG_CHANNEL_LEAVE = 0x13, + CHAT_MSG_CHANNEL_LIST = 0x14, + CHAT_MSG_CHANNEL_NOTICE = 0x15, + CHAT_MSG_CHANNEL_NOTICE_USER = 0x16, + CHAT_MSG_AFK = 0x17, + CHAT_MSG_DND = 0x18, + CHAT_MSG_IGNORED = 0x19, + CHAT_MSG_SKILL = 0x1A, + CHAT_MSG_LOOT = 0x1B, + CHAT_MSG_MONEY = 0x1C, + CHAT_MSG_OPENING = 0x1D, + CHAT_MSG_TRADESKILLS = 0x1E, + CHAT_MSG_PET_INFO = 0x1F, + CHAT_MSG_COMBAT_MISC_INFO = 0x20, + CHAT_MSG_COMBAT_XP_GAIN = 0x21, + CHAT_MSG_COMBAT_HONOR_GAIN = 0x22, + CHAT_MSG_COMBAT_FACTION_CHANGE = 0x23, + CHAT_MSG_BG_SYSTEM_NEUTRAL = 0x24, + CHAT_MSG_BG_SYSTEM_ALLIANCE = 0x25, + CHAT_MSG_BG_SYSTEM_HORDE = 0x26, + CHAT_MSG_RAID_LEADER = 0x27, + CHAT_MSG_RAID_WARNING = 0x28, + CHAT_MSG_RAID_BOSS_WHISPER = 0x29, + CHAT_MSG_RAID_BOSS_EMOTE = 0x2A, + CHAT_MSG_FILTERED = 0x2B, + CHAT_MSG_BATTLEGROUND = 0x2C, + CHAT_MSG_BATTLEGROUND_LEADER = 0x2D, + CHAT_MSG_RESTRICTED = 0x2E, }; +#define MAX_CHAT_MSG_TYPE 0x2F + // Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask enum PetDiet { Index: src/game/SkillHandler.cpp =================================================================== --- src/game/SkillHandler.cpp (revision 5641) +++ src/game/SkillHandler.cpp (working copy) @@ -153,13 +153,14 @@ if(!(_player->resetTalents())) { - WorldPacket data( MSG_TALENT_WIPE_CONFIRM, 0); //you have not any talent + WorldPacket data( MSG_TALENT_WIPE_CONFIRM, 8+4); //you have not any talent + data << uint64(0); + data << uint32(0); SendPacket( &data ); return; } unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect" - } void WorldSession::HandleUnlearnSkillOpcode(WorldPacket & recv_data) Index: src/game/Spell.cpp =================================================================== --- src/game/Spell.cpp (revision 5641) +++ src/game/Spell.cpp (working copy) @@ -209,12 +209,10 @@ return true; } -void SpellCastTargets::write ( WorldPacket * data, bool forceAppend) +void SpellCastTargets::write ( WorldPacket * data ) { - *data << uint16(m_targetMask); + *data << uint32(m_targetMask); - uint32 len = data->size(); - if(m_targetMask & TARGET_FLAG_UNIT) { if(m_unitTarget) @@ -231,7 +229,7 @@ *data << uint8(0); } - if( m_targetMask & TARGET_FLAG_ITEM ) + if( m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM ) ) { if(m_itemTarget) data->append(m_itemTarget->GetPackGUID()); @@ -250,9 +248,6 @@ if( m_targetMask & ( TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) ) data->appendPackGUID(m_CorpseTargetGUID); - - if( forceAppend && data->size() == len ) - *data << (uint8)0; } Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, Spell** triggeringContainer ) @@ -2459,10 +2454,11 @@ data << uint32(m_spellInfo->Id); data << uint16(castFlags); + data << uint32(getMSTime()); // timestamp WriteSpellGoTargets(&data); - m_targets.write(&data, true); + m_targets.write(&data); if( castFlags & CAST_FLAG_AMMO ) WriteAmmoToPacket(&data); @@ -2538,19 +2534,109 @@ else data.append(target->GetPackGUID()); - data << m_spellInfo->Id; - data << uint32(1); - data << m_spellInfo->SpellVisual; - data << uint32(1); + data << uint32(m_spellInfo->Id); + uint32 count1 = 1; + data << uint32(count1); // count1 (effect count?) + for(uint32 i = 0; i < count1; ++i) + { + data << uint32(m_spellInfo->Effect[0]); // spell effect? + uint32 count2 = 1; + data << uint32(count2); // count2 (target count?) + for(uint32 j = 0; j < count2; ++j) + { + switch(m_spellInfo->Effect[0]) + { + case SPELL_EFFECT_MANA_DRAIN: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); + data << uint32(0); + data << float(0); + break; + case SPELL_EFFECT_ADD_EXTRA_ATTACKS: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); // count? + break; + case SPELL_EFFECT_INTERRUPT_CAST: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); // spellid + break; + case SPELL_EFFECT_DURABILITY_DAMAGE: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + data << uint32(0); + data << uint32(0); + break; + case SPELL_EFFECT_OPEN_LOCK: + case SPELL_EFFECT_OPEN_LOCK_ITEM: + if(Item *item = m_targets.getItemTarget()) + data.append(item->GetPackGUID()); + else + data << uint8(0); + break; + case SPELL_EFFECT_CREATE_ITEM: + 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(Item *item = m_targets.getItemTarget()) + data.append(item->GetPackGUID()); + else if(GameObject *go = m_targets.getGOTarget()) + data.append(go->GetPackGUID()); + else + data << uint8(0); // guid + break; + case SPELL_EFFECT_FEED_PET: + if(Item *item = m_targets.getItemTarget()) + data << uint32(item->GetEntry()); + else + data << uint32(0); // item id + break; + case SPELL_EFFECT_DISMISS_PET: + if(Unit *unit = m_targets.getUnitTarget()) + data.append(unit->GetPackGUID()); + else + data << uint8(0); + break; + default: + return; + } + } + } - if(m_targets.getUnitTarget()) - data << m_targets.getUnitTargetGUID(); - else if(m_targets.getItemTargetGUID()) - data << m_targets.getItemTargetGUID(); - else if(m_targets.getGOTarget()) - data << m_targets.getGOTargetGUID(); - - m_caster->SendMessageToSet(&data,true); + m_caster->SendMessageToSet(&data, true); } void Spell::SendInterrupted(uint8 result) @@ -3558,7 +3644,7 @@ 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_SWIFT_FLIGHT || form == FORM_MOONKIN ) + form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN ) return SPELL_FAILED_NOT_SHAPESHIFT; break; Index: src/game/Spell.h =================================================================== --- src/game/Spell.h (revision 5641) +++ src/game/Spell.h (working copy) @@ -119,7 +119,7 @@ ~SpellCastTargets(); bool read ( WorldPacket * data, Unit *caster ); - void write ( WorldPacket * data, bool forceAppend=false); + void write ( WorldPacket * data ); SpellCastTargets& operator=(const SpellCastTargets &target) { @@ -175,7 +175,7 @@ float m_destX, m_destY, m_destZ; std::string m_strTarget; - uint16 m_targetMask; + uint32 m_targetMask; private: // objects (can be used at spell creating and after Update at casting Unit *m_unitTarget; Index: src/game/SpellAuraDefines.h =================================================================== --- src/game/SpellAuraDefines.h (revision 5641) +++ src/game/SpellAuraDefines.h (working copy) @@ -286,6 +286,9 @@ SPELL_AURA_246 = 246, SPELL_AURA_247 = 247, SPELL_AURA_MOD_COMBAT_RESULT = 248, - TOTAL_AURAS=249 + SPELL_AURA_249 = 249, + SPELL_AURA_250 = 250, + SPELL_AURA_251 = 251, + TOTAL_AURAS=252 }; #endif Index: src/game/SpellAuras.cpp =================================================================== --- src/game/SpellAuras.cpp (revision 5641) +++ src/game/SpellAuras.cpp (working copy) @@ -300,7 +300,10 @@ &Aura::HandleUnused, //245 used by only one test spell &Aura::HandleUnused, //246 unused &Aura::HandleUnused, //247 unused - &Aura::HandleNULL //248 SPELL_AURA_MOD_COMBAT_RESULT + &Aura::HandleNULL, //248 SPELL_AURA_MOD_COMBAT_RESULT + &Aura::HandleNULL, //249 + &Aura::HandleNULL, //250 + &Aura::HandleNULL //251 }; Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : @@ -1631,7 +1634,7 @@ else modelid = 15375; break; - case FORM_SWIFT_FLIGHT: + case FORM_FLIGHT_EPIC: if(Player::TeamForRace(m_target->getRace())==ALLIANCE) modelid = 21243; else @@ -1664,7 +1667,7 @@ m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftForm); } - m_target->SetFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) ); + m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, new_bytes_1); if(modelid > 0) { m_target->SetDisplayId(modelid); @@ -1750,7 +1753,7 @@ case FORM_AQUA: case FORM_BEAR: case FORM_DIREBEAR: - case FORM_SWIFT_FLIGHT: + case FORM_FLIGHT_EPIC: case FORM_FLIGHT: case FORM_MOONKIN: // remove movement affects @@ -1768,11 +1771,11 @@ else { m_target->SetDisplayId(m_target->GetNativeDisplayId()); - m_target->RemoveFlag(UNIT_FIELD_BYTES_1, (new_bytes_1<<16) ); + m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE); if(m_target->getClass() == CLASS_DRUID) m_target->setPowerType(POWER_MANA); m_target->m_ShapeShiftForm = 0; - m_target->m_form = 0; + m_target->m_form = FORM_NONE; switch(m_modifier.m_miscvalue) { @@ -2582,8 +2585,11 @@ if(BattleGround *bg = ((Player*)m_target)->GetBattleGround()) bg->HandleDropFlag((Player*)m_target); - m_target->SetFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_CREEP); + m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x02); + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->SetByteValue(PLAYER_FIELD_BYTES2, 1, 0x20); + // only at real aura add if(Real) { @@ -2605,8 +2611,11 @@ } else { - m_target->RemoveFlag(UNIT_FIELD_BYTES_1, PLAYER_STATE_FLAG_CREEP); + m_target->SetByteValue(UNIT_FIELD_BYTES_1, 2, 0x00); + if(m_target->GetTypeId()==TYPEID_PLAYER) + m_target->SetByteValue(PLAYER_FIELD_BYTES2, 1, 0x00); + // only at real aura remove if(Real) { @@ -4229,7 +4238,7 @@ case FORM_FLIGHT: spellId = 33948; break; - case FORM_SWIFT_FLIGHT: + case FORM_FLIGHT_EPIC: spellId = 40122; spellId2 = 40121; break; Index: src/game/SpellEffects.cpp =================================================================== --- src/game/SpellEffects.cpp (revision 5641) +++ src/game/SpellEffects.cpp (working copy) @@ -55,6 +55,7 @@ #include "BattleGroundWS.h" #include "VMapFactory.h" #include "Language.h" +#include "SocialMgr.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -178,37 +179,40 @@ &Spell::EffectSpiritHeal, //117 SPELL_EFFECT_SPIRIT_HEAL one spell: Spirit Heal &Spell::EffectSkill, //118 SPELL_EFFECT_SKILL professions and more &Spell::EffectApplyPetAura, //119 SPELL_EFFECT_APPLY_AURA_NEW - &Spell::EffectNULL, //120 SPELL_EFFECT_TELEPORT_GRAVEYARD two spells: Graveyard Teleport and Graveyard Teleport Test + &Spell::EffectNULL, //120 SPELL_EFFECT_TELEPORT_GRAVEYARD one spell: Graveyard Teleport Test &Spell::EffectWeaponDmg, //121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG - &Spell::EffectNULL, //122 SPELL_EFFECT_122 silithist cap reward spell - &Spell::EffectNULL, //123 SPELL_EFFECT_123 taxi/flight related + &Spell::EffectNULL, //122 SPELL_EFFECT_122 unused + &Spell::EffectNULL, //123 SPELL_EFFECT_SEND_TAXI taxi/flight related (misc value is taxi path id) &Spell::EffectPlayerPull, //124 SPELL_EFFECT_PLAYER_PULL opposite of knockback effect (pulls player twoard caster) &Spell::EffectReduceThreatPercent, //125 SPELL_EFFECT_REDUCE_THREAT_PERCENT &Spell::EffectStealBeneficialBuff, //126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF spell steal effect? &Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell &Spell::EffectApplyAura, //128 SPELL_EFFECT_APPLY_AURA_NEW2 probably apply aura again - &Spell::EffectNULL, //129 SPELL_EFFECT_129 probably apply aura again - &Spell::EffectNULL, //130 SPELL_EFFECT_130 threat redirect - &Spell::EffectNULL, //131 SPELL_EFFECT_131 unused - &Spell::EffectNULL, //132 SPELL_EFFECT_132 taxi related, one spell: Brazen Taxi + &Spell::EffectNULL, //129 SPELL_EFFECT_APPLY_AURA_NEW3 + &Spell::EffectNULL, //130 SPELL_EFFECT_REDIRECT_THREAT + &Spell::EffectNULL, //131 SPELL_EFFECT_131 used in some test spells + &Spell::EffectNULL, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value &Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization - &Spell::EffectNULL, //134 SPELL_EFFECT_134 - &Spell::EffectNULL, //135 SPELL_EFFECT_135 pet related + &Spell::EffectNULL, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry + &Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET &Spell::EffectNULL, //136 SPELL_EFFECT_136 &Spell::EffectNULL, //137 SPELL_EFFECT_137 &Spell::EffectNULL, //138 SPELL_EFFECT_138 - &Spell::EffectNULL, //139 SPELL_EFFECT_139 unused + &Spell::EffectNULL, //139 SPELL_EFFECT_139 unused &Spell::EffectNULL, //140 SPELL_EFFECT_140 &Spell::EffectNULL, //141 SPELL_EFFECT_141 &Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE - &Spell::EffectNULL, //143 SPELL_EFFECT_143 probably apply aura again :) - &Spell::EffectNULL, //144 SPELL_EFFECT_144 - &Spell::EffectNULL, //145 SPELL_EFFECT_145 - &Spell::EffectNULL, //146 SPELL_EFFECT_146 - &Spell::EffectNULL, //147 SPELL_EFFECT_147 - &Spell::EffectNULL, //148 SPELL_EFFECT_148 + &Spell::EffectNULL, //143 SPELL_EFFECT_APPLY_AURA_NEW4 + &Spell::EffectNULL, //144 SPELL_EFFECT_144 Spectral Blast + &Spell::EffectNULL, //145 SPELL_EFFECT_145 Black Hole Effect + &Spell::EffectNULL, //146 SPELL_EFFECT_146 unused + &Spell::EffectNULL, //147 SPELL_EFFECT_147 Torch Tossing Training Failure + &Spell::EffectNULL, //148 SPELL_EFFECT_148 unused &Spell::EffectNULL, //149 SPELL_EFFECT_149 - + &Spell::EffectNULL, //150 SPELL_EFFECT_150 unused + &Spell::EffectNULL, //151 SPELL_EFFECT_151 related to summon + &Spell::EffectNULL, //152 SPELL_EFFECT_152 RAFS + &Spell::EffectNULL, //153 SPELL_EFFECT_CREATE_PET misc value is creature entry }; void Spell::EffectNULL(uint32 /*i*/) @@ -2601,9 +2605,10 @@ float x,y,z; m_caster->GetClosePoint(x,y,z); + uint32 pet_number = objmgr.GeneratePetNumber(); if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMapId(),x,y,z,-m_caster->GetOrientation(), - m_spellInfo->EffectMiscValue[i])) + m_spellInfo->EffectMiscValue[i], pet_number)) { sLog.outErrorDb("Spell::EffectSummon: no such creature entry %u",m_spellInfo->EffectMiscValue[i]); delete spawnCreature; @@ -2630,7 +2635,7 @@ spawnCreature->InitStatsForLevel(level); - spawnCreature->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), false); + spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false); spawnCreature->AIM_Initialize(); spawnCreature->InitPetCreateSpells(); @@ -2672,7 +2677,7 @@ Player *player = (Player*)unitTarget; - uint32 spellToLearn = m_spellInfo->EffectTriggerSpell[i]; + uint32 spellToLearn = (m_spellInfo->Id==SPELL_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() ); @@ -2895,9 +2900,10 @@ Pet* spawnCreature = new Pet(m_caster, GUARDIAN_PET); + uint32 pet_number = objmgr.GeneratePetNumber(); if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMapId(),px,py,pz,m_caster->GetOrientation(), - m_spellInfo->EffectMiscValue[i])) + m_spellInfo->EffectMiscValue[i], pet_number)) { sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]); delete spawnCreature; @@ -3288,7 +3294,8 @@ return; } - if( NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMapId(), px, py, pz+1, m_caster->GetOrientation(), petentry)) + uint32 pet_number = objmgr.GeneratePetNumber(); + if( NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMapId(), px, py, pz+1, m_caster->GetOrientation(), petentry, pet_number)) { uint32 petlevel = m_caster->getLevel(); NewSummon->setPetType(SUMMON_PET); @@ -3312,7 +3319,7 @@ NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000); NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - NewSummon->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); + NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true); // this enables pet details window (Shift+P) // this enables popup window (pet dismiss, cancel), hunter pet additional flags set later @@ -3342,7 +3349,7 @@ NewSummon->SetName(new_name); } else if(NewSummon->getPetType()==HUNTER_PET) - NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_2, uint32(2 << 16)); + NewSummon->SetByteValue(UNIT_FIELD_BYTES_2, 2, 0x02); NewSummon->AIM_Initialize(); NewSummon->SetHealth(NewSummon->GetMaxHealth()); @@ -4091,7 +4098,7 @@ Player *target = (Player*)unitTarget; // caster or target already have requested duel - if( caster->duel || target->duel || target->HasInIgnoreList(caster->GetGUID()) ) + if( caster->duel || target->duel || target->GetSocial()->HasIgnore(caster->GetGUIDLow()) ) return; // Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities) @@ -4652,8 +4659,9 @@ float x,y,z; m_caster->GetClosePoint(x,y,z); + uint32 pet_number = objmgr.GeneratePetNumber(); if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), - m_caster->GetMapId(),x,y,z,m_caster->GetOrientation(),m_spellInfo->EffectMiscValue[i])) + m_caster->GetMapId(),x,y,z,m_caster->GetOrientation(),m_spellInfo->EffectMiscValue[i], pet_number)) { sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]); delete critter; Index: src/game/SpellHandler.cpp =================================================================== --- src/game/SpellHandler.cpp (revision 5641) +++ src/game/SpellHandler.cpp (working copy) @@ -34,14 +34,15 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { // TODO: add targets.read() check - CHECK_PACKET_SIZE(recvPacket,1+1+1+1); + CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8); Player* pUser = _player; uint8 bagIndex, slot; uint8 spell_count; // number of spells at item, not used uint8 cast_count; // next cast if exists (single or not) + uint64 item_guid; - recvPacket >> bagIndex >> slot >> spell_count >> cast_count; + recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid; Item *pItem = pUser->GetItemByPos(bagIndex, slot); if(!pItem) @@ -97,6 +98,27 @@ { // no script or script not process request by self + // special learning case + if(pItem->GetProto()->Spells[0].SpellId==SPELL_GENERIC_LEARN) + { + uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_GENERIC_LEARN); + if(!spellInfo) + { + sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_GENERIC_LEARN); + pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL); + return; + } + + Spell *spell = new Spell(pUser, spellInfo, false); + spell->m_CastItem = pItem; + spell->m_cast_count = cast_count; //set count of casts + spell->m_currentBasePoints[0] = learning_spell_id; + spell->prepare(&targets); + return; + } + // use triggered flag only for items with many spell casts and for not first cast int count = 0; Index: src/game/SpellMgr.h =================================================================== --- src/game/SpellMgr.h (revision 5641) +++ src/game/SpellMgr.h (working copy) @@ -35,169 +35,175 @@ enum SpellFailedReason { - SPELL_FAILED_AFFECTING_COMBAT = 0x00, - SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01, - SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x02, - SPELL_FAILED_ALREADY_BEING_TAMED = 0x03, - SPELL_FAILED_ALREADY_HAVE_CHARM = 0x04, - SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x05, - SPELL_FAILED_ALREADY_OPEN = 0x06, - SPELL_FAILED_AURA_BOUNCED = 0x07, - SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x08, - SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x09, - SPELL_FAILED_BAD_TARGETS = 0x0A, - SPELL_FAILED_CANT_BE_CHARMED = 0x0B, - SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0C, - SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0D, - SPELL_FAILED_CANT_BE_PROSPECTED = 0x0E, - SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x0F, - SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x10, - SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x11, - SPELL_FAILED_CANT_STEALTH = 0x12, - SPELL_FAILED_CASTER_AURASTATE = 0x13, - SPELL_FAILED_CASTER_DEAD = 0x14, - SPELL_FAILED_CHARMED = 0x15, - SPELL_FAILED_CHEST_IN_USE = 0x16, - SPELL_FAILED_CONFUSED = 0x17, - SPELL_FAILED_DONT_REPORT = 0x18, - SPELL_FAILED_EQUIPPED_ITEM = 0x19, - SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1A, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1B, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1C, - SPELL_FAILED_ERROR = 0x1D, - SPELL_FAILED_FIZZLE = 0x1E, - SPELL_FAILED_FLEEING = 0x1F, - SPELL_FAILED_FOOD_LOWLEVEL = 0x20, - SPELL_FAILED_HIGHLEVEL = 0x21, - SPELL_FAILED_HUNGER_SATIATED = 0x22, - SPELL_FAILED_IMMUNE = 0x23, - SPELL_FAILED_INTERRUPTED = 0x24, - SPELL_FAILED_INTERRUPTED_COMBAT = 0x25, - SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x26, - SPELL_FAILED_ITEM_GONE = 0x27, - SPELL_FAILED_ITEM_NOT_FOUND = 0x28, - SPELL_FAILED_ITEM_NOT_READY = 0x29, - SPELL_FAILED_LEVEL_REQUIREMENT = 0x2A, - SPELL_FAILED_LINE_OF_SIGHT = 0x2B, - SPELL_FAILED_LOWLEVEL = 0x2C, - SPELL_FAILED_LOW_CASTLEVEL = 0x2D, - SPELL_FAILED_MAINHAND_EMPTY = 0x2E, - SPELL_FAILED_MOVING = 0x2F, - SPELL_FAILED_NEED_AMMO = 0x30, - SPELL_FAILED_NEED_AMMO_POUCH = 0x31, - SPELL_FAILED_NEED_EXOTIC_AMMO = 0x32, - SPELL_FAILED_NOPATH = 0x33, - SPELL_FAILED_NOT_BEHIND = 0x34, - SPELL_FAILED_NOT_FISHABLE = 0x35, - SPELL_FAILED_NOT_FLYING = 0x36, - SPELL_FAILED_NOT_HERE = 0x37, - SPELL_FAILED_NOT_INFRONT = 0x38, - SPELL_FAILED_NOT_IN_CONTROL = 0x39, - SPELL_FAILED_NOT_KNOWN = 0x3A, - SPELL_FAILED_NOT_MOUNTED = 0x3B, - SPELL_FAILED_NOT_ON_TAXI = 0x3C, - SPELL_FAILED_NOT_ON_TRANSPORT = 0x3D, - SPELL_FAILED_NOT_READY = 0x3E, - SPELL_FAILED_NOT_SHAPESHIFT = 0x3F, - SPELL_FAILED_NOT_STANDING = 0x40, - SPELL_FAILED_NOT_TRADEABLE = 0x41, - SPELL_FAILED_NOT_TRADING = 0x42, - SPELL_FAILED_NOT_UNSHEATHED = 0x43, - SPELL_FAILED_NOT_WHILE_GHOST = 0x44, - SPELL_FAILED_NO_AMMO = 0x45, - SPELL_FAILED_NO_CHARGES_REMAIN = 0x46, - SPELL_FAILED_NO_CHAMPION = 0x47, - SPELL_FAILED_NO_COMBO_POINTS = 0x48, - SPELL_FAILED_NO_DUELING = 0x49, - SPELL_FAILED_NO_ENDURANCE = 0x4A, - SPELL_FAILED_NO_FISH = 0x4B, - SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4C, - SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4D, - SPELL_FAILED_NO_PET = 0x4E, - SPELL_FAILED_NO_POWER = 0x4F, - SPELL_FAILED_NOTHING_TO_DISPEL = 0x50, - SPELL_FAILED_NOTHING_TO_STEAL = 0x51, - SPELL_FAILED_ONLY_ABOVEWATER = 0x52, - SPELL_FAILED_ONLY_DAYTIME = 0x53, - SPELL_FAILED_ONLY_INDOORS = 0x54, - SPELL_FAILED_ONLY_MOUNTED = 0x55, - SPELL_FAILED_ONLY_NIGHTTIME = 0x56, - SPELL_FAILED_ONLY_OUTDOORS = 0x57, - SPELL_FAILED_ONLY_SHAPESHIFT = 0x58, - SPELL_FAILED_ONLY_STEALTHED = 0x59, - SPELL_FAILED_ONLY_UNDERWATER = 0x5A, - SPELL_FAILED_OUT_OF_RANGE = 0x5B, - SPELL_FAILED_PACIFIED = 0x5C, - SPELL_FAILED_POSSESSED = 0x5D, - SPELL_FAILED_REAGENTS = 0x5E, - SPELL_FAILED_REQUIRES_AREA = 0x5F, - SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x60, - SPELL_FAILED_ROOTED = 0x61, - SPELL_FAILED_SILENCED = 0x62, - SPELL_FAILED_SPELL_IN_PROGRESS = 0x63, - SPELL_FAILED_SPELL_LEARNED = 0x64, - SPELL_FAILED_SPELL_UNAVAILABLE = 0x65, - SPELL_FAILED_STUNNED = 0x66, - SPELL_FAILED_TARGETS_DEAD = 0x67, - SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x68, - SPELL_FAILED_TARGET_AURASTATE = 0x69, - SPELL_FAILED_TARGET_DUELING = 0x6A, - SPELL_FAILED_TARGET_ENEMY = 0x6B, - SPELL_FAILED_TARGET_ENRAGED = 0x6C, - SPELL_FAILED_TARGET_FRIENDLY = 0x6D, - SPELL_FAILED_TARGET_IN_COMBAT = 0x6E, - SPELL_FAILED_TARGET_IS_PLAYER = 0x6F, - SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x70, - SPELL_FAILED_TARGET_NOT_DEAD = 0x71, - SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x72, - SPELL_FAILED_TARGET_NOT_LOOTED = 0x73, - SPELL_FAILED_TARGET_NOT_PLAYER = 0x74, - SPELL_FAILED_TARGET_NO_POCKETS = 0x75, - SPELL_FAILED_TARGET_NO_WEAPONS = 0x76, - SPELL_FAILED_TARGET_UNSKINNABLE = 0x77, - SPELL_FAILED_THIRST_SATIATED = 0x78, - SPELL_FAILED_TOO_CLOSE = 0x79, - SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7A, - SPELL_FAILED_TOTEM_CATEGORY = 0x7B, - SPELL_FAILED_TOTEMS = 0x7C, - SPELL_FAILED_TRAINING_POINTS = 0x7D, - SPELL_FAILED_TRY_AGAIN = 0x7E, - SPELL_FAILED_UNIT_NOT_BEHIND = 0x7F, - SPELL_FAILED_UNIT_NOT_INFRONT = 0x80, - SPELL_FAILED_WRONG_PET_FOOD = 0x81, - SPELL_FAILED_NOT_WHILE_FATIGUED = 0x82, - SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x83, - SPELL_FAILED_NOT_WHILE_TRADING = 0x84, - SPELL_FAILED_TARGET_NOT_IN_RAID = 0x85, - SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x86, - SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x87, - SPELL_FAILED_PROSPECT_NEED_MORE = 0x88, - SPELL_FAILED_TARGET_FREEFORALL = 0x89, - SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8A, - SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8B, - SPELL_FAILED_TARGET_NOT_GHOST = 0x8C, - SPELL_FAILED_TOO_MANY_SKILLS = 0x8D, - SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8E, - SPELL_FAILED_WRONG_WEATHER = 0x8F, - SPELL_FAILED_DAMAGE_IMMUNE = 0x90, - SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x91, - SPELL_FAILED_PLAY_TIME = 0x92, - SPELL_FAILED_REPUTATION = 0x93, - SPELL_FAILED_MIN_SKILL = 0x94, - SPELL_FAILED_NOT_IN_ARENA = 0x95, - SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x96, - SPELL_FAILED_NOT_ON_STEALTHED = 0x97, - SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x98, - SPELL_FAILED_NOT_ON_MOUNTED = 0x99, - SPELL_FAILED_TOO_SHALLOW = 0x9A, - SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9B, - SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9C, - SPELL_FAILED_BM_OR_INVISGOD = 0x9D, - SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9E, - SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0x9F, - SPELL_FAILED_NOT_IDLE = 0xA0, - SPELL_FAILED_NOT_INACTIVE = 0xA1, - SPELL_FAILED_UNKNOWN = 0xA2 + 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 @@ -327,7 +333,7 @@ inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo) { - return SpellSchoolMask(1 << spellInfo->School); // in 2.4.* this will replaced by simple field access + return SpellSchoolMask(spellInfo->SchoolMask); } // Spell affects related declarations (accessed using SpellMgr functions) Index: src/game/TradeHandler.cpp =================================================================== --- src/game/TradeHandler.cpp (revision 5641) +++ src/game/TradeHandler.cpp (working copy) @@ -25,6 +25,7 @@ #include "Opcodes.h" #include "Player.h" #include "Item.h" +#include "SocialMgr.h" enum TradeStatus { @@ -55,8 +56,32 @@ void WorldSession::SendTradeStatus(uint32 status) { - WorldPacket data(SMSG_TRADE_STATUS,4); - data << (uint32)status; + WorldPacket data; + + switch(status) + { + case TRADE_STATUS_BEGIN_TRADE: + data.Initialize(SMSG_TRADE_STATUS, 4+8); + data << uint32(status); + data << uint64(0); + break; + case TRADE_STATUS_OPEN_WINDOW: + data.Initialize(SMSG_TRADE_STATUS, 4+4); + data << uint32(status); + data << uint32(0); // added in 2.4.0 + break; + case TRADE_STATUS_CLOSE_WINDOW: + data.Initialize(SMSG_TRADE_STATUS, 4+4+1+4); + data << uint32(status); + data << uint32(0); + data << uint8(0); + data << uint32(0); + break; + case TRADE_STATUS_ONLY_CONJURED: + data.Initialize(SMSG_TRADE_STATUS, 4+1); + data << uint32(status); + data << uint8(0); + } SendPacket(&data); } @@ -93,6 +118,7 @@ WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100)); // guess size data << (uint8 ) 1; // can be different (only seen 0 and 1) + data << (uint32) 0; // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?) data << (uint32) TRADE_SLOT_COUNT; // trade slots count/number?, = next field in most cases data << (uint32) TRADE_SLOT_COUNT; // trade slots count/number?, = prev field in most cases data << (uint32) _player->pTrader->tradeGold; // trader gold @@ -459,7 +485,7 @@ return; } - if( pOther->HasInIgnoreList(GetPlayer()->GetGUID()) ) + if( pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()) ) { SendTradeStatus(TRADE_STATUS_IGNORE_YOU); return; Index: src/game/Transports.cpp =================================================================== --- src/game/Transports.cpp (revision 5641) +++ src/game/Transports.cpp (working copy) @@ -150,7 +150,7 @@ return false; } - Object::_Create(guidlow, HIGHGUID_MO_TRANSPORT); + Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(guidlow); Index: src/game/Unit.cpp =================================================================== --- src/game/Unit.cpp (revision 5641) +++ src/game/Unit.cpp (working copy) @@ -1383,7 +1383,7 @@ data << uint32(1); data << uint32(mod->m_auraname); data << (uint32)pdamage; - data << (uint32)spellProto->School; // will be mask in 2.4.x + data << (uint32)GetSpellSchoolMask(spellProto); // will be mask in 2.4.x data << (uint32)absorb; data << (uint32)resist; SendMessageToSet(&data,true); @@ -4358,19 +4358,20 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit) { + sLog.outDebug("Sending: SMSG_SPELLNONMELEEDAMAGELOG"); WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+31)); // we guess size data.append(target->GetPackGUID()); data.append(GetPackGUID()); data << uint32(SpellID); data << uint32(Damage-AbsorbedDamage-Resist-Blocked); - data << uint8(GetFirstSchoolInMask(damageSchoolMask)); // spell school + data << uint8(damageSchoolMask); // spell school data << uint32(AbsorbedDamage); // AbsorbedDamage data << uint32(Resist); // resist - data << uint8(PhysicalDamage); - data << uint8(0); // unk + data << uint8(PhysicalDamage); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name + data << uint8(0); // unk isFromAura data << uint32(Blocked); // blocked - data << uint8(CriticalHit ? 2 : 0); // seen 0x05 also... - data << uint32(0); + data << uint32(CriticalHit ? 0x27 : 0x25); // hitType, flags: 0x2 - critial, 0x10 - replace caster? + data << uint8(0); // isDebug? SendMessageToSet( &data, true ); } @@ -4401,7 +4402,7 @@ data << (uint8)SwingType; // count? // for(i = 0; i < SwingType; ++i) - data << (uint32)GetFirstSchoolInMask(damageSchoolMask); + data << (uint32)damageSchoolMask; data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount); // still need to double check damage data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); @@ -6188,8 +6189,7 @@ void Unit::setPowerType(Powers new_powertype) { - uint32 tem_bytes_0 = GetUInt32Value(UNIT_FIELD_BYTES_0); - SetUInt32Value(UNIT_FIELD_BYTES_0,((tem_bytes_0<<8)>>8) + (uint32(new_powertype)<<24)); + SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype); if ((GetTypeId() == TYPEID_PLAYER) && ((Player*)this)->GetGroup()) ((Player*)this)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE); @@ -6764,6 +6764,7 @@ data << uint32(SpellID); data << uint32(Damage); data << uint8(critical ? 1 : 0); + data << uint8(0); // unused in client? SendMessageToSet(&data, true); } @@ -6775,7 +6776,7 @@ data << uint32(SpellID); data << uint32(powertype); data << uint32(Damage); - data << uint8(critical ? 1 : 0); + //data << uint8(critical ? 1 : 0); // removed in 2.4.0 SendMessageToSet(&data, true); } @@ -9545,9 +9546,8 @@ if(!owner || owner->GetTypeId() != TYPEID_PLAYER) return; - WorldPacket data(SMSG_PET_CAST_FAILED, (4+1+1)); + WorldPacket data(SMSG_PET_CAST_FAILED, (4+1)); data << uint32(spellid); - data << uint8(2); data << uint8(msg); ((Player*)owner)->GetSession()->SendPacket(&data); } @@ -9638,8 +9638,7 @@ void Unit::SetStandState(uint8 state) { - RemoveFlag(UNIT_FIELD_BYTES_1,0x000000FF); - SetFlag(UNIT_FIELD_BYTES_1,state); + SetByteValue(UNIT_FIELD_BYTES_1, 0, state); if(GetTypeId()==TYPEID_PLAYER) { Index: src/game/Unit.h =================================================================== --- src/game/Unit.h (revision 5641) +++ src/game/Unit.h (working copy) @@ -124,26 +124,29 @@ enum ShapeshiftForm { - FORM_CAT = 1, - FORM_TREE = 2, - FORM_TRAVEL = 3, - FORM_AQUA = 4, - FORM_BEAR = 5, - FORM_AMBIENT = 6, - FORM_GHOUL = 7, - FORM_DIREBEAR = 8, - FORM_CREATUREBEAR = 14, - FORM_CREATURECAT = 15, - FORM_GHOSTWOLF = 16, - FORM_BATTLESTANCE = 17, - FORM_DEFENSIVESTANCE = 18, - FORM_BERSERKERSTANCE = 19, - FORM_SWIFT_FLIGHT = 27, - FORM_SHADOW = 28, - FORM_FLIGHT = 29, - FORM_STEALTH = 30, - FORM_MOONKIN = 31, - FORM_SPIRITOFREDEMPTION = 32 + FORM_NONE = 0x00, + FORM_CAT = 0x01, + FORM_TREE = 0x02, + FORM_TRAVEL = 0x03, + FORM_AQUA = 0x04, + FORM_BEAR = 0x05, + FORM_AMBIENT = 0x06, + FORM_GHOUL = 0x07, + FORM_DIREBEAR = 0x08, + FORM_CREATUREBEAR = 0x0E, + FORM_CREATURECAT = 0x0F, + FORM_GHOSTWOLF = 0x10, + FORM_BATTLESTANCE = 0x11, + FORM_DEFENSIVESTANCE = 0x12, + FORM_BERSERKERSTANCE = 0x13, + FORM_TEST = 0x14, + FORM_ZOMBIE = 0x15, + FORM_FLIGHT_EPIC = 0x1B, + FORM_SHADOW = 0x1C, + FORM_FLIGHT = 0x1D, + FORM_STEALTH = 0x1E, + FORM_MOONKIN = 0x1F, + FORM_SPIRITOFREDEMPTION = 0x20 }; #define CREATURE_MAX_SPELLS 4 @@ -669,11 +672,11 @@ uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); } void SetLevel(uint32 lvl); - uint8 getRace() const { return (uint8)(GetUInt32Value(UNIT_FIELD_BYTES_0) & 0xFF); } + uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); } uint32 getRaceMask() const { return 1 << (getRace()-1); } - uint8 getClass() const { return (uint8)((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 8) & 0xFF); } + uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); } uint32 getClassMask() const { return 1 << (getClass()-1); } - uint8 getGender() const { return (uint8)((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 16) & 0xFF); } + uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); } float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT0+stat)); } void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT0+stat, val); } @@ -689,7 +692,7 @@ void SetMaxHealth(uint32 val); int32 ModifyHealth(int32 val); - Powers getPowerType() const { return Powers((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 24) & 0xFF); } + Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); } void setPowerType(Powers power); uint32 GetPower( Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); } uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); } @@ -721,7 +724,7 @@ return (creatureType >= 1) ? (1 << (creatureType - 1)) : 0; } - uint8 getStandState() const { return (uint8)(GetUInt32Value(UNIT_FIELD_BYTES_1) & 0xFF); } + uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); } bool IsStandState() const; void SetStandState(uint8 state); Index: src/game/UpdateFields.h =================================================================== --- src/game/UpdateFields.h (revision 5641) +++ src/game/UpdateFields.h (working copy) @@ -19,7 +19,7 @@ #ifndef _UPDATEFIELDS_AUTO_H #define _UPDATEFIELDS_AUTO_H -// Auto generated for version 2, 3, 3, 7799 +// Auto generated for version 2, 4, 0, 8089 enum EObjectFields { @@ -113,7 +113,7 @@ 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_PET_NAME_TIMESTAMP = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC - it's MS time, not time(NULL)... 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 @@ -154,7 +154,9 @@ 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_END = OBJECT_END + 0x00E2, + 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 @@ -166,177 +168,231 @@ PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000D, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x000E, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0011, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x0014, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x0017, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x001A, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x001C, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x001D, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x0020, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0023, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0026, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x0029, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x002B, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x002C, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x002F, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x0032, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0034, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0035, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0038, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x003A, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x003B, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x003E, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0040, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0041, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x0044, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x0047, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0049, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x004A, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x004D, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x0050, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: GROUP_ONLY - PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0053, // Size: 2, Type: INT, Flags: PRIVATE - PLAYER_VISIBLE_ITEM_1_CREATOR = UNIT_END + 0x0055, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_0 = UNIT_END + 0x0057, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_PROPERTIES = UNIT_END + 0x0063, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_PAD = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_CREATOR = UNIT_END + 0x0065, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_0 = UNIT_END + 0x0067, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_PROPERTIES = UNIT_END + 0x0073, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_PAD = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_CREATOR = UNIT_END + 0x0075, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_0 = UNIT_END + 0x0077, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_PROPERTIES = UNIT_END + 0x0083, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_PAD = UNIT_END + 0x0084, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_CREATOR = UNIT_END + 0x0085, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_0 = UNIT_END + 0x0087, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_PROPERTIES = UNIT_END + 0x0093, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_PAD = UNIT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_CREATOR = UNIT_END + 0x0095, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_0 = UNIT_END + 0x0097, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_PROPERTIES = UNIT_END + 0x00A3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_PAD = UNIT_END + 0x00A4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_CREATOR = UNIT_END + 0x00A5, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_0 = UNIT_END + 0x00A7, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_PROPERTIES = UNIT_END + 0x00B3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_PAD = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_CREATOR = UNIT_END + 0x00B5, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_0 = UNIT_END + 0x00B7, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_PROPERTIES = UNIT_END + 0x00C3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_PAD = UNIT_END + 0x00C4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_CREATOR = UNIT_END + 0x00C5, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_0 = UNIT_END + 0x00C7, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_PROPERTIES = UNIT_END + 0x00D3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_PAD = UNIT_END + 0x00D4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_CREATOR = UNIT_END + 0x00D5, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_0 = UNIT_END + 0x00D7, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_PROPERTIES = UNIT_END + 0x00E3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_PAD = UNIT_END + 0x00E4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_CREATOR = UNIT_END + 0x00E5, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_0 = UNIT_END + 0x00E7, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_PROPERTIES = UNIT_END + 0x00F3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_PAD = UNIT_END + 0x00F4, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_CREATOR = UNIT_END + 0x00F5, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_0 = UNIT_END + 0x00F7, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_PROPERTIES = UNIT_END + 0x0103, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_PAD = UNIT_END + 0x0104, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_CREATOR = UNIT_END + 0x0105, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_0 = UNIT_END + 0x0107, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_PROPERTIES = UNIT_END + 0x0113, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_PAD = UNIT_END + 0x0114, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_CREATOR = UNIT_END + 0x0115, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_0 = UNIT_END + 0x0117, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_PROPERTIES = UNIT_END + 0x0123, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_PAD = UNIT_END + 0x0124, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_CREATOR = UNIT_END + 0x0125, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_0 = UNIT_END + 0x0127, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_PROPERTIES = UNIT_END + 0x0133, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_PAD = UNIT_END + 0x0134, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_CREATOR = UNIT_END + 0x0135, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_0 = UNIT_END + 0x0137, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_PROPERTIES = UNIT_END + 0x0143, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_PAD = UNIT_END + 0x0144, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_CREATOR = UNIT_END + 0x0145, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_0 = UNIT_END + 0x0147, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_PROPERTIES = UNIT_END + 0x0153, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_PAD = UNIT_END + 0x0154, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_CREATOR = UNIT_END + 0x0155, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_0 = UNIT_END + 0x0157, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_PROPERTIES = UNIT_END + 0x0163, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_PAD = UNIT_END + 0x0164, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_CREATOR = UNIT_END + 0x0165, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_0 = UNIT_END + 0x0167, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_PROPERTIES = UNIT_END + 0x0173, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_PAD = UNIT_END + 0x0174, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_CREATOR = UNIT_END + 0x0175, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_0 = UNIT_END + 0x0177, // Size: 12, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_PROPERTIES = UNIT_END + 0x0183, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_PAD = UNIT_END + 0x0184, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_CHOSEN_TITLE = UNIT_END + 0x0185, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x0186, // Size: 46, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x01B4, // Size: 32, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x01D4, // Size: 56, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x020C, // Size: 14, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x021A, // Size: 24, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x0232, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FARSIGHT = UNIT_END + 0x0272, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x0274, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_XP = UNIT_END + 0x0276, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x0277, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x0278, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x03F8, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x03F9, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_CREATURES = UNIT_END + 0x03FA, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_RESOURCES = UNIT_END + 0x03FB, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x03FC, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x03FD, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x03FE, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPERTISE = UNIT_END + 0x03FF, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0400, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0401, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0402, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0403, // Size: 7, Type: FLOAT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK = UNIT_END + 0x040A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x040B, // Size: 64, Type: BYTES, Flags: PRIVATE - PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x044B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COINAGE = UNIT_END + 0x044C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x044D, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0454, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x045B, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0462, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0463, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES = UNIT_END + 0x0464, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_AMMO_ID = UNIT_END + 0x0465, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SELF_RES_SPELL = UNIT_END + 0x0466, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x0467, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x0468, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0474, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_KILLS = UNIT_END + 0x0480, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0481, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0482, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x0483, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES2 = UNIT_END + 0x0484, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0485, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0486, // Size: 24, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_2_4 = UNIT_END + 0x0011, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0012, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0014, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_3_4 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x0017, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_4_4 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x001C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_5_4 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0020, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_6_4 = UNIT_END + 0x0021, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x0024, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_7_4 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x0026, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x0028, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_8_4 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x002A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x002B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x002C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_9_4 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x002F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0030, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_10_4 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x0034, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_11_4 = UNIT_END + 0x0035, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0038, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_12_4 = UNIT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x003A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x003C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_13_4 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x003E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x003F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x0040, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_14_4 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_15_4 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0048, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_16_4 = UNIT_END + 0x0049, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x004C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_17_4 = UNIT_END + 0x004D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x004E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0050, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_18_4 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0054, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_19_4 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x0058, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_20_4 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x005C, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_21_4 = UNIT_END + 0x005D, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0060, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_22_4 = UNIT_END + 0x0061, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0062, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x0064, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_23_4 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x0066, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x0067, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x0068, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_QUEST_LOG_24_4 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: GROUP_ONLY + PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x006B, // Size: 1, Type: INT, Flags: PRIVATE + 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: 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: 64, Type: BYTES, Flags: PRIVATE + PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x048A, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COINAGE = UNIT_END + 0x048B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x048C, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0493, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x049A, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x04A1, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x04A2, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04A3, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x04A4, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_AMMO_ID = UNIT_END + 0x04A5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SELF_RES_SPELL = UNIT_END + 0x04A6, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x04A7, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x04A8, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x04B4, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x04C0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x04C1, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x04C2, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORBALE_KILLS = UNIT_END + 0x04C3, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0x04C4, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x04C5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x04C6, // Size: 24, Type: INT, Flags: PRIVATE // custom // client names: // RATING_WEAPON_SKILL @@ -388,21 +444,20 @@ // RATING_EXPERTISE PLAYER_FIELD_EXPERTISE_RATING = PLAYER_FIELD_COMBAT_RATING_1+23, - PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x049E, // Size: 18, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x04DE, // Size: 18, Type: INT, Flags: PRIVATE // custom PLAYER_FIELD_ARENA_TEAM_ID_2v2 = PLAYER_FIELD_ARENA_TEAM_INFO_1_1, PLAYER_FIELD_ARENA_TEAM_ID_3v3 = PLAYER_FIELD_ARENA_TEAM_INFO_1_1+6, PLAYER_FIELD_ARENA_TEAM_ID_5v5 = PLAYER_FIELD_ARENA_TEAM_INFO_1_1+12, - PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x04B0, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x04B1, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x04B2, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x04B3, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x04B4, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x04B5, // Size: 10, Type: INT, Flags: PRIVATE - PLAYER_FIELD_PADDING = UNIT_END + 0x04BF, // Size: 1, Type: INT, Flags: NONE - PLAYER_END = UNIT_END + 0x04C0, + PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x04F0, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x04F1, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_MANA_REGEN = UNIT_END + 0x04F2, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT = UNIT_END + 0x04F3, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x04F4, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x04F5, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_END = UNIT_END + 0x050E, }; enum EGameObjectFields @@ -436,7 +491,7 @@ DYNAMICOBJECT_POS_Y = OBJECT_END + 0x0006, // Size: 1, Type: FLOAT, Flags: PUBLIC DYNAMICOBJECT_POS_Z = OBJECT_END + 0x0007, // Size: 1, Type: FLOAT, Flags: PUBLIC DYNAMICOBJECT_FACING = OBJECT_END + 0x0008, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_PAD = OBJECT_END + 0x0009, // Size: 1, Type: BYTES, Flags: PUBLIC + DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC DYNAMICOBJECT_END = OBJECT_END + 0x000A, }; Index: src/game/WorldSession.cpp =================================================================== --- src/game/WorldSession.cpp (revision 5641) +++ src/game/WorldSession.cpp (working copy) @@ -37,6 +37,7 @@ #include "BattleGroundMgr.h" #include "Language.h" // for CMSG_DISMOUNT handler #include "Chat.h" +#include "SocialMgr.h" /// WorldSession constructor WorldSession::WorldSession(uint32 id, WorldSocket *sock, uint32 sec, bool tbc, time_t mute_time, LocaleConstant locale) : @@ -127,6 +128,7 @@ objmgr.opcodeTable[ CMSG_DEL_FRIEND ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode ); objmgr.opcodeTable[ CMSG_ADD_IGNORE ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode ); objmgr.opcodeTable[ CMSG_DEL_IGNORE ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode ); + objmgr.opcodeTable[ CMSG_FRIEND_SET_NOTE ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode ); objmgr.opcodeTable[ CMSG_BUG ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode ); objmgr.opcodeTable[ CMSG_SET_AMMO ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode ); objmgr.opcodeTable[ CMSG_AREATRIGGER ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode ); @@ -193,6 +195,7 @@ objmgr.opcodeTable[ CMSG_GROUP_UNINVITE_GUID ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode ); objmgr.opcodeTable[ CMSG_GROUP_SET_LEADER ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode ); objmgr.opcodeTable[ CMSG_GROUP_DISBAND ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGroupDisbandOpcode ); + objmgr.opcodeTable[ CMSG_GROUP_PASS_ON_LOOT_TOGGLE ] = OpcodeHandler( STATUS_AUTHED, &WorldSession::HandleGroupPassOnLootOpcode ); objmgr.opcodeTable[ CMSG_LOOT_METHOD ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode ); objmgr.opcodeTable[ CMSG_LOOT_ROLL ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleLootRoll ); objmgr.opcodeTable[ CMSG_REQUEST_PARTY_MEMBER_STATS ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode ); @@ -305,6 +308,7 @@ objmgr.opcodeTable[ CMSG_UNLEARN_SKILL ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode ); objmgr.opcodeTable[ CMSG_QUESTGIVER_STATUS_QUERY ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode ); + objmgr.opcodeTable[ CMSG_QUESTGIVER_STATUS_QUERY_MULTIPLE ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryMultipleOpcode ); objmgr.opcodeTable[ CMSG_QUESTGIVER_HELLO ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode ); objmgr.opcodeTable[ CMSG_QUESTGIVER_ACCEPT_QUEST ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode ); objmgr.opcodeTable[ CMSG_QUESTGIVER_CHOOSE_REWARD ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode ); @@ -471,6 +475,8 @@ objmgr.opcodeTable[ CMSG_GUILD_BANK_DEPOSIT_ITEM ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem ); objmgr.opcodeTable[ CMSG_GUILD_BANK_MODIFY_TAB ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab ); objmgr.opcodeTable[ CMSG_GUILD_BANK_BUY_TAB ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab ); + objmgr.opcodeTable[ MSG_GUILD_BANK_TAB_TEXT ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText ); + objmgr.opcodeTable[ CMSG_GUILD_BANK_SET_TAB_TEXT ] = OpcodeHandler( STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText ); } void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const @@ -721,10 +727,7 @@ _player->GetGroup()->SendUpdate(); ///- Broadcast a logout message to the player's friends - WorldPacket data(SMSG_FRIEND_STATUS, 9); - data<GetGUID(); - _player->BroadcastPacketToFriendListers(&data); + sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), "", true); ///- Delete the player object _player->CleanupsBeforeDelete(); // do some cleanup before deleting to prevent crash at crossreferences to already deleted data @@ -734,7 +737,7 @@ _player = NULL; ///- Send the 'logout complete' packet to the client - data.Initialize( SMSG_LOGOUT_COMPLETE, 0 ); + WorldPacket data( SMSG_LOGOUT_COMPLETE, 0 ); SendPacket( &data ); ///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline Index: src/game/WorldSession.h =================================================================== --- src/game/WorldSession.h (revision 5641) +++ src/game/WorldSession.h (working copy) @@ -264,6 +264,7 @@ void HandleDelFriendOpcode(WorldPacket& recvPacket); void HandleAddIgnoreOpcode(WorldPacket& recvPacket); void HandleDelIgnoreOpcode(WorldPacket& recvPacket); + void HandleSetFriendNoteOpcode(WorldPacket& recvPacket); void HandleBugOpcode(WorldPacket& recvPacket); void HandleSetAmmoOpcode(WorldPacket& recvPacket); void HandleItemNameQueryOpcode(WorldPacket& recvPacket); @@ -310,6 +311,7 @@ void HandleGroupUninvite(uint64 guid, std::string name); void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); void HandleGroupDisbandOpcode(WorldPacket& recvPacket); + void HandleGroupPassOnLootOpcode( WorldPacket &recv_data ); void HandleLootMethodOpcode(WorldPacket& recvPacket); void HandleLootRoll( WorldPacket &recv_data ); void HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ); @@ -445,6 +447,7 @@ void HandleUnlearnSkillOpcode(WorldPacket& recvPacket); void HandleQuestgiverStatusQueryOpcode(WorldPacket& recvPacket); + void HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket& recvPacket); void HandleQuestgiverHelloOpcode(WorldPacket& recvPacket); void HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvPacket); void HandleQuestgiverQuestQueryOpcode(WorldPacket& recvPacket); @@ -587,6 +590,8 @@ void HandleGuildBankDepositItem(WorldPacket& recv_data); void HandleGuildBankModifyTab(WorldPacket& recv_data); void HandleGuildBankBuyTab(WorldPacket& recv_data); + void HandleGuildBankTabText(WorldPacket& recv_data); + void HandleGuildBankSetTabText(WorldPacket& recv_data); private: // private trade methods void moveItems(Item* myItems[], Item* hisItems[]); Index: src/game/WorldSocket.h =================================================================== --- src/game/WorldSocket.h (revision 5641) +++ src/game/WorldSocket.h (working copy) @@ -28,101 +28,104 @@ enum ResponseCodes { - RESPONSE_SUCCESS = 0x00, - RESPONSE_FAILURE = 0x01, - RESPONSE_CANCELLED = 0x02, - RESPONSE_DISCONNECTED = 0x03, - RESPONSE_FAILED_TO_CONNECT = 0x04, - RESPONSE_CONNECTED = 0x05, - RESPONSE_VERSION_MISMATCH = 0x06, + RESPONSE_SUCCESS = 0x00, + RESPONSE_FAILURE = 0x01, + RESPONSE_CANCELLED = 0x02, + RESPONSE_DISCONNECTED = 0x03, + RESPONSE_FAILED_TO_CONNECT = 0x04, + RESPONSE_CONNECTED = 0x05, + RESPONSE_VERSION_MISMATCH = 0x06, - CSTATUS_CONNECTING = 0x07, - CSTATUS_NEGOTIATING_SECURITY = 0x08, - CSTATUS_NEGOTIATION_COMPLETE = 0x09, - CSTATUS_NEGOTIATION_FAILED = 0x0A, - CSTATUS_AUTHENTICATING = 0x0B, + CSTATUS_CONNECTING = 0x07, + CSTATUS_NEGOTIATING_SECURITY = 0x08, + CSTATUS_NEGOTIATION_COMPLETE = 0x09, + CSTATUS_NEGOTIATION_FAILED = 0x0A, + CSTATUS_AUTHENTICATING = 0x0B, - AUTH_OK = 0x0C, - AUTH_FAILED = 0x0D, - AUTH_REJECT = 0x0E, - AUTH_BAD_SERVER_PROOF = 0x0F, - AUTH_UNAVAILABLE = 0x10, - AUTH_SYSTEM_ERROR = 0x11, - AUTH_BILLING_ERROR = 0x12, - AUTH_BILLING_EXPIRED = 0x13, - AUTH_VERSION_MISMATCH = 0x14, - AUTH_UNKNOWN_ACCOUNT = 0x15, - AUTH_INCORRECT_PASSWORD = 0x16, - AUTH_SESSION_EXPIRED = 0x17, - AUTH_SERVER_SHUTTING_DOWN = 0x18, - AUTH_ALREADY_LOGGING_IN = 0x19, - AUTH_LOGIN_SERVER_NOT_FOUND = 0x1A, - AUTH_WAIT_QUEUE = 0x1B, - AUTH_BANNED = 0x1C, - AUTH_ALREADY_ONLINE = 0x1D, - AUTH_NO_TIME = 0x1E, - AUTH_DB_BUSY = 0x1F, - AUTH_SUSPENDED = 0x20, - AUTH_PARENTAL_CONTROL = 0x21, + AUTH_OK = 0x0C, + AUTH_FAILED = 0x0D, + AUTH_REJECT = 0x0E, + AUTH_BAD_SERVER_PROOF = 0x0F, + AUTH_UNAVAILABLE = 0x10, + AUTH_SYSTEM_ERROR = 0x11, + AUTH_BILLING_ERROR = 0x12, + AUTH_BILLING_EXPIRED = 0x13, + AUTH_VERSION_MISMATCH = 0x14, + AUTH_UNKNOWN_ACCOUNT = 0x15, + AUTH_INCORRECT_PASSWORD = 0x16, + AUTH_SESSION_EXPIRED = 0x17, + AUTH_SERVER_SHUTTING_DOWN = 0x18, + AUTH_ALREADY_LOGGING_IN = 0x19, + AUTH_LOGIN_SERVER_NOT_FOUND = 0x1A, + AUTH_WAIT_QUEUE = 0x1B, + AUTH_BANNED = 0x1C, + AUTH_ALREADY_ONLINE = 0x1D, + AUTH_NO_TIME = 0x1E, + AUTH_DB_BUSY = 0x1F, + AUTH_SUSPENDED = 0x20, + AUTH_PARENTAL_CONTROL = 0x21, + AUTH_LOCKED_ENFORCED = 0x22, - REALM_LIST_IN_PROGRESS = 0x22, - REALM_LIST_SUCCESS = 0x23, - REALM_LIST_FAILED = 0x24, - REALM_LIST_INVALID = 0x25, - REALM_LIST_REALM_NOT_FOUND = 0x26, + REALM_LIST_IN_PROGRESS = 0x23, + REALM_LIST_SUCCESS = 0x24, + REALM_LIST_FAILED = 0x25, + REALM_LIST_INVALID = 0x26, + REALM_LIST_REALM_NOT_FOUND = 0x27, - ACCOUNT_CREATE_IN_PROGRESS = 0x27, - ACCOUNT_CREATE_SUCCESS = 0x28, - ACCOUNT_CREATE_FAILED = 0x29, + ACCOUNT_CREATE_IN_PROGRESS = 0x28, + ACCOUNT_CREATE_SUCCESS = 0x29, + ACCOUNT_CREATE_FAILED = 0x2A, - CHAR_LIST_RETRIEVING = 0x2A, - CHAR_LIST_RETRIEVED = 0x2B, - CHAR_LIST_FAILED = 0x2C, + CHAR_LIST_RETRIEVING = 0x2B, + CHAR_LIST_RETRIEVED = 0x2C, + CHAR_LIST_FAILED = 0x2D, + CHAR_CREATE_IN_PROGRESS = 0x2E, + CHAR_CREATE_SUCCESS = 0x2F, + CHAR_CREATE_ERROR = 0x30, + CHAR_CREATE_FAILED = 0x31, + CHAR_CREATE_NAME_IN_USE = 0x32, + CHAR_CREATE_DISABLED = 0x33, + CHAR_CREATE_PVP_TEAMS_VIOLATION = 0x34, + CHAR_CREATE_SERVER_LIMIT = 0x35, + CHAR_CREATE_ACCOUNT_LIMIT = 0x36, + CHAR_CREATE_SERVER_QUEUE = 0x37, + CHAR_CREATE_ONLY_EXISTING = 0x38, + CHAR_CREATE_EXPANSION = 0x39, - CHAR_CREATE_IN_PROGRESS = 0x2D, - CHAR_CREATE_SUCCESS = 0x2E, - CHAR_CREATE_ERROR = 0x2F, - CHAR_CREATE_FAILED = 0x30, - CHAR_CREATE_NAME_IN_USE = 0x31, - CHAR_CREATE_DISABLED = 0x32, - CHAR_CREATE_PVP_TEAMS_VIOLATION = 0x33, - CHAR_CREATE_SERVER_LIMIT = 0x34, - CHAR_CREATE_ACCOUNT_LIMIT = 0x35, - CHAR_CREATE_SERVER_QUEUE = 0x36, - CHAR_CREATE_ONLY_EXISTING = 0x37, - CHAR_CREATE_EXPANSION = 0x38, + CHAR_DELETE_IN_PROGRESS = 0x3A, + CHAR_DELETE_SUCCESS = 0x3B, + CHAR_DELETE_FAILED = 0x3C, + CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3D, + CHAR_DELETE_FAILED_GUILD_LEADER = 0x3E, - CHAR_DELETE_IN_PROGRESS = 0x39, - CHAR_DELETE_SUCCESS = 0x3A, - CHAR_DELETE_FAILED = 0x3B, - CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x3C, - CHAR_DELETE_FAILED_GUILD_LEADER = 0x3D, + CHAR_LOGIN_IN_PROGRESS = 0x3F, + CHAR_LOGIN_SUCCESS = 0x40, + CHAR_LOGIN_NO_WORLD = 0x41, + CHAR_LOGIN_DUPLICATE_CHARACTER = 0x42, + CHAR_LOGIN_NO_INSTANCES = 0x43, + CHAR_LOGIN_FAILED = 0x44, + CHAR_LOGIN_DISABLED = 0x45, + CHAR_LOGIN_NO_CHARACTER = 0x46, + CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x47, + CHAR_LOGIN_LOCKED_BY_BILLING = 0x48, - CHAR_LOGIN_IN_PROGRESS = 0x3E, - CHAR_LOGIN_SUCCESS = 0x3F, - CHAR_LOGIN_NO_WORLD = 0x40, - CHAR_LOGIN_DUPLICATE_CHARACTER = 0x41, - CHAR_LOGIN_NO_INSTANCES = 0x42, - CHAR_LOGIN_FAILED = 0x43, - CHAR_LOGIN_DISABLED = 0x44, - CHAR_LOGIN_NO_CHARACTER = 0x45, - CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x46, - CHAR_LOGIN_LOCKED_BY_BILLING = 0x47, - - CHAR_NAME_NO_NAME = 0x48, - CHAR_NAME_TOO_SHORT = 0x49, - CHAR_NAME_TOO_LONG = 0x4A, - CHAR_NAME_INVALID_CHARACTER = 0x4B, - CHAR_NAME_MIXED_LANGUAGES = 0x4C, - CHAR_NAME_PROFANE = 0x4D, - CHAR_NAME_RESERVED = 0x4E, - CHAR_NAME_INVALID_APOSTROPHE = 0x4F, - CHAR_NAME_MULTIPLE_APOSTROPHES = 0x50, - CHAR_NAME_THREE_CONSECUTIVE = 0x51, - CHAR_NAME_INVALID_SPACE = 0x53, - CHAR_NAME_CONSECUTIVE_SPACES = 0x54, - CHAR_NAME_FAILURE = 0x55, - CHAR_NAME_SUCCESS = 0x56, + CHAR_NAME_SUCCESS = 0x49, + CHAR_NAME_FAILURE = 0x4A, + CHAR_NAME_NO_NAME = 0x4B, + CHAR_NAME_TOO_SHORT = 0x4C, + CHAR_NAME_TOO_LONG = 0x4D, + CHAR_NAME_INVALID_CHARACTER = 0x4E, + CHAR_NAME_MIXED_LANGUAGES = 0x4F, + CHAR_NAME_PROFANE = 0x50, + CHAR_NAME_RESERVED = 0x51, + CHAR_NAME_INVALID_APOSTROPHE = 0x52, + CHAR_NAME_MULTIPLE_APOSTROPHES = 0x53, + CHAR_NAME_THREE_CONSECUTIVE = 0x54, + CHAR_NAME_INVALID_SPACE = 0x55, + CHAR_NAME_CONSECUTIVE_SPACES = 0x56, + CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x57, + CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x58, + CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x59, }; class WorldPacket; Index: src/realmd/AuthCodes.h =================================================================== --- src/realmd/AuthCodes.h (revision 5641) +++ src/realmd/AuthCodes.h (working copy) @@ -42,4 +42,32 @@ REALM_AUTH_UNKNOWN5=0x0e, ///< Connected. REALM_AUTH_PARENTAL_CONTROL=0x0f ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at }; + +enum LoginResult +{ + LOGIN_OK = 0x00, + LOGIN_FAILED = 0x01, + LOGIN_FAILED2 = 0x02, + LOGIN_BANNED = 0x03, + LOGIN_UNKNOWN_ACCOUNT = 0x04, + LOGIN_UNKNOWN_ACCOUNT3 = 0x05, + LOGIN_ALREADYONLINE = 0x06, + LOGIN_NOTIME = 0x07, + LOGIN_DBBUSY = 0x08, + LOGIN_BADVERSION = 0x09, + LOGIN_DOWNLOAD_FILE = 0x0A, + LOGIN_FAILED3 = 0x0B, + LOGIN_SUSPENDED = 0x0C, + LOGIN_FAILED4 = 0x0D, + LOGIN_CONNECTED = 0x0E, + LOGIN_PARENTALCONTROL = 0x0F, + LOGIN_LOCKED_ENFORCED = 0x10, +}; + +// we need to stick to 1 version or half of the stuff will work for someone +// others will not and opposite +// will only support WoW and WoW:TBC 2.4.1 client build 8125... + +#define EXPECTED_MANGOS_CLIENT_BUILD {8125, 0} + #endif Index: src/realmd/AuthSocket.cpp =================================================================== --- src/realmd/AuthSocket.cpp (revision 5641) +++ src/realmd/AuthSocket.cpp (working copy) @@ -129,8 +129,9 @@ uint8 cmd; uint8 error; uint8 M2[20]; + uint16 unk1; uint32 unk2; - uint16 unk3; + uint32 unk3; } sAuthLogonProof_S; typedef struct XFER_INIT @@ -451,12 +452,12 @@ ///- Fill the response packet with the result pkt << (uint8)REALM_AUTH_SUCCESS; - pkt.append(B.AsByteArray(), B.GetNumBytes()); + pkt.append(B.AsByteArray(), B.GetNumBytes()); // 32 bytes pkt << (uint8)1; pkt.append(g.AsByteArray(), 1); pkt << (uint8)32; pkt.append(N.AsByteArray(), 32); - pkt.append(s.AsByteArray(), s.GetNumBytes()); + pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes pkt.append(unk3.AsByteArray(), 16); pkt << (uint8)0; // Added in 1.12.x client branch @@ -636,7 +637,8 @@ memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; - proof.unk2 = 0; + proof.unk1 = 0; + proof.unk2 = 0x80; proof.unk3 = 0; SendBuf((char *)&proof, sizeof(proof)); Index: src/shared/Common.h =================================================================== --- src/shared/Common.h (revision 5641) +++ src/shared/Common.h (working copy) @@ -43,12 +43,6 @@ #endif // __SHOW_STUPID_WARNINGS__ #endif // __GNUC__ -// we need to stick to 1 version or half of the stuff will work for someone -// others will not and opposite -// will only support WoW and WoW:TBC 2.3.3 client build 7799... - -#define EXPECTED_MANGOS_CLIENT_BUILD {7799, 0} - // must be the first thing to include for it to work #include "MemoryLeaks.h" Index: src/shared/Database/DBCfmt.cpp =================================================================== --- src/shared/Database/DBCfmt.cpp (revision 5641) +++ src/shared/Database/DBCfmt.cpp (working copy) @@ -19,12 +19,12 @@ const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxx"; const char AreaTriggerEntryfmt[]="niffffffff"; const char BankBagSlotPricesEntryfmt[]="ni"; -const char BattlemasterListEntryfmt[]="niiixxxxxiiiixxssssssssssssssssx"; +const char BattlemasterListEntryfmt[]="niiixxxxxiiiixxssssssssssssssssxx"; // data not sorted (more compact store) const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx"; -const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxx"; -const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxx"; -const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxxxxxxx"; +const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxx"; const char CreatureFamilyfmt[]="nxxxxxiissssssssssssssssxx"; const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; const char DurabilityQualityfmt[]="nf"; @@ -48,13 +48,13 @@ const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiii"; const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii"; const char LockEntryfmt[]="niiiiixxxiiiiixxxiixxxxxxxxxxxxxx"; -const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxx"; +const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxx"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxi"; const char SkillLineAbilityfmt[]="xiniixxiiiiixxi"; const char SpellCastTimefmt[]="nixx"; const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niixiiiiiiixiiiiiiixxiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiifffixiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiixxfffxxxiii"; +const char SpellEntryfmt[]="nixiiiiiiixxiiiiixiixxiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiifffixiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiixxfffxxxiiii"; const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; const char SpellItemEnchantmentfmt[]="niiiiiixxxiiissssssssssssssssxiiii"; const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; Index: src/shared/Database/DBCStores.cpp =================================================================== --- src/shared/Database/DBCStores.cpp (revision 5641) +++ src/shared/Database/DBCStores.cpp (working copy) @@ -396,23 +396,19 @@ exit(1); } - // check at up-to-date DBC files (45743 is last added spell in 2.3.2 and 2.3.3) - if( !sSpellStore.LookupEntry(45743)) + // check at up-to-date DBC files (47653 is last added spell in 2.4.1) + // check at up-to-date DBC files (47280 is last added spell in abilities in 2.4.1) + // check at up-to-date DBC files (598 is last map added in 2.4.1) + // check at up-to-date DBC files (4140 is last area added in 2.4.1) + if( !sSpellStore.LookupEntry(47653) || + !sSkillLineAbilityStore.LookupEntry(47280) || + !sMapStore.LookupEntry(598) || + !sAreaStore.LookupEntry(4140) ) { sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } - // check at up-to-date DBC files (44958 changes in 2.3.3) - if(SkillLineAbilityEntry const* ability = sSkillLineAbilityStore.LookupEntry(44958)) - { - if( ability->max_value != 250 ) - { - sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); - exit(1); - } - } - sLog.outString(); sLog.outString( ">> Loaded %d data stores", DBCFilesCount ); sLog.outString(); Index: src/shared/Database/DBCStructure.h =================================================================== --- src/shared/Database/DBCStructure.h (revision 5641) +++ src/shared/Database/DBCStructure.h (working copy) @@ -444,16 +444,16 @@ struct SpellEntry { uint32 Id; // 0 normally counted from 0 field (but some tools start counting from 1, check this before tool use for data view!) - uint32 School; // 1 (will removed in 2.4.0) - uint32 Category; // 2 - // 3 not used - uint32 Dispel; // 4 - uint32 Mechanic; // 5 - uint32 Attributes; // 6 - uint32 AttributesEx; // 7 - uint32 AttributesEx2; // 8 - uint32 AttributesEx3; // 9 - uint32 AttributesExEx; // 10 + uint32 Category; // 1 + // 2 not used + uint32 Dispel; // 3 + uint32 Mechanic; // 4 + uint32 Attributes; // 5 + uint32 AttributesEx; // 6 + uint32 AttributesEx2; // 7 + uint32 AttributesEx3; // 8 + uint32 AttributesExEx; // 9 + // 10 not used // 11 not used uint32 Stances; // 12 uint32 StancesNot; // 13 @@ -536,6 +536,7 @@ //uint32 unk3[3]; // 205-207 not used null uint32 TotemCategory[2]; // 208-209 uint32 AreaId; // 210 + uint32 SchoolMask; // school mask private: // prevent creating custom entries (copy data from original infact) Index: win/VC71/game.vcproj =================================================================== --- win/VC71/game.vcproj (revision 5641) +++ win/VC71/game.vcproj (working copy) @@ -664,6 +664,12 @@ RelativePath="..\..\src\game\RedZoneDistrict.h"> + + + + + + + + Index: win/VC90/game.vcproj =================================================================== --- win/VC90/game.vcproj (revision 5641) +++ win/VC90/game.vcproj (working copy) @@ -1064,6 +1064,14 @@ > + + + +