diff options
Diffstat (limited to 'src')
227 files changed, 24041 insertions, 14105 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp index ace18e7b45c..7a97cbee3de 100644 --- a/src/server/authserver/Authentication/AuthCodes.cpp +++ b/src/server/authserver/Authentication/AuthCodes.cpp @@ -19,20 +19,9 @@ namespace AuthHelper { - bool IsPreBCAcceptedClientBuild(int build) - { - int accepted_versions[] = PRE_BC_ACCEPTED_CLIENT_BUILD; - - for (int i = 0; accepted_versions[i]; ++i) - if (build == accepted_versions[i]) - return true; - - return false; - } - - bool IsPostBCAcceptedClientBuild(int build) + bool IsAcceptedClientBuild(int build) { - int accepted_versions[] = POST_BC_ACCEPTED_CLIENT_BUILD; + static int accepted_versions[] = TRINITYCORE_ACCEPTED_CLIENT_BUILD; for (int i = 0; accepted_versions[i]; ++i) if (build == accepted_versions[i]) @@ -40,9 +29,4 @@ namespace AuthHelper return false; } - - bool IsAcceptedClientBuild(int build) - { - return (IsPostBCAcceptedClientBuild(build) || IsPreBCAcceptedClientBuild(build)); - } }; diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index f940d459d40..9d631a5800d 100755 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -65,21 +65,12 @@ enum LoginResult LOGIN_LOCKED_ENFORCED = 0x10, }; -#define POST_BC_ACCEPTED_CLIENT_BUILD {12340, 11723, 11403, 11159, 10571, 10505, 10146, 9947, 8606, 0} -#define PRE_BC_ACCEPTED_CLIENT_BUILD {5875, 6005, 0} +#define TRINITYCORE_ACCEPTED_CLIENT_BUILD {15595, 12340, 0} // accept one Cataclysm and one Wrath of the Lich King build -enum ExpansionFlags -{ - POST_BC_EXP_FLAG = 0x2, - PRE_BC_EXP_FLAG = 0x1, - NO_VALID_EXP_FLAG = 0x0 -}; namespace AuthHelper { bool IsAcceptedClientBuild(int build); - bool IsPostBCAcceptedClientBuild(int build); - bool IsPreBCAcceptedClientBuild(int build); }; #endif diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp index 0794d9a802a..c0cf24efbfb 100755..100644 --- a/src/server/authserver/Server/AuthSocket.cpp +++ b/src/server/authserver/Server/AuthSocket.cpp @@ -343,7 +343,6 @@ bool AuthSocket::_HandleLogonChallenge() _login = (const char*)ch->I; _build = ch->build; - _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); _os = (const char*)ch->os; if (_os.size() > 4) @@ -352,8 +351,8 @@ bool AuthSocket::_HandleLogonChallenge() // Restore string order as its byte order is reversed std::reverse(_os.begin(), _os.end()); - pkt << (uint8)AUTH_LOGON_CHALLENGE; - pkt << (uint8)0x00; + pkt << uint8(AUTH_LOGON_CHALLENGE); + pkt << uint8(0x00); // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); @@ -389,7 +388,7 @@ bool AuthSocket::_HandleLogonChallenge() if (strcmp(fields[3].GetCString(), ip_address.c_str())) { sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP differs"); - pkt << (uint8) WOW_FAIL_SUSPENDED; + pkt << uint8(WOW_FAIL_SUSPENDED); locked = true; } else @@ -450,7 +449,11 @@ bool AuthSocket::_HandleLogonChallenge() unk3.SetRand(16 * 8); // Fill the response packet with the result - pkt << uint8(WOW_SUCCESS); + // If the client has no valid version + if (!AuthHelper::IsAcceptedClientBuild(_build)) + pkt << uint8(WOW_FAIL_VERSION_INVALID); + else + pkt << uint8(WOW_SUCCESS); // B may be calculated < 32B so we force minimal length to 32B pkt.append(B.AsByteArray(32), 32); // 32 bytes @@ -495,7 +498,7 @@ bool AuthSocket::_HandleLogonChallenge() } } else //no account - pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT; + pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT); } socket().send((char const*)pkt.contents(), pkt.size()); @@ -512,15 +515,6 @@ bool AuthSocket::_HandleLogonProof() if (!socket().recv((char *)&lp, sizeof(sAuthLogonProof_C))) return false; - // If the client has no valid version - if (_expversion == NO_VALID_EXP_FLAG) - { - // Check if we have the appropriate patch on the disk - sLog->outDebug(LOG_FILTER_NETWORKIO, "Client with invalid version, patching is not implemented"); - socket().shutdown(); - return true; - } - // Continue the SRP6 calculation based on data received from the client BigNumber A; @@ -621,26 +615,14 @@ bool AuthSocket::_HandleLogonProof() sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); - if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients - { - sAuthLogonProof_S proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) - proof.unk2 = 0x00; // SurveyId - proof.unk3 = 0x00; - socket().send((char *)&proof, sizeof(proof)); - } - else - { - sAuthLogonProof_S_Old proof; - memcpy(proof.M2, sha.GetDigest(), 20); - proof.cmd = AUTH_LOGON_PROOF; - proof.error = 0; - proof.unk2 = 0x00; - socket().send((char *)&proof, sizeof(proof)); - } + sAuthLogonProof_S proof; + memcpy(proof.M2, sha.GetDigest(), 20); + proof.cmd = AUTH_LOGON_PROOF; + proof.error = 0; + proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament) + proof.unk2 = 0x00; // SurveyId + proof.unk3 = 0x00; + socket().send((char *)&proof, sizeof(proof)); _authed = true; } @@ -749,7 +731,6 @@ bool AuthSocket::_HandleReconnectChallenge() // Reinitialize build, expansion and the account securitylevel _build = ch->build; - _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); _os = (const char*)ch->os; if (_os.size() > 4) @@ -766,11 +747,11 @@ bool AuthSocket::_HandleReconnectChallenge() // Sending response ByteBuffer pkt; - pkt << (uint8)AUTH_RECONNECT_CHALLENGE; - pkt << (uint8)0x00; + pkt << uint8(AUTH_RECONNECT_CHALLENGE); + pkt << uint8(0x00); _reconnectProof.SetRand(16 * 8); pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random - pkt << (uint64)0x00 << (uint64)0x00; // 16 bytes zeros + pkt << uint64(0x00) << uint64(0x00); // 16 bytes zeros socket().send((char const*)pkt.contents(), pkt.size()); return true; } @@ -800,9 +781,9 @@ bool AuthSocket::_HandleReconnectProof() { // Sending response ByteBuffer pkt; - pkt << (uint8)AUTH_RECONNECT_PROOF; - pkt << (uint8)0x00; - pkt << (uint16)0x00; // 2 bytes zeros + pkt << uint8(AUTH_RECONNECT_PROOF); + pkt << uint8(0x00); + pkt << uint16(0x00); // 2 bytes zeros socket().send((char const*)pkt.contents(), pkt.size()); _authed = true; return true; @@ -849,10 +830,8 @@ bool AuthSocket::_HandleRealmList() for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client - if ((_expversion & POST_BC_EXP_FLAG) && i->second.gamebuild != _build) + if (i->second.gamebuild != _build) continue; - else if ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) - continue; uint8 AmountOfCharacters; @@ -869,18 +848,14 @@ bool AuthSocket::_HandleRealmList() uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; pkt << i->second.icon; // realm type - if ( _expversion & POST_BC_EXP_FLAG ) // only 2.x and 3.x clients - pkt << lock; // if 1, then realm locked + pkt << lock; // if 1, then realm locked pkt << uint8(i->second.flag); // RealmFlags pkt << i->first; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; // realm category - if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients - pkt << (uint8)0x2C; // unk, may be realm number/id? - else - pkt << (uint8)0x0; // 1.12.1 and 1.12.2 clients + pkt << uint8(0x2C); // unk, may be realm number/id? if (i->second.flag & REALM_FLAG_SPECIFYBUILD) { @@ -894,28 +869,18 @@ bool AuthSocket::_HandleRealmList() ++RealmListSize; } - if ( _expversion & POST_BC_EXP_FLAG ) // 2.x and 3.x clients - { - pkt << (uint8)0x10; - pkt << (uint8)0x00; - } - else // 1.12.1 and 1.12.2 clients - { - pkt << (uint8)0x00; - pkt << (uint8)0x02; - } + pkt << uint8(0x10); + pkt << uint8(0x00); + // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << (uint32)0; - if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients - RealmListSizeBuffer << (uint16)RealmListSize; - else - RealmListSizeBuffer << (uint32)RealmListSize; + RealmListSizeBuffer << uint16(RealmListSize); ByteBuffer hdr; - hdr << (uint8) REALM_LIST; - hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); + hdr << uint8(REALM_LIST); + hdr << uint16((pkt.size() + RealmListSizeBuffer.size())); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist diff --git a/src/server/authserver/Server/AuthSocket.h b/src/server/authserver/Server/AuthSocket.h index 9be2136b55c..edd2b345183 100755 --- a/src/server/authserver/Server/AuthSocket.h +++ b/src/server/authserver/Server/AuthSocket.h @@ -70,7 +70,6 @@ private: std::string _localizationName; std::string _os; uint16 _build; - uint8 _expversion; AccountTypes _accountSecurityLevel; }; diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index aa14bc1b56e..82abfc0454c 100755 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -1310,7 +1310,7 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger return false; //Check for power - if (!triggered && me->GetPower((Powers)spell->PowerType) < spell->CalcPowerCost(me, spell->GetSchoolMask())) + if (!triggered && (uint32)me->GetPower((Powers)spell->PowerType) < spell->CalcPowerCost(me, spell->GetSchoolMask())) return false; //Unit is out of range of this spell diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp index 7289a4eed28..af25ba6af1d 100755 --- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp @@ -514,7 +514,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { //output as debug for now, also because there's no general rule all spells have RecoveryTime if (temp.event_param3 < spell->RecoveryTime) - sLog->outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1, action.cast.spellId, spell->RecoveryTime, temp.event_param3); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1, action.cast.spellId, spell->RecoveryTime, temp.event_param3); } } */ diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 76bb3aaa76a..1611ae2b85d 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -221,7 +221,7 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec continue; //Continue if we don't have the mana to actually cast this spell - if (tempSpell->ManaCost > me->GetPower(Powers(tempSpell->PowerType))) + if (tempSpell->ManaCost > (uint32)me->GetPower(Powers(tempSpell->PowerType))) continue; //Check if the spell meets our range requirements diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 05965d8ffa0..2a81339a930 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -23,6 +23,7 @@ #include "CreatureAI.h" #include "Unit.h" #include "Spell.h" +#include "DB2Stores.h" //#include "SmartScript.h" //#include "SmartAI.h" diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 191d91b61a7..68467fe4423 100755..100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -40,6 +40,7 @@ #include "BattlegroundAB.h" #include "Map.h" #include "InstanceScript.h" +#include "Group.h" namespace Trinity { @@ -155,14 +156,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) return false; } return true; - case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD: - if (player_dead.own_team_flag > 1) - { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD (%u) has wrong boolean value1 (%u).", - criteria->ID, criteria->requiredType, dataType, player_dead.own_team_flag); - return false; - } - return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA: case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA: { @@ -187,14 +180,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) } return true; } - case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA: - if (!GetAreaEntryByAreaID(area.id)) - { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) has wrong area id in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, area.id); - return false; - } - return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL: if (level.minlevel > STRONG_MAX_LEVEL) { @@ -219,14 +204,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) return false; } return true; - case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY: - if (difficulty.difficulty >= MAX_DIFFICULTY) - { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY (%u) has wrong difficulty in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, difficulty.difficulty); - return false; - } - return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT: if (map_players.maxcount <= 0) { @@ -269,14 +246,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) return false; } return true; - case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID: - if (!sMapStore.LookupEntry(map_id.mapId)) - { - sLog->outError(LOG_FILTER_SQL, "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.", - criteria->ID, criteria->requiredType, dataType, map_id.mapId); - return false; - } - return true; case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE: if (!classRace.class_id && !classRace.race_id) { @@ -333,21 +302,8 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un if (!target || target->GetTypeId() != TYPEID_PLAYER) return false; return !target->HealthAbovePct(health.percent); - case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD: - if (target && !target->isAlive()) - if (const Player* player = target->ToPlayer()) - if (player->GetDeathTimer() != 0) - // flag set == must be same team, not set == different team - return (player->GetTeam() == source->GetTeam()) == (player_dead.own_team_flag != 0); - return false; case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA: return source->HasAuraEffect(aura.spell_id, aura.effect_idx); - case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA: - { - uint32 zone_id, area_id; - source->GetZoneAndAreaId(zone_id, area_id); - return area.id == zone_id || area.id == area_id; - } case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA: return target && target->HasAuraEffect(aura.spell_id, aura.effect_idx); case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE: @@ -362,11 +318,6 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un return target->getGender() == gender.gender; case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT: return sScriptMgr->OnCriteriaCheck(this, const_cast<Player*>(source), const_cast<Unit*>(target)); - case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY: - if (source->GetMap()->IsRaid()) - if (source->GetMap()->Is25ManRaid() != (difficulty.difficulty & RAID_DIFFICULTY_MASK_25MAN)) - return false; - return source->GetMap()->GetSpawnMode() >= difficulty.difficulty; case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT: return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM: @@ -411,8 +362,6 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un return false; return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality; } - case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID: - return source->GetMapId() == map_id.mapId; default: break; } @@ -428,45 +377,89 @@ bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, return true; } -AchievementMgr::AchievementMgr(Player* player) +template<class T> +AchievementMgr<T>::AchievementMgr(T* owner) { - m_player = player; + _owner = owner; } -AchievementMgr::~AchievementMgr() +template<class T> +AchievementMgr<T>::~AchievementMgr() { } -void AchievementMgr::Reset() +template<class T> +void AchievementMgr<T>::SendPacket(WorldPacket* data) const { - for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) - { - WorldPacket data(SMSG_ACHIEVEMENT_DELETED, 4); - data << uint32(iter->first); - m_player->SendDirectMessage(&data); - } +} - for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter) - { - WorldPacket data(SMSG_CRITERIA_DELETED, 4); - data << uint32(iter->first); - m_player->SendDirectMessage(&data); - } +template<> +void AchievementMgr<Guild>::SendPacket(WorldPacket* data) const +{ + GetOwner()->BroadcastPacket(data); +} - m_completedAchievements.clear(); - m_criteriaProgress.clear(); - DeleteFromDB(m_player->GetGUIDLow()); +template<> +void AchievementMgr<Player>::SendPacket(WorldPacket* data) const +{ + GetOwner()->GetSession()->SendPacket(data); +} - // re-fill data - CheckAllAchievementCriteria(); +template<class T> +void AchievementMgr<T>::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry) +{ + CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID); + if (criteriaProgress == m_criteriaProgress.end()) + return; + + WorldPacket data(SMSG_CRITERIA_DELETED, 4); + data << uint32(entry->ID); + SendPacket(&data); + + m_criteriaProgress.erase(criteriaProgress); } -void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete) +template<> +void AchievementMgr<Guild>::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry) +{ + CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID); + if (criteriaProgress == m_criteriaProgress.end()) + return; + + ObjectGuid guid = GetOwner()->GetGUID(); + + WorldPacket data(SMSG_GUILD_CRITERIA_DELETED, 4 + 8); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[7]); + data.WriteBit(guid[0]); + data.WriteBit(guid[1]); + data.WriteBit(guid[3]); + data.WriteBit(guid[2]); + data.WriteBit(guid[4]); + + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[7]); + data << uint32(entry->ID); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[6]); + + SendPacket(&data); + + m_criteriaProgress.erase(criteriaProgress); +} + +template<class T> +void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete) { sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2); // disable for gamemasters with GM-mode enabled - if (m_player->isGameMaster()) + if (GetOwner()->isGameMaster()) return; AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type); @@ -493,7 +486,19 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin } } -void AchievementMgr::DeleteFromDB(uint32 lowguid) +template<> +void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint32 /*miscvalue1*/, uint32 /*miscvalue2*/, bool /*evenIfCriteriaComplete*/) +{ + // Not needed +} + +template<class T> +void AchievementMgr<T>::DeleteFromDB(uint32 /*lowguid*/) +{ +} + +template<> +void AchievementMgr<Player>::DeleteFromDB(uint32 lowguid) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -508,7 +513,29 @@ void AchievementMgr::DeleteFromDB(uint32 lowguid) CharacterDatabase.CommitTransaction(trans); } -void AchievementMgr::SaveToDB(SQLTransaction& trans) +template<> +void AchievementMgr<Guild>::DeleteFromDB(uint32 lowguid) +{ + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS); + stmt->setUInt32(0, lowguid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA); + stmt->setUInt32(0, lowguid); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); +} + +template<class T> +void AchievementMgr<T>::SaveToDB(SQLTransaction& /*trans*/) +{ +} + +template<> +void AchievementMgr<Player>::SaveToDB(SQLTransaction& trans) { if (!m_completedAchievements.empty()) { @@ -523,7 +550,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) /// first new/changed record prefix if (!need_execute) { - ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN ("; + ssdel << "DELETE FROM character_achievement WHERE guid = " << GetOwner()->GetGUIDLow() << " AND achievement IN ("; ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES "; need_execute = true; } @@ -536,7 +563,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) // new/changed record data ssdel << iter->first; - ssins << '(' << GetPlayer()->GetGUIDLow() << ',' << iter->first << ',' << uint64(iter->second.date) << ')'; + ssins << '(' << GetOwner()->GetGUIDLow() << ',' << iter->first << ',' << uint64(iter->second.date) << ')'; /// mark as saved in db iter->second.changed = false; @@ -567,7 +594,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) /// first new/changed record prefix (for any counter value) if (!need_execute_del) { - ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; + ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetOwner()->GetGUIDLow() << " AND criteria IN ("; need_execute_del = true; } /// next new/changed record prefix @@ -592,7 +619,7 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) ssins << ','; // new/changed record data - ssins << '(' << GetPlayer()->GetGUIDLow() << ',' << iter->first << ',' << iter->second.counter << ',' << iter->second.date << ')'; + ssins << '(' << GetOwner()->GetGUIDLow() << ',' << iter->first << ',' << iter->second.counter << ',' << iter->second.date << ')'; } /// mark as updated in db @@ -612,7 +639,61 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) } } -void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult) +template<> +void AchievementMgr<Guild>::SaveToDB(SQLTransaction& trans) +{ + PreparedStatement* stmt; + std::ostringstream guidstr; + for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) + { + if (!itr->second.changed) + continue; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT); + stmt->setUInt32(0, GetOwner()->GetId()); + stmt->setUInt16(1, itr->first); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT); + stmt->setUInt32(0, GetOwner()->GetId()); + stmt->setUInt16(1, itr->first); + stmt->setUInt32(2, itr->second.date); + for (std::set<uint64>::const_iterator gItr = itr->second.guids.begin(); gItr != itr->second.guids.end(); ++gItr) + guidstr << GUID_LOPART(*gItr) << ','; + + stmt->setString(3, guidstr.str()); + trans->Append(stmt); + + guidstr.str(""); + } + + for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr) + { + if (!itr->second.changed) + continue; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA); + stmt->setUInt32(0, GetOwner()->GetId()); + stmt->setUInt16(1, itr->first); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA); + stmt->setUInt32(0, GetOwner()->GetId()); + stmt->setUInt16(1, itr->first); + stmt->setUInt32(2, itr->second.counter); + stmt->setUInt32(3, itr->second.date); + stmt->setUInt32(4, GUID_LOPART(itr->second.CompletedGUID)); + trans->Append(stmt); + } +} + +template<class T> +void AchievementMgr<T>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult) +{ +} + +template<> +void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult) { if (achievementResult) { @@ -632,10 +713,10 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ // title achievement rewards are retroactive if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement)) - if (uint32 titleId = reward->titleId[Player::TeamForRace(GetPlayer()->getRace()) == ALLIANCE ? 0 : 1]) + if (uint32 titleId = reward->titleId[Player::TeamForRace(GetOwner()->getRace()) == ALLIANCE ? 0 : 1]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) - if (!GetPlayer()->HasTitle(titleEntry)) - GetPlayer()->SetTitle(titleEntry); + if (!GetOwner()->HasTitle(titleEntry)) + GetOwner()->SetTitle(titleEntry); } while (achievementResult->NextRow()); } @@ -656,9 +737,7 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ sLog->outError(LOG_FILTER_ACHIEVEMENTSYS, "Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA); - stmt->setUInt16(0, uint16(id)); - CharacterDatabase.Execute(stmt); continue; @@ -675,11 +754,136 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ } } -void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const +template<> +void AchievementMgr<Guild>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult) { - if (GetPlayer()->GetSession()->PlayerLoading()) - return; + if (achievementResult) + { + do + { + Field* fields = achievementResult->Fetch(); + uint32 achievementid = fields[0].GetUInt16(); + + // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements() + AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementid); + if (!achievement) + continue; + + CompletedAchievementData& ca = m_completedAchievements[achievementid]; + ca.date = time_t(fields[1].GetUInt32()); + Tokens guids(fields[2].GetString(), ' '); + for (uint32 i = 0; i < guids.size(); ++i) + ca.guids.insert(MAKE_NEW_GUID(atol(guids[i]), 0, HIGHGUID_PLAYER)); + + ca.changed = false; + + } while (achievementResult->NextRow()); + } + + if (criteriaResult) + { + time_t now = time(NULL); + do + { + Field* fields = criteriaResult->Fetch(); + uint32 id = fields[0].GetUInt16(); + uint32 counter = fields[1].GetUInt32(); + time_t date = time_t(fields[2].GetUInt32()); + uint64 guid = fields[3].GetUInt32(); + AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); + if (!criteria) + { + // we will remove not existed criteria for all guilds + sLog->outError(LOG_FILTER_GENERAL, "Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA); + stmt->setUInt16(0, uint16(id)); + CharacterDatabase.Execute(stmt); + continue; + } + + if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now) + continue; + + CriteriaProgress& progress = m_criteriaProgress[id]; + progress.counter = counter; + progress.date = date; + progress.CompletedGUID = MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER); + progress.changed = false; + } while (criteriaResult->NextRow()); + } +} + +template<class T> +void AchievementMgr<T>::Reset() +{ +} + +template<> +void AchievementMgr<Player>::Reset() +{ + for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) + { + WorldPacket data(SMSG_ACHIEVEMENT_DELETED, 4); + data << uint32(iter->first); + SendPacket(&data); + } + + for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter) + { + WorldPacket data(SMSG_CRITERIA_DELETED, 4); + data << uint32(iter->first); + SendPacket(&data); + } + + m_completedAchievements.clear(); + m_criteriaProgress.clear(); + DeleteFromDB(_owner->GetGUIDLow()); + + // re-fill data + CheckAllAchievementCriteria(GetOwner()); +} + +template<> +void AchievementMgr<Guild>::Reset() +{ + ObjectGuid guid = GetOwner()->GetGUID(); + for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) + { + WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DELETED, 4); + data.WriteBit(guid[4]); + data.WriteBit(guid[1]); + data.WriteBit(guid[2]); + data.WriteBit(guid[3]); + data.WriteBit(guid[0]); + data.WriteBit(guid[7]); + data.WriteBit(guid[5]); + data.WriteBit(guid[6]); + data << uint32(iter->first); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[7]); + data << uint32(secsToTimeBitFields(iter->second.date)); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[2]); + SendPacket(&data); + } + + while (!m_criteriaProgress.empty()) + if (AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(m_criteriaProgress.begin()->first)) + RemoveCriteriaProgress(criteria); + + m_completedAchievements.clear(); + DeleteFromDB(_owner->GetId()); +} + +template<class T> +void AchievementMgr<T>::SendAchievementEarned(AchievementEntry const* achievement) const +{ // Don't send for achievements with ACHIEVEMENT_FLAG_TRACKING if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN) return; @@ -688,47 +892,82 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SendAchievementEarned(%u)", achievement->ID); #endif - if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) + if (Guild* guild = sGuildMgr->GetGuildById(GetOwner()->GetGuildId())) { - Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID); + Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID); Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder); - guild->BroadcastWorker(say_do, GetPlayer()); + guild->BroadcastWorker(say_do); } - if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) + if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL | ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) { // broadcast realm first reached - WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4); - data << GetPlayer()->GetName(); - data << uint64(GetPlayer()->GetGUID()); + WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetOwner()->GetName())+1+8+4+4); + data << GetOwner()->GetName(); + data << uint64(GetOwner()->GetGUID()); data << uint32(achievement->ID); data << uint32(0); // 1=link supplied string as player name, 0=display plain string sWorld->SendGlobalMessage(&data); } // if player is in world he can tell his friends about new achievement - else if (GetPlayer()->IsInWorld()) + else if (GetOwner()->IsInWorld()) { - CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); + CellCoord p = Trinity::ComputeCellCoord(GetOwner()->GetPositionX(), GetOwner()->GetPositionY()); Cell cell(p); cell.SetNoCreate(); - Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID); + Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID); Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder); - Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do); + Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do); TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker); - cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY)); + cell.Visit(p, message, *GetOwner()->GetMap(), *GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY)); } WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); - data.append(GetPlayer()->GetPackGUID()); + data.append(GetOwner()->GetPackGUID()); data << uint32(achievement->ID); data << uint32(secsToTimeBitFields(time(NULL))); - data << uint32(0); - GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); + data << uint32(0); // does not notify player ingame + GetOwner()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); +} + +template<> +void AchievementMgr<Guild>::SendAchievementEarned(AchievementEntry const* achievement) const +{ + ObjectGuid guid = GetOwner()->GetGUID(); + + WorldPacket data(SMSG_GUILD_ACHIEVEMENT_EARNED, 8+4+8); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[0]); + data.WriteBit(guid[7]); + data.WriteBit(guid[4]); + data.WriteBit(guid[6]); + data.WriteBit(guid[2]); + data.WriteBit(guid[5]); + + data.WriteByteSeq(guid[2]); + data << uint32(secsToTimeBitFields(time(NULL))); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[3]); + data << uint32(achievement->ID); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[6]); + + SendPacket(&data); +} + +template<class T> +void AchievementMgr<T>::SendCriteriaUpdate(AchievementCriteriaEntry const* /*entry*/, CriteriaProgress const* /*progress*/, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const +{ } -void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const +template<> +void AchievementMgr<Player>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const { WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8); data << uint32(entry->ID); @@ -736,7 +975,7 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C // the counter is packed like a packed Guid data.appendPackGUID(progress->counter); - data.append(GetPlayer()->GetPackGUID()); + data.appendPackGUID(GetOwner()->GetGUID()); if (!entry->timeLimit) data << uint32(0); else @@ -744,17 +983,72 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C data << uint32(secsToTimeBitFields(progress->date)); data << uint32(timeElapsed); // time elapsed in seconds data << uint32(0); // unk - GetPlayer()->SendDirectMessage(&data); + SendPacket(&data); +} + +template<> +void AchievementMgr<Guild>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const +{ + //will send response to criteria progress request + WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3 + 1 + 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4); + + ObjectGuid counter = progress->counter; // for accessing every byte individually + ObjectGuid guid = progress->CompletedGUID; + + data.WriteBits(1, 21); + data.WriteBit(counter[4]); + data.WriteBit(counter[1]); + data.WriteBit(guid[2]); + data.WriteBit(counter[3]); + data.WriteBit(guid[1]); + data.WriteBit(counter[5]); + data.WriteBit(counter[0]); + data.WriteBit(guid[3]); + data.WriteBit(counter[2]); + data.WriteBit(guid[7]); + data.WriteBit(guid[5]); + data.WriteBit(guid[0]); + data.WriteBit(counter[6]); + data.WriteBit(guid[6]); + data.WriteBit(counter[7]); + data.WriteBit(guid[4]); + + data.FlushBits(); + + data.WriteByteSeq(guid[5]); + data << uint32(progress->date); // unknown date + data.WriteByteSeq(counter[3]); + data.WriteByteSeq(counter[7]); + data << uint32(progress->date); // unknown date + data.WriteByteSeq(counter[6]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(counter[4]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(counter[0]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(counter[1]); + data.WriteByteSeq(guid[6]); + data << uint32(progress->date); // last update time (not packed!) + data << uint32(entry->ID); + data.WriteByteSeq(counter[5]); + data << uint32(0); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(counter[2]); + data.WriteByteSeq(guid[0]); + + SendPacket(&data); } /** * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet */ -void AchievementMgr::CheckAllAchievementCriteria() +template<class T> +void AchievementMgr<T>::CheckAllAchievementCriteria(Player* referencePlayer) { // suppress sending packets for (uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i) - UpdateAchievementCriteria(AchievementCriteriaTypes(i)); + UpdateAchievementCriteria(AchievementCriteriaTypes(i), 0, 0, NULL, referencePlayer); } static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 }; @@ -769,18 +1063,23 @@ static const uint32 achievIdForDungeon[][4] = { 0, false, false, false } }; +// Helper function to avoid having to specialize template for a 800 line long function +template <typename T> static bool IsGuild() { return false; } +template<> static bool IsGuild<Guild>() { return true; } + /** * this function will be called whenever the user might have done a criteria relevant action */ -void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) +template<class T> +void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/, Player* referencePlayer /*= NULL*/) { sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::UpdateAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2); // disable for gamemasters with GM-mode enabled - if (m_player->isGameMaster()) + if (referencePlayer->isGameMaster()) return; - AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type); + AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, IsGuild<T>()); for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i) { AchievementCriteriaEntry const* achievementCriteria = (*i); @@ -788,9 +1087,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!achievement) continue; - if (!CanUpdateCriteria(achievementCriteria, achievement)) + if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, unit, referencePlayer)) continue; + // requirements not found in the dbc + if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria)) + if (!data->Meets(referencePlayer, unit, miscValue1)) + continue; + switch (type) { // std. case: increment at 1 @@ -807,7 +1111,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; // std case: increment at miscvalue1 case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS: @@ -823,7 +1127,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) continue; - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; // std case: high value at miscvalue1 case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID: @@ -835,7 +1139,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) continue; - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST); break; // specialized cases @@ -845,14 +1149,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1) continue; - if (achievement->categoryId == CATEGORY_CHILDRENS_WEEK) - { - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), NULL)) - continue; - } - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: @@ -860,15 +1157,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) continue; - if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId()) + if (achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId()) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: @@ -879,41 +1171,33 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (achievementCriteria->kill_creature.creatureID != miscValue1) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - - SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: - if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria)) - if (!data->Meets(GetPlayer(), unit)) - continue; - SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel()); + SetCriteriaProgress(achievementCriteria, referencePlayer->getLevel(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: // update at loading or specific skill update if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID) continue; - if (uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID)) - SetCriteriaProgress(achievementCriteria, skillvalue); + if (uint32 skillvalue = referencePlayer->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID)) + SetCriteriaProgress(achievementCriteria, skillvalue, referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL: // update at loading or specific skill update if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID) continue; - if (uint32 maxSkillvalue = GetPlayer()->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID)) - SetCriteriaProgress(achievementCriteria, maxSkillvalue); + if (uint32 maxSkillvalue = referencePlayer->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID)) + SetCriteriaProgress(achievementCriteria, maxSkillvalue, referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end()) - SetCriteriaProgress(achievementCriteria, 1); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: { - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetRewardedQuestCount()); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetRewardedQuestCount(), referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: @@ -925,7 +1209,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { // reset if player missed one day. if (progress && progress->date < (nextDailyResetTime - 2 * DAY)) - SetCriteriaProgress(achievementCriteria, 0, PROGRESS_SET); + SetCriteriaProgress(achievementCriteria, 0, referencePlayer, PROGRESS_SET); continue; } @@ -943,7 +1227,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // last progress is within the day before the reset => Already counted today. continue; - SetCriteriaProgress(achievementCriteria, 1, progressType); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, progressType); break; } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: @@ -954,31 +1238,31 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui uint32 counter = 0; - const RewardedQuestSet &rewQuests = GetPlayer()->getRewardedQuests(); + const RewardedQuestSet &rewQuests = referencePlayer->getRewardedQuests(); for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr) { Quest const* quest = sObjectMgr->GetQuestTemplate(*itr); if (quest && quest->GetZoneOrSort() >= 0 && uint32(quest->GetZoneOrSort()) == achievementCriteria->complete_quests_in_zone.zoneID) ++counter; } - SetCriteriaProgress(achievementCriteria, counter); + SetCriteriaProgress(achievementCriteria, counter, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) continue; - if (GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID) + if (referencePlayer->GetMapId() != achievementCriteria->complete_battleground.mapID) continue; - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscValue1) continue; - if (GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID) + if (referencePlayer->GetMapId() != achievementCriteria->death_at_map.mapID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_DEATH: { @@ -991,7 +1275,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { if (achievIdByArenaSlot[j] == achievement->ID) { - Battleground* bg = GetPlayer()->GetBattleground(); + Battleground* bg = referencePlayer->GetBattleground(); if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j) notfit = true; @@ -1001,7 +1285,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (notfit) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON: @@ -1010,7 +1294,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1) continue; - Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : sMapMgr->FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); + Map const* map = referencePlayer->IsInWorld() ? referencePlayer->GetMap() : sMapMgr->FindMap(referencePlayer->GetMapId(), referencePlayer->GetInstanceId()); if (!map || !map->IsDungeon()) continue; @@ -1026,7 +1310,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!achievIdForDungeon[j][2]) break; // for } - else if (GetPlayer()->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL) + else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL) { // dungeon in normal mode accepted if (!achievIdForDungeon[j][1]) @@ -1049,7 +1333,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui //FIXME: work only for instances where max == min for players if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } @@ -1059,7 +1343,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscValue1 != achievementCriteria->killed_by_creature.creatureEntry) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -1067,10 +1351,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; // if team check required: must kill by opposition faction - if (achievement->ID == 318 && miscValue2 == GetPlayer()->GetTeam()) + if (achievement->ID == 318 && miscValue2 == referencePlayer->GetTeam()) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: { @@ -1078,13 +1362,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - // miscvalue1 is the ingame fallheight*100 as stored in dbc - SetCriteriaProgress(achievementCriteria, miscValue1); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: @@ -1093,7 +1372,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscValue2 != achievementCriteria->death_from.type) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: { @@ -1106,15 +1385,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui else { // login case. - if (!GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) + if (!referencePlayer->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) continue; } if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria)) - if (!data->Meets(GetPlayer(), unit)) + if (!data->Meets(referencePlayer, unit)) continue; - SetCriteriaProgress(achievementCriteria, 1); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: @@ -1123,15 +1402,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data) - continue; - - if (!data->Meets(GetPlayer(), unit)) - continue; - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: @@ -1140,23 +1411,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data) - continue; - - if (!data->Meets(GetPlayer(), unit)) - continue; - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID) continue; - if (GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) - SetCriteriaProgress(achievementCriteria, 1); + if (referencePlayer->HasSpell(achievementCriteria->learn_spell.spellID)) + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: { @@ -1167,42 +1430,20 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue1 != achievementCriteria->loot_type.lootType) continue; - // zone specific - if (achievementCriteria->loot_type.lootTypeCount == 1) - { - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - } - - SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: // speedup for non-login case if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1) continue; - SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: if (!miscValue1) // no update at login continue; - // additional requirements - if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE) - { - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit, miscValue1)) - { - // reset the progress as we have a win without the requirement. - SetCriteriaProgress(achievementCriteria, 0); - continue; - } - } - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -1212,15 +1453,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (achievementCriteria->use_item.itemID != miscValue1) continue; - // Children's Week achievements have extra requirements - if (achievement->categoryId == CATEGORY_CHILDRENS_WEEK) - { - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), NULL)) - continue; - } - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: // You _have_ to loot that item, just owning it when logging in does _not_ count! @@ -1228,7 +1461,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscValue1 != achievementCriteria->own_item.itemID) continue; - SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: { @@ -1250,7 +1483,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui uint32 playerIndexOffset = uint32(exploreFlag) / 32; uint32 mask = 1<< (uint32(exploreFlag) % 32); - if (GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) + if (referencePlayer->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) { matchFound = true; break; @@ -1258,11 +1491,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui } if (matchFound) - SetCriteriaProgress(achievementCriteria, 1); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetBankBagSlotCount()); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetBankBagSlotCount(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: { @@ -1270,14 +1503,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID) continue; - int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID); + int32 reputation = referencePlayer->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID); if (reputation > 0) - SetCriteriaProgress(achievementCriteria, reputation); + SetCriteriaProgress(achievementCriteria, reputation, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: { - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetExaltedFactionCount()); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetExaltedFactionCount(), referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: @@ -1285,7 +1518,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // skip for login case if (!miscValue1) continue; - SetCriteriaProgress(achievementCriteria, 1); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: @@ -1298,12 +1531,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue2 != achievementCriteria->equip_epic_item.itemSlot) continue; - // check item level and quality via achievement_criteria_data - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), 0, miscValue1)) - continue; - - SetCriteriaProgress(achievementCriteria, 1); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; } @@ -1321,12 +1549,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!pProto) continue; - // check item level via achievement_criteria_data - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), 0, pProto->ItemLevel)) - continue; - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: @@ -1336,15 +1559,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscValue1 != achievementCriteria->do_emote.emoteID) continue; - if (achievementCriteria->do_emote.count) - { - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - } - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: @@ -1355,7 +1571,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP) { - if (GetPlayer()->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value) + if (referencePlayer->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value) continue; // map specific case (BG in fact) expected player targeted damage/heal @@ -1363,7 +1579,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; } - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: @@ -1373,7 +1589,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue1 != achievementCriteria->equip_item.itemID) continue; - SetCriteriaProgress(achievementCriteria, 1); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: // miscvalue1 = go entry @@ -1382,7 +1598,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue1 != achievementCriteria->use_gameobject.goEntry) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: if (!miscValue1) @@ -1390,7 +1606,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue1 != achievementCriteria->fish_in_gameobject.goEntry) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: { @@ -1398,8 +1614,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; uint32 spellCount = 0; - for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin(); - spellIter != GetPlayer()->GetSpellMap().end(); + for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin(); + spellIter != referencePlayer->GetSpellMap().end(); ++spellIter) { SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first); @@ -1409,7 +1625,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui spellCount++; } } - SetCriteriaProgress(achievementCriteria, spellCount); + SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: @@ -1417,27 +1633,16 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1) continue; - if (achievementCriteria->win_duel.duelCount) - { - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data) - continue; - - if (!data->Meets(GetPlayer(), unit)) - continue; - } - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount()); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetReveredFactionCount(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetHonoredFactionCount()); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetHonoredFactionCount(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetVisibleFactionCount()); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetVisibleFactionCount(), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: @@ -1448,7 +1653,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1); if (!proto || proto->Quality < ITEM_QUALITY_EPIC) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE: @@ -1457,8 +1662,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; uint32 spellCount = 0; - for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin(); - spellIter != GetPlayer()->GetSpellMap().end(); + for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin(); + spellIter != referencePlayer->GetSpellMap().end(); ++spellIter) { SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first); @@ -1466,26 +1671,26 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (skillIter->second->skillId == achievementCriteria->learn_skill_line.skillLine) spellCount++; } - SetCriteriaProgress(achievementCriteria, spellCount); + SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer); break; } case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS), referencePlayer); break; case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED: - SetCriteriaProgress(achievementCriteria, GetPlayer()->GetMoney(), PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, referencePlayer->GetMoney(), referencePlayer, PROGRESS_HIGHEST); break; case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS: { @@ -1495,10 +1700,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui for (CompletedAchievementMap::iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) if (AchievementEntry const* pAchievement = sAchievementStore.LookupEntry(itr->first)) points += pAchievement->points; - SetCriteriaProgress(achievementCriteria, points, PROGRESS_SET); + SetCriteriaProgress(achievementCriteria, points, referencePlayer, PROGRESS_SET); } else - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: @@ -1506,12 +1711,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: @@ -1522,12 +1722,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1) continue; - // those requirements couldn't be found in the dbc - AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria); - if (!data || !data->Meets(GetPlayer(), unit)) - continue; - - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: @@ -1535,7 +1730,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); + SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING: @@ -1547,13 +1742,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue2 != reqTeamType) continue; - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST); } else // login case { for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) { - uint32 teamId = GetPlayer()->GetArenaTeamId(arena_slot); + uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot); if (!teamId) continue; @@ -1561,7 +1756,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!team || team->GetType() != reqTeamType) continue; - SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, referencePlayer, PROGRESS_HIGHEST); break; } } @@ -1577,13 +1772,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (miscValue2 != reqTeamType) continue; - SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST); } else // login case { for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) { - uint32 teamId = GetPlayer()->GetArenaTeamId(arena_slot); + uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot); if (!teamId) continue; @@ -1591,9 +1786,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!team || team->GetType() != reqTeamType) continue; - if (ArenaTeamMember const* member = team->GetMember(GetPlayer()->GetGUID())) + if (ArenaTeamMember const* member = team->GetMember(referencePlayer->GetGUID())) { - SetCriteriaProgress(achievementCriteria, member->PersonalRating, PROGRESS_HIGHEST); + SetCriteriaProgress(achievementCriteria, member->PersonalRating, referencePlayer, PROGRESS_HIGHEST); break; } } @@ -1601,13 +1796,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui break; } - // std case: not exist in DBC, not triggered in code as result - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING: + case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: + if (!miscValue1 || !miscValue2) + continue; + if (miscValue1 != achievementCriteria->currencyGain.currency) + continue; + if (int64(miscValue2) < 0) + continue; + SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE); break; // FIXME: not triggered in code as result, need to implement case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: @@ -1617,26 +1813,39 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE: case ACHIEVEMENT_CRITERIA_TYPE_TOTAL: + case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS: + case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL: + case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD: + case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL: + case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS: + case ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND: + case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING: + case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD: + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD: + case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD: + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD: break; // Not implemented yet :( } if (IsCompletedCriteria(achievementCriteria, achievement)) - CompletedCriteriaFor(achievement); + CompletedCriteriaFor(achievement, referencePlayer); // check again the completeness for SUMM and REQ COUNT achievements, // as they don't depend on the completed criteria but on the sum of the progress of each individual criteria if (achievement->flags & ACHIEVEMENT_FLAG_SUMM) if (IsCompletedAchievement(achievement)) - CompletedAchievement(achievement); + CompletedAchievement(achievement, referencePlayer); if (AchievementEntryList const* achRefList = sAchievementMgr->GetAchievementByReferencedId(achievement->ID)) for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr) if (IsCompletedAchievement(*itr)) - CompletedAchievement(*itr); + CompletedAchievement(*itr, referencePlayer); } } -bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement) +template<class T> +bool AchievementMgr<T>::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement) { // counter can never complete if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER) @@ -1754,6 +1963,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= achievementCriteria->use_lfg.dungeonsComplete; case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS: return progress->counter >= achievementCriteria->get_killing_blow.killCount; + case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY: + return progress->counter >= achievementCriteria->currencyGain.count; // handle all statistic-only criteria here case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: @@ -1782,9 +1993,6 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED: case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER: - case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR: case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: @@ -1794,7 +2002,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return false; } -void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement) +template<class T> +void AchievementMgr<T>::CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer) { // counter can never complete if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER) @@ -1805,10 +2014,11 @@ void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement) return; if (IsCompletedAchievement(achievement)) - CompletedAchievement(achievement); + CompletedAchievement(achievement, referencePlayer); } -bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) +template<class T> +bool AchievementMgr<T>::IsCompletedAchievement(AchievementEntry const* entry) { // counter can never complete if (entry->flags & ACHIEVEMENT_FLAG_COUNTER) @@ -1870,7 +2080,8 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) return false; } -CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry const* entry) +template<class T> +CriteriaProgress* AchievementMgr<T>::GetCriteriaProgress(AchievementCriteriaEntry const* entry) { CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); @@ -1880,14 +2091,15 @@ CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry c return &(iter->second); } -void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype) +template<class T> +void AchievementMgr<T>::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, Player* referencePlayer, ProgressType ptype) { // Don't allow to cheat - doing timed achievements without timer active TimedAchievementMap::iterator timedIter = m_timedAchievements.find(entry->ID); if (entry->timeLimit && timedIter == m_timedAchievements.end()) return; - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::SetCriteriaProgress(%u, %u) for (%s GUID: "UI64FMTD")", entry->ID, changeValue, GetLogNameForGuid(GetOwner()->GetGUID()), GetOwner()->GetGUID()); CriteriaProgress* progress = GetCriteriaProgress(entry); if (!progress) @@ -1930,38 +2142,28 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, progress->changed = true; progress->date = time(NULL); // set the date to the latest update. + AchievementEntry const* achievement = sAchievementStore.LookupEntry(entry->referredAchievement); uint32 timeElapsed = 0; - bool timedCompleted = false; + bool criteriaComplete = IsCompletedCriteria(entry, achievement); if (entry->timeLimit) { - // has to exist else we wouldn't be here - timedCompleted = IsCompletedCriteria(entry, sAchievementStore.LookupEntry(entry->referredAchievement)); // Client expects this in packet timeElapsed = entry->timeLimit - (timedIter->second/IN_MILLISECONDS); // Remove the timer, we wont need it anymore - if (timedCompleted) + if (criteriaComplete) m_timedAchievements.erase(timedIter); } - SendCriteriaUpdate(entry, progress, timeElapsed, timedCompleted); -} + if (criteriaComplete && achievement->flags & ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS && !progress->CompletedGUID) + progress->CompletedGUID = referencePlayer->GetGUID(); -void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntry* entry) -{ - CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID); - if (criteriaProgress == m_criteriaProgress.end()) - return; - - WorldPacket data(SMSG_CRITERIA_DELETED, 4); - data << uint32(entry->ID); - m_player->SendDirectMessage(&data); - - m_criteriaProgress.erase(criteriaProgress); + SendCriteriaUpdate(entry, progress, timeElapsed, criteriaComplete); } -void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff) +template<class T> +void AchievementMgr<T>::UpdateTimedAchievements(uint32 timeDiff) { if (!m_timedAchievements.empty()) { @@ -1983,12 +2185,18 @@ void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff) } } -void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost /*= 0*/) +template<class T> +void AchievementMgr<T>::StartTimedAchievement(AchievementCriteriaTimedTypes /*type*/, uint32 /*entry*/, uint32 /*timeLost = 0*/) +{ +} + +template<> +void AchievementMgr<Player>::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost /* = 0 */) { AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type); for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i) { - if ((*i)->timerStartEvent != entry) + if ((*i)->timedCriteriaMiscId != entry) continue; AchievementEntry const* achievement = sAchievementStore.LookupEntry((*i)->referredAchievement); @@ -2000,18 +2208,19 @@ void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, u m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILLISECONDS - timeLost; // and at client too - SetCriteriaProgress(*i, 0, PROGRESS_SET); + SetCriteriaProgress(*i, 0, GetOwner(), PROGRESS_SET); } } } } -void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) +template<class T> +void AchievementMgr<T>::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) { AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type); for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i) { - if ((*i)->timerStartEvent != entry) + if ((*i)->timedCriteriaMiscId != entry) continue; TimedAchievementMap::iterator timedIter = m_timedAchievements.find((*i)->ID); @@ -2027,18 +2236,21 @@ void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, } } -void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) +template<class T> +void AchievementMgr<T>::CompletedAchievement(AchievementEntry const* achievement, Player* referencePlayer) { sLog->outInfo(LOG_FILTER_ACHIEVEMENTSYS, "AchievementMgr::CompletedAchievement(%u)", achievement->ID); // disable for gamemasters with GM-mode enabled - if (m_player->isGameMaster()) + if (_owner->isGameMaster()) return; if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) return; - SendAchievementEarned(achievement); + if (!GetOwner()->GetSession()->PlayerLoading()) + SendAchievementEarned(achievement); + CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; ca.date = time(NULL); ca.changed = true; @@ -2048,8 +2260,8 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) if (!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) sAchievementMgr->SetRealmCompleted(achievement); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, NULL, referencePlayer); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, NULL, referencePlayer); // reward items and titles if any AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement); @@ -2063,16 +2275,16 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) //! Since no common attributes were found, (not even in titleRewardFlags field) //! we explicitly check by ID. Maybe in the future we could move the achievement_reward //! condition fields to the condition system. - if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->getGender() : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)]) + if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetOwner()->getGender() : (GetOwner()->GetTeam() == ALLIANCE ? 0 : 1)]) if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) - GetPlayer()->SetTitle(titleEntry); + GetOwner()->SetTitle(titleEntry); // mail if (reward->sender) { - Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetPlayer()) : NULL; + Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetOwner()) : NULL; - int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); + int loc_idx = GetOwner()->GetSession()->GetSessionDbLocaleIndex(); // subject and text std::string subject = reward->subject; @@ -2098,73 +2310,342 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) draft.AddItem(item); } - draft.SendMailTo(trans, GetPlayer(), MailSender(MAIL_CREATURE, reward->sender)); + draft.SendMailTo(trans, GetOwner(), MailSender(MAIL_CREATURE, reward->sender)); CharacterDatabase.CommitTransaction(trans); } } -void AchievementMgr::SendAllAchievementData() const +template<> +void AchievementMgr<Guild>::CompletedAchievement(AchievementEntry const* achievement, Player* referencePlayer) +{ + sLog->outInfo(LOG_FILTER_GENERAL, "AchievementMgr<Guild>::CompletedAchievement(%u)", achievement->ID); + + if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID)) + return; + + SendAchievementEarned(achievement); + CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; + ca.date = time(NULL); + ca.changed = true; + + if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS) + { + if (referencePlayer->GetGuildId() == GetOwner()->GetId()) + ca.guids.insert(referencePlayer->GetGUID()); + + if (Group const* group = referencePlayer->GetGroup()) + for (GroupReference const* ref = group->GetFirstMember(); ref != NULL; ref = ref->next()) + if (Player const* groupMember = ref->getSource()) + if (groupMember->GetGuildId() == GetOwner()->GetId()) + ca.guids.insert(groupMember->GetGUID()); + } + + sAchievementMgr->SetRealmCompleted(achievement); + + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, NULL, referencePlayer); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, NULL, referencePlayer); +} + +struct VisibleAchievementPred +{ + bool operator()(CompletedAchievementMap::value_type const& val) + { + AchievementEntry const* achievement = sAchievementStore.LookupEntry(val.first); + return achievement && !(achievement->flags & ACHIEVEMENT_FLAG_HIDDEN); + } +}; + +template<class T> +void AchievementMgr<T>::SendAllAchievementData(Player* /*receiver*/) const +{ + VisibleAchievementPred isVisible; + size_t numCriteria = m_criteriaProgress.size(); + size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible); + ByteBuffer criteriaData(numCriteria * (4 + 4 + 4 + 4 + 8 + 8)); + ObjectGuid guid = GetOwner()->GetGUID(); + ObjectGuid counter; + + WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4 + numAchievements * (4 + 4) + 4 + numCriteria * (4 + 4 + 4 + 4 + 8 + 8)); + data.WriteBits(numCriteria, 21); + for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr) + { + counter = uint64(itr->second.counter); + + data.WriteBit(guid[4]); + data.WriteBit(counter[3]); + data.WriteBit(guid[5]); + data.WriteBit(counter[0]); + data.WriteBit(counter[6]); + data.WriteBit(guid[3]); + data.WriteBit(guid[0]); + data.WriteBit(counter[4]); + data.WriteBit(guid[2]); + data.WriteBit(counter[7]); + data.WriteBit(guid[7]); + data.WriteBits(0u, 2); + data.WriteBit(guid[6]); + data.WriteBit(counter[2]); + data.WriteBit(counter[1]); + data.WriteBit(counter[5]); + data.WriteBit(guid[1]); + + criteriaData.WriteByteSeq(guid[3]); + criteriaData.WriteByteSeq(counter[5]); + criteriaData.WriteByteSeq(counter[6]); + criteriaData.WriteByteSeq(guid[4]); + criteriaData.WriteByteSeq(guid[6]); + criteriaData.WriteByteSeq(counter[2]); + criteriaData << uint32(0); // timer 2 + criteriaData.WriteByteSeq(guid[2]); + criteriaData << uint32(itr->first); // criteria id + criteriaData.WriteByteSeq(guid[5]); + criteriaData.WriteByteSeq(counter[0]); + criteriaData.WriteByteSeq(counter[3]); + criteriaData.WriteByteSeq(counter[1]); + criteriaData.WriteByteSeq(counter[4]); + criteriaData.WriteByteSeq(guid[0]); + criteriaData.WriteByteSeq(guid[7]); + criteriaData.WriteByteSeq(counter[7]); + criteriaData << uint32(0); // timer 1 + criteriaData << uint32(secsToTimeBitFields(itr->second.date)); // criteria date + criteriaData.WriteByteSeq(guid[1]); + } + + data.WriteBits(numAchievements, 23); + data.FlushBits(); + data.append(criteriaData); + + for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) + { + if (!isVisible(*itr)) + continue; + + data << uint32(itr->first); + data << uint32(secsToTimeBitFields(itr->second.date)); + } + + SendPacket(&data); +} + +template<> +void AchievementMgr<Guild>::SendAllAchievementData(Player* receiver) const { - WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4); - BuildAllDataPacket(&data); - GetPlayer()->GetSession()->SendPacket(&data); + WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DATA, m_completedAchievements.size() * (4 + 4) + 4); + data.WriteBits(m_completedAchievements.size(), 23); + for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) + { + data << uint32(secsToTimeBitFields(itr->second.date)); + data << uint32(itr->first); + } + + receiver->GetSession()->SendPacket(&data); } -void AchievementMgr::SendRespondInspectAchievements(Player* player) const +template<class T> +void AchievementMgr<T>::SendAchievementInfo(Player* receiver, uint32 achievementId /*= 0*/) const { - WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 9+m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4); - data.append(GetPlayer()->GetPackGUID()); - BuildAllDataPacket(&data); - player->GetSession()->SendPacket(&data); } -/** - * used by SMSG_RESPOND_INSPECT_ACHIEVEMENT and SMSG_ALL_ACHIEVEMENT_DATA - */ -void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const +template<> +void AchievementMgr<Player>::SendAchievementInfo(Player* receiver, uint32 /*achievementId = 0 */) const { - AchievementEntry const* achievement = NULL; - for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter) + ObjectGuid guid = GetOwner()->GetGUID(); + ObjectGuid counter; + + VisibleAchievementPred isVisible; + size_t numCriteria = m_criteriaProgress.size(); + size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible); + ByteBuffer criteriaData(numCriteria * (0)); + + WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 1 + 8 + 3 + 3 + numAchievements * (4 + 4) + numCriteria * (0)); + data.WriteBit(guid[7]); + data.WriteBit(guid[4]); + data.WriteBit(guid[1]); + data.WriteBits(numAchievements, 23); + data.WriteBit(guid[0]); + data.WriteBit(guid[3]); + data.WriteBits(numCriteria, 21); + data.WriteBit(guid[2]); + for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr) { - // Skip hidden achievements - achievement = sAchievementStore.LookupEntry(iter->first); - if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN) + counter = itr->second.counter; + + data.WriteBit(counter[5]); + data.WriteBit(counter[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[4]); + data.WriteBit(guid[2]); + data.WriteBit(counter[6]); + data.WriteBit(guid[0]); + data.WriteBit(counter[4]); + data.WriteBit(counter[1]); + data.WriteBit(counter[2]); + data.WriteBit(guid[3]); + data.WriteBit(guid[7]); + data.WriteBits(0, 2); // criteria progress flags + data.WriteBit(counter[0]); + data.WriteBit(guid[5]); + data.WriteBit(guid[6]); + data.WriteBit(counter[7]); + + criteriaData.WriteByteSeq(guid[3]); + criteriaData.WriteByteSeq(counter[4]); + criteriaData << uint32(0); // timer 1 + criteriaData.WriteByteSeq(guid[1]); + criteriaData << uint32(secsToTimeBitFields(itr->second.date)); + criteriaData.WriteByteSeq(counter[3]); + criteriaData.WriteByteSeq(counter[7]); + criteriaData.WriteByteSeq(guid[5]); + criteriaData.WriteByteSeq(counter[0]); + criteriaData.WriteByteSeq(guid[4]); + criteriaData.WriteByteSeq(guid[2]); + criteriaData.WriteByteSeq(guid[6]); + criteriaData.WriteByteSeq(guid[7]); + criteriaData.WriteByteSeq(counter[6]); + criteriaData << uint32(itr->first); + criteriaData << uint32(0); // timer 2 + criteriaData.WriteByteSeq(counter[1]); + criteriaData.WriteByteSeq(counter[5]); + criteriaData.WriteByteSeq(guid[0]); + criteriaData.WriteByteSeq(counter[2]); + } + + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.FlushBits(); + data.append(criteriaData); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[2]); + + for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr) + { + if (!isVisible(*itr)) continue; - *data << uint32(iter->first); - *data << uint32(secsToTimeBitFields(iter->second.date)); + data << uint32(itr->first); + data << uint32(secsToTimeBitFields(itr->second.date)); } - *data << int32(-1); - for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter) + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[5]); + + receiver->GetSession()->SendPacket(&data); +} + +template<> +void AchievementMgr<Guild>::SendAchievementInfo(Player* receiver, uint32 achievementId /*= 0*/) const +{ + //will send response to criteria progress request + AchievementCriteriaEntryList const* criteria = sAchievementMgr->GetAchievementCriteriaByAchievement(achievementId); + if (!criteria) + { + // send empty packet + WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3); + data.WriteBits(0, 21); + receiver->GetSession()->SendPacket(&data); + return; + } + + ObjectGuid counter; + ObjectGuid guid; + uint32 numCriteria = 0; + ByteBuffer criteriaData(criteria->size() * (8 + 8 + 4 + 4 + 4)); + ByteBuffer criteriaBits(criteria->size() * (8 + 8) / 8); + for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr) { - *data << uint32(iter->first); - data->appendPackGUID(iter->second.counter); - data->append(GetPlayer()->GetPackGUID()); - *data << uint32(0); - *data << uint32(secsToTimeBitFields(iter->second.date)); - *data << uint32(0); - *data << uint32(0); + uint32 criteriaId = (*itr)->ID; + CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId); + if (progress == m_criteriaProgress.end()) + continue; + + ++numCriteria; } - *data << int32(-1); + criteriaBits.WriteBits(numCriteria, 21); + + for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr) + { + uint32 criteriaId = (*itr)->ID; + CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId); + if (progress == m_criteriaProgress.end()) + continue; + + counter = progress->second.counter; + guid = progress->second.CompletedGUID; + + criteriaBits.WriteBit(counter[4]); + criteriaBits.WriteBit(counter[1]); + criteriaBits.WriteBit(guid[2]); + criteriaBits.WriteBit(counter[3]); + criteriaBits.WriteBit(guid[1]); + criteriaBits.WriteBit(counter[5]); + criteriaBits.WriteBit(counter[0]); + criteriaBits.WriteBit(guid[3]); + criteriaBits.WriteBit(counter[2]); + criteriaBits.WriteBit(guid[7]); + criteriaBits.WriteBit(guid[5]); + criteriaBits.WriteBit(guid[0]); + criteriaBits.WriteBit(counter[6]); + criteriaBits.WriteBit(guid[6]); + criteriaBits.WriteBit(counter[7]); + criteriaBits.WriteBit(guid[4]); + + criteriaData.WriteByteSeq(guid[5]); + criteriaData << uint32(progress->second.date); // unknown date + criteriaData.WriteByteSeq(counter[3]); + criteriaData.WriteByteSeq(counter[7]); + criteriaData << uint32(progress->second.date); // unknown date + criteriaData.WriteByteSeq(counter[6]); + criteriaData.WriteByteSeq(guid[4]); + criteriaData.WriteByteSeq(guid[1]); + criteriaData.WriteByteSeq(counter[4]); + criteriaData.WriteByteSeq(guid[3]); + criteriaData.WriteByteSeq(counter[0]); + criteriaData.WriteByteSeq(guid[2]); + criteriaData.WriteByteSeq(counter[1]); + criteriaData.WriteByteSeq(guid[6]); + criteriaData << uint32(progress->second.date); // last update time (not packed!) + criteriaData << uint32(criteriaId); + criteriaData.WriteByteSeq(counter[5]); + criteriaData << uint32(0); + criteriaData.WriteByteSeq(guid[7]); + criteriaData.WriteByteSeq(counter[2]); + criteriaData.WriteByteSeq(guid[0]); + } + + WorldPacket data(SMSG_GUILD_CRITERIA_DATA, criteriaBits.size() + criteriaData.size()); + data.append(criteriaBits); + if (numCriteria) + data.append(criteriaData); + + receiver->GetSession()->SendPacket(&data); } -bool AchievementMgr::HasAchieved(uint32 achievementId) const +template<class T> +bool AchievementMgr<T>::HasAchieved(uint32 achievementId) const { return m_completedAchievements.find(achievementId) != m_completedAchievements.end(); } -bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement) +template<class T> +bool AchievementMgr<T>::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 /*miscValue2*/, Unit* unit, Player* referencePlayer) { if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL)) return false; - if (achievement->mapID != -1 && GetPlayer()->GetMapId() != uint32(achievement->mapID)) + if (achievement->mapID != -1 && referencePlayer->GetMapId() != uint32(achievement->mapID)) + return false; + + // don't update already completed criteria + if (IsCompletedCriteria(criteria, achievement)) return false; - if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && GetPlayer()->GetTeam() != HORDE) || - (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE)) + if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && referencePlayer->GetTeam() != HORDE) || + (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && referencePlayer->GetTeam() != ALLIANCE)) return false; for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i) @@ -2175,11 +2656,11 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, switch (criteria->additionalRequirements[i].additionalRequirement_type) { case ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP: - if (GetPlayer()->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value) + if (referencePlayer->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value) return false; break; case ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP: - if (GetPlayer()->GetGroup()) + if (referencePlayer->GetGroup()) return false; break; default: @@ -2187,13 +2668,131 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, } } - // don't update already completed criteria - if (IsCompletedCriteria(criteria, achievement)) - return false; + // additional conditions + for (int8 i = 0; i < MAX_ADDITIONAL_CRITERIA_CONDITIONS; ++i) + { + if (!criteria->additionalConditionType[i]) + continue; + + uint32 value = criteria->additionalConditionValue[i]; + switch (criteria->additionalConditionType[i]) + { + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER: + if (!unit || !unit->ToPlayer()) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD: + if (!unit || unit->isAlive()) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED: + if (!unit || !unit->IsMounted()) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: + if (uint32(referencePlayer->GetMap()->GetDifficulty()) != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: + if (referencePlayer->GetMapId() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE: + if (referencePlayer->GetZoneId() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA: + if (referencePlayer->GetAreaId() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY: + if (!unit) + return false; + if (const Player* player = unit->ToPlayer()) + if (player->GetTeam() == referencePlayer->GetTeam()) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY: + if (!unit || !unit->ToCreature()) + return false; + if (unit->ToCreature()->GetEntry() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA: + if (!referencePlayer->HasAura(value)) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA: + if (!unit || !unit->HasAura(value)) + return false; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN: + if (ItemTemplate const * itemProto = sObjectMgr->GetItemTemplate(miscValue1)) + if (itemProto->Quality < value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS: + if (ItemTemplate const * itemProto = sObjectMgr->GetItemTemplate(miscValue1)) + if (itemProto->Quality < value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE: + if (referencePlayer->getRace() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS: + if (referencePlayer->getClass() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE: + if (!unit || !unit->ToPlayer()) + break; + if (unit->ToPlayer()->getRace() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS: + if (!unit || !unit->ToPlayer()) + break; + if (unit->ToPlayer()->getClass() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS: + if (referencePlayer->GetGroup() && referencePlayer->GetGroup()->GetMembersCount() >= value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE: + if (!unit || !unit->ToCreature()) + return false; + if (unit->ToCreature()->GetCreatureType() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL: + if (referencePlayer->getLevel() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL: + if (!unit || unit->getLevel() != value) + return false; + break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: + if (!unit || unit->GetHealthPct() >= value) + return false; + break; + // generic, compare miscValue1 with DBC value + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: + if (miscValue1 != value) + return false; + break; + default: + break; + } + } return true; } +template class AchievementMgr<Guild>; +template class AchievementMgr<Player>; + //========================================================== void AchievementGlobalMgr::LoadAchievementCriteriaList() { @@ -2206,21 +2805,28 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList() return; } + uint32 criterias = 0; + uint32 guildCriterias = 0; for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId) { AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); if (!criteria) continue; - m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); + AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement); + m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria); + if (achievement && achievement->flags & ACHIEVEMENT_FLAG_GUILD) + ++guildCriterias, m_GuildAchievementCriteriasByType[criteria->requiredType].push_back(criteria); + else + ++criterias, m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); + if (criteria->timeLimit) - m_AchievementCriteriasByTimedType[criteria->timedType].push_back(criteria); + m_AchievementCriteriasByTimedType[criteria->timedCriteriaStartType].push_back(criteria); } - sLog->outInfo(LOG_FILTER_ACHIEVEMENTSYS, ">> Loaded %lu achievement criteria in %u ms", (unsigned long)m_AchievementCriteriasByType->size(), GetMSTimeDiffToNow(oldMSTime)); - + sLog->outInfo(LOG_FILTER_ACHIEVEMENTSYS, ">> Loaded %u achievement criteria and %u guild achievement crieteria in %u ms", criterias, guildCriterias, GetMSTimeDiffToNow(oldMSTime)); } void AchievementGlobalMgr::LoadAchievementReferenceList() diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index c7d838fcb44..1a1cc217c28 100755 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -37,6 +37,7 @@ struct CriteriaProgress { uint32 counter; time_t date; // latest update time. + uint64 CompletedGUID; // GUID of the player that completed this criteria (guild achievements) bool changed; }; @@ -46,15 +47,13 @@ enum AchievementCriteriaDataType ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0 ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH= 3, // health_percent 0 - ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // own_team 0 not corpse (not released body), own_team == false if enemy team expected ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx - ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0 ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10, // gender 0=male; 1=female ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11, // scripted requirement - ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12, // difficulty normal/heroic difficulty for current event map + // REUSE ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13, // count "with less than %u people in the zone" ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14, // team HORDE(67), ALLIANCE(469) ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15, // drunken_state 0 (enum DrunkenState) of player @@ -62,12 +61,10 @@ enum AchievementCriteriaDataType ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17, // min_score max_score player's team win bg and opposition team have team score in range ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality - ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id }; #define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 22 // maximum value in AchievementCriteriaDataType enum - class Player; class Unit; @@ -94,11 +91,6 @@ struct AchievementCriteriaData { uint32 percent; } health; - // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4 - struct - { - uint32 own_team_flag; - } player_dead; // ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5 // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7 struct @@ -106,11 +98,6 @@ struct AchievementCriteriaData uint32 spell_id; uint32 effect_idx; } aura; - // ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6 - struct - { - uint32 id; - } area; // ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8 struct { @@ -127,11 +114,6 @@ struct AchievementCriteriaData uint32 gender; } gender; // ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11 (no data) - // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12 - struct - { - uint32 difficulty; - } difficulty; // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13 struct { @@ -165,12 +147,7 @@ struct AchievementCriteriaData uint32 item_level; uint32 item_quality; } equipped_item; - // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20 - struct - { - uint32 mapId; - } map_id; - // ... + // raw struct { uint32 value1; @@ -233,6 +210,7 @@ typedef std::map<uint32, AchievementRewardLocale> AchievementRewardLocales; struct CompletedAchievementData { time_t date; + std::set<uint64> guids; bool changed; }; @@ -243,10 +221,11 @@ class Unit; class Player; class WorldPacket; +template<class T> class AchievementMgr { public: - AchievementMgr(Player* player); + AchievementMgr(T* owner); ~AchievementMgr(); void Reset(); @@ -254,13 +233,14 @@ class AchievementMgr void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult); void SaveToDB(SQLTransaction& trans); void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1 = 0, uint32 miscvalue2 = 0, bool evenIfCriteriaComplete = false); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); - void CompletedAchievement(AchievementEntry const* entry); - void CheckAllAchievementCriteria(); - void SendAllAchievementData() const; - void SendRespondInspectAchievements(Player* player) const; + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL, Player* referencePlayer = NULL); + void CompletedAchievement(AchievementEntry const* entry, Player* referencePlayer); + void CheckAllAchievementCriteria(Player* referencePlayer); + void SendAllAchievementData(Player* receiver) const; + void SendAchievementInfo(Player* receiver, uint32 achievementId = 0) const; bool HasAchieved(uint32 achievementId) const; - Player* GetPlayer() const { return m_player; } + T* GetOwner() const { return _owner; } + void UpdateTimedAchievements(uint32 timeDiff); void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0); void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements @@ -270,15 +250,15 @@ class AchievementMgr void SendAchievementEarned(AchievementEntry const* achievement) const; void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const; CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry); - void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET); + void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, Player* referencePlayer, ProgressType ptype = PROGRESS_SET); void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry); - void CompletedCriteriaFor(AchievementEntry const* achievement); + void CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer); bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement); bool IsCompletedAchievement(AchievementEntry const* entry); - bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement); - void BuildAllDataPacket(WorldPacket* data) const; + bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit, Player* referencePlayer); + void SendPacket(WorldPacket* data) const; - Player* m_player; + T* _owner; CriteriaProgressMap m_criteriaProgress; CompletedAchievementMap m_completedAchievements; typedef std::map<uint32, uint32> TimedAchievementMap; @@ -292,9 +272,9 @@ class AchievementGlobalMgr ~AchievementGlobalMgr() {} public: - AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const + AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type, bool guild = false) const { - return m_AchievementCriteriasByType[type]; + return guild ? m_GuildAchievementCriteriasByType[type] : m_AchievementCriteriasByType[type]; } AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type) const @@ -342,6 +322,22 @@ class AchievementGlobalMgr m_allCompletedAchievements.insert(achievement->ID); } + bool IsGroupCriteriaType(AchievementCriteriaTypes type) const + { + switch (type) + { + case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: + case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: // NYI + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: + case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: // NYI + case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND: // NYI + return true; + } + + return false; + } + void LoadAchievementCriteriaList(); void LoadAchievementCriteriaData(); void LoadAchievementReferenceList(); @@ -353,9 +349,13 @@ class AchievementGlobalMgr // store achievement criterias by type to speed up lookup AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; + AchievementCriteriaEntryList m_GuildAchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; + AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX]; + // store achievement criterias by achievement to speed up lookup AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement; + // store achievements by referenced achievement id to speed up lookup AchievementListByReferencedId m_AchievementListByReferencedId; diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index ab08262a928..c134f4e277e 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -29,7 +29,7 @@ #include "AuctionHouseMgr.h" #include "Item.h" #include "Language.h" -#include "Logging/Log.h" +#include "Log.h" #include <vector> enum eAuctionHouse @@ -145,7 +145,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& { bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template); // FIXME: for offline player need also - bidder->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); + bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); } MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, 0, 0)) @@ -179,8 +179,8 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa //FIXME: what do if owner offline if (owner) { - owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); - owner->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); + owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); + owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); //send auction owner notification, bidder must be current! owner->GetSession()->SendAuctionOwnerNotification(auction); } @@ -569,7 +569,7 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player if (itemRandProp) { - char* const* temp = itemRandProp->nameSuffix; + char* temp = itemRandProp->nameSuffix; //char* temp = itemRandProp->nameSuffix; // dbc local name @@ -610,7 +610,7 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const data << uint32(Id); data << uint32(item->GetEntry()); - for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i) + for (uint8 i = 0; i < PROP_ENCHANTMENT_SLOT_0; ++i) // PROP_ENCHANTMENT_SLOT_0 = 10 { data << uint32(item->GetEnchantmentId(EnchantmentSlot(i))); data << uint32(item->GetEnchantmentDuration(EnchantmentSlot(i))); @@ -623,13 +623,13 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const data << uint32(item->GetSpellCharges()); // item->charge FFFFFFF data << uint32(0); // Unknown data << uint64(owner); // Auction->owner - data << uint32(startbid); // Auction->startbid (not sure if useful) - data << uint32(bid ? GetAuctionOutBid() : 0); + data << uint64(startbid); // Auction->startbid (not sure if useful) + data << uint64(bid ? GetAuctionOutBid() : 0); // Minimal outbid - data << uint32(buyout); // Auction->buyout + data << uint64(buyout); // Auction->buyout data << uint32((expire_time - time(NULL)) * IN_MILLISECONDS); // time left data << uint64(bidder); // auction->bidder current - data << uint32(bid); // current bid + data << uint64(bid); // current bid return true; } diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index d8ad2c09e59..2528ab27141 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -57,7 +57,8 @@ enum ArenaTeamCommandErrors ERR_ARENA_TEAM_TARGET_TOO_HIGH_S = 0x16, ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S = 0x17, ERR_ARENA_TEAM_NOT_FOUND = 0x1B, - ERR_ARENA_TEAMS_LOCKED = 0x1E + ERR_ARENA_TEAMS_LOCKED = 0x1E, + ERR_ARENA_TEAM_TOO_MANY_CREATE = 0x21, }; enum ArenaTeamEvents diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index 665742c97b1..416b54a5713 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -151,16 +151,17 @@ void ArenaTeamMgr::DistributeArenaPoints() if (ArenaTeam* at = teamItr->second) at->UpdateArenaPointsHelper(PlayerPoints); + /* SQLTransaction trans = CharacterDatabase.BeginTransaction(); + // Cycle that gives points to all players PreparedStatement* stmt; - // Cycle that gives points to all players for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr) { // Add points to player if online if (Player* player = HashMapHolder<Player>::Find(playerItr->first)) - player->ModifyArenaPoints(playerItr->second, &trans); + player->ModifyConquestPoints(playerItr->second, &trans); else // Update database { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS); @@ -171,6 +172,7 @@ void ArenaTeamMgr::DistributeArenaPoints() } CharacterDatabase.CommitTransaction(trans); + */ PlayerPoints.clear(); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index cfb4aec8525..6b9cdad9272 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -34,6 +34,8 @@ #include "SpellAuras.h" #include "SpellAuraEffects.h" #include "Util.h" +#include "Guild.h" +#include "GuildMgr.h" namespace Trinity { @@ -799,6 +801,7 @@ void Battleground::EndBattleground(uint32 winner) } } + bool guildAwarded = false; uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { @@ -851,7 +854,7 @@ void Battleground::EndBattleground(uint32 winner) { // update achievement BEFORE personal rating update uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot()); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change); } @@ -866,7 +869,10 @@ void Battleground::EndBattleground(uint32 winner) uint32 winner_kills = player->GetRandomWinner() ? BG_REWARD_WINNER_HONOR_LAST : BG_REWARD_WINNER_HONOR_FIRST; uint32 loser_kills = player->GetRandomWinner() ? BG_REWARD_LOSER_HONOR_LAST : BG_REWARD_LOSER_HONOR_FIRST; - uint32 winner_arena = player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST; + + // remove temporary currency bonus auras before rewarding player + player->RemoveAura(SPELL_HONORABLE_DEFENDER_25Y); + player->RemoveAura(SPELL_HONORABLE_DEFENDER_60Y); // Reward winner team if (team == winner) @@ -874,13 +880,24 @@ void Battleground::EndBattleground(uint32 winner) if (IsRandom() || BattlegroundMgr::IsBGWeekend(GetTypeID())) { UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winner_kills)); - if (CanAwardArenaPoints()) - player->ModifyArenaPoints(winner_arena); + /*if (CanAwardArenaPoints()) + player->ModifyConquestPoints(player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST);*/ if (!player->GetRandomWinner()) player->SetRandomWinner(true); } - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1); + if (!guildAwarded) + { + guildAwarded = true; + if (uint32 guildId = GetBgMap()->GetOwnerGuildId(player->GetTeam())) + if (Guild* guild = sGuildMgr->GetGuildById(guildId)) + { + guild->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, NULL, player); + if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team) + guild->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max<uint32>(winner_arena_team->GetRating(), 1), 0, NULL, player); + } + } } else { @@ -899,7 +916,7 @@ void Battleground::EndBattleground(uint32 winner) BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType()); player->GetSession()->SendPacket(&data); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team) @@ -1643,6 +1660,7 @@ bool Battleground::AddSpiritGuide(uint32 type, float x, float y, float z, float creature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL); // correct cast speed creature->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + creature->SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f); //creature->CastSpell(creature, SPELL_SPIRIT_HEAL_CHANNEL, true); return true; } @@ -1703,6 +1721,8 @@ void Battleground::SendWarningToAll(int32 entry, ...) data << (uint32)(msg.length() + 1); data << msg.c_str(); data << (uint8)0; + data << (float)0.0f; // added in 4.2.0, unk + data << (uint8)0; // added in 4.2.0, unk for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) if (player->GetSession()) diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 290da0bb31f..f9fb27f54bc 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -775,7 +775,8 @@ void BattlegroundMgr::CreateInitialBattlegrounds() selectionWeight = fields[10].GetUInt8(); data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString()); - data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; + + //data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()]; data.MapID = bl->mapid[0]; if (!CreateBattleground(data)) @@ -814,7 +815,7 @@ void BattlegroundMgr::InitAutomaticArenaPointDistribution() sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Automatic Arena Point Distribution initialized."); } -void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere) +void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId) { if (!player) return; @@ -827,8 +828,8 @@ void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, uint64 guid loser_kills = Trinity::Honor::hk_honor_at_level(player->getLevel(), float(loser_kills)); data->Initialize(SMSG_BATTLEFIELD_LIST); + // TODO: Fix guid *data << uint64(guid); // battlemaster guid - *data << uint8(fromWhere); // from where you joined *data << uint32(bgTypeId); // battleground id *data << uint8(0); // unk *data << uint8(0); // unk diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 10a49408c06..4edad4da742 100755 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -68,7 +68,7 @@ class BattlegroundMgr /* Packet Building */ void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player); void BuildPlayerLeftBattlegroundPacket(WorldPacket* data, uint64 guid); - void BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere); + void BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId); void BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result); void BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value); void BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 8b2543f20ff..fa36f0b02aa 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -681,11 +681,11 @@ void BattlegroundAB::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_BASES_ASSAULTED: ((BattlegroundABScore*)itr->second)->BasesAssaulted += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_ASSAULT_BASE); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_ASSAULT_BASE); break; case SCORE_BASES_DEFENDED: ((BattlegroundABScore*)itr->second)->BasesDefended += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_DEFEND_BASE); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AB_OBJECTIVE_DEFEND_BASE); break; default: Battleground::UpdatePlayerScore(Source, type, value, doAddHonor); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index 96fa899a746..37072866238 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -540,19 +540,19 @@ void BattlegroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_GRAVEYARDS_ASSAULTED: ((BattlegroundAVScore*)itr->second)->GraveyardsAssaulted += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_GRAVEYARD); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_GRAVEYARD); break; case SCORE_GRAVEYARDS_DEFENDED: ((BattlegroundAVScore*)itr->second)->GraveyardsDefended += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_GRAVEYARD); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_GRAVEYARD); break; case SCORE_TOWERS_ASSAULTED: ((BattlegroundAVScore*)itr->second)->TowersAssaulted += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_TOWER); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_ASSAULT_TOWER); break; case SCORE_TOWERS_DEFENDED: ((BattlegroundAVScore*)itr->second)->TowersDefended += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_TOWER); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, AV_OBJECTIVE_DEFEND_TOWER); break; case SCORE_MINES_CAPTURED: ((BattlegroundAVScore*)itr->second)->MinesCaptured += value; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 9bab15d9b5e..35ea94ba607 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -816,7 +816,7 @@ void BattlegroundEY::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_FLAG_CAPTURES: // flags captured ((BattlegroundEYScore*)itr->second)->FlagCaptures += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, EY_OBJECTIVE_CAPTURE_FLAG); break; default: Battleground::UpdatePlayerScore(Source, type, value, doAddHonor); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 202869567d8..76e328b46ac 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -74,7 +74,7 @@ void BattlegroundIC::SendTransportInit(Player* player) if (!gunshipAlliance || !gunshipHorde) return; - UpdateData transData; + UpdateData transData(player->GetMapId()); gunshipAlliance->BuildCreateUpdateBlockForPlayer(&transData, player); gunshipHorde->BuildCreateUpdateBlockForPlayer(&transData, player); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 58f7cabc72d..f7f4df61be6 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -273,7 +273,7 @@ void BattlegroundSA::StartShips() { if (Player* p = ObjectAccessor::FindPlayer(itr->first)) { - UpdateData data; + UpdateData data(p->GetMapId()); WorldPacket pkt; GetBGObject(i)->BuildValuesUpdateBlockForPlayer(&data, p); data.BuildPacket(&pkt); @@ -912,8 +912,9 @@ void BattlegroundSA::SendTransportInit(Player* player) { if (BgObjects[BG_SA_BOAT_ONE] || BgObjects[BG_SA_BOAT_TWO]) { - UpdateData transData; + UpdateData transData(player->GetMapId()); if (BgObjects[BG_SA_BOAT_ONE]) + GetBGObject(BG_SA_BOAT_ONE)->BuildCreateUpdateBlockForPlayer(&transData, player); if (BgObjects[BG_SA_BOAT_TWO]) GetBGObject(BG_SA_BOAT_TWO)->BuildCreateUpdateBlockForPlayer(&transData, player); @@ -927,7 +928,7 @@ void BattlegroundSA::SendTransportsRemove(Player* player) { if (BgObjects[BG_SA_BOAT_ONE] || BgObjects[BG_SA_BOAT_TWO]) { - UpdateData transData; + UpdateData transData(player->GetMapId()); if (BgObjects[BG_SA_BOAT_ONE]) GetBGObject(BG_SA_BOAT_ONE)->BuildOutOfRangeUpdateBlock(&transData); if (BgObjects[BG_SA_BOAT_TWO]) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 483e8ffdaf6..c09285fd7ad 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -759,11 +759,11 @@ void BattlegroundWS::UpdatePlayerScore(Player* Source, uint32 type, uint32 value { case SCORE_FLAG_CAPTURES: // flags captured ((BattlegroundWGScore*)itr->second)->FlagCaptures += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG); break; case SCORE_FLAG_RETURNS: // flags returned ((BattlegroundWGScore*)itr->second)->FlagReturns += value; - Source->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG); + Source->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG); break; default: Battleground::UpdatePlayerScore(Source, type, value, doAddHonor); diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 9564dbb381e..503bbc57c69 100755 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -48,8 +48,8 @@ enum ChatNotify CHAT_MODE_CHANGE_NOTICE = 0x0C, //? CHAT_ANNOUNCEMENTS_ON_NOTICE = 0x0D, //+ "[%s] Channel announcements enabled by %s."; CHAT_ANNOUNCEMENTS_OFF_NOTICE = 0x0E, //+ "[%s] Channel announcements disabled by %s."; - // CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s."; - // CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s."; + CHAT_MODERATION_ON_NOTICE = 0x0F, //+ "[%s] Channel moderation enabled by %s."; + CHAT_MODERATION_OFF_NOTICE = 0x10, //+ "[%s] Channel moderation disabled by %s."; CHAT_MUTED_NOTICE = 0x11, //+ "[%s] You do not have permission to speak."; CHAT_PLAYER_KICKED_NOTICE = 0x12, //? "[%s] Player %s kicked by %s."; CHAT_BANNED_NOTICE = 0x13, //+ "[%s] You are banned from that channel."; diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index b5bad419c98..b8d4234b2a0 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -621,7 +621,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd) } //Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored) -void ChatHandler::FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker) +void ChatHandler::FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker, const char* addonPrefix /*= NULL*/) { uint32 messageLength = (message ? strlen(message) : 0) + 1; @@ -675,6 +675,13 @@ void ChatHandler::FillMessageData(WorldPacket* data, WorldSession* session, uint *data << uint32(messageLength); *data << message; *data << uint8(0); + + if (type == CHAT_MSG_RAID_BOSS_WHISPER || type == CHAT_MSG_RAID_BOSS_EMOTE) + { + *data << float(0.0f); // Added in 4.2.0, unk + *data << uint8(0); // Added in 4.2.0, unk + } + return; } default: @@ -690,9 +697,16 @@ void ChatHandler::FillMessageData(WorldPacket* data, WorldSession* session, uint { ASSERT(channelName); *data << channelName; + *data << uint64(target_guid); } + else if (type == CHAT_MSG_ADDON) + { + ASSERT(addonPrefix); + *data << addonPrefix; + } + else + *data << uint64(target_guid); - *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) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 269ebdd1d2f..c0560ee0e27 100755..100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -51,7 +51,7 @@ class ChatHandler explicit ChatHandler(Player* player) : m_session(player->GetSession()) {} virtual ~ChatHandler() {} - static void FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker); + static void FillMessageData(WorldPacket* data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit* speaker, const char* addonPrefix = NULL); void FillMessageData(WorldPacket* data, uint8 type, uint32 language, uint64 target_guid, const char* message) { diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index d26f937c43d..6860426c3eb 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -165,7 +165,7 @@ bool ItemChatLink::Initialize(std::istringstream& iss) return true; } -inline std::string ItemChatLink::FormatName(uint8 index, ItemLocale const* locale, char* const* suffixStrings) const +inline std::string ItemChatLink::FormatName(uint8 index, ItemLocale const *locale, char* suffixStrings) const { std::stringstream ss; if (locale == NULL || index >= locale->Name.size()) @@ -181,7 +181,7 @@ bool ItemChatLink::ValidateName(char* buffer, const char* context) { ChatLink::ValidateName(buffer, context); - char* const* suffixStrings = _suffix ? _suffix->nameSuffix : (_property ? _property->nameSuffix : NULL); + char* suffixStrings = _suffix ? _suffix->nameSuffix : (_property ? _property->nameSuffix : NULL); bool res = (FormatName(LOCALE_enUS, NULL, suffixStrings) == buffer); if (!res) @@ -304,30 +304,21 @@ bool SpellChatLink::ValidateName(char* buffer, const char* context) return false; } - for (uint8 i = 0; i < TOTAL_LOCALES; ++i) + uint32 skillLineNameLength = strlen(skillLine->name); + if (skillLineNameLength > 0 && strncmp(skillLine->name, buffer, skillLineNameLength) == 0) { - uint32 skillLineNameLength = strlen(skillLine->name[i]); - if (skillLineNameLength > 0 && strncmp(skillLine->name[i], buffer, skillLineNameLength) == 0) - { - // found the prefix, remove it to perform spellname validation below - // -2 = strlen(": ") - uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2; - memcpy(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1); - } + // found the prefix, remove it to perform spellname validation below + // -2 = strlen(": ") + uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2; + memcpy(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1); } } - bool res = false; - for (uint8 i = 0; i < TOTAL_LOCALES; ++i) - if (*_spell->SpellName[i] && strcmp(_spell->SpellName[i], buffer) == 0) - { - res = true; - break; - } + if (*_spell->SpellName && strcmp(_spell->SpellName, buffer) == 0) + return true; - if (!res) - sLog->outDebug(LOG_FILTER_CHATSYS, "ChatHandler::isValidChatMessage('%s'): linked spell (id: %u) name wasn't found in any localization", context, _spell->Id); - return res; + sLog->outDebug(LOG_FILTER_CHATSYS, "ChatHandler::isValidChatMessage('%s'): linked spell (id: %u) name wasn't found in any localization", context, _spell->Id); + return false; } // |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r @@ -379,17 +370,11 @@ bool AchievementChatLink::ValidateName(char* buffer, const char* context) { ChatLink::ValidateName(buffer, context); - bool res = false; - for (uint8 i = 0; i < TOTAL_LOCALES; ++i) - if (*_achievement->name[i] && strcmp(_achievement->name[i], buffer) == 0) - { - res = true; - break; - } + if (*_achievement->name && strcmp(_achievement->name, buffer) == 0) + return true; - if (!res) - sLog->outDebug(LOG_FILTER_CHATSYS, "ChatHandler::isValidChatMessage('%s'): linked achievement (id: %u) name wasn't found in any localization", context, _achievement->ID); - return res; + sLog->outDebug(LOG_FILTER_CHATSYS, "ChatHandler::isValidChatMessage('%s'): linked achievement (id: %u) name wasn't found in any localization", context, _achievement->ID); + return false; } // |color|Htrade:spell_id:cur_value:max_value:player_guid:base64_data|h[name]|h|r diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h index 392d28aca54..2301dc09f29 100644 --- a/src/server/game/Chat/ChatLink.h +++ b/src/server/game/Chat/ChatLink.h @@ -61,7 +61,7 @@ public: virtual bool ValidateName(char* buffer, const char* context); protected: - std::string FormatName(uint8 index, ItemLocale const* locale, char* const* suffixStrings) const; + std::string FormatName(uint8 index, ItemLocale const* locale, char* suffixStrings) const; ItemTemplate const* _item; int32 _data[8]; diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp new file mode 100644 index 00000000000..2e1c25ced39 --- /dev/null +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "DB2Stores.h" +#include "Log.h" +#include "SharedDefines.h" +#include "SpellMgr.h" +#include "DB2fmt.h" + +#include <map> + +DB2Storage <ItemEntry> sItemStore(Itemfmt); +DB2Storage <ItemCurrencyCostEntry> sItemCurrencyCostStore(ItemCurrencyCostfmt); +DB2Storage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt); +DB2Storage <ItemSparseEntry> sItemSparseStore (ItemSparsefmt); + +typedef std::list<std::string> StoreProblemList1; + +uint32 DB2FilesCount = 0; + +static bool LoadDB2_assert_print(uint32 fsize,uint32 rsize, const std::string& filename) +{ + sLog->outError(LOG_FILTER_GENERAL, "Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).", filename.c_str(), fsize, rsize); + + // ASSERT must fail after function call + return false; +} + +struct LocalDB2Data +{ + LocalDB2Data(LocaleConstant loc) : defaultLocale(loc), availableDb2Locales(0xFFFFFFFF) {} + + LocaleConstant defaultLocale; + + // bitmasks for index of fullLocaleNameList + uint32 availableDb2Locales; +}; + +template<class T> +inline void LoadDB2(StoreProblemList1& errlist, DB2Storage<T>& storage, const std::string& db2_path, const std::string& filename) +{ + // compatibility format and C++ structure sizes + ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDB2_assert_print(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename)); + + ++DB2FilesCount; + + std::string db2_filename = db2_path + filename; + if (!storage.Load(db2_filename.c_str())) + { + // sort problematic db2 to (1) non compatible and (2) nonexistent + if (FILE * f = fopen(db2_filename.c_str(), "rb")) + { + char buf[100]; + snprintf(buf, 100,"(exist, but have %d fields instead " SIZEFMTD ") Wrong client version DBC file?", storage.GetFieldCount(), strlen(storage.GetFormat())); + errlist.push_back(db2_filename + buf); + fclose(f); + } + else + errlist.push_back(db2_filename); + } +} + +void LoadDB2Stores(const std::string& dataPath) +{ + std::string db2Path = dataPath + "dbc/"; + + StoreProblemList1 bad_db2_files; + + LoadDB2(bad_db2_files, sItemStore, db2Path, "Item.db2"); + LoadDB2(bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2"); + LoadDB2(bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2"); + LoadDB2(bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2"); + // error checks + if (bad_db2_files.size() >= DB2FilesCount) + { + sLog->outError(LOG_FILTER_GENERAL, "\nIncorrect DataDir value in worldserver.conf or ALL required *.db2 files (%d) not found by path: %sdb2", DB2FilesCount, dataPath.c_str()); + exit(1); + } + else if (!bad_db2_files.empty()) + { + std::string str; + for (std::list<std::string>::iterator i = bad_db2_files.begin(); i != bad_db2_files.end(); ++i) + str += *i + "\n"; + + sLog->outError(LOG_FILTER_GENERAL, "\nSome required *.db2 files (%u from %d) not found or not compatible:\n%s", (uint32)bad_db2_files.size(), DB2FilesCount,str.c_str()); + exit(1); + } + + // Check loaded DB2 files proper version + if (!sItemStore.LookupEntry(83086) || // last item added in 4.3.4 (15595) + !sItemExtendedCostStore.LookupEntry(3872) ) // last item extended cost added in 4.3.4 (15595) + { + sLog->outError(LOG_FILTER_GENERAL, "Please extract correct db2 files from client 4.3.4 15595."); + exit(1); + } + + sLog->outInfo(LOG_FILTER_GENERAL, ">> Initialized %d DB2 data stores.", DB2FilesCount); +} diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h new file mode 100644 index 00000000000..6cf719da70b --- /dev/null +++ b/src/server/game/DataStores/DB2Stores.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_DB2STORES_H +#define TRINITY_DB2STORES_H + +#include "Common.h" +#include "DB2Store.h" +#include "DB2Structure.h" + +#include <list> + +extern DB2Storage <ItemEntry> sItemStore; +extern DB2Storage <ItemCurrencyCostEntry> sItemCurrencyCostStore; +extern DB2Storage <ItemExtendedCostEntry> sItemExtendedCostStore; +extern DB2Storage <ItemSparseEntry> sItemSparseStore; + +void LoadDB2Stores(const std::string& dataPath); + +#endif
\ No newline at end of file diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h new file mode 100644 index 00000000000..386e8546236 --- /dev/null +++ b/src/server/game/DataStores/DB2Structure.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_DB2STRUCTURE_H +#define TRINITY_DB2STRUCTURE_H + +#include "Common.h" +#include "DBCEnums.h" +#include "Define.h" +#include "Path.h" +#include "Util.h" +#include "Vehicle.h" +#include "SharedDefines.h" +#include "ItemPrototype.h" + +#include <map> +#include <set> +#include <vector> + +// GCC has alternative #pragma pack(N) syntax and old gcc version does not support pack(push, N), also any gcc version does not support it at some platform +#if defined(__GNUC__) +#pragma pack(1) +#else +#pragma pack(push, 1) +#endif + +// Structures used to access raw DB2 data and required packing to portability +struct ItemEntry +{ + uint32 ID; // 0 + uint32 Class; // 1 + uint32 SubClass; // 2 + int32 Unk0; // 3 + int32 Material; // 4 + uint32 DisplayId; // 5 + uint32 InventoryType; // 6 + uint32 Sheath; // 7 +}; + +struct ItemCurrencyCostEntry +{ + //uint32 Id; + uint32 ItemId; +}; + +struct ItemSparseEntry +{ + uint32 ID; // 0 + uint32 Quality; // 1 + uint32 Flags; // 2 + uint32 Flags2; // 3 + float Unk430_1; + float Unk430_2; + uint32 BuyCount; + uint32 BuyPrice; // 4 + uint32 SellPrice; // 5 + uint32 InventoryType; // 6 + int32 AllowableClass; // 7 + int32 AllowableRace; // 8 + uint32 ItemLevel; // 9 + int32 RequiredLevel; // 10 + uint32 RequiredSkill; // 11 + uint32 RequiredSkillRank; // 12 + uint32 RequiredSpell; // 13 + uint32 RequiredHonorRank; // 14 + uint32 RequiredCityRank; // 15 + uint32 RequiredReputationFaction; // 16 + uint32 RequiredReputationRank; // 17 + uint32 MaxCount; // 18 + uint32 Stackable; // 19 + uint32 ContainerSlots; // 20 + int32 ItemStatType[MAX_ITEM_PROTO_STATS]; // 21 - 30 + uint32 ItemStatValue[MAX_ITEM_PROTO_STATS]; // 31 - 40 + int32 ItemStatUnk1[MAX_ITEM_PROTO_STATS]; // 41 - 50 + int32 ItemStatUnk2[MAX_ITEM_PROTO_STATS]; // 51 - 60 + uint32 ScalingStatDistribution; // 61 + uint32 DamageType; // 62 + uint32 Delay; // 63 + float RangedModRange; // 64 + int32 SpellId[MAX_ITEM_PROTO_SPELLS]; // 65 - 69 + int32 SpellTrigger[MAX_ITEM_PROTO_SPELLS]; // 70 - 74 + int32 SpellCharges[MAX_ITEM_PROTO_SPELLS]; // 75 - 79 + int32 SpellCooldown[MAX_ITEM_PROTO_SPELLS]; // 80 - 84 + int32 SpellCategory[MAX_ITEM_PROTO_SPELLS]; // 85 - 89 + int32 SpellCategoryCooldown[MAX_ITEM_PROTO_SPELLS]; // 90 - 94 + uint32 Bonding; // 95 + char* Name; // 96 + char* Name2; // 97 + char* Name3; // 98 + char* Name4; // 99 + char* Description; // 100 + uint32 PageText; // 101 + uint32 LanguageID; // 102 + uint32 PageMaterial; // 103 + uint32 StartQuest; // 104 + uint32 LockID; // 105 + int32 Material; // 106 + uint32 Sheath; // 107 + uint32 RandomProperty; // 108 + uint32 RandomSuffix; // 109 + uint32 ItemSet; // 110 + uint32 Area; // 112 + uint32 Map; // 113 + uint32 BagFamily; // 114 + uint32 TotemCategory; // 115 + uint32 Color[MAX_ITEM_PROTO_SOCKETS]; // 116 - 118 + uint32 Content[MAX_ITEM_PROTO_SOCKETS]; // 119 - 121 + int32 SocketBonus; // 122 + uint32 GemProperties; // 123 + float ArmorDamageModifier; // 124 + uint32 Duration; // 125 + uint32 ItemLimitCategory; // 126 + uint32 HolidayId; // 127 + float StatScalingFactor; // 128 + int32 CurrencySubstitutionId; // 129 + int32 CurrencySubstitutionCount; // 130 +}; + +#define MAX_ITEM_EXT_COST_ITEMS 5 +#define MAX_ITEM_EXT_COST_CURRENCIES 5 + +struct ItemExtendedCostEntry +{ + uint32 ID; // 0 extended-cost entry id + //uint32 reqhonorpoints; // 1 required honor points + //uint32 reqarenapoints; // 2 required arena points + uint32 RequiredArenaSlot; // 3 arena slot restrictions (min slot value) + uint32 RequiredItem[MAX_ITEM_EXT_COST_ITEMS]; // 4-8 required item id + uint32 RequiredItemCount[MAX_ITEM_EXT_COST_ITEMS]; // 9-13 required count of 1st item + uint32 RequiredPersonalArenaRating; // 14 required personal arena rating + //uint32 ItemPurchaseGroup; // 15 + uint32 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES];// 16-20 required curency id + uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES];// 21-25 required curency count + //uint32 Unknown[5]; // 26-30 +}; + +// GCC has alternative #pragma pack(N) syntax and old gcc version does not support pack(push, N), also any gcc version does not support it at some platform +#if defined(__GNUC__) +#pragma pack() +#else +#pragma pack(pop) +#endif + +#endif
\ No newline at end of file diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h new file mode 100644 index 00000000000..3cc3a9b7693 --- /dev/null +++ b/src/server/game/DataStores/DB2fmt.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_DB2SFRM_H +#define TRINITY_DB2SFRM_H + +const char Itemfmt[]="niiiiiii"; +const char ItemCurrencyCostfmt[]="xn"; +const char ItemSparsefmt[]="niiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisssssiiiiiiiiiiiiiiiiiiiiiifiiifii"; +const char ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiixxxxx"; + +#endif diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index e73480cb4de..cd8accd3759 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -22,7 +22,7 @@ // Client expected level limitation, like as used in DBC item max levels for "until max player level" // use as default max player level, must be fit max level for used client // also see MAX_LEVEL and STRONG_MAX_LEVEL define -#define DEFAULT_MAX_LEVEL 80 +#define DEFAULT_MAX_LEVEL 85 // client supported max level for player/pets/etc. Avoid overflow or client stability affected. // also see GT_MAX_LEVEL define @@ -58,16 +58,24 @@ enum AchievementFaction enum AchievementFlags { - ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete) - ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only - ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx" - ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value) - ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) - ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value) - ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) - ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) - ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // - ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // + ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete) + ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only + ACHIEVEMENT_FLAG_PLAY_NO_VISUAL = 0x00000004, // Client does not play achievement earned visual + ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value) + ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) + ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value) + ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) + ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) + ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // + ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // + ACHIEVEMENT_FLAG_UNK3 = 0x00000400, // ACHIEVEMENT_FLAG_HIDE_NAME_IN_TIE + ACHIEVEMENT_FLAG_REALM_FIRST_GUILD = 0x00000800, // first guild on realm done something + ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS = 0x00001000, // Shows in guild news + ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER = 0x00002000, // Shows in guild news header + ACHIEVEMENT_FLAG_GUILD = 0x00004000, // + ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS = 0x00008000, // + ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS = 0x00010000, // + }; #define MAX_CRITERIA_REQUIREMENTS 2 @@ -84,6 +92,80 @@ enum AchievementCriteriaCondition ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk }; +#define MAX_ADDITIONAL_CRITERIA_CONDITIONS 3 + +enum AchievementCriteriaAdditionalCondition +{ + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK2 = 2, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY = 4, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER = 5, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD = 6, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY = 7, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA = 8, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK9 = 9, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA = 10, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED = 11, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK12 = 12, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK13 = 13, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN = 14, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS = 15, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK16 = 16, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA = 17, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE = 18, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK19 = 19, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 20, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_YIELDS_XP = 21, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK22 = 22, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK23 = 23, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ARENA_TEAM_SIZE = 24, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE = 25, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS = 26, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE = 27, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS = 28, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS = 29, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE = 30, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK31 = 31, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK35 = 35, // related to timed completing-quests achievements + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK36 = 36, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE) + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL = 39, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL = 40, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK42 = 42, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK43 = 43, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK44 = 44, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK45 = 45, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW = 46, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK47 = 47, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK48 = 48, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK49 = 49, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK50 = 50, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK51 = 51, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK52 = 52, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK53 = 53, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK54 = 54, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK55 = 55, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK57 = 57, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_LFG_GROUP = 58, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK59 = 59, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK60 = 60, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_GUILD_GROUP = 61, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION = 62, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND = 63, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK64 = 64, // unused in 4.0.6a + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK65 = 65, // Archaeology, item quality related + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK66 = 66, // Archaeology, race related +}; + +#define MAX_ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TYPE 66 + enum AchievementCriteriaFlags { ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar @@ -102,128 +184,150 @@ enum AchievementCriteriaTimedTypes ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET = 6, // Timer is started by being target of spell with entry in timerStartEvent ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent ACHIEVEMENT_TIMED_TYPE_ITEM = 9, // Timer is started by using item with entry in timerStartEvent + ACHIEVEMENT_TIMED_TYPE_UNK = 10, // Unknown ACHIEVEMENT_TIMED_TYPE_MAX, }; enum AchievementCriteriaTypes { - ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0, - ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1, - ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5, - ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9, + ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0, + ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS = 3, // struct { uint32 itemCount; } + ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5, + ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9, // you have to complete a daily quest x times in a row - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, - ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15, - ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16, - ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17, - ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19, - ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20, - ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23, - ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24, - ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26, - ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27, - ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28, - ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29, - ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30, - ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31, - ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32, - ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34, - ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35, - ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36, - // TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc - ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40, - ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42, - ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43, - ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44, - ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, + ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12, + ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND = 15, + ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP = 16, + ACHIEVEMENT_CRITERIA_TYPE_DEATH = 17, + ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19, + ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20, + ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23, + ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24, + ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27, + ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28, + ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL = 29, + ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30, + ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31, + ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32, + ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33, + ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34, + ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35, + ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36, + ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39, + ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40, + ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41, + ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42, + ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43, + ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK = 44, + ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT = 45, + ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION = 46, + ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION = 47, // noted: rewarded as soon as the player payed, not at taking place at the seat - ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48, - ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49, + ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48, + ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49, // TODO: itemlevel is mentioned in text but not present in dbc - ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51, - ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52, - ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53, - ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54, - ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT = 51, + ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52, + ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53, + ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54, + ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55, // TODO: in some cases map not present, and in some cases need do without die - ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56, - ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57, - ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60, - ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61, - ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67, - ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68, - ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69, - ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70, - ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72, + ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56, + ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57, + ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59, + ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60, + ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61, + ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62, + ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63, + ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65, + ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66, + ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67, + ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68, + ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2 = 69, + ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70, + ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72, // TODO: title id is not mentioned in dbc - ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75, - ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76, - ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77, + ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, + ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75, + ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76, + ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77, // TODO: creature type (demon, undead etc.) is not stored in dbc - ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, - ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80, - ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83, - ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87, - ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88, - ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90, - ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93, - ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH = 95, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR = 99, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102, - ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104, - ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105, - ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106, - ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107, - ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108, - ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109, + ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, + ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS = 80, + ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION = 82, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID = 83, + ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS = 84, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86, + ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87, + ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88, + ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89, + ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90, + ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93, + ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102, + ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104, + ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105, + ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106, + ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107, + ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108, + ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109, // TODO: target entry is missing - ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, - ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112, - ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, - ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, - // 0..115 => 116 criteria types total - ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115, + ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, + ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE = 112, + ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, + ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, + ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115, + ACHIEVEMENT_CRITERIA_TYPE_UNK118 = 118, ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119, - // 120 - // 121 - // 122 - // 123 - // 0..123 => 124 criteria types total - ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 124, + ACHIEVEMENT_CRITERIA_TYPE_UNK120 = 120, + ACHIEVEMENT_CRITERIA_TYPE_UNK121 = 121, + ACHIEVEMENT_CRITERIA_TYPE_UNK122 = 122, + ACHIEVEMENT_CRITERIA_TYPE_UNK123 = 123, + ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS = 124, + ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125, + ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD = 126, + ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL = 127, + ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS = 128, + ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS = 129, + ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND = 130, + ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING = 132, + ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD = 133, + ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD = 134, + ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD = 135, + ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD = 136, + ACHIEVEMENT_CRITERIA_TYPE_UNK137 = 137, + ACHIEVEMENT_CRITERIA_TYPE_UNK138 = 138, //struct { Flag flag; uint32 count; } 1: Guild Dungeon, 2:Guild Challenge, 3:Guild battlefield + ACHIEVEMENT_CRITERIA_TYPE_UNK139 = 139, //struct { uint32 count; } Guild Challenge + ACHIEVEMENT_CRITERIA_TYPE_UNK140 = 140, + ACHIEVEMENT_CRITERIA_TYPE_UNK141 = 141, + ACHIEVEMENT_CRITERIA_TYPE_UNK142 = 142, + ACHIEVEMENT_CRITERIA_TYPE_UNK143 = 143, + ACHIEVEMENT_CRITERIA_TYPE_UNK144 = 144, + ACHIEVEMENT_CRITERIA_TYPE_UNK145 = 145, + ACHIEVEMENT_CRITERIA_TYPE_UNK146 = 146, + ACHIEVEMENT_CRITERIA_TYPE_UNK147 = 147, + ACHIEVEMENT_CRITERIA_TYPE_UNK148 = 148, + ACHIEVEMENT_CRITERIA_TYPE_UNK149 = 149, + ACHIEVEMENT_CRITERIA_TYPE_UNK150 = 150, + // 0..144 => 145 criteria types total + ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 151, }; enum AchievementCategory @@ -233,7 +337,7 @@ enum AchievementCategory enum AreaFlags { - AREA_FLAG_UNK0 = 0x00000001, // Unknown + AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring) AREA_FLAG_UNK1 = 0x00000002, // Razorfen Downs, Naxxramas and Acherus: The Ebon Hold (3.3.5a) AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before) AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones @@ -261,7 +365,8 @@ enum AreaFlags AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Can Hearth And Resurrect From Area - AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly + AREA_FLAG_NO_FLY_ZONE = 0x20000000, // Marks zones where you cannot fly + AREA_FLAG_UNK9 = 0x40000000, }; enum Difficulty @@ -286,7 +391,7 @@ enum Difficulty enum SpawnMask { - SPAWNMASK_CONTINENT = (1 << REGULAR_DIFFICULTY), // any any maps without spawn modes + SPAWNMASK_CONTINENT = (1 << REGULAR_DIFFICULTY), // any maps without spawn modes SPAWNMASK_DUNGEON_NORMAL = (1 << DUNGEON_DIFFICULTY_NORMAL), SPAWNMASK_DUNGEON_HEROIC = (1 << DUNGEON_DIFFICULTY_HEROIC), @@ -349,19 +454,25 @@ enum ItemEnchantmentType enum ItemLimitCategoryMode { - ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank - ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1, // limit applied to amount equipped items (including used gems) + ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank + ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1, // limit applied to amount equipped items (including used gems) +}; + +enum MountFlags +{ + MOUNT_FLAG_CAN_PITCH = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING + MOUNT_FLAG_CAN_SWIM = 0x8, // client checks MOVEMENTFLAG_SWIMMING }; enum TotemCategoryType { - TOTEM_CATEGORY_TYPE_KNIFE = 1, - TOTEM_CATEGORY_TYPE_TOTEM = 2, - TOTEM_CATEGORY_TYPE_ROD = 3, - TOTEM_CATEGORY_TYPE_PICK = 21, - TOTEM_CATEGORY_TYPE_STONE = 22, - TOTEM_CATEGORY_TYPE_HAMMER = 23, - TOTEM_CATEGORY_TYPE_SPANNER = 24 + TOTEM_CATEGORY_TYPE_KNIFE = 1, + TOTEM_CATEGORY_TYPE_TOTEM = 2, + TOTEM_CATEGORY_TYPE_ROD = 3, + TOTEM_CATEGORY_TYPE_PICK = 21, + TOTEM_CATEGORY_TYPE_STONE = 22, + TOTEM_CATEGORY_TYPE_HAMMER = 23, + TOTEM_CATEGORY_TYPE_SPANNER = 24 }; // SummonProperties.dbc, col 1 @@ -389,7 +500,8 @@ enum SummonPropType SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3 SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells SUMMON_PROP_TYPE_LIGHTWELL = 11, // summon lightwell, 6 spells in 3.0.3 - SUMMON_PROP_TYPE_JEEVES = 12 // summon Jeeves, 1 spell in 3.3.5a + SUMMON_PROP_TYPE_JEEVES = 12, // summon Jeeves, 1 spell in 3.3.5a + SUMMON_PROP_TYPE_LASHTAIL = 13, // Lashtail Hatchling, 1 spell in 4.2.2 }; // SummonProperties.dbc, col 5 @@ -412,6 +524,11 @@ enum SummonPropFlags SUMMON_PROP_FLAG_UNK14 = 0x00002000, // Guides, player follows SUMMON_PROP_FLAG_UNK15 = 0x00004000, // Force of Nature, Shadowfiend, Feral Spirit, Summon Water Elemental SUMMON_PROP_FLAG_UNK16 = 0x00008000, // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related? + SUMMON_PROP_FLAG_UNK17 = 0x00010000, + SUMMON_PROP_FLAG_UNK18 = 0x00020000, + SUMMON_PROP_FLAG_UNK19 = 0x00040000, + SUMMON_PROP_FLAG_UNK20 = 0x00080000, + SUMMON_PROP_FLAG_UNK21 = 0x00100000, // Totems }; enum VehicleSeatFlags @@ -452,4 +569,13 @@ enum VehicleSeatFlagsB VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000 }; +// CurrencyTypes.dbc +enum CurrencyTypes +{ + CURRENCY_TYPE_CONQUEST_POINTS = 390, + CURRENCY_TYPE_HONOR_POINTS = 392, + CURRENCY_TYPE_JUSTICE_POINTS = 395, + CURRENCY_TYPE_VALOR_POINTS = 396 +}; + #endif diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 48ceda2a212..e2fce5491a9 100755..100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -17,12 +17,11 @@ */ #include "DBCStores.h" - #include "Log.h" #include "SharedDefines.h" #include "SpellMgr.h" - #include "DBCfmt.h" +#include "ItemPrototype.h" #include <map> @@ -59,6 +58,7 @@ static WMOAreaInfoByTripple sWMOAreaInfoByTripple; DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt); DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt); DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt); +DBCStorage <ArmorLocationEntry> sArmorLocationStore(ArmorLocationfmt); DBCStorage <AuctionHouseEntry> sAuctionHouseStore(AuctionHouseEntryfmt); DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt); @@ -68,6 +68,7 @@ DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt); DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt); DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt); DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt); +DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore(ChrClassesXPowerTypesfmt); DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt); DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt); DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt); @@ -104,15 +105,34 @@ DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStor DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt); //DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt); +DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore(GtOCTHpPerStaminafmt); DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); +DBCStorage <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore(GtOCTBaseHPByClassfmt); +DBCStorage <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore(GtOCTBaseMPByClassfmt); DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt); -DBCStorage <ItemEntry> sItemStore(Itemfmt); +DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore(ImportPriceArmorfmt); +DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore(ImportPriceQualityfmt); +DBCStorage <ImportPriceShieldEntry> sImportPriceShieldStore(ImportPriceShieldfmt); +DBCStorage <ImportPriceWeaponEntry> sImportPriceWeaponStore(ImportPriceWeaponfmt); +DBCStorage <ItemPriceBaseEntry> sItemPriceBaseStore(ItemPriceBasefmt); +DBCStorage <ItemReforgeEntry> sItemReforgeStore(ItemReforgefmt); +DBCStorage <ItemArmorQualityEntry> sItemArmorQualityStore(ItemArmorQualityfmt); +DBCStorage <ItemArmorShieldEntry> sItemArmorShieldStore(ItemArmorShieldfmt); +DBCStorage <ItemArmorTotalEntry> sItemArmorTotalStore(ItemArmorTotalfmt); +DBCStorage <ItemClassEntry> sItemClassStore(ItemClassfmt); DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt); -//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt); +DBCStorage <ItemDamageEntry> sItemDamageAmmoStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageOneHandStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageOneHandCasterStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageRangedStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageThrownStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageTwoHandStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageTwoHandCasterStore(ItemDamagefmt); +DBCStorage <ItemDamageEntry> sItemDamageWandStore(ItemDamagefmt); +DBCStorage <ItemDisenchantLootEntry> sItemDisenchantLootStore(ItemDisenchantLootfmt); //DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently -DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt); DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt); DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt); DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt); @@ -130,6 +150,12 @@ DBCStorage <MapDifficultyEntry> sMapDifficultyStore(MapDifficultyEntryfmt); // o MapDifficultyMap sMapDifficultyMap; DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt); +DBCStorage <MountCapabilityEntry> sMountCapabilityStore(MountCapabilityfmt); +DBCStorage <MountTypeEntry> sMountTypeStore(MountTypefmt); + +DBCStorage <NameGenEntry> sNameGenStore(NameGenfmt); +NameGenVectorArraysMap sGenNameVectoArraysMap; +DBCStorage <NumTalentsAtLevelEntry> sNumTalentsAtLevelStore(NumTalentsAtLevelfmt); DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore(OverrideSpellDatafmt); @@ -153,19 +179,44 @@ DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt); SpellCategoryStore sSpellCategoryStore; PetFamilySpellsStore sPetFamilySpellsStore; + +DBCStorage <SpellReagentsEntry> sSpellReagentsStore(SpellReagentsEntryfmt); +DBCStorage <SpellScalingEntry> sSpellScalingStore(SpellScalingEntryfmt); +DBCStorage <SpellTotemsEntry> sSpellTotemsStore(SpellTotemsEntryfmt); +DBCStorage <SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore(SpellTargetRestrictionsEntryfmt); +DBCStorage <SpellPowerEntry> sSpellPowerStore(SpellPowerEntryfmt); +DBCStorage <SpellLevelsEntry> sSpellLevelsStore(SpellLevelsEntryfmt); +DBCStorage <SpellInterruptsEntry> sSpellInterruptsStore(SpellInterruptsEntryfmt); +DBCStorage <SpellEquippedItemsEntry> sSpellEquippedItemsStore(SpellEquippedItemsEntryfmt); +DBCStorage <SpellClassOptionsEntry> sSpellClassOptionsStore(SpellClassOptionsEntryfmt); +DBCStorage <SpellCooldownsEntry> sSpellCooldownsStore(SpellCooldownsEntryfmt); +DBCStorage <SpellAuraOptionsEntry> sSpellAuraOptionsStore(SpellAuraOptionsEntryfmt); +DBCStorage <SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore(SpellAuraRestrictionsEntryfmt); +DBCStorage <SpellCastingRequirementsEntry> sSpellCastingRequirementsStore(SpellCastingRequirementsEntryfmt); + +SpellEffectMap sSpellEffectMap; +SpellReagentMap sSpellReagentMap; +SpellTotemMap sSpellTotemMap; + DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore(SpellCastTimefmt); +DBCStorage <SpellCategoriesEntry> sSpellCategoriesStore(SpellCategoriesEntryfmt); +DBCStorage <SpellEffectEntry> sSpellEffectStore(SpellEffectEntryfmt); DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore(SpellDifficultyfmt); DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt); DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt); DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt); DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt); DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostfmt); -DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt); +DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftEntryfmt); +DBCStorage <SpellShapeshiftFormEntry> sSpellShapeshiftFormStore(SpellShapeshiftFormfmt); DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt); DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt); TalentSpellPosMap sTalentSpellPosMap; DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt); +DBCStorage <TalentTreePrimarySpellsEntry> sTalentTreePrimarySpellsStore(TalentTreePrimarySpellsfmt); +typedef std::map<uint32, std::vector<uint32> > TalentTreePrimarySpellsMap; +TalentTreePrimarySpellsMap sTalentTreePrimarySpellsMap; // store absolute bit position for first rank for talent inspect static uint32 sTalentTabPages[MAX_CLASSES][3]; @@ -193,6 +244,7 @@ DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore(WMOAreaTableEntryfmt); DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt); DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt); DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt); +DBCStorage <PhaseEntry> sPhaseStores(PhaseEntryfmt); typedef std::list<std::string> StoreProblemList; @@ -276,34 +328,36 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex); - LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc"/*, &CustomAchievementfmt, &CustomAchievementIndex*/);//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sArmorLocationStore, dbcPath, "ArmorLocation.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sChrPowerTypesStore, dbcPath, "ChrClassesXPowerTypes.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc");//14545 for (uint32 i=0; i<sFactionStore.GetNumRows(); ++i) { FactionEntry const* faction = sFactionStore.LookupEntry(i); @@ -314,8 +368,8 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc");//14545 for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) { if (GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(i)) @@ -329,95 +383,129 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc");//14545 + //LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTHpPerStaminaStore, dbcPath, "gtOCTHpPerStamina.dbc");//14545 //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently - LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sItemStore, dbcPath, "Item.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); + //LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTBaseHPByClassStore, dbcPath, "gtOCTBaseHPByClass.dbc");//15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTBaseMPByClassStore, dbcPath, "gtOCTBaseMPByClass.dbc");//15595 + + LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceArmorStore, dbcPath, "ImportPriceArmor.dbc"); // 15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceQualityStore, dbcPath, "ImportPriceQuality.dbc"); // 15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceShieldStore, dbcPath, "ImportPriceShield.dbc"); // 15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceWeaponStore, dbcPath, "ImportPriceWeapon.dbc"); // 15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemPriceBaseStore, dbcPath, "ItemPriceBase.dbc"); // 15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemReforgeStore, dbcPath, "ItemReforge.dbc"); // 15595 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); // 15595 //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently - //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemCondExtCostsStore, dbcPath, "ItemCondExtCosts.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc");//14545 + + LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorQualityStore, dbcPath, "ItemArmorQuality.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorShieldStore, dbcPath, "ItemArmorShield.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorTotalStore, dbcPath, "ItemArmorTotal.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageAmmoStore, dbcPath, "ItemDamageAmmo.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageOneHandStore, dbcPath, "ItemDamageOneHand.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageOneHandCasterStore,dbcPath, "ItemDamageOneHandCaster.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageRangedStore, dbcPath, "ItemDamageRanged.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageThrownStore, dbcPath, "ItemDamageThrown.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageTwoHandStore, dbcPath, "ItemDamageTwoHand.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageTwoHandCasterStore,dbcPath, "ItemDamageTwoHandCaster.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageWandStore, dbcPath, "ItemDamageWand.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sItemDisenchantLootStore, dbcPath, "ItemDisenchantLoot.dbc"); + + LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sPhaseStores, dbcPath, "Phase.dbc");//14545 + + LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc");//14545 // fill data - for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) + sMapDifficultyMap[MAKE_PAIR32(0, 0)] = MapDifficulty(0, 0, false);//map 0 is missingg from MapDifficulty.dbc use this till its ported to sql + for (uint32 i = 0; i < sMapDifficultyStore.GetNumRows(); ++i) if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) - sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0'); + sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] > 0); sMapDifficultyStore.Clear(); - LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sMountCapabilityStore, dbcPath, "MountCapability.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sMountTypeStore, dbcPath, "MountType.dbc");//14545 + + LoadDBC(availableDbcLocales, bad_dbc_files, sNameGenStore, dbcPath, "NameGen.dbc");//14545 + for (uint32 i = 0; i < sNameGenStore.GetNumRows(); ++i) + if (NameGenEntry const* entry = sNameGenStore.LookupEntry(i)) + sGenNameVectoArraysMap[entry->race].stringVectorArray[entry->gender].push_back(std::string(entry->name)); + sNameGenStore.Clear(); + LoadDBC(availableDbcLocales, bad_dbc_files, sNumTalentsAtLevelStore, dbcPath, "NumTalentsAtLevel.dbc");//14545 - LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc");//14545 - LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc");//14545 + + LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc");//14545 for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); - LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc");//14545 - LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc");//14545 - LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex); + LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"/*, &CustomSpellEntryfmt, &CustomSpellEntryIndex*/);// for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) { - SpellEntry const* spell = sSpellStore.LookupEntry(i); + SpellCategoriesEntry const* spell = sSpellCategoriesStore.LookupEntry(i); if (spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); } for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { - SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); if (!skillLine) continue; SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); - if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) { for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) { + SpellLevelsEntry const* levels = sSpellLevelsStore.LookupEntry(i); + if (!levels) + continue; + CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if (!cFamily) continue; if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; - if (spellInfo->spellLevel) + if (levels->spellLevel) continue; if (skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL) @@ -428,20 +516,45 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshiftForm.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); + + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellReagentsStore, dbcPath,"SpellReagents.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellScalingStore, dbcPath,"SpellScaling.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTotemsStore, dbcPath,"SpellTotems.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTargetRestrictionsStore,dbcPath,"SpellTargetRestrictions.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellPowerStore, dbcPath,"SpellPower.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellLevelsStore, dbcPath,"SpellLevels.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellInterruptsStore, dbcPath,"SpellInterrupts.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEquippedItemsStore, dbcPath,"SpellEquippedItems.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellClassOptionsStore, dbcPath,"SpellClassOptions.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCooldownsStore, dbcPath,"SpellCooldowns.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraOptionsStore, dbcPath,"SpellAuraOptions.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraRestrictionsStore, dbcPath,"SpellAuraRestrictions.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastingRequirementsStore, dbcPath,"SpellCastingRequirements.dbc");//14545 + + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath,"SpellCategories.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEffectStore, dbcPath,"SpellEffect.dbc");//14545 + + for(uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i) + { + if(SpellEffectEntry const *spellEffect = sSpellEffectStore.LookupEntry(i)) + sSpellEffectMap[spellEffect->EffectSpellId].effects[spellEffect->EffectIndex] = spellEffect; + } + + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc"/*, &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex*/);//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshift.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc");//14545 + //LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc");//14545 + + LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc");//14545 // Create Spelldifficulty searcher for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i) @@ -482,7 +595,7 @@ void LoadDBCStores(const std::string& dataPath) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); } - LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc");//14545 // prepare fast data access to bit pos of talent ranks for use at inspecting { @@ -498,22 +611,27 @@ void LoadDBCStores(const std::string& dataPath) continue; // store class talent tab pages - uint32 cls = 1; - for (uint32 m=1; !(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES; m <<= 1, ++cls) {} - - sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; + for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) + if (talentTabInfo->ClassMask & (1 << (cls - 1))) + sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabId; } } - LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTreePrimarySpellsStore, dbcPath, "TalentTreePrimarySpells.dbc"); + for (uint32 i = 0; i < sTalentTreePrimarySpellsStore.GetNumRows(); ++i) + if (TalentTreePrimarySpellsEntry const* talentSpell = sTalentTreePrimarySpellsStore.LookupEntry(i)) + sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId); + sTalentTreePrimarySpellsStore.Clear(); + + LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc");//14545 for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); //## TaxiPathNode.dbc ## Loaded only for initialization different structures - LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc");//14545 // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used @@ -536,11 +654,10 @@ void LoadDBCStores(const std::string& dataPath) // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; - for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) - if (SpellEntry const* sInfo = sSpellStore.LookupEntry (i)) - for (int j = 0; j < MAX_SPELL_EFFECTS; ++j) - if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) - spellPaths.insert(sInfo->EffectMiscValue[j]); + for (uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i) + if (SpellEffectEntry const* sInfo = sSpellEffectStore.LookupEntry (i)) + if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI) + spellPaths.insert(sInfo->EffectMiscValue); memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); memset(sOldContinentsNodesMask, 0, sizeof(sOldContinentsNodesMask)); @@ -593,19 +710,19 @@ void LoadDBCStores(const std::string& dataPath) } } - LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); + //LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc");//14545 - LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc");//14545 - LoadDBC(availableDbcLocales, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc");//14545 for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); + LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc");//14545 + LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc");//14545 // error checks if (bad_dbc_files.size() >= DBCFileCount) @@ -624,20 +741,25 @@ void LoadDBCStores(const std::string& dataPath) } // Check loaded DBC files proper version - if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a - !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a - !sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.5a - !sItemStore.LookupEntry(56806) || // last gem property added in 3.3.5a - !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a - !sMapStore.LookupEntry(724) || // last map added in 3.3.5a - !sSpellStore.LookupEntry(80864) ) // last client known item added in 3.3.5a + if (!sAreaStore.LookupEntry(4713) || // last area (areaflag) added in 4.3.4 (15595) + !sCharTitlesStore.LookupEntry(287) || // last char title added in 4.3.4 (15595) + !sGemPropertiesStore.LookupEntry(2250) || // last gem property added in 4.3.4 (15595) + !sMapStore.LookupEntry(980) || // last map added in 4.3.4 (15595) + !sSpellStore.LookupEntry(121820) ) // last spell added in 4.3.4 (15595) { sLog->outError(LOG_FILTER_GENERAL, "You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } - sLog->outInfo(LOG_FILTER_GENERAL, ">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_GENERAL, ">> Initialized %d DBC data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); +} +const std::string* GetRandomCharacterName(uint8 race, uint8 gender) +{ + uint32 size = sGenNameVectoArraysMap[race].stringVectorArray[gender].size(); + uint32 randPos = urand(0,size-1); + + return &sGenNameVectoArraysMap[race].stringVectorArray[gender][randPos]; } SimpleFactionsList const* GetFactionTeamList(uint32 faction) @@ -649,14 +771,41 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction) return NULL; } -char* GetPetName(uint32 petfamily, uint32 dbclang) +char const* GetPetName(uint32 petfamily, uint32 /*dbclang*/) { if (!petfamily) return NULL; CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(petfamily); if (!pet_family) return NULL; - return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL; + return pet_family->Name ? pet_family->Name : NULL; +} + +SpellEffectEntry const* GetSpellEffectEntry(uint32 spellId, uint32 effect) +{ + SpellEffectMap::const_iterator itr = sSpellEffectMap.find(spellId); + if(itr == sSpellEffectMap.end()) + return NULL; + + return itr->second.effects[effect]; +} + +SpellReagentsEntry const* GetSpellReagentEntry(uint32 spellId, uint8 reagent) +{ + SpellReagentMap::const_iterator itr = sSpellReagentMap.find(spellId); + if(itr == sSpellReagentMap.end()) + return NULL; + + return itr->second.reagents[reagent]; +} + +SpellTotemsEntry const* GetSpellTotemEntry(uint32 spellId, uint8 totem) +{ + SpellTotemMap::const_iterator itr = sSpellTotemMap.find(spellId); + if(itr == sSpellTotemMap.end()) + return NULL; + + return itr->second.totems[totem]; } TalentSpellPos const* GetTalentSpellPos(uint32 spellId) @@ -724,7 +873,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid) uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { - if (mapid != 530 && mapid != 571) // speed for most cases + if (mapid != 530 && mapid != 571 && mapid != 732) // speed for most cases return mapid; if (WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) @@ -743,12 +892,7 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) if (!mapEntry) return CONTENT_1_60; - switch (mapEntry->Expansion()) - { - default: return CONTENT_1_60; - case 1: return CONTENT_61_70; - case 2: return CONTENT_71_80; - } + return ContentLevels(mapEntry->Expansion()); } bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) @@ -866,6 +1010,15 @@ uint32 const* GetTalentTabPages(uint8 cls) return sTalentTabPages[cls]; } +std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree) +{ + TalentTreePrimarySpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree); + if (itr == sTalentTreePrimarySpellsMap.end()) + return NULL; + + return &itr->second; +} + uint32 GetLiquidFlags(uint32 liquidType) { if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquidType)) @@ -874,3 +1027,155 @@ uint32 GetLiquidFlags(uint32 liquidType) return 0; } +uint32 ScalingStatValuesEntry::GetStatMultiplier(uint32 inventoryType) const +{ + if (inventoryType < MAX_INVTYPE) + { + switch (inventoryType) + { + case INVTYPE_NON_EQUIP: + case INVTYPE_BODY: + case INVTYPE_BAG: + case INVTYPE_TABARD: + case INVTYPE_AMMO: + case INVTYPE_QUIVER: + return 0; + case INVTYPE_HEAD: + case INVTYPE_CHEST: + case INVTYPE_LEGS: + case INVTYPE_2HWEAPON: + case INVTYPE_ROBE: + return StatMultiplier[0]; + case INVTYPE_SHOULDERS: + case INVTYPE_WAIST: + case INVTYPE_FEET: + case INVTYPE_HANDS: + case INVTYPE_TRINKET: + return StatMultiplier[1]; + case INVTYPE_NECK: + case INVTYPE_WRISTS: + case INVTYPE_FINGER: + case INVTYPE_SHIELD: + case INVTYPE_CLOAK: + case INVTYPE_HOLDABLE: + return StatMultiplier[2]; + case INVTYPE_RANGED: + case INVTYPE_THROWN: + case INVTYPE_RANGEDRIGHT: + case INVTYPE_RELIC: + return StatMultiplier[3]; + case INVTYPE_WEAPON: + case INVTYPE_WEAPONMAINHAND: + case INVTYPE_WEAPONOFFHAND: + return StatMultiplier[4]; + default: + break; + } + } + return 0; +} + +uint32 ScalingStatValuesEntry::GetArmor(uint32 inventoryType, uint32 armorType) const +{ + if (inventoryType <= INVTYPE_ROBE && armorType < 4) + { + switch (inventoryType) + { + case INVTYPE_NON_EQUIP: + case INVTYPE_NECK: + case INVTYPE_BODY: + case INVTYPE_FINGER: + case INVTYPE_TRINKET: + case INVTYPE_WEAPON: + case INVTYPE_SHIELD: + case INVTYPE_RANGED: + case INVTYPE_2HWEAPON: + case INVTYPE_BAG: + case INVTYPE_TABARD: + break; + case INVTYPE_SHOULDERS: + return Armor[0][armorType]; + case INVTYPE_CHEST: + case INVTYPE_ROBE: + return Armor[1][armorType]; + case INVTYPE_HEAD: + return Armor[2][armorType]; + case INVTYPE_LEGS: + return Armor[3][armorType]; + case INVTYPE_FEET: + return Armor[4][armorType]; + case INVTYPE_WAIST: + return Armor[5][armorType]; + case INVTYPE_HANDS: + return Armor[6][armorType]; + case INVTYPE_WRISTS: + return Armor[7][armorType]; + case INVTYPE_CLOAK: + return CloakArmor; + default: + break; + } + } + return 0; +} + +uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool isCasterWeapon, float* damageMultiplier) const +{ + if (!isCasterWeapon) + { + switch (subClass) + { + case ITEM_SUBCLASS_WEAPON_AXE: + case ITEM_SUBCLASS_WEAPON_MACE: + case ITEM_SUBCLASS_WEAPON_SWORD: + case ITEM_SUBCLASS_WEAPON_DAGGER: + case ITEM_SUBCLASS_WEAPON_THROWN: + *damageMultiplier = 0.3f; + return dpsMod[0]; + case ITEM_SUBCLASS_WEAPON_AXE2: + case ITEM_SUBCLASS_WEAPON_MACE2: + case ITEM_SUBCLASS_WEAPON_POLEARM: + case ITEM_SUBCLASS_WEAPON_SWORD2: + case ITEM_SUBCLASS_WEAPON_STAFF: + case ITEM_SUBCLASS_WEAPON_FISHING_POLE: + *damageMultiplier = 0.2f; + return dpsMod[1]; + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_GUN: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + *damageMultiplier = 0.3f; + return dpsMod[4]; + case ITEM_SUBCLASS_WEAPON_Obsolete: + case ITEM_SUBCLASS_WEAPON_EXOTIC: + case ITEM_SUBCLASS_WEAPON_EXOTIC2: + case ITEM_SUBCLASS_WEAPON_FIST_WEAPON: + case ITEM_SUBCLASS_WEAPON_MISCELLANEOUS: + case ITEM_SUBCLASS_WEAPON_SPEAR: + case ITEM_SUBCLASS_WEAPON_WAND: + break; + } + } + else + { + if (subClass <= ITEM_SUBCLASS_WEAPON_WAND) + { + uint32 mask = 1 << subClass; + // two-handed weapons + if (mask & 0x562) + { + *damageMultiplier = 0.2f; + return dpsMod[3]; + } + + if (mask & (1 << ITEM_SUBCLASS_WEAPON_WAND)) + { + *damageMultiplier = 0.3f; + return dpsMod[5]; + } + } + *damageMultiplier = 0.3f; + return dpsMod[2]; + } + return 0; +} + diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index cd30ed587f8..b8ecb9398fb 100755 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -28,9 +28,12 @@ typedef std::list<uint32> SimpleFactionsList; SimpleFactionsList const* GetFactionTeamList(uint32 faction); -char* GetPetName(uint32 petfamily, uint32 dbclang); +char const* GetPetName(uint32 petfamily, uint32 dbclang); uint32 GetTalentSpellCost(uint32 spellId); TalentSpellPos const* GetTalentSpellPos(uint32 spellId); +SpellEffectEntry const* GetSpellEffectEntry(uint32 spellId, uint32 effect); +SpellReagentsEntry const* GetSpellReagentEntry(uint32 spellId, uint8 reagent); +SpellTotemsEntry const* GetSpellTotemEntry(uint32 spellId, uint8 totem); int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id); @@ -41,12 +44,16 @@ WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); +const std::string* GetRandomCharacterName(uint8 race, uint8 gender); + enum ContentLevels { - CONTENT_1_60 = 0, - CONTENT_61_70, - CONTENT_71_80 + CONTENT_1_60 = 0, + CONTENT_61_70 = 1, + CONTENT_71_80 = 2, + CONTENT_81_85 = 3 }; + ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); @@ -59,6 +66,7 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty); MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty); uint32 const* /*[MAX_TALENT_TABS]*/ GetTalentTabPages(uint8 cls); +std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree); uint32 GetLiquidFlags(uint32 liquidType); @@ -71,6 +79,7 @@ extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access extern DBCStorage <AreaGroupEntry> sAreaGroupStore; extern DBCStorage <AreaPOIEntry> sAreaPOIStore; extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore; +extern DBCStorage <ArmorLocationEntry> sArmorLocationStore; extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore; extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore; extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore; @@ -80,6 +89,7 @@ extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore; extern DBCStorage <CharTitlesEntry> sCharTitlesStore; extern DBCStorage <ChrClassesEntry> sChrClassesStore; extern DBCStorage <ChrRacesEntry> sChrRacesStore; +extern DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore; extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore; extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore; extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore; @@ -107,15 +117,34 @@ extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore; extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore; extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore; extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore; -extern DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore; //extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently extern DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore; +extern DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore; extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore; +extern DBCStorage <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore; +extern DBCStorage <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore; extern DBCStorage <HolidaysEntry> sHolidaysStore; -extern DBCStorage <ItemEntry> sItemStore; +extern DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore; +extern DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore; +extern DBCStorage <ImportPriceShieldEntry> sImportPriceShieldStore; +extern DBCStorage <ImportPriceWeaponEntry> sImportPriceWeaponStore; +extern DBCStorage <ItemPriceBaseEntry> sItemPriceBaseStore; +extern DBCStorage <ItemReforgeEntry> sItemReforgeStore; +extern DBCStorage <ItemArmorQualityEntry> sItemArmorQualityStore; +extern DBCStorage <ItemArmorShieldEntry> sItemArmorShieldStore; +extern DBCStorage <ItemArmorTotalEntry> sItemArmorTotalStore; +extern DBCStorage <ItemClassEntry> sItemClassStore; extern DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore; +extern DBCStorage <ItemDamageEntry> sItemDamageAmmoStore; +extern DBCStorage <ItemDamageEntry> sItemDamageOneHandStore; +extern DBCStorage <ItemDamageEntry> sItemDamageOneHandCasterStore; +extern DBCStorage <ItemDamageEntry> sItemDamageRangedStore; +extern DBCStorage <ItemDamageEntry> sItemDamageThrownStore; +extern DBCStorage <ItemDamageEntry> sItemDamageTwoHandStore; +extern DBCStorage <ItemDamageEntry> sItemDamageTwoHandCasterStore; +extern DBCStorage <ItemDamageEntry> sItemDamageWandStore; //extern DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore; -- not used currently -extern DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore; +extern DBCStorage <ItemDisenchantLootEntry> sItemDisenchantLootStore; extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore; extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore; extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore; @@ -125,6 +154,11 @@ extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore; extern DBCStorage <LockEntry> sLockStore; extern DBCStorage <MailTemplateEntry> sMailTemplateStore; extern DBCStorage <MapEntry> sMapStore; +extern DBCStorage <MountCapabilityEntry> sMountCapabilityStore; +extern DBCStorage <MountTypeEntry> sMountTypeStore; +extern DBCStorage <NameGenEntry> sNameGenStore; +extern DBCStorage <NumTalentsAtLevelEntry> sNumTalentsAtLevelStore; +extern DBCStorage <PhaseEntry> sPhaseStore; //extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed extern MapDifficultyMap sMapDifficultyMap; extern DBCStorage <MovieEntry> sMovieStore; @@ -150,8 +184,24 @@ extern DBCStorage <SpellRadiusEntry> sSpellRadiusStore; extern DBCStorage <SpellRangeEntry> sSpellRangeStore; extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore; extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore; +extern DBCStorage <SpellShapeshiftFormEntry> sSpellShapeshiftFormStore; extern DBCStorage <SpellEntry> sSpellStore; -extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore; +extern DBCStorage <SpellAuraOptionsEntry> sSpellAuraOptionsStore; +extern DBCStorage <SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore; +extern DBCStorage <SpellCastingRequirementsEntry> sSpellCastingRequirementsStore; +extern DBCStorage <SpellCategoriesEntry> sSpellCategoriesStore; +extern DBCStorage <SpellClassOptionsEntry> sSpellClassOptionsStore; +extern DBCStorage <SpellCooldownsEntry> sSpellCooldownsStore; +extern DBCStorage <SpellEffectEntry> sSpellEffectStore; +extern DBCStorage <SpellEquippedItemsEntry> sSpellEquippedItemsStore; +extern DBCStorage <SpellInterruptsEntry> sSpellInterruptsStore; +extern DBCStorage <SpellLevelsEntry> sSpellLevelsStore; +extern DBCStorage <SpellPowerEntry> sSpellPowerStore; +extern DBCStorage <SpellReagentsEntry> sSpellReagentsStore; +extern DBCStorage <SpellScalingEntry> sSpellScalingStore; +extern DBCStorage <SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore; +extern DBCStorage <SpellTotemsEntry> sSpellTotemsStore; +//extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore; extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore; extern DBCStorage <TalentEntry> sTalentStore; extern DBCStorage <TalentTabEntry> sTalentTabStore; @@ -164,7 +214,6 @@ extern TaxiMask sAllianceTaxiNodesMask; extern TaxiMask sDeathKnightTaxiNodesMask; extern TaxiPathSetBySource sTaxiPathSetBySource; extern TaxiPathNodesByPath sTaxiPathNodesByPath; -extern DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore; extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore; extern DBCStorage <VehicleEntry> sVehicleStore; extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index fdec06f6f48..38cc9fe29e7 100755..100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -44,28 +44,24 @@ struct AchievementEntry int32 requiredFaction; // 1 -1=all, 0=horde, 1=alliance int32 mapID; // 2 -1=none //uint32 parentAchievement; // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) - char *name[16]; // 4-19 - //uint32 name_flags; // 20 - //char *description[16]; // 21-36 - //uint32 desc_flags; // 37 - uint32 categoryId; // 38 - uint32 points; // 39 reward points - //uint32 OrderInCategory; // 40 - uint32 flags; // 41 - //uint32 icon; // 42 icon (from SpellIcon.dbc) - //char *titleReward[16]; // 43-58 - //uint32 titleReward_flags; // 59 - uint32 count; // 60 - need this count of completed criterias (own or referenced achievement criterias) - uint32 refAchievement; // 61 - referenced achievement (counting of all completed criterias) + char* name; // 4 + //char* description; // 5 + uint32 categoryId; // 6 + uint32 points; // 7 reward points + //uint32 OrderInCategory; // 8 + uint32 flags; // 9 + //uint32 icon; // 10 icon (from SpellIcon.dbc) + //char* reward; // 11 + uint32 count; // 12 - need this count of completed criterias (own or referenced achievement criterias) + uint32 refAchievement; // 13 - referenced achievement (counting of all completed criterias) }; struct AchievementCategoryEntry { uint32 ID; // 0 uint32 parentCategory; // 1 -1 for main category - //char *name[16]; // 2-17 - //uint32 name_flags; // 18 - //uint32 sortOrder; // 19 + //char* name; // 2 + //uint32 sortOrder; // 3 }; struct AchievementCriteriaEntry @@ -131,6 +127,13 @@ struct AchievementCriteriaEntry uint32 questCount; // 4 } complete_quests_in_zone; + // ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12 + struct + { + uint32 currency; + uint32 count; + } currencyGain; + // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14 struct { @@ -260,7 +263,14 @@ struct AchievementCriteriaEntry struct { uint32 teamtype; // 3 {2, 3, 5} - uint32 PersonalRating; // 4 + uint32 teamrating; // 4 + } reach_team_rating; + + // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39 + struct + { + uint32 teamtype; // 3 {2, 3, 5} + uint32 PersonalRating; // 4 } highest_personal_rating; // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40 @@ -370,6 +380,7 @@ struct AchievementCriteriaEntry } do_emote; // ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13 // ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55 + // ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56 struct { uint32 unused; // 3 @@ -504,15 +515,19 @@ struct AchievementCriteriaEntry uint32 additionalRequirement_value; } additionalRequirements[MAX_CRITERIA_REQUIREMENTS]; - //char* name[16]; // 9-24 - //uint32 name_flags; // 25 - uint32 flags; // 26 - uint32 timedType; // 27 - uint32 timerStartEvent; // 28 Alway appears with timed events - // for timed spells it is spell id for - // timed kills it is creature id - uint32 timeLimit; // 29 time limit in seconds - //uint32 showOrder; // 30 show order + char* name; // 9 m_description_lang + uint32 completionFlag; // 10 m_flags + uint32 timedCriteriaStartType; // 11 m_timer_start_event Only appears with timed achievements, seems to be the type of starting a timed Achievement, only type 1 and some of type 6 need manual starting + // 1: ByEventId(?) (serverside IDs), 2: ByQuestId, 5: ByCastSpellId(?) + // 6: BySpellIdTarget(some of these are unknown spells, some not, some maybe spells) + // 7: ByKillNpcId, 9: ByUseItemId + uint32 timedCriteriaMiscId; // 12 m_timer_asset_id Alway appears with timed events, used internally to start the achievement, store + uint32 timeLimit; // 13 m_timer_time time limit in seconds + uint32 showOrder; // 14 m_ui_order also used in achievement shift-links as index in state bitmask + //uint32 unk1; // 15 only one value, still unknown + //uint32 unk2; // 16 all zeros + uint32 additionalConditionType[MAX_ADDITIONAL_CRITERIA_CONDITIONS]; // 17-19 + uint32 additionalConditionValue[MAX_ADDITIONAL_CRITERIA_CONDITIONS]; // 20-22 }; struct AreaTableEntry @@ -521,13 +536,25 @@ struct AreaTableEntry uint32 mapid; // 1 uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area uint32 exploreFlag; // 3, main index - uint32 flags; // 4, unknown value but 312 for all cities - // 5-9 unused + uint32 flags; // 4, + //uint32 unk5; // 5, + //uint32 unk6; // 6, + //uint32 unk7; // 7, + //uint32 unk8; // 8, + //uint32 unk9; // 9, int32 area_level; // 10 - char* area_name[16]; // 11-26 - // 27, string flags, unused - uint32 team; // 28 - uint32 LiquidTypeOverride[4]; // 29-32 liquid override by type + char* area_name; // 11 + uint32 team; // 12 + uint32 LiquidTypeOverride[4]; // 13-16 liquid override by type + //float unk13; // 17, + //float unk13; // 18, + //uint32 unk19; // 19, All zeros (4.2.2) + //uint32 unk20; // 20 4.0.0 + //uint32 unk21; // 21 4.0.0 + //uint32 unk22; // 22 4.0.0 + //uint32 unk23; // 23 4.0.0 + //uint32 unk24; // 24 - worldStateId + //uint32 unk25 // 25 // helpers bool IsSanctuary() const @@ -553,16 +580,14 @@ struct AreaPOIEntry uint32 icon[11]; //1-11 float x; //12 float y; //13 - float z; //14 - uint32 mapId; //15 - //uint32 val1; //16 - uint32 zoneId; //17 - //char* name[16]; //18-33 - //uint32 name_flag; //34 - //char* name2[16]; //35-50 - //uint32 name_flag2; //51 - uint32 worldState; //52 - //uint32 val2; //53 + uint32 mapId; //14 + //uint32 val1; //15 + uint32 zoneId; //16 + //char* name; //17 - name + //char* name2; //18 - name2 + uint32 worldState; //19 + //uint32 val2; //20 + //uint32 unk; //21 }; struct AreaTriggerEntry @@ -572,11 +597,20 @@ struct AreaTriggerEntry float x; // 2 m_x float y; // 3 m_y float z; // 4 m_z - float radius; // 5 m_radius - float box_x; // 6 m_box_length - float box_y; // 7 m_box_width - float box_z; // 8 m_box_heigh - float box_orientation; // 9 m_box_yaw + //uint32 // 5 + //uint32 // 6 + //uint32 // 7 + float radius; // 8 m_radius + float box_x; // 9 m_box_length + float box_y; // 10 m_box_width + float box_z; // 11 m_box_heigh + float box_orientation; // 12 m_box_yaw +}; + +struct ArmorLocationEntry +{ + uint32 InventoryType; // 0 + float Value[5]; // 1-5 multiplier for armor types (cloth...plate, no armor?) }; struct AuctionHouseEntry @@ -585,8 +619,7 @@ struct AuctionHouseEntry uint32 faction; // 1 id of faction.dbc for player factions associated with city uint32 depositPercent; // 2 1/3 from real uint32 cutPercent; // 3 - //char* name[16]; // 4-19 - // 20 string flag, unused + //char* name; // 4 }; struct BankBagSlotPricesEntry @@ -599,14 +632,12 @@ struct BarberShopStyleEntry { uint32 Id; // 0 uint32 type; // 1 value 0 -> hair, value 2 -> facialhair - //char* name[16]; // 2-17 name of hair style - //uint32 name_flags; // 18 - //uint32 unk_name[16]; // 19-34, all empty - //uint32 unk_flags; // 35 - //float CostMultiplier; // 36 values 1 and 0.75 - uint32 race; // 37 race - uint32 gender; // 38 0 -> male, 1 -> female - uint32 hair_id; // 39 real ID to hair/facial hair + //char* name; // 2 m_DisplayName_lang + //uint32 unk_name; // 3 m_Description_lang + //float CostMultiplier; // 4 m_Cost_Modifier + uint32 race; // 5 m_race + uint32 gender; // 6 m_sex + uint32 hair_id; // 7 m_data (real ID to hair/facial hair) }; struct BattlemasterListEntry @@ -615,12 +646,15 @@ struct BattlemasterListEntry int32 mapid[8]; // 1-8 mapid uint32 type; // 9 (3 - BG, 4 - arena) //uint32 canJoinAsGroup; // 10 (0 or 1) - char* name[16]; // 11-26 - //uint32 nameFlags // 27 string flag, unused - uint32 maxGroupSize; // 28 maxGroupSize, used for checking if queue as group - uint32 HolidayWorldStateId; // 29 new 3.1 - //uint32 MinLevel; // 30 - //uint32 SomeLevel; // 31, may be max level + char* name; // 11 + uint32 maxGroupSize; // 12 maxGroupSize, used for checking if queue as group + uint32 HolidayWorldStateId; // 13 new 3.1 + uint32 minLevel; // 14, min level (sync with PvPDifficulty.dbc content) + uint32 maxLevel; // 15, max level (sync with PvPDifficulty.dbc content) + //uint32 maxGroupSizeRated; // 16 4.0.1 + //uint32 unk; // 17 - 4.0.6.13596 + //uint32 maxPlayers; // 18 4.0.1 + //uint32 unk1; // 19 4.0.3, value 2 for Rated Battlegrounds }; #define MAX_OUTFIT_ITEMS 24 @@ -635,46 +669,45 @@ struct CharStartOutfitEntry //uint32 Unknown1; // 38, unique values (index-like with gaps ordered in other way as ids) //uint32 Unknown2; // 39 //uint32 Unknown3; // 40 + //uint32 Unknown4; // 41 + //uint32 Unknown5; // 42 }; struct CharTitlesEntry { uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() //uint32 unk1; // 1 flags? - char* name[16]; // 2-17 - // 18 string flag, unused - //char* name2[16]; // 19-34, unused - // 35 string flag, unused - uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES + char* name; // 2 m_name_lang + //char* name2; // 3 m_name1_lang + uint32 bit_index; // 4 m_mask_ID used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES + //uint32 // 5 }; struct ChatChannelsEntry { uint32 ChannelID; // 0 uint32 flags; // 1 - char* pattern[16]; // 3-18 - // 19 string flags, unused - //char* name[16]; // 20-35 unused - // 36 string flag, unused + //uint32 // 2 m_factionGroup + char* pattern; // 3 m_name_lang + //char* name; // 4 m_shortcut_lang }; struct ChrClassesEntry { uint32 ClassID; // 0 - // 1, unused - uint32 powerType; // 2 - // 3-4, unused - //char* name[16]; // 5-20 unused - // 21 string flag, unused - //char* nameFemale[16]; // 21-36 unused, if different from base (male) case - // 37 string flag, unused - //char* nameNeutralGender[16]; // 38-53 unused, if different from base (male) case - // 54 string flag, unused - // 55, unused - uint32 spellfamily; // 56 - // 57, unused - uint32 CinematicSequence; // 58 id from CinematicSequences.dbc - uint32 expansion; // 59 (0 - original race, 1 - tbc addon, ...) + uint32 powerType; // 1 m_DisplayPower + // 2 m_petNameToken + char* name; // 3 m_name_lang + //char* nameFemale; // 4 m_name_female_lang + //char* nameNeutralGender; // 5 m_name_male_lang + //char* capitalizedName // 6, m_filename + uint32 spellfamily; // 7 m_spellClassSet + //uint32 flags2; // 8 m_flags (0x08 HasRelicSlot) + uint32 CinematicSequence; // 9 m_cinematicSequenceID + uint32 expansion; // 10 m_required_expansion + //uint32 // 11 + //uint32 // 12 + //uint32 // 13 }; struct ChrRacesEntry @@ -689,15 +722,23 @@ struct ChrRacesEntry uint32 TeamID; // 7 (7-Alliance 1-Horde) // 8-11 unused uint32 CinematicSequence; // 12 id from CinematicSequences.dbc - //uint32 unk_322; // 13 faction (0 alliance, 1 horde, 2 not available?) - char* name[16]; // 14-29 used for DBC language detection/selection - // 30 string flags, unused - //char* nameFemale[16]; // 31-46, if different from base (male) case - // 47 string flags, unused - //char* nameNeutralGender[16]; // 48-63, if different from base (male) case - // 64 string flags, unused - // 65-67 unused - uint32 expansion; // 68 (0 - original race, 1 - tbc addon, ...) + //uint32 unk_322; // 13 m_alliance (0 alliance, 1 horde, 2 not available?) + char* name; // 14 m_name_lang used for DBC language detection/selection + //char* nameFemale; // 15 m_name_female_lang + //char* nameNeutralGender; // 16 m_name_male_lang + // 17-18 m_facialHairCustomization[2] + // 19 m_hairCustomization + uint32 expansion; // 20 m_required_expansion + //uint32 // 21 (23 for worgens) + //uint32 // 22 4.0.0 + //uint32 // 23 4.0.0 +}; + +struct ChrPowerTypesEntry +{ + uint32 entry; // 0 + uint32 classId; // 1 + uint32 power; // 2 }; /* not used @@ -737,6 +778,7 @@ struct CreatureDisplayInfoEntry // 13 m_particleColorID // 14 m_creatureGeosetData // 15 m_objectEffectPackageID + // 16 }; struct CreatureFamilyEntry @@ -750,18 +792,17 @@ struct CreatureFamilyEntry uint32 petFoodMask; // 7 m_petFoodMask int32 petTalentType; // 8 m_petTalentType // 9 m_categoryEnumID - char* Name[16]; // 10-25 m_name_lang - // 26 string flags - // 27 m_iconFile + char* Name; // 10 m_name_lang + // 11 m_iconFile }; struct CreatureModelDataEntry { uint32 Id; //uint32 Flags; - //char* ModelPath[16] + //char* ModelPath //uint32 Unk1; - float Scale; // Used in calculation of unit collision data + //float Scale; // Used in calculation of unit collision data //int32 Unk2 //int32 Unk3 //uint32 Unk4 @@ -789,9 +830,8 @@ struct CreatureSpellDataEntry struct CreatureTypeEntry { uint32 ID; // 0 m_ID - //char* Name[16]; // 1-16 name - // 17 string flags - //uint32 no_expirience; // 18 no exp? critters, non-combat pets, gas cloud. + //char* Name; // 1 m_name_lang + //uint32 no_expirience; // 2 m_flags no exp? critters, non-combat pets, gas cloud. }; /* not used @@ -806,33 +846,45 @@ struct CurrencyCategoryEntry struct CurrencyTypesEntry { - //uint32 ID; // 0 not used - uint32 ItemId; // 1 used as real index - //uint32 Category; // 2 may be category - uint32 BitIndex; // 3 bit index in PLAYER_FIELD_KNOWN_CURRENCIES (1 << (index-1)) + uint32 ID; // 0 not used + //uint32 Category; // 1 may be category + //char* name; // 2 + //char* iconName; // 3 + //uint32 unk4; // 4 all 0 + //uint32 unk5; // 5 archaeology-related (?) + uint32 SubstitutionId; // 6 + uint32 TotalCap; // 7 + uint32 WeekCap; // 8 + uint32 Flags; // 9 + //char* description; // 10 }; struct DestructibleModelDataEntry { uint32 Id; + uint32 DamagedDisplayId; //uint32 DamagedUnk1; //uint32 DamagedUnk2; - uint32 DamagedDisplayId; //uint32 DamagedUnk3; + uint32 DestroyedDisplayId; //uint32 DestroyedUnk1; //uint32 DestroyedUnk2; - uint32 DestroyedDisplayId; //uint32 DestroyedUnk3; + //uint32 DestroyedUnk4; + uint32 RebuildingDisplayId; //uint32 RebuildingUnk1; //uint32 RebuildingUnk2; - uint32 RebuildingDisplayId; //uint32 RebuildingUnk3; + //uint32 RebuildingUnk4; + uint32 SmokeDisplayId; //uint32 SmokeUnk1; //uint32 SmokeUnk2; - uint32 SmokeDisplayId; //uint32 SmokeUnk3; - //uint32 Unk4; - //uint32 Unk5; + //uint32 SmokeUnk4; + //uint32 UnkDisplayid; + //uint32 Unk6; + //uint32 Unk7; + //uint32 Unk8; }; struct DungeonEncounterEntry @@ -842,7 +894,7 @@ struct DungeonEncounterEntry uint32 difficulty; // 2 instance mode //uint32 unk0; // 3 uint32 encounterIndex; // 4 encounter index for creating completed mask - char* encounterName[16]; // 5-20 encounter name + char* encounterName; // 5 encounter name //uint32 nameFlags; // 21 //uint32 unk1; // 22 }; @@ -862,12 +914,13 @@ struct DurabilityQualityEntry struct EmotesEntry { uint32 Id; // 0 - //char* Name; // 1, internal name - //uint32 AnimationId; // 2, ref to animationData + //char* Name; // 1, internal name + //uint32 AnimationId; // 2, ref to animationData uint32 Flags; // 3, bitmask, may be unit_flags uint32 EmoteType; // 4, Can be 0, 1 or 2 (determine how emote are shown) uint32 UnitStandState; // 5, uncomfirmed, may be enum UnitStandStateType - //uint32 SoundId; // 6, ref to soundEntries + //uint32 SoundId; // 6, ref to soundEntries + //uint32 unk7 // 7 }; struct EmotesTextEntry @@ -889,10 +942,9 @@ struct FactionEntry float spilloverRateOut; // 20 Faction outputs rep * spilloverRateOut as spillover reputation uint32 spilloverMaxRankIn; // 21 The highest rank the faction will profit from incoming spillover //uint32 spilloverRank_unk; // 22 It does not seem to be the max standing at which a faction outputs spillover ...so no idea - char* name[16]; // 23-38 m_name_lang - // 39 string flags - //char* description[16]; // 40-55 m_description_lang - // 56 string flags + char* name; // 23 m_name_lang + //char* description; // 24 m_description_lang + //uint32 // 25 // helpers bool CanHaveReputation() const @@ -918,6 +970,8 @@ struct FactionTemplateEntry // helpers bool IsFriendlyTo(FactionTemplateEntry const& entry) const { + if (ID == entry.ID) + return true; if (entry.faction) { for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) @@ -931,6 +985,8 @@ struct FactionTemplateEntry } bool IsHostileTo(FactionTemplateEntry const& entry) const { + if (ID == entry.ID) + return false; if (entry.faction) { for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) @@ -956,22 +1012,25 @@ struct FactionTemplateEntry struct GameObjectDisplayInfoEntry { uint32 Displayid; // 0 m_ID - char* filename; // 1 - //uint32 unk1[10]; //2-11 + char* filename; // 1 + //uint32 unk1[10]; //2-11 float minX; float minY; float minZ; float maxX; float maxY; float maxZ; - //uint32 transport; //18 + //uint32 transport; //18 }; struct GemPropertiesEntry { - uint32 ID; - uint32 spellitemenchantement; - uint32 color; + uint32 ID; // 0 m_id + uint32 spellitemenchantement; // 1 m_enchant_id + // 2 m_maxcount_inv + // 3 m_maxcount_item + uint32 color; // 4 m_type + //uint32 // 5 }; struct GlyphPropertiesEntry @@ -996,21 +1055,25 @@ struct GlyphSlotEntry struct GtBarberShopCostBaseEntry { + //uint32 level; float cost; }; struct GtCombatRatingsEntry { + //uint32 level; float ratio; }; struct GtChanceToMeleeCritBaseEntry { + //uint32 level; float base; }; struct GtChanceToMeleeCritEntry { + //uint32 level; float ratio; }; @@ -1034,10 +1097,15 @@ struct GtOCTRegenHPEntry float ratio; }; -//struct GtOCTRegenMPEntry -//{ -// float ratio; -//}; +struct GtOCTRegenMPEntry +{ + float ratio; +}; + +struct gtOCTHpPerStaminaEntry +{ + float ratio; +}; struct GtRegenHPPerSptEntry { @@ -1049,12 +1117,20 @@ struct GtRegenMPPerSptEntry float ratio; }; +struct GtOCTBaseHPByClassEntry +{ + float ratio; +}; + +struct GtOCTBaseMPByClassEntry +{ + float ratio; +}; /* no used struct HolidayDescriptionsEntry { uint32 ID; // 0, m_holidayDescriptionID - //char* name[16] // 1-16 m_name_lang - // 17 name flags + //char* name // 1 m_name_lang }; */ @@ -1062,8 +1138,7 @@ struct HolidayDescriptionsEntry struct HolidayNamesEntry { uint32 ID; // 0, m_holidayNameID - //char* name[16] // 1-16 m_name_lang - // 17 name flags + //char* name // 1 m_name_lang }; */ @@ -1087,23 +1162,105 @@ struct HolidaysEntry //uint32 flags; // 54 m_flags (0 = Darkmoon Faire, Fishing Contest and Wotlk Launch, rest is 1) }; -struct ItemEntry +// ImportPriceArmor.dbc +struct ImportPriceArmorEntry +{ + uint32 InventoryType; // 1 Id/InventoryType + float ClothFactor; // 2 Price factor cloth + float LeatherFactor; // 3 Price factor leather + float MailFactor; // 4 Price factor mail + float PlateFactor; // 5 Price factor plate +}; + +// ImportPriceQuality.dbc +struct ImportPriceQualityEntry +{ + uint32 QualityId; // 1 Quality Id (+1?) + float Factor; // 2 Price factor +}; + +// ImportPriceShield.dbc +struct ImportPriceShieldEntry +{ + uint32 Id; // 1 Unk id (only 1 and 2) + float Factor; // 2 Price factor +}; + +// ImportPriceWeapon.dbc +struct ImportPriceWeaponEntry { - uint32 ID; // 0 - uint32 Class; // 1 - uint32 SubClass; // 2 some items have strange subclasses - int32 Unk0; // 3 - int32 Material; // 4 - uint32 DisplayId; // 5 - uint32 InventoryType; // 6 - uint32 Sheath; // 7 + uint32 Id; // 1 Unk id (mainhand - 0, offhand - 1, weapon - 2, 2hweapon - 3, ranged/rangedright/relic - 4) + float Factor; // 2 Price factor +}; + +// ItemPriceBase.dbc +struct ItemPriceBaseEntry +{ + uint32 ItemLevel; // 2 Item level (1 - 1000) + float ArmorFactor; // 3 Price factor for armor + float WeaponFactor; // 4 Price factor for weapons +}; + +struct ItemReforgeEntry +{ + uint32 Id; + uint32 SourceStat; + float SourceMultiplier; + uint32 FinalStat; + float FinalMultiplier; +}; + +// common struct for: +// ItemDamageAmmo.dbc +// ItemDamageOneHand.dbc +// ItemDamageOneHandCaster.dbc +// ItemDamageRanged.dbc +// ItemDamageThrown.dbc +// ItemDamageTwoHand.dbc +// ItemDamageTwoHandCaster.dbc +// ItemDamageWand.dbc +struct ItemDamageEntry +{ + uint32 Id; // 0 item level + float DPS[7]; // 1-7 multiplier for item quality + uint32 Id2; // 8 item level +}; + +struct ItemArmorQualityEntry +{ + uint32 Id; // 0 item level + float Value[7]; // 1-7 multiplier for item quality + uint32 Id2; // 8 item level +}; + +struct ItemArmorShieldEntry +{ + uint32 Id; // 0 item level + uint32 Id2; // 1 item level + float Value[7]; // 2-8 multiplier for item quality +}; + +struct ItemArmorTotalEntry +{ + uint32 Id; // 0 item level + uint32 Id2; // 1 item level + float Value[4]; // 2-5 multiplier for armor types (cloth...plate) +}; + +// ItemClass.dbc +struct ItemClassEntry +{ + uint32 Class; // 1 item class id + //uint32 Unk; // 2 unk + //uint32 IsWeapon; // 3 1 for weapon, 0 for everything else + float PriceFactor; // 4 used to calculate certain prices + //char* Name; // class name }; struct ItemBagFamilyEntry { uint32 ID; // 0 - //char* name[16] // 1-16 m_name_lang - // // 17 name flags + //char* name; // 1 m_name_lang }; struct ItemDisplayInfoEntry @@ -1122,34 +1279,23 @@ struct ItemDisplayInfoEntry // 11 m_particleColorID }; -//struct ItemCondExtCostsEntry -//{ -// uint32 ID; -// uint32 condExtendedCost; // ItemTemplate::CondExtendedCost -// uint32 itemextendedcostentry; // ItemTemplate::ExtendedCost -// uint32 arenaseason; // arena season number(1-4) -//}; - -#define MAX_ITEM_EXTENDED_COST_REQUIREMENTS 5 - -struct ItemExtendedCostEntry +struct ItemDisenchantLootEntry { - uint32 ID; // 0 extended-cost entry id - uint32 reqhonorpoints; // 1 required honor points - uint32 reqarenapoints; // 2 required arena points - uint32 reqarenaslot; // 3 arena slot restrctions (min slot value) - uint32 reqitem[MAX_ITEM_EXTENDED_COST_REQUIREMENTS]; // 4-8 required item id - uint32 reqitemcount[MAX_ITEM_EXTENDED_COST_REQUIREMENTS]; // 9-14 required count of 1st item - uint32 reqpersonalarenarating; // 15 required personal arena rating}; + uint32 Id; + uint32 ItemClass; + int32 Unk; + uint32 ItemQuality; + uint32 MinItemLevel; + uint32 MaxItemLevel; + uint32 RequiredDisenchantSkill; }; struct ItemLimitCategoryEntry { uint32 ID; // 0 Id - //char* name[16] // 1-16 m_name_lang - // 17 name flags - uint32 maxCount; // 18, max allowed equipped as item or in gem slot - uint32 mode; // 19, 0 = have, 1 = equip (enum ItemLimitCategoryMode) + //char* name; // 1 m_name_lang + uint32 maxCount; // 2, m_quantity max allowed equipped as item or in gem slot + uint32 mode; // 3, m_flags 0 = have, 1 = equip (enum ItemLimitCategoryMode) }; #define MAX_ITEM_ENCHANTMENT_EFFECTS 3 @@ -1157,23 +1303,19 @@ struct ItemLimitCategoryEntry struct ItemRandomPropertiesEntry { uint32 ID; // 0 m_ID - //char* internalName // 1 m_Name + //char* internalName // 1 m_Name uint32 enchant_id[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 2-4 m_Enchantment // 5-6 unused - char* nameSuffix[16]; // 7-22 m_name_lang - // 23 name flags + char* nameSuffix; // 7 m_name_lang }; struct ItemRandomSuffixEntry { uint32 ID; // 0 m_ID - char* nameSuffix[16]; // 1-16 m_name_lang - // 17, name flags - // 18 m_internalName - uint32 enchant_id[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 19-21 m_enchantment - //uint32 unk1[2] // 22-23 unknown - uint32 prefix[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 24-26 m_allocationPct - //uint32 unk2[2] // 27-28 unknown + char* nameSuffix; // 1 m_name_lang + // 2 m_internalName + uint32 enchant_id[5]; // 3-7 m_enchantment + uint32 prefix[5]; // 8-12 m_allocationPct }; #define MAX_ITEM_SET_ITEMS 10 @@ -1182,35 +1324,33 @@ struct ItemRandomSuffixEntry struct ItemSetEntry { //uint32 id // 0 m_ID - char* name[16]; // 1-16 m_name_lang - // 17 string flags, unused - uint32 itemId[MAX_ITEM_SET_ITEMS]; // 18-27 m_itemID - //uint32 unknown[7]; // 28-34 unk, all 0 - uint32 spells[MAX_ITEM_SET_SPELLS]; // 35-42 m_setSpellID - uint32 items_to_triggerspell[MAX_ITEM_SET_SPELLS]; // 43-50 m_setThreshold - uint32 required_skill_id; // 51 m_requiredSkill - uint32 required_skill_value; // 52 m_requiredSkillRank + char* name; // 1 m_name_lang + uint32 itemId[MAX_ITEM_SET_ITEMS]; // 2-18 m_itemID + uint32 spells[MAX_ITEM_SET_SPELLS]; // 19-26 m_setSpellID + uint32 items_to_triggerspell[MAX_ITEM_SET_SPELLS]; // 27-34 m_setThreshold + uint32 required_skill_id; // 35 m_requiredSkill + uint32 required_skill_value; // 36 m_requiredSkillRank }; struct LFGDungeonEntry { uint32 ID; // 0 - //char* name[16]; // 1-17 Name lang - uint32 minlevel; // 18 - uint32 maxlevel; // 19 - uint32 reclevel; // 20 - uint32 recminlevel; // 21 - uint32 recmaxlevel; // 22 - int32 map; // 23 - uint32 difficulty; // 24 - //uint32 flags; // 25 (flags & 4) = IsHoliday - uint32 type; // 26 - //uint32 unk; // 27 - //char* iconname; // 28 - uint32 expansion; // 29 - //uint32 unk4; // 30 - uint32 grouptype; // 31 - //char* desc[16]; // 32-47 Description + //char* name; // 1 + uint32 minlevel; // 2 + uint32 maxlevel; // 3 + uint32 reclevel; // 4 + uint32 recminlevel; // 5 + uint32 recmaxlevel; // 6 + int32 map; // 7 + uint32 difficulty; // 8 + //uint32 unk; // 9 + uint32 type; // 10 + //uint32 unk2; // 11 + //char* unk3; // 12 + uint32 expansion; // 13 + //uint32 unk4; // 14 + uint32 grouptype; // 15 + //char* desc; // 16 Description // Helpers uint32 Entry() const { return ID + (type << 24); } }; @@ -1250,12 +1390,18 @@ struct LockEntry //uint32 Action[MAX_LOCK_CASE]; // 25-32 m_Action }; +struct PhaseEntry +{ + uint32 ID; // 0 + char* Name; // 1 + uint32 phaseShift; // 2 +}; + struct MailTemplateEntry { uint32 ID; // 0 - //char* subject[16]; // 1-16 - // 17 name flags, unused - char* content[16]; // 18-33 + //char* subject; // 1 m_subject_lang + char* content; // 2 m_body_lang }; struct MapEntry @@ -1264,23 +1410,22 @@ struct MapEntry //char* internalname; // 1 unused uint32 map_type; // 2 //uint32 unk_330; // 3 - // 4 0 or 1 for battlegrounds (not arenas) - char* name[16]; // 5-20 - // 21 name flags, unused - uint32 linked_zone; // 22 common zone for instance and continent map - //char* hordeIntro[16]; // 23-38 text for PvP Zones - // 39 intro text flags - //char* allianceIntro[16]; // 40-55 text for PvP Zones - // 56 intro text flags - uint32 multimap_id; // 57 - // 58 - int32 entrance_map; // 59 map_id of entrance map - float entrance_x; // 60 entrance x coordinate (if exist single entry) - float entrance_y; // 61 entrance y coordinate (if exist single entry) - // 62 -1, 0 and 720 - uint32 addon; // 63 (0-original maps, 1-tbc addon) - uint32 unk_time; // 64 some kind of time? - //uint32 maxPlayers; // 65 max players + //uint32 unk4; // 4 4.0.1 + //uint32 isPvP; // 5 m_PVP 0 or 1 for battlegrounds (not arenas) + char* name; // 6 m_MapName_lang + uint32 linked_zone; // 7 m_areaTableID + //char* hordeIntro; // 8 m_MapDescription0_lang + //char* allianceIntro; // 9 m_MapDescription1_lang + uint32 multimap_id; // 10 m_LoadingScreenID (LoadingScreens.dbc) + //float BattlefieldMapIconScale; // 11 m_minimapIconScale + int32 entrance_map; // 12 m_corpseMapID map_id of entrance map in ghost mode (continent always and in most cases = normal entrance) + float entrance_x; // 13 m_corpseX entrance x coordinate in ghost mode (in most cases = normal entrance) + float entrance_y; // 14 m_corpseY entrance y coordinate in ghost mode (in most cases = normal entrance) + //uint32 timeOfDayOverride; // 15 m_timeOfDayOverride + uint32 addon; // 16 m_expansionID + uint32 unk_time; // 17 m_raidOffset + //uint32 maxPlayers; // 18 m_maxPlayers + //uint32 unk400; // 19 new 4.0.0, mapid, related to phasing // Helpers uint32 Expansion() const { return addon; } @@ -1315,18 +1460,52 @@ struct MapDifficultyEntry //uint32 Id; // 0 uint32 MapId; // 1 uint32 Difficulty; // 2 (for arenas: arena slot) - char* areaTriggerText; // 3-18 text showed when transfer to map failed (missing requirements) - //uint32 textFlags; // 19 - uint32 resetTime; // 20 - uint32 maxPlayers; // 21 - //char* difficultyString; // 22 + char* areaTriggerText; // 3 m_message_lang (text showed when transfer to map failed) + uint32 resetTime; // 4, m_raidDuration in secs, 0 if no fixed reset time + uint32 maxPlayers; // 5, m_maxPlayers some heroic versions have 0 when expected same amount as in normal version + //char* difficultyString; // 6 m_difficultystring +}; + +struct MountCapabilityEntry +{ + uint32 Id; + uint32 Flags; + uint32 RequiredRidingSkill; + uint32 RequiredArea; + uint32 RequiredAura; + uint32 RequiredSpell; + uint32 SpeedModSpell; + int32 RequiredMap; +}; + +#define MAX_MOUNT_CAPABILITIES 24 + +struct MountTypeEntry +{ + uint32 Id; + uint32 MountCapability[MAX_MOUNT_CAPABILITIES]; }; struct MovieEntry { uint32 Id; // 0 index //char* filename; // 1 - //uint32 unk2; // 2 always 100 + //uint32 unk1; // 2 m_volume + //uint32 unk2; // 3 4.0.0 +}; + +struct NameGenEntry +{ + //uint32 id; + char* name; + uint32 race; + uint32 gender; +}; + +struct NumTalentsAtLevelEntry +{ + //uint32 Level; // 0 index + float Talents; // 1 talent count }; #define MAX_OVERRIDE_SPELL 10 @@ -1336,6 +1515,7 @@ struct OverrideSpellDataEntry uint32 id; // 0 uint32 spellId[MAX_OVERRIDE_SPELL]; // 1-10 //uint32 unk0; // 11 + //uint32 unk3; // 12 possibly flag }; struct PvPDifficultyEntry @@ -1354,8 +1534,7 @@ struct PvPDifficultyEntry struct QuestSortEntry { uint32 id; // 0 m_ID - //char* name[16]; // 1-16 m_SortName_lang - // 17 name flags + //char* name; // 1 m_SortName_lang }; struct QuestXPEntry @@ -1384,78 +1563,23 @@ struct ScalingStatDistributionEntry uint32 Id; // 0 int32 StatMod[10]; // 1-10 uint32 Modifier[10]; // 11-20 - uint32 MaxLevel; // 21 + //uint32 unk1; // 21 + uint32 MaxLevel; // 22 m_maxlevel }; struct ScalingStatValuesEntry { - uint32 Id; // 0 - uint32 Level; // 1 - uint32 ssdMultiplier[4]; // 2-5 Multiplier for ScalingStatDistribution - uint32 armorMod[4]; // 6-9 Armor for level - uint32 dpsMod[6]; // 10-15 DPS mod for level - uint32 spellPower; // 16 spell power for level - uint32 ssdMultiplier2; // 17 there's data from 3.1 dbc ssdMultiplier[3] - uint32 ssdMultiplier3; // 18 3.3 - uint32 armorMod2[5]; // 19-23 Armor for level - - uint32 getssdMultiplier(uint32 mask) const - { - if (mask & 0x4001F) - { - if (mask & 0x00000001) return ssdMultiplier[0]; // Shoulder - if (mask & 0x00000002) return ssdMultiplier[1]; // Trinket - if (mask & 0x00000004) return ssdMultiplier[2]; // Weapon1H - if (mask & 0x00000008) return ssdMultiplier2; - if (mask & 0x00000010) return ssdMultiplier[3]; // Ranged - if (mask & 0x00040000) return ssdMultiplier3; - } - return 0; - } - - uint32 getArmorMod(uint32 mask) const - { - if (mask & 0x00F001E0) - { - if (mask & 0x00000020) return armorMod[0]; // Cloth shoulder - if (mask & 0x00000040) return armorMod[1]; // Leather shoulder - if (mask & 0x00000080) return armorMod[2]; // Mail shoulder - if (mask & 0x00000100) return armorMod[3]; // Plate shoulder - - if (mask & 0x00080000) return armorMod2[0]; // cloak - if (mask & 0x00100000) return armorMod2[1]; // cloth - if (mask & 0x00200000) return armorMod2[2]; // leather - if (mask & 0x00400000) return armorMod2[3]; // mail - if (mask & 0x00800000) return armorMod2[4]; // plate - } - return 0; - } - - uint32 getDPSMod(uint32 mask) const - { - if (mask & 0x7E00) - { - if (mask & 0x00000200) return dpsMod[0]; // Weapon 1h - if (mask & 0x00000400) return dpsMod[1]; // Weapon 2h - if (mask & 0x00000800) return dpsMod[2]; // Caster dps 1h - if (mask & 0x00001000) return dpsMod[3]; // Caster dps 2h - if (mask & 0x00002000) return dpsMod[4]; // Ranged - if (mask & 0x00004000) return dpsMod[5]; // Wand - } - return 0; - } + uint32 Id; // 0 + uint32 Level; // 1 + uint32 dpsMod[6]; // 2-7 DPS mod for level + uint32 Spellpower; // 8 spell power for level + uint32 StatMultiplier[5]; // 9-13 Multiplier for ScalingStatDistribution + uint32 Armor[8][4]; // 14-46 Armor for level + uint32 CloakArmor; // 47 armor for cloak - uint32 getSpellBonus(uint32 mask) const - { - if (mask & 0x00008000) return spellPower; - return 0; - } - - uint32 getFeralBonus(uint32 mask) const // removed in 3.2.x? - { - if (mask & 0x00010000) return 0; // not used? - return 0; - } + uint32 GetStatMultiplier(uint32 inventoryType) const; + uint32 GetArmor(uint32 inventoryType, uint32 armorType) const; + uint32 GetDPSAndDamageMultiplier(uint32 subClass, bool isCasterWeapon, float* damageMultiplier) const; }; //struct SkillLineCategoryEntry{ @@ -1487,14 +1611,11 @@ struct SkillLineEntry uint32 id; // 0 m_ID int32 categoryId; // 1 m_categoryID //uint32 skillCostID; // 2 m_skillCostsID - char* name[16]; // 3-18 m_displayName_lang - // 19 string flags - //char* description[16]; // 20-35 m_description_lang - // 36 string flags - uint32 spellIcon; // 37 m_spellIconID - //char* alternateVerb[16]; // 38-53 m_alternateVerb_lang - // 54 string flags - uint32 canLink; // 55 m_canLink (prof. with recipes + char* name; // 3 m_displayName_lang + //char* description; // 4 m_description_lang + uint32 spellIcon; // 5 m_spellIconID + //char* alternateVerb; // 6 m_alternateVerb_lang + uint32 canLink; // 7 m_canLink (prof. with recipes) }; struct SkillLineAbilityEntry @@ -1511,7 +1632,8 @@ struct SkillLineAbilityEntry uint32 learnOnGetSkill; // 9 m_acquireMethod uint32 max_value; // 10 m_trivialSkillLineRankHigh uint32 min_value; // 11 m_trivialSkillLineRankLow - //uint32 characterPoints[2]; // 12-13 m_characterPoints[2] + //uint32 // 12 + //uint32 // 13 4.0.0 }; struct SoundEntriesEntry @@ -1527,124 +1649,170 @@ struct SoundEntriesEntry // 26 m_minDistance // 27 m_distanceCutoff // 28 m_EAXDef - // 29 new in 3.1 + // 29 m_soundEntriesAdvancedID, new in 3.1 + //unk // 30 4.0.0 + //unk // 31 4.0.0 + //unk // 32 4.0.0 + //unk // 33 4.0.0 +}; + +// SpellEffect.dbc +struct SpellEffectEntry +{ + uint32 Id; // 0 m_ID + uint32 Effect; // 1 m_effect + float EffectValueMultiplier; // 2 m_effectAmplitude + uint32 EffectApplyAuraName; // 3 m_effectAura + uint32 EffectAmplitude; // 4 m_effectAuraPeriod + int32 EffectBasePoints; // 5 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) + float EffectBonusMultiplier; // 6 m_effectBonus + float EffectDamageMultiplier; // 7 m_effectChainAmplitude + uint32 EffectChainTarget; // 8 m_effectChainTargets + int32 EffectDieSides; // 9 m_effectDieSides + uint32 EffectItemType; // 10 m_effectItemType + uint32 EffectMechanic; // 11 m_effectMechanic + int32 EffectMiscValue; // 12 m_effectMiscValue + int32 EffectMiscValueB; // 13 m_effectMiscValueB + float EffectPointsPerComboPoint; // 14 m_effectPointsPerCombo + uint32 EffectRadiusIndex; // 15 m_effectRadiusIndex - spellradius.dbc + uint32 EffectRadiusMaxIndex; // 16 4.0.0 + float EffectRealPointsPerLevel; // 17 m_effectRealPointsPerLevel + flag96 EffectSpellClassMask; // 18 19 20 m_effectSpellClassMask1(2/3), effect 0 + uint32 EffectTriggerSpell; // 21 m_effectTriggerSpell + uint32 EffectImplicitTargetA; // 22 m_implicitTargetA + uint32 EffectImplicitTargetB; // 23 m_implicitTargetB + uint32 EffectSpellId; // 24 new 4.0.0 + uint32 EffectIndex; // 25 new 4.0.0 + //uint32 Unk0 // 26 4.2.0 only 0 or 1 }; #define MAX_SPELL_EFFECTS 3 #define MAX_EFFECT_MASK 7 #define MAX_SPELL_REAGENTS 8 +// SpellAuraOptions.dbc +struct SpellAuraOptionsEntry +{ + uint32 Id; // 0 m_ID + uint32 StackAmount; // 1 m_cumulativeAura + uint32 procChance; // 2 m_procChance + uint32 procCharges; // 3 m_procCharges + uint32 procFlags; // 4 m_procTypeMask +}; + +// SpellAuraRestrictions.dbc/ +struct SpellAuraRestrictionsEntry +{ + //uint32 Id; // 0 m_ID + uint32 CasterAuraState; // 1 m_casterAuraState + uint32 TargetAuraState; // 2 m_targetAuraState + uint32 CasterAuraStateNot; // 3 m_excludeCasterAuraState + uint32 TargetAuraStateNot; // 4 m_excludeTargetAuraState + uint32 casterAuraSpell; // 5 m_casterAuraSpell + uint32 targetAuraSpell; // 6 m_targetAuraSpell + uint32 excludeCasterAuraSpell; // 7 m_excludeCasterAuraSpell + uint32 excludeTargetAuraSpell; // 8 m_excludeTargetAuraSpell +}; + +// SpellCastingRequirements.dbc +struct SpellCastingRequirementsEntry +{ + //uint32 Id; // 0 m_ID + uint32 FacingCasterFlags; // 1 m_facingCasterFlags + //uint32 MinFactionId; // 2 m_minFactionID not used + //uint32 MinReputation; // 3 m_minReputation not used + int32 AreaGroupId; // 4 m_requiredAreaGroupId + //uint32 RequiredAuraVision; // 5 m_requiredAuraVision not used + uint32 RequiresSpellFocus; // 6 m_requiresSpellFocus +}; + +#define MAX_SPELL_TOTEMS 2 + +// SpellTotems.dbc +struct SpellTotemsEntry +{ + uint32 Id; // 0 m_ID + uint32 TotemCategory[MAX_SPELL_TOTEMS]; // 1 m_requiredTotemCategoryID + uint32 Totem[MAX_SPELL_TOTEMS]; // 2 m_totem +}; + +struct SpellTotem +{ + SpellTotem() + { + totems[0] = NULL; + totems[1] = NULL; + } + SpellTotemsEntry const* totems[MAX_SPELL_TOTEMS]; +}; + +typedef std::map<uint32, SpellTotem> SpellTotemMap; + +// Spell.dbc struct SpellEntry { uint32 Id; // 0 m_ID + uint32 Attributes; // 1 m_attribute + uint32 AttributesEx; // 2 m_attributesEx + uint32 AttributesEx2; // 3 m_attributesExB + uint32 AttributesEx3; // 4 m_attributesExC + uint32 AttributesEx4; // 5 m_attributesExD + uint32 AttributesEx5; // 6 m_attributesExE + uint32 AttributesEx6; // 7 m_attributesExF + uint32 AttributesEx7; // 8 m_attributesExG + uint32 AttributesEx8; // 9 m_attributesExH + // uint32 unk_400_1; // 10 4.0.0 + // uint32 unk_420_1 // 11 4.2.0 + uint32 CastingTimeIndex; // 12 m_castingTimeIndex + uint32 DurationIndex; // 13 m_durationIndex + uint32 powerType; // 14 m_powerType + uint32 rangeIndex; // 15 m_rangeIndex + float speed; // 16 m_speed + uint32 SpellVisual[2]; // 17-18 m_spellVisualID + uint32 SpellIconID; // 19 m_spellIconID + uint32 activeIconID; // 20 m_activeIconID + char* SpellName; // 21 m_name_lang + char* Rank; // 22 m_nameSubtext_lang + //char* Description; // 23 m_description_lang not used + //char* ToolTip; // 24 m_auraDescription_lang not used + uint32 SchoolMask; // 25 m_schoolMask + uint32 runeCostID; // 26 m_runeCostID + //uint32 spellMissileID; // 27 m_spellMissileID not used + //uint32 spellDescriptionVariableID; // 28 m_spellDescriptionVariableID, 3.2.0 + uint32 SpellDifficultyId; // 29 m_spellDifficultyID - id from SpellDifficulty.dbc + //float unk_f1; // 30 + uint32 SpellScalingId; // 31 SpellScaling.dbc + uint32 SpellAuraOptionsId; // 32 SpellAuraOptions.dbc + uint32 SpellAuraRestrictionsId; // 33 SpellAuraRestrictions.dbc + uint32 SpellCastingRequirementsId; // 34 SpellCastingRequirements.dbc + uint32 SpellCategoriesId; // 35 SpellCategories.dbc + uint32 SpellClassOptionsId; // 36 SpellClassOptions.dbc + uint32 SpellCooldownsId; // 37 SpellCooldowns.dbc + //uint32 unkIndex7; // 38 all zeros... + uint32 SpellEquippedItemsId; // 39 SpellEquippedItems.dbc + uint32 SpellInterruptsId; // 40 SpellInterrupts.dbc + uint32 SpellLevelsId; // 41 SpellLevels.dbc + uint32 SpellPowerId; // 42 SpellPower.dbc + uint32 SpellReagentsId; // 43 SpellReagents.dbc + uint32 SpellShapeshiftId; // 44 SpellShapeshift.dbc + uint32 SpellTargetRestrictionsId; // 45 SpellTargetRestrictions.dbc + uint32 SpellTotemsId; // 46 SpellTotems.dbc + //uint32 ResearchProject; // 47 ResearchProject.dbc + + // struct access functions + SpellEffectEntry const* GetSpellEffect(uint32 eff) const; +}; + +// SpellCategories.dbc +struct SpellCategoriesEntry +{ + //uint32 Id; // 0 m_ID uint32 Category; // 1 m_category + uint32 DmgClass; // 153 m_defenseType uint32 Dispel; // 2 m_dispelType uint32 Mechanic; // 3 m_mechanic - uint32 Attributes; // 4 m_attributes - uint32 AttributesEx; // 5 m_attributesEx - uint32 AttributesEx2; // 6 m_attributesExB - uint32 AttributesEx3; // 7 m_attributesExC - uint32 AttributesEx4; // 8 m_attributesExD - uint32 AttributesEx5; // 9 m_attributesExE - uint32 AttributesEx6; // 10 m_attributesExF - uint32 AttributesEx7; // 11 m_attributesExG - uint32 Stances; // 12 m_shapeshiftMask - // uint32 unk_320_2; // 13 3.2.0 - uint32 StancesNot; // 14 m_shapeshiftExclude - // uint32 unk_320_3; // 15 3.2.0 - uint32 Targets; // 16 m_targets - uint32 TargetCreatureType; // 17 m_targetCreatureType - uint32 RequiresSpellFocus; // 18 m_requiresSpellFocus - uint32 FacingCasterFlags; // 19 m_facingCasterFlags - uint32 CasterAuraState; // 20 m_casterAuraState - uint32 TargetAuraState; // 21 m_targetAuraState - uint32 CasterAuraStateNot; // 22 m_excludeCasterAuraState - uint32 TargetAuraStateNot; // 23 m_excludeTargetAuraState - uint32 casterAuraSpell; // 24 m_casterAuraSpell - uint32 targetAuraSpell; // 25 m_targetAuraSpell - uint32 excludeCasterAuraSpell; // 26 m_excludeCasterAuraSpell - uint32 excludeTargetAuraSpell; // 27 m_excludeTargetAuraSpell - uint32 CastingTimeIndex; // 28 m_castingTimeIndex - uint32 RecoveryTime; // 29 m_recoveryTime - uint32 CategoryRecoveryTime; // 30 m_categoryRecoveryTime - uint32 InterruptFlags; // 31 m_interruptFlags - uint32 AuraInterruptFlags; // 32 m_auraInterruptFlags - uint32 ChannelInterruptFlags; // 33 m_channelInterruptFlags - uint32 procFlags; // 34 m_procTypeMask - uint32 procChance; // 35 m_procChance - uint32 procCharges; // 36 m_procCharges - uint32 maxLevel; // 37 m_maxLevel - uint32 baseLevel; // 38 m_baseLevel - uint32 spellLevel; // 39 m_spellLevel - uint32 DurationIndex; // 40 m_durationIndex - uint32 powerType; // 41 m_powerType - uint32 manaCost; // 42 m_manaCost - uint32 manaCostPerlevel; // 43 m_manaCostPerLevel - uint32 manaPerSecond; // 44 m_manaPerSecond - uint32 manaPerSecondPerLevel; // 45 m_manaPerSecondPerLeve - uint32 rangeIndex; // 46 m_rangeIndex - float speed; // 47 m_speed - //uint32 modalNextSpell; // 48 m_modalNextSpell not used - uint32 StackAmount; // 49 m_cumulativeAura - uint32 Totem[2]; // 50-51 m_totem - int32 Reagent[MAX_SPELL_REAGENTS]; // 52-59 m_reagent - uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 60-67 m_reagentCount - int32 EquippedItemClass; // 68 m_equippedItemClass (value) - int32 EquippedItemSubClassMask; // 69 m_equippedItemSubclass (mask) - int32 EquippedItemInventoryTypeMask; // 70 m_equippedItemInvTypes (mask) - uint32 Effect[MAX_SPELL_EFFECTS]; // 71-73 m_effect - int32 EffectDieSides[MAX_SPELL_EFFECTS]; // 74-76 m_effectDieSides - float EffectRealPointsPerLevel[MAX_SPELL_EFFECTS]; // 77-79 m_effectRealPointsPerLevel - int32 EffectBasePoints[MAX_SPELL_EFFECTS]; // 80-82 m_effectBasePoints (must not be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) - uint32 EffectMechanic[MAX_SPELL_EFFECTS]; // 83-85 m_effectMechanic - uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]; // 86-88 m_implicitTargetA - uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]; // 89-91 m_implicitTargetB - uint32 EffectRadiusIndex[MAX_SPELL_EFFECTS]; // 92-94 m_effectRadiusIndex - spellradius.dbc - uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]; // 95-97 m_effectAura - uint32 EffectAmplitude[MAX_SPELL_EFFECTS]; // 98-100 m_effectAuraPeriod - float EffectValueMultiplier[MAX_SPELL_EFFECTS]; // 101-103 - uint32 EffectChainTarget[MAX_SPELL_EFFECTS]; // 104-106 m_effectChainTargets - uint32 EffectItemType[MAX_SPELL_EFFECTS]; // 107-109 m_effectItemType - int32 EffectMiscValue[MAX_SPELL_EFFECTS]; // 110-112 m_effectMiscValue - int32 EffectMiscValueB[MAX_SPELL_EFFECTS]; // 113-115 m_effectMiscValueB - uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 116-118 m_effectTriggerSpell - float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 119-121 m_effectPointsPerCombo - flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 122-130 - uint32 SpellVisual[2]; // 131-132 m_spellVisualID - uint32 SpellIconID; // 133 m_spellIconID - uint32 activeIconID; // 134 m_activeIconID - //uint32 spellPriority; // 135 not used - char* SpellName[16]; // 136-151 m_name_lang - //uint32 SpellNameFlag; // 152 not used - char* Rank[16]; // 153-168 m_nameSubtext_lang - //uint32 RankFlags; // 169 not used - //char* Description[16]; // 170-185 m_description_lang not used - //uint32 DescriptionFlags; // 186 not used - //char* ToolTip[16]; // 187-202 m_auraDescription_lang not used - //uint32 ToolTipFlags; // 203 not used - uint32 ManaCostPercentage; // 204 m_manaCostPct - uint32 StartRecoveryCategory; // 205 m_startRecoveryCategory - uint32 StartRecoveryTime; // 206 m_startRecoveryTime - uint32 MaxTargetLevel; // 207 m_maxTargetLevel - uint32 SpellFamilyName; // 208 m_spellClassSet - flag96 SpellFamilyFlags; // 209-211 - uint32 MaxAffectedTargets; // 212 m_maxTargets - uint32 DmgClass; // 213 m_defenseType - uint32 PreventionType; // 214 m_preventionType - //uint32 StanceBarOrder; // 215 m_stanceBarOrder not used - float EffectDamageMultiplier[MAX_SPELL_EFFECTS]; // 216-218 m_effectChainAmplitude - //uint32 MinFactionId; // 219 m_minFactionID not used - //uint32 MinReputation; // 220 m_minReputation not used - //uint32 RequiredAuraVision; // 221 m_requiredAuraVision not used - uint32 TotemCategory[2]; // 222-223 m_requiredTotemCategoryID - int32 AreaGroupId; // 224 m_requiredAreaGroupId - uint32 SchoolMask; // 225 m_schoolMask - uint32 runeCostID; // 226 m_runeCostID - //uint32 spellMissileID; // 227 m_spellMissileID not used - //uint32 PowerDisplayId; // 228 PowerDisplay.dbc, new in 3.1 - float EffectBonusMultiplier[MAX_SPELL_EFFECTS]; // 229-231 3.2.0 - //uint32 spellDescriptionVariableID; // 232 3.2.0 - //uint32 SpellDifficultyId; // 233 3.3.0 + uint32 PreventionType; // 154 m_preventionType + uint32 StartRecoveryCategory; // 145 m_startRecoveryCategory }; typedef std::set<uint32> SpellCategorySet; @@ -1669,16 +1837,15 @@ struct SpellDifficultyEntry struct SpellFocusObjectEntry { uint32 ID; // 0 - //char* Name[16]; // 1-15 unused - // 16 string flags, unused + //char* Name; // 1 m_name_lang }; struct SpellRadiusEntry { uint32 ID; - float radiusMin; + float radiusHostile; //uint32 Unk //always 0 - float radiusMax; + float radiusFriend; }; struct SpellRangeEntry @@ -1687,12 +1854,71 @@ struct SpellRangeEntry float minRangeHostile; float minRangeFriend; float maxRangeHostile; - float maxRangeFriend; + float maxRangeFriend; //friend means unattackable unit here uint32 type; - //char* Name[16]; // 7-23 unused - // 24 string flags, unused - //char* Name2[16]; // 25-40 unused - // 41 string flags, unused + //char* Name; // 6-21 m_displayName_lang + //char* ShortName; // 23-38 m_displayNameShort_lang +}; + +// SpellEquippedItems.dbc +struct SpellEquippedItemsEntry +{ + //uint32 Id; // 0 m_ID + int32 EquippedItemClass; // 70 m_equippedItemClass (value) + int32 EquippedItemInventoryTypeMask; // 72 m_equippedItemInvTypes (mask) + int32 EquippedItemSubClassMask; // 71 m_equippedItemSubclass (mask) +}; + +// SpellCooldowns.dbc +struct SpellCooldownsEntry +{ + //uint32 Id; // 0 m_ID + uint32 CategoryRecoveryTime; // 31 m_categoryRecoveryTime + uint32 RecoveryTime; // 30 m_recoveryTime + uint32 StartRecoveryTime; // 146 m_startRecoveryTime +}; + +// SpellClassOptions.dbc +struct SpellClassOptionsEntry +{ + //uint32 Id; // 0 m_ID + //uint32 modalNextSpell; // 1 m_modalNextSpell not used + flag96 SpellFamilyFlags; // 2-4 + uint32 SpellFamilyName; // 5 m_spellClassSet + //char* Description; // 6 4.0.0 +}; + +// SpellInterrupts.dbc +struct SpellInterruptsEntry +{ + //uint32 Id; // 0 m_ID + uint32 AuraInterruptFlags; // 1 m_auraInterruptFlags + //uint32 // 2 4.0.0 + uint32 ChannelInterruptFlags; // 3 m_channelInterruptFlags + //uint32 // 4 4.0.0 + uint32 InterruptFlags; // 5 m_interruptFlags +}; + +// SpellLevels.dbc +struct SpellLevelsEntry +{ + //uint32 Id; // 0 m_ID + uint32 baseLevel; // 1 m_baseLevel + uint32 maxLevel; // 2 m_maxLevel + uint32 spellLevel; // 3 m_spellLevel +}; + +// SpellPower.dbc +struct SpellPowerEntry +{ + //uint32 Id; // 0 m_ID + uint32 manaCost; // 1 m_manaCost + uint32 manaCostPerlevel; // 2 m_manaCostPerLevel + uint32 ManaCostPercentage; // 3 m_manaCostPct + uint32 manaPerSecond; // 4 m_manaPerSecond + //uint32 PowerDisplayId; // 5 m_powerDisplayID - id from PowerDisplay.dbc, new in 3.1 + //uint32 unk1; // 6 4.0.0 + //float unk2; // 7 4.3.0 }; struct SpellRuneCostEntry @@ -1707,21 +1933,84 @@ struct SpellRuneCostEntry #define MAX_SHAPESHIFT_SPELLS 8 -struct SpellShapeshiftEntry +struct SpellShapeshiftFormEntry { uint32 ID; // 0 //uint32 buttonPosition; // 1 unused - //char* Name[16]; // 2-17 unused - //uint32 NameFlags; // 18 unused - uint32 flags1; // 19 - int32 creatureType; // 20 <= 0 humanoid, other normal creature types - //uint32 unk1; // 21 unused - uint32 attackSpeed; // 22 - uint32 modelID_A; // 23 alliance modelid - uint32 modelID_H; // 24 horde modelid (only one form) - //uint32 unk3; // 25 unused - //uint32 unk4; // 26 unused - uint32 stanceSpell[MAX_SHAPESHIFT_SPELLS]; // 27 - 34 unused + //char* Name; // 2 unused + uint32 flags1; // 3 + int32 creatureType; // 4 <=0 humanoid, other normal creature types + //uint32 unk1; // 5 unused, related to next field + uint32 attackSpeed; // 6 + uint32 modelID_A; // 7 alliance modelid (0 means no model) + uint32 modelID_H; // 8 horde modelid (but only for one form) + //uint32 unk3; // 9 unused always 0 + //uint32 unk4; // 10 unused always 0 + uint32 stanceSpell[MAX_SHAPESHIFT_SPELLS]; // 11-18 spells which appear in the bar after shapeshifting + //uint32 unk5; // 19 + //uint32 unk6; // 20 +}; + +// SpellShapeshift.dbc +struct SpellShapeshiftEntry +{ + uint32 Id; // 0 - m_ID + uint32 StancesNot; // 3 - m_shapeshiftExclude + // uint32 unk_320_2; // 2 - 3.2.0 + uint32 Stances; // 1 - m_shapeshiftMask + // uint32 unk_320_3; // 4 - 3.2.0 + // uint32 StanceBarOrder; // 5 - m_stanceBarOrder not used +}; + +// SpellTargetRestrictions.dbc +struct SpellTargetRestrictionsEntry +{ + uint32 Id; // 0 m_ID + uint32 MaxAffectedTargets; // 1 m_maxTargets + uint32 MaxTargetLevel; // 2 m_maxTargetLevel + uint32 TargetCreatureType; // 3 m_targetCreatureType + uint32 Targets; // 4 m_targets +}; + +// SpellReagents.dbc +struct SpellReagentsEntry +{ + //uint32 Id; // 0 m_ID + int32 Reagent[MAX_SPELL_REAGENTS]; // 54-61 m_reagent + uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 62-69 m_reagentCount +}; + +struct SpellReagent +{ + SpellReagent() + { + reagents[0] = NULL; + reagents[1] = NULL; + reagents[2] = NULL; + reagents[3] = NULL; + reagents[4] = NULL; + reagents[5] = NULL; + reagents[6] = NULL; + reagents[7] = NULL; + } + SpellReagentsEntry const* reagents[MAX_SPELL_REAGENTS]; +}; + +typedef std::map<uint32, SpellReagent> SpellReagentMap; + +// SpellScaling.dbc +struct SpellScalingEntry +{ + //uint32 Id; // 0 m_ID + int32 castTimeMin; // 1 + int32 castTimeMax; // 2 + uint32 castScalingMaxLevel; // 3 + uint32 playerClass; // 4 (index * 100) + charLevel => gtSpellScaling.dbc + float Multiplier[3]; // 5-7 + float RandomMultiplier[3]; // 8-10 + float OtherMultiplier[3]; // 11-13 + float CoefBase; // 14 some coefficient, mostly 1.0f + uint32 CoefLevelBase; // 15 some level }; struct SpellDurationEntry @@ -1738,15 +2027,15 @@ struct SpellItemEnchantmentEntry uint32 amount[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 5-7 m_effectPointsMin[MAX_ITEM_ENCHANTMENT_EFFECTS] //uint32 amount2[MAX_ITEM_ENCHANTMENT_EFFECTS] // 8-10 m_effectPointsMax[MAX_ITEM_ENCHANTMENT_EFFECTS] uint32 spellid[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 11-13 m_effectArg[MAX_ITEM_ENCHANTMENT_EFFECTS] - char* description[16]; // 14-29 m_name_lang[16] - //uint32 descriptionFlags; // 30 name flags - uint32 aura_id; // 31 m_itemVisual - uint32 slot; // 32 m_flags - uint32 GemID; // 33 m_src_itemID - uint32 EnchantmentCondition; // 34 m_condition_id - uint32 requiredSkill; // 35 m_requiredSkillID - uint32 requiredSkillValue; // 36 m_requiredSkillRank - uint32 requiredLevel; // 37 m_requiredLevel + char* description; // 14 m_name_lang + uint32 aura_id; // 15 m_itemVisual + uint32 slot; // 16 m_flags + uint32 GemID; // 17 m_src_itemID + uint32 EnchantmentCondition; // 18 m_condition_id + uint32 requiredSkill; // 19 m_requiredSkillID + uint32 requiredSkillValue; // 20 m_requiredSkillRank + uint32 requiredLevel; // 21 new in 3.1 + // 22 new in 3.1 }; struct SpellItemEnchantmentConditionEntry @@ -1787,27 +2076,35 @@ struct TalentEntry uint32 Row; // 2 uint32 Col; // 3 uint32 RankID[MAX_TALENT_RANK]; // 4-8 - // 9-12 not used, always 0, maybe not used high ranks - uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry) - // 14-15 not used - uint32 DependsOnRank; // 16 - // 17-18 not used - //uint32 needAddInSpellBook; // 19 also need disable higest ranks on reset talent tree - //uint32 unk2; // 20, all 0 - //uint64 allowForPet; // 21 its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc + uint32 DependsOn; // 9 m_prereqTalent (Talent.dbc) + // 10-11 part of prev field + uint32 DependsOnRank; // 12 m_prereqRank + // 13-14 part of prev field + //uint32 needAddInSpellBook; // 15 m_flags also need disable higest ranks on reset talent tree + //uint32 unk2; // 16 m_requiredSpellID + //uint64 allowForPet; // 17 m_categoryMask its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc }; struct TalentTabEntry { uint32 TalentTabID; // 0 - //char* name[16]; // 1-16, unused - //uint32 nameFlags; // 17, unused - //unit32 spellicon; // 18 - // 19 not used - uint32 ClassMask; // 20 - uint32 petTalentMask; // 21 - uint32 tabpage; // 22 - //char* internalname; // 23 + //char* name; // 1 m_name_lang + //unit32 spellicon; // 2 m_spellIconID + uint32 ClassMask; // 3 m_classMask + uint32 petTalentMask; // 4 m_petTalentMask + uint32 tabpage; // 5 m_orderIndex + //char* internalname; // 6 m_backgroundFile + //char* description; // 7 + //uint32 rolesMask; // 8 4.0.0 + //uint32 spellIds[2]; // 9-10 passive mastery bonus spells? +}; + +struct TalentTreePrimarySpellsEntry +{ + //uint32 Id; // 0 index + uint32 TalentTree; // 1 entry from TalentTab.dbc + uint32 SpellId; // 2 spell id to learn + //uint32 Flags; // 3 some kind of flags }; struct TaxiNodesEntry @@ -1817,9 +2114,8 @@ struct TaxiNodesEntry float x; // 2 m_x float y; // 3 m_y float z; // 4 m_z - char* name[16]; // 5-21 m_Name_lang - // 22 string flags - uint32 MountCreatureID[2]; // 23-24 m_MountCreatureID[2] + char* name; // 5 m_Name_lang + uint32 MountCreatureID[2]; // 6-7 m_MountCreatureID[2] }; struct TaxiPathEntry @@ -1854,10 +2150,9 @@ struct TeamContributionPointsEntry struct TotemCategoryEntry { uint32 ID; // 0 - //char* name[16]; // 1-16 - // 17 string flags, unused - uint32 categoryType; // 18 (one for specialization) - uint32 categoryMask; // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods) + //char* name; // 1 m_name_lang + uint32 categoryType; // 2 m_totemCategoryType (one for specialization) + uint32 categoryMask; // 3 m_totemCategoryMask (compatibility mask for same type: different for totems, compatible from high to low for rods) }; #define MAX_VEHICLE_SEATS 8 @@ -1887,9 +2182,9 @@ struct VehicleEntry float m_msslTrgtArcRepeat; // 25 float m_msslTrgtArcWidth; // 26 float m_msslTrgtImpactRadius[2]; // 27-28 - char* m_msslTrgtArcTexture; // 29 - char* m_msslTrgtImpactTexture; // 30 - char* m_msslTrgtImpactModel[2]; // 31-32 + char* m_msslTrgtArcTexture; // 29 + char* m_msslTrgtImpactTexture; // 30 + char* m_msslTrgtImpactModel[2]; // 31-32 float m_cameraYawOffset; // 33 uint32 m_uiLocomotionType; // 34 float m_msslTrgtImpactTexRadius; // 35 @@ -1970,8 +2265,10 @@ struct WMOAreaTableEntry //uint32 field8; uint32 Flags; // 9 used for indoor/outdoor determination uint32 areaId; // 10 link to AreaTableEntry.ID - //char *Name[16]; - //uint32 nameFlags; + //char *Name; // 11 m_AreaName_lang + //uint32 field12; // 12 + //uint32 field13; // 13 + //uint32 field14; // 14 }; struct WorldMapAreaEntry @@ -1987,6 +2284,9 @@ struct WorldMapAreaEntry int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally) // int32 dungeonMap_id; // 9 pointer to DungeonMap.dbc (owerride x1, x2, y1, y2 coordinates) // uint32 parentMapID; // 10 + + // uint32 minRecommendedLevel; // 12 Minimum recommended level displayed on world map + // uint32 maxRecommendedLevel; // 13 Maximum recommended level displayed on world map }; #define MAX_WORLD_MAP_OVERLAY_AREA_IDX 4 @@ -1996,9 +2296,15 @@ struct WorldMapOverlayEntry uint32 ID; // 0 //uint32 worldMapAreaId; // 1 idx in WorldMapArea.dbc uint32 areatableID[MAX_WORLD_MAP_OVERLAY_AREA_IDX]; // 2-5 - // 6-7 always 0, possible part of areatableID[] - //char* internal_name // 8 - // 9-16 some ints + //char* internal_name // 6 m_textureName + // 7 m_textureWidth + // 8 m_textureHeight + // 9 m_offsetX + // 10 m_offsetY + // 11 m_hitRectTop + // 12 m_hitRectLeft + // 13 m_hitRectBottom + // 14 m_hitRectRight }; struct WorldSafeLocsEntry @@ -2008,8 +2314,7 @@ struct WorldSafeLocsEntry float x; // 2 float y; // 3 float z; // 4 - //char* name[16] // 5-20 name, unused - // 21 name flags, unused + //char* name; // 5 m_AreaName_lang }; /* @@ -2055,6 +2360,13 @@ struct WorldStateUI #pragma pack(pop) #endif +struct VectorArray +{ + std::vector<std::string> stringVectorArray[2]; +}; + +typedef std::map<uint32, VectorArray> NameGenVectorArraysMap; + // Structures not used for casting to loaded DBC data and not required then packing struct MapDifficulty { @@ -2077,6 +2389,19 @@ struct TalentSpellPos typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap; +struct SpellEffect +{ + SpellEffect() + { + effects[0] = NULL; + effects[1] = NULL; + effects[2] = NULL; + } + SpellEffectEntry const* effects[3]; +}; + +typedef std::map<uint32, SpellEffect> SpellEffectMap; + struct TaxiPathBySourceAndDestination { TaxiPathBySourceAndDestination() : ID(0), price(0) {} @@ -2099,7 +2424,6 @@ struct TaxiPathNodePtr typedef Path<TaxiPathNodePtr, TaxiPathNodeEntry const> TaxiPathNodeList; typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; -#define TaxiMaskSize 14 +#define TaxiMaskSize 25 typedef uint32 TaxiMask[TaxiMaskSize]; #endif - diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 39d031e96f9..6561fd9029c 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -19,111 +19,154 @@ #ifndef TRINITY_DBCSFRM_H #define TRINITY_DBCSFRM_H -const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii"; -const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp"; -const std::string CustomAchievementIndex = "ID"; -const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiiiix"; -const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxiiiiixxx"; +// x - skip<uint32>, X - skip<uint8>, s - char*, f - float, i - uint32, b - uint8, d - index (not included) +// n - index (included), l - bool, p - field present in sql dbc, a - field absent in sql dbc + +const char Achievementfmt[]="niixsxiixixxii"; +//const std::string CustomAchievementfmt="pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp"; +//const std::string CustomAchievementIndex = "ID"; +const char AchievementCriteriafmt[]="niiiiiiiisiiiiixxiiiiii"; +const char AreaTableEntryfmt[]="iiinixxxxxisiiiiixxxxxxxxx"; const char AreaGroupEntryfmt[]="niiiiiii"; -const char AreaPOIEntryfmt[]="niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; -const char AreaTriggerEntryfmt[]="niffffffff"; -const char AuctionHouseEntryfmt[]="niiixxxxxxxxxxxxxxxxx"; +const char AreaPOIEntryfmt[]="niiiiiiiiiiiffixixxixx"; +const char AreaTriggerEntryfmt[]="nifffxxxfffff"; +const char ArmorLocationfmt[]="nfffff"; +const char AuctionHouseEntryfmt[]="niiix"; const char BankBagSlotPricesEntryfmt[]="ni"; -const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; -const char BattlemasterListEntryfmt[]="niiiiiiiiixssssssssssssssssxiixx"; -const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char CharTitlesEntryfmt[]="nxssssssssssssssssxxxxxxxxxxxxxxxxxxi"; -const char ChatChannelsEntryfmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; - // ChatChannelsEntryfmt, index not used (more compact store) -const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; -const char ChrRacesEntryfmt[]="nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; +const char BarberShopStyleEntryfmt[]="nixxxiii"; +const char BattlemasterListEntryfmt[]="niiiiiiiiixsiiiixxxx"; +const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char CharTitlesEntryfmt[]="nxsxix"; +const char ChatChannelsEntryfmt[]="nixsx"; + +const char ChrClassesEntryfmt[]="nixsxxxixiixxx"; +const char ChrRacesEntryfmt[]="nxixiixixxxxixsxxxxxixxx"; +const char ChrClassesXPowerTypesfmt[]="nii"; + const char CinematicSequencesEntryfmt[]="nxxxxxxxxx"; -const char CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxx"; -const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx"; -const char CreatureModelDatafmt[]="nxxxfxxxxxxxxxxffxxxxxxxxxxx"; +const char CreatureDisplayInfofmt[]="nixxfxxxxxxxxxxxx"; +const char CreatureModelDatafmt[]="nxxxxxxxxxxxxxffxxxxxxxxxxxxxxx"; +const char CreatureFamilyfmt[]="nfifiiiiixsx"; const char CreatureSpellDatafmt[]="niiiixxxx"; -const char CreatureTypefmt[]="nxxxxxxxxxxxxxxxxxx"; -const char CurrencyTypesfmt[]="xnxi"; -const char DestructibleModelDatafmt[]="nxxixxxixxxixxxixxx"; -const char DungeonEncounterfmt[]="niixissssssssssssssssxx"; +const char CreatureTypefmt[]="nxx"; +const char CurrencyTypesfmt[]="nxxxxxiiiix"; + +const char DestructibleModelDatafmt[]="ixxixxxixxxixxxixxxxxxxx"; +const char DungeonEncounterfmt[]="iiixisxx"; const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; const char DurabilityQualityfmt[]="nf"; -const char EmotesEntryfmt[]="nxxiiix"; +const char EmotesEntryfmt[]="nxxiiixx"; const char EmotesTextEntryfmt[]="nxixxxxxxxxxxxxxxxx"; -const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx"; +const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiiffixsxx"; const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii"; -const char GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffx"; -const char GemPropertiesEntryfmt[]="nixxi"; +const char GameObjectDisplayInfofmt[]="nsxxxxxxxxxxffffffxxx"; + +const char GemPropertiesEntryfmt[]="nixxix"; const char GlyphPropertiesfmt[]="niii"; const char GlyphSlotfmt[]="nii"; -const char GtBarberShopCostBasefmt[]="f"; -const char GtCombatRatingsfmt[]="f"; -const char GtChanceToMeleeCritBasefmt[]="f"; -const char GtChanceToMeleeCritfmt[]="f"; -const char GtChanceToSpellCritBasefmt[]="f"; -const char GtChanceToSpellCritfmt[]="f"; + +const char GtBarberShopCostBasefmt[]="xf"; +const char GtCombatRatingsfmt[]="xf"; +const char GtOCTHpPerStaminafmt[]="xf"; +const char GtChanceToMeleeCritBasefmt[]="xf"; +const char GtChanceToMeleeCritfmt[]="xf"; +const char GtChanceToSpellCritBasefmt[]="xf"; +const char GtChanceToSpellCritfmt[]="xf"; const char GtOCTClassCombatRatingScalarfmt[]="df"; const char GtOCTRegenHPfmt[]="f"; //const char GtOCTRegenMPfmt[]="f"; const char GtRegenHPPerSptfmt[]="f"; -const char GtRegenMPPerSptfmt[]="f"; +const char GtRegenMPPerSptfmt[]="xf"; +const char GtOCTBaseHPByClassfmt[]="df"; +const char GtOCTBaseMPByClassfmt[]="df"; const char Holidaysfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix"; -const char Itemfmt[]="niiiiiii"; -const char ItemBagFamilyfmt[]="nxxxxxxxxxxxxxxxxx"; +const char ImportPriceArmorfmt[]="nffff"; +const char ImportPriceQualityfmt[]="nf"; +const char ImportPriceShieldfmt[]="nf"; +const char ImportPriceWeaponfmt[]="nf"; +const char ItemPriceBasefmt[]="diff"; +const char ItemReforgefmt[]="nifif"; +const char ItemBagFamilyfmt[]="nx"; +const char ItemArmorQualityfmt[]="nfffffffi"; +const char ItemArmorShieldfmt[]="nifffffff"; +const char ItemArmorTotalfmt[]="niffff"; +const char ItemClassfmt[]="dixxfx"; +const char ItemDamagefmt[]="nfffffffi"; +const char ItemDisenchantLootfmt[]="niiiiii"; //const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; -//const char ItemCondExtCostsEntryfmt[]="xiii"; -const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix"; -const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; -const char ItemRandomPropertiesfmt[]="nxiiixxssssssssssssssssx"; -const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiixxiiixx"; -const char ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii"; -const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx"; +const char ItemLimitCategoryEntryfmt[]="nxii"; +const char ItemRandomPropertiesfmt[]="nxiiixxs"; +const char ItemRandomSuffixfmt[]="nsxiiiiiiiiii"; +const char ItemSetEntryfmt[]="dsiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii"; +const char LFGDungeonEntryfmt[]="nxiiiiiiixixxixixxxxx"; const char LiquidTypefmt[]="nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; -const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx"; -const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix"; -const char MapDifficultyEntryfmt[]="diisxxxxxxxxxxxxxxxxiix"; -const char MovieEntryfmt[]="nxx"; -const char OverrideSpellDatafmt[]="niiiiiiiiiix"; -const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; +const char PhaseEntryfmt[]="nsi"; +const char MailTemplateEntryfmt[]="nxs"; +const char MapEntryfmt[]="nxixxxsixxixiffxiixx"; +const char MapDifficultyEntryfmt[]="diisiix"; +const char MovieEntryfmt[]="nxxx"; +const char MountCapabilityfmt[]="niiiiiii"; +const char MountTypefmt[]="niiiiiiiiiiiiiiiiiiiiiiii"; +const char NameGenfmt[] = "dsii"; +const char NumTalentsAtLevelfmt[]="df"; +const char OverrideSpellDatafmt[]="niiiiiiiiiixx"; +const char QuestSortEntryfmt[]="nx"; const char QuestXPfmt[]="niiiiiiiiii"; const char QuestFactionRewardfmt[]="niiiiiiiiii"; const char PvPDifficultyfmt[]="diiiii"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; -const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; -const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiii"; -const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi"; +const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiixi"; +const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; +const char SkillLinefmt[]="nisxixi"; const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; -const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellCastTimefmt[]="nixx"; +const char SpellCategoriesEntryfmt[]="diiiiii"; const char SpellDifficultyfmt[]="niiii"; const std::string CustomSpellDifficultyfmt="ppppp"; const std::string CustomSpellDifficultyIndex="id"; const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx"; +const char SpellEffectEntryfmt[]="nifiiiffiiiiiifiifiiiiiiiix"; +const char SpellEntryfmt[]="niiiiiiiiixxiiiifiiiissxxiixxixiiiiiiixiiiiiiiix"; const std::string CustomSpellEntryfmt="papppppppppppapapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa"; const std::string CustomSpellEntryIndex = "Id"; -const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; -const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii"; +const char SpellFocusObjectfmt[]="nx"; +const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiisiiiiiiix"; const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; const char SpellRadiusfmt[]="nfxf"; -const char SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char SpellRangefmt[]="nffffixx"; +const char SpellReagentsEntryfmt[]="diiiiiiiiiiiiiiii"; +const char SpellScalingEntryfmt[]="diiiiffffffffffi"; +const char SpellTotemsEntryfmt[]="niiii"; +const char SpellTargetRestrictionsEntryfmt[]="nxiiii"; +const char SpellPowerEntryfmt[]="diiiixxx"; +const char SpellInterruptsEntryfmt[]="dixixi"; +const char SpellEquippedItemsEntryfmt[]="diii"; +const char SpellAuraOptionsEntryfmt[]="niiii"; +const char SpellAuraRestrictionsEntryfmt[]="diiiiiiii"; +const char SpellCastingRequirementsEntryfmt[]="dixxixi"; +const char SpellClassOptionsEntryfmt[]="dxiiiix"; +const char SpellCooldownsEntryfmt[]="diii"; +const char SpellLevelsEntryfmt[]="diii"; const char SpellRuneCostfmt[]="niiii"; -const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii"; +const char SpellShapeshiftEntryfmt[]="nixixx"; +const char SpellShapeshiftFormfmt[]="nxxiixiiixxiiiiiiiixx"; const char StableSlotPricesfmt[] = "ni"; const char SummonPropertiesfmt[] = "niiiii"; -const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; -const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix"; -const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; +const char TalentEntryfmt[]="niiiiiiiiixxixxxxxx"; +const char TalentTabEntryfmt[]="nxxiiixxxxx"; +const char TalentTreePrimarySpellsfmt[]="diix"; +const char TaxiNodesEntryfmt[]="nifffsiixxx"; const char TaxiPathEntryfmt[]="niii"; const char TaxiPathNodeEntryfmt[]="diiifffiiii"; const char TeamContributionPointsfmt[]="df"; -const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; +const char TotemCategoryEntryfmt[]="nxii"; const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx"; -const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; -const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxxxxxxxxxxxxxxx"; -const char WorldMapAreaEntryfmt[]="xinxffffixx"; -const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx"; -const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx"; +const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxxxxxxxxxx"; +const char WMOAreaTableEntryfmt[]="niiixxxxxiixxxx"; +const char WorldMapAreaEntryfmt[]="xinxffffixxxxx"; +const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxx"; +const char WorldSafeLocsEntryfmt[]="nifffx"; #endif diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 3a2a044ca3b..18ba5926b07 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1901,7 +1901,7 @@ void LFGMgr::RewardDungeonDoneFor(const uint32 dungeonId, Player* player) // Update achievements if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC) - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1); LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel()); if (!reward) diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 60c0b7ad394..653a731b5b2 100755 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -32,7 +32,7 @@ Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES) m_objectType |= TYPEMASK_CORPSE; m_objectTypeId = TYPEID_CORPSE; - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION); + m_updateFlag = UPDATEFLAG_STATIONARY_POSITION; m_valuesCount = CORPSE_END; @@ -103,25 +103,25 @@ void Corpse::SaveToDB() SQLTransaction trans = CharacterDatabase.BeginTransaction(); DeleteFromDB(trans); + uint16 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE); - stmt->setUInt32(0, GetGUIDLow()); // corpseGuid - stmt->setUInt32(1, GUID_LOPART(GetOwnerGUID())); // guid - stmt->setFloat (2, GetPositionX()); // posX - stmt->setFloat (3, GetPositionY()); // posY - stmt->setFloat (4, GetPositionZ()); // posZ - stmt->setFloat (5, GetOrientation()); // orientation - stmt->setUInt16(6, GetMapId()); // mapId - stmt->setUInt32(7, GetUInt32Value(CORPSE_FIELD_DISPLAY_ID)); // displayId - stmt->setString(8, _ConcatFields(CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END)); // itemCache - stmt->setUInt32(9, GetUInt32Value(CORPSE_FIELD_BYTES_1)); // bytes1 - stmt->setUInt32(10, GetUInt32Value(CORPSE_FIELD_BYTES_2)); // bytes2 - stmt->setUInt32(11, GetUInt32Value(CORPSE_FIELD_GUILD)); // guildId - stmt->setUInt8 (12, GetUInt32Value(CORPSE_FIELD_FLAGS)); // flags - stmt->setUInt8 (13, GetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS)); // dynFlags - stmt->setUInt32(14, uint32(m_time)); // time - stmt->setUInt8 (15, GetType()); // corpseType - stmt->setUInt32(16, GetInstanceId()); // instanceId - stmt->setUInt16(17, GetPhaseMask()); // phaseMask + stmt->setUInt32(index++, GetGUIDLow()); // corpseGuid + stmt->setUInt32(index++, GUID_LOPART(GetOwnerGUID())); // guid + stmt->setFloat (index++, GetPositionX()); // posX + stmt->setFloat (index++, GetPositionY()); // posY + stmt->setFloat (index++, GetPositionZ()); // posZ + stmt->setFloat (index++, GetOrientation()); // orientation + stmt->setUInt16(index++, GetMapId()); // mapId + stmt->setUInt32(index++, GetUInt32Value(CORPSE_FIELD_DISPLAY_ID)); // displayId + stmt->setString(index++, _ConcatFields(CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END)); // itemCache + stmt->setUInt32(index++, GetUInt32Value(CORPSE_FIELD_BYTES_1)); // bytes1 + stmt->setUInt32(index++, GetUInt32Value(CORPSE_FIELD_BYTES_2)); // bytes2 + stmt->setUInt8 (index++, GetUInt32Value(CORPSE_FIELD_FLAGS)); // flags + stmt->setUInt8 (index++, GetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS)); // dynFlags + stmt->setUInt32(index++, uint32(m_time)); // time + stmt->setUInt8 (index++, GetType()); // corpseType + stmt->setUInt32(index++, GetInstanceId()); // instanceId + stmt->setUInt16(index++, GetPhaseMask()); // phaseMask trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); @@ -161,9 +161,10 @@ void Corpse::DeleteFromDB(SQLTransaction& trans) bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) { - uint32 ownerGuid = fields[17].GetUInt32(); - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0 + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0 + + uint32 ownerGuid = fields[16].GetUInt32(); float posX = fields[0].GetFloat(); float posY = fields[1].GetFloat(); float posZ = fields[2].GetFloat(); @@ -176,15 +177,14 @@ bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) _LoadIntoDataField(fields[6].GetCString(), CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END); SetUInt32Value(CORPSE_FIELD_BYTES_1, fields[7].GetUInt32()); SetUInt32Value(CORPSE_FIELD_BYTES_2, fields[8].GetUInt32()); - SetUInt32Value(CORPSE_FIELD_GUILD, fields[9].GetUInt32()); - SetUInt32Value(CORPSE_FIELD_FLAGS, fields[10].GetUInt8()); - SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[11].GetUInt8()); + SetUInt32Value(CORPSE_FIELD_FLAGS, fields[9].GetUInt8()); + SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[10].GetUInt8()); SetUInt64Value(CORPSE_FIELD_OWNER, MAKE_NEW_GUID(ownerGuid, 0, HIGHGUID_PLAYER)); - m_time = time_t(fields[12].GetUInt32()); + m_time = time_t(fields[11].GetUInt32()); - uint32 instanceId = fields[14].GetUInt32(); - uint32 phaseMask = fields[15].GetUInt16(); + uint32 instanceId = fields[13].GetUInt32(); + uint32 phaseMask = fields[14].GetUInt16(); // place SetLocationInstanceId(instanceId); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 866437d828c..c46fc0d91d5 100755 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -327,6 +327,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data SetFloatValue(UNIT_FIELD_COMBATREACH, minfo->combat_reach); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f); SetSpeed(MOVE_WALK, cinfo->speed_walk); SetSpeed(MOVE_RUN, cinfo->speed_run); @@ -380,6 +381,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags); + SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER); SetUInt32Value(UNIT_DYNAMIC_FLAGS, dynamicflags); @@ -439,7 +441,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data) */ // TODO: Shouldn't we check whether or not the creature is in water first? - if (cInfo->InhabitType & INHABIT_WATER) + if (cInfo->InhabitType & INHABIT_WATER && IsInWater()) AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); return true; @@ -1159,12 +1161,26 @@ void Creature::SelectLevel(const CreatureTemplate* cinfo) // mana uint32 mana = stats->GenerateMana(cinfo); - SetCreateMana(mana); - SetMaxPower(POWER_MANA, mana); //MAX Mana - SetPower(POWER_MANA, mana); - // TODO: set UNIT_FIELD_POWER*, for some creature class case (energy, etc) + switch (getClass()) + { + case CLASS_WARRIOR: + setPowerType(POWER_RAGE); + SetMaxPower(POWER_RAGE, GetCreatePowers(POWER_RAGE)); + SetPower(POWER_RAGE, GetCreatePowers(POWER_RAGE)); + break; + case CLASS_ROGUE: + setPowerType(POWER_ENERGY); + SetMaxPower(POWER_ENERGY, GetCreatePowers(POWER_ENERGY)); + SetPower(POWER_ENERGY, GetCreatePowers(POWER_ENERGY)); + break; + default: + setPowerType(POWER_MANA); + SetMaxPower(POWER_MANA, mana); + SetPower(POWER_MANA, mana); + break; + } SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health); SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana); @@ -1734,7 +1750,10 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim) if (bcontinue) continue; - if (spellInfo->ManaCost > GetPower(POWER_MANA)) + if (bcontinue) + continue; + + if (spellInfo->ManaCost > (uint32)GetPower(POWER_MANA)) continue; float range = spellInfo->GetMaxRange(false); float minrange = spellInfo->GetMinRange(false); @@ -1778,7 +1797,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim) if (bcontinue) continue; - if (spellInfo->ManaCost > GetPower(POWER_MANA)) + if (spellInfo->ManaCost > (uint32)GetPower(POWER_MANA)) continue; float range = spellInfo->GetMaxRange(true); @@ -2461,9 +2480,52 @@ bool Creature::SetWalk(bool enable) if (!Unit::SetWalk(enable)) return false; - WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9); - data.append(GetPackGUID()); - SendMessageToSet(&data, false); + ObjectGuid guid = GetGUID(); + if (enable) + { + WorldPacket data(SMSG_SPLINE_MOVE_SET_WALK_MODE, 9); + data.WriteBit(guid[7]); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[1]); + data.WriteBit(guid[3]); + data.WriteBit(guid[4]); + data.WriteBit(guid[2]); + data.WriteBit(guid[0]); + data.FlushBits(); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[3]); + SendMessageToSet(&data, false); + } + else + { + WorldPacket data(SMSG_SPLINE_MOVE_SET_RUN_MODE, 9); + data.WriteBit(guid[5]); + data.WriteBit(guid[6]); + data.WriteBit(guid[3]); + data.WriteBit(guid[7]); + data.WriteBit(guid[2]); + data.WriteBit(guid[0]); + data.WriteBit(guid[4]); + data.WriteBit(guid[1]); + data.FlushBits(); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + SendMessageToSet(&data, false); + } + return true; } @@ -2477,9 +2539,52 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/) if (!movespline->Initialized()) return true; - WorldPacket data(disable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9); - data.append(GetPackGUID()); - SendMessageToSet(&data, false); + ObjectGuid guid = GetGUID(); + if (disable) + { + WorldPacket data(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, 9); + data.WriteBit(guid[7]); + data.WriteBit(guid[3]); + data.WriteBit(guid[4]); + data.WriteBit(guid[2]); + data.WriteBit(guid[5]); + data.WriteBit(guid[1]); + data.WriteBit(guid[0]); + data.WriteBit(guid[6]); + data.FlushBits(); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[0]); + SendMessageToSet(&data, false); + } + else + { + WorldPacket data(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9); + data.WriteBit(guid[5]); + data.WriteBit(guid[4]); + data.WriteBit(guid[7]); + data.WriteBit(guid[1]); + data.WriteBit(guid[3]); + data.WriteBit(guid[6]); + data.WriteBit(guid[2]); + data.WriteBit(guid[0]); + data.FlushBits(); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[5]); + SendMessageToSet(&data, false); + } + return true; } @@ -2498,8 +2603,51 @@ bool Creature::SetHover(bool enable) return true; //! Not always a packet is sent - WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9); - data.append(GetPackGUID()); - SendMessageToSet(&data, false); + ObjectGuid guid = GetGUID(); + if (enable) + { + WorldPacket data(SMSG_SPLINE_MOVE_SET_HOVER, 9); + data.WriteBit(guid[3]); + data.WriteBit(guid[7]); + data.WriteBit(guid[0]); + data.WriteBit(guid[1]); + data.WriteBit(guid[4]); + data.WriteBit(guid[6]); + data.WriteBit(guid[2]); + data.WriteBit(guid[5]); + data.FlushBits(); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[6]); + SendMessageToSet(&data, false); + } + else + { + WorldPacket data(SMSG_SPLINE_MOVE_UNSET_HOVER, 9); + data.WriteBit(guid[6]); + data.WriteBit(guid[7]); + data.WriteBit(guid[4]); + data.WriteBit(guid[0]); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[5]); + data.WriteBit(guid[2]); + data.FlushBits(); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[1]); + SendMessageToSet(&data, false); + } + return true; } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index c8ebf1aa13b..dc1cee2e28f 100755 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -95,6 +95,7 @@ struct CreatureTemplate uint8 minlevel; uint8 maxlevel; uint32 expansion; + uint32 expansionUnknown; // either 0 or 3, sent to the client / wdb uint32 faction_A; uint32 faction_H; uint32 npcflag; @@ -122,6 +123,7 @@ struct CreatureTemplate uint32 rangedattackpower; uint32 type; // enum CreatureType values uint32 type_flags; // enum CreatureTypeFlags mask values + uint32 type_flags2; // unknown enum, only set for 4 creatures (with value 1) uint32 lootid; uint32 pickpocketLootId; uint32 SkinLootId; @@ -175,10 +177,6 @@ struct CreatureTemplate // Benchmarked: Faster than std::map (insert/find) typedef UNORDERED_MAP<uint32, CreatureTemplate> CreatureTemplateContainer; -// Represents max amount of expansions. -// TODO: Add MAX_EXPANSION constant. -#define MAX_CREATURE_BASE_HP 3 - // Defines base stats for creatures (used to calculate HP/mana/armor). struct CreatureBaseStats { diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 63e186ffc42..4e5762b87c8 100755 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -281,11 +281,11 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u", GUID_LOPART(npcGUID)); } -void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const +void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, uint64 npcGUID) const { - WorldPacket data(SMSG_QUESTGIVER_STATUS, 9); + WorldPacket data(SMSG_QUESTGIVER_STATUS, 8 + 4); data << uint64(npcGUID); - data << uint8(questStatus); + data << uint32(questStatus); _session->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u", GUID_LOPART(npcGUID), questStatus); @@ -297,6 +297,10 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, std::string questDetails = quest->GetDetails(); std::string questObjectives = quest->GetObjectives(); std::string questEndText = quest->GetEndText(); + std::string questGiverTextWindow = quest->GetQuestGiverTextWindow(); + std::string questGiverTargetName = quest->GetQuestGiverTargetName(); + std::string questTurnTextWindow = quest->GetQuestTurnTextWindow(); + std::string questTurnTargetName = quest->GetQuestTurnTargetName(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) @@ -307,86 +311,37 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails); ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives); ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText); + ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, locale, questGiverTextWindow); + ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, locale, questGiverTargetName); + ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, locale, questTurnTextWindow); + ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, locale, questTurnTargetName); } } WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size data << uint64(npcGUID); - data << uint64(0); // wotlk, something todo with quest sharing? + data << uint64(0); // either 0 or a npc guid (quest giver) data << uint32(quest->GetQuestId()); data << questTitle; data << questDetails; data << questObjectives; + data << questGiverTextWindow; // 4.x + data << questGiverTargetName; // 4.x + data << questTurnTextWindow; // 4.x + data << questTurnTargetName; // 4.x + data << uint32(quest->GetQuestGiverPortrait()); // 4.x + data << uint32(quest->GetQuestTurnInPortrait()); // 4.x data << uint8(activateAccept ? 1 : 0); // auto finish data << uint32(quest->GetFlags()); // 3.3.3 questFlags data << uint32(quest->GetSuggestedPlayers()); data << uint8(0); // IsFinished? value is sent back to server in quest accept packet + data << uint8(0); // 4.x StartType, unknown enum + data << uint32(quest->GetRequiredSpell()); // 4.x - if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) - { - data << uint32(0); // Rewarded chosen items hidden - data << uint32(0); // Rewarded items hidden - data << uint32(0); // Rewarded money hidden - data << uint32(0); // Rewarded XP hidden - } - else - { - data << uint32(quest->GetRewChoiceItemsCount()); - for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; ++i) - { - if (!quest->RewardChoiceItemId[i]) - continue; - - data << uint32(quest->RewardChoiceItemId[i]); - data << uint32(quest->RewardChoiceItemCount[i]); - - if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RewardChoiceItemId[i])) - data << uint32(itemTemplate->DisplayInfoID); - else - data << uint32(0x00); - } - - data << uint32(quest->GetRewItemsCount()); - - for (uint32 i=0; i < QUEST_REWARDS_COUNT; ++i) - { - if (!quest->RewardItemId[i]) - continue; - - data << uint32(quest->RewardItemId[i]); - data << uint32(quest->RewardItemIdCount[i]); - - if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RewardItemId[i])) - data << uint32(itemTemplate->DisplayInfoID); - else - data << uint32(0); - } - - data << uint32(quest->GetRewOrReqMoney()); - data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST)); - } - - // rewarded honor points. Multiply with 10 to satisfy client - data << 10 * Trinity::Honor::hk_honor_at_level(_session->GetPlayer()->getLevel(), quest->GetRewHonorMultiplier()); - data << float(0.0f); // new 3.3.0, honor multiplier? - data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0) - data << int32(quest->GetRewSpellCast()); // casted spell - data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) - data << uint32(quest->GetBonusTalents()); // bonus talents - data << uint32(quest->GetRewArenaPoints()); // reward arena points - data << uint32(0); // unk - - for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - data << uint32(quest->RewardFactionId[i]); - - for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - data << int32(quest->RewardFactionValueId[i]); - - for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - data << int32(quest->RewardFactionValueIdOverride[i]); + quest->BuildExtraQuestInfo(data, _session->GetPlayer()); data << uint32(QUEST_EMOTE_COUNT); - for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i) + for (uint8 i = 0; i < QUEST_EMOTE_COUNT; ++i) { data << uint32(quest->DetailsEmote[i]); data << uint32(quest->DetailsEmoteDelay[i]); // DetailsEmoteDelay (in ms) @@ -398,11 +353,17 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const { + // SMSG_QUEST_QUERY_RESPONSE - Updated to 422 + std::string questTitle = quest->GetTitle(); std::string questDetails = quest->GetDetails(); std::string questObjectives = quest->GetObjectives(); std::string questEndText = quest->GetEndText(); std::string questCompletedText = quest->GetCompletedText(); + std::string questGiverTextWindow = quest->GetQuestGiverTextWindow(); + std::string questGiverTargetName = quest->GetQuestGiverTargetName(); + std::string questTurnTextWindow = quest->GetQuestTurnTextWindow(); + std::string questTurnTargetName = quest->GetQuestTurnTargetName(); std::string questObjectiveText[QUEST_OBJECTIVES_COUNT]; for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) @@ -418,6 +379,10 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives); ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText); ObjectMgr::GetLocaleString(localeData->CompletedText, locale, questCompletedText); + ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, locale, questGiverTextWindow); + ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, locale, questGiverTargetName); + ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, locale, questTurnTextWindow); + ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, locale, questTurnTargetName); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) ObjectMgr::GetLocaleString(localeData->ObjectiveText[i], locale, questObjectiveText[i]); @@ -458,11 +423,16 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << float(0); // new reward honor (multipled by ~62 at client side) data << uint32(quest->GetSrcItemId()); // source item id data << uint32(quest->GetFlags() & 0xFFFF); // quest flags + data << uint32(quest->GetMinimapTargetMark()); // minimap target mark (skull, etc. missing enum) data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) data << uint32(quest->GetPlayersSlain()); // players slain data << uint32(quest->GetBonusTalents()); // bonus talents data << uint32(quest->GetRewArenaPoints()); // bonus arena points - data << uint32(0); // review rep show mask + data << uint32(quest->GetRewardSkillId()); // reward skill id + data << uint32(quest->GetRewardSkillPoints()); // reward skill points + data << uint32(quest->GetRewardReputationMask()); // rep mask (unsure on what it does) + data << uint32(quest->GetQuestGiverPortrait()); // quest giver entry ? + data << uint32(quest->GetQuestTurnInPortrait()); // quest turnin entry ? if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) { @@ -491,7 +461,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc? data << int32(quest->RewardFactionValueId[i]); - for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0) + for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unknown usage data << int32(quest->RewardFactionValueIdOverride[i]); data << quest->GetPointMapId(); @@ -503,7 +473,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << questObjectives; data << questDetails; data << questEndText; - data << questCompletedText; // display in quest objectives window once all objectives are completed + data << questCompletedText; for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) { @@ -514,7 +484,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << uint32(quest->RequiredNpcOrGoCount[i]); data << uint32(quest->RequiredSourceItemId[i]); - data << uint32(0); // req source count? + data << uint32(quest->RequiredSourceItemCount[i]); } for (uint32 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) @@ -523,9 +493,30 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << uint32(quest->RequiredItemCount[i]); } + data << uint32(quest->GetRequiredSpell()); // Is it required to be cast, learned or what? + for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) data << questObjectiveText[i]; + for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) + { + data << uint32(quest->RewardCurrencyId[i]); + data << uint32(quest->RewardCurrencyCount[i]); + } + + for (uint32 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) + { + data << uint32(quest->RequiredCurrencyId[i]); + data << uint32(quest->RequiredCurrencyCount[i]); + } + + data << questGiverTextWindow; + data << questGiverTargetName; + data << questTurnTextWindow; + data << questTurnTargetName; + data << uint32(quest->GetSoundAccept()); + data << uint32(quest->GetSoundTurnIn()); + _session->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", quest->GetQuestId()); } @@ -651,7 +642,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, data << questTitle; data << requestItemsText; - data << uint32(0x00); // unknown + data << uint32(0); // unknown if (canComplete) data << quest->GetCompleteEmote(); @@ -659,10 +650,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, data << quest->GetIncompleteEmote(); // Close Window after cancel - if (closeOnCancel) - data << uint32(0x01); - else - data << uint32(0x00); + data << uint32(closeOnCancel); data << uint32(quest->GetFlags()); // 3.3.3 questFlags data << uint32(quest->GetSuggestedPlayers()); // SuggestedGroupNum @@ -685,14 +673,17 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, data << uint32(0); } - if (!canComplete) - data << uint32(0x00); - else - data << uint32(0x03); - - data << uint32(0x04); - data << uint32(0x08); - data << uint32(0x10); + // if (!canComplete) + // data << uint32(0x00); + // else + // data << uint32(0x03); + + data << uint32(0x00); // Unk flags + data << uint32(0x00); // Unk flags + data << uint32(0x04); // Unk flags + data << uint32(0x08); // Unk flags + data << uint32(0x10); // Unk flags 4.x + data << uint32(0x40); // Unk flags 4.x _session->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index 15766bbcd59..237aad4e5b3 100755 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -267,7 +267,7 @@ class PlayerMenu /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ - void SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const; + void SendQuestGiverStatus(uint32 questStatus, uint64 npcGUID) const; void SendQuestGiverQuestList(QEmote eEmote, const std::string& Title, uint64 npcGUID); diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 537bbd9c099..f82dfa53f4d 100755 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -34,7 +34,7 @@ class TempSummon : public Creature void SetTempSummonType(TempSummonType type); void SaveToDB(uint32 /*mapid*/, uint8 /*spawnMask*/, uint32 /*phaseMask*/) {} Unit* GetSummoner() const; - uint64 GetSummonerGUID() { return m_summonerGUID; } + uint64 GetSummonerGUID() const { return m_summonerGUID; } TempSummonType const& GetSummonType() { return m_type; } uint32 GetTimer() { return m_timer; } diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index cd4a9443867..065333dc9e2 100755 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -33,7 +33,7 @@ DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject), m_objectType |= TYPEMASK_DYNAMICOBJECT; m_objectTypeId = TYPEID_DYNAMICOBJECT; - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION); + m_updateFlag = UPDATEFLAG_STATIONARY_POSITION; m_valuesCount = DYNAMICOBJECT_END; } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 7375ed9f886..00b98ce2cc1 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -38,7 +38,7 @@ GameObject::GameObject() : WorldObject(false), m_model(NULL), m_goValue(new Game m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION); + m_updateFlag = (UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION); m_valuesCount = GAMEOBJECT_END; m_respawnTime = 0; @@ -230,6 +230,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa m_goValue->Building.Health = goinfo->building.intactNumHits + goinfo->building.damagedNumHits; m_goValue->Building.MaxHealth = m_goValue->Building.Health; SetGoAnimProgress(255); + SetUInt32Value(GAMEOBJECT_PARENTROTATION, m_goInfo->building.destructibleData); break; case GAMEOBJECT_TYPE_TRANSPORT: SetUInt32Value(GAMEOBJECT_LEVEL, goinfo->transport.pause); @@ -311,7 +312,7 @@ void GameObject::Update(uint32 diff) SetGoState(GO_STATE_ACTIVE); SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); - UpdateData udata; + UpdateData udata(caster->GetMapId()); WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata, caster->ToPlayer()); udata.BuildPacket(&packet); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index a8035043543..80aaf1c933f 100755 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -51,6 +51,7 @@ struct GameObjectTemplate uint32 flags; float size; uint32 questItems[MAX_GAMEOBJECT_QUEST_ITEMS]; + int32 unkInt32; union // different GO types have different data field { //0 GAMEOBJECT_TYPE_DOOR diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index c032647d924..2b5cb1e359a 100755 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -237,7 +237,7 @@ Item::Item() m_objectType |= TYPEMASK_ITEM; m_objectTypeId = TYPEID_ITEM; - m_updateFlag = UPDATEFLAG_LOWGUID; + m_updateFlag = 0; m_valuesCount = ITEM_END; m_slot = 0; @@ -644,8 +644,8 @@ void Item::SetItemRandomProperties(int32 randomPropId) SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID); SetState(ITEM_CHANGED, GetOwner()); } - for (uint32 i = PROP_ENCHANTMENT_SLOT_2; i < PROP_ENCHANTMENT_SLOT_2 + 3; ++i) - SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_2], 0, 0); + for (uint32 i = PROP_ENCHANTMENT_SLOT_1; i < PROP_ENCHANTMENT_SLOT_1 + 3; ++i) + SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_1], 0, 0); } } else @@ -661,7 +661,7 @@ void Item::SetItemRandomProperties(int32 randomPropId) SetState(ITEM_CHANGED, GetOwner()); } - for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i < PROP_ENCHANTMENT_SLOT_0 + 3; ++i) + for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i <= PROP_ENCHANTMENT_SLOT_4; ++i) SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_0], 0, 0); } } @@ -781,10 +781,15 @@ bool Item::HasEnchantRequiredSkill(const Player* player) const { // Check all enchants for required skill for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) + { + if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT || enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot))) if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id)) if (enchantEntry->requiredSkill && player->GetSkillValue(enchantEntry->requiredSkill) < enchantEntry->requiredSkillValue) return false; + } return true; } @@ -795,10 +800,15 @@ uint32 Item::GetEnchantRequiredLevel() const // Check all enchants for required level for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) + { + if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT || enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot))) if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id)) if (enchantEntry->requiredLevel > level) level = enchantEntry->requiredLevel; + } return level; } @@ -807,10 +817,16 @@ bool Item::IsBoundByEnchant() const { // Check all enchants for soulbound for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) + { + if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT || enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot))) if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id)) if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND) return true; + } + return false; } @@ -1196,3 +1212,308 @@ bool Item::CheckSoulboundTradeExpire() return false; } + +bool Item::CanBeTransmogrified() const +{ + ItemTemplate const* proto = GetTemplate(); + + if (!proto) + return false; + + if (proto->Quality == ITEM_QUALITY_LEGENDARY) + return false; + + if (proto->Class != ITEM_CLASS_ARMOR && + proto->Class != ITEM_CLASS_WEAPON) + return false; + + if (proto->Class == ITEM_CLASS_WEAPON && proto->SubClass == ITEM_SUBCLASS_WEAPON_FISHING_POLE) + return false; + + if (proto->Flags2 & ITEM_FLAGS_EXTRA_CANNOT_BE_TRANSMOG) + return false; + + if (!HasStats()) + return false; + + return true; +} + +bool Item::CanTransmogrify() const +{ + ItemTemplate const* proto = GetTemplate(); + + if (!proto) + return false; + + if (proto->Flags2 & ITEM_FLAGS_EXTRA_CANNOT_TRANSMOG) + return false; + + if (proto->Quality == ITEM_QUALITY_LEGENDARY) + return false; + + if (proto->Class != ITEM_CLASS_ARMOR && + proto->Class != ITEM_CLASS_WEAPON) + return false; + + if (proto->Class == ITEM_CLASS_WEAPON && proto->SubClass == ITEM_SUBCLASS_WEAPON_FISHING_POLE) + return false; + + if (proto->Flags2 & ITEM_FLAGS_EXTRA_CAN_TRANSMOG) + return true; + + if (!HasStats()) + return false; + + return true; +} + +bool Item::CanTransmogrifyItemWithItem(Item const* transmogrified, Item const* transmogrifier) +{ + if (!transmogrifier || !transmogrified) + return false; + + ItemTemplate const* proto1 = transmogrifier->GetTemplate(); // source + ItemTemplate const* proto2 = transmogrified->GetTemplate(); // dest + + if (proto1->ItemId == proto2->ItemId) + return false; + + if (!transmogrified->CanTransmogrify() || !transmogrifier->CanBeTransmogrified()) + return false; + + if (proto1->InventoryType == INVTYPE_BAG || + proto1->InventoryType == INVTYPE_RELIC || + proto1->InventoryType == INVTYPE_BODY || + proto1->InventoryType == INVTYPE_FINGER || + proto1->InventoryType == INVTYPE_TRINKET || + proto1->InventoryType == INVTYPE_AMMO || + proto1->InventoryType == INVTYPE_QUIVER) + return false; + + if (proto1->SubClass != proto2->SubClass && (proto1->Class != ITEM_CLASS_WEAPON || !proto2->IsRangedWeapon() || !proto1->IsRangedWeapon())) + return false; + + if (proto1->InventoryType != proto2->InventoryType && + (proto1->Class != ITEM_CLASS_WEAPON || (proto2->InventoryType != INVTYPE_WEAPONMAINHAND && proto2->InventoryType != INVTYPE_WEAPONOFFHAND))) + return false; + + return true; +} + +bool Item::HasStats() const +{ + if (GetItemRandomPropertyId() != 0) + return true; + + ItemTemplate const* proto = GetTemplate(); + for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) + if (proto->ItemStat[i].ItemStatValue != 0) + return true; + + return false; +} + +// used by mail items, transmog cost, stationeryinfo and others +uint32 Item::GetSellPrice(bool& normalSellPrice) const +{ + ItemTemplate const* proto = GetTemplate(); + normalSellPrice = true; + + if (proto->Flags2 & ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE) + { + return proto->BuyPrice; + } + else + { + ImportPriceQualityEntry const* qualityPrice = sImportPriceQualityStore.LookupEntry(proto->Quality + 1); + ItemPriceBaseEntry const* basePrice = sItemPriceBaseStore.LookupEntry(proto->ItemLevel); + + if (!qualityPrice || !basePrice) + return 0; + + float qualityFactor = qualityPrice->Factor; + float baseFactor = 0.0f; + + uint32 inventoryType = proto->InventoryType; + + if (inventoryType == INVTYPE_WEAPON || + inventoryType == INVTYPE_2HWEAPON || + inventoryType == INVTYPE_WEAPONMAINHAND || + inventoryType == INVTYPE_WEAPONOFFHAND || + inventoryType == INVTYPE_RANGED || + inventoryType == INVTYPE_THROWN || + inventoryType == INVTYPE_RANGEDRIGHT) + baseFactor = basePrice->WeaponFactor; + else + baseFactor = basePrice->ArmorFactor; + + if (inventoryType == INVTYPE_ROBE) + inventoryType = INVTYPE_CHEST; + + float typeFactor = 0.0f; + uint8 wepType = -1; + + switch (inventoryType) + { + case INVTYPE_HEAD: + case INVTYPE_SHOULDERS: + case INVTYPE_CHEST: + case INVTYPE_WAIST: + case INVTYPE_LEGS: + case INVTYPE_FEET: + case INVTYPE_WRISTS: + case INVTYPE_HANDS: + case INVTYPE_CLOAK: + { + ImportPriceArmorEntry const* armorPrice = sImportPriceArmorStore.LookupEntry(inventoryType); + if (!armorPrice) + return 0; + + switch (proto->SubClass) + { + case ITEM_SUBCLASS_ARMOR_MISCELLANEOUS: + case ITEM_SUBCLASS_ARMOR_CLOTH: + { + typeFactor = armorPrice->ClothFactor; + break; + } + case ITEM_SUBCLASS_ARMOR_LEATHER: + { + typeFactor = armorPrice->ClothFactor; + break; + } + case ITEM_SUBCLASS_ARMOR_MAIL: + { + typeFactor = armorPrice->ClothFactor; + break; + } + case ITEM_SUBCLASS_ARMOR_PLATE: + { + typeFactor = armorPrice->ClothFactor; + break; + } + default: + { + return 0; + } + } + + break; + } + case INVTYPE_SHIELD: + { + ImportPriceShieldEntry const* shieldPrice = sImportPriceShieldStore.LookupEntry(1); // it only has two rows, it's unclear which is the one used + if (!shieldPrice) + return 0; + + typeFactor = shieldPrice->Factor; + break; + } + case INVTYPE_WEAPONMAINHAND: + wepType = 0; // unk enum, fall back + case INVTYPE_WEAPONOFFHAND: + wepType = 1; // unk enum, fall back + case INVTYPE_WEAPON: + wepType = 2; // unk enum, fall back + case INVTYPE_2HWEAPON: + wepType = 3; // unk enum, fall back + case INVTYPE_RANGED: + case INVTYPE_RANGEDRIGHT: + case INVTYPE_RELIC: + { + wepType = 4; // unk enum + + ImportPriceWeaponEntry const* weaponPrice = sImportPriceWeaponStore.LookupEntry(wepType + 1); + if (!weaponPrice) + return 0; + + typeFactor = weaponPrice->Factor; + break; + } + default: + return proto->BuyPrice; + } + + normalSellPrice = false; + return (uint32)(qualityFactor * proto->Unk430_2 * proto->Unk430_1 * typeFactor * baseFactor); + } +} + +uint32 Item::GetSpecialPrice(uint32 minimumPrice) const +{ + ItemTemplate const* proto = GetTemplate(); + uint32 cost = 0; + + if (proto->Flags2 & ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE) + cost = proto->SellPrice; + else + { + bool normalPrice; + cost = GetSellPrice(normalPrice); + + if (!normalPrice) + { + if (proto->BuyCount <= 1) + { + ItemClassEntry const* classEntry = sItemClassStore.LookupEntry(proto->Class); + if (classEntry) + cost *= classEntry->PriceFactor; + else + cost = 0; + } + else + cost /= 4 * proto->BuyCount; + } + else + cost = proto->SellPrice; + } + + if (cost < minimumPrice) + cost = minimumPrice; + + return cost; +} + +int32 Item::GetReforgableStat(ItemModType statType) const +{ + ItemTemplate const* proto = GetTemplate(); + for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) + if (proto->ItemStat[i].ItemStatType == statType) + return proto->ItemStat[i].ItemStatValue; + + int32 randomPropId = GetItemRandomPropertyId(); + if (!randomPropId) + return 0; + + if (randomPropId < 0) + { + ItemRandomSuffixEntry const* randomSuffix = sItemRandomSuffixStore.LookupEntry(-randomPropId); + if (!randomSuffix) + return 0; + + for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e) + if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e)))) + for (uint32 f = 0; f < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f) + if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType) + for (int k = 0; k < 5; ++k) + if (randomSuffix->enchant_id[k] == enchant->ID) + return int32((randomSuffix->prefix[k] * GetItemSuffixFactor()) / 10000); + } + else + { + ItemRandomPropertiesEntry const* randomProp = sItemRandomPropertiesStore.LookupEntry(randomPropId); + if (!randomProp) + return 0; + + for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e) + if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e)))) + for (uint32 f = 0; f < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f) + if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType) + for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k) + if (randomProp->enchant_id[k] == enchant->ID) + return int32(enchant->amount[k]); + } + + return 0; +} diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index a5f9ed5c008..5b86d55f170 100755 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -162,14 +162,17 @@ enum EnchantmentSlot SOCK_ENCHANTMENT_SLOT_3 = 4, BONUS_ENCHANTMENT_SLOT = 5, PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment - MAX_INSPECTED_ENCHANTMENT_SLOT = 7, - - PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix - PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix - PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty - PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty - PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty - MAX_ENCHANTMENT_SLOT = 12 + //TODO: 7, + REFORGE_ENCHANTMENT_SLOT = 8, + TRANSMOGRIFY_ENCHANTMENT_SLOT = 9, + MAX_INSPECTED_ENCHANTMENT_SLOT = 10, + + PROP_ENCHANTMENT_SLOT_0 = 10, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_1 = 11, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_2 = 12, // used with RandomSuffix and RandomProperty + PROP_ENCHANTMENT_SLOT_3 = 13, // used with RandomProperty + PROP_ENCHANTMENT_SLOT_4 = 14, // used with RandomProperty + MAX_ENCHANTMENT_SLOT = 15 }; #define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment) @@ -315,10 +318,12 @@ class Item : public Object bool hasQuest(uint32 quest_id) const { return GetTemplate()->StartQuest == quest_id; } bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; } + bool HasStats() const; bool IsPotion() const { return GetTemplate()->IsPotion(); } bool IsWeaponVellum() const { return GetTemplate()->IsWeaponVellum(); } bool IsArmorVellum() const { return GetTemplate()->IsArmorVellum(); } bool IsConjuredConsumable() const { return GetTemplate()->IsConjuredConsumable(); } + bool IsRangedWeapon() const { return GetTemplate()->IsRangedWeapon(); } // Item Refund system void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = NULL); @@ -341,6 +346,23 @@ class Item : public Object void BuildUpdate(UpdateDataMapType&); uint32 GetScriptId() const { return GetTemplate()->ScriptId; } + + bool CanBeTransmogrified() const; + bool CanTransmogrify() const; + static bool CanTransmogrifyItemWithItem(Item const* transmogrified, Item const* transmogrifier); + uint32 GetSpecialPrice(uint32 minimumPrice = 10000) const; + + uint32 GetVisibleEntry() const + { + if (uint32 transmogrification = GetEnchantmentId(TRANSMOGRIFY_ENCHANTMENT_SLOT)) + return transmogrification; + return GetEntry(); + } + + uint32 GetSellPrice(bool& success) const; + + int32 GetReforgableStat(ItemModType statType) const; + private: std::string m_text; uint8 m_slot; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 5088a30157c..0d51c6e7e70 100755 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -59,18 +59,23 @@ enum ItemModType ITEM_MOD_EXPERTISE_RATING = 37, ITEM_MOD_ATTACK_POWER = 38, ITEM_MOD_RANGED_ATTACK_POWER = 39, - //ITEM_MOD_FERAL_ATTACK_POWER = 40, not in 3.3 - ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated - ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated ITEM_MOD_MANA_REGENERATION = 43, ITEM_MOD_ARMOR_PENETRATION_RATING = 44, ITEM_MOD_SPELL_POWER = 45, ITEM_MOD_HEALTH_REGEN = 46, ITEM_MOD_SPELL_PENETRATION = 47, - ITEM_MOD_BLOCK_VALUE = 48 + ITEM_MOD_BLOCK_VALUE = 48, + ITEM_MOD_MASTERY_RATING = 49, + ITEM_MOD_EXTRA_ARMOR = 50, + ITEM_MOD_FIRE_RESISTANCE = 51, + ITEM_MOD_FROST_RESISTANCE = 52, + ITEM_MOD_HOLY_RESISTANCE = 53, + ITEM_MOD_SHADOW_RESISTANCE = 54, + ITEM_MOD_NATURE_RESISTANCE = 55, + ITEM_MOD_ARCANE_RESISTANCE = 56, }; -#define MAX_ITEM_MOD 49 +#define MAX_ITEM_MOD 57 enum ItemSpelltriggerType { @@ -140,7 +145,7 @@ enum ItemProtoFlags ITEM_PROTO_FLAG_TRIGGERED_CAST = 0x10000000, // Spell is cast with triggered flag ITEM_PROTO_FLAG_MILLABLE = 0x20000000, // Item can be milled ITEM_PROTO_FLAG_UNK11 = 0x40000000, // ? - ITEM_PROTO_FLAG_UNK12 = 0x80000000 // ? + ITEM_PROTO_FLAG_BOP_TRADEABLE = 0x80000000 // bound item that can be traded }; /* TODO @@ -189,7 +194,13 @@ enum ItemFlagsExtra ITEM_FLAGS_EXTRA_HORDE_ONLY = 0x00000001, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY = 0x00000002, ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD = 0x00000004, // when item uses extended cost, gold is also required - ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100 + ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100, + ITEM_FLAGS_EXTRA_CASTER_WEAPON = 0x00000200, + ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE = 0x00004000, + ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND = 0x00020000, + ITEM_FLAGS_EXTRA_CANNOT_BE_TRANSMOG = 0x00200000, + ITEM_FLAGS_EXTRA_CANNOT_TRANSMOG = 0x00400000, + ITEM_FLAGS_EXTRA_CAN_TRANSMOG = 0x00800000, }; enum ItemFlagsCustom @@ -224,10 +235,12 @@ enum SocketColor SOCKET_COLOR_META = 1, SOCKET_COLOR_RED = 2, SOCKET_COLOR_YELLOW = 4, - SOCKET_COLOR_BLUE = 8 + SOCKET_COLOR_BLUE = 8, + // 16, Hydraulic, not used + SOCKET_COLOR_COGWHEEL = 32 }; -#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE) +#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE | SOCKET_COLOR_COGWHEEL) enum InventoryType { @@ -274,14 +287,14 @@ enum ItemClass ITEM_CLASS_REAGENT = 5, ITEM_CLASS_PROJECTILE = 6, ITEM_CLASS_TRADE_GOODS = 7, - ITEM_CLASS_GENERIC = 8, + ITEM_CLASS_GENERIC = 8, // OBSOLETE ITEM_CLASS_RECIPE = 9, - ITEM_CLASS_MONEY = 10, + ITEM_CLASS_MONEY = 10, // OBSOLETE ITEM_CLASS_QUIVER = 11, ITEM_CLASS_QUEST = 12, ITEM_CLASS_KEY = 13, - ITEM_CLASS_PERMANENT = 14, - ITEM_CLASS_MISC = 15, + ITEM_CLASS_PERMANENT = 14, // OBSOLETE + ITEM_CLASS_MISCELLANEOUS = 15, ITEM_CLASS_GLYPH = 16 }; @@ -294,7 +307,7 @@ enum ItemSubclassConsumable ITEM_SUBCLASS_ELIXIR = 2, ITEM_SUBCLASS_FLASK = 3, ITEM_SUBCLASS_SCROLL = 4, - ITEM_SUBCLASS_FOOD = 5, + ITEM_SUBCLASS_FOOD_DRINK = 5, ITEM_SUBCLASS_ITEM_ENHANCEMENT = 6, ITEM_SUBCLASS_BANDAGE = 7, ITEM_SUBCLASS_CONSUMABLE_OTHER = 8 @@ -312,28 +325,29 @@ enum ItemSubclassContainer ITEM_SUBCLASS_GEM_CONTAINER = 5, ITEM_SUBCLASS_MINING_CONTAINER = 6, ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7, - ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8 + ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8, + ITEM_SUBCLASS_TACKLE_CONTAINER = 9 }; -#define MAX_ITEM_SUBCLASS_CONTAINER 9 +#define MAX_ITEM_SUBCLASS_CONTAINER 10 enum ItemSubclassWeapon { - ITEM_SUBCLASS_WEAPON_AXE = 0, - ITEM_SUBCLASS_WEAPON_AXE2 = 1, + ITEM_SUBCLASS_WEAPON_AXE = 0, // One-Handed Axes + ITEM_SUBCLASS_WEAPON_AXE2 = 1, // Two-Handed Axes ITEM_SUBCLASS_WEAPON_BOW = 2, ITEM_SUBCLASS_WEAPON_GUN = 3, - ITEM_SUBCLASS_WEAPON_MACE = 4, - ITEM_SUBCLASS_WEAPON_MACE2 = 5, + ITEM_SUBCLASS_WEAPON_MACE = 4, // One-Handed Maces + ITEM_SUBCLASS_WEAPON_MACE2 = 5, // Two-Handed Maces ITEM_SUBCLASS_WEAPON_POLEARM = 6, - ITEM_SUBCLASS_WEAPON_SWORD = 7, - ITEM_SUBCLASS_WEAPON_SWORD2 = 8, - ITEM_SUBCLASS_WEAPON_obsolete = 9, + ITEM_SUBCLASS_WEAPON_SWORD = 7, // One-Handed Swords + ITEM_SUBCLASS_WEAPON_SWORD2 = 8, // Two-Handed Swords + ITEM_SUBCLASS_WEAPON_Obsolete = 9, ITEM_SUBCLASS_WEAPON_STAFF = 10, - ITEM_SUBCLASS_WEAPON_EXOTIC = 11, - ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12, - ITEM_SUBCLASS_WEAPON_FIST = 13, - ITEM_SUBCLASS_WEAPON_MISC = 14, + ITEM_SUBCLASS_WEAPON_EXOTIC = 11, // One-Handed Exotics + ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12, // Two-Handed Exotics + ITEM_SUBCLASS_WEAPON_FIST_WEAPON = 13, + ITEM_SUBCLASS_WEAPON_MISCELLANEOUS = 14, ITEM_SUBCLASS_WEAPON_DAGGER = 15, ITEM_SUBCLASS_WEAPON_THROWN = 16, ITEM_SUBCLASS_WEAPON_SPEAR = 17, @@ -358,27 +372,30 @@ enum ItemSubclassGem ITEM_SUBCLASS_GEM_ORANGE = 5, ITEM_SUBCLASS_GEM_META = 6, ITEM_SUBCLASS_GEM_SIMPLE = 7, - ITEM_SUBCLASS_GEM_PRISMATIC = 8 + ITEM_SUBCLASS_GEM_PRISMATIC = 8, + ITEM_SUBCLASS_GEM_HYDRAULIC = 9, + ITEM_SUBCLASS_GEM_COGWHEEL = 10 }; -#define MAX_ITEM_SUBCLASS_GEM 9 +#define MAX_ITEM_SUBCLASS_GEM 11 enum ItemSubclassArmor { - ITEM_SUBCLASS_ARMOR_MISC = 0, + ITEM_SUBCLASS_ARMOR_MISCELLANEOUS = 0, ITEM_SUBCLASS_ARMOR_CLOTH = 1, ITEM_SUBCLASS_ARMOR_LEATHER = 2, ITEM_SUBCLASS_ARMOR_MAIL = 3, ITEM_SUBCLASS_ARMOR_PLATE = 4, - ITEM_SUBCLASS_ARMOR_BUCKLER = 5, + ITEM_SUBCLASS_ARMOR_BUCKLER = 5, // OBSOLETE ITEM_SUBCLASS_ARMOR_SHIELD = 6, ITEM_SUBCLASS_ARMOR_LIBRAM = 7, ITEM_SUBCLASS_ARMOR_IDOL = 8, ITEM_SUBCLASS_ARMOR_TOTEM = 9, - ITEM_SUBCLASS_ARMOR_SIGIL = 10 + ITEM_SUBCLASS_ARMOR_SIGIL = 10, + ITEM_SUBCLASS_ARMOR_RELIC = 11, }; -#define MAX_ITEM_SUBCLASS_ARMOR 11 +#define MAX_ITEM_SUBCLASS_ARMOR 12 enum ItemSubclassReagent { @@ -389,11 +406,11 @@ enum ItemSubclassReagent enum ItemSubclassProjectile { - ITEM_SUBCLASS_WAND = 0, // ABS - ITEM_SUBCLASS_BOLT = 1, // ABS + ITEM_SUBCLASS_WAND = 0, // OBSOLETE + ITEM_SUBCLASS_BOLT = 1, // OBSOLETE ITEM_SUBCLASS_ARROW = 2, ITEM_SUBCLASS_BULLET = 3, - ITEM_SUBCLASS_THROWN = 4 // ABS + ITEM_SUBCLASS_THROWN = 4 // OBSOLETE }; #define MAX_ITEM_SUBCLASS_PROJECTILE 5 @@ -414,15 +431,15 @@ enum ItemSubclassTradeGoods ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11, ITEM_SUBCLASS_ENCHANTING = 12, ITEM_SUBCLASS_MATERIAL = 13, - ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14, - ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15 + ITEM_SUBCLASS_ITEM_ENCHANTMENT = 14, + ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15 // OBSOLETE }; #define MAX_ITEM_SUBCLASS_TRADE_GOODS 16 enum ItemSubclassGeneric { - ITEM_SUBCLASS_GENERIC = 0 + ITEM_SUBCLASS_GENERIC = 0 // OBSOLETE }; #define MAX_ITEM_SUBCLASS_GENERIC 1 @@ -439,22 +456,23 @@ enum ItemSubclassRecipe ITEM_SUBCLASS_FIRST_AID_MANUAL = 7, ITEM_SUBCLASS_ENCHANTING_FORMULA = 8, ITEM_SUBCLASS_FISHING_MANUAL = 9, - ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10 + ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10, + ITEM_SUBCLASS_INSCRIPTION_TECHNIQUE = 11 }; -#define MAX_ITEM_SUBCLASS_RECIPE 11 +#define MAX_ITEM_SUBCLASS_RECIPE 12 enum ItemSubclassMoney { - ITEM_SUBCLASS_MONEY = 0 + ITEM_SUBCLASS_MONEY = 0 // OBSOLETE }; #define MAX_ITEM_SUBCLASS_MONEY 1 enum ItemSubclassQuiver { - ITEM_SUBCLASS_QUIVER0 = 0, // ABS - ITEM_SUBCLASS_QUIVER1 = 1, // ABS + ITEM_SUBCLASS_QUIVER0 = 0, // OBSOLETE + ITEM_SUBCLASS_QUIVER1 = 1, // OBSOLETE ITEM_SUBCLASS_QUIVER = 2, ITEM_SUBCLASS_AMMO_POUCH = 3 }; @@ -549,24 +567,19 @@ inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemS #pragma pack(push, 1) #endif -struct _Damage -{ - float DamageMin; - float DamageMax; - uint32 DamageType; // id from Resistances.dbc -}; - struct _ItemStat { uint32 ItemStatType; int32 ItemStatValue; + int32 ItemStatUnk1; + int32 ItemStatUnk2; }; + struct _Spell { int32 SpellId; // id from Spell.dbc uint32 SpellTrigger; int32 SpellCharges; - float SpellPPMRate; int32 SpellCooldown; uint32 SpellCategory; // id from SpellCategory.dbc int32 SpellCategoryCooldown; @@ -589,11 +602,13 @@ struct ItemTemplate uint32 Class; // id from ItemClass.dbc uint32 SubClass; // id from ItemSubClass.dbc int32 Unk0; - std::string Name1; + std::string Name1; uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc uint32 Quality; uint32 Flags; uint32 Flags2; + float Unk430_1; + float Unk430_2; uint32 BuyCount; int32 BuyPrice; uint32 SellPrice; @@ -612,24 +627,14 @@ struct ItemTemplate int32 MaxCount; // <= 0: no limit int32 Stackable; // 0: not allowed, -1: put in player coin info tab and don't limit stacking (so 1 slot) uint32 ContainerSlots; - uint32 StatsCount; _ItemStat ItemStat[MAX_ITEM_PROTO_STATS]; uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc - uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc - _Damage Damage[MAX_ITEM_PROTO_DAMAGES]; - uint32 Armor; - uint32 HolyRes; - uint32 FireRes; - uint32 NatureRes; - uint32 FrostRes; - uint32 ShadowRes; - uint32 ArcaneRes; + uint32 DamageType; // id from Resistances.dbc uint32 Delay; - uint32 AmmoType; float RangedModRange; _Spell Spells[MAX_ITEM_PROTO_SPELLS]; uint32 Bonding; - std::string Description; + std::string Description; uint32 PageText; uint32 LanguageID; uint32 PageMaterial; @@ -639,7 +644,6 @@ struct ItemTemplate uint32 Sheath; int32 RandomProperty; // id from ItemRandomProperties.dbc int32 RandomSuffix; // id from ItemRandomSuffix.dbc - uint32 Block; uint32 ItemSet; // id from ItemSet.dbc uint32 MaxDurability; uint32 Area; // id from AreaTable.dbc @@ -649,13 +653,23 @@ struct ItemTemplate _Socket Socket[MAX_ITEM_PROTO_SOCKETS]; uint32 socketBonus; // id from SpellItemEnchantment.dbc uint32 GemProperties; // id from GemProperties.dbc - uint32 RequiredDisenchantSkill; float ArmorDamageModifier; uint32 Duration; uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc uint32 HolidayId; // id from Holidays.dbc + float StatScalingFactor; + uint32 CurrencySubstitutionId; // May be used instead of a currency + uint32 CurrencySubstitutionCount; + + // extra fields, not part of db2 files + float DamageMin; + float DamageMax; + float DPS; + uint32 Armor; + float SpellPPMRate; uint32 ScriptId; uint32 DisenchantID; + uint32 RequiredDisenchantSkill; uint32 FoodType; uint32 MinMoneyLoot; uint32 MaxMoneyLoot; @@ -689,22 +703,12 @@ struct ItemTemplate return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable); } - float getDPS() const - { - if (Delay == 0) - return 0; - float temp = 0; - for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) - temp+=Damage[i].DamageMin + Damage[i].DamageMax; - return temp*500/Delay; - } - int32 getFeralBonus(int32 extraDPS = 0) const { // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc - if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3) + if (Class == ITEM_CLASS_WEAPON && (1 << SubClass) & 0x02A5F3) { - int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767; + int32 bonus = int32((extraDPS + DPS) * 14.0f) - 767; if (bonus < 0) return 0; return bonus; @@ -737,8 +741,16 @@ struct ItemTemplate bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; } bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; } - bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; } + bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ITEM_ENCHANTMENT; } bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_PROTO_FLAG_CONJURED); } + + bool IsRangedWeapon() const + { + return Class == ITEM_CLASS_WEAPON || + SubClass == ITEM_SUBCLASS_WEAPON_BOW || + SubClass == ITEM_SUBCLASS_WEAPON_GUN || + SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW; + } }; // Benchmarked: Faster than std::map (insert/find) @@ -750,17 +762,6 @@ struct ItemLocale StringVector Description; }; -struct ItemSetNameEntry -{ - std::string name; - uint32 InventoryType; -}; - -struct ItemSetNameLocale -{ - StringVector Name; -}; - // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform #if defined(__GNUC__) #pragma pack() diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index b910fee951b..264672fc5c9 100755..100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -47,6 +47,7 @@ #include "OutdoorPvPMgr.h" #include "MovementPacketBuilder.h" #include "DynamicTree.h" +#include "Unit.h" #include "Group.h" uint32 GuidHigh2TypeId(uint32 guid_hi) @@ -137,21 +138,8 @@ void Object::_Create(uint32 guidlow, uint32 entry, HighGuid guidhigh) uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh); SetUInt64Value(OBJECT_FIELD_GUID, guid); - uint32 type = 0; - switch (m_objectType) - { - //case TYPEID_ITEM: type = 3; break; - //case TYPEID_CONTAINER: type = 7; break; //+4 - //case TYPEID_UNIT: type = 9; break; //+2 - //case TYPEID_PLAYER: type = 25; break; //+16 - //case TYPEID_GAMEOBJECT: type = 33; break; //+8 - case TYPEID_DYNAMICOBJECT: type = 65; break; //+32 - //case TYPEID_CORPSE: type = 129; break; //+64 - default: type = m_objectType; break; - } - SetUInt32Value(OBJECT_FIELD_TYPE, type); - //SetUInt32Value(OBJECT_FIELD_TYPE, m_objectType); - m_PackGUID.wpos(0); + SetUInt16Value(OBJECT_FIELD_TYPE, 0, m_objectType); + m_PackGUID.clear(); m_PackGUID.appendPackGUID(GetGUID()); } @@ -187,40 +175,42 @@ void Object::RemoveFromWorld() ClearUpdateMask(true); } -void Object::BuildMovementUpdateBlock(UpdateData* data, uint32 flags) const -{ - ByteBuffer buf(500); - - buf << uint8(UPDATETYPE_MOVEMENT); - buf.append(GetPackGUID()); - - _BuildMovementUpdate(&buf, flags); - - data->AddUpdateBlock(buf); -} - void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const { if (!target) return; - uint8 updatetype = UPDATETYPE_CREATE_OBJECT; + uint8 updateType = UPDATETYPE_CREATE_OBJECT; uint16 flags = m_updateFlag; + uint32 valCount = m_valuesCount; + /** lower flag1 **/ if (target == this) // building packet for yourself flags |= UPDATEFLAG_SELF; + else if (GetTypeId() == TYPEID_PLAYER) + valCount = PLAYER_END_NOT_SELF; - if (flags & UPDATEFLAG_STATIONARY_POSITION) + switch (GetGUIDHigh()) { - // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses... - if (isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER)) - updatetype = UPDATETYPE_CREATE_OBJECT2; - - // UPDATETYPE_CREATE_OBJECT2 for pets... - if (target->GetPetGUID() == GetGUID()) - updatetype = UPDATETYPE_CREATE_OBJECT2; + case HIGHGUID_PLAYER: + case HIGHGUID_PET: + case HIGHGUID_CORPSE: + case HIGHGUID_DYNAMICOBJECT: + updateType = UPDATETYPE_CREATE_OBJECT2; + break; + case HIGHGUID_UNIT: + if (ToUnit()->ToTempSummon() && IS_PLAYER_GUID(ToUnit()->ToTempSummon()->GetSummonerGUID())) + updateType = UPDATETYPE_CREATE_OBJECT2; + break; + case HIGHGUID_GAMEOBJECT: + if (IS_PLAYER_GUID(ToGameObject()->GetOwnerGUID())) + updateType = UPDATETYPE_CREATE_OBJECT2; + break; + } + if (flags & UPDATEFLAG_STATIONARY_POSITION) + { // UPDATETYPE_CREATE_OBJECT2 for some gameobject types... if (isType(TYPEMASK_GAMEOBJECT)) { @@ -230,7 +220,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c case GAMEOBJECT_TYPE_DUEL_ARBITER: case GAMEOBJECT_TYPE_FLAGSTAND: case GAMEOBJECT_TYPE_FLAGDROP: - updatetype = UPDATETYPE_CREATE_OBJECT2; + updateType = UPDATETYPE_CREATE_OBJECT2; break; case GAMEOBJECT_TYPE_TRANSPORT: flags |= UPDATEFLAG_TRANSPORT; @@ -239,34 +229,29 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c break; } } - - if (isType(TYPEMASK_UNIT)) - { - if (((Unit*)this)->getVictim()) - flags |= UPDATEFLAG_HAS_TARGET; - } } - //sLog->outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2); + if (ToUnit() && ToUnit()->getVictim()) + flags |= UPDATEFLAG_HAS_TARGET; ByteBuffer buf(500); - buf << (uint8)updatetype; + buf << uint8(updateType); buf.append(GetPackGUID()); - buf << (uint8)m_objectTypeId; + buf << uint8(m_objectTypeId); _BuildMovementUpdate(&buf, flags); UpdateMask updateMask; - updateMask.SetCount(m_valuesCount); + updateMask.SetCount(valCount); _SetCreateBits(&updateMask, target); - _BuildValuesUpdate(updatetype, &buf, &updateMask, target); + _BuildValuesUpdate(updateType, &buf, &updateMask, target); data->AddUpdateBlock(buf); } void Object::SendUpdateToPlayer(Player* player) { // send create update to player - UpdateData upd; + UpdateData upd(player->GetMapId()); WorldPacket packet; BuildCreateUpdateBlockForPlayer(&upd, player); @@ -278,11 +263,15 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) c { ByteBuffer buf(500); - buf << (uint8) UPDATETYPE_VALUES; + buf << uint8(UPDATETYPE_VALUES); buf.append(GetPackGUID()); UpdateMask updateMask; - updateMask.SetCount(m_valuesCount); + uint32 valCount = m_valuesCount; + if (GetTypeId() == TYPEID_PLAYER && target != this) + valCount = PLAYER_END_NOT_SELF; + + updateMask.SetCount(valCount); _SetUpdateBits(&updateMask, target); _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target); @@ -309,150 +298,305 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { - *data << uint16(flags); // update flags + uint32 unkLoopCounter = 0; + // Bit content + data->WriteBit(0); + data->WriteBit(0); + data->WriteBit(flags & UPDATEFLAG_ROTATION); + data->WriteBit(flags & UPDATEFLAG_ANIMKITS); + data->WriteBit(flags & UPDATEFLAG_HAS_TARGET); + data->WriteBit(flags & UPDATEFLAG_SELF); + data->WriteBit(flags & UPDATEFLAG_VEHICLE); + data->WriteBit(flags & UPDATEFLAG_LIVING); + data->WriteBits(unkLoopCounter, 24); + data->WriteBit(0); + data->WriteBit(flags & UPDATEFLAG_GO_TRANSPORT_POSITION); + data->WriteBit(flags & UPDATEFLAG_STATIONARY_POSITION); + data->WriteBit(flags & UPDATEFLAG_UNK5); + data->WriteBit(0); + data->WriteBit(flags & UPDATEFLAG_TRANSPORT); + bool fullSpline = false; - // 0x20 if (flags & UPDATEFLAG_LIVING) { - ((Unit*)this)->BuildMovementPacket(data); + Unit const* self = ToUnit(); + ObjectGuid guid = GetGUID(); + uint32 movementFlags = self->m_movementInfo.GetMovementFlags(); + uint16 movementFlagsExtra = self->m_movementInfo.GetExtraMovementFlags(); + + data->WriteBit(!movementFlags); + data->WriteBit(G3D::fuzzyEq(self->GetOrientation(), 0.0f)); // Has Orientation + data->WriteBit(guid[7]); + data->WriteBit(guid[3]); + data->WriteBit(guid[2]); + if (movementFlags) + data->WriteBits(movementFlags, 30); + + data->WriteBit(0); + data->WriteBit(!((movementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || + (movementFlagsExtra & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))); // Has pitch + data->WriteBit(self->IsSplineEnabled()); // Has spline data + data->WriteBit(movementFlagsExtra & MOVEMENTFLAG2_INTERPOLATED_TURNING);// Has fall data + data->WriteBit(!(movementFlags & MOVEMENTFLAG_SPLINE_ELEVATION)); // Has spline elevation + data->WriteBit(guid[5]); + data->WriteBit(self->m_movementInfo.t_guid); // Has transport data + data->WriteBit(0); // Is missing time + if (self->m_movementInfo.t_guid) + { + ObjectGuid transGuid = self->m_movementInfo.t_guid; + + data->WriteBit(transGuid[1]); + data->WriteBit(0); // Has transport time 2 + data->WriteBit(transGuid[4]); + data->WriteBit(transGuid[0]); + data->WriteBit(transGuid[6]); + data->WriteBit(0); // Has transport time 3 + data->WriteBit(transGuid[7]); + data->WriteBit(transGuid[5]); + data->WriteBit(transGuid[3]); + data->WriteBit(transGuid[2]); + } + + data->WriteBit(guid[4]); + if (self->IsSplineEnabled()) + Movement::PacketBuilder::WriteCreateBits(*self->movespline, *data, fullSpline); - *data << ((Unit*)this)->GetSpeed(MOVE_WALK); - *data << ((Unit*)this)->GetSpeed(MOVE_RUN); - *data << ((Unit*)this)->GetSpeed(MOVE_RUN_BACK); - *data << ((Unit*)this)->GetSpeed(MOVE_SWIM); - *data << ((Unit*)this)->GetSpeed(MOVE_SWIM_BACK); - *data << ((Unit*)this)->GetSpeed(MOVE_FLIGHT); - *data << ((Unit*)this)->GetSpeed(MOVE_FLIGHT_BACK); - *data << ((Unit*)this)->GetSpeed(MOVE_TURN_RATE); - *data << ((Unit*)this)->GetSpeed(MOVE_PITCH_RATE); + data->WriteBit(guid[6]); + if (movementFlagsExtra & MOVEMENTFLAG2_INTERPOLATED_TURNING) + data->WriteBit(movementFlags & MOVEMENTFLAG_FALLING); - // 0x08000000 - if (((Unit*)this)->m_movementInfo.GetMovementFlags() & MOVEMENTFLAG_SPLINE_ENABLED) - Movement::PacketBuilder::WriteCreate(*((Unit*)this)->movespline, *data); + data->WriteBit(guid[0]); + data->WriteBit(guid[1]); + data->WriteBit(0); + data->WriteBit(!movementFlagsExtra); + if (movementFlagsExtra) + data->WriteBits(movementFlagsExtra, 12); } - else + + if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION) { - if (flags & UPDATEFLAG_POSITION) - { - Transport* transport = ((WorldObject*)this)->GetTransport(); - if (transport) - data->append(transport->GetPackGUID()); - else - *data << uint8(0); + WorldObject const* self = static_cast<WorldObject const*>(this); + ObjectGuid transGuid = self->m_movementInfo.t_guid; + data->WriteBit(transGuid[5]); + data->WriteBit(0); // Has GO transport time 3 + data->WriteBit(transGuid[0]); + data->WriteBit(transGuid[3]); + data->WriteBit(transGuid[6]); + data->WriteBit(transGuid[1]); + data->WriteBit(transGuid[4]); + data->WriteBit(transGuid[2]); + data->WriteBit(0); // Has GO transport time 2 + data->WriteBit(transGuid[7]); + } - *data << ((WorldObject*)this)->GetPositionX(); - *data << ((WorldObject*)this)->GetPositionY(); - if (isType(TYPEMASK_UNIT)) - *data << ((Unit*)this)->GetPositionZMinusOffset(); - else - *data << ((WorldObject*)this)->GetPositionZ(); + if (flags & UPDATEFLAG_HAS_TARGET) + { + ObjectGuid victimGuid = ToUnit()->getVictim()->GetGUID(); // checked in BuildCreateUpdateBlockForPlayer + data->WriteBit(victimGuid[2]); + data->WriteBit(victimGuid[7]); + data->WriteBit(victimGuid[0]); + data->WriteBit(victimGuid[4]); + data->WriteBit(victimGuid[5]); + data->WriteBit(victimGuid[6]); + data->WriteBit(victimGuid[1]); + data->WriteBit(victimGuid[3]); + } - if (transport) - { - *data << ((WorldObject*)this)->GetTransOffsetX(); - *data << ((WorldObject*)this)->GetTransOffsetY(); - *data << ((WorldObject*)this)->GetTransOffsetZ(); - } - else - { - *data << ((WorldObject*)this)->GetPositionX(); - *data << ((WorldObject*)this)->GetPositionY(); - if (isType(TYPEMASK_UNIT)) - *data << ((Unit*)this)->GetPositionZMinusOffset(); - else - *data << ((WorldObject*)this)->GetPositionZ(); - } + if (flags & UPDATEFLAG_ANIMKITS) + { + data->WriteBit(1); // Missing AnimKit1 + data->WriteBit(1); // Missing AnimKit2 + data->WriteBit(1); // Missing AnimKit3 + } - *data << ((WorldObject*)this)->GetOrientation(); + data->FlushBits(); - if (GetTypeId() == TYPEID_CORPSE) - *data << float(((WorldObject*)this)->GetOrientation()); - else - *data << float(0); - } - else + // Data + for (uint32 i = 0; i < unkLoopCounter; ++i) + *data << uint32(0); + + if (flags & UPDATEFLAG_LIVING) + { + Unit const* self = ToUnit(); + ObjectGuid guid = GetGUID(); + uint32 movementFlags = self->m_movementInfo.GetMovementFlags(); + uint16 movementFlagsExtra = self->m_movementInfo.GetExtraMovementFlags(); + + data->WriteByteSeq(guid[4]); + *data << self->GetSpeed(MOVE_RUN_BACK); + if (movementFlagsExtra & MOVEMENTFLAG2_INTERPOLATED_TURNING) { - // 0x40 - if (flags & UPDATEFLAG_STATIONARY_POSITION) + if (movementFlags & MOVEMENTFLAG_FALLING) { - *data << ((WorldObject*)this)->GetPositionX(); - *data << ((WorldObject*)this)->GetPositionY(); - if (isType(TYPEMASK_UNIT)) - *data << ((Unit*)this)->GetPositionZMinusOffset(); - else - *data << ((WorldObject*)this)->GetPositionZ(); - *data << ((WorldObject*)this)->GetOrientation(); + *data << float(self->m_movementInfo.j_cosAngle); + *data << float(self->m_movementInfo.j_xyspeed); + *data << float(self->m_movementInfo.j_sinAngle); } + + *data << uint32(self->m_movementInfo.fallTime); + *data << float(self->m_movementInfo.j_zspeed); } - } - // 0x8 - if (flags & UPDATEFLAG_UNKNOWN) - { - *data << uint32(0); - } + *data << self->GetSpeed(MOVE_SWIM_BACK); + if (movementFlags & MOVEMENTFLAG_SPLINE_ELEVATION) + *data << float(self->m_movementInfo.splineElevation); - // 0x10 - if (flags & UPDATEFLAG_LOWGUID) - { - switch (GetTypeId()) + if (self->IsSplineEnabled()) + Movement::PacketBuilder::WriteCreateData(*self->movespline, *data, fullSpline); + + *data << float(self->GetPositionZMinusOffset()); + data->WriteByteSeq(guid[5]); + if (self->m_movementInfo.t_guid) { - case TYPEID_OBJECT: - case TYPEID_ITEM: - case TYPEID_CONTAINER: - case TYPEID_GAMEOBJECT: - case TYPEID_DYNAMICOBJECT: - case TYPEID_CORPSE: - *data << uint32(GetGUIDLow()); // GetGUIDLow() - break; - //! Unit, Player and default here are sending wrong values. - //! TODO: Research the proper formula - case TYPEID_UNIT: - *data << uint32(0x0000000B); // unk - break; - case TYPEID_PLAYER: - if (flags & UPDATEFLAG_SELF) - *data << uint32(0x0000002F); // unk - else - *data << uint32(0x00000008); // unk - break; - default: - *data << uint32(0x00000000); // unk - break; + ObjectGuid transGuid = self->m_movementInfo.t_guid; + + data->WriteByteSeq(transGuid[5]); + data->WriteByteSeq(transGuid[7]); + *data << uint32(self->GetTransTime()); + *data << float(self->GetTransOffsetO()); + //if (hasTransportTime2) + // *data << uint32(0); + + *data << float(self->GetTransOffsetY()); + *data << float(self->GetTransOffsetX()); + data->WriteByteSeq(transGuid[3]); + *data << float(self->GetTransOffsetZ()); + data->WriteByteSeq(transGuid[0]); + //if (hasTransportTime3) + // *data << uint32(0); + + *data << int8(self->GetTransSeat()); + data->WriteByteSeq(transGuid[1]); + data->WriteByteSeq(transGuid[6]); + data->WriteByteSeq(transGuid[2]); + data->WriteByteSeq(transGuid[4]); } - } - // 0x4 - if (flags & UPDATEFLAG_HAS_TARGET) - { - if (Unit* victim = ((Unit*)this)->getVictim()) - data->append(victim->GetPackGUID()); - else - *data << uint8(0); + *data << float(self->GetPositionX()); + *data << self->GetSpeed(MOVE_PITCH_RATE); + data->WriteByteSeq(guid[3]); + data->WriteByteSeq(guid[0]); + *data << self->GetSpeed(MOVE_SWIM); + *data << float(self->GetPositionY()); + data->WriteByteSeq(guid[7]); + data->WriteByteSeq(guid[1]); + data->WriteByteSeq(guid[2]); + *data << self->GetSpeed(MOVE_WALK); + + //if (true) // Has time, controlled by bit just after HasTransport + *data << uint32(getMSTime()); + + *data << self->GetSpeed(MOVE_FLIGHT_BACK); + data->WriteByteSeq(guid[6]); + *data << self->GetSpeed(MOVE_TURN_RATE); + if (!G3D::fuzzyEq(self->GetOrientation(), 0.0f)) + *data << float(self->GetOrientation()); + + *data << self->GetSpeed(MOVE_RUN); + if ((movementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || + (movementFlagsExtra & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)) + *data << float(self->m_movementInfo.pitch); + + *data << self->GetSpeed(MOVE_FLIGHT); } - // 0x2 - if (flags & UPDATEFLAG_TRANSPORT) + if (flags & UPDATEFLAG_VEHICLE) { - *data << uint32(getMSTime()); // Unknown - getMSTime is wrong. + Unit const* self = ToUnit(); + *data << float(self->GetOrientation()); + *data << uint32(self->GetVehicleKit()->GetVehicleInfo()->m_ID); } - // 0x80 - if (flags & UPDATEFLAG_VEHICLE) + if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION) { - // TODO: Allow players to aquire this updateflag. - *data << uint32(((Unit*)this)->GetVehicleKit()->GetVehicleInfo()->m_ID); - *data << float(((Creature*)this)->GetOrientation()); + WorldObject const* self = static_cast<WorldObject const*>(this); + ObjectGuid transGuid = self->m_movementInfo.t_guid; + + data->WriteBit(transGuid[0]); + data->WriteBit(transGuid[5]); + //if (hasTransportTime3) + // *data << uint32(0); + + data->WriteBit(transGuid[3]); + *data << float(self->GetTransOffsetX()); + data->WriteBit(transGuid[4]); + data->WriteBit(transGuid[6]); + data->WriteBit(transGuid[1]); + *data << uint32(self->GetTransTime()); + *data << float(self->GetTransOffsetY()); + data->WriteBit(transGuid[2]); + data->WriteBit(transGuid[7]); + *data << float(self->GetTransOffsetZ()); + *data << int8(self->GetTransSeat()); + *data << float(self->GetTransOffsetO()); + //if (hasTransportTime2) + // *data << uint32(0); } - // 0x200 if (flags & UPDATEFLAG_ROTATION) + *data << uint64(ToGameObject()->GetRotation()); + + if (flags & UPDATEFLAG_UNK5) + { + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << uint8(0); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + *data << float(0.0f); + } + + if (flags & UPDATEFLAG_STATIONARY_POSITION) { - *data << int64(((GameObject*)this)->GetRotation()); + WorldObject const* self = static_cast<WorldObject const*>(this); + *data << float(self->GetOrientation()); + *data << float(self->GetPositionX()); + *data << float(self->GetPositionY()); + if (Unit const* unit = ToUnit()) + *data << float(unit->GetPositionZMinusOffset()); + else + *data << float(self->GetPositionZ()); } + + if (flags & UPDATEFLAG_HAS_TARGET) + { + ObjectGuid victimGuid = ToUnit()->getVictim()->GetGUID(); // checked in BuildCreateUpdateBlockForPlayer + data->WriteByteSeq(victimGuid[4]); + data->WriteByteSeq(victimGuid[0]); + data->WriteByteSeq(victimGuid[3]); + data->WriteByteSeq(victimGuid[5]); + data->WriteByteSeq(victimGuid[7]); + data->WriteByteSeq(victimGuid[6]); + data->WriteByteSeq(victimGuid[2]); + data->WriteByteSeq(victimGuid[1]); + } + + //if (flags & UPDATEFLAG_ANIMKITS) + //{ + // if (hasAnimKit1) + // *data << uint16(animKit1); + // if (hasAnimKit2) + // *data << uint16(animKit2); + // if (hasAnimKit3) + // *data << uint16(animKit3); + //} + + if (flags & UPDATEFLAG_TRANSPORT) + *data << uint32(getMSTime()); // Unknown - getMSTime is wrong. } -void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* updateMask, Player* target) const +void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, UpdateMask* updateMask, Player* target) const { if (!target) return; @@ -494,7 +638,11 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* } } - WPAssert(updateMask && updateMask->GetCount() == m_valuesCount); + uint32 valCount = m_valuesCount; + if (GetTypeId() == TYPEID_PLAYER && target != this) + valCount = PLAYER_END_NOT_SELF; + + WPAssert(updateMask && updateMask->GetCount() == valCount); *data << (uint8)updateMask->GetBlockCount(); data->append(updateMask->GetMask(), updateMask->GetLength()); @@ -502,7 +650,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* // 2 specialized loops for speed optimization in non-unit case if (isType(TYPEMASK_UNIT)) // unit (creature/player) case { - for (uint16 index = 0; index < m_valuesCount; ++index) + for (uint16 index = 0; index < valCount; ++index) { if (updateMask->GetBit(index)) { @@ -666,7 +814,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* } else if (isType(TYPEMASK_GAMEOBJECT)) // gameobject case { - for (uint16 index = 0; index < m_valuesCount; ++index) + for (uint16 index = 0; index < valCount; ++index) { if (updateMask->GetBit(index)) { @@ -682,35 +830,28 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* *data << uint16(GO_DYNFLAG_LO_ACTIVATE); else *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE); - *data << uint16(-1); break; case GAMEOBJECT_TYPE_GENERIC: if (target->isGameMaster()) *data << uint16(0); else *data << uint16(GO_DYNFLAG_LO_SPARKLE); - *data << uint16(-1); break; case GAMEOBJECT_TYPE_GOOBER: if (target->isGameMaster()) *data << uint16(GO_DYNFLAG_LO_ACTIVATE); else *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE); - *data << uint16(-1); break; default: - // unknown, not happen. - *data << uint16(0); - *data << uint16(-1); + *data << uint16(0); // unknown, not happen. break; } } else - { - // disable quest object - *data << uint16(0); - *data << uint16(-1); - } + *data << uint16(0); // disable quest object + + *data << uint16(-1); } else if (index == GAMEOBJECT_FLAGS) { @@ -728,7 +869,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask* } else // other objects case (no special index checks) { - for (uint16 index = 0; index < m_valuesCount; ++index) + for (uint16 index = 0; index < valCount; ++index) { if (updateMask->GetBit(index)) { @@ -757,7 +898,7 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons if (iter == data_map.end()) { - std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData())); + std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData(player->GetMapId()))); ASSERT(p.second); iter = p.first; } @@ -854,7 +995,11 @@ void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); - for (uint16 index = 0; index < m_valuesCount; ++index, ++indexes) + uint32 valCount = m_valuesCount; + if (GetTypeId() == TYPEID_PLAYER && target != this) + valCount = PLAYER_END_NOT_SELF; + + for (uint16 index = 0; index < valCount; ++index, ++indexes) if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*indexes && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) updateMask->SetBit(index); } @@ -871,7 +1016,11 @@ void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const GetUpdateFieldData(target, flags, isOwner, isItemOwner, hasSpecialInfo, isPartyMember); - for (uint16 index = 0; index < m_valuesCount; ++index, ++value) + uint32 valCount = m_valuesCount; + if (GetTypeId() == TYPEID_PLAYER && target != this) + valCount = PLAYER_END_NOT_SELF; + + for (uint16 index = 0; index < valCount; ++index, ++value) if (_fieldNotifyFlags & flags[index] || (flags[index] & UF_FLAG_SPECIAL_INFO && hasSpecialInfo) || (*value && IsUpdateFieldVisible(flags[index], isSelf, isOwner, isItemOwner, isPartyMember))) updateMask->SetBit(index); } @@ -1242,7 +1391,7 @@ void MovementInfo::OutDebug() sLog->outInfo(LOG_FILTER_GENERAL, "flags2 %u", flags2); sLog->outInfo(LOG_FILTER_GENERAL, "time %u current time " UI64FMTD "", flags2, uint64(::time(NULL))); sLog->outInfo(LOG_FILTER_GENERAL, "position: `%s`", pos.ToString().c_str()); - if (flags & MOVEMENTFLAG_ONTRANSPORT) + if (t_guid) { sLog->outInfo(LOG_FILTER_GENERAL, "TRANSPORT:"); sLog->outInfo(LOG_FILTER_GENERAL, "guid: " UI64FMTD, t_guid); @@ -2139,6 +2288,8 @@ void WorldObject::BuildMonsterChat(WorldPacket* data, uint8 msgtype, char const* *data << (uint32)(strlen(text)+1); *data << text; *data << (uint8)0; // ChatTag + *data << (float)0.0f; // added in 4.2.0, unk + *data << (uint8)0; // added in 4.2.0, unk } void Unit::BuildHeartBeatMsg(WorldPacket* data) const diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index ab9ea2daea9..3829e2f75f2 100755 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -119,6 +119,62 @@ class Transport; typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType; +//! Structure to ease conversions from single 64 bit integer guid into individual bytes, for packet sending purposes +//! Nuke this out when porting ObjectGuid from MaNGOS, but preserve the per-byte storage +struct ObjectGuid +{ + public: + ObjectGuid() { _data.u64 = 0LL; } + ObjectGuid(uint64 guid) { _data.u64 = guid; } + ObjectGuid(ObjectGuid const& other) { _data.u64 = other._data.u64; } + + uint8& operator[](uint32 index) + { + ASSERT(index < sizeof(uint64)); + +#if TRINITY_ENDIAN == TRINITY_LITTLEENDIAN + return _data.byte[index]; +#else + return _data.byte[7 - index]; +#endif + } + + uint8 const& operator[](uint32 index) const + { + ASSERT(index < sizeof(uint64)); + +#if TRINITY_ENDIAN == TRINITY_LITTLEENDIAN + return _data.byte[index]; +#else + return _data.byte[7 - index]; +#endif + } + + operator uint64() + { + return _data.u64; + } + + ObjectGuid& operator=(uint64 guid) + { + _data.u64 = guid; + return *this; + } + + ObjectGuid& operator=(ObjectGuid const& other) + { + _data.u64 = other._data.u64; + return *this; + } + + private: + union + { + uint64 u64; + uint8 byte[8]; + } _data; +}; + class Object { public: @@ -147,7 +203,6 @@ class Object void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const; void BuildOutOfRangeUpdateBlock(UpdateData* data) const; - void BuildMovementUpdateBlock(UpdateData* data, uint32 flags = 0) const; virtual void DestroyForPlayer(Player* target, bool onDeath = false) const; @@ -307,19 +362,24 @@ class Object void ForceValuesUpdateAtIndex(uint32); Player* ToPlayer() { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return NULL; } - Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return (Player const*)((Player*)this); else return NULL; } + Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player const*>(this); else return NULL; } + Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return NULL; } - Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return (Creature const*)((Creature*)this); else return NULL; } + Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature const*>(this); else return NULL; } + + Unit* ToUnit() { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit*>(this); else return NULL; } + Unit const* ToUnit() const { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit const*>(this); else return NULL; } - Unit* ToUnit() { if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Unit*>(this); else return NULL; } - Unit const* ToUnit() const { if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) return (const Unit*)((Unit*)this); else return NULL; } GameObject* ToGameObject() { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(this); else return NULL; } - GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return (const GameObject*)((GameObject*)this); else return NULL; } + GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject const*>(this); else return NULL; } Corpse* ToCorpse() { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(this); else return NULL; } - Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return (const Corpse*)((Corpse*)this); else return NULL; } - protected: + Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse const*>(this); else return NULL; } + DynamicObject* ToDynObject() { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject*>(this); else return NULL; } + DynamicObject const* ToDynObject() const { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject const*>(this); else return NULL; } + + protected: Object(); void _InitValues(); @@ -474,25 +534,26 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& st struct MovementInfo { // common - uint64 guid; - uint32 flags; - uint16 flags2; + uint64 guid; + uint32 flags; + uint16 flags2; Position pos; - uint32 time; + uint32 time; // transport - uint64 t_guid; + uint64 t_guid; Position t_pos; - uint32 t_time; - uint32 t_time2; - int8 t_seat; + int8 t_seat; + uint32 t_time; + uint32 t_time2; + uint32 t_time3; // swimming/flying - float pitch; + float pitch; // falling - uint32 fallTime; + uint32 fallTime; // jumping - float j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed; + float j_zspeed, j_cosAngle, j_sinAngle, j_xyspeed; // spline - float splineElevation; + float splineElevation; MovementInfo() { @@ -500,7 +561,7 @@ struct MovementInfo guid = 0; flags = 0; flags2 = 0; - time = t_time = t_time2 = fallTime = 0; + time = t_time = t_time2 = t_time3 = fallTime = 0; splineElevation = 0; pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = 0.0f; t_guid = 0; diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index c227d081d8b..9fd4279a79c 100755 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -33,18 +33,19 @@ enum HighGuid { - 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_VEHICLE = 0xF150, // blizz F550 - HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100 - HIGHGUID_CORPSE = 0xF101, // blizz F100 - HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) - HIGHGUID_GROUP = 0x1F50, + HIGHGUID_ITEM = 0x400, // blizz 4000 + HIGHGUID_CONTAINER = 0x400, // blizz 4000 + HIGHGUID_PLAYER = 0x000, // blizz 0000 + HIGHGUID_GAMEOBJECT = 0xF11, // blizz F110 + HIGHGUID_TRANSPORT = 0xF12, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) + HIGHGUID_UNIT = 0xF13, // blizz F130 + HIGHGUID_PET = 0xF14, // blizz F140 + HIGHGUID_VEHICLE = 0xF15, // blizz F550 + HIGHGUID_DYNAMICOBJECT = 0xF10, // blizz F100 + HIGHGUID_CORPSE = 0xF101, // blizz F100 + HIGHGUID_MO_TRANSPORT = 0x1FC, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) + HIGHGUID_GROUP = 0x1F5, + HIGHGUID_GUILD = 0x1FF5, // new 4.x }; #define IS_EMPTY_GUID(Guid) (Guid == 0) @@ -64,19 +65,25 @@ enum HighGuid #define IS_TRANSPORT(Guid) (GUID_HIPART(Guid) == HIGHGUID_TRANSPORT) #define IS_MO_TRANSPORT(Guid) (GUID_HIPART(Guid) == HIGHGUID_MO_TRANSPORT) #define IS_GROUP(Guid) (GUID_HIPART(Guid) == HIGHGUID_GROUP) +#define IS_GUILD(Guid) (GUID_HIPART(Guid) == HIGHGUID_GUILD) // 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 MAKE_NEW_GUID(l, e, h) uint64(uint64(l) | (uint64(e) << 32) | (uint64(h) << ((h == HIGHGUID_GUILD || h == HIGHGUID_CORPSE) ? 48 : 52))) -#define GUID_HIPART(x) (uint32)((uint64(x) >> 48) & 0x0000FFFF) +//#define GUID_HIPART(x) (uint32)((uint64(x) >> 52)) & 0x0000FFFF) +inline uint32 GUID_HIPART(uint64 guid) +{ + uint32 t = ((uint64(guid) >> 48) & 0x0000FFFF); + return (t == HIGHGUID_GUILD || t == HIGHGUID_CORPSE) ? t : ((uint32(t) >> 4) & 0x00000FFF); +} // We have different low and middle part size for different guid types #define _GUID_ENPART_2(x) 0 -#define _GUID_ENPART_3(x) (uint32)((uint64(x) >> 24) & UI64LIT(0x0000000000FFFFFF)) +#define _GUID_ENPART_3(x) (uint32)((uint64(x) >> 32) & UI64LIT(0x00000000000FFFFF)) #define _GUID_LOPART_2(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF)) -#define _GUID_LOPART_3(x) (uint32)(uint64(x) & UI64LIT(0x0000000000FFFFFF)) +#define _GUID_LOPART_3(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF)) inline bool IsGuidHaveEnPart(uint64 guid) { @@ -87,6 +94,7 @@ inline bool IsGuidHaveEnPart(uint64 guid) case HIGHGUID_DYNAMICOBJECT: case HIGHGUID_CORPSE: case HIGHGUID_GROUP: + case HIGHGUID_GUILD: return false; case HIGHGUID_GAMEOBJECT: case HIGHGUID_TRANSPORT: @@ -117,6 +125,7 @@ inline char const* GetLogNameForGuid(uint64 guid) case HIGHGUID_CORPSE: return "corpse"; case HIGHGUID_MO_TRANSPORT: return "mo_transport"; case HIGHGUID_GROUP: return "group"; + case HIGHGUID_GUILD: return "guild"; default: return "<unknown>"; } diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp index 45464f19083..afe43ca245c 100755..100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp @@ -25,7 +25,7 @@ #include "World.h" #include "zlib.h" -UpdateData::UpdateData() : m_blockCount(0) +UpdateData::UpdateData(uint16 map) : m_map(map), m_blockCount(0) { } @@ -45,104 +45,24 @@ void UpdateData::AddUpdateBlock(const ByteBuffer &block) ++m_blockCount; } -void UpdateData::Compress(void* dst, uint32 *dst_size, void* src, int src_size) -{ - z_stream c_stream; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - // default Z_BEST_SPEED (1) - int z_res = deflateInit(&c_stream, sWorld->getIntConfig(CONFIG_COMPRESSION)); - if (z_res != Z_OK) - { - sLog->outError(LOG_FILTER_GENERAL, "Can't compress update packet (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res)); - *dst_size = 0; - return; - } - - c_stream.next_out = (Bytef*)dst; - c_stream.avail_out = *dst_size; - c_stream.next_in = (Bytef*)src; - c_stream.avail_in = (uInt)src_size; - - z_res = deflate(&c_stream, Z_NO_FLUSH); - if (z_res != Z_OK) - { - sLog->outError(LOG_FILTER_GENERAL, "Can't compress update packet (zlib: deflate) Error code: %i (%s)", z_res, zError(z_res)); - *dst_size = 0; - return; - } - - if (c_stream.avail_in != 0) - { - sLog->outError(LOG_FILTER_GENERAL, "Can't compress update packet (zlib: deflate not greedy)"); - *dst_size = 0; - return; - } - - z_res = deflate(&c_stream, Z_FINISH); - if (z_res != Z_STREAM_END) - { - sLog->outError(LOG_FILTER_GENERAL, "Can't compress update packet (zlib: deflate should report Z_STREAM_END instead %i (%s)", z_res, zError(z_res)); - *dst_size = 0; - return; - } - - z_res = deflateEnd(&c_stream); - if (z_res != Z_OK) - { - sLog->outError(LOG_FILTER_GENERAL, "Can't compress update packet (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res)); - *dst_size = 0; - return; - } - - *dst_size = c_stream.total_out; -} - bool UpdateData::BuildPacket(WorldPacket* packet) { ASSERT(packet->empty()); // shouldn't happen + packet->Initialize(SMSG_UPDATE_OBJECT, 2 + 4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos()); - ByteBuffer buf(4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos()); - - buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount); + *packet << uint16(m_map); + *packet << uint32(m_blockCount + (m_outOfRangeGUIDs.empty() ? 0 : 1)); if (!m_outOfRangeGUIDs.empty()) { - buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS; - buf << (uint32) m_outOfRangeGUIDs.size(); + *packet << uint8(UPDATETYPE_OUT_OF_RANGE_OBJECTS); + *packet << uint32(m_outOfRangeGUIDs.size()); for (std::set<uint64>::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i) - { - buf.appendPackGUID(*i); - } - } - - buf.append(m_data); - - size_t pSize = buf.wpos(); // use real used data size - - if (pSize > 100) // compress large packets - { - uint32 destsize = compressBound(pSize); - packet->resize(destsize + sizeof(uint32)); - - packet->put<uint32>(0, pSize); - Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize); - if (destsize == 0) - return false; - - packet->resize(destsize + sizeof(uint32)); - packet->SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT); - } - else // send small packets without compression - { - packet->append(buf); - packet->SetOpcode(SMSG_UPDATE_OBJECT); + packet->appendPackGUID(*i); } + packet->append(m_data); return true; } @@ -151,5 +71,6 @@ void UpdateData::Clear() m_data.clear(); m_outOfRangeGUIDs.clear(); m_blockCount = 0; + m_map = 0; } diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h index ff649b7cb2f..27a42be5c2d 100755 --- a/src/server/game/Entities/Object/Updates/UpdateData.h +++ b/src/server/game/Entities/Object/Updates/UpdateData.h @@ -25,32 +25,34 @@ class WorldPacket; enum OBJECT_UPDATE_TYPE { UPDATETYPE_VALUES = 0, - UPDATETYPE_MOVEMENT = 1, - UPDATETYPE_CREATE_OBJECT = 2, - UPDATETYPE_CREATE_OBJECT2 = 3, - UPDATETYPE_OUT_OF_RANGE_OBJECTS = 4, - UPDATETYPE_NEAR_OBJECTS = 5 + UPDATETYPE_CREATE_OBJECT = 1, + UPDATETYPE_CREATE_OBJECT2 = 2, + UPDATETYPE_OUT_OF_RANGE_OBJECTS = 3, }; enum OBJECT_UPDATE_FLAGS { - UPDATEFLAG_NONE = 0x0000, - UPDATEFLAG_SELF = 0x0001, - UPDATEFLAG_TRANSPORT = 0x0002, - UPDATEFLAG_HAS_TARGET = 0x0004, - UPDATEFLAG_UNKNOWN = 0x0008, - UPDATEFLAG_LOWGUID = 0x0010, - UPDATEFLAG_LIVING = 0x0020, - UPDATEFLAG_STATIONARY_POSITION = 0x0040, - UPDATEFLAG_VEHICLE = 0x0080, - UPDATEFLAG_POSITION = 0x0100, - UPDATEFLAG_ROTATION = 0x0200 + UPDATEFLAG_NONE = 0x0000, + UPDATEFLAG_SELF = 0x0001, + UPDATEFLAG_TRANSPORT = 0x0002, + UPDATEFLAG_HAS_TARGET = 0x0004, + UPDATEFLAG_UNKNOWN = 0x0008, + UPDATEFLAG_LOWGUID = 0x0010, + UPDATEFLAG_LIVING = 0x0020, + UPDATEFLAG_STATIONARY_POSITION = 0x0040, + UPDATEFLAG_VEHICLE = 0x0080, + UPDATEFLAG_GO_TRANSPORT_POSITION = 0x0100, + UPDATEFLAG_ROTATION = 0x0200, + UPDATEFLAG_UNK3 = 0x0400, + UPDATEFLAG_ANIMKITS = 0x0800, + UPDATEFLAG_UNK5 = 0x1000, + UPDATEFLAG_UNK6 = 0x2000, }; class UpdateData { public: - UpdateData(); + UpdateData(uint16 map); void AddOutOfRangeGUID(std::set<uint64>& guids); void AddOutOfRangeGUID(uint64 guid); @@ -62,11 +64,10 @@ class UpdateData std::set<uint64> const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; } protected: + uint16 m_map; uint32 m_blockCount; std::set<uint64> m_outOfRangeGUIDs; ByteBuffer m_data; - - void Compress(void* dst, uint32 *dst_size, void* src, int src_size); }; #endif diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp index 95bdaef221b..2c15487180c 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp @@ -21,6 +21,8 @@ uint32 ItemUpdateFieldFlags[CONTAINER_END] = { UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1 UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X @@ -77,12 +79,20 @@ uint32 ItemUpdateFieldFlags[CONTAINER_END] = UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_12_1 UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_12_1+1 UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_12_3 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_13_1 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_13_1+1 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_13_3 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_14_1 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_14_1+1 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_14_3 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_15_1 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_15_1+1 + UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_15_3 UF_FLAG_PUBLIC, // ITEM_FIELD_PROPERTY_SEED UF_FLAG_PUBLIC, // ITEM_FIELD_RANDOM_PROPERTIES_ID UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER, // ITEM_FIELD_DURABILITY UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER, // ITEM_FIELD_MAXDURABILITY UF_FLAG_PUBLIC, // ITEM_FIELD_CREATE_PLAYED_TIME - UF_FLAG_NONE, // ITEM_FIELD_PAD UF_FLAG_PUBLIC, // CONTAINER_FIELD_NUM_SLOTS UF_FLAG_NONE, // CONTAINER_ALIGN_PAD UF_FLAG_PUBLIC, // CONTAINER_FIELD_SLOT_1 @@ -163,6 +173,8 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = { UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1 UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X @@ -191,30 +203,22 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PUBLIC, // UNIT_FIELD_POWER3 UF_FLAG_PUBLIC, // UNIT_FIELD_POWER4 UF_FLAG_PUBLIC, // UNIT_FIELD_POWER5 - UF_FLAG_PUBLIC, // UNIT_FIELD_POWER6 - UF_FLAG_PUBLIC, // UNIT_FIELD_POWER7 UF_FLAG_PUBLIC, // UNIT_FIELD_MAXHEALTH UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER1 UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER2 UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER3 UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER4 UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER5 - UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER6 - UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER7 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+1 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+2 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+3 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+4 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+5 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+6 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+1 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+2 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+3 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+4 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+5 - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+6 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+1 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+2 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+3 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+4 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+1 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+2 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+3 + UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+4 UF_FLAG_PUBLIC, // UNIT_FIELD_LEVEL UF_FLAG_PUBLIC, // UNIT_FIELD_FACTIONTEMPLATE UF_FLAG_PUBLIC, // UNIT_VIRTUAL_ITEM_SLOT_ID @@ -228,7 +232,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // UNIT_FIELD_RANGEDATTACKTIME UF_FLAG_PUBLIC, // UNIT_FIELD_BOUNDINGRADIUS UF_FLAG_PUBLIC, // UNIT_FIELD_COMBATREACH - UF_FLAG_PUBLIC, // UNIT_FIELD_DISPLAYID + UF_FLAG_DYNAMIC, // UNIT_FIELD_DISPLAYID UF_FLAG_PUBLIC, // UNIT_FIELD_NATIVEDISPLAYID UF_FLAG_PUBLIC, // UNIT_FIELD_MOUNTDISPLAYID UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_SPECIAL_INFO, // UNIT_FIELD_MINDAMAGE @@ -242,6 +246,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_OWNER, // UNIT_FIELD_PETNEXTLEVELEXP UF_FLAG_DYNAMIC, // UNIT_DYNAMIC_FLAGS UF_FLAG_PUBLIC, // UNIT_MOD_CAST_SPEED + UF_FLAG_PUBLIC, // UNIT_MOD_CAST_HASTE UF_FLAG_PUBLIC, // UNIT_CREATED_BY_SPELL UF_FLAG_DYNAMIC, // UNIT_NPC_FLAGS UF_FLAG_PUBLIC, // UNIT_NPC_EMOTESTATE @@ -285,10 +290,12 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_BASE_HEALTH UF_FLAG_PUBLIC, // UNIT_FIELD_BYTES_2 UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MODS + UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MOD_POS + UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MOD_NEG UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MULTIPLIER UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER - UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MODS + UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS + UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_MINRANGEDDAMAGE UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_MAXRANGEDDAMAGE @@ -308,142 +315,269 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_COST_MULTIPLIER+6 UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_MAXHEALTHMODIFIER UF_FLAG_PUBLIC, // UNIT_FIELD_HOVERHEIGHT + UF_FLAG_PUBLIC, // UNIT_FIELD_MAXITEMLEVEL UF_FLAG_NONE, // UNIT_FIELD_PADDING UF_FLAG_PUBLIC, // PLAYER_DUEL_ARBITER UF_FLAG_PUBLIC, // PLAYER_DUEL_ARBITER+1 UF_FLAG_PUBLIC, // PLAYER_FLAGS - UF_FLAG_PUBLIC, // PLAYER_GUILDID UF_FLAG_PUBLIC, // PLAYER_GUILDRANK + UF_FLAG_PUBLIC, // PLAYER_GUILDDELETE_DATE + UF_FLAG_PUBLIC, // PLAYER_GUILDLEVEL UF_FLAG_PUBLIC, // PLAYER_BYTES UF_FLAG_PUBLIC, // PLAYER_BYTES_2 UF_FLAG_PUBLIC, // PLAYER_BYTES_3 UF_FLAG_PUBLIC, // PLAYER_DUEL_TEAM UF_FLAG_PUBLIC, // PLAYER_GUILD_TIMESTAMP UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_4 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_4 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_5 UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_2 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_3 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_3+1 - UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_5 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_2 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_3 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_3+1 + UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_5 UF_FLAG_PUBLIC, // PLAYER_VISIBLE_ITEM_1_ENTRYID UF_FLAG_PUBLIC, // PLAYER_VISIBLE_ITEM_1_ENCHANTMENT UF_FLAG_PUBLIC, // PLAYER_VISIBLE_ITEM_2_ENTRYID @@ -657,134 +791,6 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_VENDORBUYBACK_SLOT_1+21 UF_FLAG_PRIVATE, // PLAYER_FIELD_VENDORBUYBACK_SLOT_1+22 UF_FLAG_PRIVATE, // PLAYER_FIELD_VENDORBUYBACK_SLOT_1+23 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+1 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+2 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+3 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+4 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+5 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+6 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+7 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+8 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+9 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+10 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+11 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+12 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+13 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+14 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+15 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+16 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+17 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+18 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+19 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+20 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+21 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+22 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+23 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+24 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+25 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+26 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+27 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+28 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+29 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+30 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+31 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+32 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+33 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+34 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+35 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+36 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+37 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+38 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+39 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+40 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+41 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+42 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+43 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+44 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+45 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+46 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+47 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+48 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+49 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+50 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+51 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+52 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+53 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+54 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+55 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+56 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+57 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+58 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+59 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+60 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+61 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+62 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+63 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+1 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+2 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+3 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+4 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+5 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+6 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+7 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+8 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+9 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+10 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+11 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+12 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+13 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+14 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+15 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+16 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+17 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+18 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+19 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+20 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+21 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+22 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+23 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+24 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+25 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+26 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+27 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+28 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+29 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+30 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+31 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+32 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+33 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+34 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+35 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+36 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+37 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+38 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+39 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+40 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+41 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+42 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+43 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+44 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+45 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+46 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+47 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+48 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+49 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+50 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+51 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+52 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+53 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+54 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+55 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+56 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+57 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+58 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+59 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+60 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+61 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+62 - UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+63 UF_FLAG_PRIVATE, // PLAYER_FARSIGHT UF_FLAG_PRIVATE, // PLAYER_FARSIGHT+1 UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES @@ -793,403 +799,402 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES1+1 UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES2 UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES2+1 - UF_FLAG_PRIVATE, // PLAYER_FIELD_KNOWN_CURRENCIES - UF_FLAG_PRIVATE, // PLAYER_FIELD_KNOWN_CURRENCIES+1 + UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES3 + UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES3+1 UF_FLAG_PRIVATE, // PLAYER_XP UF_FLAG_PRIVATE, // PLAYER_NEXT_LEVEL_XP - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+1 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+2 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+3 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+4 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+5 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+6 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+7 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+8 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+9 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+10 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+11 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+12 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+13 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+14 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+15 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+16 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+17 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+18 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+19 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+20 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+21 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+22 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+23 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+24 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+25 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+26 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+27 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+28 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+29 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+30 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+31 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+32 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+33 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+34 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+35 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+36 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+37 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+38 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+39 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+40 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+41 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+42 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+43 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+44 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+45 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+46 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+47 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+48 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+49 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+50 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+51 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+52 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+53 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+54 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+55 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+56 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+57 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+58 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+59 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+60 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+61 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+62 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+63 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+64 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+65 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+66 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+67 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+68 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+69 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+70 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+71 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+72 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+73 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+74 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+75 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+76 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+77 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+78 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+79 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+80 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+81 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+82 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+83 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+84 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+85 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+86 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+87 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+88 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+89 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+90 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+91 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+92 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+93 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+94 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+95 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+96 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+97 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+98 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+99 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+100 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+101 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+102 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+103 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+104 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+105 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+106 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+107 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+108 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+109 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+110 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+111 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+112 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+113 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+114 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+115 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+116 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+117 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+118 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+119 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+120 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+121 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+122 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+123 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+124 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+125 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+126 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+127 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+128 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+129 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+130 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+131 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+132 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+133 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+134 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+135 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+136 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+137 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+138 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+139 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+140 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+141 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+142 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+143 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+144 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+145 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+146 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+147 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+148 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+149 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+150 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+151 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+152 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+153 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+154 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+155 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+156 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+157 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+158 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+159 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+160 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+161 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+162 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+163 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+164 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+165 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+166 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+167 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+168 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+169 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+170 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+171 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+172 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+173 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+174 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+175 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+176 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+177 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+178 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+179 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+180 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+181 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+182 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+183 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+184 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+185 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+186 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+187 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+188 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+189 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+190 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+191 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+192 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+193 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+194 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+195 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+196 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+197 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+198 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+199 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+200 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+201 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+202 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+203 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+204 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+205 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+206 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+207 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+208 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+209 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+210 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+211 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+212 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+213 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+214 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+215 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+216 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+217 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+218 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+219 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+220 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+221 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+222 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+223 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+224 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+225 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+226 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+227 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+228 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+229 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+230 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+231 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+232 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+233 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+234 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+235 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+236 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+237 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+238 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+239 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+240 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+241 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+242 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+243 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+244 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+245 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+246 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+247 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+248 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+249 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+250 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+251 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+252 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+253 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+254 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+255 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+256 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+257 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+258 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+259 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+260 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+261 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+262 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+263 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+264 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+265 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+266 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+267 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+268 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+269 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+270 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+271 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+272 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+273 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+274 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+275 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+276 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+277 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+278 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+279 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+280 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+281 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+282 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+283 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+284 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+285 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+286 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+287 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+288 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+289 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+290 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+291 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+292 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+293 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+294 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+295 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+296 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+297 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+298 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+299 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+300 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+301 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+302 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+303 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+304 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+305 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+306 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+307 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+308 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+309 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+310 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+311 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+312 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+313 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+314 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+315 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+316 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+317 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+318 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+319 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+320 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+321 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+322 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+323 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+324 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+325 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+326 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+327 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+328 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+329 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+330 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+331 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+332 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+333 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+334 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+335 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+336 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+337 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+338 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+339 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+340 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+341 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+342 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+343 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+344 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+345 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+346 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+347 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+348 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+349 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+350 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+351 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+352 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+353 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+354 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+355 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+356 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+357 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+358 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+359 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+360 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+361 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+362 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+363 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+364 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+365 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+366 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+367 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+368 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+369 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+370 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+371 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+372 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+373 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+374 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+375 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+376 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+377 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+378 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+379 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+380 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+381 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+382 - UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+383 - UF_FLAG_PRIVATE, // PLAYER_CHARACTER_POINTS1 - UF_FLAG_PRIVATE, // PLAYER_CHARACTER_POINTS2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+1 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+3 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+4 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+5 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+6 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+7 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+8 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+9 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+10 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+11 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+12 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+13 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+14 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+15 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+16 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+17 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+18 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+19 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+20 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+21 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+22 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+23 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+24 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+25 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+26 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+27 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+28 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+29 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+30 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+31 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+32 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+33 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+34 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+35 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+36 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+37 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+38 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+39 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+40 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+41 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+42 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+43 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+44 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+45 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+46 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+47 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+48 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+49 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+50 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+51 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+52 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+53 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+54 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+55 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+56 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+57 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+58 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+59 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+60 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+61 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+62 + UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+63 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+1 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+3 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+4 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+5 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+6 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+7 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+8 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+9 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+10 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+11 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+12 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+13 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+14 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+15 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+16 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+17 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+18 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+19 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+20 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+21 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+22 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+23 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+24 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+25 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+26 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+27 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+28 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+29 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+30 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+31 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+32 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+33 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+34 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+35 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+36 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+37 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+38 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+39 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+40 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+41 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+42 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+43 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+44 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+45 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+46 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+47 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+48 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+49 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+50 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+51 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+52 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+53 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+54 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+55 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+56 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+57 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+58 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+59 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+60 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+61 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+62 + UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+63 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+1 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+3 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+4 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+5 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+6 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+7 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+8 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+9 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+10 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+11 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+12 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+13 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+14 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+15 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+16 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+17 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+18 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+19 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+20 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+21 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+22 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+23 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+24 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+25 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+26 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+27 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+28 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+29 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+30 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+31 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+32 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+33 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+34 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+35 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+36 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+37 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+38 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+39 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+40 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+41 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+42 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+43 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+44 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+45 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+46 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+47 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+48 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+49 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+50 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+51 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+52 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+53 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+54 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+55 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+56 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+57 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+58 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+59 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+60 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+61 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+62 + UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+63 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+1 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+3 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+4 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+5 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+6 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+7 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+8 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+9 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+10 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+11 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+12 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+13 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+14 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+15 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+16 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+17 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+18 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+19 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+20 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+21 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+22 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+23 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+24 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+25 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+26 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+27 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+28 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+29 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+30 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+31 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+32 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+33 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+34 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+35 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+36 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+37 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+38 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+39 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+40 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+41 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+42 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+43 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+44 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+45 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+46 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+47 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+48 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+49 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+50 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+51 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+52 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+53 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+54 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+55 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+56 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+57 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+58 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+59 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+60 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+61 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+62 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+63 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+1 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+3 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+4 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+5 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+6 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+7 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+8 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+9 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+10 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+11 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+12 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+13 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+14 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+15 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+16 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+17 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+18 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+19 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+20 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+21 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+22 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+23 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+24 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+25 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+26 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+27 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+28 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+29 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+30 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+31 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+32 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+33 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+34 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+35 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+36 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+37 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+38 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+39 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+40 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+41 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+42 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+43 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+44 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+45 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+46 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+47 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+48 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+49 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+50 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+51 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+52 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+53 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+54 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+55 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+56 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+57 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+58 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+59 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+60 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+61 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+62 + UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+63 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+1 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+2 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+3 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+4 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+5 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+6 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+7 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+8 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+9 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+10 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+11 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+12 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+13 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+14 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+15 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+16 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+17 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+18 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+19 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+20 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+21 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+22 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+23 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+24 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+25 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+26 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+27 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+28 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+29 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+30 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+31 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+32 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+33 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+34 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+35 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+36 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+37 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+38 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+39 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+40 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+41 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+42 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+43 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+44 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+45 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+46 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+47 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+48 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+49 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+50 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+51 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+52 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+53 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+54 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+55 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+56 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+57 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+58 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+59 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+60 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+61 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+62 + UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+63 + UF_FLAG_PRIVATE, // PLAYER_CHARACTER_POINTS UF_FLAG_PRIVATE, // PLAYER_TRACK_CREATURES UF_FLAG_PRIVATE, // PLAYER_TRACK_RESOURCES + UF_FLAG_PRIVATE, // PLAYER_EXPERTISE + UF_FLAG_PRIVATE, // PLAYER_OFFHAND_EXPERTISE UF_FLAG_PRIVATE, // PLAYER_BLOCK_PERCENTAGE UF_FLAG_PRIVATE, // PLAYER_DODGE_PERCENTAGE UF_FLAG_PRIVATE, // PLAYER_PARRY_PERCENTAGE - UF_FLAG_PRIVATE, // PLAYER_EXPERTISE - UF_FLAG_PRIVATE, // PLAYER_OFFHAND_EXPERTISE UF_FLAG_PRIVATE, // PLAYER_CRIT_PERCENTAGE UF_FLAG_PRIVATE, // PLAYER_RANGED_CRIT_PERCENTAGE UF_FLAG_PRIVATE, // PLAYER_OFFHAND_CRIT_PERCENTAGE @@ -1202,6 +1207,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_SPELL_CRIT_PERCENTAGE1+6 UF_FLAG_PRIVATE, // PLAYER_SHIELD_BLOCK UF_FLAG_PRIVATE, // PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE + UF_FLAG_PRIVATE, // PLAYER_MASTERY UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1 UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+1 UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+2 @@ -1330,8 +1336,37 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+125 UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+126 UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+127 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+128 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+129 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+130 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+131 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+132 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+133 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+134 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+135 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+136 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+137 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+138 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+139 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+140 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+141 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+142 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+143 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+144 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+145 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+146 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+147 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+148 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+149 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+150 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+151 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+152 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+153 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+154 + UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+155 UF_FLAG_PRIVATE, // PLAYER_REST_STATE_EXPERIENCE UF_FLAG_PRIVATE, // PLAYER_FIELD_COINAGE + UF_FLAG_PRIVATE, // PLAYER_FIELD_COINAGE+1 UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_DAMAGE_DONE_POS UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_DAMAGE_DONE_POS+1 UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_DAMAGE_DONE_POS+2 @@ -1356,10 +1391,14 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HEALING_DONE_POS UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HEALING_PCT UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HEALING_DONE_PCT + UF_FLAG_PRIVATE, // PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS + UF_FLAG_PRIVATE, // PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS+1 + UF_FLAG_PRIVATE, // PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS+2 + UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_SPELL_POWER_PCT + UF_FLAG_PRIVATE, // PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_TARGET_RESISTANCE UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE UF_FLAG_PRIVATE, // PLAYER_FIELD_BYTES - UF_FLAG_PRIVATE, // PLAYER_AMMO_ID UF_FLAG_PRIVATE, // PLAYER_SELF_RES_SPELL UF_FLAG_PRIVATE, // PLAYER_FIELD_PVP_MEDALS UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_PRICE_1 @@ -1387,8 +1426,6 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_TIMESTAMP_1+10 UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_TIMESTAMP_1+11 UF_FLAG_PRIVATE, // PLAYER_FIELD_KILLS - UF_FLAG_PRIVATE, // PLAYER_FIELD_TODAY_CONTRIBUTION - UF_FLAG_PRIVATE, // PLAYER_FIELD_YESTERDAY_CONTRIBUTION UF_FLAG_PRIVATE, // PLAYER_FIELD_LIFETIME_HONORBALE_KILLS UF_FLAG_PRIVATE, // PLAYER_FIELD_BYTES2 UF_FLAG_PRIVATE, // PLAYER_FIELD_WATCHED_FACTION_INDEX @@ -1417,6 +1454,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+22 UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+23 UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+24 + UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+25 UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1 UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+1 UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+2 @@ -1438,8 +1476,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+18 UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+19 UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+20 - UF_FLAG_PRIVATE, // PLAYER_FIELD_HONOR_CURRENCY - UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_CURRENCY + UF_FLAG_PRIVATE, // PLAYER_FIELD_BATTLEGROUND_RATING UF_FLAG_PRIVATE, // PLAYER_FIELD_MAX_LEVEL UF_FLAG_PRIVATE, // PLAYER_FIELD_DAILY_QUESTS_1 UF_FLAG_PRIVATE, // PLAYER_FIELD_DAILY_QUESTS_1+1 @@ -1479,20 +1516,53 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+3 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+4 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+5 + UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+6 + UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+7 + UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+8 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+1 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+2 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+3 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+4 UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+5 + UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+6 + UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+7 + UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+8 UF_FLAG_PRIVATE, // PLAYER_GLYPHS_ENABLED UF_FLAG_PRIVATE, // PLAYER_PET_SPELL_POWER + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+1 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+2 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+3 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+4 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+5 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+6 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+7 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+1 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+2 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+3 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+4 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+5 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+6 + UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+7 + UF_FLAG_PRIVATE, // PLAYER_PROFESSION_SKILL_LINE_1 + UF_FLAG_PRIVATE, // PLAYER_PROFESSION_SKILL_LINE_1+1 + UF_FLAG_PRIVATE, // PLAYER_FIELD_UI_HIT_MODIFIER + UF_FLAG_PRIVATE, // PLAYER_FIELD_UI_SPELL_HIT_MODIFIER + UF_FLAG_PRIVATE, // PLAYER_FIELD_HOME_REALM_TIME_OFFSET + UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HASTE + UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_RANGED_HASTE + UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_PET_HASTE + UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HASTE_REGEN }; uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END] = { UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1 UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X @@ -1515,13 +1585,15 @@ uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END] = { UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1 UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X UF_FLAG_NONE, // OBJECT_FIELD_PADDING UF_FLAG_PUBLIC, // DYNAMICOBJECT_CASTER UF_FLAG_PUBLIC, // DYNAMICOBJECT_CASTER+1 - UF_FLAG_PUBLIC, // DYNAMICOBJECT_BYTES + UF_FLAG_DYNAMIC, // DYNAMICOBJECT_BYTES UF_FLAG_PUBLIC, // DYNAMICOBJECT_SPELLID UF_FLAG_PUBLIC, // DYNAMICOBJECT_RADIUS UF_FLAG_PUBLIC, // DYNAMICOBJECT_CASTTIME @@ -1531,6 +1603,8 @@ uint32 CorpseUpdateFieldFlags[CORPSE_END] = { UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1 UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X @@ -1561,8 +1635,24 @@ uint32 CorpseUpdateFieldFlags[CORPSE_END] = UF_FLAG_PUBLIC, // CORPSE_FIELD_ITEM+18 UF_FLAG_PUBLIC, // CORPSE_FIELD_BYTES_1 UF_FLAG_PUBLIC, // CORPSE_FIELD_BYTES_2 - UF_FLAG_PUBLIC, // CORPSE_FIELD_GUILD UF_FLAG_PUBLIC, // CORPSE_FIELD_FLAGS UF_FLAG_DYNAMIC, // CORPSE_FIELD_DYNAMIC_FLAGS - UF_FLAG_NONE, // CORPSE_FIELD_PAD +}; + +uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END] = +{ + UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID + UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA + UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1 + UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE + UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY + UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X + UF_FLAG_NONE, // OBJECT_FIELD_PADDING + UF_FLAG_PUBLIC, // AREATRIGGER_SPELLID + UF_FLAG_PUBLIC, // AREATRIGGER_SPELLVISUALID + UF_FLAG_PUBLIC, // AREATRIGGER_DURATION + UF_FLAG_PUBLIC, // AREATRIGGER_FINAL_POS + UF_FLAG_PUBLIC, // AREATRIGGER_FINAL_POS+1 + UF_FLAG_PUBLIC, // AREATRIGGER_FINAL_POS+2 }; diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h index 71b3f0cd4aa..5a4186c9894 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h +++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h @@ -40,5 +40,6 @@ extern uint32 UnitUpdateFieldFlags[PLAYER_END]; extern uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END]; extern uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END]; extern uint32 CorpseUpdateFieldFlags[CORPSE_END]; +extern uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END]; #endif // _UPDATEFIELDFLAGS_H diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 825bda98ae6..3602cbea648 100755 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -16,418 +16,550 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _UPDATEFIELDS_AUTO_H -#define _UPDATEFIELDS_AUTO_H +#ifndef _UPDATEFIELDS_H +#define _UPDATEFIELDS_H -// Auto generated for version 3, 3, 5, 12340 +// Auto generated for version 4, 3, 4, 15595 enum EObjectFields { - OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC - OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC - OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC - OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE - OBJECT_END = 0x0006, + OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + OBJECT_FIELD_DATA = 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + OBJECT_FIELD_TYPE = 0x0004, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + OBJECT_FIELD_ENTRY = 0x0005, // Size: 1, Type: INT, Flags: PUBLIC + OBJECT_FIELD_SCALE_X = 0x0006, // Size: 1, Type: FLOAT, Flags: PUBLIC + OBJECT_FIELD_PADDING = 0x0007, // Size: 1, Type: INT, Flags: NONE + OBJECT_END = 0x0008, }; enum EItemFields { - ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC - ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC - ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC - ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC - ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_DURABILITY = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER - ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: PUBLIC - ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE - ITEM_END = OBJECT_END + 0x003A, + ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC + ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_13_1 = OBJECT_END + 0x0034, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_13_3 = OBJECT_END + 0x0036, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_14_1 = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_14_3 = OBJECT_END + 0x0039, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_15_1 = OBJECT_END + 0x003A, // Size: 2, Type: INT, Flags: PUBLIC + ITEM_FIELD_ENCHANTMENT_15_3 = OBJECT_END + 0x003C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_FIELD_DURABILITY = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0040, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER + ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0041, // Size: 1, Type: INT, Flags: PUBLIC + ITEM_END = OBJECT_END + 0x0042, }; enum EContainerFields { - CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC - CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE - CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC - CONTAINER_END = ITEM_END + 0x004A, + CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC + CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE + CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC + CONTAINER_END = ITEM_END + 0x004A, }; enum EUnitFields { - UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE - UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC - UNIT_CHANNEL_SPELL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_HEALTH = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER1 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER2 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER3 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER4 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER5 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER6 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER7 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0021, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0022, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0029, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_LEVEL = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0032, // Size: 3, Type: INT, Flags: PUBLIC - UNIT_FIELD_FLAGS = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_AURASTATE = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0038, // Size: 2, Type: INT, Flags: PUBLIC - UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x003A, // Size: 1, Type: INT, Flags: PRIVATE - UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003C, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0043, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER - UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: OWNER - UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: DYNAMIC - UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC - UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER - UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC - UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC - UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER - UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC - UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE - UNIT_END = OBJECT_END + 0x008E, + UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE + UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC + UNIT_CHANNEL_SPELL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_HEALTH = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER1 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER2 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER3 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER4 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER5 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x001E, // Size: 5, Type: FLOAT, Flags: PRIVATE, OWNER, UNUSED2 + UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0023, // Size: 5, Type: FLOAT, Flags: PRIVATE, OWNER, UNUSED2 + UNIT_FIELD_LEVEL = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x002A, // Size: 3, Type: INT, Flags: PUBLIC + UNIT_FIELD_FLAGS = OBJECT_END + 0x002D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x002E, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_AURASTATE = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0030, // Size: 2, Type: INT, Flags: PUBLIC + UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PRIVATE + UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0033, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0034, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0038, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0039, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_BYTES_1 = OBJECT_END + 0x003C, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_PETNUMBER = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: OWNER + UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0040, // Size: 1, Type: INT, Flags: OWNER + UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0041, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_MOD_CAST_SPEED = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_MOD_CAST_HASTE = OBJECT_END + 0x0043, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_CREATED_BY_SPELL = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_NPC_FLAGS = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: DYNAMIC + UNIT_NPC_EMOTESTATE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_STAT0 = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT1 = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT2 = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT3 = OBJECT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_STAT4 = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RESISTANCES = OBJECT_END + 0x0056, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_BASE_MANA = OBJECT_END + 0x006B, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x006C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_BYTES_2 = OBJECT_END + 0x006D, // Size: 1, Type: BYTES, Flags: PUBLIC + UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x006E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MOD_POS = OBJECT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x0070, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0071, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0075, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x0076, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x0078, // Size: 7, Type: INT, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x007F, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x0086, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER + UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x0087, // Size: 1, Type: FLOAT, Flags: PUBLIC + UNIT_FIELD_MAXITEMLEVEL = OBJECT_END + 0x0088, // Size: 1, Type: INT, Flags: PUBLIC + UNIT_FIELD_PADDING = OBJECT_END + 0x0089, // Size: 1, Type: INT, Flags: NONE + UNIT_END = OBJECT_END + 0x008A, +}; + +enum EPlayerFields +{ + PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDRANK = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDDELETE_DATE = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILDLEVEL = UNIT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_BYTES = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_BYTES_2 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_BYTES_3 = UNIT_END + 0x0008, // Size: 1, Type: BYTES, Flags: PUBLIC + PLAYER_DUEL_TEAM = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000D, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0011, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0012, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0017, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001C, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x0020, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0021, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0026, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x002A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002B, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x0030, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0034, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0035, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0039, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x003A, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003F, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0044, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0048, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0049, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004E, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0053, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0057, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0058, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005D, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0061, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0062, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0066, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0067, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006C, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x0070, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0071, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0075, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0076, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x007A, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007B, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x0080, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0084, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0085, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_1 = UNIT_END + 0x0088, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_2 = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_3 = UNIT_END + 0x008A, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_26_5 = UNIT_END + 0x008C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_1 = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_2 = UNIT_END + 0x008E, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_3 = UNIT_END + 0x008F, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_27_5 = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_1 = UNIT_END + 0x0092, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_2 = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_3 = UNIT_END + 0x0094, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_28_5 = UNIT_END + 0x0096, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_1 = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_2 = UNIT_END + 0x0098, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_3 = UNIT_END + 0x0099, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_29_5 = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_1 = UNIT_END + 0x009C, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_2 = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_3 = UNIT_END + 0x009E, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_30_5 = UNIT_END + 0x00A0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_1 = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_2 = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_3 = UNIT_END + 0x00A3, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_31_5 = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_1 = UNIT_END + 0x00A6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_2 = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_3 = UNIT_END + 0x00A8, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_32_5 = UNIT_END + 0x00AA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_1 = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_2 = UNIT_END + 0x00AC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_3 = UNIT_END + 0x00AD, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_33_5 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_1 = UNIT_END + 0x00B0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_2 = UNIT_END + 0x00B1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_3 = UNIT_END + 0x00B2, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_34_5 = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_1 = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_2 = UNIT_END + 0x00B6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_3 = UNIT_END + 0x00B7, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_35_5 = UNIT_END + 0x00B9, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_1 = UNIT_END + 0x00BA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_2 = UNIT_END + 0x00BB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_3 = UNIT_END + 0x00BC, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_36_5 = UNIT_END + 0x00BE, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_1 = UNIT_END + 0x00BF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_2 = UNIT_END + 0x00C0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_3 = UNIT_END + 0x00C1, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_37_5 = UNIT_END + 0x00C3, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_1 = UNIT_END + 0x00C4, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_2 = UNIT_END + 0x00C5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_3 = UNIT_END + 0x00C6, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_38_5 = UNIT_END + 0x00C8, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_1 = UNIT_END + 0x00C9, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_2 = UNIT_END + 0x00CA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_3 = UNIT_END + 0x00CB, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_39_5 = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_1 = UNIT_END + 0x00CE, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_2 = UNIT_END + 0x00CF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_3 = UNIT_END + 0x00D0, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_40_5 = UNIT_END + 0x00D2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_1 = UNIT_END + 0x00D3, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_2 = UNIT_END + 0x00D4, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_3 = UNIT_END + 0x00D5, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_41_5 = UNIT_END + 0x00D7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_1 = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_2 = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_3 = UNIT_END + 0x00DA, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_42_5 = UNIT_END + 0x00DC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_1 = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_2 = UNIT_END + 0x00DE, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_3 = UNIT_END + 0x00DF, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_43_5 = UNIT_END + 0x00E1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_1 = UNIT_END + 0x00E2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_2 = UNIT_END + 0x00E3, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_3 = UNIT_END + 0x00E4, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_44_5 = UNIT_END + 0x00E6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_1 = UNIT_END + 0x00E7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_2 = UNIT_END + 0x00E8, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_3 = UNIT_END + 0x00E9, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_45_5 = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_1 = UNIT_END + 0x00EC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_2 = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_3 = UNIT_END + 0x00EE, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_46_5 = UNIT_END + 0x00F0, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_1 = UNIT_END + 0x00F1, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_2 = UNIT_END + 0x00F2, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_3 = UNIT_END + 0x00F3, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_47_5 = UNIT_END + 0x00F5, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_1 = UNIT_END + 0x00F6, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_2 = UNIT_END + 0x00F7, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_3 = UNIT_END + 0x00F8, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_48_5 = UNIT_END + 0x00FA, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_1 = UNIT_END + 0x00FB, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_2 = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_3 = UNIT_END + 0x00FD, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_49_5 = UNIT_END + 0x00FF, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_1 = UNIT_END + 0x0100, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_2 = UNIT_END + 0x0101, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_3 = UNIT_END + 0x0102, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER + PLAYER_QUEST_LOG_50_5 = UNIT_END + 0x0104, // Size: 1, Type: INT, Flags: PARTY_MEMBER + PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0105, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0106, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0107, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x0108, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x0109, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x010A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x010B, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x010E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0110, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0111, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0112, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0113, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0114, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0115, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0116, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0117, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x0118, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x0119, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x011A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x011B, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x011E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x011F, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x0120, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x0122, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x0123, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x0124, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x0125, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x0126, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x0127, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x0128, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x0129, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x012A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC + PLAYER_CHOSEN_TITLE = UNIT_END + 0x012B, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_FAKE_INEBRIATION = UNIT_END + 0x012C, // Size: 1, Type: INT, Flags: PUBLIC + PLAYER_FIELD_PAD_0 = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: NONE + PLAYER_END_NOT_SELF = UNIT_END + 0x012E, - PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC - PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC - PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC - 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: PARTY_MEMBER - PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0011, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0016, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0018, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0020, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0025, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x002F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0034, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0039, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003E, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0040, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0043, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0048, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004D, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0052, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0057, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0061, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0066, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0068, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0070, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0075, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0077, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x007F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0081, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER - PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0084, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0086, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0088, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x008A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x008B, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x008E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x008F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x0090, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0092, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0094, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0096, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0098, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0099, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x009A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x009E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x00A0, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x00A2, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x00A6, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x00A8, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x00A9, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x00AA, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC - PLAYER_CHOSEN_TITLE = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FAKE_INEBRIATION = UNIT_END + 0x00AE, // Size: 1, Type: INT, Flags: PUBLIC - PLAYER_FIELD_PAD_0 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: NONE - PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x00B0, // Size: 46, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00DE, // Size: 32, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00FE, // Size: 56, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0136, // Size: 14, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0144, // Size: 24, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x015C, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x019C, // Size: 64, Type: LONG, Flags: PRIVATE - PLAYER_FARSIGHT = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01E4, // Size: 2, Type: LONG, Flags: PRIVATE - PLAYER_XP = UNIT_END + 0x01E6, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E7, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x01E8, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_CREATURES = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_TRACK_RESOURCES = UNIT_END + 0x036B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPERTISE = UNIT_END + 0x036F, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x0370, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0371, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0372, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0373, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0374, // Size: 7, Type: FLOAT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK = UNIT_END + 0x037B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x037C, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037D, // Size: 128, Type: BYTES, Flags: PRIVATE - PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COINAGE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x03FF, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0406, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x040D, // Size: 7, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0414, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0415, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0416, // Size: 1, Type: FLOAT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0418, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES = UNIT_END + 0x0419, // Size: 1, Type: BYTES, Flags: PRIVATE - PLAYER_AMMO_ID = UNIT_END + 0x041A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_SELF_RES_SPELL = UNIT_END + 0x041B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x041D, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0429, // Size: 12, Type: INT, Flags: PRIVATE - PLAYER_FIELD_KILLS = UNIT_END + 0x0435, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE - PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_BYTES2 = UNIT_END + 0x0439, // Size: 1, Type: 6, Flags: PRIVATE - PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x043B, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0454, // Size: 21, Type: INT, Flags: PRIVATE - PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0469, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x046A, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x046B, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x046C, // Size: 25, Type: INT, Flags: PRIVATE - PLAYER_RUNE_REGEN_1 = UNIT_END + 0x0485, // Size: 4, Type: FLOAT, Flags: PRIVATE - PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x0489, // Size: 3, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x048C, // Size: 6, Type: INT, Flags: PRIVATE - PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0492, // Size: 6, Type: INT, Flags: PRIVATE - PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0498, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_PET_SPELL_POWER = UNIT_END + 0x0499, // Size: 1, Type: INT, Flags: PRIVATE - PLAYER_END = UNIT_END + 0x049A, + PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x012E, // Size: 46, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x015C, // Size: 32, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x017C, // Size: 56, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x01B4, // Size: 14, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x01C2, // Size: 24, Type: LONG, Flags: PRIVATE + PLAYER_FARSIGHT = UNIT_END + 0x01DA, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES3 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER_XP = UNIT_END + 0x01E4, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E5, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SKILL_LINEID_0 = UNIT_END + 0x01E6, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_SKILL_STEP_0 = UNIT_END + 0x0226, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_SKILL_RANK_0 = UNIT_END + 0x0266, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_SKILL_MAX_RANK_0 = UNIT_END + 0x02A6, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_SKILL_MODIFIER_0 = UNIT_END + 0x02E6, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_SKILL_TALENT_0 = UNIT_END + 0x0326, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_CHARACTER_POINTS = UNIT_END + 0x0366, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_CREATURES = UNIT_END + 0x0367, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_TRACK_RESOURCES = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_EXPERTISE = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036B, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x036F, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0370, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0371, // Size: 7, Type: FLOAT, Flags: PRIVATE + PLAYER_SHIELD_BLOCK = UNIT_END + 0x0378, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x0379, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_MASTERY = UNIT_END + 0x037A, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037B, // Size: 156, Type: BYTES, Flags: PRIVATE + PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COINAGE = UNIT_END + 0x0418, // Size: 2, Type: LONG, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x041A, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0421, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x0428, // Size: 7, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x042F, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0430, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0431, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS = UNIT_END + 0x0432, // Size: 3, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_SPELL_POWER_PCT = UNIT_END + 0x0435, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT = UNIT_END + 0x0436, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x0439, // Size: 1, Type: BYTES, Flags: PRIVATE + PLAYER_SELF_RES_SPELL = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x043B, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x043C, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0448, // Size: 12, Type: INT, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x0454, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x0455, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0x0456, // Size: 1, Type: 6, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0457, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0458, // Size: 26, Type: INT, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0472, // Size: 21, Type: INT, Flags: PRIVATE + PLAYER_FIELD_BATTLEGROUND_RATING = UNIT_END + 0x0487, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0488, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0489, // Size: 25, Type: INT, Flags: PRIVATE + PLAYER_RUNE_REGEN_1 = UNIT_END + 0x04A2, // Size: 4, Type: FLOAT, Flags: PRIVATE + PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x04A6, // Size: 3, Type: INT, Flags: PRIVATE + PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x04A9, // Size: 9, Type: INT, Flags: PRIVATE + PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x04B2, // Size: 9, Type: INT, Flags: PRIVATE + PLAYER_GLYPHS_ENABLED = UNIT_END + 0x04BB, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_PET_SPELL_POWER = UNIT_END + 0x04BC, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_RESEARCHING_1 = UNIT_END + 0x04BD, // Size: 8, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_FIELD_RESERACH_SITE_1 = UNIT_END + 0x04C5, // Size: 8, Type: TWO_SHORT, Flags: PRIVATE + PLAYER_PROFESSION_SKILL_LINE_1 = UNIT_END + 0x04CD, // Size: 2, Type: INT, Flags: PRIVATE + PLAYER_FIELD_UI_HIT_MODIFIER = UNIT_END + 0x04CF, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_UI_SPELL_HIT_MODIFIER = UNIT_END + 0x04D0, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_HOME_REALM_TIME_OFFSET = UNIT_END + 0x04D1, // Size: 1, Type: INT, Flags: PRIVATE + PLAYER_FIELD_MOD_HASTE = UNIT_END + 0x04D2, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_RANGED_HASTE = UNIT_END + 0x04D3, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_PET_HASTE = UNIT_END + 0x04D4, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_FIELD_MOD_HASTE_REGEN = UNIT_END + 0x04D5, // Size: 1, Type: FLOAT, Flags: PRIVATE + PLAYER_END = UNIT_END + 0x04D6, }; enum EGameObjectFields { - OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC - GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC - GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC - GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC - GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC - GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC - GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC - GAMEOBJECT_END = OBJECT_END + 0x000C, + OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC + GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC + GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC + GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC + GAMEOBJECT_END = OBJECT_END + 0x000C, }; enum EDynamicObjectFields { - DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC - DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC - DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC - DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC - DYNAMICOBJECT_END = OBJECT_END + 0x0006, + DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: DYNAMIC + DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC + DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC + DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC + DYNAMICOBJECT_END = OBJECT_END + 0x0006, }; enum ECorpseFields { - CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC - CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC - CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC - CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC - CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC - CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC - CORPSE_FIELD_GUILD = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC - CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC - CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC - CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE - CORPSE_END = OBJECT_END + 0x001E, + CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC + CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC + CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC + CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC + CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC + CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC + CORPSE_FIELD_FLAGS = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC + CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: DYNAMIC + CORPSE_END = OBJECT_END + 0x001C, }; -#endif + +enum EAreaTriggerFields +{ + AREATRIGGER_SPELLID = OBJECT_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC + AREATRIGGER_SPELLVISUALID = OBJECT_END + 0x0001, // Size: 1, Type: INT, Flags: PUBLIC + AREATRIGGER_DURATION = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC + AREATRIGGER_FINAL_POS = OBJECT_END + 0x0003, // Size: 3, Type: FLOAT, Flags: PUBLIC + AREATRIGGER_END = OBJECT_END + 0x0006, +}; + +#endif // _UPDATEFIELDS_H diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 17b214857db..8392fbb9e49 100755 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -35,7 +35,7 @@ Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner, true), m_usedTalentCount(0), m_removed(false), m_owner(owner), -m_happinessTimer(7500), m_petType(type), m_duration(0), +m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL) { m_unitTypeMask |= UNIT_MASK_PET; @@ -147,7 +147,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c if (!petentry) return false; - uint32 summon_spell_id = fields[15].GetUInt32(); + uint32 summon_spell_id = fields[14].GetUInt32(); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summon_spell_id); bool is_temporary_summoned = spellInfo && spellInfo->GetDuration() > 0; @@ -156,7 +156,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c if (current && is_temporary_summoned) return false; - PetType pet_type = PetType(fields[16].GetUInt8()); + PetType pet_type = PetType(fields[15].GetUInt8()); if (pet_type == HUNTER_PET) { CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petentry); @@ -223,8 +223,6 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet abandon, cancel) - SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); - SetPower(POWER_HAPPINESS, fields[12].GetUInt32()); setPowerType(POWER_FOCUS); break; default: @@ -303,13 +301,13 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c InitTalentForLevel(); // set original talents points before spell loading - uint32 timediff = uint32(time(NULL) - fields[14].GetUInt32()); + uint32 timediff = uint32(time(NULL) - fields[13].GetUInt32()); _LoadAuras(timediff); // load action bar, if data broken will fill later by default spells. if (!is_temporary_summoned) { - m_charmInfo->LoadPetActionBar(fields[13].GetString()); + m_charmInfo->LoadPetActionBar(fields[12].GetString()); _LoadSpells(); InitTalentForLevel(); // re-init to check talent count @@ -437,7 +435,7 @@ void Pet::SavePetToDB(PetSaveMode mode) // save pet std::ostringstream ss; - ss << "INSERT INTO character_pet (id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType) " + ss << "INSERT INTO character_pet (id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType) " << "VALUES (" << m_charmInfo->GetPetNumber() << ',' << GetEntry() << ',' @@ -450,8 +448,7 @@ void Pet::SavePetToDB(PetSaveMode mode) << name.c_str() << "', " << uint32(HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ? 0 : 1) << ',' << curhealth << ',' - << curmana << ',' - << GetPower(POWER_HAPPINESS) << ", '"; + << curmana << ", '"; for (uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i) { @@ -512,12 +509,6 @@ void Pet::setDeathState(DeathState s) // overwrite virtual // pet corpse non lootable and non skinnable SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - - //lose happiness when died and not in BG/Arena - MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId()); - if (!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND)) - ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE); - //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } } @@ -611,18 +602,6 @@ void Pet::Update(uint32 diff) } } } - - if (getPetType() != HUNTER_PET) - break; - - if (m_happinessTimer <= diff) - { - LoseHappiness(); - m_happinessTimer = 7500; - } - else - m_happinessTimer -= diff; - break; } default: @@ -670,27 +649,6 @@ void Creature::Regenerate(Powers power) ModifyPower(power, int32(addvalue)); } -void Pet::LoseHappiness() -{ - uint32 curValue = GetPower(POWER_HAPPINESS); - if (curValue <= 0) - return; - int32 addvalue = 670; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs) - if (isInCombat()) //we know in combat happiness fades faster, multiplier guess - addvalue = int32(addvalue * 1.5f); - ModifyPower(POWER_HAPPINESS, -addvalue); -} - -HappinessState Pet::GetHappinessState() -{ - if (GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE) - return UNHAPPY; - else if (GetPower(POWER_HAPPINESS) >= HAPPINESS_LEVEL_SIZE * 2) - return HAPPY; - else - return CONTENT; -} - void Pet::Remove(PetSaveMode mode, bool returnreagent) { m_owner->RemovePet(this, mode, returnreagent); @@ -775,7 +733,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature) SetDisplayId(creature->GetDisplayId()); if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family)) - SetName(cFamily->Name[sWorld->GetDefaultDbcLocale()]); + SetName(cFamily->Name); else SetName(creature->GetNameForLocaleIdx(sObjectMgr->GetDBCLocaleIndex())); @@ -788,7 +746,7 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner) return false; if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family)) - SetName(cFamily->Name[sWorld->GetDefaultDbcLocale()]); + SetName(cFamily->Name); Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation()); @@ -803,8 +761,6 @@ bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phas if (!Create(guid, map, phaseMask, cinfo->Entry, pet_number)) return false; - SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); - SetPower(POWER_HAPPINESS, 166500); setPowerType(POWER_FOCUS); SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); @@ -857,6 +813,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f); //scale CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); @@ -1893,6 +1850,8 @@ bool Pet::IsPermanentPetFor(Player* owner) return GetCreatureTemplate()->type == CREATURE_TYPE_DEMON; case CLASS_DEATH_KNIGHT: return GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD; + case CLASS_MAGE: + return GetCreatureTemplate()->type == CREATURE_TYPE_ELEMENTAL; default: return false; } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 3475817816d..5759a58a575 100755 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -42,13 +42,6 @@ enum PetSaveMode PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100 }; -enum HappinessState -{ - UNHAPPY = 1, - CONTENT = 2, - HAPPY = 3 -}; - enum PetSpellState { PETSPELL_UNCHANGED = 0, @@ -108,8 +101,6 @@ enum PetNameInvalidReason typedef UNORDERED_MAP<uint32, PetSpell> PetSpellMap; typedef std::vector<uint32> AutoSpellList; -#define HAPPINESS_LEVEL_SIZE 333000 - #define ACTIVE_SPELLS_MAX 4 #define PET_FOLLOW_DIST 1.0f @@ -156,8 +147,6 @@ class Pet : public Guardian return m_autospells[pos]; } - void LoseHappiness(); - HappinessState GetHappinessState(); void GivePetXP(uint32 xp); void GivePetLevel(uint8 level); void SynchronizeLevelWithOwner(); @@ -227,7 +216,6 @@ class Pet : public Guardian Player* GetOwner() { return m_owner; } protected: Player* m_owner; - uint32 m_happinessTimer; PetType m_petType; int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) uint64 m_auraRaidUpdateMask; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 72c500513cd..7250feefc21 100755..100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -74,21 +74,10 @@ #include "InstanceScript.h" #include <cmath> #include "AccountMgr.h" +#include "DB2Stores.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) -#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3)) -#define PLAYER_SKILL_VALUE_INDEX(x) (PLAYER_SKILL_INDEX(x)+1) -#define PLAYER_SKILL_BONUS_INDEX(x) (PLAYER_SKILL_INDEX(x)+2) - -#define SKILL_VALUE(x) PAIR32_LOPART(x) -#define SKILL_MAX(x) PAIR32_HIPART(x) -#define MAKE_SKILL_VALUE(v, m) MAKE_PAIR32(v, m) - -#define SKILL_TEMP_BONUS(x) int16(PAIR32_LOPART(x)) -#define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x)) -#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p) - enum CharacterFlags { CHARACTER_FLAG_NONE = 0x00000000, @@ -357,7 +346,7 @@ void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/) Update(false); // send spell info to caster self } -void TradeData::SetMoney(uint32 money) +void TradeData::SetMoney(uint64 money) { if (m_money == money) return; @@ -431,6 +420,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) // 4.3. Give reputation (player must not be on BG). // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse). // 5. Credit instance encounter. +// 6. Update guild achievements. KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) : // 1. Initialize internal variables to default values. _killer(killer), _victim(victim), _group(killer->GetGroup()), @@ -622,10 +612,18 @@ void KillRewarder::Reward() } // 5. Credit instance encounter. + // 6. Update guild achievements. if (Creature* victim = _victim->ToCreature()) + { if (victim->IsDungeonBoss()) if (InstanceScript* instance = _victim->GetInstanceScript()) instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim); + + if (uint32 guildId = victim->GetMap()->GetOwnerGuildId()) + if (Guild* guild = sGuildMgr->GetGuildById(guildId)) + guild->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, victim, _killer); + } + } // == Player ==================================================== @@ -668,9 +666,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_comboTarget = 0; m_comboPoints = 0; - m_usedTalentCount = 0; - m_questRewardTalentCount = 0; - m_regenTimer = 0; m_regenTimerCount = 0; m_weaponChangeTimer = 0; @@ -719,7 +714,7 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_DailyQuestChanged = false; m_lastDailyQuestTime = 0; - for (uint8 i=0; i<MAX_TIMERS; i++) + for (uint8 i=0; i < MAX_TIMERS; i++) m_MirrorTimer[i] = DISABLED_MIRROR_TIMER; m_MirrorTimerFlags = UNDERWATER_NONE; @@ -734,7 +729,7 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep for (uint8 j = 0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; ++j) { - m_bgBattlegroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE; + m_bgBattlegroundQueueID[j].bgQueueTypeId = BATTLEGROUND_QUEUE_NONE; m_bgBattlegroundQueueID[j].invitedToInstance = 0; } @@ -746,7 +741,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_canBlock = false; m_canDualWield = false; m_canTitanGrip = false; - m_ammoDPS = 0.0f; m_temporaryUnsummonedPetNumber = 0; //cache for UNIT_CREATED_BY_SPELL to allow @@ -770,8 +764,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep unReadMails = 0; m_nextMailDelivereTime = 0; - m_resetTalentsCost = 0; - m_resetTalentsTime = 0; m_itemUpdateQueueBlocked = false; for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) @@ -787,17 +779,7 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL; m_lastPotionId = 0; - - m_activeSpec = 0; - m_specsCount = 1; - - for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) - { - for (uint8 g = 0; g < MAX_GLYPH_SLOT_INDEX; ++g) - m_Glyphs[i][g] = 0; - - m_talents[i] = new PlayerTalentMap(); - } + _talentMgr = new PlayerTalentInfo(); for (uint8 i = 0; i < BASEMOD_END; ++i) { @@ -859,6 +841,8 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_SeasonalQuestChanged = false; SetPendingBind(0, 0); + + memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); } Player::~Player() @@ -873,12 +857,7 @@ Player::~Player() for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) delete itr->second; - for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) - { - for (PlayerTalentMap::const_iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end(); ++itr) - delete itr->second; - delete m_talents[i]; - } + delete _talentMgr; //all mailed items should be deleted, also all mail should be deallocated for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr) @@ -895,6 +874,9 @@ Player::~Player() delete m_declinedname; delete m_runes; + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + delete _voidStorageItems[i]; + sWorld->DecreasePlayerCount(); } @@ -973,6 +955,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) } SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client + SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // default for players in 3.0.3 // -1 is default value @@ -986,7 +969,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) SetByteValue(PLAYER_BYTES_3, 0, createInfo->Gender); SetByteValue(PLAYER_BYTES_3, 3, 0); // BattlefieldArenaFaction (0 or 1) - SetUInt32Value(PLAYER_GUILDID, 0); + SetUInt64Value(OBJECT_FIELD_DATA, 0); SetUInt32Value(PLAYER_GUILDRANK, 0); SetUInt32Value(PLAYER_GUILD_TIMESTAMP, 0); @@ -996,8 +979,6 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) SetUInt32Value(PLAYER_FIELD_KILLS, 0); SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); // set starting level uint32 start_level = getClass() != CLASS_DEATH_KNIGHT @@ -1016,8 +997,8 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) InitRunes(); SetUInt32Value(PLAYER_FIELD_COINAGE, sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY)); - SetHonorPoints(sWorld->getIntConfig(CONFIG_START_HONOR_POINTS)); - SetArenaPoints(sWorld->getIntConfig(CONFIG_START_ARENA_POINTS)); + SetCurrency(CURRENCY_TYPE_HONOR_POINTS, sWorld->getIntConfig(CONFIG_START_HONOR_POINTS)); + SetCurrency(CURRENCY_TYPE_CONQUEST_POINTS, sWorld->getIntConfig(CONFIG_START_ARENA_POINTS)); // start with every map explored if (sWorld->getBoolConfig(CONFIG_START_ALL_EXPLORED)) @@ -1137,7 +1118,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) uint32 count = iProto->BuyCount; // special amount for food/drink - if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD) + if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD_DRINK) { switch (iProto->Spells[0].SpellCategory) { @@ -1173,7 +1154,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) RemoveItem(INVENTORY_SLOT_BAG_0, i, true); EquipItem(eDest, pItem, true); } - // move other items to more appropriate slots (ammo not equipped in special bag) + // move other items to more appropriate slots else { ItemPosCountVec sDest; @@ -1183,11 +1164,6 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) RemoveItem(INVENTORY_SLOT_BAG_0, i, true); pItem = StoreItem(sDest, pItem, true); } - - // if this is ammo then use it - msg = CanUseAmmo(pItem->GetEntry()); - if (msg == EQUIP_ERR_OK) - SetAmmo(pItem->GetEntry()); } } } @@ -1301,7 +1277,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) GetSession()->SendPacket(&data2); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); } return final_damage; @@ -1840,9 +1816,9 @@ void Player::setDeathState(DeathState s) // passive spell if (!ressSpellId) ressSpellId = GetResurrectionSpellId(); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH); @@ -1859,7 +1835,7 @@ void Player::setDeathState(DeathState s) SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); } -bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) +bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer) { // 0 1 2 3 4 5 6 7 // "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, " @@ -1870,89 +1846,58 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) Field* fields = result->Fetch(); - uint32 guid = fields[0].GetUInt32(); + ObjectGuid guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); + std::string name = fields[1].GetString(); uint8 plrRace = fields[2].GetUInt8(); uint8 plrClass = fields[3].GetUInt8(); uint8 gender = fields[4].GetUInt8(); - - PlayerInfo const* info = sObjectMgr->GetPlayerInfo(plrRace, plrClass); - if (!info) - { - sLog->outError(LOG_FILTER_PLAYER_LOADING, "Player %u has incorrect race/class pair. Don't build enum.", guid); - return false; - } - else if (!IsValidGender(gender)) - { - sLog->outError(LOG_FILTER_PLAYER_LOADING, "Player (%u) has incorrect gender (%hu), don't build enum.", guid, gender); - return false; - } - - *data << uint64(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); - *data << fields[1].GetString(); // name - *data << uint8(plrRace); // race - *data << uint8(plrClass); // class - *data << uint8(gender); // gender - - uint32 playerBytes = fields[5].GetUInt32(); - *data << uint8(playerBytes); // skin - *data << uint8(playerBytes >> 8); // face - *data << uint8(playerBytes >> 16); // hair style - *data << uint8(playerBytes >> 24); // hair color - - uint32 playerBytes2 = fields[6].GetUInt32(); - *data << uint8(playerBytes2 & 0xFF); // facial hair - - *data << uint8(fields[7].GetUInt8()); // level - *data << uint32(fields[8].GetUInt16()); // zone - *data << uint32(fields[9].GetUInt16()); // map - - *data << fields[10].GetFloat(); // x - *data << fields[11].GetFloat(); // y - *data << fields[12].GetFloat(); // z - - *data << uint32(fields[13].GetUInt32()); // guild id + uint8 skin = uint8(fields[5].GetUInt32() & 0xFF); + uint8 face = uint8((fields[5].GetUInt32() >> 8) & 0xFF); + uint8 hairStyle = uint8((fields[5].GetUInt32() >> 16) & 0xFF); + uint8 hairColor = uint8((fields[5].GetUInt32() >> 24) & 0xFF); + uint8 facialHair = uint8(fields[6].GetUInt32() & 0xFF); + uint8 level = fields[7].GetUInt8(); + uint32 zone = fields[8].GetUInt16(); + uint32 mapId = uint32(fields[9].GetUInt16()); + float x = fields[10].GetFloat(); + float y = fields[11].GetFloat(); + float z = fields[12].GetFloat(); + uint32 guildId = fields[13].GetUInt32(); + ObjectGuid guildGuid = MAKE_NEW_GUID(guildId, 0, guildId ? HIGHGUID_GUILD : 0); + uint32 playerFlags = fields[14].GetUInt32(); + uint32 atLoginFlags = fields[15].GetUInt16(); + Tokens equipment(fields[19].GetString(), ' '); uint32 charFlags = 0; - uint32 playerFlags = fields[14].GetUInt32(); - uint16 atLoginFlags = fields[15].GetUInt16(); if (playerFlags & PLAYER_FLAGS_HIDE_HELM) charFlags |= CHARACTER_FLAG_HIDE_HELM; + if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK) charFlags |= CHARACTER_FLAG_HIDE_CLOAK; + if (playerFlags & PLAYER_FLAGS_GHOST) charFlags |= CHARACTER_FLAG_GHOST; + if (atLoginFlags & AT_LOGIN_RENAME) charFlags |= CHARACTER_FLAG_RENAME; + if (fields[20].GetUInt32()) charFlags |= CHARACTER_FLAG_LOCKED_BY_BILLING; - if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED)) - { - if (!fields[21].GetString().empty()) - charFlags |= CHARACTER_FLAG_DECLINED; - } - else - charFlags |= CHARACTER_FLAG_DECLINED; - *data << uint32(charFlags); // character flags + if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) && !fields[21].GetString().empty()) + charFlags |= CHARACTER_FLAG_DECLINED; - // character customize flags + uint32 customizationFlag = 0; if (atLoginFlags & AT_LOGIN_CUSTOMIZE) - *data << uint32(CHAR_CUSTOMIZE_FLAG_CUSTOMIZE); + customizationFlag = CHAR_CUSTOMIZE_FLAG_CUSTOMIZE; else if (atLoginFlags & AT_LOGIN_CHANGE_FACTION) - *data << uint32(CHAR_CUSTOMIZE_FLAG_FACTION); + customizationFlag = CHAR_CUSTOMIZE_FLAG_FACTION; else if (atLoginFlags & AT_LOGIN_CHANGE_RACE) - *data << uint32(CHAR_CUSTOMIZE_FLAG_RACE); - else - *data << uint32(CHAR_CUSTOMIZE_FLAG_NONE); + customizationFlag = CHAR_CUSTOMIZE_FLAG_RACE; - // First login - *data << uint8(atLoginFlags & AT_LOGIN_FIRST ? 1 : 0); - - // Pets info uint32 petDisplayId = 0; - uint32 petLevel = 0; - uint32 petFamily = 0; - + uint32 petLevel = 0; + uint32 petFamily = 0; // show pet at selection character in character list only for non-ghost character if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (plrClass == CLASS_WARLOCK || plrClass == CLASS_HUNTER || plrClass == CLASS_DEATH_KNIGHT)) { @@ -1961,32 +1906,48 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) if (creatureInfo) { petDisplayId = fields[17].GetUInt32(); - petLevel = fields[18].GetUInt16(); - petFamily = creatureInfo->family; - } - } - - *data << uint32(petDisplayId); - *data << uint32(petLevel); - *data << uint32(petFamily); - - Tokens equipment(fields[19].GetString(), ' '); + petLevel = fields[18].GetUInt16(); + petFamily = creatureInfo->family; + } + } + + // Packet content flags + bitBuffer->WriteBit(guid[3]); + bitBuffer->WriteBit(guildGuid[1]); + bitBuffer->WriteBit(guildGuid[7]); + bitBuffer->WriteBit(guildGuid[2]); + bitBuffer->WriteBits(uint32(name.length()), 7); + bitBuffer->WriteBit(guid[4]); + bitBuffer->WriteBit(guid[7]); + bitBuffer->WriteBit(guildGuid[3]); + bitBuffer->WriteBit(guid[5]); + bitBuffer->WriteBit(guildGuid[6]); + bitBuffer->WriteBit(guid[1]); + bitBuffer->WriteBit(guildGuid[5]); + bitBuffer->WriteBit(guildGuid[4]); + bitBuffer->WriteBit(atLoginFlags & AT_LOGIN_FIRST); + bitBuffer->WriteBit(guid[0]); + bitBuffer->WriteBit(guid[2]); + bitBuffer->WriteBit(guid[6]); + bitBuffer->WriteBit(guildGuid[0]); + + // Character data + *dataBuffer << uint8(plrClass); // Class for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot) { - uint32 visualBase = slot * 2; - uint32 itemId = GetUInt32ValueFromArray(equipment, visualBase); + uint32 visualbase = slot * 2; + uint32 itemId = GetUInt32ValueFromArray(equipment, visualbase); ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId); if (!proto) { - *data << uint32(0); - *data << uint8(0); - *data << uint32(0); + *dataBuffer << uint8(0); + *dataBuffer << uint32(0); + *dataBuffer << uint32(0); continue; } - SpellItemEnchantmentEntry const* enchant = NULL; - - uint32 enchants = GetUInt32ValueFromArray(equipment, visualBase + 1); + SpellItemEnchantmentEntry const *enchant = NULL; + uint32 enchants = GetUInt32ValueFromArray(equipment, visualbase + 1); for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot) { // values stored in 2 uint16 @@ -1999,11 +1960,47 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) break; } - *data << uint32(proto->DisplayInfoID); - *data << uint8(proto->InventoryType); - *data << uint32(enchant ? enchant->aura_id : 0); - } - + *dataBuffer << uint8(proto->InventoryType); + *dataBuffer << uint32(proto->DisplayInfoID); + *dataBuffer << uint32(enchant ? enchant->aura_id : 0); + } + + *dataBuffer << uint32(petFamily); // Pet family + dataBuffer->WriteByteSeq(guildGuid[2]); + *dataBuffer << uint8(0); // List order + *dataBuffer << uint8(hairStyle); // Hair style + dataBuffer->WriteByteSeq(guildGuid[3]); + *dataBuffer << uint32(petDisplayId); // Pet DisplayID + *dataBuffer << uint32(charFlags); // Character flags + *dataBuffer << uint8(hairColor); // Hair color + dataBuffer->WriteByteSeq(guid[4]); + *dataBuffer << uint32(mapId); // Map Id + dataBuffer->WriteByteSeq(guildGuid[5]); + *dataBuffer << float(z); // Z + dataBuffer->WriteByteSeq(guildGuid[6]); + *dataBuffer << uint32(petLevel); // Pet level + dataBuffer->WriteByteSeq(guid[3]); + *dataBuffer << float(y); // Y + *dataBuffer << uint32(customizationFlag); // Character customization flags + *dataBuffer << uint8(facialHair); // Facial hair + dataBuffer->WriteByteSeq(guid[7]); + *dataBuffer << uint8(gender); // Gender + dataBuffer->append(name.c_str(), name.length()); // Name + *dataBuffer << uint8(face); // Face + dataBuffer->WriteByteSeq(guid[0]); + dataBuffer->WriteByteSeq(guid[2]); + dataBuffer->WriteByteSeq(guildGuid[1]); + dataBuffer->WriteByteSeq(guildGuid[7]); + *dataBuffer << float(x); // X + *dataBuffer << uint8(skin); // Skin + *dataBuffer << uint8(plrRace); // Race + *dataBuffer << uint8(level); // Level + dataBuffer->WriteByteSeq(guid[6]); + dataBuffer->WriteByteSeq(guildGuid[4]); + dataBuffer->WriteByteSeq(guildGuid[0]); + dataBuffer->WriteByteSeq(guid[5]); + dataBuffer->WriteByteSeq(guid[1]); + *dataBuffer << uint32(zone); // Zone id return true; } @@ -2045,20 +2042,62 @@ uint8 Player::GetChatTag() const void Player::SendTeleportPacket(Position &oldPos) { - WorldPacket data2(MSG_MOVE_TELEPORT, 38); - data2.append(GetPackGUID()); - BuildMovementPacket(&data2); - Relocate(&oldPos); - SendMessageToSet(&data2, false); -} + ObjectGuid guid = GetGUID(); + ObjectGuid transGuid = GetTransGUID(); + + WorldPacket data(MSG_MOVE_TELEPORT, 38); + data.WriteBit(guid[6]); + data.WriteBit(guid[0]); + data.WriteBit(guid[3]); + data.WriteBit(guid[2]); + data.WriteBit(0); // unknown + data.WriteBit(uint64(transGuid)); + data.WriteBit(guid[1]); + if (transGuid) + { + data.WriteBit(transGuid[1]); + data.WriteBit(transGuid[3]); + data.WriteBit(transGuid[2]); + data.WriteBit(transGuid[5]); + data.WriteBit(transGuid[0]); + data.WriteBit(transGuid[7]); + data.WriteBit(transGuid[6]); + data.WriteBit(transGuid[4]); + } + + data.WriteBit(guid[4]); + data.WriteBit(guid[7]); + data.WriteBit(guid[5]); + data.FlushBits(); + + if (transGuid) + { + data.WriteByteSeq(transGuid[6]); + data.WriteByteSeq(transGuid[5]); + data.WriteByteSeq(transGuid[1]); + data.WriteByteSeq(transGuid[7]); + data.WriteByteSeq(transGuid[0]); + data.WriteByteSeq(transGuid[2]); + data.WriteByteSeq(transGuid[4]); + data.WriteByteSeq(transGuid[3]); + } + + data << uint32(0); // counter + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[5]); + data << float(GetPositionX()); + data.WriteByteSeq(guid[4]); + data << float(GetOrientation()); + data.WriteByteSeq(guid[7]); + data << float(GetPositionZMinusOffset()); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[6]); + data << float(GetPositionY()); -void Player::SendTeleportAckPacket() -{ - WorldPacket data(MSG_MOVE_TELEPORT_ACK, 41); - data.append(GetPackGUID()); - data << uint32(0); // this value increments every time - BuildMovementPacket(&data); - GetSession()->SendPacket(&data); + Relocate(&oldPos); + SendDirectMessage(&data); } bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options) @@ -2115,15 +2154,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (m_transport) { - if (options & TELE_TO_NOT_LEAVE_TRANSPORT) - AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - else + if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT)) { m_transport->RemovePassenger(this); m_transport = NULL; m_movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); m_movementInfo.t_time = 0; m_movementInfo.t_seat = -1; + m_movementInfo.t_guid = 0; } } @@ -2165,15 +2203,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati SetFallInformation(0, z); // code for finish transfer called in WorldSession::HandleMovementOpcodes() - // at client packet MSG_MOVE_TELEPORT_ACK + // at client packet CMSG_MOVE_TELEPORT_ACK SetSemaphoreTeleportNear(true); - // near teleport, triggering send MSG_MOVE_TELEPORT_ACK from client at landing + // near teleport, triggering send CMSG_MOVE_TELEPORT_ACK from client at landing if (!GetSession()->PlayerLogout()) { Position oldPos; GetPosition(&oldPos); Relocate(x, y, z, orientation); - SendTeleportAckPacket(); SendTeleportPacket(oldPos); // this automatically relocates to oldPos in order to broadcast the packet in the right place } } @@ -2257,10 +2294,16 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati { // send transfer packets WorldPacket data(SMSG_TRANSFER_PENDING, 4 + 4 + 4); - data << uint32(mapid); + data.WriteBit(0); // unknown if (m_transport) - data << m_transport->GetEntry() << GetMapId(); + { + data.WriteBit(1); // has transport + data << GetMapId() << m_transport->GetEntry(); + } + else + data.WriteBit(0); // has transport + data << uint32(mapid); GetSession()->SendPacket(&data); } @@ -2290,11 +2333,11 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!GetSession()->PlayerLogout()) { WorldPacket data(SMSG_NEW_WORLD, 4 + 4 + 4 + 4 + 4); + data << float(m_teleport_dest.GetPositionX()); + data << float(m_teleport_dest.GetOrientation()); + data << float(m_teleport_dest.GetPositionZ()); data << uint32(mapid); - if (m_transport) - data << m_movementInfo.t_pos.PositionXYZOStream(); - else - data << m_teleport_dest.PositionXYZOStream(); + data << float(m_teleport_dest.GetPositionY()); GetSession()->SendPacket(&data); SendSavedInstances(); @@ -2439,14 +2482,28 @@ void Player::RegenerateAll() m_regenTimerCount += m_regenTimer; Regenerate(POWER_ENERGY); - + Regenerate(POWER_FOCUS); Regenerate(POWER_MANA); // Runes act as cooldowns, and they don't need to send any data if (getClass() == CLASS_DEATH_KNIGHT) - for (uint8 i = 0; i < MAX_RUNES; ++i) - if (uint32 cd = GetRuneCooldown(i)) - SetRuneCooldown(i, (cd > m_regenTimer) ? cd - m_regenTimer : 0); + { + for (uint8 i = 0; i < MAX_RUNES; i += 2) + { + uint8 runeToRegen = i; + uint32 cd = GetRuneCooldown(i); + uint32 secondRuneCd = GetRuneCooldown(i + 1); + // Regenerate second rune of the same type only after first rune is off the cooldown + if (secondRuneCd && (cd > secondRuneCd || !cd)) + { + runeToRegen = i + 1; + cd = secondRuneCd; + } + + if (cd) + SetRuneCooldown(runeToRegen, (cd > m_regenTimer) ? cd - m_regenTimer : 0); + } + } if (m_regenTimerCount >= 2000) { @@ -2496,7 +2553,8 @@ void Player::Regenerate(Powers power) addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer; else addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer; - } break; + } + break; case POWER_RAGE: // Regenerate rage { if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) @@ -2504,7 +2562,8 @@ void Player::Regenerate(Powers power) float RageDecreaseRate = sWorld->getRate(RATE_POWER_RAGE_LOSS); addvalue += -20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec) } - } break; + } + break; case POWER_ENERGY: // Regenerate energy (rogue) addvalue += 0.01f * m_regenTimer * sWorld->getRate(RATE_POWER_ENERGY); break; @@ -2515,10 +2574,12 @@ void Player::Regenerate(Powers power) float RunicPowerDecreaseRate = sWorld->getRate(RATE_POWER_RUNICPOWER_LOSS); addvalue += -30 * RunicPowerDecreaseRate; // 3 RunicPower by tick } - } break; - case POWER_RUNE: + } + break; case POWER_FOCUS: - case POWER_HAPPINESS: + addvalue += 4.0f * m_modAttackSpeedPct[RANGED_ATTACK] * sWorld->getRate(RATE_POWER_FOCUS); + break; + case POWER_RUNE: case POWER_HEALTH: break; default: @@ -3000,23 +3061,21 @@ void Player::GiveLevel(uint8 level) PlayerLevelInfo info; sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info); - PlayerClassLevelInfo classInfo; - sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo); + uint32 basehp = 0, basemana = 0; + sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, basehp, basemana); // send levelup info to client - WorldPacket data(SMSG_LEVELUP_INFO, (4+4+MAX_POWERS*4+MAX_STATS*4)); + WorldPacket data(SMSG_LEVELUP_INFO, (4+4+MAX_STORED_POWERS*4+MAX_STATS*4)); data << uint32(level); - data << uint32(int32(classInfo.basehealth) - int32(GetCreateHealth())); - // for (int i = 0; i < MAX_POWERS; ++i) // Powers loop (0-6) - data << uint32(int32(classInfo.basemana) - int32(GetCreateMana())); - data << uint32(0); - data << uint32(0); + data << uint32(int32(basehp) - int32(GetCreateHealth())); + // for (int i = 0; i < MAX_STORED_POWERS; ++i) // Powers loop (0-10) + data << uint32(int32(basemana) - int32(GetCreateMana())); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); // end for - for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4) + for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4) data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i))); GetSession()->SendPacket(&data); @@ -3036,8 +3095,8 @@ void Player::GiveLevel(uint8 level) for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetCreateStat(Stats(i), info.stats[i]); - SetCreateHealth(classInfo.basehealth); - SetCreateMana(classInfo.basemana); + SetCreateHealth(basehp); + SetCreateMana(basemana); InitTalentForLevel(); InitTaxiNodesForLevel(); @@ -3052,10 +3111,9 @@ void Player::GiveLevel(uint8 level) SetFullHealth(); SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); - if (GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE)) + if ((uint32)GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE)) SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE)); SetPower(POWER_FOCUS, 0); - SetPower(POWER_HAPPINESS, 0); _ApplyAllLevelScaleItemMods(true); @@ -3071,7 +3129,7 @@ void Player::GiveLevel(uint8 level) CharacterDatabase.CommitTransaction(trans); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); // Refer-A-Friend if (GetSession()->GetRecruiterId()) @@ -3094,33 +3152,33 @@ void Player::InitTalentForLevel() if (level < 10) { // Remove all talent points - if (m_usedTalentCount > 0) // Free any used talents + if (GetUsedTalentCount() > 0) // Free any used talents { - resetTalents(true); + ResetTalents(true); SetFreeTalentPoints(0); } } else { - if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || m_specsCount == 0) + if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || GetSpecsCount() == 0) { - m_specsCount = 1; - m_activeSpec = 0; + SetSpecsCount(1); + SetActiveSpec(0); } uint32 talentPointsForLevel = CalculateTalentsPoints(); // if used more that have then reset - if (m_usedTalentCount > talentPointsForLevel) + if (GetUsedTalentCount() > talentPointsForLevel) { if (!AccountMgr::IsAdminAccount(GetSession()->GetSecurity())) - resetTalents(true); + ResetTalents(true); else SetFreeTalentPoints(0); } // else update amount of free points else - SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount); + SetFreeTalentPoints(talentPointsForLevel - GetUsedTalentCount()); } if (!GetSession()->PlayerLoading()) @@ -3132,8 +3190,8 @@ void Player::InitStatsForLevel(bool reapplyMods) if (reapplyMods) //reapply stats values only on .reset stats (level) command _RemoveAllStatBonuses(); - PlayerClassLevelInfo classInfo; - sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), &classInfo); + uint32 basehp = 0, basemana = 0; + sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), basehp, basemana); PlayerLevelInfo info; sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), getLevel(), &info); @@ -3148,6 +3206,7 @@ void Player::InitStatsForLevel(bool reapplyMods) // set default cast time multiplier SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); + SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f); // reset size before reapply auras SetObjectScale(1.0f); @@ -3159,10 +3218,10 @@ void Player::InitStatsForLevel(bool reapplyMods) for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetStat(Stats(i), info.stats[i]); - SetCreateHealth(classInfo.basehealth); + SetCreateHealth(basehp); //set create powers - SetCreateMana(classInfo.basemana); + SetCreateMana(basemana); SetArmor(int32(m_createStats[STAT_AGILITY]*2)); @@ -3193,10 +3252,8 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, 0.0f); SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0); - SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0); SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, 0.0f); SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0); - SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS, 0); SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER, 0.0f); // Base crit values (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset @@ -3242,9 +3299,9 @@ void Player::InitStatsForLevel(bool reapplyMods) // save new stats for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i) - SetMaxPower(Powers(i), uint32(GetCreatePowers(Powers(i)))); + SetMaxPower(Powers(i), GetCreatePowers(Powers(i))); - SetMaxHealth(classInfo.basehealth); // stamina bonus will applied later + SetMaxHealth(basehp); // stamina bonus will applied later // cleanup mounted state (it will set correctly at aura loading if player saved at mount. SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); @@ -3277,10 +3334,9 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFullHealth(); SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); - if (GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE)) + if ((uint32)GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE)) SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE)); - SetPower(POWER_FOCUS, 0); - SetPower(POWER_HAPPINESS, 0); + SetPower(POWER_FOCUS, GetMaxPower(POWER_FOCUS)); SetPower(POWER_RUNIC_POWER, 0); // update level to hunter/summon pet @@ -3312,7 +3368,7 @@ void Player::SendInitialSpells() data << uint32(itr->first); data << uint16(0); // it's not slot id - spellCount +=1; + ++spellCount; } data.put<uint16>(countPos, spellCount); // write real count value @@ -3327,7 +3383,7 @@ void Player::SendInitialSpells() data << uint32(itr->first); - data << uint16(itr->second.itemid); // cast item id + data << uint32(itr->second.itemid); // cast item id data << uint16(sEntry->Category); // spell category // send infinity cooldown in special format @@ -3373,15 +3429,15 @@ void Player::RemoveMail(uint32 id) void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError, uint32 item_guid, uint32 item_count) { WorldPacket data(SMSG_SEND_MAIL_RESULT, (4+4+4+(mailError == MAIL_ERR_EQUIP_ERROR?4:(mailAction == MAIL_ITEM_TAKEN?4+4:0)))); - data << (uint32) mailId; - data << (uint32) mailAction; - data << (uint32) mailError; + data << uint32(mailId); + data << uint32(mailAction); + data << uint32(mailError); if (mailError == MAIL_ERR_EQUIP_ERROR) - data << (uint32) equipError; + data << uint32(equipError); else if (mailAction == MAIL_ITEM_TAKEN) { - data << (uint32) item_guid; // item guid low? - data << (uint32) item_count; // item count? + data << uint32(item_guid); // item guid low? + data << uint32(item_count); // item count? } GetSession()->SendPacket(&data); } @@ -3468,8 +3524,8 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) return false; } - PlayerTalentMap::iterator itr = m_talents[spec]->find(spellId); - if (itr != m_talents[spec]->end()) + PlayerTalentMap::iterator itr = GetTalentMap(spec)->find(spellId); + if (itr != GetTalentMap(spec)->end()) itr->second->state = PLAYERSPELL_UNCHANGED; else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId)) { @@ -3482,8 +3538,8 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) if (!rankSpellId || rankSpellId == spellId) continue; - itr = m_talents[spec]->find(rankSpellId); - if (itr != m_talents[spec]->end()) + itr = GetTalentMap(spec)->find(rankSpellId); + if (itr != GetTalentMap(spec)->end()) itr->second->state = PLAYERSPELL_REMOVED; } } @@ -3494,7 +3550,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) newtalent->state = state; newtalent->spec = spec; - (*m_talents[spec])[spellId] = newtalent; + (*GetTalentMap(spec))[spellId] = newtalent; return true; } return false; @@ -3771,7 +3827,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent } // update used talent points count - m_usedTalentCount += talentCost; + SetUsedTalentCount(GetUsedTalentCount() + talentCost); // update free primary prof.points (if any, can be none in case GM .learn prof. learning) if (uint32 freeProfs = GetFreePrimaryProfessionPoints()) @@ -3811,12 +3867,6 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent if (!pSkill) continue; - if (!Has310Flyer(false) && pSkill->id == SKILL_MOUNTS) - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - spellInfo->Effects[i].CalcValue() == 310) - SetHas310Flyer(true); - if (HasSkill(pSkill->id)) continue; @@ -3861,11 +3911,11 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent // not ranked skills for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx) { - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE, _spell_idx->second->skillId); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE, _spell_idx->second->skillId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId); } // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell @@ -3923,9 +3973,9 @@ void Player::learnSpell(uint32 spell_id, bool dependent) // prevent duplicated entires in spell book, also not send if not in world (loading) if (learning && IsInWorld()) { - WorldPacket data(SMSG_LEARNED_SPELL, 6); + WorldPacket data(SMSG_LEARNED_SPELL, 8); data << uint32(spell_id); - data << uint16(0); + data << uint32(0); GetSession()->SendPacket(&data); } @@ -4007,10 +4057,10 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) uint32 talentCosts = GetTalentSpellCost(spell_id); if (talentCosts > 0 && giveTalentPoints) { - if (talentCosts < m_usedTalentCount) - m_usedTalentCount -= talentCosts; + if (talentCosts < GetUsedTalentCount()) + SetUsedTalentCount(GetUsedTalentCount() - talentCosts); else - m_usedTalentCount = 0; + SetUsedTalentCount(0); } // update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning) @@ -4081,16 +4131,6 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) SetSkill(pSkill->id, GetSkillStep(pSkill->id), 0, 0); } - - // most likely will never be used, haven't heard of cases where players unlearn a mount - if (Has310Flyer(false) && _spell_idx->second->skillId == SKILL_MOUNTS) - { - if (spellInfo) - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - spellInfo->Effects[i].CalcValue() == 310) - Has310Flyer(true, spell_id); // with true as first argument its also used to set/remove the flag - } } } @@ -4145,8 +4185,19 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) if (spell_id == 46917 && m_canTitanGrip) SetCanTitanGrip(false); - if (spell_id == 674 && m_canDualWield) - SetCanDualWield(false); + if (m_canDualWield) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id); + if (spellInfo->IsPassive()) + { + for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + if (spellInfo->Effects[i].Effect == SPELL_EFFECT_DUAL_WIELD) + { + SetCanDualWield(false); + break; + } + } + } if (sWorld->getBoolConfig(CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN)) AutoUnequipOffhandIfNeed(); @@ -4160,40 +4211,6 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) } } -bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId) -{ - if (!checkAllSpells) - return m_ExtraFlags & PLAYER_EXTRA_HAS_310_FLYER; - else - { - SetHas310Flyer(false); - SpellInfo const* spellInfo; - for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) - { - if (itr->first == excludeSpellId) - continue; - - SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(itr->first); - for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) - { - if (_spell_idx->second->skillId != SKILL_MOUNTS) - break; // We can break because mount spells belong only to one skillline (at least 310 flyers do) - - spellInfo = sSpellMgr->GetSpellInfo(itr->first); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - spellInfo->Effects[i].CalcValue() == 310) - { - SetHas310Flyer(true); - return true; - } - } - } - } - - return false; -} - void Player::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */) { m_spellCooldowns.erase(spell_id); @@ -4344,31 +4361,31 @@ void Player::_SaveSpellCooldowns(SQLTransaction& trans) trans->Append(ss.str().c_str()); } -uint32 Player::resetTalentsCost() const +uint32 Player::GetNextResetTalentsCost() const { // The first time reset costs 1 gold - if (m_resetTalentsCost < 1*GOLD) + if (GetTalentResetCost() < 1*GOLD) return 1*GOLD; // then 5 gold - else if (m_resetTalentsCost < 5*GOLD) + else if (GetTalentResetCost() < 5*GOLD) return 5*GOLD; // After that it increases in increments of 5 gold - else if (m_resetTalentsCost < 10*GOLD) + else if (GetTalentResetCost() < 10*GOLD) return 10*GOLD; else { - uint64 months = (sWorld->GetGameTime() - m_resetTalentsTime)/MONTH; + uint64 months = (sWorld->GetGameTime() - GetTalentResetTime())/MONTH; if (months > 0) { // This cost will be reduced by a rate of 5 gold per month - int32 new_cost = int32(m_resetTalentsCost - 5*GOLD*months); + int32 new_cost = int32(GetTalentResetCost() - 5*GOLD*months); // to a minimum of 10 gold. return (new_cost < 10*GOLD ? 10*GOLD : new_cost); } else { // After that it increases in increments of 5 gold - int32 new_cost = m_resetTalentsCost + 5*GOLD; + int32 new_cost = GetTalentResetCost() + 5*GOLD; // until it hits a cap of 50 gold. if (new_cost > 50*GOLD) new_cost = 50*GOLD; @@ -4377,7 +4394,7 @@ uint32 Player::resetTalentsCost() const } } -bool Player::resetTalents(bool no_cost) +bool Player::ResetTalents(bool no_cost) { sScriptMgr->OnPlayerTalentsReset(this, no_cost); @@ -4387,7 +4404,7 @@ bool Player::resetTalents(bool no_cost) uint32 talentPointsForLevel = CalculateTalentsPoints(); - if (m_usedTalentCount == 0) + if (!GetUsedTalentCount()) { SetFreeTalentPoints(talentPointsForLevel); return false; @@ -4397,9 +4414,9 @@ bool Player::resetTalents(bool no_cost) if (!no_cost && !sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST)) { - cost = resetTalentsCost(); + cost = GetNextResetTalentsCost(); - if (!HasEnoughMoney(cost)) + if (!HasEnoughMoney(uint64(cost))) { SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); return false; @@ -4440,27 +4457,37 @@ bool Player::resetTalents(bool no_cost) if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL) removeSpell(_spellEntry->Effects[i].TriggerSpell, true); // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted - PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]); - if (plrTalent != m_talents[m_activeSpec]->end()) + PlayerTalentMap::iterator plrTalent = GetTalentMap(GetActiveSpec())->find(talentInfo->RankID[rank]); + if (plrTalent != GetTalentMap(GetActiveSpec())->end()) plrTalent->second->state = PLAYERSPELL_REMOVED; } } + // Remove spec specific spells + for (uint32 i = 0; i < MAX_TALENT_TABS; ++i) + { + std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]); + if (specSpells) + for (size_t i = 0; i < specSpells->size(); ++i) + removeSpell(specSpells->at(i), true); + } + + SetPrimaryTalentTree(GetActiveSpec(), 0); + SetFreeTalentPoints(talentPointsForLevel); + SQLTransaction trans = CharacterDatabase.BeginTransaction(); _SaveTalents(trans); _SaveSpells(trans); CharacterDatabase.CommitTransaction(trans); - SetFreeTalentPoints(talentPointsForLevel); - if (!no_cost) { - ModifyMoney(-(int32)cost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1); + ModifyMoney(-(int64)cost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1); - m_resetTalentsCost = cost; - m_resetTalentsTime = time(NULL); + SetTalentResetCost(cost); + SetTalentResetTime(time(NULL)); } /* when prev line will dropped use next line @@ -4474,12 +4501,6 @@ bool Player::resetTalents(bool no_cost) return true; } -void Player::SetFreeTalentPoints(uint32 points) -{ - sScriptMgr->OnPlayerFreeTalentPointsChanged(this, points); - SetUInt32Value(PLAYER_CHARACTER_POINTS1, points); -} - Mail* Player::GetMail(uint32 id) { for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr) @@ -4508,13 +4529,6 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); } - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - { - if (m_items[i] == NULL) - continue; - - m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); - } } Unit::BuildCreateUpdateBlockForPlayer(data, target); @@ -4541,13 +4555,6 @@ void Player::DestroyForPlayer(Player* target, bool onDeath) const m_items[i]->DestroyForPlayer(target); } - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - { - if (m_items[i] == NULL) - continue; - - m_items[i]->DestroyForPlayer(target); - } } } @@ -4560,8 +4567,8 @@ bool Player::HasSpell(uint32 spell) const bool Player::HasTalent(uint32 spell, uint8 spec) const { - PlayerTalentMap::const_iterator itr = m_talents[spec]->find(spell); - return (itr != m_talents[spec]->end() && itr->second->state != PLAYERSPELL_REMOVED); + PlayerTalentMap::const_iterator itr = GetTalentMap(spec)->find(spell); + return (itr != GetTalentMap(spec)->end() && itr->second->state != PLAYERSPELL_REMOVED); } bool Player::HasActiveSpell(uint32 spell) const @@ -4713,7 +4720,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC uint32 sender = mailFields[3].GetUInt32(); std::string subject = mailFields[4].GetString(); std::string body = mailFields[5].GetString(); - uint32 money = mailFields[6].GetUInt32(); + uint64 money = mailFields[6].GetUInt64(); bool has_items = mailFields[7].GetBool(); // We can return mail now @@ -5012,24 +5019,6 @@ void Player::DeleteOldCharacters(uint32 keepDays) } } -void Player::SetMovement(PlayerMovementType pType) -{ - WorldPacket data; - switch (pType) - { - case MOVE_ROOT: data.Initialize(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size()+4); break; - case MOVE_UNROOT: data.Initialize(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size()+4); break; - case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_WATER_WALK, GetPackGUID().size()+4); break; - case MOVE_LAND_WALK: data.Initialize(SMSG_MOVE_LAND_WALK, GetPackGUID().size()+4); break; - default: - sLog->outError(LOG_FILTER_PLAYER, "Player::SetMovement: Unsupported move type (%d), data not sent to client.", pType); - return; - } - data.append(GetPackGUID()); - data << uint32(0); - GetSession()->SendPacket(&data); -} - /* Preconditions: - a resurrectable corpse must not be loaded for the player (only bones) - the player must be in world @@ -5068,9 +5057,9 @@ void Player::BuildPlayerRepop() // convert player body to ghost SetHealth(1); - SetMovement(MOVE_WATER_WALK); + SendMovementSetWaterWalking(true); if (!GetSession()->isLogingOut()) - SetMovement(MOVE_UNROOT); + SetRooted(false); // BG - remove insignia related RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); @@ -5110,8 +5099,8 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) setDeathState(ALIVE); - SetMovement(MOVE_LAND_WALK); - SetMovement(MOVE_UNROOT); + SendMovementSetWaterWalking(false); + SetRooted(false); m_deathTimer = 0; @@ -5122,6 +5111,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) SetPower(POWER_MANA, uint32(GetMaxPower(POWER_MANA)*restore_percent)); SetPower(POWER_RAGE, 0); SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent)); + SetPower(POWER_FOCUS, uint32(GetMaxPower(POWER_FOCUS)*restore_percent)); } // trigger update zone for alive state zone updates @@ -5171,7 +5161,7 @@ void Player::KillPlayer() if (IsFlying() && !GetTransport()) i_motionMaster.MoveFall(); - SetMovement(MOVE_ROOT); + SetRooted(true); StopMirrorTimers(); //disable timers(bars) @@ -5233,12 +5223,10 @@ void Player::CreateCorpse() flags |= CORPSE_FLAG_HIDE_CLOAK; if (InBattleground() && !InArena()) flags |= CORPSE_FLAG_LOOTABLE; // to be able to remove insignia - corpse->SetUInt32Value(CORPSE_FIELD_FLAGS, flags); + corpse->SetUInt32Value(CORPSE_FIELD_FLAGS, flags); corpse->SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, GetNativeDisplayId()); - corpse->SetUInt32Value(CORPSE_FIELD_GUILD, GetGuildId()); - uint32 iDisplayID; uint32 iIventoryType; uint32 _cfi; @@ -5289,9 +5277,6 @@ void Player::DurabilityLossAll(double percent, bool inventory) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) DurabilityLoss(pItem, percent); - // keys not have durability - //for (int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) @@ -5310,6 +5295,8 @@ void Player::DurabilityLoss(Item* item, double percent) if (!pMaxDurability) return; + percent /= GetTotalAuraMultiplier(SPELL_AURA_MOD_DURABILITY_LOSS); + uint32 pDurabilityLoss = uint32(pMaxDurability*percent); if (pDurabilityLoss < 1) @@ -5333,9 +5320,6 @@ void Player::DurabilityPointsLossAll(int32 points, bool inventory) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) DurabilityPointsLoss(pItem, points); - // keys not have durability - //for (int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) @@ -5454,13 +5438,13 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g TotalCost = costs; } - else if (!HasEnoughMoney(costs)) + else if (!HasEnoughMoney(uint64(costs))) { sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "You do not have enough money"); return TotalCost; } else - ModifyMoney(-int32(costs)); + ModifyMoney(-int64(costs)); } } @@ -5567,7 +5551,7 @@ void Player::UpdateLocalChannels(uint32 newZone) if (!cMgr) return; - std::string current_zone_name = current_zone->area_name[GetSession()->GetSessionDbcLocale()]; + std::string current_zone_name = current_zone->area_name; for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) { @@ -5603,7 +5587,7 @@ void Player::UpdateLocalChannels(uint32 newZone) else currentNameExt = current_zone_name.c_str(); - snprintf(new_channel_name_buf, 100, channel->pattern[m_session->GetSessionDbcLocale()], currentNameExt); + snprintf(new_channel_name_buf, 100, channel->pattern, currentNameExt); joinChannel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID); if (usedChannel) @@ -5618,7 +5602,7 @@ void Player::UpdateLocalChannels(uint32 newZone) } } else - joinChannel = cMgr->GetJoinChannel(channel->pattern[m_session->GetSessionDbcLocale()], channel->ChannelID); + joinChannel = cMgr->GetJoinChannel(channel->pattern, channel->ChannelID); } else removeChannel = usedChannel; @@ -5852,16 +5836,13 @@ float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const float Player::OCTRegenHPPerSpirit() { + /* uint8 level = getLevel(); uint32 pclass = getClass(); if (level > GT_MAX_LEVEL) level = GT_MAX_LEVEL; - - GtOCTRegenHPEntry const* baseRatio = sGtOCTRegenHPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); - GtRegenHPPerSptEntry const* moreRatio = sGtRegenHPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); - if (baseRatio == NULL || moreRatio == NULL) - return 0.0f; + */ // Formula from PaperDollFrame script float spirit = GetStat(STAT_SPIRIT); @@ -5869,7 +5850,7 @@ float Player::OCTRegenHPPerSpirit() if (baseSpirit > 50) baseSpirit = 50; float moreSpirit = spirit - baseSpirit; - float regen = baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio; + float regen = baseSpirit + moreSpirit; return regen; } @@ -6046,25 +6027,27 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step) if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return false; - uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos); - uint32 data = GetUInt32Value(valueIndex); - uint32 value = SKILL_VALUE(data); - uint32 max = SKILL_MAX(data); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 + + uint16 value = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset); + uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset); - if ((!max) || (!value) || (value >= max)) + if (!max || !value || value >= max) return false; if (value < max) { - uint32 new_value = value+step; + uint16 new_value = value + step; if (new_value > max) new_value = max; - SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(new_value, max)); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, new_value); if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; + UpdateSkillEnchantments(skill_id, value, new_value); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id); return true; } @@ -6177,37 +6160,39 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return false; - uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 - uint32 data = GetUInt32Value(valueIndex); - uint16 SkillValue = SKILL_VALUE(data); - uint16 MaxValue = SKILL_MAX(data); + uint16 value = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset); + uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset); - if (!MaxValue || !SkillValue || SkillValue >= MaxValue) + if (!max || !value || value >= max) return false; int32 Roll = irand(1, 1000); if (Roll <= Chance) { - uint32 new_value = SkillValue+step; - if (new_value > MaxValue) - new_value = MaxValue; + uint16 new_value = value + step; + if (new_value > max) + new_value = max; - SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(new_value, MaxValue)); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, new_value); if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; + for (size_t i = 0; i < bonusSkillLevelsSize; ++i) { uint32 bsl = bonusSkillLevels[i]; - if (SkillValue < bsl && new_value >= bsl) + if (value < bsl && new_value >= bsl) { learnSkillRewardedSpells(SkillId, new_value); break; } } - UpdateSkillEnchantments(SkillId, SkillValue, new_value); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId); + + UpdateSkillEnchantments(SkillId, value, new_value); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId); sLog->outDebug(LOG_FILTER_PLAYER_SKILLS, "Player::UpdateSkillPro Chance=%3.1f%% taken", Chance / 10.0f); return true; } @@ -6286,16 +6271,12 @@ void Player::ModifySkillBonus(uint32 skillid, int32 val, bool talent) if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return; - uint32 bonusIndex = PLAYER_SKILL_BONUS_INDEX(itr->second.pos); + uint16 field = itr->second.pos / 2 + (talent ? PLAYER_SKILL_TALENT_0 : PLAYER_SKILL_MODIFIER_0); + uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 - uint32 bonus_val = GetUInt32Value(bonusIndex); - int16 temp_bonus = SKILL_TEMP_BONUS(bonus_val); - int16 perm_bonus = SKILL_PERM_BONUS(bonus_val); + uint16 bonus = GetUInt16Value(field, offset); - if (talent) // permanent bonus stored in high part - SetUInt32Value(bonusIndex, MAKE_SKILL_BONUS(temp_bonus, perm_bonus+val)); - else // temporary/item bonus stored in low part - SetUInt32Value(bonusIndex, MAKE_SKILL_BONUS(temp_bonus+val, perm_bonus)); + SetUInt16Value(field, offset, bonus + val); } void Player::UpdateSkillsForLevel() @@ -6318,10 +6299,11 @@ void Player::UpdateSkillsForLevel() if (GetSkillRangeType(pSkill, false) != SKILL_RANGE_LEVEL) continue; - uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos); - uint32 data = GetUInt32Value(valueIndex); - uint32 max = SKILL_MAX(data); - uint32 val = SKILL_VALUE(data); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 + + uint16 val = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset); + uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset); /// update only level dependent max skill values if (max != 1) @@ -6329,13 +6311,16 @@ void Player::UpdateSkillsForLevel() /// maximize skill always if (alwaysMaxSkill) { - SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(maxSkill, maxSkill)); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, maxSkill); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxSkill); if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; } + else if (max != maxconfskill) /// update max skill value if current max skill not maximized { - SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(val, maxSkill)); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, val); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxSkill); if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; } @@ -6353,13 +6338,16 @@ void Player::UpdateSkillsToMaxSkillsForLevel() uint32 pskill = itr->first; if (IsProfessionOrRidingSkill(pskill)) continue; - uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos); - uint32 data = GetUInt32Value(valueIndex); - uint32 max = SKILL_MAX(data); + + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 + + uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset); if (max > 1) { - SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(max, max)); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, max); + if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; } @@ -6381,33 +6369,43 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) //has skill if (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED) { - currVal = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; // itr->second.pos % 2 + currVal = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset); if (newVal) { // if skill value is going down, update enchantments before setting the new value if (newVal < currVal) UpdateSkillEnchantments(id, currVal, newVal); + // update step - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), MAKE_PAIR32(id, step)); + SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, step); // update value - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), MAKE_SKILL_VALUE(newVal, maxVal)); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, newVal); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxVal); + if (itr->second.uState != SKILL_NEW) itr->second.uState = SKILL_CHANGED; + learnSkillRewardedSpells(id, newVal); // if skill value is going up, update enchantments after setting the new value if (newVal > currVal) UpdateSkillEnchantments(id, currVal, newVal); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); + + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); } else //remove { //remove enchantments needing this skill UpdateSkillEnchantments(id, currVal, 0); // clear skill fields - SetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos), 0); - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), 0); - SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos), 0); + SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0); // mark as deleted or simply remove from map if not saved yet if (itr->second.uState != SKILL_NEW) @@ -6425,49 +6423,58 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) else if (newVal) //add { currVal = 0; - for (int i=0; i < PLAYER_MAX_SKILLS; ++i) - if (!GetUInt32Value(PLAYER_SKILL_INDEX(i))) + for (uint32 i = 0; i < PLAYER_MAX_SKILLS; ++i) { - SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id); - if (!pSkill) + uint16 field = i / 2; + uint8 offset = i & 1; // i % 2 + + if (!GetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset)) { - sLog->outError(LOG_FILTER_PLAYER_SKILLS, "Skill not found in SkillLineStore: skill #%u", id); - return; - } + SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id); + if (!pSkill) + { + sLog->outError(LOG_FILTER_GENERAL, "Skill not found in SkillLineStore: skill #%u", id); + return; + } - SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step)); - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(newVal, maxVal)); - UpdateSkillEnchantments(id, currVal, newVal); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); + SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, id); + SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, step); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, newVal); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxVal); - // insert new entry or update if not deleted old entry yet - if (itr != mSkillStatus.end()) - { - itr->second.pos = i; - itr->second.uState = SKILL_CHANGED; - } - else - mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW))); + UpdateSkillEnchantments(id, currVal, newVal); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id); + + // insert new entry or update if not deleted old entry yet + if (itr != mSkillStatus.end()) + { + itr->second.pos = i; + itr->second.uState = SKILL_CHANGED; + } + else + mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW))); - // apply skill bonuses - SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i), 0); + // apply skill bonuses + SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0); - // temporary bonuses - AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL); - for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j) - if ((*j)->GetMiscValue() == int32(id)) + // temporary bonuses + AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL); + for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j) + if ((*j)->GetMiscValue() == int32(id)) (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true); - // permanent bonuses - AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT); - for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j) - if ((*j)->GetMiscValue() == int32(id)) + // permanent bonuses + AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT); + for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j) + if ((*j)->GetMiscValue() == int32(id)) (*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true); - // Learn all spells for skill - learnSkillRewardedSpells(id, newVal); - return; + // Learn all spells for skill + learnSkillRewardedSpells(id, newVal); + return; + } } } } @@ -6490,7 +6497,7 @@ uint16 Player::GetSkillStep(uint16 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - return PAIR32_HIPART(GetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos))); + return GetUInt16Value(PLAYER_SKILL_STEP_0 + itr->second.pos / 2, itr->second.pos & 1); } uint16 Player::GetSkillValue(uint32 skill) const @@ -6502,11 +6509,12 @@ uint16 Player::GetSkillValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; - int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)))); - result += SKILL_TEMP_BONUS(bonus); - result += SKILL_PERM_BONUS(bonus); + int32 result = int32(GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset)); + result += int32(GetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset)); + result += int32(GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset)); return result < 0 ? 0 : result; } @@ -6519,11 +6527,12 @@ uint16 Player::GetMaxSkillValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; - int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)))); - result += SKILL_TEMP_BONUS(bonus); - result += SKILL_PERM_BONUS(bonus); + int32 result = int32(GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset)); + result += int32(GetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset)); + result += int32(GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset)); return result < 0 ? 0 : result; } @@ -6536,7 +6545,10 @@ uint16 Player::GetPureMaxSkillValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - return SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; + + return GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset); } uint16 Player::GetBaseSkillValue(uint32 skill) const @@ -6548,8 +6560,11 @@ uint16 Player::GetBaseSkillValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)))); - result += SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos))); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; + + int32 result = int32(GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset)); + result += int32(GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset)); return result < 0 ? 0 : result; } @@ -6562,7 +6577,10 @@ uint16 Player::GetPureSkillValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - return SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; + + return GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset); } int16 Player::GetSkillPermBonusValue(uint32 skill) const @@ -6574,7 +6592,10 @@ int16 Player::GetSkillPermBonusValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos))); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; + + return GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset); } int16 Player::GetSkillTempBonusValue(uint32 skill) const @@ -6586,13 +6607,15 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) return 0; - return SKILL_TEMP_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos))); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; + + return GetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset); } void Player::SendActionButtons(uint32 state) const { WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4)); - data << uint8(state); /* state can be 0, 1, 2 0 - Looks to be sent when initial action buttons get sent, however on Trinity we use 1 since 0 had some difficulties @@ -6611,8 +6634,9 @@ void Player::SendActionButtons(uint32 state) const } } + data << uint8(state); GetSession()->SendPacket(&data); - sLog->outInfo(LOG_FILTER_NETWORKIO, "SMSG_ACTION_BUTTONS sent '%u' spec '%u' Sent", GetGUIDLow(), m_activeSpec); + sLog->outInfo(LOG_FILTER_NETWORKIO, "Action Buttons for '%u' spec '%u' Sent", GetGUIDLow(), GetActiveSpec()); } bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) @@ -6807,7 +6831,7 @@ void Player::CheckAreaExploreAndOutdoor() { SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId()); if (!areaEntry) @@ -7052,16 +7076,12 @@ void Player::UpdateHonorFields() // update yesterday's contribution if (m_lastHonorUpdateTime >= yesterday) { - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); - // this is the first update today, reset today's contribution - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); SetUInt32Value(PLAYER_FIELD_KILLS, MAKE_PAIR32(0, kills_today)); } else { // no honor/kills yesterday or today, reset - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); SetUInt32Value(PLAYER_FIELD_KILLS, 0); } } @@ -7072,15 +7092,15 @@ void Player::UpdateHonorFields() ///Calculate the amount of honor gained based on the victim ///and the size of the group for which the honor is divided ///An exact honor value can also be given (overriding the calcs) -bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvptoken) +bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvptoken) { // do not reward honor in arenas, but enable onkill spellproc if (InArena()) { - if (!uVictim || uVictim == this || uVictim->GetTypeId() != TYPEID_PLAYER) + if (!victim || victim == this || victim->GetTypeId() != TYPEID_PLAYER) return false; - if (GetBGTeam() == uVictim->ToPlayer()->GetBGTeam()) + if (GetBGTeam() == victim->ToPlayer()->GetBGTeam()) return false; return true; @@ -7105,16 +7125,14 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvpt if (honor_f <= 0) { - if (!uVictim || uVictim == this || uVictim->HasAuraType(SPELL_AURA_NO_PVP_CREDIT)) + if (!victim || victim == this || victim->HasAuraType(SPELL_AURA_NO_PVP_CREDIT)) return false; - victim_guid = uVictim->GetGUID(); + victim_guid = victim->GetGUID(); - if (uVictim->GetTypeId() == TYPEID_PLAYER) + if (Player* plrVictim = victim->ToPlayer()) { - Player* victim = uVictim->ToPlayer(); - - if (GetTeam() == victim->GetTeam() && !sWorld->IsFFAPvPRealm()) + if (GetTeam() == plrVictim->GetTeam() && !sWorld->IsFFAPvPRealm()) return false; uint8 k_level = getLevel(); @@ -7159,7 +7177,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvpt } else { - if (!uVictim->ToCreature()->isRacialLeader()) + if (!victim->ToCreature()->isRacialLeader()) return false; honor_f = 100.0f; // ??? need more info @@ -7167,7 +7185,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvpt } } - if (uVictim != NULL) + if (victim != NULL) { if (groupsize > 1) honor_f /= groupsize; @@ -7192,9 +7210,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvpt GetSession()->SendPacket(&data); // add honor points - ModifyHonorPoints(honor); - - ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, honor, true); + ModifyCurrency(CURRENCY_TYPE_HONOR_POINTS, int32(honor)); if (InBattleground() && honor > 0) { @@ -7206,10 +7222,10 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvpt if (sWorld->getBoolConfig(CONFIG_PVP_TOKEN_ENABLE) && pvptoken) { - if (!uVictim || uVictim == this || uVictim->HasAuraType(SPELL_AURA_NO_PVP_CREDIT)) + if (!victim || victim == this || victim ->HasAuraType(SPELL_AURA_NO_PVP_CREDIT)) return true; - if (uVictim->GetTypeId() == TYPEID_PLAYER) + if (victim->GetTypeId() == TYPEID_PLAYER) { // Check if allowed to receive it in current map uint8 MapType = sWorld->getIntConfig(CONFIG_PVP_TOKEN_MAP_TYPE); @@ -7229,86 +7245,195 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool pvpt return true; } -void Player::SetHonorPoints(uint32 value) -{ - if (value > sWorld->getIntConfig(CONFIG_MAX_HONOR_POINTS)) - value = sWorld->getIntConfig(CONFIG_MAX_HONOR_POINTS); - SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, value); - if (value) - AddKnownCurrency(ITEM_HONOR_POINTS_ID); -} -void Player::SetArenaPoints(uint32 value) +void Player::SendCurrencies() const { - if (value > sWorld->getIntConfig(CONFIG_MAX_ARENA_POINTS)) - value = sWorld->getIntConfig(CONFIG_MAX_ARENA_POINTS); - SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, value); - if (value) - AddKnownCurrency(ITEM_ARENA_POINTS_ID); -} + ByteBuffer currencyData; + WorldPacket packet(SMSG_INIT_CURRENCY, 4 + m_currencies.size()*(5*4 + 1)); + packet.WriteBits(m_currencies.size(), 23); -void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/) -{ - PreparedStatement* stmt = NULL; + for (PlayerCurrenciesMap::const_iterator itr = m_currencies.begin(); itr != m_currencies.end(); ++itr) + { + CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(itr->first); + if (!entry) // should never happen + continue; - int32 newValue = int32(GetHonorPoints()) + value; - if (newValue < 0) - newValue = 0; - SetHonorPoints(uint32(newValue)); + uint32 precision = (entry->Flags & 0x8) ? 100 : 1; + uint32 weekCount = itr->second.weekCount / precision; + uint32 weekCap = _GetCurrencyWeekCap(entry) / precision; - if (trans && !trans->null()) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_HONOR_POINTS); - stmt->setUInt32(0, newValue); - stmt->setUInt32(1, GetGUIDLow()); - (*trans)->Append(stmt); - } -} + packet.WriteBit(weekCount); + packet.WriteBits(0, 4); // some flags + packet.WriteBit(weekCap); + packet.WriteBit(0); // season total earned -void Player::ModifyArenaPoints(int32 value, SQLTransaction* trans /*=NULL*/) -{ - PreparedStatement* stmt = NULL; + currencyData << uint32(itr->second.totalCount / precision); + if (weekCap) + currencyData << uint32(weekCap); - int32 newValue = int32(GetArenaPoints()) + value; - if (newValue < 0) - newValue = 0; - SetArenaPoints(uint32(newValue)); + //if (seasonTotal) + // currencyData << uint32(seasonTotal); - if (trans && !trans->null()) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_ARENA_POINTS); - stmt->setUInt32(0, newValue); - stmt->setUInt32(1, GetGUIDLow()); - (*trans)->Append(stmt); + currencyData << uint32(entry->ID); + if (weekCount) + currencyData << uint32(weekCount); } + + packet.FlushBits(); + packet.append(currencyData); + GetSession()->SendPacket(&packet); +} + +uint32 Player::GetCurrency(uint32 id) const +{ + PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id); + return itr != m_currencies.end() ? itr->second.totalCount : 0; +} + +bool Player::HasCurrency(uint32 id, uint32 count) const +{ + PlayerCurrenciesMap::const_iterator itr = m_currencies.find(id); + return itr != m_currencies.end() && itr->second.totalCount >= count; +} + +void Player::ModifyCurrency(uint32 id, int32 count) +{ + if (!count) + return; + + CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id); + ASSERT(currency); + + int32 precision = currency->Flags & 0x8 ? 100 : 1; + uint32 oldTotalCount = 0; + uint32 oldWeekCount = 0; + PlayerCurrenciesMap::iterator itr = m_currencies.find(id); + if (itr == m_currencies.end()) + { + PlayerCurrency cur; + cur.state = PLAYERCURRENCY_NEW; + cur.totalCount = 0; + cur.weekCount = 0; + m_currencies[id] = cur; + itr = m_currencies.find(id); + } + else + { + oldTotalCount = itr->second.totalCount; + oldWeekCount = itr->second.weekCount; + } + + int32 newTotalCount = int32(oldTotalCount) + count; + if (newTotalCount < 0) + newTotalCount = 0; + + int32 newWeekCount = int32(oldWeekCount) + (count > 0 ? count : 0); + if (newWeekCount < 0) + newWeekCount = 0; + + if (currency->TotalCap && int32(currency->TotalCap) < newTotalCount) + { + int32 delta = newTotalCount - int32(currency->TotalCap); + newTotalCount = int32(currency->TotalCap); + newWeekCount -= delta; + } + + // TODO: fix conquest points + uint32 weekCap = _GetCurrencyWeekCap(currency); + if (weekCap && int32(weekCap) < newTotalCount) + { + int32 delta = newWeekCount - int32(weekCap); + newWeekCount = int32(weekCap); + newTotalCount -= delta; + } + + // if we change total, we must change week + ASSERT(((newTotalCount-oldTotalCount) != 0) == ((newWeekCount-oldWeekCount) != 0)); + + if (newTotalCount != oldTotalCount) + { + if(itr->second.state != PLAYERCURRENCY_NEW) + itr->second.state = PLAYERCURRENCY_CHANGED; + + itr->second.totalCount = newTotalCount; + itr->second.weekCount = newWeekCount; + + // probably excessive checks + if (IsInWorld() && !GetSession()->PlayerLoading()) + { + if (count > 0) + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count); + + WorldPacket packet(SMSG_UPDATE_CURRENCY, 12); + packet << uint32(id); + packet << uint32(weekCap ? (newWeekCount / precision) : 0); + packet << uint32(newTotalCount / precision); + GetSession()->SendPacket(&packet); + } + } +} + +void Player::SetCurrency(uint32 id, uint32 count) +{ + ModifyCurrency(id, int32(count) - GetCurrency(id)); +} + +uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const +{ + uint32 cap = currency->WeekCap; + switch (currency->ID) + { + case CURRENCY_TYPE_CONQUEST_POINTS: + { + // TODO: implement + cap = 0; + break; + } + case CURRENCY_TYPE_HONOR_POINTS: + { + uint32 honorcap = sWorld->getIntConfig(CONFIG_MAX_HONOR_POINTS); + if (honorcap > 0) + cap = honorcap; + break; + } + case CURRENCY_TYPE_JUSTICE_POINTS: + { + uint32 justicecap = sWorld->getIntConfig(CONFIG_MAX_JUSTICE_POINTS); + if (justicecap > 0) + cap = justicecap; + break; + } + } + + if (cap != currency->WeekCap && IsInWorld() && !GetSession()->PlayerLoading()) + { + WorldPacket packet(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, 8); + packet << uint32(cap / ((currency->Flags & 0x8) ? 100 : 1)); + packet << uint32(currency->ID); + GetSession()->SendPacket(&packet); + } + + return cap; } uint32 Player::GetGuildIdFromDB(uint64 guid) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER); stmt->setUInt32(0, GUID_LOPART(guid)); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (!result) - return 0; + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + return result->Fetch()[0].GetUInt32(); - uint32 id = result->Fetch()[0].GetUInt32(); - return id; + return 0; } uint8 Player::GetRankFromDB(uint64 guid) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER); stmt->setUInt32(0, GUID_LOPART(guid)); - PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) + return result->Fetch()[1].GetUInt8(); - if (result) - { - uint32 v = result->Fetch()[1].GetUInt8(); - return v; - } - else - return 0; + return 0; } uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) @@ -7582,8 +7707,8 @@ void Player::DuelComplete(DuelCompleteType type) { data.Initialize(SMSG_DUEL_WINNER, (1+20)); // we guess size data << uint8(type == DUEL_WON ? 0 : 1); // 0 = just won; 1 = fled - data << duel->opponent->GetName(); data << GetName(); + data << duel->opponent->GetName(); SendMessageToSet(&data, true); } @@ -7608,10 +7733,10 @@ void Player::DuelComplete(DuelCompleteType type) } break; case DUEL_WON: - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL, 1); if (duel->opponent) { - duel->opponent->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1); + duel->opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1); //Credit for quest Death's Challenge if (getClass() == CLASS_DEATH_KNIGHT && duel->opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE) @@ -7706,10 +7831,6 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply) _ApplyWeaponDependentAuraMods(item, WeaponAttackType(attacktype), apply); _ApplyItemBonuses(proto, slot, apply); - - if (slot == EQUIPMENT_SLOT_RANGED) - _ApplyAmmoBonuses(); - ApplyItemEquipSpell(item, apply); ApplyEnchantment(item, apply); @@ -7730,7 +7851,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (ssd && ssd_level > ssd->MaxLevel) ssd_level = ssd->MaxLevel; - ScalingStatValuesEntry const* ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL; + ScalingStatValuesEntry const* ssv = ssd ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL; if (only_level_scale && !ssv) return; @@ -7744,12 +7865,10 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (ssd->StatMod[i] < 0) continue; statType = ssd->StatMod[i]; - val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000; + val = (ssv->GetStatMultiplier(proto->InventoryType) * ssd->Modifier[i]) / 10000; } else { - if (i >= proto->StatsCount) - continue; statType = proto->ItemStat[i].ItemStatType; val = proto->ItemStat[i].ItemStatValue; } @@ -7882,9 +8001,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply case ITEM_MOD_RANGED_ATTACK_POWER: HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply); break; -// case ITEM_MOD_FERAL_ATTACK_POWER: -// ApplyFeralAPBonus(int32(val), apply); -// break; case ITEM_MOD_MANA_REGENERATION: ApplyManaRegenBonus(int32(val), apply); break; @@ -7901,23 +8017,36 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -val, apply); m_spellPenetrationItemMod += apply ? val : -val; break; - // deprecated item mods - case ITEM_MOD_SPELL_HEALING_DONE: - case ITEM_MOD_SPELL_DAMAGE_DONE: + case ITEM_MOD_FIRE_RESISTANCE: + HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_FROST_RESISTANCE: + HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_HOLY_RESISTANCE: + HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_SHADOW_RESISTANCE: + HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_NATURE_RESISTANCE: + HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(val), apply); + break; + case ITEM_MOD_ARCANE_RESISTANCE: + HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(val), apply); break; } } // Apply Spell Power from ScalingStatValue if set - if (ssv) - if (int32 spellbonus = ssv->getSpellBonus(proto->ScalingStatValue)) + if (ssv && proto->Flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON) + if (int32 spellbonus = int32(ssv->Spellpower)) ApplySpellPowerBonus(spellbonus, apply); // If set ScalingStatValue armor get it or use item armor uint32 armor = proto->Armor; - if (ssv) - if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) - armor = ssvarmor; + if (ssv && proto->Class == ITEM_CLASS_ARMOR) + armor = ssv->GetArmor(proto->InventoryType, proto->SubClass - 1); if (armor) { @@ -7942,27 +8071,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (proto->ArmorDamageModifier > 0) HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply); - if (proto->Block) - HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply); - - if (proto->HolyRes) - HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(proto->HolyRes), apply); - - if (proto->FireRes) - HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(proto->FireRes), apply); - - if (proto->NatureRes) - HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(proto->NatureRes), apply); - - if (proto->FrostRes) - HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(proto->FrostRes), apply); - - if (proto->ShadowRes) - HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(proto->ShadowRes), apply); - - if (proto->ArcaneRes) - HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply); - WeaponAttackType attType = BASE_ATTACK; if (slot == EQUIPMENT_SLOT_RANGED && ( @@ -7978,23 +8086,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (CanUseAttackType(attType)) _ApplyWeaponDamage(slot, proto, ssv, apply); - - - // Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue) - if (getClass() == CLASS_DRUID) - { - int32 dpsMod = 0; - int32 feral_bonus = 0; - if (ssv) - { - dpsMod = ssv->getDPSMod(proto->ScalingStatValue); - feral_bonus += ssv->getFeralBonus(proto->ScalingStatValue); - } - - feral_bonus += proto->getFeralBonus(dpsMod); - if (feral_bonus) - ApplyFeralAPBonus(feral_bonus, apply); - } } void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply) @@ -8013,18 +8104,20 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt attType = OFF_ATTACK; } - float minDamage = proto->Damage[0].DamageMin; - float maxDamage = proto->Damage[0].DamageMax; + float minDamage = proto->DamageMin; + float maxDamage = proto->DamageMax; // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage + int32 extraDPS = 0; if (ssv) { - int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue); + float damageMultiplier = 0.0f; + extraDPS = ssv->GetDPSAndDamageMultiplier(proto->SubClass, proto->Flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON, &damageMultiplier); if (extraDPS) { float average = extraDPS * proto->Delay / 1000.0f; - minDamage = 0.7f * average; - maxDamage = 1.3f * average; + minDamage = (1.0f - damageMultiplier) * average; + maxDamage = (1.0f + damageMultiplier) * average; } } @@ -8297,7 +8390,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 float chance = (float)spellInfo->ProcChance; - if (spellData.SpellPPMRate) + if (proto->SpellPPMRate) { if (spellData.SpellId == 52781) // Persuasive Strike { @@ -8312,7 +8405,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 } } uint32 WeaponSpeed = GetAttackTime(attType); - chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate, spellInfo); + chance = GetPPMProcChance(WeaponSpeed, proto->SpellPPMRate, spellInfo); } else if (chance > 100.0f) { @@ -8327,6 +8420,9 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 // item combat enchantments for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) { + if (e_slot > PRISMATIC_ENCHANTMENT_SLOT || e_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot)); SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); if (!pEnchant) @@ -8449,6 +8545,9 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 // Item enchantments spells casted at use for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) { + if (e_slot > PRISMATIC_ENCHANTMENT_SLOT || e_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot)); SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); if (!pEnchant) @@ -8515,9 +8614,6 @@ void Player::_RemoveAllItemMods() _ApplyWeaponDependentAuraMods(m_items[i], WeaponAttackType(attacktype), false); _ApplyItemBonuses(proto, i, false); - - if (i == EQUIPMENT_SLOT_RANGED) - _ApplyAmmoBonuses(); } } @@ -8544,9 +8640,6 @@ void Player::_ApplyAllItemMods() _ApplyWeaponDependentAuraMods(m_items[i], WeaponAttackType(attacktype), true); _ApplyItemBonuses(proto, i, true); - - if (i == EQUIPMENT_SLOT_RANGED) - _ApplyAmmoBonuses(); } } @@ -8591,63 +8684,6 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply) } } -void Player::_ApplyAmmoBonuses() -{ - // check ammo - uint32 ammo_id = GetUInt32Value(PLAYER_AMMO_ID); - if (!ammo_id) - return; - - float currentAmmoDPS; - - ItemTemplate const* ammo_proto = sObjectMgr->GetItemTemplate(ammo_id); - if (!ammo_proto || ammo_proto->Class != ITEM_CLASS_PROJECTILE || !CheckAmmoCompatibility(ammo_proto)) - currentAmmoDPS = 0.0f; - else - currentAmmoDPS = (ammo_proto->Damage[0].DamageMin + ammo_proto->Damage[0].DamageMax) / 2; - - if (currentAmmoDPS == GetAmmoDPS()) - return; - - m_ammoDPS = currentAmmoDPS; - - if (CanModifyStats()) - UpdateDamagePhysical(RANGED_ATTACK); -} - -bool Player::CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const -{ - if (!ammo_proto) - return false; - - // check ranged weapon - Item* weapon = GetWeaponForAttack(RANGED_ATTACK); - if (!weapon || weapon->IsBroken()) - return false; - - ItemTemplate const* weapon_proto = weapon->GetTemplate(); - if (!weapon_proto || weapon_proto->Class != ITEM_CLASS_WEAPON) - return false; - - // check ammo ws. weapon compatibility - switch (weapon_proto->SubClass) - { - case ITEM_SUBCLASS_WEAPON_BOW: - case ITEM_SUBCLASS_WEAPON_CROSSBOW: - if (ammo_proto->SubClass != ITEM_SUBCLASS_ARROW) - return false; - break; - case ITEM_SUBCLASS_WEAPON_GUN: - if (ammo_proto->SubClass != ITEM_SUBCLASS_BULLET) - return false; - break; - default: - return false; - } - - return true; -} - /* If in a battleground a player dies, and an enemy removes the insignia, the player's bones is lootable Called by remove insignia spell effect */ void Player::RemovedInsignia(Player* looterPlr) @@ -8984,7 +9020,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type) // need know merged fishing/corpse loot type for achievements loot->loot_type = loot_type; - WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size + WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1); // we guess size data << uint64(guid); data << uint8(loot_type); data << LootView(*loot, this, permission); @@ -9014,9 +9050,10 @@ void Player::SendNotifyLootItemRemoved(uint8 lootSlot) void Player::SendUpdateWorldState(uint32 Field, uint32 Value) { - WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8); + WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4+1); data << Field; data << Value; + data << uint8(0); GetSession()->SendPacket(&data); } @@ -9705,7 +9742,7 @@ void Player::SendTalentWipeConfirm(uint64 guid) { WorldPacket data(MSG_TALENT_WIPE_CONFIRM, (8+4)); data << uint64(guid); - uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : resetTalentsCost(); + uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : GetNextResetTalentsCost(); data << cost; GetSession()->SendPacket(&data); } @@ -9918,7 +9955,7 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c if (playerClass == CLASS_SHAMAN) slots[0] = EQUIPMENT_SLOT_RANGED; break; - case ITEM_SUBCLASS_ARMOR_MISC: + case ITEM_SUBCLASS_ARMOR_MISCELLANEOUS: if (playerClass == CLASS_WARLOCK) slots[0] = EQUIPMENT_SLOT_RANGED; break; @@ -9989,14 +10026,6 @@ InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const return EQUIP_ERR_OK; } - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == item) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return EQUIP_ERR_OK; - } for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) if (Bag* pBag = GetBagByPos(i)) @@ -10021,11 +10050,6 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const if (pItem != skipItem && pItem->GetEntry() == item) count += pItem->GetCount(); - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem && pItem->GetEntry() == item) - count += pItem->GetCount(); - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) if (Bag* pBag = GetBagByPos(i)) count += pBag->GetItemCount(item, skipItem); @@ -10068,13 +10092,6 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte if (pProto->ItemLimitCategory == limitCategory) count += pItem->GetCount(); - for (int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem != skipItem) - if (ItemTemplate const* pProto = pItem->GetTemplate()) - if (pProto->ItemLimitCategory == limitCategory) - count += pItem->GetCount(); - for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) if (Bag* pBag = GetBagByPos(i)) count += pBag->GetItemCountWithLimitCategory(limitCategory, skipItem); @@ -10100,11 +10117,6 @@ Item* Player::GetItemByGuid(uint64 guid) const if (pItem->GetGUID() == guid) return pItem; - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetGUID() == guid) - return pItem; - for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetGUID() == guid) @@ -10136,7 +10148,7 @@ Item* Player::GetItemByPos(uint16 pos) const Item* Player::GetItemByPos(uint8 bag, uint8 slot) const { - if (bag == INVENTORY_SLOT_BAG_0 && (slot < BANK_SLOT_BAG_END || (slot >= KEYRING_SLOT_START && slot < CURRENCYTOKEN_SLOT_END))) + if (bag == INVENTORY_SLOT_BAG_0 && slot < BANK_SLOT_BAG_END) return m_items[slot]; else if (Bag* pBag = GetBagByPos(bag)) return pBag->GetItemByPos(slot); @@ -10218,8 +10230,6 @@ bool Player::IsInventoryPos(uint8 bag, uint8 slot) return true; if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END) return true; - if (bag == INVENTORY_SLOT_BAG_0 && (slot >= KEYRING_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)) - return true; return false; } @@ -10278,10 +10288,6 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_END) return true; - // keyring slots - if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END) - return true; - // bank main slots if (slot >= BANK_SLOT_ITEM_START && slot < BANK_SLOT_ITEM_END) return true; @@ -10321,16 +10327,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const return true; } } - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - { - Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) - { - tempcount += pItem->GetCount(); - if (tempcount >= count) - return true; - } - } + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { if (Bag* pBag = GetBagByPos(i)) @@ -10516,12 +10513,7 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const if (pItem && IsTotemCategoryCompatiableWith(pItem->GetTemplate()->TotemCategory, TotemCategory)) return true; } - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - { - pItem = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && IsTotemCategoryCompatiableWith(pItem->GetTemplate()->TotemCategory, TotemCategory)) - return true; - } + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { if (Bag* pBag = GetBagByPos(i)) @@ -10555,14 +10547,6 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP { if (bag == INVENTORY_SLOT_BAG_0) { - // keyring case - if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS)) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - - // currencytoken case - if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->IsCurrencyToken())) - return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - // prevent cheating if ((slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END) || slot >= PLAYER_SLOT_END) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; @@ -10808,24 +10792,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des { if (bag == INVENTORY_SLOT_BAG_0) // inventory { - res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot); if (res != EQUIP_ERR_OK) { @@ -10873,67 +10839,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // search free slot in bag for place to if (bag == INVENTORY_SLOT_BAG_0) // inventory { - // search free slot - keyring case - if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS) - { - uint32 keyringSize = GetMaxKeyringSize(); - res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, KEYRING_SLOT_START+keyringSize, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - - res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if (pProto->IsCurrencyToken()) - { - res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot); if (res != EQUIP_ERR_OK) { @@ -10982,24 +10887,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // search stack for merge to if (pProto->Stackable != 1) { - res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, true, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot); if (res != EQUIP_ERR_OK) { @@ -11059,48 +10946,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des // search free slot - special bag case if (pProto->BagFamily) { - if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS) - { - uint32 keyringSize = GetMaxKeyringSize(); - res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, KEYRING_SLOT_START+keyringSize, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - else if (pProto->IsCurrencyToken()) - { - res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot); - if (res != EQUIP_ERR_OK) - { - if (no_space_count) - *no_space_count = count + no_similar_count; - return res; - } - - if (count == 0) - { - if (no_similar_count == 0) - return EQUIP_ERR_OK; - - if (no_space_count) - *no_space_count = count + no_similar_count; - return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; - } - } - for (uint32 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { res = CanStoreItem_InBag(i, dest, pProto, count, false, false, pItem, bag, slot); @@ -11172,13 +11017,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const // fill space table int inv_slot_items[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START]; int inv_bags[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; - int inv_keys[KEYRING_SLOT_END - KEYRING_SLOT_START]; - int inv_tokens[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START]; memset(inv_slot_items, 0, sizeof(int) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START)); memset(inv_bags, 0, sizeof(int) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE); - memset(inv_keys, 0, sizeof(int) * (KEYRING_SLOT_END - KEYRING_SLOT_START)); - memset(inv_tokens, 0, sizeof(int) * (CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START)); for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) { @@ -11187,20 +11028,6 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const inv_slot_items[i - INVENTORY_SLOT_ITEM_START] = pItem2->GetCount(); } - for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) - { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsInTrade()) - inv_keys[i - KEYRING_SLOT_START] = pItem2->GetCount(); - } - - for (uint8 i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++) - { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsInTrade()) - inv_tokens[i - CURRENCYTOKEN_SLOT_START] = pItem2->GetCount(); - } - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) @@ -11246,32 +11073,6 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const { bool b_found = false; - for (uint8 t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; ++t) - { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize()) - { - inv_keys[t-KEYRING_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) - continue; - - for (int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) - { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize()) - { - inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount(); - b_found = true; - break; - } - } - if (b_found) - continue; - for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) { pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); @@ -11312,38 +11113,6 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const if (pProto->BagFamily) { bool b_found = false; - if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS) - { - uint32 keyringSize = GetMaxKeyringSize(); - for (uint32 t = KEYRING_SLOT_START; t < KEYRING_SLOT_START+keyringSize; ++t) - { - if (inv_keys[t-KEYRING_SLOT_START] == 0) - { - inv_keys[t-KEYRING_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) - continue; - - if (pProto->IsCurrencyToken()) - { - for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) - { - if (inv_tokens[t-CURRENCYTOKEN_SLOT_START] == 0) - { - inv_tokens[t-CURRENCYTOKEN_SLOT_START] = 1; - b_found = true; - break; - } - } - } - - if (b_found) - continue; for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t) { @@ -11622,8 +11391,7 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest return EQUIP_ERR_DONT_OWN_THAT_ITEM; // Currency tokens are not supposed to be swapped out of their hidden bag - uint8 pItemslot = pItem->GetSlot(); - if (pItemslot >= CURRENCYTOKEN_SLOT_START && pItemslot < CURRENCYTOKEN_SLOT_END) + if(pItem->IsCurrencyToken()) { sLog->outError(LOG_FILTER_PLAYER, "Possible hacking attempt: Player %s [guid: %u] tried to move token [guid: %u, entry: %u] out of the currency bag!", GetName(), GetGUIDLow(), pItem->GetGUIDLow(), pProto->ItemId); @@ -11939,7 +11707,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje if (proto->Class == ITEM_CLASS_WEAPON && GetSkillValue(item_weapon_skills[proto->SubClass]) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISC && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK) + if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISCELLANEOUS && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK) { if (_class == CLASS_WARRIOR || _class == CLASS_PALADIN || _class == CLASS_DEATH_KNIGHT) { @@ -11974,71 +11742,6 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje return EQUIP_ERR_OK; } -InventoryResult Player::CanUseAmmo(uint32 item) const -{ - sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "STORAGE: CanUseAmmo item = %u", item); - if (!isAlive()) - return EQUIP_ERR_YOU_ARE_DEAD; - //if (isStunned()) - // return EQUIP_ERR_YOU_ARE_STUNNED; - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item); - if (pProto) - { - if (pProto->InventoryType!= INVTYPE_AMMO) - return EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE; - - InventoryResult res = CanUseItem(pProto); - if (res != EQUIP_ERR_OK) - return res; - - /*if (GetReputationMgr().GetReputation() < pProto->RequiredReputation) - return EQUIP_ERR_CANT_EQUIP_REPUTATION; - */ - - // Requires No Ammo - if (HasAura(46699)) - return EQUIP_ERR_BAG_FULL6; - - return EQUIP_ERR_OK; - } - return EQUIP_ERR_ITEM_NOT_FOUND; -} - -void Player::SetAmmo(uint32 item) -{ - if (!item) - return; - - // already set - if (GetUInt32Value(PLAYER_AMMO_ID) == item) - return; - - // check ammo - if (item) - { - InventoryResult msg = CanUseAmmo(item); - if (msg != EQUIP_ERR_OK) - { - SendEquipError(msg, NULL, NULL, item); - return; - } - } - - SetUInt32Value(PLAYER_AMMO_ID, item); - - _ApplyAmmoBonuses(); -} - -void Player::RemoveAmmo() -{ - SetUInt32Value(PLAYER_AMMO_ID, 0); - - m_ammoDPS = 0.0f; - - if (CanModifyStats()) - UpdateDamagePhysical(RANGED_ATTACK); -} - Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update, int32 randomPropertyId) { AllowedLooterSet allowedLooters; @@ -12056,8 +11759,8 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update if (pItem) { ItemAddedQuestCheck(item, count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, item, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, item, 1); if (randomPropertyId) pItem->SetItemRandomProperties(randomPropertyId); pItem = StoreItem(dest, pItem, update); @@ -12146,10 +11849,6 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool pItem->SetSlot(slot); pItem->SetContainer(NULL); - - // need update known currency - if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END) - AddKnownCurrency(pItem->GetEntry()); } else pBag->StoreItem(slot, pItem, update); @@ -12227,7 +11926,7 @@ Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update) if (Item* pItem = Item::CreateItem(item, 1, this)) { ItemAddedQuestCheck(item, 1); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1); return EquipItem(pos, pItem, update); } @@ -12337,8 +12036,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) } // only for full equip instead adding to stack - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); return pItem; } @@ -12359,8 +12058,8 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem) pItem->SendUpdateToPlayer(this); } - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); } } @@ -12368,7 +12067,7 @@ void Player::SetVisibleItemSlot(uint8 slot, Item* pItem) { if (pItem) { - SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry()); + SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetVisibleEntry()); SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 0, pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 1, pItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)); } @@ -12506,7 +12205,7 @@ void Player::MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool { // update quest counters ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); // store item Item* pLastItem = StoreItem(dest, pItem, update); @@ -12655,34 +12354,6 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ } } - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - { - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - { - if (pItem->GetEntry() == item && !pItem->IsInTrade()) - { - if (pItem->GetCount() + remcount <= count) - { - // all keys can be unequipped - remcount += pItem->GetCount(); - DestroyItem(INVENTORY_SLOT_BAG_0, i, update); - - if (remcount >= count) - return; - } - else - { - ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount); - pItem->SetCount(pItem->GetCount() - count + remcount); - if (IsInWorld() && update) - pItem->SendUpdateToPlayer(this); - pItem->SetState(ITEM_CHANGED, this); - return; - } - } - } - } - // in inventory bags for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) { @@ -12760,11 +12431,6 @@ void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone) if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone)) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone)) - DestroyItem(INVENTORY_SLOT_BAG_0, i, update); - // in inventory bags for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = GetBagByPos(i)) @@ -12815,11 +12481,6 @@ Item* Player::GetItemByEntry(uint32 entry) const if (pItem->GetEntry() == entry) return pItem; - for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) - if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEntry() == entry) - return pItem; - for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); ++j) @@ -13467,8 +13128,6 @@ void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 WorldPacket data(SMSG_BUY_FAILED, (8+4+4+1)); data << uint64(creature ? creature->GetGUID() : 0); data << uint32(item); - if (param > 0) - data << uint32(param); data << uint8(msg); GetSession()->SendPacket(&data); } @@ -13584,6 +13243,9 @@ void Player::AddEnchantmentDurations(Item* item) { for (int x = 0; x < MAX_ENCHANTMENT_SLOT; ++x) { + if (x > PRISMATIC_ENCHANTMENT_SLOT || x < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + if (!item->GetEnchantmentId(EnchantmentSlot(x))) continue; @@ -13678,10 +13340,257 @@ void Player::AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 dur } } +void Player::ApplyReforgeEnchantment(Item* item, bool apply) +{ + if (!item) + return; + + ItemReforgeEntry const* reforge = sItemReforgeStore.LookupEntry(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT)); + if (!reforge) + return; + + ItemTemplate const* proto = item->GetTemplate(); + + float removeValue = item->GetReforgableStat(ItemModType(reforge->SourceStat)) * reforge->SourceMultiplier; + float addValue = removeValue * reforge->FinalMultiplier; + + switch (reforge->SourceStat) + { + case ITEM_MOD_MANA: + HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, -removeValue, apply); + break; + case ITEM_MOD_HEALTH: + HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, -removeValue, apply); + break; + case ITEM_MOD_AGILITY: + HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, -removeValue, apply); + ApplyStatBuffMod(STAT_AGILITY, -removeValue, apply); + break; + case ITEM_MOD_STRENGTH: + HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, -removeValue, apply); + ApplyStatBuffMod(STAT_STRENGTH, -removeValue, apply); + break; + case ITEM_MOD_INTELLECT: + HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, -removeValue, apply); + ApplyStatBuffMod(STAT_INTELLECT, -removeValue, apply); + break; + case ITEM_MOD_SPIRIT: + HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, -removeValue, apply); + ApplyStatBuffMod(STAT_SPIRIT, -removeValue, apply); + break; + case ITEM_MOD_STAMINA: + HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, -removeValue, apply); + ApplyStatBuffMod(STAT_STAMINA, -removeValue, apply); + break; + case ITEM_MOD_DEFENSE_SKILL_RATING: + ApplyRatingMod(CR_DEFENSE_SKILL, -int32(removeValue), apply); + break; + case ITEM_MOD_DODGE_RATING: + ApplyRatingMod(CR_DODGE, -int32(removeValue), apply); + break; + case ITEM_MOD_PARRY_RATING: + ApplyRatingMod(CR_PARRY, -int32(removeValue), apply); + break; + case ITEM_MOD_BLOCK_RATING: + ApplyRatingMod(CR_BLOCK, -int32(removeValue), apply); + break; + case ITEM_MOD_HIT_MELEE_RATING: + ApplyRatingMod(CR_HIT_MELEE, -int32(removeValue), apply); + break; + case ITEM_MOD_HIT_RANGED_RATING: + ApplyRatingMod(CR_HIT_RANGED, -int32(removeValue), apply); + break; + case ITEM_MOD_HIT_SPELL_RATING: + ApplyRatingMod(CR_HIT_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_CRIT_MELEE_RATING: + ApplyRatingMod(CR_CRIT_MELEE, -int32(removeValue), apply); + break; + case ITEM_MOD_CRIT_RANGED_RATING: + ApplyRatingMod(CR_CRIT_RANGED, -int32(removeValue), apply); + break; + case ITEM_MOD_CRIT_SPELL_RATING: + ApplyRatingMod(CR_CRIT_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_HASTE_SPELL_RATING: + ApplyRatingMod(CR_HASTE_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_HIT_RATING: + ApplyRatingMod(CR_HIT_MELEE, -int32(removeValue), apply); + ApplyRatingMod(CR_HIT_RANGED, -int32(removeValue), apply); + ApplyRatingMod(CR_HIT_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_CRIT_RATING: + ApplyRatingMod(CR_CRIT_MELEE, -int32(removeValue), apply); + ApplyRatingMod(CR_CRIT_RANGED, -int32(removeValue), apply); + ApplyRatingMod(CR_CRIT_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_RESILIENCE_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_MELEE, -int32(removeValue), apply); + ApplyRatingMod(CR_CRIT_TAKEN_RANGED, -int32(removeValue), apply); + ApplyRatingMod(CR_CRIT_TAKEN_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_HASTE_RATING: + ApplyRatingMod(CR_HASTE_MELEE, -int32(removeValue), apply); + ApplyRatingMod(CR_HASTE_RANGED, -int32(removeValue), apply); + ApplyRatingMod(CR_HASTE_SPELL, -int32(removeValue), apply); + break; + case ITEM_MOD_EXPERTISE_RATING: + ApplyRatingMod(CR_EXPERTISE, -int32(removeValue), apply); + break; + case ITEM_MOD_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, -removeValue, apply); + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, -removeValue, apply); + break; + case ITEM_MOD_RANGED_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, -removeValue, apply); + break; + case ITEM_MOD_MANA_REGENERATION: + ApplyManaRegenBonus(-int32(removeValue), apply); + break; + case ITEM_MOD_ARMOR_PENETRATION_RATING: + ApplyRatingMod(CR_ARMOR_PENETRATION, -int32(removeValue), apply); + break; + case ITEM_MOD_SPELL_POWER: + ApplySpellPowerBonus(-int32(removeValue), apply); + break; + case ITEM_MOD_HEALTH_REGEN: + ApplyHealthRegenBonus(-int32(removeValue), apply); + break; + case ITEM_MOD_SPELL_PENETRATION: + ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -int32(removeValue), apply); + m_spellPenetrationItemMod += apply ? -int32(removeValue) : int32(removeValue); + break; + case ITEM_MOD_BLOCK_VALUE: + HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, -removeValue, apply); + break; + } + + switch (reforge->FinalStat) + { + case ITEM_MOD_MANA: + HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, addValue, apply); + break; + case ITEM_MOD_HEALTH: + HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, addValue, apply); + break; + case ITEM_MOD_AGILITY: + HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, addValue, apply); + ApplyStatBuffMod(STAT_AGILITY, addValue, apply); + break; + case ITEM_MOD_STRENGTH: + HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, addValue, apply); + ApplyStatBuffMod(STAT_STRENGTH, addValue, apply); + break; + case ITEM_MOD_INTELLECT: + HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, addValue, apply); + ApplyStatBuffMod(STAT_INTELLECT, addValue, apply); + break; + case ITEM_MOD_SPIRIT: + HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, addValue, apply); + ApplyStatBuffMod(STAT_SPIRIT, addValue, apply); + break; + case ITEM_MOD_STAMINA: + HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, addValue, apply); + ApplyStatBuffMod(STAT_STAMINA, addValue, apply); + break; + case ITEM_MOD_DEFENSE_SKILL_RATING: + ApplyRatingMod(CR_DEFENSE_SKILL, int32(addValue), apply); + break; + case ITEM_MOD_DODGE_RATING: + ApplyRatingMod(CR_DODGE, int32(addValue), apply); + break; + case ITEM_MOD_PARRY_RATING: + ApplyRatingMod(CR_PARRY, int32(addValue), apply); + break; + case ITEM_MOD_BLOCK_RATING: + ApplyRatingMod(CR_BLOCK, int32(addValue), apply); + break; + case ITEM_MOD_HIT_MELEE_RATING: + ApplyRatingMod(CR_HIT_MELEE, int32(addValue), apply); + break; + case ITEM_MOD_HIT_RANGED_RATING: + ApplyRatingMod(CR_HIT_RANGED, int32(addValue), apply); + break; + case ITEM_MOD_HIT_SPELL_RATING: + ApplyRatingMod(CR_HIT_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_CRIT_MELEE_RATING: + ApplyRatingMod(CR_CRIT_MELEE, int32(addValue), apply); + break; + case ITEM_MOD_CRIT_RANGED_RATING: + ApplyRatingMod(CR_CRIT_RANGED, int32(addValue), apply); + break; + case ITEM_MOD_CRIT_SPELL_RATING: + ApplyRatingMod(CR_CRIT_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_HASTE_SPELL_RATING: + ApplyRatingMod(CR_HASTE_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_HIT_RATING: + ApplyRatingMod(CR_HIT_MELEE, int32(addValue), apply); + ApplyRatingMod(CR_HIT_RANGED, int32(addValue), apply); + ApplyRatingMod(CR_HIT_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_CRIT_RATING: + ApplyRatingMod(CR_CRIT_MELEE, int32(addValue), apply); + ApplyRatingMod(CR_CRIT_RANGED, int32(addValue), apply); + ApplyRatingMod(CR_CRIT_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_RESILIENCE_RATING: + ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(addValue), apply); + ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(addValue), apply); + ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_HASTE_RATING: + ApplyRatingMod(CR_HASTE_MELEE, int32(addValue), apply); + ApplyRatingMod(CR_HASTE_RANGED, int32(addValue), apply); + ApplyRatingMod(CR_HASTE_SPELL, int32(addValue), apply); + break; + case ITEM_MOD_EXPERTISE_RATING: + ApplyRatingMod(CR_EXPERTISE, int32(addValue), apply); + break; + case ITEM_MOD_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, addValue, apply); + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, addValue, apply); + break; + case ITEM_MOD_RANGED_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, addValue, apply); + break; + case ITEM_MOD_MANA_REGENERATION: + ApplyManaRegenBonus(int32(addValue), apply); + break; + case ITEM_MOD_ARMOR_PENETRATION_RATING: + ApplyRatingMod(CR_ARMOR_PENETRATION, int32(addValue), apply); + break; + case ITEM_MOD_SPELL_POWER: + ApplySpellPowerBonus(int32(addValue), apply); + break; + case ITEM_MOD_HEALTH_REGEN: + ApplyHealthRegenBonus(int32(addValue), apply); + break; + case ITEM_MOD_SPELL_PENETRATION: + ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, int32(addValue), apply); + m_spellPenetrationItemMod += apply ? int32(addValue) : -int32(addValue); + break; + case ITEM_MOD_BLOCK_VALUE: + HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, addValue, apply); + break; + } +} + void Player::ApplyEnchantment(Item* item, bool apply) { for (uint32 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) + { + // Apply reforge as last enchant + if (slot == REFORGE_ENCHANTMENT_SLOT) + continue; + ApplyEnchantment(item, EnchantmentSlot(slot), apply); + } + + ApplyEnchantment(item, REFORGE_ENCHANTMENT_SLOT, apply); } void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur, bool ignore_condition) @@ -13692,6 +13601,15 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool if (slot >= MAX_ENCHANTMENT_SLOT) return; + if (slot == TRANSMOGRIFY_ENCHANTMENT_SLOT) + return; + + if (slot == REFORGE_ENCHANTMENT_SLOT) + { + ApplyReforgeEnchantment(item, apply); + return; + } + uint32 enchant_id = item->GetEnchantmentId(slot); if (!enchant_id) return; @@ -13709,6 +13627,11 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool if (pEnchant->requiredSkill > 0 && pEnchant->requiredSkillValue > GetSkillValue(pEnchant->requiredSkill)) return; + // Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2 + if (ItemTemplate const* gem = sObjectMgr->GetItemTemplate(pEnchant->GemID)) + if (gem->RequiredSkill && GetSkillValue(gem->RequiredSkill) < gem->RequiredSkillRank) + return; + // If we're dealing with a gem inside a prismatic socket we need to check the prismatic socket requirements // rather than the gem requirements itself. If the socket has no color it is a prismatic socket. if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3) @@ -13750,13 +13673,13 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool { int32 basepoints = 0; // Random Property Exist - try found basepoints for spell (basepoints depends from item suffix factor) - if (item->GetItemRandomPropertyId()) + if (item->GetItemRandomPropertyId() < 0) { ItemRandomSuffixEntry const* item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId())); if (item_rand) { // Search enchant_amount - for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k) + for (int k = 0; k < 5; ++k) { if (item_rand->enchant_id[k] == enchant_id) { @@ -13802,7 +13725,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool ItemRandomSuffixEntry const* item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId())); if (item_rand_suffix) { - for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k) + for (int k = 0; k < 5; ++k) { if (item_rand_suffix->enchant_id[k] == enchant_id) { @@ -13966,10 +13889,6 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply); sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "+ %u RANGED_ATTACK_POWER", enchant_amount); break; -// case ITEM_MOD_FERAL_ATTACK_POWER: -// ApplyFeralAPBonus(enchant_amount, apply); -// sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "+ %u FERAL_ATTACK_POWER", enchant_amount); -// break; case ITEM_MOD_MANA_REGENERATION: ApplyManaRegenBonus(enchant_amount, apply); sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "+ %u MANA_REGENERATION", enchant_amount); @@ -13995,8 +13914,6 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(enchant_amount), apply); sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "+ %u BLOCK_VALUE", enchant_amount); break; - case ITEM_MOD_SPELL_HEALING_DONE: // deprecated - case ITEM_MOD_SPELL_DAMAGE_DONE: // deprecated default: break; } @@ -14065,6 +13982,9 @@ void Player::UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16 { for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) { + if (slot > PRISMATIC_ENCHANTMENT_SLOT || slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + uint32 ench_id = m_items[i]->GetEnchantmentId(EnchantmentSlot(slot)); if (!ench_id) continue; @@ -14105,17 +14025,13 @@ void Player::UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16 void Player::SendEnchantmentDurations() { for (EnchantDurationList::const_iterator itr = m_enchantDuration.begin(); itr != m_enchantDuration.end(); ++itr) - { GetSession()->SendItemEnchantTimeUpdate(GetGUID(), itr->item->GetGUID(), itr->slot, uint32(itr->leftduration) / 1000); - } } void Player::SendItemDurations() { for (ItemDurationList::const_iterator itr = m_itemDuration.begin(); itr != m_itemDuration.end(); ++itr) - { (*itr)->SendTimeUpdate(this); - } } void Player::SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast) @@ -14353,7 +14269,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men return; int32 cost = int32(item->BoxMoney); - if (!HasEnoughMoney(cost)) + if (!HasEnoughMoney(int64(cost))) { SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); PlayerTalkClass->SendCloseGossip(); @@ -14801,7 +14717,7 @@ bool Player::CanCompleteQuest(uint32 quest_id) if (qInfo->GetRewOrReqMoney() < 0) { - if (!HasEnoughMoney(-qInfo->GetRewOrReqMoney())) + if (!HasEnoughMoney(-int64(qInfo->GetRewOrReqMoney()))) return false; } @@ -14864,7 +14780,7 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg) } // prevent receive reward with low money and GetRewOrReqMoney() < 0 - if (quest->GetRewOrReqMoney() < 0 && !HasEnoughMoney(-quest->GetRewOrReqMoney())) + if (quest->GetRewOrReqMoney() < 0 && !HasEnoughMoney(-int64(quest->GetRewOrReqMoney()))) return false; return true; @@ -15009,7 +14925,7 @@ void Player::CompleteQuest(uint32 quest_id) if (qInfo->HasFlag(QUEST_FLAGS_AUTO_REWARDED)) RewardQuest(qInfo, 0, this, false); else - SendQuestComplete(quest_id); + SendQuestComplete(qInfo); } } } @@ -15109,7 +15025,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, ModifyMoney(moneyRew); if (moneyRew > 0) - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, uint32(moneyRew)); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD, uint32(moneyRew)); } // honor reward @@ -15123,15 +15039,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, SetTitle(titleEntry); } - if (quest->GetBonusTalents()) + if (uint32 talents = quest->GetBonusTalents()) { - m_questRewardTalentCount+=quest->GetBonusTalents(); + AddQuestRewardedTalentCount(talents); InitTalentForLevel(); } - if (quest->GetRewArenaPoints()) - ModifyArenaPoints(quest->GetRewArenaPoints()); - // Send reward mail if (uint32 mail_template_id = quest->GetRewMailTemplateId()) { @@ -15146,8 +15059,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, SetDailyQuestStatus(quest_id); if (quest->IsDaily()) { - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id); } } else if (quest->IsWeekly()) @@ -15175,9 +15088,9 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, CastSpell(this, quest->GetRewSpell(), true); if (quest->GetZoneOrSort() > 0) - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort()); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, quest->GetZoneOrSort()); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, quest->GetQuestId()); uint32 zone = 0; uint32 area = 0; @@ -15957,7 +15870,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid) } GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL); for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) { @@ -16330,39 +16243,83 @@ bool Player::HasQuestForItem(uint32 itemid) const return false; } -void Player::SendQuestComplete(uint32 quest_id) +void Player::SendQuestComplete(Quest const* quest) { - if (quest_id) + // SMSG_QUESTUPDATE_COMPLETE - whole new structure in 4.x + + std::string title = quest->GetTitle(); + std::string completedText = quest->GetCompletedText(); + std::string questGiverTextWindow = quest->GetQuestGiverTextWindow(); + std::string questGiverTargetName = quest->GetQuestGiverTargetName(); + std::string questTurnTextWindow = quest->GetQuestTurnTextWindow(); + std::string questTurnTargetName = quest->GetQuestTurnTargetName(); + + int32 locale = GetSession()->GetSessionDbLocaleIndex(); + if (locale >= 0) { - WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4); - data << uint32(quest_id); - GetSession()->SendPacket(&data); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id); + if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) + { + ObjectMgr::GetLocaleString(localeData->Title, locale, title); + ObjectMgr::GetLocaleString(localeData->CompletedText, locale, completedText); + ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, locale, questGiverTextWindow); + ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, locale, questGiverTargetName); + ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, locale, questTurnTextWindow); + ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, locale, questTurnTargetName); + } } + + WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4); + data << uint64(this->GetGUID()); + data << uint32(quest->GetQuestId()); + data << title; + data << completedText; + data << questGiverTextWindow; + data << questGiverTargetName; + data << questTurnTextWindow; + data << questTurnTargetName; + data << uint32(quest->GetQuestGiverPortrait()); + data << uint32(quest->GetQuestTurnInPortrait()); + data << int8(0); // Unk + data << uint32(quest->GetFlags()); + data << int32(0); // Unk + data << uint32(QUEST_EMOTE_COUNT); + for (uint8 i = 0; i < QUEST_EMOTE_COUNT; ++i) + { + data << uint32(quest->DetailsEmote[i]); + data << uint32(quest->DetailsEmoteDelay[i]); // DetailsEmoteDelay (in ms) + } + + quest->BuildExtraQuestInfo(data, this); + + GetSession()->SendPacket(&data); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest->GetQuestId()); } void Player::SendQuestReward(Quest const* quest, uint32 XP, Object* questGiver) { - uint32 questid = quest->GetQuestId(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid); - sGameEventMgr->HandleQuestComplete(questid); + uint32 questId = quest->GetQuestId(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questId); + sGameEventMgr->HandleQuestComplete(questId); WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4)); - data << uint32(questid); + + data << uint8(0x80); // 4.x unknown flag, most common value is 0x80 (it might be a single bit) if (getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) { data << uint32(XP); data << uint32(quest->GetRewOrReqMoney()); } - else + else // At max level, increase gold reward { data << uint32(0); data << uint32(quest->GetRewOrReqMoney() + int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(RATE_DROP_MONEY))); } - data << 10 * Trinity::Honor::hk_honor_at_level(getLevel(), quest->GetRewHonorMultiplier()); - data << uint32(quest->GetBonusTalents()); // bonus talents - data << uint32(quest->GetRewArenaPoints()); + data << uint32(quest->GetRewardSkillPoints()); // 4.x bonus skill points + data << uint32(questId); + data << uint32(quest->GetRewardSkillId()); // 4.x bonus skill id + + data << uint32(quest->GetBonusTalents()); // bonus talents (not verified for 4.x) GetSession()->SendPacket(&data); if (quest->GetQuestCompleteScript() != 0) @@ -16660,12 +16617,14 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) //QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " // 12 13 14 15 16 17 18 19 20 21 22 23 24 //"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - // 25 26 27 28 29 30 31 32 33 34 35 36 37 38 - //"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " - // 39 40 41 42 43 44 45 46 47 48 49 - //"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " - // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 - //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid); + // 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 + //"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " + // 40 41 42 43 44 45 46 47 + //"conquestPoints, totalHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " + // 48 49 50 51 52 53 54 55 56 57 58 + //"health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, " + // 59 60 61 + //"knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid); PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADFROM); if (!result) @@ -16730,8 +16689,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8()); SetUInt32Value(PLAYER_XP, fields[7].GetUInt32()); - _LoadIntoDataField(fields[61].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); - _LoadIntoDataField(fields[64].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); + _LoadIntoDataField(fields[57].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); + _LoadIntoDataField(fields[59].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); @@ -16740,7 +16699,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria) m_achievementMgr.LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS)); - uint32 money = fields[8].GetUInt32(); + uint64 money = fields[8].GetUInt64(); if (money > MAX_MONEY_AMOUNT) money = MAX_MONEY_AMOUNT; SetMoney(money); @@ -16748,16 +16707,12 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32()); SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32()); SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8()); - SetByteValue(PLAYER_BYTES_3, 1, fields[49].GetUInt8()); + SetByteValue(PLAYER_BYTES_3, 1, fields[47].GetUInt8()); SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32()); - SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[48].GetUInt32()); - - SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[47].GetUInt64()); - - SetUInt32Value(PLAYER_AMMO_ID, fields[63].GetUInt32()); + SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[46].GetUInt32()); // set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise) - SetByteValue(PLAYER_FIELD_BYTES, 2, fields[65].GetUInt8()); + SetByteValue(PLAYER_FIELD_BYTES, 2, fields[60].GetUInt8()); InitDisplayIds(); @@ -16785,21 +16740,21 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) InitPrimaryProfessions(); // to max set before any spell loaded // init saved position, and fix it later if problematic - uint32 transGUID = fields[30].GetUInt32(); + uint32 transGUID = uint32(fields[31].GetUInt32()); Relocate(fields[12].GetFloat(), fields[13].GetFloat(), fields[14].GetFloat(), fields[16].GetFloat()); uint32 mapId = fields[15].GetUInt16(); - uint32 instanceId = fields[58].GetUInt32(); + uint32 instanceId = fields[54].GetUInt32(); - uint32 dungeonDiff = fields[38].GetUInt8() & 0x0F; + uint32 dungeonDiff = fields[39].GetUInt8() & 0x0F; if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY) dungeonDiff = DUNGEON_DIFFICULTY_NORMAL; - uint32 raidDiff = (fields[38].GetUInt8() >> 4) & 0x0F; + uint32 raidDiff = (fields[39].GetUInt8() >> 4) & 0x0F; if (raidDiff >= MAX_RAID_DIFFICULTY) raidDiff = RAID_DIFFICULTY_10MAN_NORMAL; SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup - std::string taxi_nodes = fields[37].GetString(); + std::string taxi_nodes = fields[38].GetString(); #define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); } @@ -16807,8 +16762,6 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) _LoadArenaTeamInfo(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADARENAINFO)); - SetArenaPoints(fields[39].GetUInt32()); - // check arena teams integrity for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) { @@ -16825,12 +16778,11 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) SetArenaTeamInfoField(arena_slot, ArenaTeamInfoType(j), 0); } - SetHonorPoints(fields[40].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[41].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[42].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[43].GetUInt32()); - SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[44].GetUInt16()); - SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[45].GetUInt16()); + SetCurrency(CURRENCY_TYPE_CONQUEST_POINTS, fields[40].GetUInt32()); + SetCurrency(CURRENCY_TYPE_HONOR_POINTS, fields[41].GetUInt32()); + SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[42].GetUInt32()); + SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[43].GetUInt16()); + SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[44].GetUInt16()); _LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES)); _LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES)); @@ -16892,7 +16844,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) else if (transGUID) { m_movementInfo.t_guid = MAKE_NEW_GUID(transGUID, 0, HIGHGUID_MO_TRANSPORT); - m_movementInfo.t_pos.Relocate(fields[26].GetFloat(), fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat()); + m_movementInfo.t_pos.Relocate(fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat(), fields[30].GetFloat()); if (!Trinity::IsValidMapCoord( GetPositionX()+m_movementInfo.t_pos.m_positionX, GetPositionY()+m_movementInfo.t_pos.m_positionY, @@ -17068,28 +17020,28 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32(); m_Played_time[PLAYED_TIME_LEVEL]= fields[20].GetUInt32(); - m_resetTalentsCost = fields[24].GetUInt32(); - m_resetTalentsTime = time_t(fields[25].GetUInt32()); + SetTalentResetCost(fields[24].GetUInt32()); + SetTalentResetTime(time_t(fields[25].GetUInt32())); m_taxi.LoadTaxiMask(fields[17].GetCString()); // must be before InitTaxiNodesForLevel - uint32 extraflags = fields[31].GetUInt16(); + uint32 extraflags = fields[32].GetUInt16(); - m_stableSlots = fields[32].GetUInt8(); + m_stableSlots = fields[33].GetUInt8(); if (m_stableSlots > MAX_PET_STABLES) { sLog->outError(LOG_FILTER_PLAYER, "Player can have not more %u stable slots, but have in DB %u", MAX_PET_STABLES, uint32(m_stableSlots)); m_stableSlots = MAX_PET_STABLES; } - m_atLoginFlags = fields[33].GetUInt16(); + m_atLoginFlags = fields[34].GetUInt16(); // Honor system // Update Honor kills data m_lastHonorUpdateTime = logoutTime; UpdateHonorFields(); - m_deathExpireTime = time_t(fields[36].GetUInt32()); + m_deathExpireTime = time_t(fields[37].GetUInt32()); if (m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP) m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1; @@ -17149,14 +17101,14 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) //mails are loaded only when needed ;-) - when player in game click on mailbox. //_LoadMail(); - m_specsCount = fields[59].GetUInt8(); - m_activeSpec = fields[60].GetUInt8(); + SetSpecsCount(fields[55].GetUInt8()); + SetActiveSpec(fields[56].GetUInt8()); // sanity check - if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC || m_specsCount < MIN_TALENT_SPECS) + if (GetSpecsCount() > MAX_TALENT_SPECS || GetActiveSpec() > MAX_TALENT_SPEC || GetSpecsCount() < MIN_TALENT_SPECS) { - m_activeSpec = 0; - sLog->outError(LOG_FILTER_PLAYER, "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName(), GetGUIDLow(), m_specsCount, m_activeSpec); + SetActiveSpec(0); + sLog->outError(LOG_FILTER_PLAYER, "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName(), GetGUIDLow(), GetSpecsCount(), GetActiveSpec()); } _LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADTALENTS)); @@ -17186,6 +17138,9 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) _LoadInventory(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADINVENTORY), time_diff); + if (IsVoidStorageUnlocked()) + _LoadVoidStorage(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADVOIDSTORAGE)); + // update items with duration and realtime UpdateItemDuration(time_diff, true); @@ -17198,7 +17153,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded - uint32 curTitle = fields[46].GetUInt32(); + uint32 curTitle = fields[45].GetUInt32(); if (curTitle && !HasTitle(curTitle)) curTitle = 0; @@ -17221,12 +17176,36 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) UpdateAllStats(); // restore remembered power/health values (but not more max values) - uint32 savedHealth = fields[50].GetUInt32(); + uint32 savedHealth = fields[48].GetUInt32(); SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth); - for (uint8 i = 0; i < MAX_POWERS; ++i) + uint32 loadedPowers = 0; + for (uint32 i = 0; i < MAX_POWERS; ++i) { - uint32 savedPower = fields[51+i].GetUInt32(); - SetPower(Powers(i), savedPower > GetMaxPower(Powers(i)) ? GetMaxPower(Powers(i)) : savedPower); + if (GetPowerIndexByClass(Powers(i), getClass()) != MAX_POWERS) + { + uint32 savedPower = fields[49+loadedPowers].GetUInt32(); + uint32 maxPower = GetUInt32Value(UNIT_FIELD_MAXPOWER1 + loadedPowers); + SetPower(Powers(i), (savedPower > maxPower) ? maxPower : savedPower); + if (++loadedPowers >= MAX_STORED_POWERS) + break; + } + } + + for (; loadedPowers < MAX_STORED_POWERS; ++loadedPowers) + SetUInt32Value(UNIT_FIELD_POWER1 + loadedPowers, 0); + + // must be after loading spells and talents + Tokens talentTrees(fields[26].GetString(), ' ', MAX_TALENT_SPECS); + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + { + if (i >= talentTrees.size()) + break; + + uint32 talentTree = atol(talentTrees[i]); + if (sTalentTabStore.LookupEntry(talentTree)) + SetPrimaryTalentTree(i, talentTree); + else if (i == GetActiveSpec()) + SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents } sLog->outDebug(LOG_FILTER_PLAYER_LOADING, "The value of player %s after load item and aura is: ", m_name.c_str()); @@ -17281,7 +17260,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) } // RaF stuff. - m_grantableLevels = fields[66].GetUInt8(); + m_grantableLevels = fields[61].GetUInt8(); if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0)) SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND); @@ -17290,7 +17269,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) _LoadDeclinedNames(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES)); - m_achievementMgr.CheckAllAchievementCriteria(); + m_achievementMgr.CheckAllAchievementCriteria(this); _LoadEquipmentSets(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS)); @@ -17450,7 +17429,7 @@ void Player::_LoadGlyphAuras() { for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) { - if (uint32 glyph = GetGlyph(i)) + if (uint32 glyph = GetGlyph(GetActiveSpec(), i)) { if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph)) { @@ -17621,6 +17600,52 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) _ApplyAllItemMods(); } +void Player::_LoadVoidStorage(PreparedQueryResult result) +{ + if (!result) + return; + + do + { + // SELECT itemid, itemEntry, slot, creatorGuid FROM void_storage WHERE playerGuid = ? + Field* fields = result->Fetch(); + + uint64 itemId = fields[0].GetUInt64(); + uint32 itemEntry = fields[1].GetUInt32(); + uint8 slot = fields[2].GetUInt8(); + uint32 creatorGuid = fields[3].GetUInt32(); + uint32 randomProperty = fields[4].GetUInt32(); + uint32 suffixFactor = fields[5].GetUInt32(); + + if (!itemId) + { + sLog->outError(LOG_FILTER_GENERAL, "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid id (item id: %u, entry: %u).", GetGUIDLow(), GetName(), itemId, itemEntry); + continue; + } + + if (!sObjectMgr->GetItemTemplate(itemEntry)) + { + sLog->outError(LOG_FILTER_GENERAL, "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid entry (item id: %u, entry: %u).", GetGUIDLow(), GetName(), itemId, itemEntry); + continue; + } + + if (slot < 0 || slot > VOID_STORAGE_MAX_SLOT) + { + sLog->outError(LOG_FILTER_GENERAL, "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid slot (item id: %u, entry: %u, slot: %u).", GetGUIDLow(), GetName(), itemId, itemEntry, slot); + continue; + } + + if (!sObjectMgr->GetPlayerByLowGUID(creatorGuid)) + { + sLog->outError(LOG_FILTER_GENERAL, "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid creator guid, set to 0 (item id: %u, entry: %u, creatorGuid: %u).", GetGUIDLow(), GetName(), itemId, itemEntry, creatorGuid); + creatorGuid = 0; + } + + _voidStorageItems[slot] = new VoidStorageItem(itemId, itemEntry, creatorGuid, randomProperty, suffixFactor); + } + while (result->NextRow()); +} + Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields) { PreparedStatement* stmt = NULL; @@ -17835,8 +17860,8 @@ void Player::_LoadMail() bool has_items = fields[6].GetBool(); m->expire_time = time_t(fields[7].GetUInt32()); m->deliver_time = time_t(fields[8].GetUInt32()); - m->money = fields[9].GetUInt32(); - m->COD = fields[10].GetUInt32(); + m->money = fields[9].GetUInt64(); + m->COD = fields[10].GetUInt64(); m->checked = fields[11].GetUInt8(); m->stationery = fields[12].GetUInt8(); m->mailTemplateId = fields[13].GetInt16(); @@ -17986,8 +18011,8 @@ void Player::_LoadQuestStatusRewarded(PreparedQueryResult result) SetTitle(titleEntry); } - if (quest->GetBonusTalents()) - m_questRewardTalentCount += quest->GetBonusTalents(); + if (uint32 talents = quest->GetBonusTalents()) + AddQuestRewardedTalentCount(talents); } m_RewardedQuests.insert(quest_id); @@ -18340,14 +18365,17 @@ void Player::SendRaidInfo() InstanceSave* save = itr->second.save; data << uint32(save->GetMapId()); // map id data << uint32(save->GetDifficulty()); // difficulty + data << uint32(0); // Unknown 4.2.2 data << uint64(save->GetInstanceId()); // instance id data << uint8(1); // expired = 0 data << uint8(0); // extended = 1 data << uint32(save->GetResetTime() - now); // reset time + data << uint32(0); // Unknown 4.2.2 ++counter; } } } + data.put<uint32>(p_counter, counter); GetSession()->SendPacket(&data); } @@ -18372,8 +18400,8 @@ void Player::SendSavedInstances() } } - //Send opcode 811. true or false means, whether you have current raid/heroic instances - data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP); + //Send opcode SMSG_UPDATE_INSTANCE_OWNERSHIP. true or false means, whether you have current raid/heroic instances + data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP, 4); data << uint32(hasBeenSaved); GetSession()->SendPacket(&data); @@ -18386,7 +18414,7 @@ void Player::SendSavedInstances() { if (itr->second.perm) { - data.Initialize(SMSG_UPDATE_LAST_INSTANCE); + data.Initialize(SMSG_UPDATE_LAST_INSTANCE, 4); data << uint32(itr->second.save->GetMapId()); GetSession()->SendPacket(&data); } @@ -18519,7 +18547,7 @@ bool Player::_LoadHomeBind(PreparedQueryResult result) PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); if (!info) { - sLog->outError(LOG_FILTER_PLAYER, "Player (Name %s) has incorrect race/class pair. Can't be loaded.", GetName()); + sLog->outError(LOG_FILTER_PLAYER, "Player (Name %s) has incorrect race/class (%u/%u) pair. Can't be loaded.", GetName(), uint32(getRace()), uint32(getClass())); return false; } @@ -18611,7 +18639,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, getGender()); stmt->setUInt8(index++, getLevel()); stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP)); - stmt->setUInt32(index++, GetMoney()); + stmt->setUInt64(index++, GetMoney()); stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS)); @@ -18634,8 +18662,13 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0)); //save, far from tavern/city //save, but in tavern/city - stmt->setUInt32(index++, m_resetTalentsCost); - stmt->setUInt32(index++, uint32(m_resetTalentsTime)); + stmt->setUInt32(index++, GetTalentResetCost()); + stmt->setUInt32(index++, GetTalentResetTime()); + + ss.str(""); + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + ss << GetPrimaryTalentTree(i) << " "; + stmt->setString(index++, ss.str()); stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt8(index++, m_stableSlots); stmt->setUInt16(index++, (uint16)m_atLoginFlags); @@ -18646,26 +18679,34 @@ void Player::SaveToDB(bool create /*=false*/) ss << m_taxi.SaveTaxiDestinationsToString(); stmt->setString(index++, ss.str()); - stmt->setUInt32(index++, GetArenaPoints()); - stmt->setUInt32(index++, GetHonorPoints()); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); + stmt->setUInt32(index++, GetCurrency(CURRENCY_TYPE_CONQUEST_POINTS)); + stmt->setUInt32(index++, GetCurrency(CURRENCY_TYPE_HONOR_POINTS)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 0)); stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 1)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE)); - stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX)); stmt->setUInt8(index++, GetDrunkValue()); stmt->setUInt32(index++, GetHealth()); + uint32 storedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) - stmt->setUInt32(index++, GetPower(Powers(i))); + { + if (GetPowerIndexByClass(Powers(i), getClass()) != MAX_POWERS) + { + stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_POWER1 + storedPowers)); + if (++storedPowers >= MAX_STORED_POWERS) + break; + } + } + + for (; storedPowers < MAX_STORED_POWERS; ++storedPowers) + stmt->setUInt32(index++, 0); stmt->setUInt32(index++, GetSession()->GetLatency()); - stmt->setUInt8(index++, m_specsCount); - stmt->setUInt8(index++, m_activeSpec); + stmt->setUInt8(index++, GetSpecsCount()); + stmt->setUInt8(index++, GetActiveSpec()); ss.str(""); for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) @@ -18686,15 +18727,13 @@ void Player::SaveToDB(bool create /*=false*/) ss << '0'; ss << " 0 "; } - stmt->setString(index++, ss.str()); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_AMMO_ID)); ss.str(""); for (uint32 i = 0; i < KNOWN_TITLES_SIZE*2; ++i) ss << GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES + i) << ' '; - stmt->setString(index++, ss.str()); + stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, 2)); stmt->setUInt32(index++, m_grantableLevels); } @@ -18708,7 +18747,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, getGender()); stmt->setUInt8(index++, getLevel()); stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP)); - stmt->setUInt32(index++, GetMoney()); + stmt->setUInt64(index++, GetMoney()); stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS)); @@ -18745,8 +18784,13 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0)); //save, far from tavern/city //save, but in tavern/city - stmt->setUInt32(index++, m_resetTalentsCost); - stmt->setUInt32(index++, uint32(m_resetTalentsTime)); + stmt->setUInt32(index++, GetTalentResetCost()); + stmt->setUInt32(index++, GetTalentResetTime()); + + ss.str(""); + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + ss << GetPrimaryTalentTree(i) << " "; + stmt->setString(index++, ss.str()); stmt->setUInt16(index++, (uint16)m_ExtraFlags); stmt->setUInt8(index++, m_stableSlots); stmt->setUInt16(index++, (uint16)m_atLoginFlags); @@ -18757,26 +18801,34 @@ void Player::SaveToDB(bool create /*=false*/) ss << m_taxi.SaveTaxiDestinationsToString(); stmt->setString(index++, ss.str()); - stmt->setUInt32(index++, GetArenaPoints()); - stmt->setUInt32(index++, GetHonorPoints()); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); + stmt->setUInt32(index++, GetCurrency(CURRENCY_TYPE_CONQUEST_POINTS)); + stmt->setUInt32(index++, GetCurrency(CURRENCY_TYPE_HONOR_POINTS)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 0)); stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 1)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE)); - stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX)); stmt->setUInt8(index++, GetDrunkValue()); stmt->setUInt32(index++, GetHealth()); + uint32 storedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) - stmt->setUInt32(index++, GetPower(Powers(i))); + { + if (GetPowerIndexByClass(Powers(i), getClass()) != MAX_POWERS) + { + stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_POWER1 + storedPowers)); + if (++storedPowers >= MAX_STORED_POWERS) + break; + } + } + + for (; storedPowers < MAX_STORED_POWERS; ++storedPowers) + stmt->setUInt32(index++, 0); stmt->setUInt32(index++, GetSession()->GetLatency()); - stmt->setUInt8(index++, m_specsCount); - stmt->setUInt8(index++, m_activeSpec); + stmt->setUInt8(index++, GetSpecsCount()); + stmt->setUInt8(index++, GetActiveSpec()); ss.str(""); for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) @@ -18799,7 +18851,6 @@ void Player::SaveToDB(bool create /*=false*/) } stmt->setString(index++, ss.str()); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_AMMO_ID)); ss.str(""); for (uint32 i = 0; i < KNOWN_TITLES_SIZE*2; ++i) @@ -18823,6 +18874,7 @@ void Player::SaveToDB(bool create /*=false*/) _SaveBGData(trans); _SaveInventory(trans); + _SaveVoidStorage(trans); _SaveQuestStatus(trans); _SaveDailyQuestStatus(trans); _SaveWeeklyQuestStatus(trans); @@ -18862,7 +18914,7 @@ void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans) void Player::SaveGoldToDB(SQLTransaction& trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_MONEY); - stmt->setUInt32(0, GetMoney()); + stmt->setUInt64(0, GetMoney()); stmt->setUInt32(1, GetGUIDLow()); trans->Append(stmt); } @@ -18878,7 +18930,7 @@ void Player::_SaveActions(SQLTransaction& trans) case ACTIONBUTTON_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION); stmt->setUInt32(0, GetGUIDLow()); - stmt->setUInt8(1, m_activeSpec); + stmt->setUInt8(1, GetActiveSpec()); stmt->setUInt8(2, itr->first); stmt->setUInt32(3, itr->second.GetAction()); stmt->setUInt8(4, uint8(itr->second.GetType())); @@ -18893,7 +18945,7 @@ void Player::_SaveActions(SQLTransaction& trans) stmt->setUInt8(1, uint8(itr->second.GetType())); stmt->setUInt32(2, GetGUIDLow()); stmt->setUInt8(3, itr->first); - stmt->setUInt8(4, m_activeSpec); + stmt->setUInt8(4, GetActiveSpec()); trans->Append(stmt); itr->second.uState = ACTIONBUTTON_UNCHANGED; @@ -18903,7 +18955,7 @@ void Player::_SaveActions(SQLTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC); stmt->setUInt32(0, GetGUIDLow()); stmt->setUInt8(1, itr->first); - stmt->setUInt8(2, m_activeSpec); + stmt->setUInt8(2, GetActiveSpec()); trans->Append(stmt); m_actionButtons.erase(itr++); @@ -19062,7 +19114,7 @@ void Player::_SaveInventory(SQLTransaction& trans) // save all changes to the item... if (item->GetState() != ITEM_NEW) // only for existing items, no dupes item->SaveToDB(trans); - // ...but do not save position in invntory + // ...but do not save position in inventory continue; } } @@ -19092,6 +19144,37 @@ void Player::_SaveInventory(SQLTransaction& trans) m_itemUpdateQueue.clear(); } +void Player::_SaveVoidStorage(SQLTransaction& trans) +{ + PreparedStatement* stmt = NULL; + uint32 lowGuid = GetGUIDLow(); + + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + { + if (!_voidStorageItems[i]) // unused item + { + // DELETE FROM void_storage WHERE slot = ? AND playerGuid = ? + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_VOID_STORAGE_ITEM_BY_SLOT); + stmt->setUInt8(0, i); + stmt->setUInt32(1, lowGuid); + } + else + { + // REPLACE INTO character_inventory (itemId, playerGuid, itemEntry, slot, creatorGuid) VALUES (?, ?, ?, ?, ?) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_VOID_STORAGE_ITEM); + stmt->setUInt64(0, _voidStorageItems[i]->ItemId); + stmt->setUInt32(1, lowGuid); + stmt->setUInt32(2, _voidStorageItems[i]->ItemEntry); + stmt->setUInt8(3, i); + stmt->setUInt32(4, _voidStorageItems[i]->CreatorGuid); + stmt->setUInt32(5, _voidStorageItems[i]->ItemRandomPropertyId); + stmt->setUInt32(6, _voidStorageItems[i]->ItemSuffixFactor); + } + + trans->Append(stmt); + } +} + void Player::_SaveMail(SQLTransaction& trans) { if (!m_mailsLoaded) @@ -19352,9 +19435,11 @@ void Player::_SaveSkills(SQLTransaction& trans) continue; } - uint32 valueData = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)); - uint16 value = SKILL_VALUE(valueData); - uint16 max = SKILL_MAX(valueData); + uint16 field = itr->second.pos / 2; + uint8 offset = itr->second.pos & 1; + + uint16 value = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset); + uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset); switch (itr->second.uState) { @@ -19365,7 +19450,6 @@ void Player::_SaveSkills(SQLTransaction& trans) stmt->setUInt16(2, value); stmt->setUInt16(3, max); trans->Append(stmt); - break; case SKILL_CHANGED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_SKILLS); @@ -19374,13 +19458,12 @@ void Player::_SaveSkills(SQLTransaction& trans) stmt->setUInt32(2, GetGUIDLow()); stmt->setUInt16(3, uint16(itr->first)); trans->Append(stmt); - break; default: break; } - itr->second.uState = SKILL_UNCHANGED; + itr->second.uState = SKILL_UNCHANGED; ++itr; } } @@ -19443,7 +19526,7 @@ void Player::_SaveStats(SQLTransaction& trans) stmt->setUInt32(index++, GetGUIDLow()); stmt->setUInt32(index++, GetMaxHealth()); - for (uint8 i = 0; i < MAX_POWERS; ++i) + for (uint8 i = 0; i < MAX_STORED_POWERS; ++i) stmt->setUInt32(index++, GetMaxPower(Powers(i))); for (uint8 i = 0; i < MAX_STATS; ++i) @@ -19901,13 +19984,16 @@ void Player::StopCastingCharm() } } -inline void Player::BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language) const +inline void Player::BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language, const char* addonPrefix /*= NULL*/) const { *data << uint8(msgtype); *data << uint32(language); *data << uint64(GetGUID()); *data << uint32(0); // constant unknown time - *data << uint64(GetGUID()); + if (addonPrefix) + *data << addonPrefix; + else + *data << uint64(GetGUID()); *data << uint32(text.length() + 1); *data << text; *data << uint8(GetChatTag()); @@ -19943,13 +20029,20 @@ void Player::TextEmote(const std::string& text) SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT)); } -void Player::Whisper(const std::string& text, uint32 language, uint64 receiver) +void Player::WhisperAddon(const std::string& text, const std::string& prefix, uint64 receiver) { - bool isAddonMessage = language == LANG_ADDON; + Player* rPlayer = ObjectAccessor::FindPlayer(receiver); + + std::string _text(text); + sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, LANG_UNIVERSAL, _text, rPlayer); - if (!isAddonMessage) // if not addon data - language = LANG_UNIVERSAL; // whispers should always be readable + WorldPacket data(SMSG_MESSAGECHAT, 200); + BuildPlayerChat(&data, CHAT_MSG_WHISPER, _text, LANG_UNIVERSAL, prefix.c_str()); + rPlayer->GetSession()->SendPacket(&data); +} +void Player::Whisper(const std::string& text, uint32 language, uint64 receiver) +{ Player* rPlayer = ObjectAccessor::FindPlayer(receiver); std::string _text(text); @@ -19962,22 +20055,13 @@ void Player::Whisper(const std::string& text, uint32 language, uint64 receiver) BuildPlayerChat(&data, CHAT_MSG_WHISPER, _text, language); rPlayer->GetSession()->SendPacket(&data); - // not send confirmation for addon messages - if (!isAddonMessage) - { - data.Initialize(SMSG_MESSAGECHAT, 200); - rPlayer->BuildPlayerChat(&data, CHAT_MSG_WHISPER_INFORM, _text, language); - GetSession()->SendPacket(&data); - } + data.Initialize(SMSG_MESSAGECHAT, 200); + rPlayer->BuildPlayerChat(&data, CHAT_MSG_WHISPER_INFORM, _text, language); + GetSession()->SendPacket(&data); } - else if (!isAddonMessage) - // announce to player that player he is whispering to is dnd and cannot receive his message + else // announce to player that player he is whispering to is dnd and cannot receive his message ChatHandler(this).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName(), rPlayer->dndMsg.c_str()); - // rest stuff shouldn't happen in case of addon message - if (isAddonMessage) - return; - if (!isAcceptWhispers() && !isGameMaster() && !rPlayer->isGameMaster()) { SetAcceptWhispers(true); @@ -20268,33 +20352,37 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod void Player::AddSpellMod(SpellModifier* mod, bool apply) { sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Player::AddSpellMod %d", mod->spellId); - uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; + Opcodes opcode = Opcodes((mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER); int i = 0; flag96 _mask = 0; + uint32 modTypeCount = 0; // count of mods per one mod->op + WorldPacket data(opcode); + data << uint32(1); // count of different mod->op's in packet + size_t writePos = data.wpos(); + data << uint32(modTypeCount); + data << uint8(mod->op); for (int eff = 0; eff < 96; ++eff) { - if (eff != 0 && eff%32 == 0) + if (eff != 0 && (eff % 32) == 0) _mask[i++] = 0; - _mask[i] = uint32(1) << (eff-(32*i)); + _mask[i] = uint32(1) << (eff - (32 * i)); if (mod->mask & _mask) { int32 val = 0; for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) - { if ((*itr)->type == mod->type && (*itr)->mask & _mask) val += (*itr)->value; - } val += apply ? mod->value : -(mod->value); - WorldPacket data(Opcode, (1+1+4)); + data << uint8(eff); - data << uint8(mod->op); - data << int32(val); - SendDirectMessage(&data); + data << float(val); + ++modTypeCount; } } - + data.put<uint32>(writePos, modTypeCount); + SendDirectMessage(&data); if (apply) m_spellMods[mod->op].push_back(mod); else @@ -20709,7 +20797,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc return false; } - uint32 money = GetMoney(); + uint64 money = GetMoney(); if (npc) totalcost = (uint32)ceil(totalcost*GetReputationPriceDiscount(npc)); @@ -20722,9 +20810,9 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc } //Checks and preparations done, DO FLIGHT - ModifyMoney(-(int32)totalcost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1); + ModifyMoney(-int64(totalcost)); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1); // prevent stealth flight //RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK); @@ -20860,7 +20948,7 @@ void Player::InitDataForForm(bool reapplyMods) { ShapeshiftForm form = GetShapeshiftForm(); - SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (ssEntry && ssEntry->attackSpeed) { SetAttackTime(BASE_ATTACK, ssEntry->attackSpeed); @@ -20929,7 +21017,7 @@ void Player::InitDisplayIds() } } -inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore) +inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const *pProto, Creature *pVendor, VendorItem const* crItem, bool bStore) { ItemPosCountVec vDest; uint16 uiDest = 0; @@ -20944,19 +21032,19 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c ModifyMoney(-price); - if (crItem->ExtendedCost) // case for new honor system + if (crItem->ExtendedCost) // case for new honor system { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); - if (iece->reqhonorpoints) - ModifyHonorPoints(- int32(iece->reqhonorpoints * count)); - - if (iece->reqarenapoints) - ModifyArenaPoints(- int32(iece->reqarenapoints * count)); + for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) + { + if (iece->RequiredItem[i]) + DestroyItemCount(iece->RequiredItem[i], iece->RequiredItem[i], true); + } - for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) + for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) { - if (iece->reqitem[i]) - DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true); + if (iece->RequiredCurrency[i]) + ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i])); } } @@ -21065,24 +21153,10 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 return false; } - // honor points price - if (GetHonorPoints() < (iece->reqhonorpoints * count)) - { - SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); - return false; - } - - // arena points price - if (GetArenaPoints() < (iece->reqarenapoints * count)) - { - SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); - return false; - } - // item base price - for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) { - if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count))) + if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], (iece->RequiredItemCount[i] * count))) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); return false; @@ -21090,7 +21164,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 } // check for personal arena rating requirement - if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating) + if (GetMaxPersonalArenaRatingRequirement(iece->RequiredArenaSlot) < iece->RequiredPersonalArenaRating) { // probably not the proper equip err SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL); @@ -21112,7 +21186,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 // reputation discount price = uint32(floor(price * GetReputationPriceDiscount(creature))); - if (!HasEnoughMoney(price)) + if (!HasEnoughMoney(uint64(price))) { SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, item, 0); return false; @@ -21524,7 +21598,7 @@ void Player::ToggleMetaGemsActive(uint8 exceptslot, bool apply) //cycle all equipped items for (int slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) { - //enchants for the slot being socketed are handled by WorldSession::HandleSocketOpcode(WorldPacket& recv_data) + //enchants for the slot being socketed are handled by WorldSession::HandleSocketOpcode(WorldPacket& recvData) if (slot == exceptslot) continue; @@ -21808,7 +21882,7 @@ void Player::UpdateTriggerVisibility() if (!IsInWorld()) return; - UpdateData udata; + UpdateData udata(GetMapId()); WorldPacket packet; for (ClientGUIDs::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) { @@ -21900,16 +21974,16 @@ void Player::InitPrimaryProfessions() SetFreePrimaryProfessions(sWorld->getIntConfig(CONFIG_MAX_PRIMARY_TRADE_SKILL)); } -void Player::ModifyMoney(int32 d) +void Player::ModifyMoney(int64 d) { sScriptMgr->OnPlayerMoneyChanged(this, d); if (d < 0) - SetMoney (GetMoney() > uint32(-d) ? GetMoney() + d : 0); + SetMoney (GetMoney() > uint64(-d) ? GetMoney() + d : 0); else { - uint32 newAmount = 0; - if (GetMoney() < uint32(MAX_MONEY_AMOUNT - d)) + uint64 newAmount = 0; + if (GetMoney() < uint64(MAX_MONEY_AMOUNT - d)) newAmount = GetMoney() + d; else { @@ -21918,7 +21992,7 @@ void Player::ModifyMoney(int32 d) if (d) SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); } - SetMoney (newAmount); + SetMoney(newAmount); } } @@ -22058,12 +22132,6 @@ void Player::SendInitialPacketsBeforeAddToMap() SendTalentsInfoData(false); - // SMSG_INSTANCE_DIFFICULTY - data.Initialize(SMSG_INSTANCE_DIFFICULTY, 4+4); - data << uint32(GetMap()->GetDifficulty()); - data << uint32(0); - GetSession()->SendPacket(&data); - SendInitialSpells(); data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4); @@ -22072,7 +22140,7 @@ void Player::SendInitialPacketsBeforeAddToMap() SendInitialActionButtons(); m_reputationMgr.SendInitialReputations(); - m_achievementMgr.SendAllAchievementData(); + m_achievementMgr.SendAllAchievementData(this); SendEquipmentSetList(); @@ -22089,6 +22157,7 @@ void Player::SendInitialPacketsBeforeAddToMap() // SMSG_UPDATE_WORLD_STATE // SMSG_POWER_UPDATE + SendCurrencies(); SetMover(this); } @@ -22123,12 +22192,12 @@ void Player::SendInitialPacketsAfterAddToMap() } if (HasAuraType(SPELL_AURA_MOD_STUN)) - SetMovement(MOVE_ROOT); + SetRooted(true); // manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that must not be re-applied. if (HasAuraType(SPELL_AURA_MOD_ROOT)) { - WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10); + WorldPacket data2(SMSG_MOVE_ROOT, 10); data2.append(GetPackGUID()); data2 << (uint32)2; SendMessageToSet(&data2, true); @@ -22168,18 +22237,8 @@ void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 { WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2); data << uint32(mapid); - data << uint8(reason); // transfer abort reason - switch (reason) - { - case TRANSFER_ABORT_INSUF_EXPAN_LVL: - case TRANSFER_ABORT_DIFFICULTY: - case TRANSFER_ABORT_UNIQUE_MESSAGE: - // these are the ONLY cases that have an extra argument in the packet!!! - data << uint8(arg); - break; - default: - break; - } + data << uint8(reason); // transfer abort reason + data << uint8(arg); GetSession()->SendPacket(&data); } @@ -22520,6 +22579,7 @@ void Player::ResetWeeklyQuestStatus() m_weeklyquests.clear(); // DB data deleted in caller m_WeeklyQuestChanged = false; + } void Player::ResetSeasonalQuestStatus(uint16 event_id) @@ -22646,7 +22706,7 @@ void Player::UpdateForQuestWorldObjects() if (m_clientGUIDs.empty()) return; - UpdateData udata; + UpdateData udata(GetMapId()); WorldPacket packet; for (ClientGUIDs::iterator itr=m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) { @@ -22714,7 +22774,7 @@ void Player::SummonIfPossible(bool agree) m_summon_expire = 0; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation()); } @@ -23075,8 +23135,8 @@ void Player::ResurectUsingRequestData() SetPower(POWER_MANA, GetMaxPower(POWER_MANA)); SetPower(POWER_RAGE, 0); - SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY)); + SetPower(POWER_FOCUS, GetMaxPower(POWER_FOCUS)); SpawnCorpseBones(); } @@ -23554,27 +23614,22 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n void Player::InitGlyphsForLevel() { - for (uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i) + uint32 slot = 0; + for (uint32 i = 0; i < sGlyphSlotStore.GetNumRows() && slot < MAX_GLYPH_SLOT_INDEX; ++i) if (GlyphSlotEntry const* gs = sGlyphSlotStore.LookupEntry(i)) - if (gs->Order) - SetGlyphSlot(gs->Order - 1, gs->Id); + SetGlyphSlot(slot++, gs->Id); uint8 level = getLevel(); - uint32 value = 0; + uint32 slotMask = 0; - // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level - if (level >= 15) - value |= (0x01 | 0x02); - if (level >= 30) - value |= 0x08; + if (level >= 25) + slotMask |= 0x01 | 0x02 | 0x40; if (level >= 50) - value |= 0x04; - if (level >= 70) - value |= 0x10; - if (level >= 80) - value |= 0x20; + slotMask |= 0x04 | 0x08 | 0x80; + if (level >= 75) + slotMask |= 0x10 | 0x20 | 0x100; - SetUInt32Value(PLAYER_GLYPHS_ENABLED, value); + SetUInt32Value(PLAYER_GLYPHS_ENABLED, slotMask); } bool Player::isTotalImmune() @@ -23888,9 +23943,9 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) --loot->unlootedCount; SendNewItem(newitem, uint32(item->count), false, false, true); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); } else SendEquipError(msg, NULL, NULL, item->itemid); @@ -23898,16 +23953,30 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) uint32 Player::CalculateTalentsPoints() const { - uint32 base_talent = getLevel() < 10 ? 0 : getLevel()-9; + // this dbc file has entries only up to level 100 + NumTalentsAtLevelEntry const* count = sNumTalentsAtLevelStore.LookupEntry(std::min<uint32>(getLevel(), 100)); + if (!count) + return 0; + + float baseForLevel = count->Talents; if (getClass() != CLASS_DEATH_KNIGHT || GetMapId() != 609) - return uint32(base_talent * sWorld->getRate(RATE_TALENT)); + return uint32(baseForLevel * sWorld->getRate(RATE_TALENT)); + + // Death Knight starting level + // hardcoded here - number of quest awarded talents is equal to number of talents any other class would have at level 55 + if (getLevel() < 55) + return 0; + + NumTalentsAtLevelEntry const* dkBase = sNumTalentsAtLevelStore.LookupEntry(55); + if (!dkBase) + return 0; - uint32 talentPointsForLevel = getLevel() < 56 ? 0 : getLevel() - 55; - talentPointsForLevel += m_questRewardTalentCount; + float talentPointsForLevel = count->Talents - dkBase->Talents; + talentPointsForLevel += float(GetQuestRewardedTalentCount()); - if (talentPointsForLevel > base_talent) - talentPointsForLevel = base_talent; + if (talentPointsForLevel > baseForLevel) + talentPointsForLevel = baseForLevel; return uint32(talentPointsForLevel * sWorld->getRate(RATE_TALENT)); } @@ -23933,6 +24002,7 @@ void Player::_LoadSkills(PreparedQueryResult result) // SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", GUID_LOPART(m_guid)); uint32 count = 0; + uint8 professionCount = 0; if (result) { do @@ -23975,14 +24045,28 @@ void Player::_LoadSkills(PreparedQueryResult result) continue; } - // enable unlearn button for primary professions only + uint16 field = count / 2; + uint8 offset = count & 1; + + SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, skill); + uint16 step = 0; + + if (pSkill->categoryId == SKILL_CATEGORY_SECONDARY) + step = max / 75; + if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION) - SetUInt32Value(PLAYER_SKILL_INDEX(count), MAKE_PAIR32(skill, 1)); - else - SetUInt32Value(PLAYER_SKILL_INDEX(count), MAKE_PAIR32(skill, 0)); + { + step = max / 75; + + if (professionCount < 2) + SetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + professionCount++, skill); + } - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(count), MAKE_SKILL_VALUE(value, max)); - SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(count), 0); + SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, step); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, value); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, max); + SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0); mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(count, SKILL_UNCHANGED))); @@ -24001,9 +24085,15 @@ void Player::_LoadSkills(PreparedQueryResult result) for (; count < PLAYER_MAX_SKILLS; ++count) { - SetUInt32Value(PLAYER_SKILL_INDEX(count), 0); - SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(count), 0); - SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(count), 0); + uint16 field = count / 2; + uint8 offset = count & 1; + + SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0); + SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0); } // special settings @@ -24121,7 +24211,7 @@ void Player::HandleFall(MovementInfo const& movementInfo) { // calculate total z distance of the fall float z_diff = m_lastFallZ - movementInfo.pos.GetPositionZ(); - //sLog->outDebug("zDiff = %f", z_diff); + //sLog->outDebug(LOG_FILTER_GENERAL, "zDiff = %f", z_diff); //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored // 14.57 can be calculated by resolving damageperc formula below to 0 @@ -24156,7 +24246,7 @@ void Player::HandleFall(MovementInfo const& movementInfo) // recheck alive, might have died of EnvironmentalDamage, avoid cases when player die in fact like Spirit of Redemption case if (isAlive() && final_damage < original_health) - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100)); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING, uint32(z_diff*100)); } //Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction @@ -24168,37 +24258,45 @@ void Player::HandleFall(MovementInfo const& movementInfo) void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) { - GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit); + GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, this); + + // Update only individual achievement criteria here, otherwise we may get multiple updates + // from a single boss kill + if (sAchievementMgr->IsGroupCriteriaType(type)) + return; + + if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId())) + guild->GetAchievementMgr().UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, this); } void Player::CompletedAchievement(AchievementEntry const* entry) { - GetAchievementMgr().CompletedAchievement(entry); + GetAchievementMgr().CompletedAchievement(entry, this); } -void Player::LearnTalent(uint32 talentId, uint32 talentRank) +bool Player::LearnTalent(uint32 talentId, uint32 talentRank) { uint32 CurTalentPoints = GetFreeTalentPoints(); if (CurTalentPoints == 0) - return; + return false; if (talentRank >= MAX_TALENT_RANK) - return; + return false; TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId); if (!talentInfo) - return; + return false; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); if (!talentTabInfo) - return; + return false; // prevent learn talent for different class (cheating) if ((getClassMask() & talentTabInfo->ClassMask) == 0) - return; + return false; // find current max talent rank (0~5) uint8 curtalent_maxrank = 0; // 0 = not learned any rank @@ -24213,11 +24311,11 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) // we already have same or higher talent rank learned if (curtalent_maxrank >= (talentRank + 1)) - return; + return false; // check if we have enough talent points if (CurTalentPoints < (talentRank - curtalent_maxrank + 1)) - return; + return false; // Check if it requires another talent if (talentInfo->DependsOn > 0) @@ -24232,33 +24330,32 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) hasEnoughRank = true; } if (!hasEnoughRank) - return; + return false; } } // Find out how many points we have in this field uint32 spentPoints = 0; - + uint32 primaryTreeTalents = 0; uint32 tTab = talentInfo->TalentTab; - if (talentInfo->Row > 0) + bool isMainTree = GetPrimaryTalentTree(GetActiveSpec()) == tTab || !GetPrimaryTalentTree(GetActiveSpec()); + + if (talentInfo->Row > 0 || !isMainTree) { - uint32 numRows = sTalentStore.GetNumRows(); - for (uint32 i = 0; i < numRows; i++) // Loop through all talents. + for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents. { - // Someday, someone needs to revamp - const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i); - if (tmpTalent) // the way talents are tracked + if (TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i)) // Someday, someone needs to revamp the way talents are tracked { - if (tmpTalent->TalentTab == tTab) + for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++) { - for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++) + if (tmpTalent->RankID[rank] != 0) { - if (tmpTalent->RankID[rank] != 0) + if (HasSpell(tmpTalent->RankID[rank])) { - if (HasSpell(tmpTalent->RankID[rank])) - { + if (tmpTalent->TalentTab == tTab) spentPoints += (rank + 1); - } + if (tmpTalent->TalentTab == GetPrimaryTalentTree(GetActiveSpec())) + primaryTreeTalents += (rank + 1); } } } @@ -24268,28 +24365,43 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) // not have required min points spent in talent tree if (spentPoints < (talentInfo->Row * MAX_TALENT_RANK)) - return; + return false; + + // player has not spent 31 talents in main tree before attempting to learn other tree's talents + if (!isMainTree && primaryTreeTalents < REQ_PRIMARY_TREE_TALENTS) + return false; // spell not set in talent.dbc uint32 spellid = talentInfo->RankID[talentRank]; if (spellid == 0) { sLog->outError(LOG_FILTER_PLAYER, "Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank); - return; + return false; } // already known if (HasSpell(spellid)) - return; + return false; // learn! (other talent ranks will unlearned at learning) learnSpell(spellid, false); - AddTalent(spellid, m_activeSpec, true); + AddTalent(spellid, GetActiveSpec(), true); + + sLog->outInfo(LOG_FILTER_GENERAL, "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, GetActiveSpec()); - sLog->outInfo(LOG_FILTER_PLAYER, "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, m_activeSpec); + // set talent tree for player + if (!GetPrimaryTalentTree(GetActiveSpec())) + { + SetPrimaryTalentTree(GetActiveSpec(), talentInfo->TalentTab); + std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab); + if (specSpells) + for (size_t i = 0; i < specSpells->size(); ++i) + learnSpell(specSpells->at(i), false); + } // update free talent points SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1)); + return true; } void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank) @@ -24430,7 +24542,7 @@ void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank) void Player::AddKnownCurrency(uint32 itemId) { if (CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId)) - SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (1LL << (ctEntry->BitIndex-1))); + SetFlag64(0, (1LL << (ctEntry->ID-1))); } void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode) @@ -24499,17 +24611,18 @@ bool Player::canSeeSpellClickOn(Creature const* c) const void Player::BuildPlayerTalentsInfoData(WorldPacket* data) { *data << uint32(GetFreeTalentPoints()); // unspentTalentPoints - *data << uint8(m_specsCount); // talent group count (0, 1 or 2) - *data << uint8(m_activeSpec); // talent group index (0 or 1) + *data << uint8(GetSpecsCount()); // talent group count (0, 1 or 2) + *data << uint8(GetActiveSpec()); // talent group index (0 or 1) - if (m_specsCount) + if (GetSpecsCount()) { - if (m_specsCount > MAX_TALENT_SPECS) - m_specsCount = MAX_TALENT_SPECS; + if (GetSpecsCount() > MAX_TALENT_SPECS) + SetSpecsCount(MAX_TALENT_SPECS); // loop through all specs (only 1 for now) - for (uint32 specIdx = 0; specIdx < m_specsCount; ++specIdx) + for (uint8 specIdx = 0; specIdx < GetSpecsCount(); ++specIdx) { + *data << uint32(GetPrimaryTalentTree(specIdx)); uint8 talentIdCount = 0; size_t pos = data->wpos(); *data << uint8(talentIdCount); // [PH], talentIdCount @@ -24558,7 +24671,7 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket* data) *data << uint8(MAX_GLYPH_SLOT_INDEX); // glyphs count for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) - *data << uint16(m_Glyphs[specIdx][i]); // GlyphProperties.dbc + *data << uint16(GetGlyph(specIdx, i)); // GlyphProperties.dbc } } } @@ -24898,15 +25011,11 @@ void Player::_LoadGlyphs(PreparedQueryResult result) Field* fields = result->Fetch(); uint8 spec = fields[0].GetUInt8(); - if (spec >= m_specsCount) + if (spec >= GetSpecsCount()) continue; - m_Glyphs[spec][0] = fields[1].GetUInt16(); - m_Glyphs[spec][1] = fields[2].GetUInt16(); - m_Glyphs[spec][2] = fields[3].GetUInt16(); - m_Glyphs[spec][3] = fields[4].GetUInt16(); - m_Glyphs[spec][4] = fields[5].GetUInt16(); - m_Glyphs[spec][5] = fields[6].GetUInt16(); + for (uint8 i = 0; i < 6; ++i) + _talentMgr->SpecInfo[spec].Glyphs[i] = fields[i + 1].GetUInt16(); } while (result->NextRow()); } @@ -24918,7 +25027,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans) trans->Append(stmt); - for (uint8 spec = 0; spec < m_specsCount; ++spec) + for (uint8 spec = 0; spec < GetSpecsCount(); ++spec) { uint8 index = 0; @@ -24928,7 +25037,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans) stmt->setUInt8(index++, spec); for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) - stmt->setUInt16(index++, uint16(m_Glyphs[spec][i])); + stmt->setUInt16(index++, uint16(GetGlyph(spec, i))); trans->Append(stmt); } @@ -24951,7 +25060,7 @@ void Player::_SaveTalents(SQLTransaction& trans) for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) { - for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();) + for (PlayerTalentMap::iterator itr = GetTalentMap(i)->begin(); itr != GetTalentMap(i)->end();) { if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) { @@ -24974,7 +25083,7 @@ void Player::_SaveTalents(SQLTransaction& trans) if (itr->second->state == PLAYERSPELL_REMOVED) { delete itr->second; - m_talents[i]->erase(itr++); + GetTalentMap(i)->erase(itr++); } else { @@ -24991,7 +25100,7 @@ void Player::UpdateSpecCount(uint8 count) if (curCount == count) return; - if (m_activeSpec >= count) + if (GetActiveSpec() >= count) ActivateSpec(0); SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -25018,11 +25127,10 @@ void Player::UpdateSpecCount(uint8 count) _SaveActions(trans); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC); - stmt->setUInt8(0, m_activeSpec); + stmt->setUInt8(0, GetActiveSpec()); stmt->setUInt32(1, GetGUIDLow()); trans->Append(stmt); - m_activeSpec = 0; } CharacterDatabase.CommitTransaction(trans); @@ -25100,10 +25208,19 @@ void Player::ActivateSpec(uint8 spec) } } + // Remove spec specific spells + for (uint32 i = 0; i < MAX_TALENT_TABS; ++i) + { + std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]); + if (specSpells) + for (size_t i = 0; i < specSpells->size(); ++i) + removeSpell(specSpells->at(i), true); + } + // set glyphs for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot) // remove secondary glyph - if (uint32 oldglyph = m_Glyphs[m_activeSpec][slot]) + if (uint32 oldglyph = GetGlyph(GetActiveSpec(), slot)) if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) RemoveAurasDueToSpell(old_gp->SpellId); @@ -25133,7 +25250,7 @@ void Player::ActivateSpec(uint8 spec) if (talentInfo->RankID[rank] == 0) continue; // if the talent can be found in the newly activated PlayerTalentMap - if (HasTalent(talentInfo->RankID[rank], m_activeSpec)) + if (HasTalent(talentInfo->RankID[rank], GetActiveSpec())) { learnSpell(talentInfo->RankID[rank], false); // add the talent to the PlayerSpellMap spentTalents += (rank + 1); // increment the spentTalents count @@ -25141,10 +25258,15 @@ void Player::ActivateSpec(uint8 spec) } } + std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetPrimaryTalentTree(GetActiveSpec())); + if (specSpells) + for (size_t i = 0; i < specSpells->size(); ++i) + learnSpell(specSpells->at(i), false); + // set glyphs for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot) { - uint32 glyph = m_Glyphs[m_activeSpec][slot]; + uint32 glyph = GetGlyph(GetActiveSpec(), slot); // apply primary glyph if (glyph) @@ -25154,13 +25276,13 @@ void Player::ActivateSpec(uint8 spec) SetGlyph(slot, glyph); } - m_usedTalentCount = spentTalents; + SetUsedTalentCount(spentTalents); InitTalentForLevel(); { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC); stmt->setUInt32(0, GetGUIDLow()); - stmt->setUInt8(1, m_activeSpec); + stmt->setUInt8(1, GetActiveSpec()); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) _LoadActions(result); } @@ -25172,6 +25294,9 @@ void Player::ActivateSpec(uint8 spec) SetPower(POWER_MANA, 0); // Mana must be 0 even if it isn't the active power type. SetPower(pw, 0); + + if (!sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec()))) + ResetTalents(true); } void Player::ResetTimeSync() @@ -25197,6 +25322,7 @@ void Player::SetReputation(uint32 factionentry, uint32 value) { GetReputationMgr().SetReputation(sFactionStore.LookupEntry(factionentry), value); } + uint32 Player::GetReputation(uint32 factionentry) { return GetReputationMgr().GetReputation(sFactionStore.LookupEntry(factionentry)); @@ -25204,7 +25330,7 @@ uint32 Player::GetReputation(uint32 factionentry) std::string Player::GetGuildName() { - return sGuildMgr->GetGuildById(GetGuildId())->GetName(); + return GetGuildId() ? sGuildMgr->GetGuildById(GetGuildId())->GetName() : ""; } void Player::SendDuelCountdown(uint32 counter) @@ -25228,7 +25354,7 @@ void Player::DeleteRefundReference(uint32 it) } } -void Player::SendRefundInfo(Item* item) +void Player::SendRefundInfo(Item *item) { // This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours. item->UpdatePlayedTime(this); @@ -25253,18 +25379,40 @@ void Player::SendRefundInfo(Item* item) return; } + ObjectGuid guid = item->GetGUID(); WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); - data << uint64(item->GetGUID()); // item guid - data << uint32(item->GetPaidMoney()); // money cost - data << uint32(iece->reqhonorpoints); // honor point cost - data << uint32(iece->reqarenapoints); // arena point cost - for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) // item cost data + data.WriteBit(guid[3]); + data.WriteBit(guid[5]); + data.WriteBit(guid[7]); + data.WriteBit(guid[6]); + data.WriteBit(guid[2]); + data.WriteBit(guid[4]); + data.WriteBit(guid[0]); + data.WriteBit(guid[1]); + data.FlushBits(); + data.WriteByteSeq(guid[7]); + data << uint32(GetTotalPlayedTime() - item->GetPlayedTime()); + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data { - data << uint32(iece->reqitem[i]); - data << uint32(iece->reqitemcount[i]); + data << uint32(iece->RequiredItemCount[i]); + data << uint32(iece->RequiredItem[i]); } + + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[2]); + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data + { + data << uint32(iece->RequiredCurrencyCount[i]); + data << uint32(iece->RequiredCurrency[i]); + } + + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[5]); data << uint32(0); - data << uint32(GetTotalPlayedTime() - item->GetPlayedTime()); + data.WriteByteSeq(guid[0]); + data << uint32(item->GetPaidMoney()); // money cost GetSession()->SendPacket(&data); } @@ -25324,10 +25472,10 @@ void Player::RefundItem(Item* item) } bool store_error = false; - for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) { - uint32 count = iece->reqitemcount[i]; - uint32 itemid = iece->reqitem[i]; + uint32 count = iece->RequiredItemCount[i]; + uint32 itemid = iece->RequiredItem[i]; if (count && itemid) { @@ -25354,12 +25502,10 @@ void Player::RefundItem(Item* item) data << uint64(item->GetGUID()); // item guid data << uint32(0); // 0, or error code data << uint32(item->GetPaidMoney()); // money cost - data << uint32(iece->reqhonorpoints); // honor point cost - data << uint32(iece->reqarenapoints); // arena point cost - for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) // item cost data + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // item cost data { - data << uint32(iece->reqitem[i]); - data << uint32(iece->reqitemcount[i]); + data << uint32(iece->RequiredItem[i]); + data << uint32(iece->RequiredItemCount[i]); } GetSession()->SendPacket(&data); @@ -25375,10 +25521,10 @@ void Player::RefundItem(Item* item) DestroyItem(item->GetBagSlot(), item->GetSlot(), true); // Grant back extendedcost items - for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) + for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) { - uint32 count = iece->reqitemcount[i]; - uint32 itemid = iece->reqitem[i]; + uint32 count = iece->RequiredItemCount[i]; + uint32 itemid = iece->RequiredItem[i]; if (count && itemid) { ItemPosCountVec dest; @@ -25393,13 +25539,7 @@ void Player::RefundItem(Item* item) if (moneyRefund) ModifyMoney(moneyRefund); // Saved in SaveInventoryAndGoldToDB - // Grant back Honor points - if (uint32 honorRefund = iece->reqhonorpoints) - ModifyHonorPoints(honorRefund, &trans); - - // Grant back Arena points - if (uint32 arenaRefund = iece->reqarenapoints) - ModifyArenaPoints(arenaRefund, &trans); + // Grant back Arena and Honor points ? SaveInventoryAndGoldToDB(trans); @@ -25488,6 +25628,106 @@ bool Player::IsInWhisperWhiteList(uint64 guid) return false; } +uint8 Player::GetNextVoidStorageFreeSlot() const +{ + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + if (!_voidStorageItems[i]) // unused item + return i; + + return -1; +} + +uint8 Player::GetNumOfVoidStorageFreeSlots() const +{ + uint8 count = 0; + + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + if (!_voidStorageItems[i]) + count++; + + return count; +} + +uint8 Player::AddVoidStorageItem(const VoidStorageItem& item) +{ + uint8 slot = GetNextVoidStorageFreeSlot(); + + if (slot < 0 || slot > VOID_STORAGE_MAX_SLOT) + { + GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); + return -1; + } + + _voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemEntry, + item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor); + return slot; +} + +void Player::AddVoidStorageItemAtSlot(uint8 slot, const VoidStorageItem& item) +{ + if (slot < 0 || slot > VOID_STORAGE_MAX_SLOT) + { + GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); + return; + } + + if (_voidStorageItems[slot]) + { + sLog->outError(LOG_FILTER_GENERAL, "Player::AddVoidStorageItemAtSlot - Player (GUID: %u, name: %s) tried to add an item to an used slot (item id: %u, entry: %u, slot: %u).", GetGUIDLow(), GetName(), _voidStorageItems[slot]->ItemId, _voidStorageItems[slot]->ItemEntry, slot); + GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); + return; + } + + _voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemId, + item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor); +} + +void Player::DeleteVoidStorageItem(uint8 slot) +{ + if (slot < 0 || slot > VOID_STORAGE_MAX_SLOT) + { + GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); + return; + } + + delete _voidStorageItems[slot]; + _voidStorageItems[slot] = NULL; +} + +bool Player::SwapVoidStorageItem(uint8 oldSlot, uint8 newSlot) +{ + if (oldSlot < 0 || oldSlot > VOID_STORAGE_MAX_SLOT || newSlot < 0 || newSlot > VOID_STORAGE_MAX_SLOT || oldSlot == newSlot) + return false; + + std::swap(_voidStorageItems[newSlot], _voidStorageItems[oldSlot]); + return true; +} + +VoidStorageItem* Player::GetVoidStorageItem(uint8 slot) const +{ + if (slot < 0 || slot > VOID_STORAGE_MAX_SLOT) + { + GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); + return NULL; + } + + return _voidStorageItems[slot]; +} + +VoidStorageItem* Player::GetVoidStorageItem(uint64 id, uint8& slot) const +{ + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + { + if (_voidStorageItems[i] && _voidStorageItems[i]->ItemId == id) + { + slot = i; + return _voidStorageItems[i]; + } + } + + return NULL; +} + bool Player::SetHover(bool enable) { if (!Unit::SetHover(enable)) @@ -25537,3 +25777,32 @@ void Player::SendMovementSetFeatherFall(bool apply) data << uint32(0); //! movement counter SendDirectMessage(&data); } + +void Player::SendMovementSetCollisionHeight(float height) +{ + ObjectGuid guid = GetGUID(); + WorldPacket data(SMSG_MOVE_SET_COLLISION_HEIGHT, 2 + 8 + 4 + 4); + data.WriteBits(0, 2); + data.WriteBit(guid[6]); + data.WriteBit(guid[1]); + data.WriteBit(guid[4]); + data.WriteBit(guid[7]); + data.WriteBit(guid[5]); + data.WriteBit(guid[2]); + data.WriteBit(guid[0]); + data.WriteBit(guid[3]); + data.FlushBits(); + + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[5]); + data << uint32(sWorld->GetGameTime()); // Packet counter + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[7]); + data << float(height); + + SendDirectMessage(&data); +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 413d7fae32c..cea45d06936 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -57,7 +57,7 @@ class UpdateMask; typedef std::deque<Mail*> PlayerMails; -#define PLAYER_MAX_SKILLS 127 +#define PLAYER_MAX_SKILLS 128 #define PLAYER_MAX_DAILY_QUESTS 25 #define PLAYER_EXPLORED_ZONES_SIZE 128 @@ -124,9 +124,25 @@ struct SpellModifier Aura* const ownerAura; }; +enum PlayerCurrencyState +{ + PLAYERCURRENCY_UNCHANGED = 0, + PLAYERCURRENCY_CHANGED = 1, + PLAYERCURRENCY_NEW = 2, + PLAYERCURRENCY_REMOVED = 3 +}; + +struct PlayerCurrency +{ + PlayerCurrencyState state; + uint32 totalCount; + uint32 weekCount; +}; + typedef UNORDERED_MAP<uint32, PlayerTalent*> PlayerTalentMap; typedef UNORDERED_MAP<uint32, PlayerSpell*> PlayerSpellMap; typedef std::list<SpellModifier*> SpellModList; +typedef UNORDERED_MAP<uint32, PlayerCurrency> PlayerCurrenciesMap; typedef std::list<uint64> WhisperListContainer; @@ -141,9 +157,9 @@ typedef UNORDERED_MAP<uint32 /*instanceId*/, time_t/*releaseTime*/> InstanceTime enum TrainerSpellState { - TRAINER_SPELL_GREEN = 0, - TRAINER_SPELL_RED = 1, - TRAINER_SPELL_GRAY = 2, + TRAINER_SPELL_GRAY = 0, + TRAINER_SPELL_GREEN = 1, + TRAINER_SPELL_RED = 2, TRAINER_SPELL_GREEN_DISABLED = 10 // custom value, not send to client: formally green but learn not allowed }; @@ -205,20 +221,6 @@ struct PlayerCreateInfoItem typedef std::list<PlayerCreateInfoItem> PlayerCreateInfoItems; -struct PlayerClassLevelInfo -{ - PlayerClassLevelInfo() : basehealth(0), basemana(0) {} - uint16 basehealth; - uint16 basemana; -}; - -struct PlayerClassInfo -{ - PlayerClassInfo() : levelInfo(NULL) { } - - PlayerClassLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1 -}; - struct PlayerLevelInfo { PlayerLevelInfo() { for (uint8 i=0; i < MAX_STATS; ++i) stats[i] = 0; } @@ -348,14 +350,6 @@ struct EnchantDuration typedef std::list<EnchantDuration> EnchantDurationList; typedef std::list<Item*> ItemDurationList; -enum PlayerMovementType -{ - MOVE_ROOT = 1, - MOVE_UNROOT = 2, - MOVE_WATER_WALK = 3, - MOVE_LAND_WALK = 4 -}; - enum DrunkenState { DRUNKEN_SOBER = 0, @@ -397,7 +391,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK26 = 0x04000000, PLAYER_FLAGS_UNK27 = 0x08000000, PLAYER_FLAGS_UNK28 = 0x10000000, - PLAYER_FLAGS_UNK29 = 0x20000000, + PLAYER_FLAGS_VOID_UNLOCKED = 0x20000000, // void storage PLAYER_FLAGS_UNK30 = 0x40000000, PLAYER_FLAGS_UNK31 = 0x80000000, }; @@ -470,7 +464,7 @@ enum MirrorTimerType { FATIGUE_TIMER = 0, BREATH_TIMER = 1, - FIRE_TIMER = 2 + FIRE_TIMER = 2 // feign death }; #define MAX_TIMERS 3 #define DISABLED_MIRROR_TIMER -1 @@ -484,7 +478,6 @@ enum PlayerExtraFlags PLAYER_EXTRA_TAXICHEAT = 0x0008, PLAYER_EXTRA_GM_INVISIBLE = 0x0010, PLAYER_EXTRA_GM_CHAT = 0x0020, // Show GM badge in chat messages - PLAYER_EXTRA_HAS_310_FLYER = 0x0040, // Marks if player already has 310% speed flying mount // other states PLAYER_EXTRA_PVP_DEATH = 0x0100 // store PvP death status until corpse creating. @@ -556,7 +549,7 @@ enum PlayerSlots // first slot for item stored (in any way in player m_items data) PLAYER_SLOT_START = 0, // last+1 slot for item stored (in any way in player m_items data) - PLAYER_SLOT_END = 150, + PLAYER_SLOT_END = 86, PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START) }; @@ -618,18 +611,6 @@ enum BuyBackSlots // 12 slots BUYBACK_SLOT_END = 86 }; -enum KeyRingSlots // 32 slots -{ - KEYRING_SLOT_START = 86, - KEYRING_SLOT_END = 118 -}; - -enum CurrencyTokenSlots // 32 slots -{ - CURRENCYTOKEN_SLOT_START = 118, - CURRENCYTOKEN_SLOT_END = 150 -}; - enum EquipmentSetUpdateState { EQUIPMENT_SET_UNCHANGED = 0, @@ -677,22 +658,24 @@ enum TradeSlots enum TransferAbortReason { - TRANSFER_ABORT_NONE = 0x00, - TRANSFER_ABORT_ERROR = 0x01, - TRANSFER_ABORT_MAX_PLAYERS = 0x02, // Transfer Aborted: instance is full - TRANSFER_ABORT_NOT_FOUND = 0x03, // Transfer Aborted: instance not found - TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x04, // You have entered too many instances recently. - TRANSFER_ABORT_ZONE_IN_COMBAT = 0x06, // Unable to zone in while an encounter is in progress. - TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x07, // You must have <TBC, WotLK> expansion installed to access this area. - TRANSFER_ABORT_DIFFICULTY = 0x08, // <Normal, Heroic, Epic> difficulty mode is not available for %s. - TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place! - TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later. - TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1 - TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1 - TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1 - TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2 - TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. - TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time. + TRANSFER_ABORT_NONE = 0x00, + TRANSFER_ABORT_ERROR = 0x01, + TRANSFER_ABORT_MAX_PLAYERS = 0x02, // Transfer Aborted: instance is full + TRANSFER_ABORT_NOT_FOUND = 0x03, // Transfer Aborted: instance not found + TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x04, // You have entered too many instances recently. + TRANSFER_ABORT_ZONE_IN_COMBAT = 0x06, // Unable to zone in while an encounter is in progress. + TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x07, // You must have <TBC, WotLK> expansion installed to access this area. + TRANSFER_ABORT_DIFFICULTY = 0x08, // <Normal, Heroic, Epic> difficulty mode is not available for %s. + TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place! + TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later. + TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1 + TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1 + TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1 + TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2 + TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm. + TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time. + TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE = 0x12, // 4.2.2 + TRANSFER_ABORT_ALREADY_COMPLETED_ENCOUNTER = 0x13, // 4.2.2 }; enum InstanceResetWarningType @@ -807,6 +790,7 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOADQUESTSTATUSREW = 29, PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES = 30, PLAYER_LOGIN_QUERY_LOADSEASONALQUESTSTATUS = 31, + PLAYER_LOGIN_QUERY_LOADVOIDSTORAGE = 32, MAX_PLAYER_LOGIN_QUERY, }; @@ -823,7 +807,7 @@ enum PlayerDelayedOperations // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) -#define MAX_MONEY_AMOUNT (0x7FFFFFFF-1) +#define MAX_MONEY_AMOUNT (UI64LIT(9999999999)) // TODO: Move this restriction to worldserver.conf, default to this value, hardcap at uint64.max struct InstancePlayerBind { @@ -865,12 +849,6 @@ enum CharDeleteMethod // the name gets freed up and appears as deleted ingame }; -enum CurrencyItems -{ - ITEM_HONOR_POINTS_ID = 43308, - ITEM_ARENA_POINTS_ID = 43307 -}; - enum ReferAFriendError { ERR_REFER_A_FRIEND_NONE = 0x00, @@ -976,6 +954,33 @@ struct BGData bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; } }; +struct VoidStorageItem +{ + VoidStorageItem() + { + ItemId = 0; + ItemEntry = 0; + CreatorGuid = 0; + ItemRandomPropertyId = 0; + ItemSuffixFactor = 0; + } + + VoidStorageItem(uint64 id, uint32 entry, uint32 creator, uint32 randomPropertyId, uint32 suffixFactor) + { + ItemId = id; + ItemEntry = entry; + CreatorGuid = creator; + ItemRandomPropertyId = randomPropertyId; + ItemSuffixFactor = suffixFactor; + } + + uint64 ItemId; + uint32 ItemEntry; + uint32 CreatorGuid; + uint32 ItemRandomPropertyId; + uint32 ItemSuffixFactor; +}; + class TradeData { public: // constructors @@ -997,8 +1002,8 @@ class TradeData Item* GetSpellCastItem() const; bool HasSpellCastItem() const { return m_spellCastItem != 0; } - uint32 GetMoney() const { return m_money; } - void SetMoney(uint32 money); + uint64 GetMoney() const { return m_money; } + void SetMoney(uint64 money); bool IsAccepted() const { return m_accepted; } void SetAccepted(bool state, bool crosssend = false); @@ -1018,12 +1023,12 @@ class TradeData bool m_accepted; // m_player press accept for trade list bool m_acceptProccess; // one from player/trader press accept and this processed - uint32 m_money; // m_player place money to trade + uint64 m_money; // m_player place money to trade uint32 m_spell; // m_player apply spell to non-traded slot item uint64 m_spellCastItem; // applied spell casted by item use - uint64 m_items[TRADE_SLOT_COUNT]; // traded itmes from m_player side including non-traded slot + uint64 m_items[TRADE_SLOT_COUNT]; // traded items from m_player side including non-traded slot }; class KillRewarder @@ -1058,6 +1063,50 @@ private: bool _isPvP; }; +struct PlayerTalentInfo +{ + PlayerTalentInfo() : + FreeTalentPoints(0), UsedTalentCount(0), QuestRewardedTalentCount(0), + ResetTalentsCost(0), ResetTalentsTime(0), + ActiveSpec(0), SpecsCount(1) + { + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + { + SpecInfo[i].Talents = new PlayerTalentMap(); + memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32)); + SpecInfo[i].TalentTree = 0; + } + } + + ~PlayerTalentInfo() + { + for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) + { + for (PlayerTalentMap::const_iterator itr = SpecInfo[i].Talents->begin(); itr != SpecInfo[i].Talents->end(); ++itr) + delete itr->second; + delete SpecInfo[i].Talents; + } + } + + struct TalentSpecInfo + { + PlayerTalentMap* Talents; + uint32 Glyphs[MAX_GLYPH_SLOT_INDEX]; + uint32 TalentTree; + } SpecInfo[MAX_TALENT_SPECS]; + + uint32 FreeTalentPoints; + uint32 UsedTalentCount; + uint32 QuestRewardedTalentCount; + uint32 ResetTalentsCost; + time_t ResetTalentsTime; + uint8 ActiveSpec; + uint8 SpecsCount; + +private: + PlayerTalentInfo(PlayerTalentInfo const&); +}; + class Player : public Unit, public GridObject<Player> { friend class WorldSession; @@ -1093,7 +1142,7 @@ class Player : public Unit, public GridObject<Player> void Update(uint32 time); - static bool BuildEnumData(PreparedQueryResult result, WorldPacket* data); + static bool BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer); void SetInWater(bool apply); @@ -1139,8 +1188,6 @@ class Player : public Unit, public GridObject<Player> void SetTaxiCheater(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; } bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); } void SetGMVisible(bool on); - bool Has310Flyer(bool checkAllSpells, uint32 excludeSpellId = 0); - void SetHas310Flyer(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_HAS_310_FLYER; else m_ExtraFlags &= ~PLAYER_EXTRA_HAS_310_FLYER; } void SetPvPDeath(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_PVP_DEATH; else m_ExtraFlags &= ~PLAYER_EXTRA_PVP_DEATH; } void GiveXP(uint32 xp, Unit* victim, float group_rate=1.0f); @@ -1189,7 +1236,8 @@ class Player : public Unit, public GridObject<Player> void Yell(const std::string& text, const uint32 language); void TextEmote(const std::string& text); void Whisper(const std::string& text, const uint32 language, uint64 receiver); - void BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language) const; + void WhisperAddon(const std::string& text, const std::string& prefix, uint64 receiver); + void BuildPlayerChat(WorldPacket* data, uint8 msgtype, const std::string& text, uint32 language, const char* addonPrefix = NULL) const; /*********************************************************/ /*** STORAGE SYSTEM ***/ @@ -1276,11 +1324,13 @@ class Player : public Unit, public GridObject<Player> void AddRefundReference(uint32 it); void DeleteRefundReference(uint32 it); + void SendCurrencies() const; + uint32 GetCurrency(uint32 id) const; + bool HasCurrency(uint32 id, uint32 count) const; + void SetCurrency(uint32 id, uint32 count); + void ModifyCurrency(uint32 id, int32 count); + void ApplyEquipCooldown(Item* pItem); - void SetAmmo(uint32 item); - void RemoveAmmo(); - float GetAmmoDPS() const { return m_ammoDPS; } - bool CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const; void QuickEquipItem(uint16 pos, Item* pItem); void VisualizeItem(uint8 slot, Item* pItem); void SetVisibleItemSlot(uint8 slot, Item* pItem); @@ -1305,7 +1355,6 @@ class Player : public Unit, public GridObject<Player> void AddItemToBuyBackSlot(Item* pItem); Item* GetItemFromBuyBackSlot(uint32 slot); void RemoveItemFromBuyBackSlot(uint32 slot, bool del); - uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END-KEYRING_SLOT_START; } void SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2 = NULL, uint32 itemid = 0); void SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param); void SendSellError(SellResult msg, Creature* creature, uint64 guid, uint32 param); @@ -1344,6 +1393,7 @@ class Player : public Unit, public GridObject<Player> void AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 duration); void ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur = true, bool ignore_condition = false); void ApplyEnchantment(Item* item, bool apply); + void ApplyReforgeEnchantment(Item* item, bool apply); void UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16 new_value); void SendEnchantmentDurations(); void BuildEnchantmentsInfoData(WorldPacket* data); @@ -1474,7 +1524,7 @@ class Player : public Unit, public GridObject<Player> void UpdateForQuestWorldObjects(); bool CanShareQuest(uint32 quest_id) const; - void SendQuestComplete(uint32 quest_id); + void SendQuestComplete(Quest const* quest); void SendQuestReward(Quest const* quest, uint32 XP, Object* questGiver); void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK); void SendQuestTimerFailed(uint32 quest_id); @@ -1510,6 +1560,8 @@ class Player : public Unit, public GridObject<Player> static bool LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, float& o, bool& in_flight, uint64 guid); static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; } + static bool IsValidClass(uint8 Class) { return (1 << (Class - 1)) & CLASSMASK_ALL_PLAYABLE; } + static bool IsValidRace(uint8 Race) { return (1 << (Race - 1)) & RACEMASK_ALL_PLAYABLE; } /*********************************************************/ /*** SAVE SYSTEM ***/ @@ -1541,19 +1593,19 @@ class Player : public Unit, public GridObject<Player> void setRegenTimerCount(uint32 time) {m_regenTimerCount = time;} void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;} - uint32 GetMoney() const { return GetUInt32Value(PLAYER_FIELD_COINAGE); } - void ModifyMoney(int32 d); - bool HasEnoughMoney(uint32 amount) const { return (GetMoney() >= amount); } - bool HasEnoughMoney(int32 amount) const + uint64 GetMoney() const { return GetUInt64Value(PLAYER_FIELD_COINAGE); } + void ModifyMoney(int64 d); + bool HasEnoughMoney(uint64 amount) const { return GetMoney() >= amount; } + bool HasEnoughMoney(int64 amount) const { if (amount > 0) - return (GetMoney() >= (uint32) amount); + return (GetMoney() >= (uint64)amount); return true; } - void SetMoney(uint32 value) + void SetMoney(uint64 value) { - SetUInt32Value(PLAYER_FIELD_COINAGE, value); + SetUInt64Value(PLAYER_FIELD_COINAGE, value); MoneyChanged(value); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED); } @@ -1650,42 +1702,57 @@ class Player : public Unit, public GridObject<Player> void SetReputation(uint32 factionentry, uint32 value); uint32 GetReputation(uint32 factionentry); std::string GetGuildName(); - uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); } - void SetFreeTalentPoints(uint32 points); - bool resetTalents(bool no_cost = false); - uint32 resetTalentsCost() const; + + // Talents + uint32 GetFreeTalentPoints() const { return _talentMgr->FreeTalentPoints; } + void SetFreeTalentPoints(uint32 points) { _talentMgr->FreeTalentPoints = points; } + uint32 GetUsedTalentCount() const { return _talentMgr->UsedTalentCount; } + void SetUsedTalentCount(uint32 talents) { _talentMgr->UsedTalentCount = talents; } + uint32 GetQuestRewardedTalentCount() const { return _talentMgr->QuestRewardedTalentCount; } + void AddQuestRewardedTalentCount(uint32 points) { _talentMgr->QuestRewardedTalentCount += points; } + uint32 GetTalentResetCost() const { return _talentMgr->ResetTalentsCost; } + void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; } + uint32 GetTalentResetTime() const { return _talentMgr->ResetTalentsTime; } + void SetTalentResetTime(time_t time_) { _talentMgr->ResetTalentsTime = time_; } + uint32 GetPrimaryTalentTree(uint8 spec) const { return _talentMgr->SpecInfo[spec].TalentTree; } + void SetPrimaryTalentTree(uint8 spec, uint32 tree) { _talentMgr->SpecInfo[spec].TalentTree = tree; } + uint8 GetActiveSpec() const { return _talentMgr->ActiveSpec; } + void SetActiveSpec(uint8 spec){ _talentMgr->ActiveSpec = spec; } + uint8 GetSpecsCount() const { return _talentMgr->SpecsCount; } + void SetSpecsCount(uint8 count) { _talentMgr->SpecsCount = count; } + + bool ResetTalents(bool no_cost = false); + uint32 GetNextResetTalentsCost() const; void InitTalentForLevel(); void BuildPlayerTalentsInfoData(WorldPacket* data); void BuildPetTalentsInfoData(WorldPacket* data); void SendTalentsInfoData(bool pet); - void LearnTalent(uint32 talentId, uint32 talentRank); + bool LearnTalent(uint32 talentId, uint32 talentRank); void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank); - bool AddTalent(uint32 spellId, uint8 spec, bool learning); bool HasTalent(uint32 spell_id, uint8 spec) const; - uint32 CalculateTalentsPoints() const; // Dual Spec void UpdateSpecCount(uint8 count); - uint32 GetActiveSpec() { return m_activeSpec; } - void SetActiveSpec(uint8 spec){ m_activeSpec = spec; } - uint8 GetSpecsCount() { return m_specsCount; } - void SetSpecsCount(uint8 count) { m_specsCount = count; } void ActivateSpec(uint8 spec); void InitGlyphsForLevel(); void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); } - uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } + uint32 GetGlyphSlot(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } void SetGlyph(uint8 slot, uint32 glyph) { - m_Glyphs[m_activeSpec][slot] = glyph; + _talentMgr->SpecInfo[GetActiveSpec()].Glyphs[slot] = glyph; SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); } - uint32 GetGlyph(uint8 slot) { return m_Glyphs[m_activeSpec][slot]; } + uint32 GetGlyph(uint8 spec, uint8 slot) const { return _talentMgr->SpecInfo[spec].Glyphs[slot]; } + + PlayerTalentMap const* GetTalentMap(uint8 spec) const { return _talentMgr->SpecInfo[spec].Talents; } + PlayerTalentMap* GetTalentMap(uint8 spec) { return _talentMgr->SpecInfo[spec].Talents; } + ActionButtonList const& GetActionButtons() const { return m_actionButtons; } - uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); } - void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2, profs); } + uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); } + void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS, profs); } void InitPrimaryProfessions(); PlayerSpellMap const& GetSpellMap() const { return m_spells; } @@ -1805,11 +1872,20 @@ class Player : public Unit, public GridObject<Player> void RemoveFromGroup(RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT) { RemoveFromGroup(GetGroup(), GetGUID(), method); } void SendUpdateToOutOfRangeGroupMembers(); - void SetInGuild(uint32 GuildId) { SetUInt32Value(PLAYER_GUILDID, GuildId); } + void SetInGuild(uint32 guildId) + { + if (guildId) + SetUInt64Value(OBJECT_FIELD_DATA, MAKE_NEW_GUID(guildId, 0, HIGHGUID_GUILD)); + else + SetUInt64Value(OBJECT_FIELD_DATA, 0); + + SetUInt16Value(OBJECT_FIELD_TYPE, 1, guildId != 0); + } + void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); } - uint8 GetRank() { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); } + uint32 GetRank() { return GetUInt32Value(PLAYER_GUILDRANK); } void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; } - uint32 GetGuildId() { return GetUInt32Value(PLAYER_GUILDID); } + uint32 GetGuildId() const { return GetUInt32Value(OBJECT_FIELD_DATA); /* return only lower part */ } static uint32 GetGuildIdFromDB(uint64 guid); static uint8 GetRankFromDB(uint64 guid); int GetGuildIdInvited() { return m_GuildIdInvited; } @@ -1861,7 +1937,6 @@ class Player : public Unit, public GridObject<Player> void UpdateArmor(); void UpdateMaxHealth(); void UpdateMaxPower(Powers power); - void ApplyFeralAPBonus(int32 amount, bool apply); void UpdateAttackPowerAndDamage(bool ranged = false); void UpdateShieldBlockValue(); void UpdateDamagePhysical(WeaponAttackType attType); @@ -1942,7 +2017,6 @@ class Player : public Unit, public GridObject<Player> void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr); void SendTeleportPacket(Position &oldPos); - void SendTeleportAckPacket(); Corpse* GetCorpse() const; void SpawnCorpseBones(); @@ -1970,8 +2044,6 @@ class Player : public Unit, public GridObject<Player> } bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); } - void SetMovement(PlayerMovementType pType); - bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone); void JoinedChannel(Channel* c); @@ -2036,15 +2108,10 @@ class Player : public Unit, public GridObject<Player> /*********************************************************/ /*** PVP SYSTEM ***/ /*********************************************************/ + // TODO: Properly implement correncies as of Cataclysm void UpdateHonorFields(); bool RewardHonor(Unit* victim, uint32 groupsize, int32 honor = -1, bool pvptoken = false); - uint32 GetHonorPoints() const { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); } - uint32 GetArenaPoints() const { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); } - void ModifyHonorPoints(int32 value, SQLTransaction* trans = NULL); //! If trans is specified, honor save query will be added to trans - void ModifyArenaPoints(int32 value, SQLTransaction* trans = NULL); //! If trans is specified, arena point save query will be added to trans uint32 GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const; - void SetHonorPoints(uint32 value); - void SetArenaPoints(uint32 value); //End of PvP System @@ -2089,7 +2156,6 @@ class Player : public Unit, public GridObject<Player> void _ApplyAllLevelScaleItemMods(bool apply); void _ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply, bool only_level_scale = false); void _ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply); - void _ApplyAmmoBonuses(); bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot); void ToggleMetaGemsActive(uint8 exceptslot, bool apply); void CorrectMetaGemEnchants(uint8 slot, bool apply); @@ -2457,8 +2523,8 @@ class Player : public Unit, public GridObject<Player> void AddRunePower(uint8 index); void InitRunes(); - AchievementMgr& GetAchievementMgr() { return m_achievementMgr; } - AchievementMgr const& GetAchievementMgr() const { return m_achievementMgr; } + AchievementMgr<Player>& GetAchievementMgr() { return m_achievementMgr; } + AchievementMgr<Player> const& GetAchievementMgr() const { return m_achievementMgr; } void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); void CompletedAchievement(AchievementEntry const* entry); @@ -2488,6 +2554,7 @@ class Player : public Unit, public GridObject<Player> void SendMovementSetHover(bool apply); void SendMovementSetWaterWalking(bool apply); void SendMovementSetFeatherFall(bool apply); + void SendMovementSetCollisionHeight(float height); bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } @@ -2525,6 +2592,19 @@ class Player : public Unit, public GridObject<Player> } } + // Void Storage + bool IsVoidStorageUnlocked() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); } + void UnlockVoidStorage() { SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); } + void LockVoidStorage() { RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); } + uint8 GetNextVoidStorageFreeSlot() const; + uint8 GetNumOfVoidStorageFreeSlots() const; + uint8 AddVoidStorageItem(const VoidStorageItem& item); + void AddVoidStorageItemAtSlot(uint8 slot, const VoidStorageItem& item); + void DeleteVoidStorageItem(uint8 slot); + bool SwapVoidStorageItem(uint8 oldSlot, uint8 newSlot); + VoidStorageItem* GetVoidStorageItem(uint8 slot) const; + VoidStorageItem* GetVoidStorageItem(uint64 id, uint8& slot) const; + protected: // Gamemaster whisper whitelist WhisperListContainer WhisperList; @@ -2574,6 +2654,7 @@ class Player : public Unit, public GridObject<Player> void _LoadGlyphAuras(); void _LoadBoundInstances(PreparedQueryResult result); void _LoadInventory(PreparedQueryResult result, uint32 timeDiff); + void _LoadVoidStorage(PreparedQueryResult result); void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery); void _LoadMail(); void _LoadMailedItems(Mail* mail); @@ -2603,6 +2684,7 @@ class Player : public Unit, public GridObject<Player> void _SaveActions(SQLTransaction& trans); void _SaveAuras(SQLTransaction& trans); void _SaveInventory(SQLTransaction& trans); + void _SaveVoidStorage(SQLTransaction& trans); void _SaveMail(SQLTransaction& trans); void _SaveQuestStatus(SQLTransaction& trans); void _SaveDailyQuestStatus(SQLTransaction& trans); @@ -2647,6 +2729,11 @@ class Player : public Unit, public GridObject<Player> Item* m_items[PLAYER_SLOTS_COUNT]; uint32 m_currentBuybackSlot; + PlayerCurrenciesMap m_currencies; + uint32 _GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const; + + VoidStorageItem* _voidStorageItems[VOID_STORAGE_MAX_SLOT]; + std::vector<Item*> m_itemUpdateQueue; bool m_itemUpdateQueueBlocked; @@ -2669,15 +2756,11 @@ class Player : public Unit, public GridObject<Player> PlayerMails m_mail; PlayerSpellMap m_spells; - PlayerTalentMap* m_talents[MAX_TALENT_SPECS]; uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use GlobalCooldownMgr m_GlobalCooldownMgr; - uint8 m_activeSpec; - uint8 m_specsCount; - - uint32 m_Glyphs[MAX_TALENT_SPECS][MAX_GLYPH_SLOT_INDEX]; + PlayerTalentInfo* _talentMgr; ActionButtonList m_actionButtons; @@ -2737,7 +2820,6 @@ class Player : public Unit, public GridObject<Player> bool m_canBlock; bool m_canTitanGrip; uint8 m_swingErrorMsg; - float m_ammoDPS; ////////////////////Rest System///////////////////// time_t time_inn_enter; @@ -2748,10 +2830,6 @@ class Player : public Unit, public GridObject<Player> float m_rest_bonus; RestType rest_type; ////////////////////Rest System///////////////////// - uint32 m_resetTalentsCost; - time_t m_resetTalentsTime; - uint32 m_usedTalentCount; - uint32 m_questRewardTalentCount; // Social PlayerSocial *m_social; @@ -2839,7 +2917,7 @@ class Player : public Unit, public GridObject<Player> uint32 m_temporaryUnsummonedPetNumber; uint32 m_oldpetspell; - AchievementMgr m_achievementMgr; + AchievementMgr<Player> m_achievementMgr; ReputationMgr m_reputationMgr; SpellCooldowns m_spellCooldowns; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 52d5c9114ff..aa5c33d8c67 100755 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -173,7 +173,7 @@ void MapManager::LoadTransportNPCs() Transport::Transport(uint32 period, uint32 script) : GameObject(), m_pathTime(0), m_timer(0), currenttguid(0), m_period(period), ScriptId(script), m_nextNodeTime(0) { - m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION); + m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION); } Transport::~Transport() @@ -584,7 +584,7 @@ void Transport::UpdateForMap(Map const* targetMap) { if (this != itr->getSource()->GetTransport()) { - UpdateData transData; + UpdateData transData(GetMapId()); BuildCreateUpdateBlockForPlayer(&transData, itr->getSource()); WorldPacket packet; transData.BuildPacket(&packet); @@ -594,7 +594,7 @@ void Transport::UpdateForMap(Map const* targetMap) } else { - UpdateData transData; + UpdateData transData(targetMap->GetId()); BuildOutOfRangeUpdateBlock(&transData); WorldPacket out_packet; transData.BuildPacket(&out_packet); @@ -642,8 +642,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, } creature->SetTransport(this); - creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); - creature->m_movementInfo.guid = GetGUID(); + creature->m_movementInfo.t_guid = GetGUID(); creature->m_movementInfo.t_pos.Relocate(x, y, z, o); if (anim) diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 5cec0cf4375..4bc33dd10f1 100755 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -273,12 +273,6 @@ void Player::UpdateMaxPower(Powers power) SetMaxPower(power, uint32(value)); } -void Player::ApplyFeralAPBonus(int32 amount, bool apply) -{ - _ModifyUInt32(apply, m_baseFeralAP, amount); - UpdateAttackPowerAndDamage(); -} - void Player::UpdateAttackPowerAndDamage(bool ranged) { float val2 = 0.0f; @@ -287,14 +281,10 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; - uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; - index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; - index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; switch (getClass()) { @@ -345,51 +335,15 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) break; case CLASS_DRUID: { - // Check if Predatory Strikes is skilled - float mLevelMult = 0.0f; - float weapon_bonus = 0.0f; - if (IsInFeralForm()) - { - Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_DUMMY); - for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) - { - AuraEffect* aurEff = *itr; - if (aurEff->GetSpellInfo()->SpellIconID == 1563) - { - switch (aurEff->GetEffIndex()) - { - case 0: // Predatory Strikes (effect 0) - mLevelMult = CalculatePctN(1.0f, aurEff->GetAmount()); - break; - case 1: // Predatory Strikes (effect 1) - if (Item* mainHand = m_items[EQUIPMENT_SLOT_MAINHAND]) - { - // also gains % attack power from equipped weapon - ItemTemplate const* proto = mainHand->GetTemplate(); - if (!proto) - continue; - - weapon_bonus = CalculatePctN(float(proto->getFeralBonus()), aurEff->GetAmount()); - } - break; - default: - break; - } - } - } - } - switch (GetShapeshiftForm()) { case FORM_CAT: - val2 = getLevel() * (mLevelMult + 2.0f) + GetStat(STAT_STRENGTH) * 2.0f + GetStat(STAT_AGILITY) - 20.0f + weapon_bonus + m_baseFeralAP; + val2 = GetStat(STAT_STRENGTH) * 2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: - val2 = getLevel() * (mLevelMult + 3.0f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + weapon_bonus + m_baseFeralAP; - break; case FORM_MOONKIN: - val2 = getLevel() * (mLevelMult + 1.5f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + m_baseFeralAP; + val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f; @@ -436,11 +390,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } - float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; - SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field - SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field - SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet* pet = GetPet(); //update pet's AP //automatically update weapon damage after attack power modification @@ -517,11 +467,13 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo weapon_mindamage = BASE_MINDAMAGE; weapon_maxdamage = BASE_MAXDAMAGE; } + /* + TODO: Is this still needed after ammo has been removed? else if (attType == RANGED_ATTACK) //add ammo DPS to ranged damage { - weapon_mindamage += GetAmmoDPS() * att_speed; - weapon_maxdamage += GetAmmoDPS() * att_speed; - } + weapon_mindamage += ammo * att_speed; + weapon_maxdamage += ammo * att_speed; + }*/ min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; @@ -848,9 +800,7 @@ void Player::UpdateManaRegen() // Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura AuraEffectList const& regenAura = GetAuraEffectsByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT); for (AuraEffectList::const_iterator i = regenAura.begin(); i != regenAura.end(); ++i) - { power_regen_mp5 += GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 500.0f; - } // Set regen rate in cast state apply only on spirit based regen int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); @@ -968,22 +918,18 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; - uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS; uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; - index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS; index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); - float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field - SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field //automatically update weapon damage after attack power modification @@ -1117,18 +1063,6 @@ bool Guardian::UpdateStats(Stats stat) else { mod = 0.45f; - if (isPet()) - { - PetSpellMap::const_iterator itr = (ToPet()->m_spells.find(62758)); // Wild Hunt rank 1 - if (itr == ToPet()->m_spells.end()) - itr = ToPet()->m_spells.find(62762); // Wild Hunt rank 2 - - if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value - AddPctN(mod, spellInfo->Effects[EFFECT_0].CalcValue()); - } - } ownersBonus = float(owner->GetStat(stat)) * mod; value += ownersBonus; } @@ -1287,19 +1221,6 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged) if (isHunterPet()) //hunter pets benefit from owner's attack power { float mod = 1.0f; //Hunter contribution modifier - if (isPet()) - { - PetSpellMap::const_iterator itr = ToPet()->m_spells.find(62758); //Wild Hunt rank 1 - if (itr == ToPet()->m_spells.end()) - itr = ToPet()->m_spells.find(62762); //Wild Hunt rank 2 - - if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt - { - SpellInfo const* sProto = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value - mod += CalculatePctN(1.0f, sProto->Effects[1].CalcValue()); - } - } - bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod; SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod)); } @@ -1333,13 +1254,10 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged) //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); - float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower); - //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field - SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); @@ -1386,27 +1304,6 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType) float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; - // Pet's base damage changes depending on happiness - if (isHunterPet() && attType == BASE_ATTACK) - { - switch (ToPet()->GetHappinessState()) - { - case HAPPY: - // 125% of normal damage - mindamage = mindamage * 1.25f; - maxdamage = maxdamage * 1.25f; - break; - case CONTENT: - // 100% of normal damage, nothing to modify - break; - case UNHAPPY: - // 75% of normal damage - mindamage = mindamage * 0.75f; - maxdamage = maxdamage * 0.75f; - break; - } - } - Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACKSPEED); for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d65d717c236..e57c5a99acd 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -165,7 +165,7 @@ m_HostileRefManager(this) m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; - m_updateFlag = (UPDATEFLAG_LIVING | UPDATEFLAG_STATIONARY_POSITION); + m_updateFlag = UPDATEFLAG_LIVING; m_attackTimer[BASE_ATTACK] = 0; m_attackTimer[OFF_ATTACK] = 0; @@ -397,7 +397,7 @@ void Unit::UpdateSplineMovement(uint32 t_diff) m_movesplineTimer.Reset(POSITION_UPDATE_DELAY); Movement::Location loc = movespline->ComputePosition(); - if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (GetTransGUID()) { Position& pos = m_movementInfo.t_pos; pos.m_positionX = loc.x; @@ -421,7 +421,7 @@ void Unit::UpdateSplineMovement(uint32 t_diff) void Unit::DisableSpline() { - m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD)); + m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD); movespline->_Interrupt(); } @@ -694,7 +694,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam // call before auras are removed if (Player* killer = GetCharmerOrOwnerPlayerOrPlayerItself()) - killer->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim); + killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim); } Kill(victim, durabilityLoss); @@ -1373,7 +1373,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) victim->DealDamageMods(this, damage, NULL); // TODO: Move this to a packet handler - WorldPacket data(SMSG_SPELLDAMAGESHIELD, (8+8+4+4+4+4)); + WorldPacket data(SMSG_SPELLDAMAGESHIELD, 8 + 8 + 4 + 4 + 4 + 4 + 4); data << uint64(victim->GetGUID()); data << uint64(GetGUID()); data << uint32(i_spellProto->Id); @@ -1381,6 +1381,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) int32 overkill = int32(damage) - int32(GetHealth()); data << uint32(overkill > 0 ? overkill : 0); // Overkill data << uint32(i_spellProto->SchoolMask); + data << uint32(0); // Unknown 4.x victim->SendMessageToSet(&data, true); victim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true); @@ -1424,6 +1425,14 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo uint32 newdamage = 0; float armor = float(victim->GetArmor()); + // bypass enemy armor by SPELL_AURA_BYPASS_ARMOR_FOR_CASTER + int32 armorBypassPct = 0; + AuraEffectList const & reductionAuras = victim->GetAuraEffectsByType(SPELL_AURA_BYPASS_ARMOR_FOR_CASTER); + for (AuraEffectList::const_iterator i = reductionAuras.begin(); i != reductionAuras.end(); ++i) + if ((*i)->GetCasterGUID() == GetGUID()) + armorBypassPct += (*i)->GetAmount(); + armor = CalculatePctN(armor, 100 - std::min(armorBypassPct, 100)); + // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL); @@ -1435,7 +1444,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j) { if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL - && (*j)->IsAffectedOnSpell(spellInfo)) + && (*j)->IsAffectingSpell(spellInfo)) armor = floor(AddPctN(armor, -(*j)->GetAmount())); } @@ -1455,7 +1464,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo { if ((*itr)->GetSpellInfo()->EquippedItemClass == -1) { - if (!spellInfo || (*itr)->IsAffectedOnSpell(spellInfo) || (*itr)->GetMiscValue() & spellInfo->GetSchoolMask()) + if (!spellInfo || (*itr)->IsAffectingSpell(spellInfo) || (*itr)->GetMiscValue() & spellInfo->GetSchoolMask()) bonusPct += (*itr)->GetAmount(); else if (!(*itr)->GetMiscValue() && !(*itr)->HasSpellClassMask()) bonusPct += (*itr)->GetAmount(); @@ -1559,7 +1568,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe AuraEffectList const& ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST); for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j) - if (((*j)->GetMiscValue() & schoolMask) && (*j)->IsAffectedOnSpell(spellInfo)) + if (((*j)->GetMiscValue() & schoolMask) && (*j)->IsAffectingSpell(spellInfo)) AddPctN(damageResisted, -(*j)->GetAmount()); AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); @@ -1588,7 +1597,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe if (!((*itr)->GetMiscValue() & schoolMask)) continue; - if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo)) + if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectingSpell(spellInfo)) auraAbsorbMod = float((*itr)->GetAmount()); } RoundToInterval(auraAbsorbMod, 0.0f, 100.0f); @@ -2321,7 +2330,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spell) AuraEffectList const& ignore = GetAuraEffectsByType(SPELL_AURA_IGNORE_COMBAT_RESULT); for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(spell)) + if (!(*i)->IsAffectingSpell(spell)) continue; switch ((*i)->GetMiscValue()) { @@ -2638,7 +2647,7 @@ float Unit::GetUnitBlockChance() const if (player->CanBlock()) { Item* tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - if (tmpitem && !tmpitem->IsBroken() && tmpitem->GetTemplate()->Block) + if (tmpitem && !tmpitem->IsBroken()) return GetFloatValue(PLAYER_BLOCK_PERCENTAGE); } // is player but has no block ability or no not broken shield equipped @@ -4169,7 +4178,7 @@ bool Unit::HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const* affecte { AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) - if ((*i)->IsAffectedOnSpell(affectedSpell)) + if ((*i)->IsAffectingSpell(affectedSpell)) return true; return false; } @@ -4229,7 +4238,7 @@ AuraEffect* Unit::IsScriptOverriden(SpellInfo const* spell, int32 script) const for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i) { if ((*i)->GetMiscValue() == script) - if ((*i)->IsAffectedOnSpell(spell)) + if ((*i)->IsAffectingSpell(spell)) return (*i); } return NULL; @@ -4477,7 +4486,7 @@ int32 Unit::GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const* AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { - if ((*i)->IsAffectedOnSpell(affectedSpell)) + if ((*i)->IsAffectingSpell(affectedSpell)) if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) modifier += (*i)->GetAmount(); } @@ -4496,7 +4505,7 @@ float Unit::GetTotalAuraMultiplierByAffectMask(AuraType auratype, SpellInfo cons AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { - if ((*i)->IsAffectedOnSpell(affectedSpell)) + if ((*i)->IsAffectingSpell(affectedSpell)) if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) AddPctN(multiplier, (*i)->GetAmount()); } @@ -4514,7 +4523,7 @@ int32 Unit::GetMaxPositiveAuraModifierByAffectMask(AuraType auratype, SpellInfo AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { - if ((*i)->IsAffectedOnSpell(affectedSpell) && (*i)->GetAmount() > modifier) + if ((*i)->IsAffectingSpell(affectedSpell) && (*i)->GetAmount() > modifier) modifier = (*i)->GetAmount(); } @@ -4528,7 +4537,7 @@ int32 Unit::GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellInfo AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) { - if ((*i)->IsAffectedOnSpell(affectedSpell) && (*i)->GetAmount() < modifier) + if ((*i)->IsAffectingSpell(affectedSpell) && (*i)->GetAmount() < modifier) modifier = (*i)->GetAmount(); } @@ -8664,7 +8673,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg ItemTemplate const* weapon = item->GetTemplate(); - float weaponDPS = weapon->getDPS(); + float weaponDPS = weapon->DPS; float attackPower = GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f; float weaponSpeed = float(weapon->Delay) / 1000.0f; basepoints0 = int32((weaponDPS + attackPower) * weaponSpeed); @@ -9190,10 +9199,6 @@ void Unit::setPowerType(Powers new_powertype) case POWER_ENERGY: SetMaxPower(POWER_ENERGY, GetCreatePowers(POWER_ENERGY)); break; - case POWER_HAPPINESS: - SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); - SetPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); - break; } } @@ -9642,7 +9647,7 @@ bool Unit::HasAuraState(AuraStateType flag, SpellInfo const* spellProto, Unit co { AuraEffectList const& stateAuras = Caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE); for (AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j) - if ((*j)->IsAffectedOnSpell(spellProto)) + if ((*j)->IsAffectingSpell(spellProto)) return true; } // Check per caster aura state @@ -9675,7 +9680,7 @@ void Unit::SetOwnerGUID(uint64 owner) SetFieldNotifyFlag(UF_FLAG_OWNER); - UpdateData udata; + UpdateData udata(GetMapId()); WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata, player); udata.BuildPacket(&packet); @@ -10042,15 +10047,15 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth) // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria) if (gain) - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth); } if (Player* player = victim->ToPlayer()) { - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED, gain); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth); } return gain; @@ -10343,7 +10348,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(spellProto)) + if (!(*i)->IsAffectingSpell(spellProto)) continue; switch ((*i)->GetMiscValue()) @@ -10743,7 +10748,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui // From caster spells AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) + if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectingSpell(spellProto)) AddPctN(TakenTotalMod, (*i)->GetAmount()); // Mod damage from spell mechanic @@ -10905,7 +10910,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas AuraEffectList const& mOverrideClassScript = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) { - if (!((*i)->IsAffectedOnSpell(spellProto))) + if (!((*i)->IsAffectingSpell(spellProto))) continue; int32 modChance = 0; switch ((*i)->GetMiscValue()) @@ -11041,6 +11046,11 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance); + AuraEffectList const& critAuras = victim->GetAuraEffectsByType(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER); + for (AuraEffectList::const_iterator i = critAuras.begin(); i != critAuras.end(); ++i) + if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectingSpell(spellProto)) + crit_chance += (*i)->GetAmount(); + crit_chance = crit_chance > 0.0f ? crit_chance : 0.0f; if (roll_chance_f(crit_chance)) return true; @@ -11138,7 +11148,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(spellProto)) + if (!(*i)->IsAffectingSpell(spellProto)) continue; switch ((*i)->GetMiscValue()) { @@ -11358,7 +11368,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u AuraEffectList const& mHealingGet= GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED); for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i) - if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto)) + if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectingSpell(spellProto)) AddPctN(TakenTotalMod, (*i)->GetAmount()); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) @@ -11662,7 +11672,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(spellProto)) + if (!(*i)->IsAffectingSpell(spellProto)) continue; switch ((*i)->GetMiscValue()) @@ -11783,7 +11793,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT // From caster spells AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) - if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectedOnSpell(spellProto)) + if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectingSpell(spellProto)) AddPctN(TakenTotalMod, (*i)->GetAmount()); // Mod damage from spell mechanic @@ -11986,11 +11996,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) player->UnsummonPetTemporaryIfAny(); } - WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); - data.append(GetPackGUID()); - data << uint32(sWorld->GetGameTime()); // Packet counter - data << player->GetCollisionHeight(true); - player->GetSession()->SendPacket(&data); + player->SendMovementSetCollisionHeight(player->GetCollisionHeight(true)); } RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT); @@ -12005,13 +12011,7 @@ void Unit::Dismount() RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); if (Player* thisPlayer = ToPlayer()) - { - WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4); - data.append(GetPackGUID()); - data << uint32(sWorld->GetGameTime()); // Packet counter - data << thisPlayer->GetCollisionHeight(false); - thisPlayer->GetSession()->SendPacket(&data); - } + thisPlayer->SendMovementSetCollisionHeight(thisPlayer->GetCollisionHeight(false)); WorldPacket data(SMSG_DISMOUNT, 8); data.appendPackGUID(GetGUID()); @@ -12046,6 +12046,64 @@ void Unit::Dismount() } } +MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const +{ + if (!mountType) + return NULL; + + MountTypeEntry const* mountTypeEntry = sMountTypeStore.LookupEntry(mountType); + if (!mountTypeEntry) + return NULL; + + uint32 zoneId, areaId; + GetZoneAndAreaId(zoneId, areaId); + uint32 ridingSkill = 5000; + if (GetTypeId() == TYPEID_PLAYER) + ridingSkill = ToPlayer()->GetSkillValue(SKILL_RIDING); + + for (uint32 i = MAX_MOUNT_CAPABILITIES; i > 0; --i) + { + MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(mountTypeEntry->MountCapability[i - 1]); + if (!mountCapability) + continue; + + if (ridingSkill < mountCapability->RequiredRidingSkill) + continue; + + if (HasExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING)) + { + if (!(mountCapability->Flags & MOUNT_FLAG_CAN_PITCH)) + continue; + } + else if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING)) + { + if (!(mountCapability->Flags & MOUNT_FLAG_CAN_SWIM)) + continue; + } + else if (!(mountCapability->Flags & 0x1)) // unknown flags, checked in 4.2.2 14545 client + { + if (!(mountCapability->Flags & 0x2)) + continue; + } + + if (mountCapability->RequiredMap != -1 && int32(GetMapId()) != mountCapability->RequiredMap) + continue; + + if (mountCapability->RequiredArea && (mountCapability->RequiredArea != zoneId && mountCapability->RequiredArea != areaId)) + continue; + + if (mountCapability->RequiredAura && !HasAura(mountCapability->RequiredAura)) + continue; + + if (mountCapability->RequiredSpell && (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->HasSpell(mountCapability->RequiredSpell))) + continue; + + return mountCapability; + } + + return NULL; +} + void Unit::SetInCombatWith(Unit* enemy) { Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf(); @@ -12684,44 +12742,199 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) propagateSpeedChange(); WorldPacket data; + uint64 guid = GetGUID(); + uint8* bytes = (uint8*)&guid; if (!forced) { switch (mtype) { case MOVE_WALK: - data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); break; case MOVE_RUN: - data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_SPEED, 1 + 8 + 4); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[2]); + data.FlushBits(); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[4]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[1]); break; case MOVE_RUN_BACK: - data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, 1 + 8 + 4); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[4]); + data.FlushBits(); + data.WriteByteSeq(bytes[1]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[7]); break; case MOVE_SWIM: - data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, 1 + 8 + 4); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[1]); + data.FlushBits(); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[4]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[3]); break; case MOVE_SWIM_BACK: - data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, 1 + 8 + 4); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[2]); + data.FlushBits(); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[6]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[2]); break; case MOVE_TURN_RATE: - data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_TURN_RATE, 1 + 8 + 4); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[0]); + data.FlushBits(); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[0]); break; case MOVE_FLIGHT: - data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, 1 + 8 + 4); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[2]); + data.FlushBits(); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[6]); + data << float(GetSpeed(mtype)); break; case MOVE_FLIGHT_BACK: - data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[7]); + data.FlushBits(); + data.WriteByteSeq(bytes[5]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[4]); break; case MOVE_PITCH_RATE: - data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4); + data.Initialize(SMSG_SPLINE_MOVE_SET_PITCH_RATE, 1 + 8 + 4); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[2]); + data.FlushBits(); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[2]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[4]); break; default: sLog->outError(LOG_FILTER_UNITS, "Unit::SetSpeed: Unsupported move type (%d), data not sent to client.", mtype); return; } - BuildMovementPacket(&data); - data << float(GetSpeed(mtype)); + /*data.append(GetPackGUID()); + data << uint32(0); // movement flags + data << uint16(0); // unk flags + data << uint32(getMSTime()); + data << float(GetPositionX()); + data << float(GetPositionY()); + data << float(GetPositionZ()); + data << float(GetOrientation()); + data << uint32(0); // fall time + data << float(GetSpeed(mtype));*/ + SendMessageToSet(&data, true); } else @@ -12740,41 +12953,212 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) switch (mtype) { case MOVE_WALK: - data.Initialize(SMSG_FORCE_WALK_SPEED_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_WALK_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[3]); + + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[1]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[5]); + data << uint32(0); + data.WriteByteSeq(bytes[0]); break; case MOVE_RUN: - data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE, 17); + data.Initialize(SMSG_MOVE_SET_RUN_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[6]); + + data.WriteByteSeq(bytes[1]); + + data << float(GetSpeed(mtype)); + + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[5]); + data << uint32(0); break; case MOVE_RUN_BACK: - data.Initialize(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_RUN_BACK_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[5]); + + data << float(GetSpeed(mtype)); + + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[1]); + data << uint32(0); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[0]); break; case MOVE_SWIM: - data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_SWIM_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[0]); + + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[0]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[2]); + data << uint32(0); break; case MOVE_SWIM_BACK: - data.Initialize(SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_SWIM_BACK_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[0]); + + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[0]); + data << uint32(0); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[2]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[5]); break; case MOVE_TURN_RATE: - data.Initialize(SMSG_FORCE_TURN_RATE_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_TURN_RATE, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[4]); + + data << float(GetSpeed(mtype)); + + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[5]); + data << uint32(0); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[7]); break; case MOVE_FLIGHT: - data.Initialize(SMSG_FORCE_FLIGHT_SPEED_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_FLIGHT_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[3]); + + data << float(GetSpeed(mtype)); + + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[0]); + data.WriteByteSeq(bytes[2]); + data << uint32(0); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[4]); break; case MOVE_FLIGHT_BACK: - data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[7]); + + data.WriteByteSeq(bytes[0]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[7]); + data << uint32(0); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[5]); break; case MOVE_PITCH_RATE: - data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16); + data.Initialize(SMSG_MOVE_SET_PITCH_RATE, 1 + 8 + 4 + 4 ); + data.WriteBit(bytes[7]); + data.WriteBit(bytes[5]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[1]); + + data.WriteByteSeq(bytes[0]); + data << uint32(0); + data.WriteByteSeq(bytes[3]); + data << float(GetSpeed(mtype)); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[6]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[4]); break; default: sLog->outError(LOG_FILTER_UNITS, "Unit::SetSpeed: Unsupported move type (%d), data not sent to client.", mtype); return; } - data.append(GetPackGUID()); - data << (uint32)0; // moveEvent, NUM_PMOVE_EVTS = 0x39 - if (mtype == MOVE_RUN) - data << uint8(0); // new 2.1.0 - data << float(GetSpeed(mtype)); SendMessageToSet(&data, true); } } @@ -13405,7 +13789,7 @@ uint32 Unit::GetCreatureType() const if (GetTypeId() == TYPEID_PLAYER) { ShapeshiftForm form = GetShapeshiftForm(); - SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (ssEntry && ssEntry->creatureType > 0) return ssEntry->creatureType; else @@ -13461,7 +13845,6 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f case UNIT_MOD_RAGE: case UNIT_MOD_FOCUS: case UNIT_MOD_ENERGY: - case UNIT_MOD_HAPPINESS: case UNIT_MOD_RUNE: case UNIT_MOD_RUNIC_POWER: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break; @@ -13581,7 +13964,6 @@ Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const case UNIT_MOD_RAGE: return POWER_RAGE; case UNIT_MOD_FOCUS: return POWER_FOCUS; case UNIT_MOD_ENERGY: return POWER_ENERGY; - case UNIT_MOD_HAPPINESS: return POWER_HAPPINESS; case UNIT_MOD_RUNE: return POWER_RUNE; case UNIT_MOD_RUNIC_POWER: return POWER_RUNIC_POWER; default: @@ -13593,14 +13975,14 @@ float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const { if (attType == RANGED_ATTACK) { - int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS); + int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER); if (ap < 0) return 0.0f; return ap * (1.0f + GetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER)); } else { - int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS); + int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER); if (ap < 0) return 0.0f; return ap * (1.0f + GetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER)); @@ -13684,21 +14066,67 @@ void Unit::SetMaxHealth(uint32 val) SetHealth(val); } -void Unit::SetPower(Powers power, uint32 val) +uint32 Unit::GetPowerIndexByClass(uint32 powerId, uint32 classId) const +{ + ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(classId); + + ASSERT(classEntry && "Class not found"); + + uint32 index = 0; + for (uint32 i = 0; i <= sChrPowerTypesStore.GetNumRows(); ++i) + { + ChrPowerTypesEntry const* powerEntry = sChrPowerTypesStore.LookupEntry(i); + if (!powerEntry) + continue; + + if (powerEntry->classId != classId) + continue; + + if (powerEntry->power == powerId) + return index; + + ++index; + } + + // return invalid value - this class doesn't use this power + return MAX_POWERS; +}; + +int32 Unit::GetPower(Powers power) const +{ + uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + if (powerIndex == MAX_POWERS) + return 0; + + return GetUInt32Value(UNIT_FIELD_POWER1 + powerIndex); +} + +uint32 Unit::GetMaxPower(Powers power) const { - if (GetPower(power) == val) + uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + if (powerIndex == MAX_POWERS) + return 0; + + return GetUInt32Value(UNIT_FIELD_MAXPOWER1 + powerIndex); +} + +void Unit::SetPower(Powers power, int32 val) +{ + uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + if (powerIndex == MAX_POWERS) return; - uint32 maxPower = GetMaxPower(power); + int32 maxPower = int32(GetMaxPower(power)); if (maxPower < val) val = maxPower; - SetStatInt32Value(UNIT_FIELD_POWER1 + power, val); + SetStatInt32Value(UNIT_FIELD_POWER1 + powerIndex, val); - WorldPacket data(SMSG_POWER_UPDATE); + WorldPacket data(SMSG_POWER_UPDATE, 8 + 4 + 1 + 4); data.append(GetPackGUID()); - data << uint8(power); - data << uint32(val); + data << uint32(1);//unk + data << uint8(powerIndex); + data << int32(val); SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? true : false); // group update @@ -13715,17 +14143,17 @@ void Unit::SetPower(Powers power, uint32 val) if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); } - - // Update the pet's character sheet with happiness damage bonus - if (pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS) - pet->UpdateDamagePhysical(BASE_ATTACK); } } -void Unit::SetMaxPower(Powers power, uint32 val) +void Unit::SetMaxPower(Powers power, int32 val) { - uint32 cur_power = GetPower(power); - SetStatInt32Value(UNIT_FIELD_MAXPOWER1 + power, val); + uint32 powerIndex = GetPowerIndexByClass(power, getClass()); + if (powerIndex == MAX_POWERS) + return; + + int32 cur_power = GetPower(power); + SetStatInt32Value(UNIT_FIELD_MAXPOWER1 + powerIndex, val); // group update if (GetTypeId() == TYPEID_PLAYER) @@ -13747,19 +14175,32 @@ void Unit::SetMaxPower(Powers power, uint32 val) SetPower(power, val); } -uint32 Unit::GetCreatePowers(Powers power) const +int32 Unit::GetCreatePowers(Powers power) const { - // Only hunter pets have POWER_FOCUS and POWER_HAPPINESS switch (power) { - case POWER_MANA: return GetCreateMana(); - case POWER_RAGE: return 1000; - case POWER_FOCUS: return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100); - case POWER_ENERGY: return 100; - case POWER_HAPPINESS: return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 1050000); - case POWER_RUNIC_POWER: return 1000; - case POWER_RUNE: return 0; - case POWER_HEALTH: return 0; + case POWER_MANA: + return GetCreateMana(); + case POWER_RAGE: + return 1000; + case POWER_FOCUS: + if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_HUNTER) + return 100; + return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100); + case POWER_ENERGY: + return 100; + case POWER_RUNIC_POWER: + return 1000; + case POWER_RUNE: + return 0; + case POWER_SOULSHARD: + return 3; + case POWER_ECLIPSE: + return 0; + case POWER_HOLY_POWER: + return 0; + case POWER_HEALTH: + return 0; default: break; } @@ -15547,7 +15988,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) // update get killing blow achievements, must be done before setDeathState to be able to require auras on target // and before Spirit of Redemption as it also removes auras if (player) - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim); // if talent known but not triggered (check priest class for speedup check) bool spiritOfRedemption = false; @@ -15698,9 +16139,9 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (victim->GetTypeId() == TYPEID_PLAYER) { if (GetTypeId() == TYPEID_UNIT) - victim->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); + victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); else if (GetTypeId() == TYPEID_PLAYER && victim != this) - victim->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam()); + victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1, ToPlayer()->GetTeam()); } // Hook for OnPVPKill Event @@ -15811,7 +16252,7 @@ void Unit::SetStunned(bool apply) else SetStandState(UNIT_STAND_STATE_STAND); - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8); + WorldPacket data(SMSG_MOVE_ROOT, 8); data.append(GetPackGUID()); data << uint32(0); SendMessageToSet(&data, true); @@ -15830,7 +16271,7 @@ void Unit::SetStunned(bool apply) if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect { - WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4); + WorldPacket data(SMSG_MOVE_UNROOT, 8+4); data.append(GetPackGUID()); data << uint32(0); SendMessageToSet(&data, true); @@ -15855,17 +16296,34 @@ void Unit::SetRooted(bool apply) if (GetTypeId() == TYPEID_PLAYER) { - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); + WorldPacket data(SMSG_MOVE_ROOT, 10); data.append(GetPackGUID()); data << m_rootTimes; SendMessageToSet(&data, true); } else { + ObjectGuid guid = GetGUID(); WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8); - data.append(GetPackGUID()); + data.WriteBit(guid[5]); + data.WriteBit(guid[4]); + data.WriteBit(guid[6]); + data.WriteBit(guid[1]); + data.WriteBit(guid[3]); + data.WriteBit(guid[7]); + data.WriteBit(guid[2]); + data.WriteBit(guid[0]); + data.FlushBits(); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[4]); SendMessageToSet(&data, true); - ToCreature()->StopMoving(); + StopMoving(); } } else @@ -15874,15 +16332,32 @@ void Unit::SetRooted(bool apply) { if (GetTypeId() == TYPEID_PLAYER) { - WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10); + WorldPacket data(SMSG_MOVE_UNROOT, 10); data.append(GetPackGUID()); data << ++m_rootTimes; SendMessageToSet(&data, true); } else { + ObjectGuid guid = GetGUID(); WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); - data.append(GetPackGUID()); + data.WriteBit(guid[0]); + data.WriteBit(guid[1]); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[3]); + data.WriteBit(guid[2]); + data.WriteBit(guid[7]); + data.WriteBit(guid[4]); + data.FlushBits(); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[5]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[4]); SendMessageToSet(&data, true); } @@ -16394,9 +16869,29 @@ void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack) void Unit::SendPlaySpellVisual(uint32 id) { - WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 8 + 4); - data << uint64(GetGUID()); + ObjectGuid guid = GetGUID(); + + WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 4 * 3 + 8); + data << uint32(0); data << uint32(id); // SpellVisualKit.dbc index + data << uint32(0); + data.WriteBit(guid[4]); + data.WriteBit(guid[7]); + data.WriteBit(guid[5]); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[2]); + data.WriteBit(guid[0]); + data.WriteBit(guid[6]); + data.FlushBits(); + data.WriteByteSeq(guid[0]); + data.WriteByteSeq(guid[4]); + data.WriteByteSeq(guid[1]); + data.WriteByteSeq(guid[6]); + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[5]); SendMessageToSet(&data, false); } @@ -16603,13 +17098,33 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) float vcos, vsin; GetSinCos(x, y, vsin, vcos); - WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); - data.append(GetPackGUID()); - data << uint32(0); // counter - data << float(vcos); // x direction - data << float(vsin); // y direction - data << float(speedXY); // Horizontal speed - data << float(-speedZ); // Z Movement speed (vertical) + WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1+8+4+4+4+4+4)); + uint64 guid = GetGUID(); + uint8* bytes = (uint8*)&guid; + + data.WriteBit(bytes[5]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[7]); + + data.WriteByteSeq(bytes[0]); + data << float(speedXY); + data << uint32(0); + data << float(-speedZ); + data.WriteByteSeq(bytes[6]); + data << float(vcos); + data << float(vsin); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[5]); + data.WriteByteSeq(bytes[5]); player->GetSession()->SendPacket(&data); } @@ -16808,7 +17323,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) } uint32 modelid = 0; - SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* formEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (formEntry && formEntry->modelID_A) { // Take the alliance modelid as default @@ -16923,13 +17438,32 @@ void Unit::JumpTo(float speedXY, float speedZ, bool forward) float vcos = cos(angle+GetOrientation()); float vsin = sin(angle+GetOrientation()); - WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); - data.append(GetPackGUID()); - data << uint32(0); // Sequence - data << float(vcos); // x direction - data << float(vsin); // y direction - data << float(speedXY); // Horizontal speed - data << float(-speedZ); // Z Movement speed (vertical) + WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1+8+4+4+4+4+4)); + uint64 guid = GetGUID(); + uint8* bytes = (uint8*)&guid; + + data.WriteBit(bytes[5]); + data.WriteBit(bytes[2]); + data.WriteBit(bytes[6]); + data.WriteBit(bytes[3]); + data.WriteBit(bytes[1]); + data.WriteBit(bytes[4]); + data.WriteBit(bytes[0]); + data.WriteBit(bytes[7]); + + data.WriteByteSeq(bytes[0]); + data << float(speedXY); + data << uint32(0); + data << float(-speedZ); + data.WriteByteSeq(bytes[6]); + data << float(vcos); + data << float(vsin); + data.WriteByteSeq(bytes[3]); + data.WriteByteSeq(bytes[1]); + data.WriteByteSeq(bytes[2]); + data.WriteByteSeq(bytes[4]); + data.WriteByteSeq(bytes[7]); + data.WriteByteSeq(bytes[5]); ToPlayer()->GetSession()->SendPacket(&data); } @@ -17181,45 +17715,79 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const *data << GetPositionZMinusOffset(); *data << GetOrientation(); - // 0x00000200 - if (GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT) + bool onTransport = m_movementInfo.t_guid != 0; + bool hasInterpolatedMovement = m_movementInfo.flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT; + bool time3 = false; + bool swimming = ((GetUnitMovementFlags() & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) + || (m_movementInfo.flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)); + bool interPolatedTurning = m_movementInfo.flags2 & MOVEMENTFLAG2_INTERPOLATED_TURNING; + bool jumping = GetUnitMovementFlags() & MOVEMENTFLAG_FALLING; + bool splineElevation = GetUnitMovementFlags() & MOVEMENTFLAG_SPLINE_ELEVATION; + bool splineData = false; + + data->WriteBits(GetUnitMovementFlags(), 30); + data->WriteBits(m_movementInfo.flags2, 12); + data->WriteBit(onTransport); + if (onTransport) + { + data->WriteBit(hasInterpolatedMovement); + data->WriteBit(time3); + } + + data->WriteBit(swimming); + data->WriteBit(interPolatedTurning); + if (interPolatedTurning) + data->WriteBit(jumping); + + data->WriteBit(splineElevation); + data->WriteBit(splineData); + + data->FlushBits(); // reset bit stream + + *data << uint64(GetGUID()); + *data << uint32(getMSTime()); + *data << float(GetPositionX()); + *data << float(GetPositionY()); + *data << float(GetPositionZ()); + *data << float(GetOrientation()); + + if (onTransport) { if (m_vehicle) - data->append(m_vehicle->GetBase()->GetPackGUID()); + *data << uint64(m_vehicle->GetBase()->GetGUID()); else if (GetTransport()) - data->append(GetTransport()->GetPackGUID()); - else - *data << (uint8)0; + *data << uint64(GetTransport()->GetGUID()); + else // probably should never happen + *data << (uint64)0; *data << float (GetTransOffsetX()); *data << float (GetTransOffsetY()); *data << float (GetTransOffsetZ()); *data << float (GetTransOffsetO()); - *data << uint32(GetTransTime()); *data << uint8 (GetTransSeat()); - - if (GetExtraUnitMovementFlags() & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT) - *data << uint32(m_movementInfo.t_time2); + *data << uint32(GetTransTime()); + if (hasInterpolatedMovement) + *data << int32(0); // Transport Time 2 + if (time3) + *data << int32(0); // Transport Time 3 } - // 0x02200000 - if ((GetUnitMovementFlags() & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) - || (m_movementInfo.flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)) + if (swimming) *data << (float)m_movementInfo.pitch; - *data << (uint32)m_movementInfo.fallTime; - - // 0x00001000 - if (GetUnitMovementFlags() & MOVEMENTFLAG_FALLING) + if (interPolatedTurning) { + *data << (uint32)m_movementInfo.fallTime; *data << (float)m_movementInfo.j_zspeed; - *data << (float)m_movementInfo.j_sinAngle; - *data << (float)m_movementInfo.j_cosAngle; - *data << (float)m_movementInfo.j_xyspeed; + if (jumping) + { + *data << (float)m_movementInfo.j_sinAngle; + *data << (float)m_movementInfo.j_cosAngle; + *data << (float)m_movementInfo.j_xyspeed; + } } - // 0x04000000 - if (GetUnitMovementFlags() & MOVEMENTFLAG_SPLINE_ELEVATION) + if (splineElevation) *data << (float)m_movementInfo.splineElevation; } @@ -17299,7 +17867,7 @@ void Unit::SendThreatListUpdate() { uint32 count = getThreatManager().getThreatList().size(); - //sLog->outDebug(LOG_FILTER_UNITS, "WORLD: Send SMSG_THREAT_UPDATE Message"); + sLog->outDebug(LOG_FILTER_UNITS, "WORLD: Send SMSG_THREAT_UPDATE Message"); WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8); data.append(GetPackGUID()); data << uint32(count); @@ -17688,3 +18256,8 @@ void Unit::SendMovementCanFlyChange() BuildMovementPacket(&data); SendMessageToSet(&data, false); } + +bool Unit::IsSplineEnabled() const +{ + return movespline->Initialized(); +} diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 46dbf4829a6..8fee3ed74e0 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -35,6 +35,7 @@ #include "SpellInfo.h" #include "Path.h" #include "WorldPacket.h" +#include "WorldSession.h" #include "Timer.h" #include <list> @@ -417,7 +418,6 @@ enum UnitMods UNIT_MOD_RAGE, UNIT_MOD_FOCUS, UNIT_MOD_ENERGY, - UNIT_MOD_HAPPINESS, UNIT_MOD_RUNE, UNIT_MOD_RUNIC_POWER, UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum. @@ -636,7 +636,7 @@ enum NPCFlags { UNIT_NPC_FLAG_NONE = 0x00000000, UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100% - UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok + UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // 100% UNIT_NPC_FLAG_UNK1 = 0x00000004, UNIT_NPC_FLAG_UNK2 = 0x00000008, UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100% @@ -661,6 +661,9 @@ enum NPCFlags UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set + UNIT_NPC_FLAG_REFORGER = 0x08000000, // reforging + UNIT_NPC_FLAG_TRANSMOGRIFIER = 0x10000000, // transmogrification + UNIT_NPC_FLAG_VAULTKEEPER = 0x20000000, // void storage }; enum MovementFlags @@ -675,28 +678,26 @@ enum MovementFlags MOVEMENTFLAG_PITCH_UP = 0x00000040, MOVEMENTFLAG_PITCH_DOWN = 0x00000080, MOVEMENTFLAG_WALKING = 0x00000100, // Walking - MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures - MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible. - MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING - MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling - MOVEMENTFLAG_FALLING_FAR = 0x00002000, - MOVEMENTFLAG_PENDING_STOP = 0x00004000, - MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000, - MOVEMENTFLAG_PENDING_FORWARD = 0x00010000, - MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000, - MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000, - MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000, - MOVEMENTFLAG_PENDING_ROOT = 0x00100000, - MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also - MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying - MOVEMENTFLAG_DESCENDING = 0x00800000, - MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk - MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity - MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths - MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths - MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water - MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive) - MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump + MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000200, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible. + MOVEMENTFLAG_ROOT = 0x00000400, // Must not be set along with MOVEMENTFLAG_MASK_MOVING + MOVEMENTFLAG_FALLING = 0x00000800, // damage dealt on that type of falling + MOVEMENTFLAG_FALLING_FAR = 0x00001000, + MOVEMENTFLAG_PENDING_STOP = 0x00002000, + MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00004000, + MOVEMENTFLAG_PENDING_FORWARD = 0x00008000, + MOVEMENTFLAG_PENDING_BACKWARD = 0x00010000, + MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00020000, + MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00040000, + MOVEMENTFLAG_PENDING_ROOT = 0x00080000, + MOVEMENTFLAG_SWIMMING = 0x00100000, // appears with fly flag also + MOVEMENTFLAG_ASCENDING = 0x00200000, // press "space" when flying + MOVEMENTFLAG_DESCENDING = 0x00400000, + MOVEMENTFLAG_CAN_FLY = 0x00800000, // Appears when unit can fly AND also walk + MOVEMENTFLAG_FLYING = 0x01000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity + MOVEMENTFLAG_SPLINE_ELEVATION = 0x02000000, // used for flight paths + MOVEMENTFLAG_WATERWALKING = 0x04000000, // prevent unit from falling through water + MOVEMENTFLAG_FALLING_SLOW = 0x08000000, // active rogue safe fall spell (passive) + MOVEMENTFLAG_HOVER = 0x10000000, // hover, cannot jump // TODO: Check if PITCH_UP and PITCH_DOWN really belong here.. MOVEMENTFLAG_MASK_MOVING = @@ -719,20 +720,16 @@ enum MovementFlags2 MOVEMENTFLAG2_NONE = 0x00000000, MOVEMENTFLAG2_NO_STRAFE = 0x00000001, MOVEMENTFLAG2_NO_JUMPING = 0x00000002, - MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks - MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008, - MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010, - MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020, - MOVEMENTFLAG2_UNK7 = 0x00000040, - MOVEMENTFLAG2_UNK8 = 0x00000080, - MOVEMENTFLAG2_UNK9 = 0x00000100, - MOVEMENTFLAG2_UNK10 = 0x00000200, - MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400, - MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800, - MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000, - MOVEMENTFLAG2_UNK14 = 0x00002000, - MOVEMENTFLAG2_UNK15 = 0x00004000, - MOVEMENTFLAG2_UNK16 = 0x00008000, + MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000004, + MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000008, + MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000010, + MOVEMENTFLAG2_UNK7 = 0x00000020, + MOVEMENTFLAG2_UNK8 = 0x00000040, + MOVEMENTFLAG2_UNK9 = 0x00000080, + MOVEMENTFLAG2_UNK10 = 0x00000100, + MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000200, + MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000400, + MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00000800, }; enum UnitTypeMask @@ -1335,14 +1332,16 @@ class Unit : public WorldObject 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); } - void SetPower(Powers power, uint32 val); - void SetMaxPower(Powers power, uint32 val); + int32 GetPower(Powers power) const; + uint32 GetMaxPower(Powers power) const; + void SetPower(Powers power, int32 val); + void SetMaxPower(Powers power, int32 val); // returns the change in power int32 ModifyPower(Powers power, int32 val); int32 ModifyPowerPct(Powers power, float pct, bool apply = true); + uint32 GetPowerIndexByClass(uint32 powerId, uint32 classId) const; + uint32 GetAttackTime(WeaponAttackType att) const { float f_BaseAttackTime = GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att) / m_modAttackSpeedPct[att]; @@ -1405,6 +1404,7 @@ class Unit : public WorldObject uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); } void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0); void Dismount(); + MountCapabilityEntry const* GetMountCapability(uint32 mountType) const; uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } void DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb); @@ -1851,7 +1851,7 @@ class Unit : public WorldObject uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); } void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); } uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); } - uint32 GetCreatePowers(Powers power) const; + int32 GetCreatePowers(Powers power) const; float GetPosStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_POSSTAT0+stat); } float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); } float GetCreateStat(Stats stat) const { return m_createStats[stat]; } @@ -2083,6 +2083,7 @@ class Unit : public WorldObject uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.flags2 & f; } uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.flags2; } void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; } + bool IsSplineEnabled() const; float GetPositionZMinusOffset() const { @@ -2321,11 +2322,13 @@ class Unit : public WorldObject float GetCombatRatingReduction(CombatRating cr) const; uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const; + protected: void SetFeared(bool apply); void SetConfused(bool apply); void SetStunned(bool apply); void SetRooted(bool apply); + private: uint32 m_rootTimes; uint32 m_state; // Even derived shouldn't modify diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 710821f2f24..3d36f6ccda5 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -342,7 +342,6 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING)) unit->AddUnitState(UNIT_STATE_ONVEHICLE); - unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); VehicleSeatEntry const* veSeat = seat->second.SeatInfo; unit->m_movementInfo.t_pos.m_positionX = veSeat->m_attachmentOffsetX; unit->m_movementInfo.t_pos.m_positionY = veSeat->m_attachmentOffsetY; @@ -362,9 +361,9 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) if (_me->IsInWorld()) { - unit->SendClearTarget(); // SMSG_BREAK_TARGET + unit->SendClearTarget(); // SMSG_BREAK_TARGET unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) - // also adds MOVEMENTFLAG_ROOT + // also adds MOVEMENTFLAG_ROOT Movement::MoveSplineInit init(*unit); init.DisableTransportPathTransformations(); init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ); @@ -419,7 +418,6 @@ void Vehicle::RemovePassenger(Unit* unit) if (_me->IsInWorld()) { - unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); unit->m_movementInfo.t_pos.Relocate(0, 0, 0, 0); unit->m_movementInfo.t_time = 0; unit->m_movementInfo.t_seat = 0; diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index df34a61d444..fe7840c9878 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -32,7 +32,29 @@ enum PowerType POWER_HEAT = 101, POWER_OOZE = 121, POWER_BLOOD = 141, - POWER_WRATH = 142 + POWER_WRATH = 142, + POWER_ARCANE_ENERGY = 143, + POWER_LIFE_ENERGY = 144, + POWER_SUN_ENERGY = 145, + POWER_SWING_VELOCITY = 146, + POWER_SHADOWFLAME_ENERGY = 147, + POWER_BLUE_POWER = 148, + POWER_PURPLE_POWER = 149, + POWER_GREEN_POWER = 150, + POWER_ORANGE_POWER = 151, + POWER_ENERGY_2 = 153, + POWER_ARCANEENERGY = 161, + POWER_WIND_POWER_1 = 162, + POWER_WIND_POWER_2 = 163, + POWER_WIND_POWER_3 = 164, + POWER_FUEL = 165, + POWER_SUN_POWER = 166, + POWER_TWILIGHT_ENERGY = 169, + POWER_VENOM = 174, + POWER_ORANGE_POWER_2 = 176, + POWER_CONSUMING_FLAME = 177, + POWER_PYROCLASTIC_FRENZY = 178, + POWER_FLASHFIRE = 179, }; enum VehicleFlags diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index afbae063e5e..0936275e90c 100755 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -1064,14 +1064,14 @@ uint32 GameEventMgr::Update() // return the next e // changed, save to DB the gameevent state, will be updated in next update cycle SaveWorldEventStateToDB(itr); - //sLog->outDebug("GameEvent %u is active", itr->first); + //sLog->outDebug(LOG_FILTER_GENERAL, "GameEvent %u is active", itr->first); // queue for activation if (!IsActiveEvent(itr)) activate.insert(itr); } else { - //sLog->outDebug("GameEvent %u is not active", itr->first); + //sLog->outDebug(LOG_FILTER_GENERAL, "GameEvent %u is not active", itr->first); if (IsActiveEvent(itr)) deactivate.insert(itr); else @@ -1229,7 +1229,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) if (!map->Instanceable() && map->IsGridLoaded(data->posX, data->posY)) { Creature* creature = new Creature; - //sLog->outDebug("Spawning creature %u", *itr); + //sLog->outDebug(LOG_FILTER_GENERAL, "Spawning creature %u", *itr); if (!creature->LoadCreatureFromDB(*itr, map)) delete creature; } @@ -1256,7 +1256,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) if (!map->Instanceable() && map->IsGridLoaded(data->posX, data->posY)) { GameObject* pGameobject = new GameObject; - //sLog->outDebug("Spawning gameobject %u", *itr); + //sLog->outDebug(LOG_FILTER_GENERAL, "Spawning gameobject %u", *itr); //TODO: find out when it is add to map if (!pGameobject->LoadGameObjectFromDB(*itr, map, false)) delete pGameobject; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index fc4386633ff..81fb8ad9646 100755..100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -45,6 +45,8 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "PoolMgr.h" +#include "DB2Structure.h" +#include "DB2Stores.h" ScriptMapMap sQuestEndScripts; ScriptMapMap sQuestStartScripts; @@ -177,7 +179,9 @@ LanguageDesc lang_description[LANGUAGES_COUNT] = { LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI }, { LANG_ZOMBIE, 0, 0 }, { LANG_GNOMISH_BINARY, 0, 0 }, - { LANG_GOBLIN_BINARY, 0, 0 } + { LANG_GOBLIN_BINARY, 0, 0 }, + { LANG_WORGEN, 69270, SKILL_LANG_WORGEN }, + { LANG_GOBLIN, 69269, SKILL_LANG_GOBLIN } }; LanguageDesc const* GetLanguageDescByID(uint32 lang) @@ -229,7 +233,7 @@ bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clicke ObjectMgr::ObjectMgr(): _auctionId(1), _equipmentSetGuid(1), _itemTextId(1), _mailId(1), _hiPetNumber(1), _hiCharGuid(1), _hiCreatureGuid(1), _hiPetGuid(1), _hiVehicleGuid(1), _hiItemGuid(1), - _hiGoGuid(1), _hiDoGuid(1), _hiCorpseGuid(1), _hiMoTransGuid(1) + _hiGoGuid(1), _hiDoGuid(1), _hiCorpseGuid(1), _hiMoTransGuid(1), _voidItemId(1) {} ObjectMgr::~ObjectMgr() @@ -240,10 +244,6 @@ ObjectMgr::~ObjectMgr() for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i) delete[] i->second; - // free only if loaded - for (int class_ = 0; class_ < MAX_CLASSES; ++class_) - delete[] _playerClassInfo[class_].levelInfo; - for (int race = 0; race < MAX_RACES; ++race) for (int class_ = 0; class_ < MAX_CLASSES; ++class_) delete[] _playerInfo[race][class_].levelInfo; @@ -370,19 +370,19 @@ void ObjectMgr::LoadCreatureTemplates() // 0 1 2 3 4 5 6 7 8 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " - // 9 10 11 12 13 14 15 16 17 18 19 20 21 - "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, " - // 22 23 24 25 26 27 28 29 30 31 32 - "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, " - // 33 34 35 36 37 38 39 40 41 42 + // 9 10 11 12 13 14 15 16 17 18 19 20 21 + "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, " + // 22 23 24 25 26 27 28 29 30 31 32 33 + "speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, " + // 34 35 36 37 38 39 40 41 42 43 "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 43 44 45 46 47 48 49 50 51 52 53 - "type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, " - // 54 55 56 57 58 59 60 61 62 63 64 65 66 - "spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 67 68 69 70 71 72 73 74 75 76 77 + // 44 45 46 47 48 49 50 51 52 53 54 + "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, " + // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 + "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " + // 69 70 71 72 73 74 75 76 77 78 79 "InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 78 79 80 81 82 83 + // 80 81 82 83 84 85 86 " questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName " "FROM creature_template;"); @@ -423,65 +423,67 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.minlevel = fields[14].GetUInt8(); creatureTemplate.maxlevel = fields[15].GetUInt8(); creatureTemplate.expansion = uint32(fields[16].GetInt16()); - creatureTemplate.faction_A = uint32(fields[17].GetUInt16()); - creatureTemplate.faction_H = uint32(fields[18].GetUInt16()); - creatureTemplate.npcflag = fields[19].GetUInt32(); - creatureTemplate.speed_walk = fields[20].GetFloat(); - creatureTemplate.speed_run = fields[21].GetFloat(); - creatureTemplate.scale = fields[22].GetFloat(); - creatureTemplate.rank = uint32(fields[23].GetUInt8()); - creatureTemplate.mindmg = fields[24].GetFloat(); - creatureTemplate.maxdmg = fields[25].GetFloat(); - creatureTemplate.dmgschool = uint32(fields[26].GetInt8()); - creatureTemplate.attackpower = fields[27].GetUInt32(); - creatureTemplate.dmg_multiplier = fields[28].GetFloat(); - creatureTemplate.baseattacktime = fields[29].GetUInt32(); - creatureTemplate.rangeattacktime = fields[30].GetUInt32(); - creatureTemplate.unit_class = uint32(fields[31].GetUInt8()); - creatureTemplate.unit_flags = fields[32].GetUInt32(); - creatureTemplate.dynamicflags = fields[33].GetUInt32(); - creatureTemplate.family = uint32(fields[34].GetUInt8()); - creatureTemplate.trainer_type = uint32(fields[35].GetUInt8()); - creatureTemplate.trainer_spell = fields[36].GetUInt32(); - creatureTemplate.trainer_class = uint32(fields[37].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[38].GetUInt8()); - creatureTemplate.minrangedmg = fields[39].GetFloat(); - creatureTemplate.maxrangedmg = fields[40].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[41].GetUInt16()); - creatureTemplate.type = uint32(fields[42].GetUInt8()); - creatureTemplate.type_flags = fields[43].GetUInt32(); - creatureTemplate.lootid = fields[44].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[45].GetUInt32(); - creatureTemplate.SkinLootId = fields[46].GetUInt32(); + creatureTemplate.expansionUnknown = uint32(fields[17].GetUInt16()); + creatureTemplate.faction_A = uint32(fields[18].GetUInt16()); + creatureTemplate.faction_H = uint32(fields[19].GetUInt16()); + creatureTemplate.npcflag = fields[20].GetUInt32(); + creatureTemplate.speed_walk = fields[21].GetFloat(); + creatureTemplate.speed_run = fields[22].GetFloat(); + creatureTemplate.scale = fields[23].GetFloat(); + creatureTemplate.rank = uint32(fields[24].GetUInt8()); + creatureTemplate.mindmg = fields[25].GetFloat(); + creatureTemplate.maxdmg = fields[26].GetFloat(); + creatureTemplate.dmgschool = uint32(fields[27].GetInt8()); + creatureTemplate.attackpower = fields[28].GetUInt32(); + creatureTemplate.dmg_multiplier = fields[29].GetFloat(); + creatureTemplate.baseattacktime = fields[30].GetUInt32(); + creatureTemplate.rangeattacktime = fields[31].GetUInt32(); + creatureTemplate.unit_class = uint32(fields[32].GetUInt8()); + creatureTemplate.unit_flags = fields[33].GetUInt32(); + creatureTemplate.dynamicflags = fields[34].GetUInt32(); + creatureTemplate.family = uint32(fields[35].GetUInt8()); + creatureTemplate.trainer_type = uint32(fields[36].GetUInt8()); + creatureTemplate.trainer_spell = fields[37].GetUInt32(); + creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); + creatureTemplate.minrangedmg = fields[40].GetFloat(); + creatureTemplate.maxrangedmg = fields[41].GetFloat(); + creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); + creatureTemplate.type = uint32(fields[43].GetUInt8()); + creatureTemplate.type_flags = fields[44].GetUInt32(); + creatureTemplate.type_flags2 = fields[45].GetUInt32(); + creatureTemplate.lootid = fields[46].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[47].GetUInt32(); + creatureTemplate.SkinLootId = fields[48].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[47 + i -1].GetInt16(); + creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[53 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[61].GetUInt32(); - creatureTemplate.VehicleId = fields[62].GetUInt32(); - creatureTemplate.mingold = fields[63].GetUInt32(); - creatureTemplate.maxgold = fields[64].GetUInt32(); - creatureTemplate.AIName = fields[65].GetString(); - creatureTemplate.MovementType = uint32(fields[66].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[67].GetUInt8()); - creatureTemplate.HoverHeight = fields[68].GetFloat(); - creatureTemplate.ModHealth = fields[69].GetFloat(); - creatureTemplate.ModMana = fields[70].GetFloat(); - creatureTemplate.ModArmor = fields[71].GetFloat(); - creatureTemplate.RacialLeader = fields[72].GetBool(); + creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[63].GetUInt32(); + creatureTemplate.VehicleId = fields[64].GetUInt32(); + creatureTemplate.mingold = fields[65].GetUInt32(); + creatureTemplate.maxgold = fields[66].GetUInt32(); + creatureTemplate.AIName = fields[67].GetString(); + creatureTemplate.MovementType = uint32(fields[68].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[69].GetUInt8()); + creatureTemplate.HoverHeight = fields[70].GetFloat(); + creatureTemplate.ModHealth = fields[71].GetFloat(); + creatureTemplate.ModMana = fields[72].GetFloat(); + creatureTemplate.ModArmor = fields[73].GetFloat(); + creatureTemplate.RacialLeader = fields[74].GetBool(); for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[73 + i].GetUInt32(); + creatureTemplate.questItems[i] = fields[75 + i].GetUInt32(); - creatureTemplate.movementId = fields[79].GetUInt32(); - creatureTemplate.RegenHealth = fields[80].GetBool(); - creatureTemplate.equipmentId = fields[81].GetUInt32(); - creatureTemplate.MechanicImmuneMask = fields[82].GetUInt32(); - creatureTemplate.flags_extra = fields[83].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString()); + creatureTemplate.movementId = fields[81].GetUInt32(); + creatureTemplate.RegenHealth = fields[82].GetBool(); + creatureTemplate.equipmentId = fields[83].GetUInt32(); + creatureTemplate.MechanicImmuneMask = fields[84].GetUInt32(); + creatureTemplate.flags_extra = fields[85].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[86].GetCString()); ++count; } @@ -857,12 +859,18 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast<CreatureTemplate*>(cInfo)->scale = 1.0f; } - if (cInfo->expansion > (MAX_CREATURE_BASE_HP - 1)) + if (cInfo->expansion > MAX_CREATURE_BASE_HP) { - sLog->outError(LOG_FILTER_SQL, "Table `creature_template` lists creature (Entry: %u) with expansion %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion); + sLog->outError(LOG_FILTER_SQL, "Table `creature_template` lists creature (Entry: %u) with `exp` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion); const_cast<CreatureTemplate*>(cInfo)->expansion = 0; } + if (cInfo->expansionUnknown > MAX_CREATURE_BASE_HP) + { + sLog->outError(LOG_FILTER_SQL, "Table `creature_template` lists creature (Entry: %u) with `exp_unk` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansionUnknown); + const_cast<CreatureTemplate*>(cInfo)->expansionUnknown = 0; + } + if (uint32 badFlags = (cInfo->flags_extra & ~CREATURE_FLAG_EXTRA_DB_ALLOWED)) { sLog->outError(LOG_FILTER_SQL, "Table `creature_template` lists creature (Entry: %u) with disallowed `flags_extra` %u, removing incorrect flag.", cInfo->Entry, badFlags); @@ -1468,7 +1476,7 @@ void ObjectMgr::LoadCreatures() } if (data.spawnMask & ~spawnMasks[data.mapid]) - sLog->outError(LOG_FILTER_SQL, "Table `creature` have creature (GUID: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u).", guid, data.spawnMask, data.mapid); + sLog->outError(LOG_FILTER_SQL, "Table `creature` have creature (GUID: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u) spawnMasks[data.mapid]: %u.", guid, data.spawnMask, data.mapid, spawnMasks[data.mapid]); bool ok = true; for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff) @@ -2013,583 +2021,503 @@ void ObjectMgr::LoadItemLocales() } -void ObjectMgr::LoadItemTemplates() +void FillItemDamageFields(float* minDamage, float* maxDamage, float* dps, uint32 itemLevel, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32 delay, float statScalingFactor, uint32 inventoryType, uint32 flags2) { - uint32 oldMSTime = getMSTime(); - - // 0 1 2 3 4 5 6 7 8 9 10 11 12 - QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, unk0, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, " - // 13 14 15 16 17 18 19 20 - "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, " - // 21 22 23 24 25 26 27 28 - "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount, stat_type1, " - // 29 30 31 32 33 34 35 36 37 38 - "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, " - // 39 40 41 42 43 44 45 46 47 - "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, " - // 48 49 50 51 52 53 54 55 56 57 58 - "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, " - // 59 60 61 62 63 64 65 66 67 68 - "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, " - // 69 70 71 72 73 74 75 - "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, " - // 76 77 78 79 80 81 82 - "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, " - // 83 84 85 86 87 88 89 - "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, " - // 90 91 92 93 94 95 96 - "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, " - // 97 98 99 100 101 102 103 104 105 - "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, " - // 106 107 108 109 110 111 112 113 114 115 116 117 - "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, " - // 118 119 120 121 122 123 124 125 - "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, " - // 126 127 128 129 130 131 132 133 - "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, " - // 134 135 136 - "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template"); - - if (!result) - { - sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded 0 item templates. DB table `item_template` is empty."); - + *minDamage = *maxDamage = *dps = 0.0f; + if (itemClass != ITEM_CLASS_WEAPON || quality > ITEM_QUALITY_ARTIFACT) return; - } - _itemTemplateStore.rehash(result->GetRowCount()); - uint32 count = 0; - bool enforceDBCAttributes = sWorld->getBoolConfig(CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES); + DBCStorage<ItemDamageEntry>* store = NULL; + // get the right store here + if (inventoryType > 0xD + 13) + return; - do + switch (inventoryType) { - Field* fields = result->Fetch(); - - uint32 entry = fields[0].GetUInt32(); - - ItemTemplate& itemTemplate = _itemTemplateStore[entry]; - - itemTemplate.ItemId = entry; - itemTemplate.Class = uint32(fields[1].GetUInt8()); - itemTemplate.SubClass = uint32(fields[2].GetUInt8()); - itemTemplate.Unk0 = fields[3].GetInt32(); - itemTemplate.Name1 = fields[4].GetString(); - itemTemplate.DisplayInfoID = fields[5].GetUInt32(); - itemTemplate.Quality = uint32(fields[6].GetUInt8()); - itemTemplate.Flags = uint32(fields[7].GetInt64()); - itemTemplate.Flags2 = fields[8].GetUInt32(); - itemTemplate.BuyCount = uint32(fields[9].GetUInt8()); - itemTemplate.BuyPrice = int32(fields[10].GetInt64()); - itemTemplate.SellPrice = fields[11].GetUInt32(); - itemTemplate.InventoryType = uint32(fields[12].GetUInt8()); - itemTemplate.AllowableClass = fields[13].GetInt32(); - itemTemplate.AllowableRace = fields[14].GetInt32(); - itemTemplate.ItemLevel = uint32(fields[15].GetUInt16()); - itemTemplate.RequiredLevel = uint32(fields[16].GetUInt8()); - itemTemplate.RequiredSkill = uint32(fields[17].GetUInt16()); - itemTemplate.RequiredSkillRank = uint32(fields[18].GetUInt16()); - itemTemplate.RequiredSpell = fields[19].GetUInt32(); - itemTemplate.RequiredHonorRank = fields[20].GetUInt32(); - itemTemplate.RequiredCityRank = fields[21].GetUInt32(); - itemTemplate.RequiredReputationFaction = uint32(fields[22].GetUInt16()); - itemTemplate.RequiredReputationRank = uint32(fields[23].GetUInt16()); - itemTemplate.MaxCount = fields[24].GetInt32(); - itemTemplate.Stackable = fields[25].GetInt32(); - itemTemplate.ContainerSlots = uint32(fields[26].GetUInt8()); - itemTemplate.StatsCount = uint32(fields[27].GetUInt8()); - - for (uint8 i = 0; i < itemTemplate.StatsCount; ++i) - { - itemTemplate.ItemStat[i].ItemStatType = uint32(fields[28 + i*2].GetUInt8()); - itemTemplate.ItemStat[i].ItemStatValue = int32(fields[29 + i*2].GetInt16()); - } - - itemTemplate.ScalingStatDistribution = uint32(fields[48].GetUInt16()); - itemTemplate.ScalingStatValue = fields[49].GetInt32(); - - for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) - { - itemTemplate.Damage[i].DamageMin = fields[50 + i*3].GetFloat(); - itemTemplate.Damage[i].DamageMax = fields[51 + i*3].GetFloat(); - itemTemplate.Damage[i].DamageType = uint32(fields[52 + i*3].GetUInt8()); - } - - itemTemplate.Armor = uint32(fields[56].GetUInt16()); - itemTemplate.HolyRes = uint32(fields[57].GetUInt8()); - itemTemplate.FireRes = uint32(fields[58].GetUInt8()); - itemTemplate.NatureRes = uint32(fields[59].GetUInt8()); - itemTemplate.FrostRes = uint32(fields[60].GetUInt8()); - itemTemplate.ShadowRes = uint32(fields[61].GetUInt8()); - itemTemplate.ArcaneRes = uint32(fields[62].GetUInt8()); - itemTemplate.Delay = uint32(fields[63].GetUInt16()); - itemTemplate.AmmoType = uint32(fields[64].GetUInt8()); - itemTemplate.RangedModRange = fields[65].GetFloat(); - - for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - { - itemTemplate.Spells[i].SpellId = fields[66 + i*7 ].GetInt32(); - itemTemplate.Spells[i].SpellTrigger = uint32(fields[67 + i*7].GetUInt8()); - itemTemplate.Spells[i].SpellCharges = int32(fields[68 + i*7].GetInt16()); - itemTemplate.Spells[i].SpellPPMRate = fields[69 + i*7].GetFloat(); - itemTemplate.Spells[i].SpellCooldown = fields[70 + i*7].GetInt32(); - itemTemplate.Spells[i].SpellCategory = uint32(fields[71 + i*7].GetUInt16()); - itemTemplate.Spells[i].SpellCategoryCooldown = fields[72 + i*7].GetInt32(); - } - - itemTemplate.Bonding = uint32(fields[101].GetUInt8()); - itemTemplate.Description = fields[102].GetString(); - itemTemplate.PageText = fields[103].GetUInt32(); - itemTemplate.LanguageID = uint32(fields[104].GetUInt8()); - itemTemplate.PageMaterial = uint32(fields[105].GetUInt8()); - itemTemplate.StartQuest = fields[106].GetUInt32(); - itemTemplate.LockID = fields[107].GetUInt32(); - itemTemplate.Material = int32(fields[108].GetInt8()); - itemTemplate.Sheath = uint32(fields[109].GetUInt8()); - itemTemplate.RandomProperty = fields[110].GetUInt32(); - itemTemplate.RandomSuffix = fields[111].GetInt32(); - itemTemplate.Block = fields[112].GetUInt32(); - itemTemplate.ItemSet = fields[113].GetUInt32(); - itemTemplate.MaxDurability = uint32(fields[114].GetUInt16()); - itemTemplate.Area = fields[115].GetUInt32(); - itemTemplate.Map = uint32(fields[116].GetUInt16()); - itemTemplate.BagFamily = fields[117].GetUInt32(); - itemTemplate.TotemCategory = fields[118].GetUInt32(); - - for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i) - { - itemTemplate.Socket[i].Color = uint32(fields[119 + i*2].GetUInt8()); - itemTemplate.Socket[i].Content = fields[120 + i*2].GetUInt32(); - } - - itemTemplate.socketBonus = fields[125].GetUInt32(); - itemTemplate.GemProperties = fields[126].GetUInt32(); - itemTemplate.RequiredDisenchantSkill = uint32(fields[127].GetInt16()); - itemTemplate.ArmorDamageModifier = fields[128].GetFloat(); - itemTemplate.Duration = fields[129].GetUInt32(); - itemTemplate.ItemLimitCategory = uint32(fields[130].GetInt16()); - itemTemplate.HolidayId = fields[131].GetUInt32(); - itemTemplate.ScriptId = sObjectMgr->GetScriptId(fields[132].GetCString()); - itemTemplate.DisenchantID = fields[133].GetUInt32(); - itemTemplate.FoodType = uint32(fields[134].GetUInt8()); - itemTemplate.MinMoneyLoot = fields[135].GetUInt32(); - itemTemplate.MaxMoneyLoot = fields[136].GetUInt32(); - itemTemplate.FlagsCu = fields[137].GetUInt32(); - - // Checks - - ItemEntry const* dbcitem = sItemStore.LookupEntry(entry); - - if (dbcitem) - { - if (itemTemplate.Class != dbcitem->Class) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct class %u, must be %u .", entry, itemTemplate.Class, dbcitem->Class); - if (enforceDBCAttributes) - itemTemplate.Class = dbcitem->Class; - } - - if (itemTemplate.Unk0 != dbcitem->Unk0) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct Unk0 (%i), must be %i .", entry, itemTemplate.Unk0, dbcitem->Unk0); - if (enforceDBCAttributes) - itemTemplate.Unk0 = dbcitem->Unk0; - } - if (itemTemplate.Material != dbcitem->Material) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct material (%i), must be %i .", entry, itemTemplate.Material, dbcitem->Material); - if (enforceDBCAttributes) - itemTemplate.Material = dbcitem->Material; - } - if (itemTemplate.InventoryType != dbcitem->InventoryType) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct inventory type (%u), must be %u .", entry, itemTemplate.InventoryType, dbcitem->InventoryType); - if (enforceDBCAttributes) - itemTemplate.InventoryType = dbcitem->InventoryType; - } - if (itemTemplate.DisplayInfoID != dbcitem->DisplayId) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct display id (%u), must be %u .", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayId); - if (enforceDBCAttributes) - itemTemplate.DisplayInfoID = dbcitem->DisplayId; - } - if (itemTemplate.Sheath != dbcitem->Sheath) + case INVTYPE_AMMO: + store = &sItemDamageAmmoStore; + break; + case INVTYPE_2HWEAPON: + if (flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON) + store = &sItemDamageTwoHandCasterStore; + else + store = &sItemDamageTwoHandStore; + break; + case INVTYPE_RANGED: + case INVTYPE_THROWN: + case INVTYPE_RANGEDRIGHT: + switch (itemSubClass) { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have a correct sheathid (%u), must be %u .", entry, itemTemplate.Sheath, dbcitem->Sheath); - if (enforceDBCAttributes) - itemTemplate.Sheath = dbcitem->Sheath; + case ITEM_SUBCLASS_WEAPON_WAND: + store = &sItemDamageWandStore; + break; + case ITEM_SUBCLASS_WEAPON_THROWN: + store = &sItemDamageThrownStore; + break; + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_GUN: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + store = &sItemDamageRangedStore; + break; + default: + return; } + break; + case INVTYPE_WEAPON: + case INVTYPE_WEAPONMAINHAND: + case INVTYPE_WEAPONOFFHAND: + if (flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON) + store = &sItemDamageOneHandCasterStore; + else + store = &sItemDamageOneHandStore; + break; + default: + return; + } - } - else - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not exist in item.dbc! (not correct id?).", entry); - - if (itemTemplate.Class >= MAX_ITEM_CLASS) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Class value (%u)", entry, itemTemplate.Class); - itemTemplate.Class = ITEM_CLASS_MISC; - } - - if (itemTemplate.SubClass >= MaxItemSubclassValues[itemTemplate.Class]) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Subclass value (%u) for class %u", entry, itemTemplate.SubClass, itemTemplate.Class); - itemTemplate.SubClass = 0;// exist for all item classes - } - - if (itemTemplate.Quality >= MAX_ITEM_QUALITY) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Quality value (%u)", entry, itemTemplate.Quality); - itemTemplate.Quality = ITEM_QUALITY_NORMAL; - } - - if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) - { - if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE)) - if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_HORDE_ONLY (%u) in Flags field, item cannot be equipped or used by these races.", - entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_HORDE_ONLY); - - if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has value (%u) in `Flags2` flags (ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) and ITEM_FLAGS_EXTRA_HORDE_ONLY (%u) in Flags field, this is a wrong combination.", - entry, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY, ITEM_FLAGS_EXTRA_HORDE_ONLY); - } - else if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) - { - if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE)) - if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_ALLIANCE_ONLY (%u) in Flags field, item cannot be equipped or used by these races.", - entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY); - } - - if (itemTemplate.BuyCount <= 0) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong BuyCount value (%u), set to default(1).", entry, itemTemplate.BuyCount); - itemTemplate.BuyCount = 1; - } - - if (itemTemplate.InventoryType >= MAX_INVTYPE) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong InventoryType value (%u)", entry, itemTemplate.InventoryType); - itemTemplate.InventoryType = INVTYPE_NON_EQUIP; - } - - if (itemTemplate.RequiredSkill >= MAX_SKILL_TYPE) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong RequiredSkill value (%u)", entry, itemTemplate.RequiredSkill); - itemTemplate.RequiredSkill = 0; - } - - { - // can be used in equip slot, as page read use in inventory, or spell casting at use - bool req = itemTemplate.InventoryType != INVTYPE_NON_EQUIP || itemTemplate.PageText; - if (!req) - for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j) - { - if (itemTemplate.Spells[j].SpellId) - { - req = true; - break; - } - } - - if (req) - { - if (!(itemTemplate.AllowableClass & CLASSMASK_ALL_PLAYABLE)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have any playable classes (%u) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate.AllowableClass); + if (!store) + return; - if (!(itemTemplate.AllowableRace & RACEMASK_ALL_PLAYABLE)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have any playable races (%u) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate.AllowableRace); - } - } + ItemDamageEntry const* damageInfo = store->LookupEntry(itemLevel); + if (!damageInfo) + return; - if (itemTemplate.RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate.RequiredSpell)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has a wrong (non-existing) spell in RequiredSpell (%u)", entry, itemTemplate.RequiredSpell); - itemTemplate.RequiredSpell = 0; - } + *dps = damageInfo->DPS[quality]; + float avgDamage = *dps * delay * 0.001f; + *minDamage = (statScalingFactor * -0.5f + 1.0f) * avgDamage; + *maxDamage = floor(float(avgDamage * (statScalingFactor * 0.5f + 1.0f) + 0.5f)); +} - if (itemTemplate.RequiredReputationRank >= MAX_REPUTATION_RANK) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used.", entry, itemTemplate.RequiredReputationRank); +uint32 FillItemArmor(uint32 itemlevel, uint32 itemClass, uint32 itemSubclass, uint32 quality, uint32 inventoryType) +{ + if (quality > ITEM_QUALITY_ARTIFACT) + return 0; - if (itemTemplate.RequiredReputationFaction) - { - if (!sFactionStore.LookupEntry(itemTemplate.RequiredReputationFaction)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)", entry, itemTemplate.RequiredReputationFaction); - itemTemplate.RequiredReputationFaction = 0; - } + // all items but shields + if (itemClass != ITEM_CLASS_ARMOR || itemSubclass != ITEM_SUBCLASS_ARMOR_SHIELD) + { + ItemArmorQualityEntry const* armorQuality = sItemArmorQualityStore.LookupEntry(itemlevel); + ItemArmorTotalEntry const* armorToral = sItemArmorTotalStore.LookupEntry(itemlevel); + if (!armorQuality || !armorToral) + return 0; - if (itemTemplate.RequiredReputationRank == MIN_REPUTATION_RANK) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry); - } + if (inventoryType == INVTYPE_ROBE) + inventoryType = INVTYPE_CHEST; - if (itemTemplate.MaxCount < -1) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has too large negative in maxcount (%i), replace by value (-1) no storing limits.", entry, itemTemplate.MaxCount); - itemTemplate.MaxCount = -1; - } + ArmorLocationEntry const* location = sArmorLocationStore.LookupEntry(inventoryType); + if (!location) + return 0; - if (itemTemplate.Stackable == 0) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong value in stackable (%i), replace by default 1.", entry, itemTemplate.Stackable); - itemTemplate.Stackable = 1; - } - else if (itemTemplate.Stackable < -1) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits.", entry, itemTemplate.Stackable); - itemTemplate.Stackable = -1; - } + if (itemSubclass < ITEM_SUBCLASS_ARMOR_CLOTH) + return 0; - if (itemTemplate.ContainerSlots > MAX_BAG_SIZE) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has too large value in ContainerSlots (%u), replace by hardcoded limit (%u).", entry, itemTemplate.ContainerSlots, MAX_BAG_SIZE); - itemTemplate.ContainerSlots = MAX_BAG_SIZE; - } + return uint32(armorQuality->Value[quality] * armorToral->Value[quality] * location->Value[itemSubclass - 1] + 0.5f); + } - if (itemTemplate.StatsCount > MAX_ITEM_PROTO_STATS) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).", entry, itemTemplate.StatsCount, MAX_ITEM_PROTO_STATS); - itemTemplate.StatsCount = MAX_ITEM_PROTO_STATS; - } + // shields + ItemArmorShieldEntry const* shield = sItemArmorShieldStore.LookupEntry(itemlevel); + if (!shield) + return 0; - for (uint8 j = 0; j < itemTemplate.StatsCount; ++j) - { - // for ItemStatValue != 0 - if (itemTemplate.ItemStat[j].ItemStatValue && itemTemplate.ItemStat[j].ItemStatType >= MAX_ITEM_MOD) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong (non-existing?) stat_type%d (%u)", entry, j+1, itemTemplate.ItemStat[j].ItemStatType); - itemTemplate.ItemStat[j].ItemStatType = 0; - } + return uint32(shield->Value[quality] + 0.5f); +} - switch (itemTemplate.ItemStat[j].ItemStatType) - { - case ITEM_MOD_SPELL_HEALING_DONE: - case ITEM_MOD_SPELL_DAMAGE_DONE: - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has deprecated stat_type%d (%u)", entry, j+1, itemTemplate.ItemStat[j].ItemStatType); - break; - default: - break; - } - } +uint32 FillMaxDurability(uint32 itemClass, uint32 itemSubClass, uint32 inventoryType, uint32 quality, uint32 itemLevel) +{ + if (itemClass != ITEM_CLASS_ARMOR && itemClass != ITEM_CLASS_WEAPON) + return 0; - for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j) - { - if (itemTemplate.Damage[j].DamageType >= MAX_SPELL_SCHOOL) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong dmg_type%d (%u)", entry, j+1, itemTemplate.Damage[j].DamageType); - itemTemplate.Damage[j].DamageType = 0; - } - } + static float const qualityMultipliers[MAX_ITEM_QUALITY] = + { + 1.0f, 1.0f, 1.0f, 1.17f, 1.37f, 1.68f, 0.0f, 0.0f + }; - // special format - if ((itemTemplate.Spells[0].SpellId == 483) || (itemTemplate.Spells[0].SpellId == 55884)) - { - // spell_1 - if (itemTemplate.Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format", entry, 0+1, itemTemplate.Spells[0].SpellTrigger); - itemTemplate.Spells[0].SpellId = 0; - itemTemplate.Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - itemTemplate.Spells[1].SpellId = 0; - itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } + static float const armorMultipliers[MAX_INVTYPE] = + { + 0.00f, // INVTYPE_NON_EQUIP + 0.59f, // INVTYPE_HEAD + 0.00f, // INVTYPE_NECK + 0.59f, // INVTYPE_SHOULDERS + 0.00f, // INVTYPE_BODY + 1.00f, // INVTYPE_CHEST + 0.35f, // INVTYPE_WAIST + 0.75f, // INVTYPE_LEGS + 0.49f, // INVTYPE_FEET + 0.35f, // INVTYPE_WRISTS + 0.35f, // INVTYPE_HANDS + 0.00f, // INVTYPE_FINGER + 0.00f, // INVTYPE_TRINKET + 0.00f, // INVTYPE_WEAPON + 1.00f, // INVTYPE_SHIELD + 0.00f, // INVTYPE_RANGED + 0.00f, // INVTYPE_CLOAK + 0.00f, // INVTYPE_2HWEAPON + 0.00f, // INVTYPE_BAG + 0.00f, // INVTYPE_TABARD + 1.00f, // INVTYPE_ROBE + 0.00f, // INVTYPE_WEAPONMAINHAND + 0.00f, // INVTYPE_WEAPONOFFHAND + 0.00f, // INVTYPE_HOLDABLE + 0.00f, // INVTYPE_AMMO + 0.00f, // INVTYPE_THROWN + 0.00f, // INVTYPE_RANGEDRIGHT + 0.00f, // INVTYPE_QUIVER + 0.00f, // INVTYPE_RELIC + }; - // spell_2 have learning spell - if (itemTemplate.Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.", entry, 1+1, itemTemplate.Spells[1].SpellTrigger); - itemTemplate.Spells[0].SpellId = 0; - itemTemplate.Spells[1].SpellId = 0; - itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } - else if (!itemTemplate.Spells[1].SpellId) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not have an expected spell in spellid_%d in special learning format.", entry, 1+1); - itemTemplate.Spells[0].SpellId = 0; - itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } - else if (itemTemplate.Spells[1].SpellId != -1) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[1].SpellId); - if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[1].SpellId, NULL)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)", entry, 1+1, itemTemplate.Spells[1].SpellId); - itemTemplate.Spells[0].SpellId = 0; - itemTemplate.Spells[1].SpellId = 0; - itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } - // allowed only in special format - else if ((itemTemplate.Spells[1].SpellId == 483) || (itemTemplate.Spells[1].SpellId == 55884)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has broken spell in spellid_%d (%d)", entry, 1+1, itemTemplate.Spells[1].SpellId); - itemTemplate.Spells[0].SpellId = 0; - itemTemplate.Spells[1].SpellId = 0; - itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } - } + static float const weaponMultipliers[MAX_ITEM_SUBCLASS_WEAPON] = + { + 0.89f, // ITEM_SUBCLASS_WEAPON_AXE + 1.03f, // ITEM_SUBCLASS_WEAPON_AXE2 + 0.77f, // ITEM_SUBCLASS_WEAPON_BOW + 0.77f, // ITEM_SUBCLASS_WEAPON_GUN + 0.89f, // ITEM_SUBCLASS_WEAPON_MACE + 1.03f, // ITEM_SUBCLASS_WEAPON_MACE2 + 1.03f, // ITEM_SUBCLASS_WEAPON_POLEARM + 0.89f, // ITEM_SUBCLASS_WEAPON_SWORD + 1.03f, // ITEM_SUBCLASS_WEAPON_SWORD2 + 0.00f, // ITEM_SUBCLASS_WEAPON_Obsolete + 1.03f, // ITEM_SUBCLASS_WEAPON_STAFF + 0.00f, // ITEM_SUBCLASS_WEAPON_EXOTIC + 0.00f, // ITEM_SUBCLASS_WEAPON_EXOTIC2 + 0.64f, // ITEM_SUBCLASS_WEAPON_FIST_WEAPON + 0.00f, // ITEM_SUBCLASS_WEAPON_MISCELLANEOUS + 0.64f, // ITEM_SUBCLASS_WEAPON_DAGGER + 0.64f, // ITEM_SUBCLASS_WEAPON_THROWN + 0.00f, // ITEM_SUBCLASS_WEAPON_SPEAR + 0.77f, // ITEM_SUBCLASS_WEAPON_CROSSBOW + 0.64f, // ITEM_SUBCLASS_WEAPON_WAND + 0.64f, // ITEM_SUBCLASS_WEAPON_FISHING_POLE + }; - // spell_3*, spell_4*, spell_5* is empty - for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j) - { - if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)", entry, j+1, itemTemplate.Spells[j].SpellTrigger); - itemTemplate.Spells[j].SpellId = 0; - itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } - else if (itemTemplate.Spells[j].SpellId != 0) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong spell in spellid_%d (%d) for learning special format", entry, j+1, itemTemplate.Spells[j].SpellId); - itemTemplate.Spells[j].SpellId = 0; - } - } - } - // normal spell list - else - { - for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j) - { - if (itemTemplate.Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate.Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)", entry, j+1, itemTemplate.Spells[j].SpellTrigger); - itemTemplate.Spells[j].SpellId = 0; - itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE; - } + float levelPenalty = 1.0f; + if (itemLevel <= 28) + levelPenalty = 0.966f - float(28u - itemLevel) / 54.0f; - if (itemTemplate.Spells[j].SpellId && itemTemplate.Spells[j].SpellId != -1) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[j].SpellId); - if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[j].SpellId, NULL)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)", entry, j+1, itemTemplate.Spells[j].SpellId); - itemTemplate.Spells[j].SpellId = 0; - } - // allowed only in special format - else if ((itemTemplate.Spells[j].SpellId == 483) || (itemTemplate.Spells[j].SpellId == 55884)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has broken spell in spellid_%d (%d)", entry, j+1, itemTemplate.Spells[j].SpellId); - itemTemplate.Spells[j].SpellId = 0; - } - } - } - } + if (itemClass == ITEM_CLASS_ARMOR) + { + if (inventoryType > INVTYPE_ROBE) + return 0; - if (itemTemplate.Bonding >= MAX_BIND_TYPE) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Bonding value (%u)", entry, itemTemplate.Bonding); + return 5 * uint32(23.0f * qualityMultipliers[quality] * armorMultipliers[inventoryType] * levelPenalty + 0.5f); + } - if (itemTemplate.PageText && !GetPageText(itemTemplate.PageText)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has non existing first page (Id:%u)", entry, itemTemplate.PageText); + return 5 * uint32(17.0f * qualityMultipliers[quality] * weaponMultipliers[itemSubClass] * levelPenalty + 0.5f); +}; - if (itemTemplate.LockID && !sLockStore.LookupEntry(itemTemplate.LockID)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong LockID (%u)", entry, itemTemplate.LockID); +void FillDisenchantFields(uint32* disenchantID, uint32* requiredDisenchantSkill, ItemTemplate const& itemTemplate) +{ + *disenchantID = 0; + *(int32*)requiredDisenchantSkill = -1; + if ((itemTemplate.Flags & (ITEM_PROTO_FLAG_CONJURED | ITEM_PROTO_FLAG_UNK6)) || + itemTemplate.Bonding == BIND_QUEST_ITEM || itemTemplate.Area || itemTemplate.Map || + itemTemplate.Stackable > 1 || + !(itemTemplate.SellPrice || sItemCurrencyCostStore.LookupEntry(itemTemplate.ItemId))) + return; - if (itemTemplate.Sheath >= MAX_SHEATHETYPE) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Sheath (%u)", entry, itemTemplate.Sheath); - itemTemplate.Sheath = SHEATHETYPE_NONE; - } + for (uint32 i = 0; i < sItemDisenchantLootStore.GetNumRows(); ++i) + { + ItemDisenchantLootEntry const* disenchant = sItemDisenchantLootStore.LookupEntry(i); + if (!disenchant) + continue; - if (itemTemplate.RandomProperty) + if (disenchant->ItemClass == itemTemplate.Class && + disenchant->ItemQuality == itemTemplate.Quality && + disenchant->MinItemLevel <= itemTemplate.ItemLevel && + disenchant->MaxItemLevel >= itemTemplate.ItemLevel) { - // To be implemented later - if (itemTemplate.RandomProperty == -1) - itemTemplate.RandomProperty = 0; - - else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomProperty))) + // extra check for epics in range 90 - 99 + if (disenchant->MinItemLevel < 90) { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)", entry, itemTemplate.RandomProperty); - itemTemplate.RandomProperty = 0; + if (itemTemplate.RequiredLevel > 60 || itemTemplate.RequiredSkillRank > 300) + continue; } - } - - if (itemTemplate.RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomSuffix))) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong RandomSuffix (%u)", entry, itemTemplate.RandomSuffix); - itemTemplate.RandomSuffix = 0; - } - - if (itemTemplate.ItemSet && !sItemSetStore.LookupEntry(itemTemplate.ItemSet)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) have wrong ItemSet (%u)", entry, itemTemplate.ItemSet); - itemTemplate.ItemSet = 0; - } - - if (itemTemplate.Area && !GetAreaEntryByAreaID(itemTemplate.Area)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Area (%u)", entry, itemTemplate.Area); - - if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong Map (%u)", entry, itemTemplate.Map); - - if (itemTemplate.BagFamily) - { - // check bits - for (uint32 j = 0; j < sizeof(itemTemplate.BagFamily)*8; ++j) + else { - uint32 mask = 1 << j; - if ((itemTemplate.BagFamily & mask) == 0) + if (itemTemplate.RequiredLevel <= 60 || itemTemplate.RequiredSkillRank <= 300) continue; - - ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j+1); - if (!bf) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry); - itemTemplate.BagFamily &= ~mask; - continue; - } - - if (BAG_FAMILY_MASK_CURRENCY_TOKENS & mask) - { - CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate.ItemId); - if (!ctEntry) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry); - itemTemplate.BagFamily &= ~mask; - } - } } - } - - if (itemTemplate.TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate.TotemCategory)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong TotemCategory (%u)", entry, itemTemplate.TotemCategory); - for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j) - { - if (itemTemplate.Socket[j].Color && (itemTemplate.Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate.Socket[j].Color) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong socketColor_%d (%u)", entry, j+1, itemTemplate.Socket[j].Color); - itemTemplate.Socket[j].Color = 0; - } + *disenchantID = disenchant->Id; + *requiredDisenchantSkill = disenchant->RequiredDisenchantSkill; + return; } + } +} - if (itemTemplate.GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate.GemProperties)) - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong GemProperties (%u)", entry, itemTemplate.GemProperties); - - if (itemTemplate.FoodType >= MAX_PET_DIET) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong FoodType value (%u)", entry, itemTemplate.FoodType); - itemTemplate.FoodType = 0; - } +void ObjectMgr::LoadItemTemplates() +{ + uint32 oldMSTime = getMSTime(); + uint32 sparseCount = 0; + uint32 dbCount = 0; - if (itemTemplate.ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate.ItemLimitCategory)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong LimitCategory value (%u)", entry, itemTemplate.ItemLimitCategory); - itemTemplate.ItemLimitCategory = 0; - } + for (uint32 itemId = 0; itemId < sItemSparseStore.GetNumRows(); ++itemId) + { + ItemSparseEntry const* sparse = sItemSparseStore.LookupEntry(itemId); + ItemEntry const* db2Data = sItemStore.LookupEntry(itemId); + if (!sparse || !db2Data) + continue; - if (itemTemplate.HolidayId && !sHolidaysStore.LookupEntry(itemTemplate.HolidayId)) - { - sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) has wrong HolidayId value (%u)", entry, itemTemplate.HolidayId); - itemTemplate.HolidayId = 0; - } + ItemTemplate& itemTemplate = _itemTemplateStore[itemId]; + + itemTemplate.ItemId = itemId; + itemTemplate.Class = db2Data->Class; + itemTemplate.SubClass = db2Data->SubClass; + itemTemplate.Unk0 = db2Data->Unk0; + itemTemplate.Name1 = sparse->Name; + itemTemplate.DisplayInfoID = db2Data->DisplayId; + itemTemplate.Quality = sparse->Quality; + itemTemplate.Flags = sparse->Flags; + itemTemplate.Flags2 = sparse->Flags2; + itemTemplate.Unk430_1 = sparse->Unk430_1; + itemTemplate.Unk430_2 = sparse->Unk430_2; + itemTemplate.BuyCount = std::max(sparse->BuyCount, 1u); + itemTemplate.BuyPrice = sparse->BuyPrice; + itemTemplate.SellPrice = sparse->SellPrice; + itemTemplate.InventoryType = db2Data->InventoryType; + itemTemplate.AllowableClass = sparse->AllowableClass; + itemTemplate.AllowableRace = sparse->AllowableRace; + itemTemplate.ItemLevel = sparse->ItemLevel; + itemTemplate.RequiredLevel = sparse->RequiredLevel; + itemTemplate.RequiredSkill = sparse->RequiredSkill; + itemTemplate.RequiredSkillRank = sparse->RequiredSkillRank; + itemTemplate.RequiredSpell = sparse->RequiredSpell; + itemTemplate.RequiredHonorRank = sparse->RequiredHonorRank; + itemTemplate.RequiredCityRank = sparse->RequiredCityRank; + itemTemplate.RequiredReputationFaction = sparse->RequiredReputationFaction; + itemTemplate.RequiredReputationRank = sparse->RequiredReputationRank; + itemTemplate.MaxCount = sparse->MaxCount; + itemTemplate.Stackable = sparse->Stackable; + itemTemplate.ContainerSlots = sparse->ContainerSlots; + for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) + { + itemTemplate.ItemStat[i].ItemStatType = sparse->ItemStatType[i]; + itemTemplate.ItemStat[i].ItemStatValue = sparse->ItemStatValue[i]; + itemTemplate.ItemStat[i].ItemStatUnk1 = sparse->ItemStatUnk1[i]; + itemTemplate.ItemStat[i].ItemStatUnk2 = sparse->ItemStatUnk2[i]; + } + + itemTemplate.ScalingStatDistribution = sparse->ScalingStatDistribution; + + // cache item damage + FillItemDamageFields(&itemTemplate.DamageMin, &itemTemplate.DamageMax, &itemTemplate.DPS, sparse->ItemLevel, + db2Data->Class, db2Data->SubClass, sparse->Quality, sparse->Delay, sparse->StatScalingFactor, + sparse->InventoryType, sparse->Flags2); + + itemTemplate.DamageType = sparse->DamageType; + itemTemplate.Armor = FillItemArmor(sparse->ItemLevel, db2Data->Class, db2Data->SubClass, sparse->Quality, sparse->InventoryType); + itemTemplate.Delay = sparse->Delay; + itemTemplate.RangedModRange = sparse->RangedModRange; + for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + { + itemTemplate.Spells[i].SpellId = sparse->SpellId[i]; + itemTemplate.Spells[i].SpellTrigger = sparse->SpellTrigger[i]; + itemTemplate.Spells[i].SpellCharges = sparse->SpellCharges[i]; + itemTemplate.Spells[i].SpellCooldown = sparse->SpellCooldown[i]; + itemTemplate.Spells[i].SpellCategory = sparse->SpellCategory[i]; + itemTemplate.Spells[i].SpellCategoryCooldown = sparse->SpellCategoryCooldown[i]; + } + + itemTemplate.SpellPPMRate = 0.0f; + itemTemplate.Bonding = sparse->Bonding; + itemTemplate.Description = sparse->Description; + itemTemplate.PageText = sparse->PageText; + itemTemplate.LanguageID = sparse->LanguageID; + itemTemplate.PageMaterial = sparse->PageMaterial; + itemTemplate.StartQuest = sparse->StartQuest; + itemTemplate.LockID = sparse->LockID; + itemTemplate.Material = sparse->Material; + itemTemplate.Sheath = sparse->Sheath; + itemTemplate.RandomProperty = sparse->RandomProperty; + itemTemplate.RandomSuffix = sparse->RandomSuffix; + itemTemplate.ItemSet = sparse->ItemSet; + itemTemplate.MaxDurability = FillMaxDurability(db2Data->Class, db2Data->SubClass, sparse->InventoryType, sparse->Quality, sparse->ItemLevel); + itemTemplate.Area = sparse->Area; + itemTemplate.Map = sparse->Map; + itemTemplate.BagFamily = sparse->BagFamily; + itemTemplate.TotemCategory = sparse->TotemCategory; + for (uint32 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i) + { + itemTemplate.Socket[i].Color = sparse->Color[i]; + itemTemplate.Socket[i].Content = sparse->Content[i]; + } + + itemTemplate.socketBonus = sparse->SocketBonus; + itemTemplate.GemProperties = sparse->GemProperties; + FillDisenchantFields(&itemTemplate.DisenchantID, &itemTemplate.RequiredDisenchantSkill, itemTemplate); + + itemTemplate.ArmorDamageModifier = sparse->ArmorDamageModifier; + itemTemplate.Duration = sparse->Duration; + itemTemplate.ItemLimitCategory = sparse->ItemLimitCategory; + itemTemplate.HolidayId = sparse->HolidayId; + itemTemplate.StatScalingFactor = sparse->StatScalingFactor; + itemTemplate.CurrencySubstitutionId = sparse->CurrencySubstitutionId; + itemTemplate.CurrencySubstitutionCount = sparse->CurrencySubstitutionCount; + itemTemplate.ScriptId = 0; + itemTemplate.FoodType = 0; + itemTemplate.MinMoneyLoot = 0; + itemTemplate.MaxMoneyLoot = 0; + ++sparseCount; + } + + // Load missing items from item_template AND overwrite data from Item-sparse.db2 (item_template is supposed to contain Item-sparse.adb data) + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + QueryResult result = WorldDatabase.Query("SELECT entry, Class, SubClass, Unk0, Name, DisplayId, Quality, Flags, FlagsExtra, Unk430_1, Unk430_2, BuyCount, BuyPrice, SellPrice, " + // 14 15 16 17 18 19 20 21 + "InventoryType, AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, RequiredSpell, " + // 22 23 24 25 26 27 28 + "RequiredHonorRank, RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, MaxCount, Stackable, ContainerSlots, " + // 29 30 31 32 33 34 35 36 + "stat_type1, stat_value1, stat_unk1_1, stat_unk2_1, stat_type2, stat_value2, stat_unk1_2, stat_unk2_2, " + // 37 38 39 40 41 42 43 44 + "stat_type3, stat_value3, stat_unk1_3, stat_unk2_3, stat_type4, stat_value4, stat_unk1_4, stat_unk2_4, " + // 45 46 47 48 49 50 51 52 + "stat_type5, stat_value5, stat_unk1_5, stat_unk2_5, stat_type6, stat_value6, stat_unk1_6, stat_unk2_6, " + // 53 54 55 56 57 58 59 60 + "stat_type7, stat_value7, stat_unk1_7, stat_unk2_7, stat_type8, stat_value8, stat_unk1_8, stat_unk2_8, " + // 61 62 63 64 65 66 67 68 + "stat_type9, stat_value9, stat_unk1_9, stat_unk2_9, stat_type10, stat_value10, stat_unk1_10, stat_unk2_10, " + // 69 70 71 72 + "ScalingStatDistribution, DamageType, Delay, RangedModRange, " + // 73 74 75 76 77 78 + "spellid_1, spelltrigger_1, spellcharges_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, " + // 79 80 81 82 83 84 + "spellid_2, spelltrigger_2, spellcharges_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, " + // 85 86 87 88 89 90 + "spellid_3, spelltrigger_3, spellcharges_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, " + // 91 92 93 94 95 96 + "spellid_4, spelltrigger_4, spellcharges_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, " + // 97 98 99 100 101 102 + "spellid_5, spelltrigger_5, spellcharges_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, " + // 103 104 105 106 107 108 109 110 + "Bonding, Description, PageText, LanguageID, PageMaterial, StartQuest, LockID, Material, " + // 111 112 113 114 115 116 117 118 + "Sheath, RandomProperty, RandomSuffix, ItemSet, Area, Map, BagFamily, TotemCategory, " + // 119 120 121 122 123 124 125 + "SocketColor_1, SocketContent_1, SocketColor_2, SocketContent_2, SocketColor_3, SocketContent_3, SocketBonus, " + // 126 127 128 129 130 131 + "GemProperties, ArmorDamageModifier, Duration, ItemLimitCategory, HolidayId, StatScalingFactor, " + // 132 133 + "CurrencySubstitutionId, CurrencySubstitutionCount " + "FROM item_template"); - if (itemTemplate.FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME && !itemTemplate.Duration) + if (result) + { + do { - sLog->outError(LOG_FILTER_SQL, "Item (Entry %u) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry); - itemTemplate.FlagsCu &= ~ITEM_FLAGS_CU_DURATION_REAL_TIME; - } - - ++count; + Field* fields = result->Fetch(); + uint32 itemId = fields[0].GetUInt32(); + if (_itemTemplateStore.find(itemId) != _itemTemplateStore.end()) + --sparseCount; + + ItemTemplate& itemTemplate = _itemTemplateStore[itemId]; + + itemTemplate.ItemId = itemId; + itemTemplate.Class = uint32(fields[1].GetUInt8()); + itemTemplate.SubClass = uint32(fields[2].GetUInt8()); + itemTemplate.Unk0 = fields[3].GetInt32(); + itemTemplate.Name1 = fields[4].GetString(); + itemTemplate.DisplayInfoID = fields[5].GetUInt32(); + itemTemplate.Quality = uint32(fields[6].GetUInt8()); + itemTemplate.Flags = uint32(fields[7].GetInt64()); + itemTemplate.Flags2 = fields[8].GetUInt32(); + itemTemplate.Unk430_1 = fields[9].GetFloat(); + itemTemplate.Unk430_2 = fields[10].GetFloat(); + itemTemplate.BuyCount = uint32(fields[11].GetUInt8()); + itemTemplate.BuyPrice = int32(fields[12].GetInt64()); + itemTemplate.SellPrice = fields[13].GetUInt32(); + + itemTemplate.InventoryType = uint32(fields[14].GetUInt8()); + itemTemplate.AllowableClass = fields[15].GetInt32(); + itemTemplate.AllowableRace = fields[16].GetInt32(); + itemTemplate.ItemLevel = uint32(fields[17].GetUInt16()); + itemTemplate.RequiredLevel = uint32(fields[18].GetUInt8()); + itemTemplate.RequiredSkill = uint32(fields[19].GetUInt16()); + itemTemplate.RequiredSkillRank = uint32(fields[20].GetUInt16()); + itemTemplate.RequiredSpell = fields[21].GetUInt32(); + itemTemplate.RequiredHonorRank = fields[22].GetUInt32(); + itemTemplate.RequiredCityRank = fields[23].GetUInt32(); + itemTemplate.RequiredReputationFaction = uint32(fields[24].GetUInt16()); + itemTemplate.RequiredReputationRank = uint32(fields[25].GetUInt16()); + itemTemplate.MaxCount = fields[26].GetInt32(); + itemTemplate.Stackable = fields[27].GetInt32(); + itemTemplate.ContainerSlots = uint32(fields[28].GetUInt8()); + for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) + { + itemTemplate.ItemStat[i].ItemStatType = uint32(fields[29 + i * 4 + 0].GetUInt8()); + itemTemplate.ItemStat[i].ItemStatValue = int32(fields[29 + i * 4 + 1].GetInt16()); + itemTemplate.ItemStat[i].ItemStatUnk1 = fields[29 + i * 4 + 2].GetInt32(); + itemTemplate.ItemStat[i].ItemStatUnk2 = fields[29 + i * 4 + 3].GetInt32(); + } + + itemTemplate.ScalingStatDistribution = uint32(fields[69].GetUInt16()); + + // cache item damage + FillItemDamageFields(&itemTemplate.DamageMin, &itemTemplate.DamageMax, &itemTemplate.DPS, itemTemplate.ItemLevel, + itemTemplate.Class, itemTemplate.SubClass, itemTemplate.Quality, fields[71].GetUInt16(), + fields[131].GetFloat(), itemTemplate.InventoryType, itemTemplate.Flags2); + + itemTemplate.DamageType = fields[70].GetUInt8(); + itemTemplate.Armor = FillItemArmor(itemTemplate.ItemLevel, itemTemplate.Class, + itemTemplate.SubClass, itemTemplate.Quality, + itemTemplate.InventoryType); + + itemTemplate.Delay = fields[71].GetUInt16(); + itemTemplate.RangedModRange = fields[72].GetFloat(); + for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + { + itemTemplate.Spells[i].SpellId = fields[73 + 6 * i + 0].GetInt32(); + itemTemplate.Spells[i].SpellTrigger = uint32(fields[73 + 6 * i + 1].GetUInt8()); + itemTemplate.Spells[i].SpellCharges = int32(fields[73 + 6 * i + 2].GetInt16()); + itemTemplate.Spells[i].SpellCooldown = fields[73 + 6 * i + 3].GetInt32(); + itemTemplate.Spells[i].SpellCategory = uint32(fields[73 + 6 * i + 4].GetUInt16()); + itemTemplate.Spells[i].SpellCategoryCooldown = fields[73 + 6 * i + 5].GetInt32(); + } + + itemTemplate.SpellPPMRate = 0.0f; + itemTemplate.Bonding = uint32(fields[103].GetUInt8()); + itemTemplate.Description = fields[104].GetString(); + itemTemplate.PageText = fields[105].GetUInt32(); + itemTemplate.LanguageID = uint32(fields[106].GetUInt8()); + itemTemplate.PageMaterial = uint32(fields[107].GetUInt8()); + itemTemplate.StartQuest = fields[108].GetUInt32(); + itemTemplate.LockID = fields[109].GetUInt32(); + itemTemplate.Material = int32(fields[110].GetInt8()); + itemTemplate.Sheath = uint32(fields[111].GetUInt8()); + itemTemplate.RandomProperty = fields[112].GetUInt32(); + itemTemplate.RandomSuffix = fields[113].GetInt32(); + itemTemplate.ItemSet = fields[114].GetUInt32(); + itemTemplate.MaxDurability = FillMaxDurability(itemTemplate.Class, itemTemplate.SubClass, + itemTemplate.InventoryType, itemTemplate.Quality, itemTemplate.ItemLevel); + + itemTemplate.Area = fields[115].GetUInt32(); + itemTemplate.Map = uint32(fields[116].GetUInt16()); + itemTemplate.BagFamily = fields[117].GetUInt32(); + itemTemplate.TotemCategory = fields[118].GetUInt32(); + for (uint32 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i) + { + itemTemplate.Socket[i].Color = uint32(fields[119 + i*2].GetUInt8()); + itemTemplate.Socket[i].Content = fields[119 + i * 2 + 1].GetUInt32(); + } + + itemTemplate.socketBonus = fields[125].GetUInt32(); + itemTemplate.GemProperties = fields[126].GetUInt32(); + FillDisenchantFields(&itemTemplate.DisenchantID, &itemTemplate.RequiredDisenchantSkill, itemTemplate); + + itemTemplate.ArmorDamageModifier = fields[127].GetFloat(); + itemTemplate.Duration = fields[128].GetUInt32(); + itemTemplate.ItemLimitCategory = uint32(fields[129].GetInt16()); + itemTemplate.HolidayId = fields[130].GetUInt32(); + itemTemplate.StatScalingFactor = fields[131].GetFloat(); + itemTemplate.CurrencySubstitutionId = fields[132].GetInt32(); + itemTemplate.CurrencySubstitutionCount = fields[133].GetInt32(); + itemTemplate.ScriptId = 0; + itemTemplate.FoodType = 0; + itemTemplate.MinMoneyLoot = 0; + itemTemplate.MaxMoneyLoot = 0; + ++dbCount; + } while (result->NextRow()); } - while (result->NextRow()); // Check if item templates for DBC referenced character start outfit are present std::set<uint32> notFoundOutfit; @@ -2614,128 +2542,81 @@ void ObjectMgr::LoadItemTemplates() for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr) sLog->outError(LOG_FILTER_SQL, "Item (Entry: %u) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr); - sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u item templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - -} - -ItemTemplate const* ObjectMgr::GetItemTemplate(uint32 entry) -{ - ItemTemplateContainer::const_iterator itr = _itemTemplateStore.find(entry); - if (itr != _itemTemplateStore.end()) - return &(itr->second); - - return NULL; + sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u item templates from Item-sparse.db2 and %u from database in %u ms", sparseCount, dbCount, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadItemSetNameLocales() +void ObjectMgr::LoadItemTemplateAddon() { uint32 oldMSTime = getMSTime(); + uint32 count = 0; - _itemSetNameLocaleStore.clear(); // need for reload case - - QueryResult result = WorldDatabase.Query("SELECT `entry`, `name_loc1`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc5`, `name_loc6`, `name_loc7`, `name_loc8` FROM `locales_item_set_names`"); - - if (!result) - return; - - do + QueryResult result = WorldDatabase.Query("SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon"); + if (result) { - Field* fields = result->Fetch(); - - uint32 entry = fields[0].GetUInt32(); - - ItemSetNameLocale& data = _itemSetNameLocaleStore[entry]; + do + { + Field* fields = result->Fetch(); + uint32 itemId = fields[0].GetUInt32(); + if (!GetItemTemplate(itemId)) + { + sLog->outError(LOG_FILTER_SQL, "Item %u specified in `item_template_addon` does not exist, skipped.", itemId); + continue; + } - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) - AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Name); - } while (result->NextRow()); + uint32 minMoneyLoot = fields[3].GetUInt32(); + uint32 maxMoneyLoot = fields[4].GetUInt32(); + if (minMoneyLoot > maxMoneyLoot) + { + sLog->outError(LOG_FILTER_SQL, "Minimum money loot specified in `item_template_addon` for item %u was greater than maximum amount, swapping.", itemId); + std::swap(minMoneyLoot, maxMoneyLoot); + } - sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded " UI64FMTD " Item set name locale strings in %u ms", uint64(_itemSetNameLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); + ItemTemplate& itemTemplate = _itemTemplateStore[itemId]; + itemTemplate.FlagsCu = fields[1].GetUInt32(); + itemTemplate.FoodType = fields[2].GetUInt8(); + itemTemplate.MinMoneyLoot = minMoneyLoot; + itemTemplate.MaxMoneyLoot = maxMoneyLoot; + itemTemplate.SpellPPMRate = fields[5].GetFloat(); + ++count; + } while (result->NextRow()); + } + sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u item addon templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadItemSetNames() +void ObjectMgr::LoadItemScriptNames() { uint32 oldMSTime = getMSTime(); - - _itemSetNameStore.clear(); // needed for reload case - - std::set<uint32> itemSetItems; - - // fill item set member ids - for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId) - { - ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId); - if (!setEntry) - continue; - - for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i) - if (setEntry->itemId[i]) - itemSetItems.insert(setEntry->itemId[i]); - } - - // 0 1 2 - QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`"); - - if (!result) - { - sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded 0 item set names. DB table `item_set_names` is empty."); - - return; - } - - _itemSetNameStore.rehash(result->GetRowCount()); uint32 count = 0; - do - { - Field* fields = result->Fetch(); - - uint32 entry = fields[0].GetUInt32(); - if (itemSetItems.find(entry) == itemSetItems.end()) - { - sLog->outError(LOG_FILTER_SQL, "Item set name (Entry: %u) not found in ItemSet.dbc, data useless.", entry); - continue; - } - - ItemSetNameEntry &data = _itemSetNameStore[entry]; - data.name = fields[1].GetString(); - - uint32 invType = fields[2].GetUInt8(); - if (invType >= MAX_INVTYPE) - { - sLog->outError(LOG_FILTER_SQL, "Item set name (Entry: %u) has wrong InventoryType value (%u)", entry, invType); - invType = INVTYPE_NON_EQUIP; - } - - data.InventoryType = invType; - itemSetItems.erase(entry); - ++count; - } while (result->NextRow()); - - if (!itemSetItems.empty()) + QueryResult result = WorldDatabase.Query("SELECT Id, ScriptName FROM item_script_names"); + if (result) { - ItemTemplate const* pProto; - for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr) + do { - uint32 entry = *itr; - // add data from item_template if available - pProto = sObjectMgr->GetItemTemplate(entry); - if (pProto) + Field* fields = result->Fetch(); + uint32 itemId = fields[0].GetUInt32(); + if (!GetItemTemplate(itemId)) { - sLog->outError(LOG_FILTER_SQL, "Item set part (Entry: %u) does not have entry in `item_set_names`, adding data from `item_template`.", entry); - ItemSetNameEntry &data = _itemSetNameStore[entry]; - data.name = pProto->Name1; - data.InventoryType = pProto->InventoryType; - ++count; + sLog->outError(LOG_FILTER_SQL, "Item %u specified in `item_script_names` does not exist, skipped.", itemId); + continue; } - else - sLog->outError(LOG_FILTER_SQL, "Item set part (Entry: %u) does not have entry in `item_set_names`, set will not display properly.", entry); - } + + _itemTemplateStore[itemId].ScriptId = GetScriptId(fields[1].GetCString()); + ++count; + } while (result->NextRow()); } - sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u item set names in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u item script names in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} +ItemTemplate const* ObjectMgr::GetItemTemplate(uint32 entry) +{ + ItemTemplateContainer::const_iterator itr = _itemTemplateStore.find(entry); + if (itr != _itemTemplateStore.end()) + return &(itr->second); + + return NULL; } void ObjectMgr::LoadVehicleTemplateAccessories() @@ -3252,87 +3133,6 @@ void ObjectMgr::LoadPlayerInfo() } } - // Loading levels data (class only dependent) - sLog->outInfo(LOG_FILTER_GENERAL, "Loading Player Create Level HP/Mana Data..."); - { - uint32 oldMSTime = getMSTime(); - - // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats"); - - if (!result) - { - sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 level health/mana definitions. DB table `game_event_condition` is empty."); - - exit(1); - } - - uint32 count = 0; - - do - { - Field* fields = result->Fetch(); - - uint32 current_class = fields[0].GetUInt8(); - if (current_class >= MAX_CLASSES) - { - sLog->outError(LOG_FILTER_SQL, "Wrong class %u in `player_classlevelstats` table, ignoring.", current_class); - continue; - } - - uint8 current_level = fields[1].GetUInt8(); // Can't be > than STRONG_MAX_LEVEL (hardcoded level maximum) due to var type - if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - sLog->outInfo(LOG_FILTER_GENERAL, "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_classlevelstats` table, ignoring.", current_level); - ++count; // make result loading percent "expected" correct in case disabled detail mode for example. - continue; - } - - PlayerClassInfo* pClassInfo = &_playerClassInfo[current_class]; - - if (!pClassInfo->levelInfo) - pClassInfo->levelInfo = new PlayerClassLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)]; - - PlayerClassLevelInfo* pClassLevelInfo = &pClassInfo->levelInfo[current_level-1]; - - pClassLevelInfo->basehealth = fields[2].GetUInt16(); - pClassLevelInfo->basemana = fields[3].GetUInt16(); - - ++count; - } - while (result->NextRow()); - - // Fill gaps and check integrity - for (int class_ = 0; class_ < MAX_CLASSES; ++class_) - { - // skip non existed classes - if (!sChrClassesStore.LookupEntry(class_)) - continue; - - PlayerClassInfo* pClassInfo = &_playerClassInfo[class_]; - - // fatal error if no level 1 data - if (!pClassInfo->levelInfo || pClassInfo->levelInfo[0].basehealth == 0) - { - sLog->outError(LOG_FILTER_SQL, "Class %i Level 1 does not have health/mana data!", class_); - exit(1); - } - - // fill level gaps - for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) - { - if (pClassInfo->levelInfo[level].basehealth == 0) - { - sLog->outError(LOG_FILTER_SQL, "Class %i Level %i does not have health/mana data. Using stats data of level %i.", class_, level+1, level); - pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level-1]; - } - } - } - - sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u level health/mana definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - - } - // Loading levels data (class/race dependent) sLog->outInfo(LOG_FILTER_GENERAL, "Loading Player Create Level Stats Data..."); { @@ -3507,17 +3307,25 @@ void ObjectMgr::LoadPlayerInfo() } } -void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint8 level, PlayerClassLevelInfo* info) const +void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32& baseHP, uint32& baseMana) const { if (level < 1 || class_ >= MAX_CLASSES) return; - PlayerClassInfo const* pInfo = &_playerClassInfo[class_]; - if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)) level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); - *info = pInfo->levelInfo[level-1]; + GtOCTBaseHPByClassEntry const* hp = sGtOCTBaseHPByClassStore.LookupEntry((class_-1) * GT_MAX_LEVEL + level-1); + GtOCTBaseMPByClassEntry const* mp = sGtOCTBaseMPByClassStore.LookupEntry((class_-1) * GT_MAX_LEVEL + level-1); + + if (!hp || !mp) + { + sLog->outError(LOG_FILTER_GENERAL, "Tried to get non-existant Class-Level combination data for base hp/mp. Class %u Level %u", class_, level); + return; + } + + baseHP = uint32(hp->ratio); + baseMana = uint32(mp->ratio); } void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo* info) const @@ -3629,33 +3437,37 @@ void ObjectMgr::LoadQuests() "RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, " // 21 22 23 24 25 26 27 28 29 30 31 "PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, " - // 32 33 34 35 36 37 38 39 40 41 42 - "RewardMailTemplateId, RewardMailDelay, SourceItemId, SourceItemCount, SourceSpellId, Flags, SpecialFlags, RewardTitleId, RequiredPlayerKills, RewardTalents, RewardArenaPoints, " - // 43 44 45 46 47 48 49 50 - "RewardItemId1, RewardItemId2, RewardItemId3, RewardItemId4, RewardItemCount1, RewardItemCount2, RewardItemCount3, RewardItemCount4, " - // 51 52 53 54 55 56 57 58 59 60 61 62 + // 32 33 34 35 36 37 38 39 40 41 42 43 + "RewardMailTemplateId, RewardMailDelay, SourceItemId, SourceItemCount, SourceSpellId, Flags, SpecialFlags, MinimapTargetMark, RewardTitleId, RequiredPlayerKills, RewardTalents, RewardArenaPoints, " + // 44 45 46 47 48 49 50 51 52 53 54 55 56 + "RewardSkillId, RewardSkillPoints, RewardReputationMask, QuestGiverPortrait, QuestTurnInPortrait, RewardItemId1, RewardItemId2, RewardItemId3, RewardItemId4, RewardItemCount1, RewardItemCount2, RewardItemCount3, RewardItemCount4, " + // 57 58 59 60 61 62 63 64 65 66 67 68 "RewardChoiceItemId1, RewardChoiceItemId2, RewardChoiceItemId3, RewardChoiceItemId4, RewardChoiceItemId5, RewardChoiceItemId6, RewardChoiceItemCount1, RewardChoiceItemCount2, RewardChoiceItemCount3, RewardChoiceItemCount4, RewardChoiceItemCount5, RewardChoiceItemCount6, " - // 63 64 65 66 67 68 69 70 71 72 + // 69 70 71 72 73 74 75 76 77 78 "RewardFactionId1, RewardFactionId2, RewardFactionId3, RewardFactionId4, RewardFactionId5, RewardFactionValueId1, RewardFactionValueId2, RewardFactionValueId3, RewardFactionValueId4, RewardFactionValueId5, " - // 73 74 75 76 77 + // 79 80 81 82 83 "RewardFactionValueIdOverride1, RewardFactionValueIdOverride2, RewardFactionValueIdOverride3, RewardFactionValueIdOverride4, RewardFactionValueIdOverride5, " - // 78 79 80 81 - "PointMapId, PointX, PointY, PointOption, " - // 82 83 84 85 86 87 88 - "Title, Objectives, Details, EndText, OfferRewardText, RequestItemsText, CompletedText, " - // 89 90 91 92 93 94 95 96 + // 84 85 86 87 88 89 90 91 92 93 94 + "PointMapId, PointX, PointY, PointOption, Title, Objectives, Details, EndText, CompletedText, OfferRewardText, RequestItemsText, " + // 95 96 97 98 99 100 101 102 "RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, " - // 97 98 99 100 101 102 103 104 + // 103 104 105 106 107 108 109 110 "RequiredSourceItemId1, RequiredSourceItemId2, RequiredSourceItemId3, RequiredSourceItemId4, RequiredSourceItemCount1, RequiredSourceItemCount2, RequiredSourceItemCount3, RequiredSourceItemCount4, " - // 105 106 107 108 109 110 111 112 113 114 115 116 + // 111 112 113 114 115 116 117 118 119 120 121 122 "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, " - // 117 118 119 120 121 122 123 124 125 - "RequiredSpellCast1, RequiredSpellCast2, RequiredSpellCast3, RequiredSpellCast4, Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, " - // 126 127 128 129 130 131 132 133 134 135 + // 123 124 125 126 127 128 129 130 131 + "RequiredSpell, RequiredSpellCast1, RequiredSpellCast2, RequiredSpellCast3, RequiredSpellCast4, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, " + // 132 133 134 135 136 137 138 139 + "RewardCurrencyId1, RewardCurrencyId2, RewardCurrencyId3, RewardCurrencyId4, RewardCurrencyCount1, RewardCurrencyCount2, RewardCurrencyCount3, RewardCurrencyCount4, " + // 140 141 142 143 144 145 146 147 + "RequiredCurrencyId1, RequiredCurrencyId2, RequiredCurrencyId3, RequiredCurrencyId4, RequiredCurrencyCount1, RequiredCurrencyCount2, RequiredCurrencyCount3, RequiredCurrencyCount4, " + // 148 149 150 151 152 153 + "QuestGiverTextWindow, QuestGiverTargetName, QuestTurnTextWindow, QuestTurnTargetName, SoundAccept, SoundTurnIn, " + // 154 155 156 157 158 159 160 161 162 163 "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, EmoteOnIncomplete, EmoteOnComplete, " - // 136 137 138 139 140 141 142 143 + // 164 165 166 167 168 169 170 171 "OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4, " - // 144 145 146 + // 172 173 174 "StartScript, CompleteScript, WDBVerified" " FROM quest_template"); if (!result) @@ -3946,7 +3758,7 @@ void ObjectMgr::LoadQuests() qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest } } - else if (qinfo->RequiredItemCount[j]>0) + else if (qinfo->RequiredItemCount[j] > 0) { sLog->outError(LOG_FILTER_SQL, "Quest %u has `RequiredItemId%d` = 0 but `RequiredItemCount%d` = %u, quest can't be done.", qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredItemCount[j]); @@ -4224,6 +4036,161 @@ void ObjectMgr::LoadQuests() qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId()); } + for (uint8 j = 0; j < QUEST_REWARD_CURRENCY_COUNT; ++j) + { + uint32 currency = qinfo->RewardCurrencyId[j]; + if (currency) + { + if (qinfo->RewardCurrencyCount[j] == 0) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardCurrencyId%d` = %u but `RewardCurrencyCount%d` = 0, quest can't be done.", + qinfo->GetQuestId(), j+1, currency, j+1); + // no changes, quest can't be done for this requirement + } + + /* TODO: Re-enable once currency dbc getters are implemented + if (!sObjectMgr->GetCurrency(currency)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardCurrencyId%d` = %u but currency with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(), j+1, currency, currency); + qinfo->RewardCurrencyCount[j] = 0; // prevent incorrect work of quest + }*/ + } + else if (qinfo->RewardCurrencyCount[j] > 0) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardCurrencyId%d` = 0 but `RewardCurrencyCount%d` = %u, quest can't be done.", + qinfo->GetQuestId(), j+1, j+1, qinfo->RewardCurrencyCount[j]); + qinfo->RewardCurrencyCount[j] = 0; // prevent incorrect work of quest + } + } + + for (uint8 j = 0; j < QUEST_REQUIRED_CURRENCY_COUNT; ++j) + { + uint32 currency = qinfo->RequiredCurrencyId[j]; + if (currency) + { + if (qinfo->RequiredCurrencyCount[j] == 0) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RequiredCurrencyId%d` = %u but `RequiredCurrencyCount%d` = 0, quest can't be done.", + qinfo->GetQuestId(), j+1, currency, j+1); + // no changes, quest can't be done for this requirement + } + + /* TODO: Re-enable once currency dbc getters are implemented + if (!sObjectMgr->GetCurrency(currency)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RequiredCurrencyId%d` = %u but currency with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(), j+1, currency, currency); + qinfo->RequiredCurrencyCount[j] = 0; // prevent incorrect work of quest + }*/ + } + else if (qinfo->RequiredCurrencyCount[j] > 0) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RequiredCurrencyId%d` = 0 but `RequiredCurrencyCount%d` = %u, quest can't be done.", + qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredCurrencyCount[j]); + qinfo->RequiredCurrencyCount[j] = 0; // prevent incorrect work of quest + } + } + + if (qinfo->SoundAccept) + { + if (!sSoundEntriesStore.LookupEntry(qinfo->SoundAccept)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `SoundAccept` = %u but sound %u does not exist, set to 0.", + qinfo->GetQuestId(), qinfo->SoundAccept, qinfo->SoundAccept); + qinfo->SoundAccept = 0; // no sound will be played + } + } + + if (qinfo->SoundTurnIn) + { + if (!sSoundEntriesStore.LookupEntry(qinfo->SoundTurnIn)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `SoundTurnIn` = %u but sound %u does not exist, set to 0.", + qinfo->GetQuestId(), qinfo->SoundTurnIn, qinfo->SoundTurnIn); + qinfo->SoundTurnIn = 0; // no sound will be played + } + } + + if (qinfo->RequiredSpell > 0) + { + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RequiredSpell); + + if (!spellInfo) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RequiredSpell` = %u but spell %u does not exist, quest will not require a spell.", + qinfo->GetQuestId(), qinfo->RequiredSpell, qinfo->RequiredSpell); + qinfo->RequiredSpell = 0; // no spell will be required + } + + else if (!SpellMgr::IsSpellValid(spellInfo)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RequiredSpell` = %u but spell %u is broken, quest will not require a spell.", + qinfo->GetQuestId(), qinfo->RequiredSpell, qinfo->RequiredSpell); + qinfo->RequiredSpell = 0; // no spell will be required + } + + /* Can we require talents? + else if (GetTalentSpellCost(qinfo->RewardSpellCast)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.", + qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast); + qinfo->RewardSpellCast = 0; // no spell will be casted on player + } + }*/ + } + + if (qinfo->RewardSkillId) + { + if (!sSkillLineStore.LookupEntry(qinfo->RewardSkillId)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardSkillId` = %u but this skill does not exist", + qinfo->GetQuestId(), qinfo->RewardSkillId); + } + if (!qinfo->RewardSkillPoints) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardSkillId` = %u but `RewardSkillPoints` is 0", + qinfo->GetQuestId(), qinfo->RewardSkillId); + } + } + + if (qinfo->RewardSkillPoints) + { + if (qinfo->RewardSkillPoints > sWorld->GetConfigMaxSkillValue()) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardSkillPoints` = %u but max possible skill is %u, quest can't be done.", + qinfo->GetQuestId(), qinfo->RewardSkillPoints, sWorld->GetConfigMaxSkillValue()); + // no changes, quest can't be done for this requirement + } + if (!qinfo->RewardSkillId) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `RewardSkillPoints` = %u but `RewardSkillId` is 0", + qinfo->GetQuestId(), qinfo->RewardSkillPoints); + } + } + + if (qinfo->QuestGiverPortrait) + { + if (!sObjectMgr->GetCreatureTemplate(qinfo->QuestGiverPortrait)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `QuestGiverPortrait` = %u but creature with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(), qinfo->QuestGiverPortrait, qinfo->QuestGiverPortrait); + qinfo->QuestGiverPortrait = 0; + } + } + + if (qinfo->QuestTurnInPortrait) + { + if (!sObjectMgr->GetCreatureTemplate(qinfo->QuestTurnInPortrait)) + { + sLog->outError(LOG_FILTER_SQL, "Quest %u has `QuestTurnInPortrait` = %u but creature with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(), qinfo->QuestTurnInPortrait, qinfo->QuestTurnInPortrait); + qinfo->QuestTurnInPortrait = 0; + } + } + + + // fill additional data stores if (qinfo->PrevQuestId) { @@ -4300,14 +4267,14 @@ void ObjectMgr::LoadQuestLocales() _questLocaleStore.clear(); // need for reload case QueryResult result = WorldDatabase.Query("SELECT entry, " - "Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, " - "Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, " - "Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, " - "Title_loc4, Details_loc4, Objectives_loc4, OfferRewardText_loc4, RequestItemsText_loc4, EndText_loc4, CompletedText_loc4, ObjectiveText1_loc4, ObjectiveText2_loc4, ObjectiveText3_loc4, ObjectiveText4_loc4, " - "Title_loc5, Details_loc5, Objectives_loc5, OfferRewardText_loc5, RequestItemsText_loc5, EndText_loc5, CompletedText_loc5, ObjectiveText1_loc5, ObjectiveText2_loc5, ObjectiveText3_loc5, ObjectiveText4_loc5, " - "Title_loc6, Details_loc6, Objectives_loc6, OfferRewardText_loc6, RequestItemsText_loc6, EndText_loc6, CompletedText_loc6, ObjectiveText1_loc6, ObjectiveText2_loc6, ObjectiveText3_loc6, ObjectiveText4_loc6, " - "Title_loc7, Details_loc7, Objectives_loc7, OfferRewardText_loc7, RequestItemsText_loc7, EndText_loc7, CompletedText_loc7, ObjectiveText1_loc7, ObjectiveText2_loc7, ObjectiveText3_loc7, ObjectiveText4_loc7, " - "Title_loc8, Details_loc8, Objectives_loc8, OfferRewardText_loc8, RequestItemsText_loc8, EndText_loc8, CompletedText_loc8, ObjectiveText1_loc8, ObjectiveText2_loc8, ObjectiveText3_loc8, ObjectiveText4_loc8" + "Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, QuestGiverTextWindow_loc1, QuestGiverTargetName_loc1, QuestTurnTextWindow_loc1, QuestTurnTargetName_loc1," + "Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, QuestGiverTextWindow_loc2, QuestGiverTargetName_loc2, QuestTurnTextWindow_loc2, QuestTurnTargetName_loc2," + "Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, QuestGiverTextWindow_loc3, QuestGiverTargetName_loc3, QuestTurnTextWindow_loc3, QuestTurnTargetName_loc3," + "Title_loc4, Details_loc4, Objectives_loc4, OfferRewardText_loc4, RequestItemsText_loc4, EndText_loc4, CompletedText_loc4, ObjectiveText1_loc4, ObjectiveText2_loc4, ObjectiveText3_loc4, ObjectiveText4_loc4, QuestGiverTextWindow_loc4, QuestGiverTargetName_loc4, QuestTurnTextWindow_loc4, QuestTurnTargetName_loc4," + "Title_loc5, Details_loc5, Objectives_loc5, OfferRewardText_loc5, RequestItemsText_loc5, EndText_loc5, CompletedText_loc5, ObjectiveText1_loc5, ObjectiveText2_loc5, ObjectiveText3_loc5, ObjectiveText4_loc5, QuestGiverTextWindow_loc5, QuestGiverTargetName_loc5, QuestTurnTextWindow_loc5, QuestTurnTargetName_loc5," + "Title_loc6, Details_loc6, Objectives_loc6, OfferRewardText_loc6, RequestItemsText_loc6, EndText_loc6, CompletedText_loc6, ObjectiveText1_loc6, ObjectiveText2_loc6, ObjectiveText3_loc6, ObjectiveText4_loc6, QuestGiverTextWindow_loc6, QuestGiverTargetName_loc6, QuestTurnTextWindow_loc6, QuestTurnTargetName_loc6," + "Title_loc7, Details_loc7, Objectives_loc7, OfferRewardText_loc7, RequestItemsText_loc7, EndText_loc7, CompletedText_loc7, ObjectiveText1_loc7, ObjectiveText2_loc7, ObjectiveText3_loc7, ObjectiveText4_loc7, QuestGiverTextWindow_loc7, QuestGiverTargetName_loc7, QuestTurnTextWindow_loc7, QuestTurnTargetName_loc7," + "Title_loc8, Details_loc8, Objectives_loc8, OfferRewardText_loc8, RequestItemsText_loc8, EndText_loc8, CompletedText_loc8, ObjectiveText1_loc8, ObjectiveText2_loc8, ObjectiveText3_loc8, ObjectiveText4_loc8, QuestGiverTextWindow_loc8, QuestGiverTargetName_loc8, QuestTurnTextWindow_loc8, QuestTurnTargetName_loc8" " FROM locales_quest"); if (!result) @@ -4325,16 +4292,21 @@ void ObjectMgr::LoadQuestLocales() { LocaleConstant locale = (LocaleConstant) i; - AddLocaleString(fields[1 + 11 * (i - 1)].GetString(), locale, data.Title); - AddLocaleString(fields[1 + 11 * (i - 1) + 1].GetString(), locale, data.Details); - AddLocaleString(fields[1 + 11 * (i - 1) + 2].GetString(), locale, data.Objectives); - AddLocaleString(fields[1 + 11 * (i - 1) + 3].GetString(), locale, data.OfferRewardText); - AddLocaleString(fields[1 + 11 * (i - 1) + 4].GetString(), locale, data.RequestItemsText); - AddLocaleString(fields[1 + 11 * (i - 1) + 5].GetString(), locale, data.EndText); - AddLocaleString(fields[1 + 11 * (i - 1) + 6].GetString(), locale, data.CompletedText); + AddLocaleString(fields[1 + 15 * (i - 1)].GetString(), locale, data.Title); + AddLocaleString(fields[1 + 15 * (i - 1) + 1].GetString(), locale, data.Details); + AddLocaleString(fields[1 + 15 * (i - 1) + 2].GetString(), locale, data.Objectives); + AddLocaleString(fields[1 + 15 * (i - 1) + 3].GetString(), locale, data.OfferRewardText); + AddLocaleString(fields[1 + 15 * (i - 1) + 4].GetString(), locale, data.RequestItemsText); + AddLocaleString(fields[1 + 15 * (i - 1) + 5].GetString(), locale, data.EndText); + AddLocaleString(fields[1 + 15 * (i - 1) + 6].GetString(), locale, data.CompletedText); for (uint8 k = 0; k < 4; ++k) - AddLocaleString(fields[1 + 11 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveText[k]); + AddLocaleString(fields[1 + 15 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveText[k]); + + AddLocaleString(fields[1 + 15 * (i - 1) + 11].GetString(), locale, data.QuestGiverTextWindow); + AddLocaleString(fields[1 + 15 * (i - 1) + 12].GetString(), locale, data.QuestGiverTargetName); + AddLocaleString(fields[1 + 15 * (i - 1) + 13].GetString(), locale, data.QuestTurnTextWindow); + AddLocaleString(fields[1 + 15 * (i - 1) + 14].GetString(), locale, data.QuestTurnTargetName); } } while (result->NextRow()); @@ -5076,7 +5048,7 @@ void ObjectMgr::LoadInstanceEncounters() if (lastEncounterDungeon && !sLFGDungeonStore.LookupEntry(lastEncounterDungeon)) { - sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon); + sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName, lastEncounterDungeon); continue; } @@ -5085,7 +5057,7 @@ void ObjectMgr::LoadInstanceEncounters() { if (itr != dungeonLastBosses.end()) { - sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName[0], itr->second->id, itr->second->encounterName[0]); + sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName, itr->second->id, itr->second->encounterName); continue; } @@ -5099,7 +5071,7 @@ void ObjectMgr::LoadInstanceEncounters() CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry); if (!creatureInfo) { - sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an invalid creature (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]); + sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an invalid creature (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName); continue; } const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS; @@ -5108,12 +5080,12 @@ void ObjectMgr::LoadInstanceEncounters() case ENCOUNTER_CREDIT_CAST_SPELL: if (!sSpellMgr->GetSpellInfo(creditEntry)) { - sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an invalid spell (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]); + sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an invalid spell (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName); continue; } break; default: - sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an invalid credit type (%u) for encounter %u (%s), skipped!", creditType, entry, dungeonEncounter->encounterName[0]); + sLog->outError(LOG_FILTER_SQL, "Table `instance_encounters` has an invalid credit type (%u) for encounter %u (%s), skipped!", creditType, entry, dungeonEncounter->encounterName); continue; } @@ -5286,7 +5258,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) bool has_items = fields[4].GetBool(); m->expire_time = time_t(fields[5].GetUInt32()); m->deliver_time = 0; - m->COD = fields[6].GetUInt32(); + m->COD = fields[6].GetUInt64(); m->checked = fields[7].GetUInt8(); m->mailTemplateId = fields[8].GetInt16(); @@ -6152,6 +6124,10 @@ void ObjectMgr::SetHighestGuids() result = CharacterDatabase.Query("SELECT MAX(guid) FROM groups"); if (result) sGroupMgr->SetGroupDbStoreSize((*result)[0].GetUInt32()+1); + + result = CharacterDatabase.Query("SELECT MAX(itemId) from void_storage"); + if (result) + _voidItemId = (*result)[0].GetUInt64()+1; } uint32 ObjectMgr::GenerateAuctionID() @@ -6339,8 +6315,10 @@ void ObjectMgr::LoadGameObjectTemplate() QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, faction, flags, size, questItem1, questItem2, questItem3, " // 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 "questItem4, questItem5, questItem6, data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, " - // 29 30 31 32 33 34 35 36 37 38 39 40 41 - "data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, AIName, ScriptName " + // 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 + "data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, data24, data25, data26, data27, data28, " + // 45 46 47 48 49 50 + "data29, data30, data31, unkInt32, AIName, ScriptName " "FROM gameobject_template"); if (!result) @@ -6375,10 +6353,11 @@ void ObjectMgr::LoadGameObjectTemplate() got.questItems[i] = fields[10 + i].GetUInt32(); for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i) - got.raw.data[i] = fields[16 + i].GetInt32(); // data1 and data6 can be -1 + got.raw.data[i] = fields[16 + i].GetUInt32(); - got.AIName = fields[40].GetString(); - got.ScriptId = GetScriptId(fields[41].GetCString()); + got.unkInt32 = fields[48].GetInt32(); + got.AIName = fields[49].GetString(); + got.ScriptId = GetScriptId(fields[50].GetCString()); // Checks @@ -6616,7 +6595,7 @@ std::string ObjectMgr::GeneratePetName(uint32 entry) if (list0.empty() || list1.empty()) { CreatureTemplate const* cinfo = GetCreatureTemplate(entry); - char* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale()); + const char* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale()); if (!petname) return cinfo->Name; @@ -6631,8 +6610,16 @@ uint32 ObjectMgr::GeneratePetNumber() return ++_hiPetNumber; } +uint64 ObjectMgr::GenerateVoidStorageItemId() +{ + return ++_voidItemId; +} + void ObjectMgr::LoadCorpses() { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0 + uint32 oldMSTime = getMSTime(); PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES)); @@ -6648,7 +6635,7 @@ void ObjectMgr::LoadCorpses() { Field* fields = result->Fetch(); uint32 guid = fields[16].GetUInt32(); - CorpseType type = CorpseType(fields[13].GetUInt8()); + CorpseType type = CorpseType(fields[12].GetUInt8()); if (type >= MAX_CORPSE_TYPE) { sLog->outError(LOG_FILTER_GENERAL, "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type); @@ -8366,7 +8353,7 @@ void ObjectMgr::LoadScriptNames() "UNION " "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' " "UNION " - "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' " + "SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' " "UNION " "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " "UNION " @@ -8499,7 +8486,7 @@ void ObjectMgr::LoadCreatureClassLevelStats() { uint32 oldMSTime = getMSTime(); - QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor FROM creature_classlevelstats"); + QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basehp3, basemana, basearmor FROM creature_classlevelstats"); if (!result) { @@ -8519,10 +8506,10 @@ void ObjectMgr::LoadCreatureClassLevelStats() CreatureBaseStats stats; for (uint8 i = 0; i < MAX_CREATURE_BASE_HP; ++i) - stats.BaseHealth[i] = fields[i + 2].GetInt16(); + stats.BaseHealth[i] = fields[i + 2].GetUInt32(); - stats.BaseMana = fields[5].GetInt16(); - stats.BaseArmor = fields[6].GetInt16(); + stats.BaseMana = fields[5].GetUInt32(); + stats.BaseArmor = fields[6].GetUInt32(); if (!Class || ((1 << (Class - 1)) & CLASSMASK_ALL_CREATURES) == 0) sLog->outError(LOG_FILTER_SQL, "Creature base stats for level %u has invalid class %u", Level, Class); @@ -8704,6 +8691,39 @@ void ObjectMgr::LoadFactionChangeReputations() } +void ObjectMgr::LoadHotfixData() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT entry, type, UNIX_TIMESTAMP(hotfixDate) FROM hotfix_data"); + + if (!result) + { + sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded 0 hotfix info entries. DB table `hotfix_data` is empty."); + return; + } + + uint32 count = 0; + + _hotfixData.reserve(result->GetRowCount()); + + do + { + Field* fields = result->Fetch(); + + HotfixInfo info; + info.Entry = fields[0].GetUInt32(); + info.Type = fields[1].GetUInt32(); + info.Timestamp = fields[2].GetUInt64(); + + _hotfixData.push_back(info); + ++count; + } + while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_GENERAL, ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) { GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 59bb2fb536f..7850eda6c83 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -389,7 +389,6 @@ typedef UNORDERED_MAP<uint32, GameObjectData> GameObjectDataContainer; typedef UNORDERED_MAP<uint32, CreatureLocale> CreatureLocaleContainer; typedef UNORDERED_MAP<uint32, GameObjectLocale> GameObjectLocaleContainer; typedef UNORDERED_MAP<uint32, ItemLocale> ItemLocaleContainer; -typedef UNORDERED_MAP<uint32, ItemSetNameLocale> ItemSetNameLocaleContainer; typedef UNORDERED_MAP<uint32, QuestLocale> QuestLocaleContainer; typedef UNORDERED_MAP<uint32, NpcTextLocale> NpcTextLocaleContainer; typedef UNORDERED_MAP<uint32, PageTextLocale> PageTextLocaleContainer; @@ -578,6 +577,15 @@ struct DungeonEncounter typedef std::list<DungeonEncounter const*> DungeonEncounterList; typedef UNORDERED_MAP<uint32, DungeonEncounterList> DungeonEncounterContainer; +struct HotfixInfo +{ + uint32 Type; + uint32 Timestamp; + uint32 Entry; +}; + +typedef std::vector<HotfixInfo> HotfixData; + class PlayerDumpReader; class ObjectMgr @@ -631,25 +639,11 @@ class ObjectMgr ItemTemplate const* GetItemTemplate(uint32 entry); ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; } - ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId) - { - ItemSetNameContainer::iterator itr = _itemSetNameStore.find(itemId); - if (itr != _itemSetNameStore.end()) - return &itr->second; - return NULL; - } - InstanceTemplate const* GetInstanceTemplate(uint32 mapId); PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint8 level) const; - PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const - { - if (class_ >= MAX_CLASSES) - return NULL; - return &_playerClassInfo[class_]; - } - void GetPlayerClassLevelInfo(uint32 class_, uint8 level, PlayerClassLevelInfo* info) const; + void GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32& baseHP, uint32& baseMana) const; PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const { @@ -858,9 +852,9 @@ class ObjectMgr void LoadGameObjectLocales(); void LoadGameobjects(); void LoadItemTemplates(); + void LoadItemTemplateAddon(); + void LoadItemScriptNames(); void LoadItemLocales(); - void LoadItemSetNames(); - void LoadItemSetNameLocales(); void LoadQuestLocales(); void LoadNpcTextLocales(); void LoadPageTextLocales(); @@ -930,6 +924,7 @@ class ObjectMgr uint64 GenerateEquipmentSetGuid(); uint32 GenerateMailID(); uint32 GeneratePetNumber(); + uint64 GenerateVoidStorageItemId(); typedef std::multimap<int32, uint32> ExclusiveQuestGroups; ExclusiveQuestGroups mExclusiveQuestGroups; @@ -984,12 +979,6 @@ class ObjectMgr if (itr == _itemLocaleStore.end()) return NULL; return &itr->second; } - ItemSetNameLocale const* GetItemSetNameLocale(uint32 entry) const - { - ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry); - if (itr == _itemSetNameLocaleStore.end())return NULL; - return &itr->second; - } QuestLocale const* GetQuestLocale(uint32 entry) const { QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry); @@ -1145,6 +1134,19 @@ class ObjectMgr void LoadFactionChangeSpells(); void LoadFactionChangeReputations(); + void LoadHotfixData(); + HotfixData const& GetHotfixData() const { return _hotfixData; } + time_t GetHotfixDate(uint32 entry, uint32 type) const + { + time_t ret = 0; + for (HotfixData::const_iterator itr = _hotfixData.begin(); itr != _hotfixData.end(); ++itr) + if (itr->Entry == entry && itr->Type == type) + if (itr->Timestamp > ret) + ret = itr->Timestamp; + + return ret; + } + private: // first free id for selected id type uint32 _auctionId; @@ -1152,6 +1154,7 @@ class ObjectMgr uint32 _itemTextId; uint32 _mailId; uint32 _hiPetNumber; + uint64 _voidItemId; // first free low guid for selected guid type uint32 _hiCharGuid; @@ -1229,8 +1232,6 @@ class ObjectMgr // PetLevelInfoContainer[creature_id][level] PetLevelInfoContainer _petInfoStore; // [creature_id][level] - PlayerClassInfo _playerClassInfo[MAX_CLASSES]; - void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const; PlayerInfo _playerInfo[MAX_RACES][MAX_CLASSES]; @@ -1248,9 +1249,6 @@ class ObjectMgr HalfNameContainer _petHalfName0; HalfNameContainer _petHalfName1; - typedef UNORDERED_MAP<uint32, ItemSetNameEntry> ItemSetNameContainer; - ItemSetNameContainer _itemSetNameStore; - MapObjectGuids _mapObjectGuidsStore; CreatureDataContainer _creatureDataStore; CreatureTemplateContainer _creatureTemplateStore; @@ -1266,7 +1264,6 @@ class ObjectMgr ItemTemplateContainer _itemTemplateStore; ItemLocaleContainer _itemLocaleStore; - ItemSetNameLocaleContainer _itemSetNameLocaleStore; QuestLocaleContainer _questLocaleStore; NpcTextLocaleContainer _npcTextLocaleStore; PageTextLocaleContainer _pageTextLocaleStore; @@ -1287,6 +1284,7 @@ class ObjectMgr GO_TO_GO, GO_TO_CREATURE, // GO is dependant on creature }; + HotfixData _hotfixData; }; #define sObjectMgr ACE_Singleton<ObjectMgr, ACE_Null_Mutex>::instance() diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 072db578220..75df3e67c5a 100755 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -44,7 +44,7 @@ namespace Trinity std::set<Unit*> i_visibleNow; Player::ClientGUIDs vis_guids; - VisibleNotifier(Player &player) : i_player(player), vis_guids(player.m_clientGUIDs) {} + VisibleNotifier(Player &player) : i_player(player), i_data(player.GetMapId()), vis_guids(player.m_clientGUIDs) {} template<class T> void Visit(GridRefManager<T> &m); void SendToSelf(void); }; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 5ace6da2f44..34fa9f300ab 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -269,6 +269,37 @@ void Group::ConvertToRaid() player->UpdateForQuestWorldObjects(); } +void Group::ConvertToGroup() +{ + if (m_memberSlots.size() > 5) + return; // What message error should we send? + + m_groupType = GroupType(GROUPTYPE_NORMAL); + + if (m_subGroupsCounts) + { + delete[] m_subGroupsCounts; + m_subGroupsCounts = NULL;; + } + + if (!isBGGroup()) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE); + + stmt->setUInt8(0, uint8(m_groupType)); + stmt->setUInt32(1, m_dbStoreId); + + CharacterDatabase.Execute(stmt); + } + + SendUpdate(); + + // update quest related GO states (quest activity dependent from raid membership) + for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + if (Player* player = ObjectAccessor::FindPlayer(citr->guid)) + player->UpdateForQuestWorldObjects(); +} + bool Group::AddInvite(Player* player) { if (!player || player->GetGroupInvite()) @@ -442,7 +473,7 @@ bool Group::AddMember(Player* player) // Broadcast new player group member fields to rest of the group player->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER); - UpdateData groupData; + UpdateData groupData(player->GetMapId()); WorldPacket groupDataPacket; // Broadcast group members' fields to player @@ -453,7 +484,7 @@ bool Group::AddMember(Player* player) if (Player* member = itr->getSource()) { - if (player->HaveAtClient(member)) + if (player->HaveAtClient(member)) // must be on the same map, or shit will break { member->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER); member->BuildValuesUpdateBlockForPlayer(&groupData, player); @@ -462,7 +493,7 @@ bool Group::AddMember(Player* player) if (member->HaveAtClient(player)) { - UpdateData newData; + UpdateData newData(player->GetMapId()); WorldPacket newDataPacket; player->BuildValuesUpdateBlockForPlayer(&newData, member); member->SendDirectMessage(&newDataPacket); @@ -769,7 +800,7 @@ void Group::Disband(bool hideDestroy /* = false */) /*** LOOT SYSTEM ***/ /*********************************************************/ -void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) +void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r) { WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1)); data << uint64(r.itemGUID); // guid of rolled item @@ -779,8 +810,9 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r) data << uint32(r.itemRandomSuffix); // randomSuffix data << uint32(r.itemRandomPropId); // item random property ID data << uint32(r.itemCount); // items in stack - data << uint32(CountDown); // the countdown time to choose "need" or "greed" + data << uint32(countDown); // the countdown time to choose "need" or "greed" data << uint8(r.rollVoteMask); // roll type mask + data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it??? for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr) { @@ -811,6 +843,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, if (!canNeed) voteMask &= ~ROLL_FLAG_TYPE_NEED; data << uint8(voteMask); // roll type mask + data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it??? p->GetSession()->SendPacket(&data); } @@ -824,7 +857,7 @@ void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for data << uint32(roll.itemRandomSuffix); // randomSuffix data << uint32(roll.itemRandomPropId); // Item random property ID - data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number + data << uint32(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); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed @@ -848,7 +881,7 @@ void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumb data << uint32(roll.itemRandomSuffix); // randomSuffix data << uint32(roll.itemRandomPropId); // Item random property data << uint64(targetGuid); // guid of the player who won. - data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL + data << uint32(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) @@ -913,7 +946,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) item = sObjectMgr->GetItemTemplate(i->itemid); if (!item) { - //sLog->outDebug("Group::GroupLoot: missing item prototype for item with id: %d", i->itemid); + //sLog->outDebug(LOG_FILTER_GENERAL, "Group::GroupLoot: missing item prototype for item with id: %d", i->itemid); continue; } @@ -1000,7 +1033,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) item = sObjectMgr->GetItemTemplate(i->itemid); if (!item) { - //sLog->outDebug("Group::GroupLoot: missing item prototype for item with id: %d", i->itemid); + //sLog->outDebug(LOG_FILTER_GENERAL, "Group::GroupLoot: missing item prototype for item with id: %d", i->itemid); continue; } @@ -1197,11 +1230,11 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) void Group::MasterLoot(Loot* /*loot*/, WorldObject* pLootedObject) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "Group::MasterLoot (SMSG_LOOT_MASTER_LIST, 330)"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "Group::MasterLoot (SMSG_LOOT_MASTER_LIST)"); uint32 real_count = 0; - WorldPacket data(SMSG_LOOT_MASTER_LIST, 330); + WorldPacket data(SMSG_LOOT_MASTER_LIST, GetMembersCount()*8); data << (uint8)GetMembersCount(); for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) @@ -1322,7 +1355,7 @@ void Group::CountTheRoll(Rolls::iterator rollI) if (player && player->GetSession()) { - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul); ItemPosCountVec dest; LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]); @@ -1372,7 +1405,7 @@ void Group::CountTheRoll(Rolls::iterator rollI) if (player && player->GetSession()) { - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul); LootItem* item = &(roll->itemSlot >= roll->getLoot()->items.size() ? roll->getLoot()->quest_items[roll->itemSlot - roll->getLoot()->items.size()] : roll->getLoot()->items[roll->itemSlot]); @@ -1526,7 +1559,6 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) data << uint8(m_lootThreshold); // loot threshold data << uint8(m_dungeonDifficulty); // Dungeon Difficulty data << uint8(m_raidDifficulty); // Raid Difficulty - data << uint8(0); // 3.3 } player->GetSession()->SendPacket(&data); diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index e5f174c4230..f909b755829 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -113,7 +113,9 @@ enum GroupUpdateFlags GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras... - GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint32 vehicle_seat_id (index from VehicleSeat.dbc) + GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint8, uint64, if (uint32 != 0) { uint32, if (uint16 & 0x40) { uint32, uint32, uint32 } } + GROUP_UPDATE_FLAG_UNKNOWN_1 = 0x00100000, // uint32 + GROUP_UPDATE_FLAG_UNKNOWN_2 = 0x00200000, // uint32, uint32, string GROUP_UPDATE_PET = 0x0007FC00, // all pet flags GROUP_UPDATE_FULL = 0x0007FFFF, // all known flags }; @@ -239,6 +241,7 @@ class Group void ConvertToLFG(); void ConvertToRaid(); + void ConvertToGroup(); void SetBattlegroundGroup(Battleground* bg); GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4df77f874f3..66e0c968d2c 100755..100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -219,17 +219,6 @@ void Guild::RankInfo::SaveToDB(SQLTransaction& trans) const CharacterDatabase.ExecuteOrAppend(trans, stmt); } -void Guild::RankInfo::WritePacket(WorldPacket& data) const -{ - data << uint32(m_rights); - data << uint32(m_bankMoneyPerDay); // In game set in gold, in packet set in bronze. - for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i) - { - data << uint32(m_bankTabRightsAndSlots[i].rights); - data << uint32(m_bankTabRightsAndSlots[i].slots); - } -} - void Guild::RankInfo::SetName(const std::string& name) { if (m_name == name) @@ -620,35 +609,6 @@ bool Guild::Member::CheckStats() const return true; } -void Guild::Member::WritePacket(WorldPacket& data) const -{ - if (Player* player = FindPlayer()) - { - data << uint64(player->GetGUID()); - data << uint8(1); - data << player->GetName(); - data << uint32(m_rankId); - data << uint8(player->getLevel()); - data << uint8(player->getClass()); - data << uint8(0); // new 2.4.0 - data << uint32(player->GetZoneId()); - } - else - { - data << m_guid; - data << uint8(0); - data << m_name; - data << uint32(m_rankId); - data << uint8(m_level); - data << uint8(m_class); - data << uint8(0); // new 2.4.0 - data << uint32(m_zoneId); - data << float(float(::time(NULL) - m_logoutTime) / DAY); - } - data << m_publicNote; - data << m_officerNote; -} - // Decreases amount of money/slots left for today. // If (tabId == GUILD_BANK_MAX_TABS) decrease money amount. // Otherwise decrease remaining items amount for specified tab. @@ -1069,7 +1029,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap) /////////////////////////////////////////////////////////////////////////////// // Guild -Guild::Guild() : m_id(0), m_leaderGuid(0), m_createdDate(0), m_accountsNumber(0), m_bankMoney(0), m_eventLog(NULL) +Guild::Guild() : m_id(0), m_leaderGuid(0), m_createdDate(0), m_accountsNumber(0), m_bankMoney(0), m_eventLog(NULL), m_achievementMgr(this), m_level(1) { memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*)); } @@ -1144,6 +1104,8 @@ bool Guild::Create(Player* pLeader, const std::string& name) // Call scripts on successful create sScriptMgr->OnGuildCreate(this, pLeader, name); + _BroadcastEvent(GE_FOUNDER, m_leaderGuid); + return ret; } @@ -1202,18 +1164,95 @@ void Guild::Disband() // HANDLE CLIENT COMMANDS void Guild::HandleRoster(WorldSession* session /*= NULL*/) { + ByteBuffer memberData(100); // Guess size - WorldPacket data(SMSG_GUILD_ROSTER, (4 + m_motd.length() + 1 + m_info.length() + 1 + 4 + _GetRanksSize() * (4 + 4 + GUILD_BANK_MAX_TABS * (4 + 4)) + m_members.size() * 50)); - data << uint32(m_members.size()); - data << m_motd; - data << m_info; - - data << uint32(_GetRanksSize()); - for (Ranks::const_iterator ritr = m_ranks.begin(); ritr != m_ranks.end(); ++ritr) - ritr->WritePacket(data); + WorldPacket data(SMSG_GUILD_ROSTER, 100); + data.WriteBits(m_motd.length(), 11); + data.WriteBits(m_members.size(), 18); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - itr->second->WritePacket(data); + { + Member* member = itr->second; + Player* player = member->FindPlayer(); + size_t pubNoteLength = member->GetPublicNote().length(); + size_t offNoteLength = member->GetOfficerNote().length(); + + ObjectGuid guid = member->GetGUID(); + data.WriteBit(guid[3]); + data.WriteBit(guid[4]); + data.WriteBit(0); // unk + data.WriteBit(0); // unk + data.WriteBits(pubNoteLength, 8); + data.WriteBits(offNoteLength, 8); + data.WriteBit(guid[0]); + data.WriteBits(member->GetName().length(), 7); + data.WriteBit(guid[1]); + data.WriteBit(guid[2]); + data.WriteBit(guid[6]); + data.WriteBit(guid[5]); + data.WriteBit(guid[7]); + + uint8 flags = GUILDMEMBER_STATUS_NONE; + if (player) + { + flags |= GUILDMEMBER_STATUS_ONLINE; + if (player->isAFK()) + flags |= GUILDMEMBER_STATUS_AFK; + if (player->isDND()) + flags |= GUILDMEMBER_STATUS_DND; + } + + memberData << uint8(member->GetClass()); + memberData << int32(0); // unk + memberData.WriteByteSeq(guid[0]); + memberData << uint64(0); // weekly activity + memberData << uint32(member->GetRankId()); + memberData << uint32(0); // player->GetAchievementMgr().GetCompletedAchievementsAmount() + + // for (2 professions) + memberData << uint32(0) << uint32(0) << uint32(0); + memberData << uint32(0) << uint32(0) << uint32(0); + + memberData.WriteByteSeq(guid[2]); + memberData << uint8(flags); + memberData << uint32(player ? player->GetZoneId() : member->GetZone()); + memberData << uint64(0); // Total activity + memberData.WriteByteSeq(guid[7]); + memberData << uint32(0); // Remaining guild week Rep + + if (pubNoteLength) + memberData.append(member->GetPublicNote().c_str(), pubNoteLength); + + memberData.WriteByteSeq(guid[3]); + memberData << uint8(player ? player->getLevel() : member->GetLevel()); + memberData << int32(0); // unk + memberData.WriteByteSeq(guid[5]); + memberData.WriteByteSeq(guid[4]); + memberData << uint8(0); // unk + memberData.WriteByteSeq(guid[1]); + memberData << float(player ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / DAY); + + if (offNoteLength) + memberData.append(member->GetOfficerNote().c_str(), offNoteLength); + + memberData.WriteByteSeq(guid[6]); + memberData.append(member->GetName().c_str(), member->GetName().length()); + } + + size_t infoLength = m_info.length(); + data.WriteBits(infoLength, 12); + + data.FlushBits(); + data.append(memberData); + + if (infoLength) + data.append(m_info.c_str(), infoLength); + + data.append(m_motd.c_str(), m_motd.length()); + data << uint32(0); + data << uint32(0); + data << uint32(0); + data << uint32(0); if (session) session->SendPacket(&data); @@ -1225,9 +1264,11 @@ void Guild::HandleRoster(WorldSession* session /*= NULL*/) void Guild::HandleQuery(WorldSession* session) { WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, 8 * 32 + 200); // Guess size - data << uint32(m_id); + + data << uint64(GetGUID()); data << m_name; + // Rank name for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i) // Always show 10 ranks { if (i < _GetRanksSize()) @@ -1236,13 +1277,71 @@ void Guild::HandleQuery(WorldSession* session) data << uint8(0); // Empty string } + // Rank order of creation + for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i) + { + if (i < _GetRanksSize()) + data << uint32(i); + else + data << uint32(0); + } + + // Rank order of "importance" (sorting by rights) + for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i) + { + if (i < _GetRanksSize()) + data << uint32(m_ranks[i].GetId()); + else + data << uint32(0); + } + m_emblemInfo.WritePacket(data); - data << uint32(_GetRanksSize()); // Amount of ranks + + data << uint32(_GetRanksSize()); // Number of ranks used + session->SendPacket(&data); sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)"); } +void Guild::HandleGuildRanks(WorldSession* session) +{ + // perhaps move to guild.cpp..... + ByteBuffer rankData(100); + WorldPacket data(SMSG_GUILD_RANK, 100); + + data.WriteBits(_GetRanksSize(), 18); + + for (uint8 i = 0; i < _GetRanksSize(); i++) + { + RankInfo* rankInfo = GetRankInfo(i); + if (!rankInfo) + continue; + + data.WriteBits(rankInfo->GetName().length(), 7); + + rankData << uint32(i); + + for (uint8 j = 0; j < GUILD_BANK_MAX_TABS; ++j) + { + rankData << uint32(rankInfo->GetBankTabSlotsPerDay(j)); + rankData << uint32(rankInfo->GetBankTabRights(j)); + } + + rankData << uint32(rankInfo->GetBankMoneyPerDay()); + rankData << uint32(rankInfo->GetRights()); + + if (rankInfo->GetName().length()) + rankData.append(rankInfo->GetName().c_str(), rankInfo->GetName().length()); + + rankData << uint32(rankInfo->GetId()); + } + + data.FlushBits(); + data.append(rankData); + session->SendPacket(&data); +} + void Guild::HandleSetMOTD(WorldSession* session, const std::string& motd) { if (m_motd == motd) @@ -1250,7 +1349,7 @@ void Guild::HandleSetMOTD(WorldSession* session, const std::string& motd) // Player must have rights to set MOTD if (!_HasRankRight(session->GetPlayer(), GR_RIGHT_SETMOTD)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); else { m_motd = motd; @@ -1273,7 +1372,7 @@ void Guild::HandleSetInfo(WorldSession* session, const std::string& info) // Player must have rights to set guild's info if (!_HasRankRight(session->GetPlayer(), GR_RIGHT_MODIFY_GUILD_INFO)) - SendCommandResult(session, GUILD_CREATE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_CREATE, ERR_GUILD_PERMISSIONS); else { m_info = info; @@ -1293,12 +1392,12 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo) if (!_IsLeader(player)) // "Only guild leaders can create emblems." SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTGUILDMASTER); - else if (!player->HasEnoughMoney(EMBLEM_PRICE)) + else if (!player->HasEnoughMoney(uint64(EMBLEM_PRICE))) // "You can't afford to do that." SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTENOUGHMONEY); else { - player->ModifyMoney(-int32(EMBLEM_PRICE)); + player->ModifyMoney(-int64(EMBLEM_PRICE)); m_emblemInfo = emblemInfo; m_emblemInfo.SaveToDB(m_id); @@ -1315,7 +1414,7 @@ void Guild::HandleSetLeader(WorldSession* session, const std::string& name) Player* player = session->GetPlayer(); // Only leader can assign new leader if (!_IsLeader(player)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); // Old leader must be a member of guild else if (Member* pOldLeader = GetMember(player->GetGUID())) { @@ -1328,7 +1427,7 @@ void Guild::HandleSetLeader(WorldSession* session, const std::string& name) } } else - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); } void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, const std::string& name, const std::string& icon) @@ -1341,27 +1440,26 @@ void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, const std:: } } -void Guild::HandleSetMemberNote(WorldSession* session, const std::string& name, const std::string& note, bool officer) +void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic) { // Player must have rights to set public/officer note - if (!_HasRankRight(session->GetPlayer(), officer ? GR_RIGHT_EOFFNOTE : GR_RIGHT_EPNOTE)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - // Noted player must be a member of guild - else if (Member* member = GetMember(session, name)) + if (!_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE)) + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); + else if (Member* member = GetMember(guid)) { - if (officer) - member->SetOfficerNote(note); - else + if (isPublic) member->SetPublicNote(note); + else + member->SetOfficerNote(note); HandleRoster(session); } } -void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, const std::string& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots) +void Guild::HandleSetRankInfo(WorldSession* session, uint32 rankId, const std::string& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots) { // Only leader can modify ranks if (!_IsLeader(session->GetPlayer())) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); else if (RankInfo* rankInfo = GetRankInfo(rankId)) { sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Changed RankName to '%s', rights to 0x%08X", name.c_str(), rights); @@ -1389,13 +1487,13 @@ void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId) return; Player* player = session->GetPlayer(); - if (!player->HasEnoughMoney(tabCost)) // Should not happen, this is checked by client + if (!player->HasEnoughMoney(uint64(tabCost))) // Should not happen, this is checked by client return; if (!_CreateNewBankTab()) return; - player->ModifyMoney(-int32(tabCost)); + player->ModifyMoney(-int64(tabCost)); _SetRankBankMoneyPerDay(player->GetRank(), uint32(GUILD_WITHDRAW_MONEY_UNLIMITED)); _SetRankBankTabRightsAndSlots(player->GetRank(), tabId, GuildBankRightsAndSlots(GUILD_BANK_RIGHT_FULL, uint32(GUILD_WITHDRAW_SLOT_UNLIMITED))); HandleRoster(); // Broadcast for tab rights update @@ -1407,7 +1505,7 @@ void Guild::HandleInviteMember(WorldSession* session, const std::string& name) Player* pInvitee = sObjectAccessor->FindPlayerByName(name.c_str()); if (!pInvitee) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PLAYER_NOT_FOUND_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PLAYER_NOT_FOUND_S, name); return; } @@ -1417,25 +1515,25 @@ void Guild::HandleInviteMember(WorldSession* session, const std::string& name) return; if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && pInvitee->GetTeam() != player->GetTeam()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_NOT_ALLIED, name); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_NOT_ALLIED, name); return; } // Invited player cannot be in another guild - if (pInvitee->GetGuildId()) + /*if (pInvitee->GetGuildId()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_ALREADY_IN_GUILD_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_ALREADY_IN_GUILD_S, name); return; - } + }*/ // Invited player cannot be invited if (pInvitee->GetGuildIdInvited()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_ALREADY_INVITED_TO_GUILD_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, name); return; } // Inviting player must have rights to invite if (!_HasRankRight(player, GR_RIGHT_INVITE)) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); return; } @@ -1444,9 +1542,65 @@ void Guild::HandleInviteMember(WorldSession* session, const std::string& name) pInvitee->SetGuildIdInvited(m_id); _LogEvent(GUILD_EVENT_LOG_INVITE_PLAYER, player->GetGUIDLow(), pInvitee->GetGUIDLow()); - WorldPacket data(SMSG_GUILD_INVITE, 8 + 10); // Guess size - data << player->GetName(); - data << m_name; + WorldPacket data(SMSG_GUILD_INVITE, 100); + data << uint32(GetLevel()); + data << uint32(m_emblemInfo.GetStyle()); + data << uint32(m_emblemInfo.GetBorderColor()); + data << uint32(m_emblemInfo.GetBorderStyle()); + data << uint32(m_emblemInfo.GetBackgroundColor()); + data << uint32(m_emblemInfo.GetColor()); + + ObjectGuid oldGuildGuid = MAKE_NEW_GUID(pInvitee->GetGuildId(), 0, pInvitee->GetGuildId() ? HIGHGUID_GUILD : 0); + ObjectGuid newGuildGuid = GetGUID(); + + data.WriteBit(newGuildGuid[3]); + data.WriteBit(newGuildGuid[2]); + data.WriteBits(pInvitee->GetGuildName().length(), 8); + data.WriteBit(newGuildGuid[1]); + data.WriteBit(oldGuildGuid[6]); + data.WriteBit(oldGuildGuid[4]); + data.WriteBit(oldGuildGuid[1]); + data.WriteBit(oldGuildGuid[5]); + data.WriteBit(oldGuildGuid[7]); + data.WriteBit(oldGuildGuid[2]); + data.WriteBit(newGuildGuid[7]); + data.WriteBit(newGuildGuid[0]); + data.WriteBit(newGuildGuid[6]); + data.WriteBits(m_name.length(), 8); + data.WriteBit(oldGuildGuid[3]); + data.WriteBit(oldGuildGuid[0]); + data.WriteBit(newGuildGuid[5]); + data.WriteBits(strlen(player->GetName()), 7); + data.WriteBit(newGuildGuid[4]); + + data.FlushBits(); + + data.WriteByteSeq(newGuildGuid[1]); + data.WriteByteSeq(oldGuildGuid[3]); + data.WriteByteSeq(newGuildGuid[6]); + data.WriteByteSeq(oldGuildGuid[2]); + data.WriteByteSeq(oldGuildGuid[1]); + data.WriteByteSeq(newGuildGuid[0]); + + if (!pInvitee->GetGuildName().empty()) + data.append(pInvitee->GetGuildName().c_str(), pInvitee->GetGuildName().length()); + + data.WriteByteSeq(newGuildGuid[7]); + data.WriteByteSeq(newGuildGuid[2]); + + data.append(player->GetName(), strlen(player->GetName())); + + data.WriteByteSeq(oldGuildGuid[7]); + data.WriteByteSeq(oldGuildGuid[6]); + data.WriteByteSeq(oldGuildGuid[5]); + data.WriteByteSeq(oldGuildGuid[0]); + data.WriteByteSeq(newGuildGuid[4]); + + data.append(m_name.c_str(), m_name.length()); + + data.WriteByteSeq(newGuildGuid[5]); + data.WriteByteSeq(newGuildGuid[3]); + data.WriteByteSeq(oldGuildGuid[4]); pInvitee->GetSession()->SendPacket(&data); sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_INVITE)"); @@ -1474,7 +1628,7 @@ void Guild::HandleLeaveMember(WorldSession* session) { if (m_members.size() > 1) // Leader cannot leave if he is not the last member - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_LEADER_LEAVE); + SendCommandResult(session, GUILD_QUIT, ERR_GUILD_LEADER_LEAVE); else // Guild is disbanded if leader leaves. Disband(); @@ -1486,49 +1640,57 @@ void Guild::HandleLeaveMember(WorldSession* session) _LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUIDLow()); _BroadcastEvent(GE_LEFT, player->GetGUID(), player->GetName()); - SendCommandResult(session, GUILD_QUIT_S, ERR_PLAYER_NO_MORE_IN_GUILD, m_name); + SendCommandResult(session, GUILD_QUIT, ERR_PLAYER_NO_MORE_IN_GUILD, m_name); } } -void Guild::HandleRemoveMember(WorldSession* session, const std::string& name) +void Guild::HandleRemoveMember(WorldSession* session, uint64 guid) { Player* player = session->GetPlayer(); + Player* removedPlayer = ObjectAccessor::FindPlayer(guid); + Member* member = GetMember(guid); + // Player must have rights to remove members if (!_HasRankRight(player, GR_RIGHT_REMOVE)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); - // Removed player must be a member of guild - else if (Member* member = GetMember(session, name)) + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); + // Removed player must be a member of the guild + else if (member && removedPlayer) { - // Leader cannot be removed + // Guild masters cannot be removed if (member->IsRank(GR_GUILDMASTER)) - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_LEADER_LEAVE); + SendCommandResult(session, GUILD_QUIT, ERR_GUILD_LEADER_LEAVE); // Do not allow to remove player with the same rank or higher else if (member->IsRankNotLower(player->GetRank())) - SendCommandResult(session, GUILD_QUIT_S, ERR_GUILD_RANK_TOO_HIGH_S, name); + SendCommandResult(session, GUILD_QUIT, ERR_GUILD_RANK_TOO_HIGH_S, removedPlayer->GetName()); else { - uint64 guid = member->GetGUID(); // After call to DeleteMember pointer to member becomes invalid DeleteMember(guid, false, true); _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUIDLow(), GUID_LOPART(guid)); - _BroadcastEvent(GE_REMOVED, 0, name.c_str(), player->GetName()); + _BroadcastEvent(GE_REMOVED, 0, removedPlayer->GetName(), player->GetName()); } } + else if (removedPlayer) + SendCommandResult(session, GUILD_QUIT, ERR_PLAYER_NO_MORE_IN_GUILD, removedPlayer->GetName()); } -void Guild::HandleUpdateMemberRank(WorldSession* session, const std::string& name, bool demote) +void Guild::HandleUpdateMemberRank(WorldSession* session, uint64 targetGuid, bool demote) { Player* player = session->GetPlayer(); - // Player must have rights to promote - if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE)) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + // Promoted player must be a member of guild - else if (Member* member = GetMember(session, name)) + if (Member* member = GetMember(targetGuid)) { + if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE)) + { + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); + return; + } + // Player cannot promote himself if (member->IsSamePlayer(player->GetGUID())) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_NAME_INVALID); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_NAME_INVALID); return; } @@ -1537,13 +1699,13 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, const std::string& nam // Player can demote only lower rank members if (member->IsRankNotLower(player->GetRank())) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_RANK_TOO_HIGH_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_RANK_TOO_HIGH_S, member->GetName()); return; } // Lowest rank cannot be demoted if (member->GetRankId() >= _GetLowestRankId()) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_RANK_TOO_LOW_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_RANK_TOO_LOW_S, member->GetName()); return; } } @@ -1553,27 +1715,50 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, const std::string& nam // member->GetRank() + 1 is the highest rank that current player can promote to if (member->IsRankNotLower(player->GetRank() + 1)) { - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_RANK_TOO_HIGH_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_RANK_TOO_HIGH_S, member->GetName()); return; } } - // When promoting player, rank is decreased, when demoting - increased uint32 newRankId = member->GetRankId() + (demote ? 1 : -1); member->ChangeRank(newRankId); _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUIDLow(), GUID_LOPART(member->GetGUID()), newRankId); - _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, 0, player->GetName(), name.c_str(), _GetRankName(newRankId).c_str()); + _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, 0, player->GetName(), member->GetName().c_str(), _GetRankName(newRankId).c_str()); + } +} + +void Guild::HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank) +{ + Player* player = session->GetPlayer(); + + // Promoted player must be a member of guild + if (Member* member = GetMember(targetGuid)) + { + if (!_HasRankRight(player, rank > member->GetRankId() ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE)) + { + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); + return; + } + + // Player cannot promote himself + if (member->IsSamePlayer(player->GetGUID())) + { + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_NAME_INVALID); + return; + } + + SendGuildRanksUpdate(setterGuid, targetGuid, rank); } } -void Guild::HandleAddNewRank(WorldSession* session, const std::string& name) +void Guild::HandleAddNewRank(WorldSession* session, std::string const& name) //, uint32 rankId) { if (_GetRanksSize() >= GUILD_RANKS_MAX_COUNT) return; // Only leader can add new rank if (!_IsLeader(session->GetPlayer())) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); else { _CreateRank(name, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK); @@ -1582,7 +1767,7 @@ void Guild::HandleAddNewRank(WorldSession* session, const std::string& name) } } -void Guild::HandleRemoveLowestRank(WorldSession* session) +void Guild::HandleRemoveRank(WorldSession* session, uint32 rankId) { // Cannot remove rank if total count is minimum allowed by the client if (_GetRanksSize() <= GUILD_RANKS_MIN_COUNT) @@ -1590,22 +1775,21 @@ void Guild::HandleRemoveLowestRank(WorldSession* session) // Only leader can delete ranks if (!_IsLeader(session->GetPlayer())) - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); else { - uint8 rankId = _GetLowestRankId(); // Delete bank rights for rank PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK); stmt->setUInt32(0, m_id); - stmt->setUInt8 (1, rankId); + stmt->setUInt8(1, rankId); CharacterDatabase.Execute(stmt); // Delete rank - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_LOWEST_RANK); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK); stmt->setUInt32(0, m_id); - stmt->setUInt8 (1, rankId); + stmt->setUInt8(1, rankId); CharacterDatabase.Execute(stmt); - m_ranks.pop_back(); + m_ranks.erase(m_ranks.begin() + rankId-1); HandleQuery(session); HandleRoster(); // Broadcast for tab rights update @@ -1623,13 +1807,13 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount) // Add money to bank _ModifyBankMoney(trans, amount, true); // Remove money from player - player->ModifyMoney(-int32(amount)); + player->ModifyMoney(-int64(amount)); player->SaveGoldToDB(trans); // Log GM action (TODO: move to scripts) if (!AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(player->GetSession()->GetAccountId(), - "GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)", + "GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)", player->GetName(), player->GetSession()->GetAccountId(), amount, m_id); } // Log guild bank event @@ -1703,7 +1887,7 @@ void Guild::HandleDisband(WorldSession* session) { // Only leader can disband guild if (!_IsLeader(session->GetPlayer())) - Guild::SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PERMISSIONS); + Guild::SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PERMISSIONS); else { Disband(); @@ -1758,6 +1942,7 @@ void Guild::SendBankTabData(WorldSession* session, uint8 tabId) const void Guild::SendBankTabsInfo(WorldSession* session) const { + // TODO WorldPacket data(SMSG_GUILD_BANK_LIST, 500); data << uint64(m_bankMoney); @@ -1784,29 +1969,29 @@ void Guild::SendBankTabText(WorldSession* session, uint8 tabId) const void Guild::SendPermissions(WorldSession* session) const { uint64 guid = session->GetPlayer()->GetGUID(); - uint8 rankId = session->GetPlayer()->GetRank(); - - WorldPacket data(MSG_GUILD_PERMISSIONS, 4 * 15 + 1); + uint32 rankId = session->GetPlayer()->GetRank(); + WorldPacket data(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, 4 * 15 + 1); data << uint32(rankId); + data << uint32(_GetPurchasedTabsSize()); data << uint32(_GetRankRights(rankId)); data << uint32(_GetMemberRemainingMoney(guid)); - data << uint8 (_GetPurchasedTabsSize()); - // Why sending all info when not all tabs are purchased??? + data.WriteBits(GUILD_BANK_MAX_TABS, 23); for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) { data << uint32(_GetRankBankTabRights(rankId, tabId)); data << uint32(_GetMemberRemainingSlots(guid, tabId)); } + session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (MSG_GUILD_PERMISSIONS)"); + sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent (SMSG_GUILD_PERMISSIONS_QUERY_RESULTS)"); } void Guild::SendMoneyInfo(WorldSession* session) const { - WorldPacket data(MSG_GUILD_BANK_MONEY_WITHDRAWN, 4); - data << uint32(_GetMemberRemainingMoney(session->GetPlayer()->GetGUID())); + WorldPacket data(SMSG_GUILD_BANK_MONEY_WITHDRAWN, 4); + data << uint64(_GetMemberRemainingMoney(session->GetPlayer()->GetGUID())); session->SendPacket(&data); - sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent MSG_GUILD_BANK_MONEY_WITHDRAWN"); + sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent SMSG_GUILD_BANK_MONEY_WITHDRAWN"); } void Guild::SendLoginInfo(WorldSession* session) const @@ -2040,6 +2225,20 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, const std: } } +void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, const std::string& msg, const std::string& prefix) const +{ + if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) + { + WorldPacket data; + ChatHandler::FillMessageData(&data, session, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, CHAT_MSG_ADDON, NULL, 0, msg.c_str(), NULL, prefix.c_str()); + for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) + if (Player* player = itr->second->FindPlayer()) + if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && + !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow())) + player->GetSession()->SendPacket(&data); + } +} + void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const { for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) @@ -2075,7 +2274,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId) uint32 lowguid = GUID_LOPART(guid); - // If rank was not passed, assing lowest possible rank + // If rank was not passed, assign lowest possible rank if (rankId == GUILD_RANK_NONE) rankId = _GetLowestRankId(); @@ -2193,6 +2392,12 @@ bool Guild::ChangeMemberRank(uint64 guid, uint8 newRank) return false; } +bool Guild::IsMember(uint64 guid) +{ + Members::const_iterator itr = m_members.find(GUID_LOPART(guid)); + return itr != m_members.end(); +} + /////////////////////////////////////////////////////////////////////////////// // Bank (items move) void Guild::SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount) @@ -2292,7 +2497,7 @@ void Guild::_CreateRank(const std::string& name, uint32 rights) return; // Ranks represent sequence 0, 1, 2, ... where 0 means guildmaster - uint8 newRankId = _GetRanksSize(); + uint32 newRankId = _GetRanksSize(); RankInfo info(m_id, newRankId, name, rights, 0); m_ranks.push_back(info); @@ -2379,7 +2584,7 @@ void Guild::_SetLeaderGUID(Member* pLeader) CharacterDatabase.Execute(stmt); } -void Guild::_SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay) +void Guild::_SetRankBankMoneyPerDay(uint32 rankId, uint32 moneyPerDay) { if (RankInfo* rankInfo = GetRankInfo(rankId)) { @@ -2391,7 +2596,7 @@ void Guild::_SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay) } } -void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) +void Guild::_SetRankBankTabRightsAndSlots(uint32 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB) { if (tabId >= _GetPurchasedTabsSize()) return; @@ -2406,28 +2611,28 @@ void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, uint8 tabId, GuildBankRi } } -inline std::string Guild::_GetRankName(uint8 rankId) const +inline std::string Guild::_GetRankName(uint32 rankId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetName(); return "<unknown>"; } -inline uint32 Guild::_GetRankRights(uint8 rankId) const +inline uint32 Guild::_GetRankRights(uint32 rankId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetRights(); return 0; } -inline uint32 Guild::_GetRankBankMoneyPerDay(uint8 rankId) const +inline uint32 Guild::_GetRankBankMoneyPerDay(uint32 rankId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankMoneyPerDay(); return 0; } -inline uint32 Guild::_GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const +inline uint32 Guild::_GetRankBankTabSlotsPerDay(uint32 rankId, uint8 tabId) const { if (tabId < _GetPurchasedTabsSize()) if (const RankInfo* rankInfo = GetRankInfo(rankId)) @@ -2435,7 +2640,7 @@ inline uint32 Guild::_GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const return 0; } -inline uint8 Guild::_GetRankBankTabRights(uint8 rankId, uint8 tabId) const +inline uint32 Guild::_GetRankBankTabRights(uint32 rankId, uint8 tabId) const { if (const RankInfo* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankTabRights(tabId); @@ -2742,3 +2947,56 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* par sLog->outDebug(LOG_FILTER_GUILD, "WORLD: Sent SMSG_GUILD_EVENT"); } + +void Guild::SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank) +{ + ObjectGuid tarGuid = targetGuid; + ObjectGuid setGuid = setterGuid; + + Member* member = GetMember(targetGuid); + ASSERT(member); + + WorldPacket data(SMSG_GUILD_RANKS_UPDATE, 100); + data.WriteBit(setGuid[7]); + data.WriteBit(setGuid[2]); + data.WriteBit(tarGuid[2]); + data.WriteBit(setGuid[1]); + data.WriteBit(tarGuid[1]); + data.WriteBit(tarGuid[7]); + data.WriteBit(tarGuid[0]); + data.WriteBit(tarGuid[5]); + data.WriteBit(tarGuid[4]); + data.WriteBit(rank < member->GetRankId()); // 1 == higher, 0 = lower? + data.WriteBit(setGuid[5]); + data.WriteBit(setGuid[0]); + data.WriteBit(tarGuid[6]); + data.WriteBit(setGuid[3]); + data.WriteBit(setGuid[6]); + data.WriteBit(tarGuid[3]); + data.WriteBit(setGuid[4]); + + data.FlushBits(); + + data << uint32(rank); + data.WriteByteSeq(setGuid[3]); + data.WriteByteSeq(tarGuid[7]); + data.WriteByteSeq(setGuid[6]); + data.WriteByteSeq(setGuid[2]); + data.WriteByteSeq(tarGuid[5]); + data.WriteByteSeq(tarGuid[0]); + data.WriteByteSeq(setGuid[7]); + data.WriteByteSeq(setGuid[5]); + data.WriteByteSeq(tarGuid[2]); + data.WriteByteSeq(tarGuid[1]); + data.WriteByteSeq(setGuid[0]); + data.WriteByteSeq(setGuid[4]); + data.WriteByteSeq(setGuid[1]); + data.WriteByteSeq(tarGuid[3]); + data.WriteByteSeq(tarGuid[6]); + data.WriteByteSeq(tarGuid[4]); + BroadcastPacket(&data); + + member->ChangeRank(rank); + + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_GUILD_RANKS_UPDATE"); +} diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index e18e62e51b7..5e02e88a224 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -29,7 +29,7 @@ class Item; enum GuildMisc { - GUILD_BANK_MAX_TABS = 6, // send by client for money log also + GUILD_BANK_MAX_TABS = 8, // send by client for money log also GUILD_BANK_MAX_SLOTS = 98, GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB GUILD_RANKS_MIN_COUNT = 5, @@ -77,12 +77,23 @@ enum GuildRankRights enum GuildCommandType { - GUILD_CREATE_S = 0x00, - GUILD_INVITE_S = 0x01, - GUILD_QUIT_S = 0x03, - GUILD_FOUNDER_S = 0x0E, - GUILD_UNK1 = 0x13, - GUILD_UNK2 = 0x14 + GUILD_CREATE = 0x00, + GUILD_INVITE = 0x01, + GUILD_QUIT = 0x03, + GUILD_ROSTER = 0x05, + GUILD_PROMOTE = 0x06, + GUILD_DEMOTE = 0x07, + GUILD_KICK = 0x08, + GUILD_LEADER = 0x0A, + GUILD_MOTD = 0x0B, + GUILD_GUILDCHAT = 0x0D, + GUILD_FOUNDER = 0x0E, + GUILD_CHANGE_RANK = 0x10, + GUILD_EDIT_PUB_NOTE = 0x13, + GUILD_UNK = 0x14, + GUILD_VIEW_TAB = 0x15, + GUILD_MOVE_ITEM = 0x16, + GUILD_REPAIR = 0x19, }; enum GuildCommandError @@ -110,31 +121,41 @@ enum GuildCommandError ERR_GUILD_WITHDRAW_LIMIT = 0x19, ERR_GUILD_NOT_ENOUGH_MONEY = 0x1A, ERR_GUILD_BANK_FULL = 0x1C, - ERR_GUILD_ITEM_NOT_FOUND = 0x1D + ERR_GUILD_ITEM_NOT_FOUND = 0x1D, + ERR_GUILD_TOO_MUCH_MONEY = 0x1F, + ERR_GUILD_WRONG_TAB = 0x20, + ERR_GUILD_REQ_AUTHENTICATOR = 0x22, + ERR_GUILD_BANK_VOUCHER_FAILED = 0x23, }; enum GuildEvents { - GE_PROMOTION = 0x00, - GE_DEMOTION = 0x01, - GE_MOTD = 0x02, - GE_JOINED = 0x03, - GE_LEFT = 0x04, - GE_REMOVED = 0x05, - GE_LEADER_IS = 0x06, - GE_LEADER_CHANGED = 0x07, - GE_DISBANDED = 0x08, - GE_TABARDCHANGE = 0x09, - GE_UNK1 = 0x0A, // string, string EVENT_GUILD_ROSTER_UPDATE tab content change? - GE_UNK2 = 0x0B, // EVENT_GUILD_ROSTER_UPDATE - GE_SIGNED_ON = 0x0C, // ERR_FRIEND_ONLINE_SS - GE_SIGNED_OFF = 0x0D, // ERR_FRIEND_OFFLINE_S - GE_GUILDBANK_BAGSLOTS_CHANGED = 0x0E, // EVENT_GUILDBANK_BAGSLOTS_CHANGED - GE_GUILDBANK_TAB_PURCHASED = 0x0F, // EVENT_GUILDBANK_UPDATE_TABS - GE_UNK5 = 0x10, // EVENT_GUILDBANK_UPDATE_TABS - GE_GUILDBANK_MONEY_UPDATE = 0x11, // EVENT_GUILDBANK_UPDATE_MONEY, string 0000000000002710 is 1 gold - GE_GUILDBANK_MONEY_WITHDRAWN = 0x12, // MSG_GUILD_BANK_MONEY_WITHDRAWN - GE_GUILDBANK_TEXT_CHANGED = 0x13 // EVENT_GUILDBANK_TEXT_CHANGED + GE_PROMOTION = 1, + GE_DEMOTION = 2, + GE_MOTD = 3, + GE_JOINED = 4, + GE_LEFT = 5, + GE_REMOVED = 6, + GE_LEADER_IS = 7, + GE_LEADER_CHANGED = 8, + GE_DISBANDED = 9, + GE_TABARDCHANGE = 10, + GE_RANK_UPDATED = 11, + GE_RANK_CREATED = 12, + GE_RANK_DELETED = 13, + GE_RANK_ORDER_CHANGED = 14, + GE_FOUNDER = 15, // At guild creation - Set founder + GE_SIGNED_ON = 16, + GE_SIGNED_OFF = 17, + GE_GUILDBANKBAGSLOTS_CHANGED = 18, + GE_BANK_TAB_PURCHASED = 19, + GE_BANK_TAB_UPDATED = 20, + GE_BANK_MONEY_UPDATED = 21, + GE_BANK_MONEY_WITHDRAWN = 22, + GE_BANK_TEXT_CHANGED = 23, + // 24 - error 795 + GE_SIGNED_ON_MOBILE = 25, + GE_SIGNED_Off_MOBILE = 26, }; enum PetitionTurns @@ -142,15 +163,20 @@ enum PetitionTurns PETITION_TURN_OK = 0, PETITION_TURN_ALREADY_IN_GUILD = 2, PETITION_TURN_NEED_MORE_SIGNATURES = 4, + PETITION_TURN_GUILD_PERMISSIONS = 11, + PETITION_TURN_GUILD_NAME_INVALID = 12, }; enum PetitionSigns { - PETITION_SIGN_OK = 0, - PETITION_SIGN_ALREADY_SIGNED = 1, - PETITION_SIGN_ALREADY_IN_GUILD = 2, - PETITION_SIGN_CANT_SIGN_OWN = 3, - PETITION_SIGN_NOT_SERVER = 4, + PETITION_SIGN_OK = 0, + PETITION_SIGN_ALREADY_SIGNED = 1, + PETITION_SIGN_ALREADY_IN_GUILD = 2, + PETITION_SIGN_CANT_SIGN_OWN = 3, + PETITION_SIGN_NOT_SERVER = 4, + PETITION_SIGN_FULL = 5, + PETITION_SIGN_ALREADY_SIGNED_OTHER = 6, + PETITION_SIGN_RESTRICTED_ACCOUNT = 7, }; enum GuildBankRights @@ -173,7 +199,7 @@ enum GuildBankEventLogTypes GUILD_BANK_LOG_REPAIR_MONEY = 6, GUILD_BANK_LOG_MOVE_ITEM2 = 7, GUILD_BANK_LOG_UNK1 = 8, - GUILD_BANK_LOG_UNK2 = 9, + GUILD_BANK_LOG_BUY_SLOT = 9, }; enum GuildEventLogTypes @@ -196,6 +222,15 @@ enum GuildEmblemError ERR_GUILDEMBLEM_INVALIDVENDOR = 5 }; +enum GuildMemberFlags +{ + GUILDMEMBER_STATUS_NONE = 0x0000, + GUILDMEMBER_STATUS_ONLINE = 0x0001, + GUILDMEMBER_STATUS_AFK = 0x0002, + GUILDMEMBER_STATUS_DND = 0x0004, + GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app +}; + //////////////////////////////////////////////////////////////////////////////////////////// // Emblem info class EmblemInfo @@ -226,7 +261,7 @@ private: struct GuildBankRightsAndSlots { GuildBankRightsAndSlots() : rights(0), slots(0) { } - GuildBankRightsAndSlots(uint8 _rights, uint32 _slots) : rights(_rights), slots(_slots) { } + GuildBankRightsAndSlots(uint32 _rights, uint32 _slots) : rights(_rights), slots(_slots) { } inline bool IsEqual(GuildBankRightsAndSlots const& rhs) const { return rights == rhs.rights && slots == rhs.slots; } void SetGuildMasterValues() @@ -235,7 +270,7 @@ struct GuildBankRightsAndSlots slots = uint32(GUILD_WITHDRAW_SLOT_UNLIMITED); } - uint8 rights; + uint32 rights; uint32 slots; }; typedef std::vector <GuildBankRightsAndSlots> GuildBankRightsAndSlotsVec; @@ -257,7 +292,7 @@ private: }; public: - Member(uint32 guildId, uint64 guid, uint8 rankId) : m_guildId(guildId), m_guid(guid), m_logoutTime(::time(NULL)), m_rankId(rankId) { } + Member(uint32 guildId, uint64 guid, uint32 rankId) : m_guildId(guildId), m_guid(guid), m_logoutTime(::time(NULL)), m_rankId(rankId) { } void SetStats(Player* player); void SetStats(const std::string& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId); @@ -266,14 +301,20 @@ private: void SetPublicNote(const std::string& publicNote); void SetOfficerNote(const std::string& officerNote); + std::string GetPublicNote() { return m_publicNote; }; + std::string GetOfficerNote() { return m_officerNote; }; + bool LoadFromDB(Field* fields); void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data) const; uint64 GetGUID() const { return m_guid; } std::string GetName() const { return m_name; } uint32 GetAccountId() const { return m_accountId; } - uint8 GetRankId() const { return m_rankId; } + uint32 GetRankId() const { return m_rankId; } + uint8 GetClass() const { return m_class; } + uint8 GetLevel() const { return m_level; } + uint8 GetZone() const { return m_zoneId; } + uint64 GetLogoutTime() const { return m_logoutTime; } void ChangeRank(uint8 newRank); @@ -301,7 +342,7 @@ private: uint64 m_logoutTime; uint32 m_accountId; // Fields from guild_member table - uint8 m_rankId; + uint32 m_rankId; std::string m_publicNote; std::string m_officerNote; @@ -409,19 +450,18 @@ private: uint32 m_nextGUID; }; - // Class incapsulating guild rank data + // Class encapsulating guild rank data class RankInfo { public: RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { } - RankInfo(uint32 guildId, uint8 rankId, const std::string& name, uint32 rights, uint32 money) : + RankInfo(uint32 guildId, uint32 rankId, const std::string& name, uint32 rights, uint32 money) : m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights), m_bankMoneyPerDay(money) { } void LoadFromDB(Field* fields); void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data) const; - uint8 GetId() const { return m_rankId; } + uint32 GetId() const { return m_rankId; } std::string GetName() const { return m_name; } void SetName(const std::string& name); @@ -429,10 +469,13 @@ private: uint32 GetRights() const { return m_rights; } void SetRights(uint32 rights); + bool operator < (const RankInfo& rank) const { return m_rights > rank.GetRights(); } + bool operator == (const RankInfo& rank) const { return m_rights == rank.GetRights(); } + uint32 GetBankMoneyPerDay() const { return m_rankId == GR_GUILDMASTER ? GUILD_WITHDRAW_MONEY_UNLIMITED : m_bankMoneyPerDay; } void SetBankMoneyPerDay(uint32 money); - inline uint8 GetBankTabRights(uint8 tabId) const { return tabId < GUILD_BANK_MAX_TABS ? m_bankTabRightsAndSlots[tabId].rights : 0; } + inline uint32 GetBankTabRights(uint8 tabId) const { return tabId < GUILD_BANK_MAX_TABS ? m_bankTabRightsAndSlots[tabId].rights : 0; } inline uint32 GetBankTabSlotsPerDay(uint8 tabId) const { if (tabId < GUILD_BANK_MAX_TABS) @@ -443,8 +486,7 @@ private: private: uint32 m_guildId; - - uint8 m_rankId; + uint32 m_rankId; std::string m_name; uint32 m_rights; uint32 m_bankMoneyPerDay; @@ -590,6 +632,7 @@ public: // Getters uint32 GetId() const { return m_id; } + uint64 GetGUID() const { return MAKE_NEW_GUID(m_id, 0, HIGHGUID_GUILD); } uint64 GetLeaderGUID() const { return m_leaderGuid; } const std::string& GetName() const { return m_name; } const std::string& GetMOTD() const { return m_motd; } @@ -598,21 +641,23 @@ public: // Handle client commands void HandleRoster(WorldSession* session = NULL); // NULL = broadcast void HandleQuery(WorldSession* session); + void HandleGuildRanks(WorldSession* session); void HandleSetMOTD(WorldSession* session, const std::string& motd); void HandleSetInfo(WorldSession* session, const std::string& info); void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo); void HandleSetLeader(WorldSession* session, const std::string& name); void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, const std::string& name, const std::string& icon); - void HandleSetMemberNote(WorldSession* session, const std::string& name, const std::string& note, bool officer); - void HandleSetRankInfo(WorldSession* session, uint8 rankId, const std::string& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots); + void HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic); + void HandleSetRankInfo(WorldSession* session, uint32 rankId, const std::string& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots); void HandleBuyBankTab(WorldSession* session, uint8 tabId); void HandleInviteMember(WorldSession* session, const std::string& name); void HandleAcceptMember(WorldSession* session); void HandleLeaveMember(WorldSession* session); - void HandleRemoveMember(WorldSession* session, const std::string& name); - void HandleUpdateMemberRank(WorldSession* session, const std::string& name, bool demote); + void HandleRemoveMember(WorldSession* session, uint64 guid); + void HandleUpdateMemberRank(WorldSession* session, uint64 targetGuid, bool demote); + void HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank); void HandleAddNewRank(WorldSession* session, const std::string& name); - void HandleRemoveLowestRank(WorldSession* session); + void HandleRemoveRank(WorldSession* session, uint32 rankId); void HandleMemberDepositMoney(WorldSession* session, uint32 amount); bool HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool repair = false); void HandleMemberLogout(WorldSession* session); @@ -642,6 +687,7 @@ public: // Broadcasts void BroadcastToGuild(WorldSession* session, bool officerOnly, const std::string& msg, uint32 language = LANG_UNIVERSAL) const; + void BroadcastAddonToGuild(WorldSession* session, bool officerOnly, const std::string& msg, const std::string& prefix) const; void BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const; void BroadcastPacket(WorldPacket* packet) const; @@ -659,6 +705,7 @@ public: bool AddMember(uint64 guid, uint8 rankId = GUILD_RANK_NONE); void DeleteMember(uint64 guid, bool isDisbanding = false, bool isKicked = false); bool ChangeMemberRank(uint64 guid, uint8 newRank); + bool IsMember(uint64 guid); // Bank void SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount); @@ -667,6 +714,11 @@ public: // Bank tabs void SetBankTabText(uint8 tabId, const std::string& text); + AchievementMgr<Guild>& GetAchievementMgr() { return m_achievementMgr; } + AchievementMgr<Guild> const& GetAchievementMgr() const { return m_achievementMgr; } + + uint32 GetLevel() const { return m_level; } + protected: uint32 m_id; std::string m_name; @@ -687,12 +739,16 @@ protected: LogHolder* m_eventLog; LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1]; + AchievementMgr<Guild> m_achievementMgr; + + uint32 m_level; + private: - inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); } - inline const RankInfo* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } - inline RankInfo* GetRankInfo(uint8 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } + inline uint32 _GetRanksSize() const { return uint32(m_ranks.size()); } + inline const RankInfo* GetRankInfo(uint32 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } + inline RankInfo* GetRankInfo(uint32 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; } inline bool _HasRankRight(Player* player, uint32 right) const { return (_GetRankRights(player->GetRank()) & right) != GR_RIGHT_EMPTY; } - inline uint8 _GetLowestRankId() const { return uint8(m_ranks.size() - 1); } + inline uint32 _GetLowestRankId() const { return uint32(m_ranks.size() - 1); } inline uint8 _GetPurchasedTabsSize() const { return uint8(m_bankTabs.size()); } inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : NULL; } @@ -714,7 +770,7 @@ private: if (itr->second->GetName() == name) return itr->second; - SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD_S, name); + SendCommandResult(session, GUILD_INVITE, ERR_GUILD_PLAYER_NOT_IN_GUILD_S, name); return NULL; } inline void _DeleteMemberFromDB(uint32 lowguid) const @@ -739,13 +795,13 @@ private: bool _ModifyBankMoney(SQLTransaction& trans, uint64 amount, bool add); void _SetLeaderGUID(Member* pLeader); - void _SetRankBankMoneyPerDay(uint8 rankId, uint32 moneyPerDay); - void _SetRankBankTabRightsAndSlots(uint8 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); - uint8 _GetRankBankTabRights(uint8 rankId, uint8 tabId) const; - uint32 _GetRankRights(uint8 rankId) const; - uint32 _GetRankBankMoneyPerDay(uint8 rankId) const; - uint32 _GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const; - std::string _GetRankName(uint8 rankId) const; + void _SetRankBankMoneyPerDay(uint32 rankId, uint32 moneyPerDay); + void _SetRankBankTabRightsAndSlots(uint32 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true); + uint32 _GetRankBankTabRights(uint32 rankId, uint8 tabId) const; + uint32 _GetRankRights(uint32 rankId) const; + uint32 _GetRankBankMoneyPerDay(uint32 rankId) const; + uint32 _GetRankBankTabSlotsPerDay(uint32 rankId, uint8 tabId) const; + std::string _GetRankName(uint32 rankId) const; uint32 _GetMemberRemainingSlots(uint64 guid, uint8 tabId) const; uint32 _GetMemberRemainingMoney(uint64 guid) const; @@ -765,6 +821,8 @@ private: void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const; void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const; + void SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank); + void _BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL) const; }; #endif diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index dab67c59d2a..72c791e8a9f 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -59,6 +59,17 @@ Guild* GuildMgr::GetGuildById(uint32 guildId) const return NULL; } +Guild* GuildMgr::GetGuildByGuid(uint64 guid) const +{ + // Full guids are only used when receiving/sending data to client + // everywhere else guild id is used + if (IS_GUILD(guid)) + if (uint32 guildId = GUID_LOPART(guid)) + return GetGuildById(guildId); + + return NULL; +} + Guild* GuildMgr::GetGuildByName(const std::string& guildName) const { std::string search = guildName; @@ -178,7 +189,7 @@ void GuildMgr::LoadGuilds() CharacterDatabase.DirectExecute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL"); // 0 1 2 3 4 5 6 - QueryResult result = CharacterDatabase.Query("SELECT guildid, gm.guid, rank, pnote, offnote, BankResetTimeMoney, BankRemMoney, " + QueryResult result = CharacterDatabase.Query("SELECT gm.guildid, gm.guid, rank, pnote, offnote, BankResetTimeMoney, BankRemMoney, " // 7 8 9 10 11 12 "BankResetTimeTab0, BankRemSlotsTab0, BankResetTimeTab1, BankRemSlotsTab1, BankResetTimeTab2, BankRemSlotsTab2, " // 13 14 15 16 17 18 @@ -394,8 +405,26 @@ void GuildMgr::LoadGuilds() } } - // 9. Validate loaded guild data - sLog->outInfo(LOG_FILTER_GUILD, "Validating data of loaded guilds..."); + // 9. Load guild achievements + { + PreparedQueryResult achievementResult; + PreparedQueryResult criteriaResult; + for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_ACHIEVEMENT); + stmt->setUInt32(0, itr->first); + achievementResult = CharacterDatabase.Query(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA); + stmt->setUInt32(0, itr->first); + criteriaResult = CharacterDatabase.Query(stmt); + + itr->second->GetAchievementMgr().LoadFromDB(achievementResult, criteriaResult); + } + } + + // 10. Validate loaded guild data + sLog->outInfo(LOG_FILTER_GENERAL, "Validating data of loaded guilds..."); { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index 9654fced227..d9c18a8026d 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -32,6 +32,7 @@ public: Guild* GetGuildByLeader(uint64 guid) const; Guild* GetGuildById(uint32 guildId) const; + Guild* GetGuildByGuid(uint64 guid) const; Guild* GetGuildByName(const std::string& guildName) const; std::string GetGuildNameById(uint32 guildId) const; diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 8fb820713ce..ce4e2a15ca9 100755 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -152,7 +152,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_INVITE"); } -void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_ACCEPT"); // empty opcode @@ -185,7 +185,7 @@ void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recv_data*/) arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName(), arenaTeam->GetName(), ""); } -void WorldSession::HandleArenaTeamDeclineOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleArenaTeamDeclineOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ARENA_TEAM_DECLINE"); // empty opcode diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 10a130536c9..385bb8abb45 100755..100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -33,10 +33,10 @@ //post-incrementation is always slower than pre-incrementation ! //void called when player click on auctioneer npc -void WorldSession::HandleAuctionHelloOpcode(WorldPacket & recv_data) +void WorldSession::HandleAuctionHelloOpcode(WorldPacket& recvData) { uint64 guid; //NPC guid - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); if (!unit) @@ -91,34 +91,34 @@ void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auction data << uint32(location); data << uint32(auctionId); data << uint64(bidder); - data << uint32(bidSum); - data << uint32(diff); + data << uint64(bidSum); + data << uint64(diff); data << uint32(item_template); data << uint32(0); SendPacket(&data); } -//this void causes on client to display: "Your auction sold" +// this void causes on client to display: "Your auction sold" void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) { - WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (8*4)); + WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, 40); data << uint32(auction->Id); - data << uint32(auction->bid); - data << uint32(0); //unk - data << uint64(0); //unk (bidder guid?) + data << uint64(auction->bid); + data << uint64(0); //unk + data << uint64(0); //unk data << uint32(auction->item_template); - data << uint32(0); //unk - data << float(0); //unk (time?) + data << uint32(0); //unk + data << float(0); //unk SendPacket(&data); } //this void creates new auction and adds auction to some auctionhouse -void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) +void WorldSession::HandleAuctionSellItem(WorldPacket & recvData) { uint64 auctioneer; uint32 itemsCount, etime, bid, buyout; - recv_data >> auctioneer; - recv_data >> itemsCount; + recvData >> auctioneer; + recvData >> itemsCount; uint64 itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot uint32 count[MAX_AUCTION_ITEMS]; @@ -131,16 +131,16 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) for (uint32 i = 0; i < itemsCount; ++i) { - recv_data >> itemGUIDs[i]; - recv_data >> count[i]; + recvData >> itemGUIDs[i]; + recvData >> count[i]; if (!itemGUIDs[i] || !count[i] || count[i] > 1000 ) return; } - recv_data >> bid; - recv_data >> buyout; - recv_data >> etime; + recvData >> bid; + recvData >> buyout; + recvData >> etime; if (!bid || !etime) return; @@ -225,7 +225,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount); - if (!_player->HasEnoughMoney(deposit)) + if (!_player->HasEnoughMoney((uint64)deposit)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); return; @@ -277,7 +277,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); return; } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size @@ -347,25 +347,26 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); return; } } } -//this function is called when client bids or buys out auction -void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) +// this function is called when client bids or buys out auction +void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_PLACE_BID"); uint64 auctioneer; uint32 auctionId; - uint32 price; - recv_data >> auctioneer; - recv_data >> auctionId >> price; + uint64 price; + recvData >> auctioneer; + recvData >> auctionId; + recvData >> price; if (!auctionId || !price) - return; //check for cheaters + return; // check for cheaters Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) @@ -425,20 +426,20 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) if (auction->bidder > 0) { if (auction->bidder == player->GetGUIDLow()) - player->ModifyMoney(-int32(price - auction->bid)); + player->ModifyMoney(-int64(price - auction->bid)); else { // mail to last bidder and return money sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans); - player->ModifyMoney(-int32(price)); + player->ModifyMoney(-int64(price)); } } else - player->ModifyMoney(-int32(price)); + player->ModifyMoney(-int64(price)); auction->bidder = player->GetGUIDLow(); auction->bid = price; - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_AUCTION_BID); stmt->setUInt32(0, auction->bidder); @@ -452,16 +453,16 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) { //buyout: if (player->GetGUIDLow() == auction->bidder) - player->ModifyMoney(-int32(auction->buyout - auction->bid)); + player->ModifyMoney(-int64(auction->buyout - auction->bid)); else { - player->ModifyMoney(-int32(auction->buyout)); + player->ModifyMoney(-int64(auction->buyout)); if (auction->bidder) //buyout for bidded auction .. sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans); } auction->bidder = player->GetGUIDLow(); auction->bid = auction->buyout; - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); //- Mails must be under transaction control too to prevent data loss sAuctionMgr->SendAuctionSalePendingMail(auction, trans); @@ -481,15 +482,14 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) } //this void is called when auction_owner cancels his auction -void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) +void WorldSession::HandleAuctionRemoveItem(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_REMOVE_ITEM"); uint64 auctioneer; uint32 auctionId; - recv_data >> auctioneer; - recv_data >> auctionId; - //sLog->outDebug("Cancel AUCTION AuctionID: %u", auctionId); + recvData >> auctioneer; + recvData >> auctionId; Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) @@ -516,11 +516,11 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid { uint32 auctionCut = auction->GetAuctionCut(); - if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed + if (!player->HasEnoughMoney((uint64)auctionCut)) //player doesn't have enough money, maybe message needed return; //some auctionBidderNotification would be needed, but don't know that parts.. sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans); - player->ModifyMoney(-int32(auctionCut)); + player->ModifyMoney(-int64(auctionCut)); } // item will deleted or added to received mail list @@ -530,7 +530,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) } else { - sLog->outError(LOG_FILTER_NETWORKIO, "Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->item_guidlow); + sLog->outError(LOG_FILTER_NETWORKIO, "Auction id: %u got non existing item (item guid : %u)!", auction->Id, auction->item_guidlow); SendAuctionCommandResult(0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR); return; } @@ -539,7 +539,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) { SendAuctionCommandResult(0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR); //this code isn't possible ... maybe there should be assert - sLog->outError(LOG_FILTER_NETWORKIO, "CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", player->GetGUIDLow(), auctionId); + sLog->outError(LOG_FILTER_NETWORKIO, "CHEATER: %u tried to cancel auction (id: %u) of another player or auction is NULL", player->GetGUIDLow(), auctionId); return; } @@ -558,7 +558,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) } //called when player lists his bids -void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) +void WorldSession::HandleAuctionListBidderItems(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_BIDDER_ITEMS"); @@ -566,12 +566,12 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) uint32 listfrom; //page of auctions uint32 outbiddedCount; //count of outbidded auctions - recv_data >> guid; - recv_data >> listfrom; // not used in fact (this list not have page control in client) - recv_data >> outbiddedCount; - if (recv_data.size() != (16 + outbiddedCount * 4)) + recvData >> guid; + recvData >> listfrom; // not used in fact (this list not have page control in client) + recvData >> outbiddedCount; + if (recvData.size() != (16 + outbiddedCount * 4)) { - sLog->outError(LOG_FILTER_NETWORKIO, "Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recv_data.size(), (16 + outbiddedCount * 4)); + sLog->outError(LOG_FILTER_NETWORKIO, "Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recvData.size(), (16 + outbiddedCount * 4)); outbiddedCount = 0; } @@ -579,7 +579,7 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) if (!creature) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); - recv_data.rfinish(); + recvData.rfinish(); return; } @@ -591,14 +591,14 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4)); Player* player = GetPlayer(); - data << (uint32) 0; //add 0 as count + data << uint32(0); //add 0 as count uint32 count = 0; uint32 totalcount = 0; while (outbiddedCount > 0) //add all data, which client requires { --outbiddedCount; uint32 outbiddedAuctionId; - recv_data >> outbiddedAuctionId; + recvData >> outbiddedAuctionId; AuctionEntry* auction = auctionHouse->GetAuction(outbiddedAuctionId); if (auction && auction->BuildAuctionInfo(data)) { @@ -610,20 +610,20 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) auctionHouse->BuildListBidderItems(data, player, count, totalcount); data.put<uint32>(0, count); // add count to placeholder data << totalcount; - data << (uint32)300; //unk 2.3.0 + data << uint32(300); //unk 2.3.0 SendPacket(&data); } //this void sends player info about his auctions -void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data) +void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_OWNER_ITEMS"); uint32 listfrom; uint64 guid; - recv_data >> guid; - recv_data >> listfrom; // not used in fact (this list not have page control in client) + recvData >> guid; + recvData >> listfrom; // not used in fact (this list not have page control in client) Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) @@ -639,20 +639,20 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4)); - data << (uint32) 0; // amount place holder + data << uint32(0); // amount place holder uint32 count = 0; uint32 totalcount = 0; auctionHouse->BuildListOwnerItems(data, _player, count, totalcount); data.put<uint32>(0, count); - data << (uint32) totalcount; - data << (uint32) 0; + data << uint32(totalcount); + data << uint32(0); SendPacket(&data); } //this void is called when player clicks on search button -void WorldSession::HandleAuctionListItems(WorldPacket & recv_data) +void WorldSession::HandleAuctionListItems(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_ITEMS"); @@ -661,23 +661,23 @@ void WorldSession::HandleAuctionListItems(WorldPacket & recv_data) uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; uint64 guid; - recv_data >> guid; - recv_data >> listfrom; // start, used for page control listing by 50 elements - recv_data >> searchedname; + recvData >> guid; + recvData >> listfrom; // start, used for page control listing by 50 elements + recvData >> searchedname; - recv_data >> levelmin >> levelmax; - recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; - recv_data >> quality >> usable; + recvData >> levelmin >> levelmax; + recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; + recvData >> quality >> usable; - recv_data.read_skip<uint8>(); // unk + recvData.read_skip<uint8>(); // unk // this block looks like it uses some lame byte packing or similar... uint8 unkCnt; - recv_data >> unkCnt; + recvData >> unkCnt; for (uint8 i = 0; i < unkCnt; i++) { - recv_data.read_skip<uint8>(); - recv_data.read_skip<uint8>(); + recvData.read_skip<uint8>(); + recvData.read_skip<uint8>(); } Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); @@ -693,7 +693,7 @@ void WorldSession::HandleAuctionListItems(WorldPacket & recv_data) AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); - //sLog->outDebug("Auctionhouse search (GUID: %u TypeId: %u)",, list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", + //sLog->outDebug(LOG_FILTER_GENERAL, "Auctionhouse search (GUID: %u TypeId: %u)",, list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", // GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4)); @@ -714,16 +714,16 @@ void WorldSession::HandleAuctionListItems(WorldPacket & recv_data) count, totalcount); data.put<uint32>(0, count); - data << (uint32) totalcount; - data << (uint32) 300; // unk 2.3.0 const? + data << uint32(totalcount); + data << uint32(300); //unk 2.3.0 SendPacket(&data); } -void WorldSession::HandleAuctionListPendingSales(WorldPacket & recv_data) +void WorldSession::HandleAuctionListPendingSales(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_AUCTION_LIST_PENDING_SALES"); - recv_data.read_skip<uint64>(); + recvData.read_skip<uint64>(); uint32 count = 0; diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp index 49027bdf497..5085bb15584 100755 --- a/src/server/game/Handlers/AuthHandler.cpp +++ b/src/server/game/Handlers/AuthHandler.cpp @@ -19,20 +19,28 @@ #include "WorldSession.h" #include "WorldPacket.h" -void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos) +void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos) { - WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1))); - packet << uint8(code); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1 /*bits*/ + 4 + 1 + 4 + 1 + 4 + 1 + 1 + (queued ? 4 : 0)); + packet.WriteBit(queued); + if (queued) + packet.WriteBit(0); + + packet.WriteBit(1); // has account info + + packet.FlushBits(); + + // account info packet << uint32(0); // BillingTimeRemaining - packet << uint8(0); // BillingPlanFlags + packet << uint8(Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, 3 - CATA; must be set in database manually for each account + packet << uint32(0); + packet << uint8(Expansion()); // Unknown, these two show the same packet << uint32(0); // BillingTimeRested - packet << uint8(Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account + packet << uint8(0); // BillingPlanFlags - if (!shortForm) - { + packet << uint8(code); + if (queued) packet << uint32(queuePos); // Queue position - packet << uint8(0); // Realm has a free character migration - bool - } SendPacket(&packet); } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 2e0bbf786a9..6836d5b3e9f 100755 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -35,10 +35,10 @@ #include "DisableMgr.h" #include "Group.h" -void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket & recv_data) +void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); @@ -66,11 +66,11 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket & recv_data) void WorldSession::SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId) { WorldPacket data; - sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0); + sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId); SendPacket(&data); } -void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data) +void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recvData) { uint64 guid; uint32 bgTypeId_; @@ -79,10 +79,10 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data) bool isPremade = false; Group* grp = NULL; - recv_data >> guid; // battlemaster guid - recv_data >> bgTypeId_; // battleground type id (DBC id) - recv_data >> instanceId; // instance id, 0 if First Available selected - recv_data >> joinAsGroup; // join as group + recvData >> guid; // battlemaster guid + recvData >> bgTypeId_; // battleground type id (DBC id) + recvData >> instanceId; // instance id, 0 if First Available selected + recvData >> joinAsGroup; // join as group if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { @@ -244,7 +244,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket & recv_data) sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } -void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message"); @@ -290,7 +290,7 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket & /*recv_ SendPacket(&data); } -void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd MSG_PVP_LOG_DATA Message"); @@ -309,18 +309,12 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recv_data*/) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent MSG_PVP_LOG_DATA Message"); } -void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recv_data) +void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message"); uint32 bgTypeId; - recv_data >> bgTypeId; // id from DBC - - uint8 fromWhere; - recv_data >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo) - - uint8 unk1; - recv_data >> unk1; // Unknown 3.2.2 + recvData >> bgTypeId; // id from DBC BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); if (!bl) @@ -330,11 +324,11 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recv_data) } WorldPacket data; - sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId), fromWhere); + sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId)); SendPacket(&data); } -void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data) +void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); @@ -344,7 +338,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data) uint16 unk; // 0x1F90 constant? uint8 action; // enter battle 0x1, leave queue 0x0 - recv_data >> type >> unk2 >> bgTypeId_ >> unk >> action; + recvData >> type >> unk2 >> bgTypeId_ >> unk >> action; if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { @@ -483,14 +477,14 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data) } } -void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recv_data) +void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message"); - recv_data.read_skip<uint8>(); // unk1 - recv_data.read_skip<uint8>(); // unk2 - recv_data.read_skip<uint32>(); // BattlegroundTypeId - recv_data.read_skip<uint16>(); // unk3 + recvData.read_skip<uint8>(); // unk1 + recvData.read_skip<uint8>(); // unk2 + recvData.read_skip<uint32>(); // BattlegroundTypeId + recvData.read_skip<uint16>(); // unk3 // not allow leave battleground in combat if (_player->isInCombat()) @@ -501,7 +495,7 @@ void WorldSession::HandleLeaveBattlefieldOpcode(WorldPacket& recv_data) _player->LeaveBattleground(); } -void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // empty opcode sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Battleground status"); @@ -565,14 +559,14 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recv_data*/) } } -void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY"); Battleground* bg = _player->GetBattleground(); uint64 guid; - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) @@ -585,14 +579,14 @@ void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recv_data) sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid); } -void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket & recv_data) +void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE"); Battleground* bg = _player->GetBattleground(); uint64 guid; - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) @@ -605,7 +599,7 @@ void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket & recv_data) bg->AddPlayerToResurrectQueue(guid, _player->GetGUID()); } -void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recv_data) +void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); @@ -615,7 +609,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recv_data) uint8 isRated; // isRated Group* grp = NULL; - recv_data >> guid >> arenaslot >> asGroup >> isRated; + recvData >> guid >> arenaslot >> asGroup >> isRated; // ignore if we already in BG or BG queue if (_player->InBattleground()) @@ -773,10 +767,10 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket & recv_data) sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } -void WorldSession::HandleReportPvPAFK(WorldPacket & recv_data) +void WorldSession::HandleReportPvPAFK(WorldPacket & recvData) { uint64 playerGuid; - recv_data >> playerGuid; + recvData >> playerGuid; Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid); if (!reportedPlayer) diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp index 9b749fa8005..dba4645e2b5 100755 --- a/src/server/game/Handlers/ChannelHandler.cpp +++ b/src/server/game/Handlers/ChannelHandler.cpp @@ -23,18 +23,21 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - uint32 channel_id; - uint8 unknown1, unknown2; - std::string channelname, pass; - - recvPacket >> channel_id; - recvPacket >> unknown1 >> unknown2; - recvPacket >> channelname; - recvPacket >> pass; - - if (channel_id) + uint32 channelId; + uint32 channelLength, passLength; + std::string channelName, pass; + + recvPacket >> channelId; + recvPacket.ReadBit(); // unknowns + recvPacket.ReadBit(); + channelLength = recvPacket.ReadBits(8); + passLength = recvPacket.ReadBits(8); + channelName = recvPacket.ReadString(channelLength); + pass = recvPacket.ReadString(passLength); + + if (channelId) { - ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channel_id); + ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId); if (!channel) return; @@ -46,13 +49,13 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) return; } - if (channelname.empty()) + if (channelName.empty()) return; if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) { cMgr->team = _player->GetTeam(); - if (Channel* chn = cMgr->GetJoinChannel(channelname, channel_id)) + if (Channel* chn = cMgr->GetJoinChannel(channelName, channelId)) chn->Join(_player->GetGUID(), pass.c_str()); } } @@ -80,8 +83,9 @@ void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket) void WorldSession::HandleChannelList(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname; - recvPacket >> channelname; + + uint32 length = recvPacket.ReadBits(8); + std::string channelname = recvPacket.ReadString(length); if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if (Channel* chn = cMgr->GetChannel(channelname, _player)) @@ -91,10 +95,11 @@ void WorldSession::HandleChannelList(WorldPacket& recvPacket) void WorldSession::HandleChannelPassword(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, pass; - recvPacket >> channelname; - - recvPacket >> pass; + uint32 passLength = recvPacket.ReadBits(8); + uint32 nameLength = recvPacket.ReadBits(7); + + std::string pass = recvPacket.ReadString(passLength); + std::string channelname = recvPacket.ReadString(nameLength); if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if (Channel* chn = cMgr->GetChannel(channelname, _player)) @@ -104,11 +109,13 @@ void WorldSession::HandleChannelPassword(WorldPacket& recvPacket) void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, newp; - recvPacket >> channelname; - - recvPacket >> newp; + + uint32 channelLength = recvPacket.ReadBits(8); + uint32 nameLength = recvPacket.ReadBits(7); + std::string newp = recvPacket.ReadString(nameLength); + std::string channelname = recvPacket.ReadString(channelLength); + if (!normalizePlayerName(newp)) return; @@ -120,8 +127,9 @@ void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket) void WorldSession::HandleChannelOwner(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname; - recvPacket >> channelname; + uint32 length = recvPacket.ReadBits(8); + std::string channelname = recvPacket.ReadString(length); + if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if (Channel* chn = cMgr->GetChannel(channelname, _player)) chn->SendWhoOwner(_player->GetGUID()); @@ -130,11 +138,13 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket) void WorldSession::HandleChannelModerator(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; - - recvPacket >> otp; - + + uint32 channelLength = recvPacket.ReadBits(8); + uint32 nameLength = recvPacket.ReadBits(7); + + std::string otp = recvPacket.ReadString(nameLength); + std::string channelname = recvPacket.ReadString(channelLength); + if (!normalizePlayerName(otp)) return; @@ -146,10 +156,12 @@ void WorldSession::HandleChannelModerator(WorldPacket& recvPacket) void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; - - recvPacket >> otp; + + uint32 nameLength = recvPacket.ReadBits(7); + uint32 channelLength = recvPacket.ReadBits(8); + + std::string channelname = recvPacket.ReadString(channelLength); + std::string otp = recvPacket.ReadString(nameLength); if (!normalizePlayerName(otp)) return; @@ -162,10 +174,11 @@ void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket) void WorldSession::HandleChannelMute(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; - - recvPacket >> otp; + uint32 channelLength = recvPacket.ReadBits(8); + uint32 nameLength = recvPacket.ReadBits(7); + + std::string channelname = recvPacket.ReadString(channelLength); + std::string otp = recvPacket.ReadString(nameLength); if (!normalizePlayerName(otp)) return; @@ -179,11 +192,12 @@ void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; - - recvPacket >> otp; + uint32 nameLength = recvPacket.ReadBits(8); + uint32 channelLength = recvPacket.ReadBits(7); + std::string otp = recvPacket.ReadString(nameLength); + std::string channelname = recvPacket.ReadString(channelLength); + if (!normalizePlayerName(otp)) return; @@ -195,11 +209,12 @@ void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket) void WorldSession::HandleChannelInvite(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; - - recvPacket >> otp; - + uint32 channelLength = recvPacket.ReadBits(7); + uint32 nameLength = recvPacket.ReadBits(8); + + std::string channelname = recvPacket.ReadString(channelLength); + std::string otp = recvPacket.ReadString(nameLength); + if (!normalizePlayerName(otp)) return; @@ -211,10 +226,12 @@ void WorldSession::HandleChannelInvite(WorldPacket& recvPacket) void WorldSession::HandleChannelKick(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; + uint32 channelLength = recvPacket.ReadBits(8); + uint32 nameLength = recvPacket.ReadBits(7); + + std::string channelname = recvPacket.ReadString(channelLength); + std::string otp = recvPacket.ReadString(nameLength); - recvPacket >> otp; if (!normalizePlayerName(otp)) return; @@ -226,10 +243,14 @@ void WorldSession::HandleChannelKick(WorldPacket& recvPacket) void WorldSession::HandleChannelBan(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); + uint32 channelLength, nameLength; std::string channelname, otp; - recvPacket >> channelname; + + channelLength = recvPacket.ReadBits(8); + nameLength = recvPacket.ReadBits(7); - recvPacket >> otp; + otp = recvPacket.ReadString(nameLength); + channelname = recvPacket.ReadString(channelLength); if (!normalizePlayerName(otp)) return; @@ -243,11 +264,12 @@ void WorldSession::HandleChannelUnban(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname, otp; - recvPacket >> channelname; - - recvPacket >> otp; - + uint32 channelLength = recvPacket.ReadBits(7); + uint32 nameLength = recvPacket.ReadBits(8); + + std::string otp = recvPacket.ReadString(nameLength); + std::string channelname = recvPacket.ReadString(channelLength); + if (!normalizePlayerName(otp)) return; @@ -259,8 +281,10 @@ void WorldSession::HandleChannelUnban(WorldPacket& recvPacket) void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Opcode %u", recvPacket.GetOpcode()); - std::string channelname; - recvPacket >> channelname; + + uint32 length = recvPacket.ReadBits(8); + std::string channelname = recvPacket.ReadString(length); + if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if (Channel* chn = cMgr->GetChannel(channelname, _player)) chn->Announce(_player->GetGUID()); @@ -296,7 +320,7 @@ void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket) std::string channelname; recvPacket >> channelname; /*if (ChannelMgr* cMgr = channelMgr(_player->GetTeam())) - if (Channel* chn = cMgr->GetChannel(channelname, _player)) + if (Channel* chn = cMgr->GetChannel(channelName, _player)) chn->JoinNotify(_player->GetGUID());*/ } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 7451bd2dc2a..7a728ac1dd0 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -26,7 +26,6 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "DatabaseEnv.h" - #include "ArenaTeam.h" #include "Chat.h" #include "Group.h" @@ -43,6 +42,7 @@ #include "ScriptMgr.h" #include "Battleground.h" #include "AccountMgr.h" +#include "DBCStores.h" #include "LFGMgr.h" class LoginQueryHolder : public SQLQueryHolder @@ -110,6 +110,10 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_VOID_STORAGE); + stmt->setUInt32(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADVOIDSTORAGE, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, stmt); @@ -203,34 +207,47 @@ bool LoginQueryHolder::Initialize() void WorldSession::HandleCharEnum(PreparedQueryResult result) { - WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size - - uint8 num = 0; - - data << num; + uint32 charCount = 0; + ByteBuffer bitBuffer; + ByteBuffer dataBuffer; - _allowedCharsToLogin.clear(); + bitBuffer.WriteBits(0, 23); + bitBuffer.WriteBit(1); if (result) { + _allowedCharsToLogin.clear(); + + charCount = uint32(result->GetRowCount()); + bitBuffer.reserve(24 * charCount / 8); + dataBuffer.reserve(charCount * 381); + + bitBuffer.WriteBits(charCount, 17); + do { - uint32 guidlow = (*result)[0].GetUInt32(); - sLog->outInfo(LOG_FILTER_NETWORKIO, "Loading char guid %u from account %u.", guidlow, GetAccountId()); - if (Player::BuildEnumData(result, &data)) - { - _allowedCharsToLogin.insert(guidlow); - ++num; - } - } - while (result->NextRow()); + uint32 guidLow = (*result)[0].GetUInt32(); + + sLog->outInfo(LOG_FILTER_NETWORKIO, "Loading char guid %u from account %u.", guidLow, GetAccountId()); + + Player::BuildEnumData(result, &dataBuffer, &bitBuffer); + + _allowedCharsToLogin.insert(guidLow); + } while (result->NextRow()); + + bitBuffer.FlushBits(); } + else + bitBuffer.WriteBits(0, 17); - data.put<uint8>(0, num); + WorldPacket data(SMSG_CHAR_ENUM, 7 + bitBuffer.size() + dataBuffer.size()); + data.append(bitBuffer); + if (charCount) + data.append(dataBuffer); SendPacket(&data); } -void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recvData*/) { // remove expired bans PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EXPIRED_BANS); @@ -249,20 +266,20 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/) _charEnumCallback = CharacterDatabase.AsyncQuery(stmt); } -void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data) +void WorldSession::HandleCharCreateOpcode(WorldPacket & recvData) { std::string name; uint8 race_, class_; - recv_data >> name; + recvData >> name; - recv_data >> race_; - recv_data >> class_; + recvData >> race_; + recvData >> class_; // extract other data required for player creating uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId; - recv_data >> gender >> skin >> face; - recv_data >> hairStyle >> hairColor >> facialHair >> outfitId; + recvData >> gender >> skin >> face; + recvData >> hairStyle >> hairColor >> facialHair >> outfitId; WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases @@ -387,7 +404,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data) } delete _charCreateCallback.GetParam(); // Delete existing if any, to make the callback chain reset to stage 0 - _charCreateCallback.SetParam(new CharacterCreateInfo(name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId, recv_data)); + _charCreateCallback.SetParam(new CharacterCreateInfo(name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId, recvData)); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME); stmt->setString(0, name); _charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt)); @@ -670,10 +687,10 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte } } -void WorldSession::HandleCharDeleteOpcode(WorldPacket & recv_data) +void WorldSession::HandleCharDeleteOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; // can't delete loaded character if (ObjectAccessor::FindPlayer(guid)) @@ -733,20 +750,37 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recv_data) SendPacket(&data); } -void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data) +void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) { if (PlayerLoading() || GetPlayer() != NULL) { - sLog->outError(LOG_FILTER_NETWORKIO, "Player tryes to login again, AccountId = %d", GetAccountId()); + sLog->outError(LOG_FILTER_NETWORKIO, "Player tries to login again, AccountId = %d", GetAccountId()); return; } m_playerLoading = true; - uint64 playerGuid = 0; + ObjectGuid playerGuid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd Player Logon Message"); - - recv_data >> playerGuid; + playerGuid[2] = recvData.ReadBit(); + playerGuid[3] = recvData.ReadBit(); + playerGuid[0] = recvData.ReadBit(); + playerGuid[6] = recvData.ReadBit(); + playerGuid[4] = recvData.ReadBit(); + playerGuid[5] = recvData.ReadBit(); + playerGuid[1] = recvData.ReadBit(); + playerGuid[7] = recvData.ReadBit(); + + recvData.ReadByteSeq(playerGuid[2]); + recvData.ReadByteSeq(playerGuid[7]); + recvData.ReadByteSeq(playerGuid[0]); + recvData.ReadByteSeq(playerGuid[3]); + recvData.ReadByteSeq(playerGuid[5]); + recvData.ReadByteSeq(playerGuid[6]); + recvData.ReadByteSeq(playerGuid[1]); + recvData.ReadByteSeq(playerGuid[4]); + + sLog->outDebug(LOG_FILTER_NETWORKIO, "Character (Guid: %u) logging in", GUID_LOPART(playerGuid)); if (!CharCanLogin(GUID_LOPART(playerGuid))) { @@ -766,6 +800,17 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data) _charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder); } +void WorldSession::HandleLoadScreenOpcode(WorldPacket& recvPacket) +{ + sLog->outInfo(LOG_FILTER_GENERAL, "WORLD: Recvd CMSG_LOAD_SCREEN"); + uint32 mapID; + + recvPacket >> mapID; + recvPacket.ReadBit(); + + // TODO: Do something with this packet +} + void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) { uint64 playerGuid = holder->GetGuid(); @@ -800,9 +845,34 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) LoadAccountData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA), PER_CHARACTER_CACHE_MASK); SendAccountDataTimes(PER_CHARACTER_CACHE_MASK); - data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 + bool featureBit4 = true; + data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 7); // checked in 4.2.2 data << uint8(2); // unknown value - data << uint8(0); // enable(1)/disable(0) voice chat interface in client + data << uint32(1); + data << uint32(1); + data << uint32(2); + data << uint32(0); + data.WriteBit(1); + data.WriteBit(1); + data.WriteBit(0); + data.WriteBit(featureBit4); + data.WriteBit(0); + data.WriteBit(0); + data.FlushBits(); + if (featureBit4) + { + data << uint32(1); + data << uint32(0); + data << uint32(10); + data << uint32(60); + } + + //if (featureBit5) + //{ + // data << uint32(0); + // data << uint32(0); + // data << uint32(0); + //} SendPacket(&data); // Send MOTD @@ -849,6 +919,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) Field* fields = resultGuild->Fetch(); pCurrChar->SetInGuild(fields[0].GetUInt32()); pCurrChar->SetRank(fields[1].GetUInt8()); + if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId())) + pCurrChar->SetUInt32Value(PLAYER_GUILDLEVEL, guild->GetLevel()); } else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership { @@ -856,21 +928,20 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) pCurrChar->SetRank(0); } - if (pCurrChar->GetGuildId() != 0) + data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4); + data << uint64(0); + SendPacket(&data); + + data.Initialize(SMSG_HOTFIX_INFO); + HotfixData const& hotfix = sObjectMgr->GetHotfixData(); + data.WriteBits(hotfix.size(), 22); + data.FlushBits(); + for (uint32 i = 0; i < hotfix.size(); ++i) { - if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId())) - guild->SendLoginInfo(this); - else - { - // remove wrong guild data - sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); - pCurrChar->SetInGuild(0); - } + data << uint32(hotfix[i].Type); + data << uint32(hotfix[i].Timestamp); + data << uint32(hotfix[i].Entry); } - - data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4); - data << uint32(0); - data << uint32(0); SendPacket(&data); pCurrChar->SendInitialPacketsBeforeAddToMap(); @@ -914,20 +985,28 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) } sObjectAccessor->AddObject(pCurrChar); - //sLog->outDebug("Player %s added to Map.", pCurrChar->GetName()); + //sLog->outDebug(LOG_FILTER_GENERAL, "Player %s added to Map.", pCurrChar->GetName()); + + if (pCurrChar->GetGuildId() != 0) + { + if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId())) + guild->SendLoginInfo(this); + else + { + // remove wrong guild data + sLog->outError(LOG_FILTER_GENERAL, "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); + pCurrChar->SetInGuild(0); + } + } pCurrChar->SendInitialPacketsAfterAddToMap(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE); - stmt->setUInt32(0, pCurrChar->GetGUIDLow()); - CharacterDatabase.Execute(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_ONLINE); - stmt->setUInt32(0, GetAccountId()); - LoginDatabase.Execute(stmt); pCurrChar->SetInGameTime(getMSTime()); @@ -954,7 +1033,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) - pCurrChar->SetMovement(MOVE_WATER_WALK); + pCurrChar->SendMovementSetWaterWalking(true); } pCurrChar->ContinueTaxiFlight(); @@ -982,7 +1061,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { - pCurrChar->resetTalents(true); + pCurrChar->ResetTalents(true); pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state SendNotification(LANG_RESET_TALENTS); } @@ -1013,30 +1092,30 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) delete holder; } -void WorldSession::HandleSetFactionAtWar(WorldPacket & recv_data) +void WorldSession::HandleSetFactionAtWar(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_FACTION_ATWAR"); uint32 repListID; uint8 flag; - recv_data >> repListID; - recv_data >> flag; + recvData >> repListID; + recvData >> flag; GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag); } //I think this function is never used :/ I dunno, but i guess this opcode not exists -void WorldSession::HandleSetFactionCheat(WorldPacket & /*recv_data*/) +void WorldSession::HandleSetFactionCheat(WorldPacket & /*recvData*/) { sLog->outError(LOG_FILTER_NETWORKIO, "WORLD SESSION: HandleSetFactionCheat, not expected call, please report."); GetPlayer()->GetReputationMgr().SendStates(); } -void WorldSession::HandleTutorialFlag(WorldPacket & recv_data) +void WorldSession::HandleTutorialFlag(WorldPacket & recvData) { uint32 data; - recv_data >> data; + recvData >> data; uint8 index = uint8(data / 32); if (index >= MAX_ACCOUNT_TUTORIAL_VALUES) @@ -1049,57 +1128,57 @@ void WorldSession::HandleTutorialFlag(WorldPacket & recv_data) SetTutorialInt(index, flag); } -void WorldSession::HandleTutorialClear(WorldPacket & /*recv_data*/) +void WorldSession::HandleTutorialClear(WorldPacket & /*recvData*/) { for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) SetTutorialInt(i, 0xFFFFFFFF); } -void WorldSession::HandleTutorialReset(WorldPacket & /*recv_data*/) +void WorldSession::HandleTutorialReset(WorldPacket & /*recvData*/) { for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) SetTutorialInt(i, 0x00000000); } -void WorldSession::HandleSetWatchedFactionOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetWatchedFactionOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_WATCHED_FACTION"); uint32 fact; - recv_data >> fact; + recvData >> fact; GetPlayer()->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fact); } -void WorldSession::HandleSetFactionInactiveOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetFactionInactiveOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_FACTION_INACTIVE"); uint32 replistid; uint8 inactive; - recv_data >> replistid >> inactive; + recvData >> replistid >> inactive; _player->GetReputationMgr().SetInactive(replistid, inactive); } -void WorldSession::HandleShowingHelmOpcode(WorldPacket& recv_data) +void WorldSession::HandleShowingHelmOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SHOWING_HELM for %s", _player->GetName()); - recv_data.read_skip<uint8>(); // unknown, bool? + recvData.read_skip<uint8>(); // unknown, bool? _player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM); } -void WorldSession::HandleShowingCloakOpcode(WorldPacket& recv_data) +void WorldSession::HandleShowingCloakOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SHOWING_CLOAK for %s", _player->GetName()); - recv_data.read_skip<uint8>(); // unknown, bool? + recvData.read_skip<uint8>(); // unknown, bool? _player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK); } -void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data) +void WorldSession::HandleCharRenameOpcode(WorldPacket& recvData) { uint64 guid; std::string newName; - recv_data >> guid; - recv_data >> newName; + recvData >> guid; + recvData >> newName; // prevent character rename to invalid name if (!normalizePlayerName(newName)) @@ -1189,11 +1268,11 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult resu sWorld->UpdateCharacterNameData(guidLow, newName); } -void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) +void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; // not accept declined names for unsupported languages std::string name; @@ -1228,7 +1307,7 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) std::string name2; DeclinedName declinedname; - recv_data >> name2; + recvData >> name2; if (name2 != name) // character have different name { @@ -1241,7 +1320,7 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { - recv_data >> declinedname.name[i]; + recvData >> declinedname.name[i]; if (!normalizePlayerName(declinedname.name[i])) { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); @@ -1286,12 +1365,12 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) SendPacket(&data); } -void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) +void WorldSession::HandleAlterAppearance(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ALTER_APPEARANCE"); uint32 Hair, Color, FacialHair, SkinColor; - recv_data >> Hair >> Color >> FacialHair >> SkinColor; + recvData >> Hair >> Color >> FacialHair >> SkinColor; BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair); @@ -1308,12 +1387,12 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender())) return; - uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor); + uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor); // 0 - ok // 1, 3 - not enough money // 2 - you have to seat on barber chair - if (!_player->HasEnoughMoney(Cost)) + if (!_player->HasEnoughMoney((uint64)cost)) { WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); data << uint32(1); // no money @@ -1327,8 +1406,8 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) SendPacket(&data); } - _player->ModifyMoney(-int32(Cost)); // it isn't free - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost); + _player->ModifyMoney(-int64(cost)); // it isn't free + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, cost); _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id)); _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color)); @@ -1336,15 +1415,15 @@ void WorldSession::HandleAlterAppearance(WorldPacket & recv_data) if (bs_skinColor) _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id)); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); _player->SetStandState(0); // stand up } -void WorldSession::HandleRemoveGlyph(WorldPacket & recv_data) +void WorldSession::HandleRemoveGlyph(WorldPacket & recvData) { uint32 slot; - recv_data >> slot; + recvData >> slot; if (slot >= MAX_GLYPH_SLOT_INDEX) { @@ -1352,7 +1431,7 @@ void WorldSession::HandleRemoveGlyph(WorldPacket & recv_data) return; } - if (uint32 glyph = _player->GetGlyph(slot)) + if (uint32 glyph = _player->GetGlyph(_player->GetActiveSpec(), slot)) { if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph)) { @@ -1363,21 +1442,19 @@ void WorldSession::HandleRemoveGlyph(WorldPacket & recv_data) } } -void WorldSession::HandleCharCustomize(WorldPacket& recv_data) +void WorldSession::HandleCharCustomize(WorldPacket& recvData) { uint64 guid; std::string newName; - recv_data >> guid; - recv_data >> newName; + recvData >> guid; + recvData >> newName; uint8 gender, skin, face, hairStyle, hairColor, facialHair; - recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face; + recvData >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AT_LOGIN); - stmt->setUInt32(0, GUID_LOPART(guid)); - PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) @@ -1479,23 +1556,23 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) SendPacket(&data); } -void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) +void WorldSession::HandleEquipmentSetSave(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_EQUIPMENT_SET_SAVE"); uint64 setGuid; - recv_data.readPackGUID(setGuid); + recvData.readPackGUID(setGuid); uint32 index; - recv_data >> index; + recvData >> index; if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount return; std::string name; - recv_data >> name; + recvData >> name; std::string iconName; - recv_data >> iconName; + recvData >> iconName; EquipmentSet eqSet; @@ -1507,7 +1584,7 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { uint64 itemGuid; - recv_data.readPackGUID(itemGuid); + recvData.readPackGUID(itemGuid); // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set) if (itemGuid == 1) @@ -1531,17 +1608,17 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) _player->SetEquipmentSet(index, eqSet); } -void WorldSession::HandleEquipmentSetDelete(WorldPacket &recv_data) +void WorldSession::HandleEquipmentSetDelete(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_EQUIPMENT_SET_DELETE"); uint64 setGuid; - recv_data.readPackGUID(setGuid); + recvData.readPackGUID(setGuid); _player->DeleteEquipmentSet(setGuid); } -void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) +void WorldSession::HandleEquipmentSetUse(WorldPacket &recvData) { if (_player->isInCombat()) return; @@ -1551,10 +1628,10 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { uint64 itemGuid; - recv_data.readPackGUID(itemGuid); + recvData.readPackGUID(itemGuid); uint8 srcbag, srcslot; - recv_data >> srcbag >> srcslot; + recvData >> srcbag >> srcslot; sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "Item " UI64FMTD ": srcbag %u, srcslot %u", itemGuid, srcbag, srcslot); @@ -1596,15 +1673,15 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) SendPacket(&data); } -void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) +void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) { // TODO: Move queries to prepared statements uint64 guid; std::string newname; uint8 gender, skin, face, hairStyle, hairColor, facialHair, race; - recv_data >> guid; - recv_data >> newname; - recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face >> race; + recvData >> guid; + recvData >> newname; + recvData >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face >> race; uint32 lowGuid = GUID_LOPART(guid); @@ -1626,7 +1703,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) uint32 playerClass = uint32(fields[0].GetUInt8()); uint32 level = uint32(fields[1].GetUInt8()); uint32 at_loginFlags = fields[2].GetUInt16(); - uint32 used_loginFlag = ((recv_data.GetOpcode() == CMSG_CHAR_RACE_CHANGE) ? AT_LOGIN_CHANGE_RACE : AT_LOGIN_CHANGE_FACTION); + uint32 used_loginFlag = ((recvData.GetOpcode() == CMSG_CHAR_RACE_CHANGE) ? AT_LOGIN_CHANGE_RACE : AT_LOGIN_CHANGE_FACTION); if (!sObjectMgr->GetPlayerInfo(race, playerClass)) { @@ -1718,6 +1795,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) switch (race) { case RACE_ORC: + case RACE_GOBLIN: case RACE_TAUREN: case RACE_UNDEAD_PLAYER: case RACE_TROLL: @@ -1766,6 +1844,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) case RACE_NIGHTELF: stmt->setUInt16(1, 113); break; + case RACE_WORGEN: + stmt->setUInt16(1, 791); + break; case RACE_UNDEAD_PLAYER: stmt->setUInt16(1, 673); break; @@ -1778,12 +1859,15 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) case RACE_BLOODELF: stmt->setUInt16(1, 137); break; + case RACE_GOBLIN: + stmt->setUInt16(1, 792); + break; } trans->Append(stmt); } - if (recv_data.GetOpcode() == CMSG_CHAR_FACTION_CHANGE) + if (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE) { // Delete all Flypaths PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH); @@ -2017,3 +2101,30 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data) data << uint8(race); SendPacket(&data); } + +void WorldSession::HandleRandomizeCharNameOpcode(WorldPacket& recvData) +{ + uint8 gender, race; + + recvData >> race; + recvData >> gender; + + if (!Player::IsValidRace(race)) + { + sLog->outError(LOG_FILTER_GENERAL, "Invalid race (%u) sent by accountId: %u", race, GetAccountId()); + return; + } + + if (!Player::IsValidGender(gender)) + { + sLog->outError(LOG_FILTER_GENERAL, "Invalid gender (%u) sent by accountId: %u", gender, GetAccountId()); + return; + } + + std::string const* name = GetRandomCharacterName(race, gender); + WorldPacket data(SMSG_RANDOMIZE_CHAR_NAME, 10); + data.WriteBit(0); // unk + data.WriteBits(name->size(), 7); + data.append(name->c_str(), name->size()); + SendPacket(&data); +} diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 880f2df86f7..8b994c2fedc 100755..100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -63,131 +63,180 @@ bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg return true; } -void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) +void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { - uint32 type; + uint32 type = 0; uint32 lang; - recv_data >> type; - recv_data >> lang; + switch(recvData.GetOpcode()) + { + case CMSG_MESSAGECHAT_SAY: + type = CHAT_MSG_SAY; + break; + case CMSG_MESSAGECHAT_YELL: + type = CHAT_MSG_YELL; + break; + case CMSG_MESSAGECHAT_CHANNEL: + type = CHAT_MSG_CHANNEL; + break; + case CMSG_MESSAGECHAT_WHISPER: + type = CHAT_MSG_WHISPER; + break; + case CMSG_MESSAGECHAT_GUILD: + type = CHAT_MSG_GUILD; + break; + case CMSG_MESSAGECHAT_OFFICER: + type = CHAT_MSG_OFFICER; + break; + case CMSG_MESSAGECHAT_AFK: + type = CHAT_MSG_AFK; + break; + case CMSG_MESSAGECHAT_DND: + type = CHAT_MSG_DND; + break; + case CMSG_MESSAGECHAT_EMOTE: + type = CHAT_MSG_EMOTE; + break; + case CMSG_MESSAGECHAT_PARTY: + type = CHAT_MSG_PARTY; + break; + case CMSG_MESSAGECHAT_RAID: + type = CHAT_MSG_RAID; + break; + case CMSG_MESSAGECHAT_BATTLEGROUND: + type = CHAT_MSG_BATTLEGROUND; + break; + case CMSG_MESSAGECHAT_RAID_WARNING: + type = CHAT_MSG_RAID_WARNING; + break; + default: + sLog->outInfo(LOG_FILTER_NETWORKIO, "HandleMessagechatOpcode : Unknown chat opcode (%u)", recvData.GetOpcode()); + recvData.hexlike(); + return; + } if (type >= MAX_CHAT_MSG_TYPE) { sLog->outError(LOG_FILTER_NETWORKIO, "CHAT: Wrong message type received: %u", type); - recv_data.rfinish(); + recvData.rfinish(); return; } Player* sender = GetPlayer(); - //sLog->outDebug("CHAT: packet received. type %u, lang %u", type, lang); + //sLog->outDebug(LOG_FILTER_GENERAL, "CHAT: packet received. type %u, lang %u", type, lang); - // prevent talking at unknown language (cheating) - LanguageDesc const* langDesc = GetLanguageDescByID(lang); - if (!langDesc) + // no language sent with emote packet. + if (type != CHAT_MSG_EMOTE && type != CHAT_MSG_AFK && type != CHAT_MSG_DND) { - SendNotification(LANG_UNKNOWN_LANGUAGE); - recv_data.rfinish(); - return; - } - if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) - { - // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) - Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); - bool foundAura = false; - for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) + recvData >> lang; + + // prevent talking at unknown language (cheating) + LanguageDesc const* langDesc = GetLanguageDescByID(lang); + if (!langDesc) { - if ((*i)->GetMiscValue() == int32(lang)) - { - foundAura = true; - break; - } + SendNotification(LANG_UNKNOWN_LANGUAGE); + recvData.rfinish(); + return; } - if (!foundAura) + if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) { - SendNotification(LANG_NOT_LEARNED_LANGUAGE); - recv_data.rfinish(); - return; + // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) + Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); + bool foundAura = false; + for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) + { + if ((*i)->GetMiscValue() == int32(lang)) + { + foundAura = true; + break; + } + } + if (!foundAura) + { + SendNotification(LANG_NOT_LEARNED_LANGUAGE); + recvData.rfinish(); + return; + } } - } - if (lang == LANG_ADDON) - { - if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) + if (lang == LANG_ADDON) { - std::string msg = ""; - recv_data >> msg; + if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) + { + std::string msg = ""; + recvData >> msg; - if (msg.empty()) - return; + if (msg.empty()) + return; - sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg); - } + sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg); + } - // Disabled addon channel? - if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) - return; - } - // LANG_ADDON should not be changed nor be affected by flood control - else - { - // send in universal language if player in .gmon mode (ignore spell effects) - if (sender->isGameMaster()) - lang = LANG_UNIVERSAL; + // Disabled addon channel? + if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) + return; + } + // LANG_ADDON should not be changed nor be affected by flood control else { - // send in universal language in two side iteration allowed mode - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT)) + // send in universal language if player in .gm on mode (ignore spell effects) + if (sender->isGameMaster()) lang = LANG_UNIVERSAL; else { - switch (type) + // send in universal language in two side iteration allowed mode + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT)) + lang = LANG_UNIVERSAL; + else { - case CHAT_MSG_PARTY: - case CHAT_MSG_PARTY_LEADER: - case CHAT_MSG_RAID: - case CHAT_MSG_RAID_LEADER: - case CHAT_MSG_RAID_WARNING: - // allow two side chat at group channel if two side group allowed - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) - lang = LANG_UNIVERSAL; - break; - case CHAT_MSG_GUILD: - case CHAT_MSG_OFFICER: - // allow two side chat at guild channel if two side guild allowed - if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) - lang = LANG_UNIVERSAL; - break; + switch (type) + { + case CHAT_MSG_PARTY: + case CHAT_MSG_PARTY_LEADER: + case CHAT_MSG_RAID: + case CHAT_MSG_RAID_LEADER: + case CHAT_MSG_RAID_WARNING: + // allow two side chat at group channel if two side group allowed + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) + lang = LANG_UNIVERSAL; + break; + case CHAT_MSG_GUILD: + case CHAT_MSG_OFFICER: + // allow two side chat at guild channel if two side guild allowed + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) + lang = LANG_UNIVERSAL; + break; + } } - } - // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) - Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); - if (!ModLangAuras.empty()) - lang = ModLangAuras.front()->GetMiscValue(); - } + // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) + Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); + if (!ModLangAuras.empty()) + lang = ModLangAuras.front()->GetMiscValue(); + } - if (!sender->CanSpeak()) - { - std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); - SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); - recv_data.rfinish(); // Prevent warnings - return; + if (!sender->CanSpeak()) + { + std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); + recvData.rfinish(); // Prevent warnings + return; + } } - - if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) - sender->UpdateSpeakTime(); } + else + lang = LANG_UNIVERSAL; if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) { - std::string msg=""; - recv_data >> msg; - + recvData.rfinish(); SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName()); return; } + uint32 textLength = 0; + uint32 receiverLength = 0; std::string to, channel, msg; bool ignoreChecks = false; switch (type) @@ -196,27 +245,30 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: case CHAT_MSG_PARTY: - case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_RAID: - case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_BATTLEGROUND: - case CHAT_MSG_BATTLEGROUND_LEADER: - recv_data >> msg; + textLength = recvData.ReadBits(9); + msg = recvData.ReadString(textLength); break; case CHAT_MSG_WHISPER: - recv_data >> to; - recv_data >> msg; + receiverLength = recvData.ReadBits(10); + textLength = recvData.ReadBits(9); + to = recvData.ReadString(receiverLength); + msg = recvData.ReadString(textLength); break; case CHAT_MSG_CHANNEL: - recv_data >> channel; - recv_data >> msg; + receiverLength = recvData.ReadBits(10); + textLength = recvData.ReadBits(9); + msg = recvData.ReadString(textLength); + channel = recvData.ReadString(receiverLength); break; case CHAT_MSG_AFK: case CHAT_MSG_DND: - recv_data >> msg; + textLength = recvData.ReadBits(9); + msg = recvData.ReadString(textLength); ignoreChecks = true; break; } @@ -309,8 +361,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) return; } - if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(_player->GetGUID())) - return; + if (group->IsLeader(GetPlayer()->GetGUID())) + type = CHAT_MSG_PARTY_LEADER; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); @@ -343,6 +395,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) } } break; case CHAT_MSG_RAID: + case CHAT_MSG_RAID_LEADER: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); @@ -353,27 +406,13 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) return; } - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - - WorldPacket data; - ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(), NULL); - group->BroadcastPacket(&data, false); - } break; - case CHAT_MSG_RAID_LEADER: - { - // if player is in battleground, he cannot say to battleground members by /ra - Group* group = GetPlayer()->GetOriginalGroup(); - if (!group) - { - group = GetPlayer()->GetGroup(); - if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID())) - return; - } + if (group->IsLeader(GetPlayer()->GetGUID())) + type = CHAT_MSG_RAID_LEADER; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(), NULL); + ChatHandler::FillMessageData(&data, this, uint8(type), lang, "", 0, msg.c_str(), NULL); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: @@ -390,29 +429,20 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: - { - //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() - Group* group = GetPlayer()->GetGroup(); - if (!group || !group->isBGGroup()) - return; - - sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - - WorldPacket data; - ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(), NULL); - group->BroadcastPacket(&data, false); - } break; case CHAT_MSG_BATTLEGROUND_LEADER: { // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); - if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) + if (!group || !group->isBGGroup()) return; + if (group->IsLeader(GetPlayer()->GetGUID())) + type = CHAT_MSG_BATTLEGROUND_LEADER; + sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(), NULL); + ChatHandler::FillMessageData(&data, this, uint8(type), lang, "", 0, msg.c_str(), NULL); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: @@ -479,13 +509,149 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleEmoteOpcode(WorldPacket & recv_data) +void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData) +{ + Player* sender = GetPlayer(); + ChatMsg type; + + switch (recvData.GetOpcode()) + { + case CMSG_MESSAGECHAT_ADDON_BATTLEGROUND: + type = CHAT_MSG_BATTLEGROUND; + break; + case CMSG_MESSAGECHAT_ADDON_GUILD: + type = CHAT_MSG_GUILD; + break; + case CMSG_MESSAGECHAT_ADDON_OFFICER: + type = CHAT_MSG_OFFICER; + break; + case CMSG_MESSAGECHAT_ADDON_PARTY: + type = CHAT_MSG_PARTY; + break; + case CMSG_MESSAGECHAT_ADDON_RAID: + type = CHAT_MSG_RAID; + break; + case CMSG_MESSAGECHAT_ADDON_WHISPER: + type = CHAT_MSG_WHISPER; + break; + default: + sLog->outInfo(LOG_FILTER_NETWORKIO, "HandleAddonMessagechatOpcode: Unknown addon chat opcode (%u)", recvData.GetOpcode()); + recvData.hexlike(); + return; + } + + std::string message; + std::string prefix; + std::string targetName; + + switch (type) + { + case CHAT_MSG_WHISPER: + { + uint32 msgLen = recvData.ReadBits(9); + uint32 prefixLen = recvData.ReadBits(5); + uint32 targetLen = recvData.ReadBits(10); + message = recvData.ReadString(msgLen); + prefix = recvData.ReadString(prefixLen); + targetName = recvData.ReadString(targetLen); + break; + } + case CHAT_MSG_PARTY: + case CHAT_MSG_RAID: + case CHAT_MSG_OFFICER: + { + uint32 prefixLen = recvData.ReadBits(5); + uint32 msgLen = recvData.ReadBits(9); + prefix = recvData.ReadString(prefixLen); + message = recvData.ReadString(msgLen); + break; + } + case CHAT_MSG_GUILD: + case CHAT_MSG_BATTLEGROUND: + { + uint32 msgLen = recvData.ReadBits(9); + uint32 prefixLen = recvData.ReadBits(5); + message = recvData.ReadString(msgLen); + prefix = recvData.ReadString(prefixLen); + break; + } + } + + // Logging enabled? + if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON)) + { + if (message.empty()) + return; + + // Weird way to log stuff... + sScriptMgr->OnPlayerChat(sender, CHAT_MSG_ADDON, LANG_ADDON, message); + } + + // Disabled addon channel? + if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) + return; + + switch (type) + { + case CHAT_MSG_BATTLEGROUND: + { + Group* group = sender->GetGroup(); + if (!group || !group->isBGGroup()) + return; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, type, LANG_ADDON, "", 0, message.c_str(), NULL); + group->BroadcastPacket(&data, false); + break; + } + case CHAT_MSG_GUILD: + case CHAT_MSG_OFFICER: + { + if (sender->GetGuildId()) + if (Guild* guild = sGuildMgr->GetGuildById(sender->GetGuildId())) + guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, message, prefix); + break; + } + case CHAT_MSG_WHISPER: + { + if (!normalizePlayerName(targetName)) + break; + Player* receiver = sObjectAccessor->FindPlayerByName(targetName.c_str()); + if (!receiver) + break; + + sender->WhisperAddon(message, prefix, receiver->GetGUID()); + break; + } + // Messages sent to "RAID" while in a party will get delivered to "PARTY" + case CHAT_MSG_PARTY: + case CHAT_MSG_RAID: + { + + Group* group = sender->GetGroup(); + if (!group || group->isBGGroup()) + break; + + WorldPacket data; + ChatHandler::FillMessageData(&data, this, type, LANG_ADDON, "", 0, message.c_str(), NULL, prefix.c_str()); + group->BroadcastPacket(&data, true, -1, group->GetMemberGroup(sender->GetGUID())); + break; + } + default: + { + sLog->outError(LOG_FILTER_GENERAL, "HandleAddonMessagechatOpcode: unknown addon message type %u", type); + break; + } + } +} + +void WorldSession::HandleEmoteOpcode(WorldPacket & recvData) { if (!GetPlayer()->isAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED)) return; uint32 emote; - recv_data >> emote; + recvData >> emote; sScriptMgr->OnPlayerEmote(GetPlayer(), emote); GetPlayer()->HandleEmoteCommand(emote); } @@ -522,7 +688,7 @@ namespace Trinity }; } // namespace Trinity -void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data) +void WorldSession::HandleTextEmoteOpcode(WorldPacket & recvData) { if (!GetPlayer()->isAlive()) return; @@ -537,9 +703,9 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data) uint32 text_emote, emoteNum; uint64 guid; - recv_data >> text_emote; - recv_data >> emoteNum; - recv_data >> guid; + recvData >> text_emote; + recvData >> emoteNum; + recvData >> guid; sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid); @@ -577,21 +743,21 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket & recv_data) TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker); cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); //Send scripted event call if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI()) ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote); } -void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data) +void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) { uint64 iguid; uint8 unk; //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: Received CMSG_CHAT_IGNORED"); - recv_data >> iguid; - recv_data >> unk; // probably related to spam reporting + recvData >> iguid; + recvData >> unk; // probably related to spam reporting Player* player = ObjectAccessor::FindPlayer(iguid); if (!player || !player->GetSession()) diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 78547d2d0f3..1cd86afc6d2 100755 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -26,10 +26,10 @@ #include "Vehicle.h" #include "VehicleDefines.h" -void WorldSession::HandleAttackSwingOpcode(WorldPacket& recv_data) +void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid)); @@ -66,15 +66,15 @@ void WorldSession::HandleAttackSwingOpcode(WorldPacket& recv_data) _player->Attack(pEnemy, true); } -void WorldSession::HandleAttackStopOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleAttackStopOpcode(WorldPacket & /*recvData*/) { GetPlayer()->AttackStop(); } -void WorldSession::HandleSetSheathedOpcode(WorldPacket& recv_data) +void WorldSession::HandleSetSheathedOpcode(WorldPacket& recvData) { uint32 sheathed; - recv_data >> sheathed; + recvData >> sheathed; //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index e0ff3933c3a..4e492c6626d 100755..100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -31,6 +31,8 @@ #include "Util.h" #include "SpellAuras.h" #include "Vehicle.h" +#include "DB2Structure.h" +#include "DB2Stores.h" class Aura; @@ -47,72 +49,105 @@ class Aura; void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val /* = 0 */) { - WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4); + WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4 + 8); data << uint32(operation); data << member; data << uint32(res); data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S) + data << uint64(0); // player who caused error (in some cases). SendPacket(&data); } -void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data) +void WorldSession::HandleGroupInviteOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE"); - std::string membername; - recv_data >> membername; - recv_data.read_skip<uint32>(); + ObjectGuid crossRealmGuid; // unused + + recvData.read_skip<uint32>(); // Non-zero in cross realm invites + recvData.read_skip<uint32>(); // Always 0 + + crossRealmGuid[2] = recvData.ReadBit(); + crossRealmGuid[7] = recvData.ReadBit(); + + uint8 realmLen = recvData.ReadBits(9); + + crossRealmGuid[3] = recvData.ReadBit(); + + uint8 nameLen = recvData.ReadBits(10); + crossRealmGuid[5] = recvData.ReadBit(); + crossRealmGuid[4] = recvData.ReadBit(); + crossRealmGuid[6] = recvData.ReadBit(); + crossRealmGuid[0] = recvData.ReadBit(); + crossRealmGuid[1] = recvData.ReadBit(); + + recvData.ReadByteSeq(crossRealmGuid[4]); + recvData.ReadByteSeq(crossRealmGuid[7]); + recvData.ReadByteSeq(crossRealmGuid[6]); + + std::string memberName, realmName; + memberName = recvData.ReadString(nameLen); + realmName = recvData.ReadString(realmLen); // unused + + recvData.ReadByteSeq(crossRealmGuid[1]); + recvData.ReadByteSeq(crossRealmGuid[0]); + recvData.ReadByteSeq(crossRealmGuid[5]); + recvData.ReadByteSeq(crossRealmGuid[3]); + recvData.ReadByteSeq(crossRealmGuid[2]); + // attempt add selected player // cheating - if (!normalizePlayerName(membername)) + if (!normalizePlayerName(memberName)) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } - Player* player = sObjectAccessor->FindPlayerByName(membername.c_str()); + Player* player = sObjectAccessor->FindPlayerByName(memberName.c_str()); // no player if (!player) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->isGameMaster() && player->isGameMaster()) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->isGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); return; } + ObjectGuid invitedGuid = player->GetGUID(); + Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); @@ -123,17 +158,63 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data) // player already in another group or invited if (group2 || player->GetGroupInvite()) { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group - WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size - data << uint8(0); // invited/already in group flag - data << GetPlayer()->GetName(); // max len 48 - data << uint32(0); // unk - data << uint8(0); // count - data << uint32(0); // unk + WorldPacket data(SMSG_GROUP_INVITE, 45); + + data.WriteBit(0); + + data.WriteBit(invitedGuid[0]); + data.WriteBit(invitedGuid[3]); + data.WriteBit(invitedGuid[2]); + + data.WriteBit(0); // Inverse already in group + + data.WriteBit(invitedGuid[6]); + data.WriteBit(invitedGuid[5]); + + data.WriteBits(0, 9); // Realm name + + data.WriteBit(invitedGuid[4]); + + data.WriteBits(strlen(player->GetName()), 7); // Invited name length + + data.WriteBits(0, 24); // Count 2 + + data.WriteBit(0); + + data.WriteBit(invitedGuid[1]); + data.WriteBit(invitedGuid[7]); + + data.FlushBits(); + + data.WriteByteSeq(invitedGuid[1]); + data.WriteByteSeq(invitedGuid[4]); + + data << int32(getMSTime()); + data << int32(0); + data << int32(0); + + data.WriteByteSeq(invitedGuid[6]); + data.WriteByteSeq(invitedGuid[0]); + data.WriteByteSeq(invitedGuid[2]); + data.WriteByteSeq(invitedGuid[3]); + + // for count2 { int32(0) } + + data.WriteByteSeq(invitedGuid[5]); + + // data.append(realm name); + + data.WriteByteSeq(invitedGuid[7]); + + data.append((uint8 const*)player->GetName(), strlen(player->GetName())); // invited name + + data << int32(0); + player->GetSession()->SendPacket(&data); } @@ -184,101 +265,146 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data) } // ok, we do it - WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size - data << uint8(1); // invited/already in group flag - data << GetPlayer()->GetName(); // max len 48 - data << uint32(0); // unk - data << uint8(0); // count - data << uint32(0); // unk + WorldPacket data(SMSG_GROUP_INVITE, 45); + + data.WriteBit(0); + + data.WriteBit(invitedGuid[0]); + data.WriteBit(invitedGuid[3]); + data.WriteBit(invitedGuid[2]); + + data.WriteBit(1); // Inverse already in group + + data.WriteBit(invitedGuid[6]); + data.WriteBit(invitedGuid[5]); + + data.WriteBits(0, 9); // Realm name + + data.WriteBit(invitedGuid[4]); + + data.WriteBits(strlen(player->GetName()), 7); // Invited name length + + data.WriteBits(0, 24); // Count 2 + + data.WriteBit(0); + + data.WriteBit(invitedGuid[1]); + data.WriteBit(invitedGuid[7]); + + data.FlushBits(); + + data.WriteByteSeq(invitedGuid[1]); + data.WriteByteSeq(invitedGuid[4]); + + data << int32(getMSTime()); + data << int32(0); + data << int32(0); + + data.WriteByteSeq(invitedGuid[6]); + data.WriteByteSeq(invitedGuid[0]); + data.WriteByteSeq(invitedGuid[2]); + data.WriteByteSeq(invitedGuid[3]); + + // for count2 { int32(0) } + + data.WriteByteSeq(invitedGuid[5]); + + // data.append(realm name); + + data.WriteByteSeq(invitedGuid[7]); + + data.append((uint8 const*)player->GetName(), strlen(player->GetName())); // invited name + + data << int32(0); + player->GetSession()->SendPacket(&data); - SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); + SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); } -void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recv_data) +void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_ACCEPT"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE_RESPONSE"); + + bool accept = !recvData.ReadBit(); + if (!accept) + recvData.read_skip<uint32>(); // unk - recv_data.read_skip<uint32>(); Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; - // Remove player from invitees in any case - group->RemoveInvite(GetPlayer()); - - if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) - { - sLog->outError(LOG_FILTER_NETWORKIO, "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); - return; - } - - // Group is full - if (group->IsFull()) + if (accept) { - SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); - return; - } - - Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); + // Remove player from invitees in any case + group->RemoveInvite(GetPlayer()); - // Forming a new group, create it - if (!group->IsCreated()) - { - // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented - if (!leader) + if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { - group->RemoveAllInvites(); + sLog->outError(LOG_FILTER_NETWORKIO, "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } - // If we're about to create a group there really should be a leader present - ASSERT(leader); - group->RemoveInvite(leader); - group->Create(leader); - sGroupMgr->AddGroup(group); - } + // Group is full + if (group->IsFull()) + { + SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); + return; + } - // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! - if (!group->AddMember(GetPlayer())) - return; + Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); - group->BroadcastGroupUpdate(); -} + // Forming a new group, create it + if (!group->IsCreated()) + { + // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented + if (!leader) + { + group->RemoveAllInvites(); + return; + } -void WorldSession::HandleGroupDeclineOpcode(WorldPacket & /*recv_data*/) -{ - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_DECLINE"); + // If we're about to create a group there really should be a leader present + ASSERT(leader); + group->RemoveInvite(leader); + group->Create(leader); + sGroupMgr->AddGroup(group); + } - Group* group = GetPlayer()->GetGroupInvite(); - if (!group) - return; + // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! + if (!group->AddMember(GetPlayer())) + return; - // Remember leader if online (group pointer will be invalid if group gets disbanded) - Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); + group->BroadcastGroupUpdate(); + } + else + { + // Remember leader if online (group pointer will be invalid if group gets disbanded) + Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); - // uninvite, group can be deleted - GetPlayer()->UninviteFromGroup(); + // uninvite, group can be deleted + GetPlayer()->UninviteFromGroup(); - if (!leader || !leader->GetSession()) - return; + if (!leader || !leader->GetSession()) + return; - // report - std::string name = std::string(GetPlayer()->GetName()); - WorldPacket data(SMSG_GROUP_DECLINE, name.length()); - data << name.c_str(); - leader->GetSession()->SendPacket(&data); + // report + std::string name = std::string(GetPlayer()->GetName()); + WorldPacket data(SMSG_GROUP_DECLINE, name.length()); + data << name.c_str(); + leader->GetSession()->SendPacket(&data); + } } -void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data) +void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_UNINVITE_GUID"); uint64 guid; std::string reason; - recv_data >> guid; - recv_data >> reason; + recvData >> guid; + recvData >> reason; //can't uninvite yourself if (guid == GetPlayer()->GetGUID()) @@ -319,12 +445,12 @@ void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data) SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S); } -void WorldSession::HandleGroupUninviteOpcode(WorldPacket & recv_data) +void WorldSession::HandleGroupUninviteOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_UNINVITE"); std::string membername; - recv_data >> membername; + recvData >> membername; // player not found if (!normalizePlayerName(membername)) @@ -363,12 +489,12 @@ void WorldSession::HandleGroupUninviteOpcode(WorldPacket & recv_data) SendPartyResult(PARTY_OP_UNINVITE, membername, ERR_TARGET_NOT_IN_GROUP_S); } -void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket & recv_data) +void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SET_LEADER"); uint64 guid; - recv_data >> guid; + recvData >> guid; Player* player = ObjectAccessor::FindPlayer(guid); Group* group = GetPlayer()->GetGroup(); @@ -384,7 +510,7 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket & recv_data) group->SendUpdate(); } -void WorldSession::HandleGroupDisbandOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleGroupDisbandOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_DISBAND"); @@ -407,14 +533,14 @@ void WorldSession::HandleGroupDisbandOpcode(WorldPacket & /*recv_data*/) GetPlayer()->RemoveFromGroup(GROUP_REMOVEMETHOD_LEAVE); } -void WorldSession::HandleLootMethodOpcode(WorldPacket & recv_data) +void WorldSession::HandleLootMethodOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_LOOT_METHOD"); uint32 lootMethod; uint64 lootMaster; uint32 lootThreshold; - recv_data >> lootMethod >> lootMaster >> lootThreshold; + recvData >> lootMethod >> lootMaster >> lootThreshold; Group* group = GetPlayer()->GetGroup(); if (!group) @@ -450,15 +576,15 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData) switch (rollType) { case ROLL_NEED: - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1); break; case ROLL_GREED: - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); break; } } -void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data) +void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_MINIMAP_PING"); @@ -466,10 +592,10 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data) return; float x, y; - recv_data >> x; - recv_data >> y; + recvData >> x; + recvData >> y; - //sLog->outDebug("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y); + //sLog->outDebug(LOG_FILTER_GENERAL, "Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y); /** error handling **/ /********************/ @@ -482,13 +608,13 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recv_data) GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); } -void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data) +void WorldSession::HandleRandomRollOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_RANDOM_ROLL"); uint32 minimum, maximum, roll; - recv_data >> minimum; - recv_data >> maximum; + recvData >> minimum; + recvData >> maximum; /** error handling **/ if (minimum > maximum || maximum > 10000) // < 32768 for urand call @@ -498,7 +624,7 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data) // everything's fine, do it roll = urand(minimum, maximum); - //sLog->outDebug("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll); + //sLog->outDebug(LOG_FILTER_GENERAL, "ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll); WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8); data << uint32(minimum); @@ -511,7 +637,7 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recv_data) SendPacket(&data); } -void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket & recv_data) +void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_RAID_TARGET_UPDATE"); @@ -520,7 +646,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket & recv_data) return; uint8 x; - recv_data >> x; + recvData >> x; /** error handling **/ /********************/ @@ -536,12 +662,12 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket & recv_data) return; uint64 guid; - recv_data >> guid; + recvData >> guid; group->SetTargetIcon(x, _player->GetGUID(), guid); } } -void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_RAID_CONVERT"); @@ -552,17 +678,25 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket & /*recv_data*/) if (_player->InBattleground()) return; - /** error handling **/ + // error handling if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2) return; - /********************/ // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code) SendPartyResult(PARTY_OP_INVITE, "", ERR_PARTY_RESULT_OK); - group->ConvertToRaid(); + + // New 4.x: it is now possible to convert a raid to a group if member count is 5 or less + + bool toRaid; + recvData >> toRaid; + + if (toRaid) + group->ConvertToRaid(); + else + group->ConvertToGroup(); } -void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data) +void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_CHANGE_SUB_GROUP"); @@ -573,8 +707,8 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data) std::string name; uint8 groupNr; - recv_data >> name; - recv_data >> groupNr; + recvData >> name; + recvData >> groupNr; if (groupNr >= MAX_RAID_SUBGROUPS) return; @@ -601,7 +735,17 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data) group->ChangeMembersGroup(guid, groupNr); } -void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket & recv_data) +void WorldSession::HandleGroupSwapSubGroupOpcode(WorldPacket & recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SWAP_SUB_GROUP"); + std::string unk1; + std::string unk2; + + recvData >> unk1; + recvData >> unk2; +} + +void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_ASSISTANT_LEADER"); @@ -614,15 +758,15 @@ void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket & recv_data) uint64 guid; bool apply; - recv_data >> guid; - recv_data >> apply; + recvData >> guid; + recvData >> apply; group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT); group->SendUpdate(); } -void WorldSession::HandlePartyAssignmentOpcode(WorldPacket & recv_data) +void WorldSession::HandlePartyAssignmentOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_PARTY_ASSIGNMENT"); @@ -637,8 +781,8 @@ void WorldSession::HandlePartyAssignmentOpcode(WorldPacket & recv_data) uint8 assignment; bool apply; uint64 guid; - recv_data >> assignment >> apply; - recv_data >> guid; + recvData >> assignment >> apply; + recvData >> guid; switch (assignment) { @@ -656,7 +800,7 @@ void WorldSession::HandlePartyAssignmentOpcode(WorldPacket & recv_data) group->SendUpdate(); } -void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket & recv_data) +void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_RAID_READY_CHECK"); @@ -664,7 +808,7 @@ void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket & recv_data) if (!group) return; - if (recv_data.empty()) // request + if (recvData.empty()) // request { /** error handling **/ if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) @@ -681,7 +825,7 @@ void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket & recv_data) else // answer { uint8 state; - recv_data >> state; + recvData >> state; // everything's fine, do it WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9); @@ -691,7 +835,7 @@ void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleRaidReadyCheckFinishedOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleRaidReadyCheckFinishedOpcode(WorldPacket& /*recvData*/) { //Group* group = GetPlayer()->GetGroup(); //if (!group) @@ -871,11 +1015,11 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke } /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ -void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data) +void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; - recv_data >> Guid; + recvData >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) @@ -961,28 +1105,28 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data) SendPacket(&data); } -/*!*/void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket & /*recv_data*/) +/*!*/void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket & /*recvData*/) { // every time the player checks the character screen _player->SendRaidInfo(); } -/*void WorldSession::HandleGroupCancelOpcode(WorldPacket & recv_data) +/*void WorldSession::HandleGroupCancelOpcode(WorldPacket & recvData) { - sLog->outDebug("WORLD: got CMSG_GROUP_CANCEL."); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: got CMSG_GROUP_CANCEL."); }*/ -void WorldSession::HandleOptOutOfLootOpcode(WorldPacket & recv_data) +void WorldSession::HandleOptOutOfLootOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_OPT_OUT_OF_LOOT"); - uint32 passOnLoot; - recv_data >> passOnLoot; // 1 always pass, 0 do not pass + bool passOnLoot; + recvData >> passOnLoot; // 1 always pass, 0 do not pass // ignore if player not loaded if (!GetPlayer()) // needed because STATUS_AUTHED { - if (passOnLoot != 0) + if (passOnLoot) sLog->outError(LOG_FILTER_NETWORKIO, "CMSG_OPT_OUT_OF_LOOT value<>0 for not-loaded character!"); return; } diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index ccd1c931f51..73631e2f003 100755 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -36,7 +36,7 @@ inline Guild* _GetPlayerGuild(WorldSession* session, bool sendError = false) if (Guild* guild = sGuildMgr->GetGuildById(guildId)) // Find guild by id return guild; if (sendError) - Guild::SendCommandResult(session, GUILD_CREATE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD); + Guild::SendCommandResult(session, GUILD_CREATE, ERR_GUILD_PLAYER_NOT_IN_GUILD); return NULL; } @@ -44,13 +44,18 @@ void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_QUERY"); - uint32 guildId; - recvPacket >> guildId; - // Use received guild id to access guild method (not player's guild id) - if (Guild* guild = sGuildMgr->GetGuildById(guildId)) - guild->HandleQuery(this); - else - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD); + uint64 guildGuid, playerGuid; + recvPacket >> guildGuid >> playerGuid; + + // If guild doesn't exist or player is not part of the guild send error + if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid)) + if (guild->IsMember(playerGuid)) + { + guild->HandleQuery(this); + return; + } + + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_PLAYER_NOT_IN_GUILD); } void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket) @@ -74,8 +79,8 @@ void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_INVITE"); - std::string invitedName; - recvPacket >> invitedName; + uint32 nameLength = recvPacket.ReadBits(7); + std::string invitedName = recvPacket.ReadString(nameLength); if (normalizePlayerName(invitedName)) if (Guild* guild = _GetPlayerGuild(this, true)) @@ -86,12 +91,28 @@ void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_REMOVE"); - std::string playerName; - recvPacket >> playerName; + ObjectGuid playerGuid; + + playerGuid[6] = recvPacket.ReadBit(); + playerGuid[5] = recvPacket.ReadBit(); + playerGuid[4] = recvPacket.ReadBit(); + playerGuid[0] = recvPacket.ReadBit(); + playerGuid[1] = recvPacket.ReadBit(); + playerGuid[3] = recvPacket.ReadBit(); + playerGuid[7] = recvPacket.ReadBit(); + playerGuid[2] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(playerGuid[2]); + recvPacket.ReadByteSeq(playerGuid[6]); + recvPacket.ReadByteSeq(playerGuid[5]); + recvPacket.ReadByteSeq(playerGuid[7]); + recvPacket.ReadByteSeq(playerGuid[1]); + recvPacket.ReadByteSeq(playerGuid[4]); + recvPacket.ReadByteSeq(playerGuid[3]); + recvPacket.ReadByteSeq(playerGuid[0]); - if (normalizePlayerName(playerName)) - if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleRemoveMember(this, playerName); + if (Guild* guild = _GetPlayerGuild(this, true)) + guild->HandleRemoveMember(this, playerGuid); } void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/) @@ -120,11 +141,13 @@ void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/) guild->SendInfo(this); } -void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildRosterOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ROSTER"); - if (Guild* guild = _GetPlayerGuild(this)) + recvPacket.rfinish(); + + if (Guild* guild = _GetPlayerGuild(this, true)) guild->HandleRoster(this); } @@ -132,24 +155,104 @@ void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_PROMOTE"); - std::string playerName; - recvPacket >> playerName; + ObjectGuid targetGuid; + + targetGuid[7] = recvPacket.ReadBit(); + targetGuid[2] = recvPacket.ReadBit(); + targetGuid[5] = recvPacket.ReadBit(); + targetGuid[6] = recvPacket.ReadBit(); + targetGuid[1] = recvPacket.ReadBit(); + targetGuid[0] = recvPacket.ReadBit(); + targetGuid[3] = recvPacket.ReadBit(); + targetGuid[4] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(targetGuid[0]); + recvPacket.ReadByteSeq(targetGuid[5]); + recvPacket.ReadByteSeq(targetGuid[2]); + recvPacket.ReadByteSeq(targetGuid[3]); + recvPacket.ReadByteSeq(targetGuid[6]); + recvPacket.ReadByteSeq(targetGuid[4]); + recvPacket.ReadByteSeq(targetGuid[1]); + recvPacket.ReadByteSeq(targetGuid[7]); - if (normalizePlayerName(playerName)) - if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleUpdateMemberRank(this, playerName, false); + if (Guild* guild = _GetPlayerGuild(this, true)) + guild->HandleUpdateMemberRank(this, targetGuid, false); } void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_DEMOTE"); - std::string playerName; - recvPacket >> playerName; + ObjectGuid targetGuid; + + targetGuid[7] = recvPacket.ReadBit(); + targetGuid[1] = recvPacket.ReadBit(); + targetGuid[5] = recvPacket.ReadBit(); + targetGuid[6] = recvPacket.ReadBit(); + targetGuid[2] = recvPacket.ReadBit(); + targetGuid[3] = recvPacket.ReadBit(); + targetGuid[0] = recvPacket.ReadBit(); + targetGuid[4] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(targetGuid[1]); + recvPacket.ReadByteSeq(targetGuid[2]); + recvPacket.ReadByteSeq(targetGuid[7]); + recvPacket.ReadByteSeq(targetGuid[5]); + recvPacket.ReadByteSeq(targetGuid[6]); + recvPacket.ReadByteSeq(targetGuid[0]); + recvPacket.ReadByteSeq(targetGuid[4]); + recvPacket.ReadByteSeq(targetGuid[3]); - if (normalizePlayerName(playerName)) - if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleUpdateMemberRank(this, playerName, true); + if (Guild* guild = _GetPlayerGuild(this, true)) + guild->HandleUpdateMemberRank(this, targetGuid, true); +} + +void WorldSession::HandleGuildAssignRankOpcode(WorldPacket& recvPacket) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ASSIGN_MEMBER_RANK"); + + ObjectGuid targetGuid; + ObjectGuid setterGuid; + + uint32 rankId; + recvPacket >> rankId; + + targetGuid[1] = recvPacket.ReadBit(); + targetGuid[7] = recvPacket.ReadBit(); + setterGuid[4] = recvPacket.ReadBit(); + setterGuid[2] = recvPacket.ReadBit(); + targetGuid[4] = recvPacket.ReadBit(); + targetGuid[5] = recvPacket.ReadBit(); + targetGuid[6] = recvPacket.ReadBit(); + setterGuid[1] = recvPacket.ReadBit(); + setterGuid[7] = recvPacket.ReadBit(); + targetGuid[2] = recvPacket.ReadBit(); + targetGuid[3] = recvPacket.ReadBit(); + targetGuid[0] = recvPacket.ReadBit(); + setterGuid[6] = recvPacket.ReadBit(); + setterGuid[3] = recvPacket.ReadBit(); + setterGuid[0] = recvPacket.ReadBit(); + setterGuid[5] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(targetGuid[0]); + recvPacket.ReadByteSeq(setterGuid[1]); + recvPacket.ReadByteSeq(setterGuid[3]); + recvPacket.ReadByteSeq(setterGuid[5]); + recvPacket.ReadByteSeq(targetGuid[7]); + recvPacket.ReadByteSeq(targetGuid[3]); + recvPacket.ReadByteSeq(setterGuid[0]); + recvPacket.ReadByteSeq(targetGuid[1]); + recvPacket.ReadByteSeq(setterGuid[6]); + recvPacket.ReadByteSeq(targetGuid[2]); + recvPacket.ReadByteSeq(targetGuid[5]); + recvPacket.ReadByteSeq(targetGuid[4]); + recvPacket.ReadByteSeq(setterGuid[2]); + recvPacket.ReadByteSeq(setterGuid[4]); + recvPacket.ReadByteSeq(targetGuid[6]); + recvPacket.ReadByteSeq(setterGuid[7]); + + if (Guild* guild = _GetPlayerGuild(this, true)) + guild->HandleSetMemberRank(this, targetGuid, setterGuid, rankId); } void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) @@ -184,107 +287,104 @@ void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_MOTD"); - std::string motd; // Empty by default - if (!recvPacket.empty()) - recvPacket >> motd; + uint32 motdLength = recvPacket.ReadBits(11); + std::string motd = recvPacket.ReadString(motdLength); if (Guild* guild = _GetPlayerGuild(this, true)) guild->HandleSetMOTD(this, motd); } -void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildSetNoteOpcode(WorldPacket& recvPacket) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_SET_PUBLIC_NOTE"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_SET_NOTE"); - std::string playerName; - recvPacket >> playerName; + ObjectGuid playerGuid; - std::string publicNote; - recvPacket >> publicNote; + playerGuid[1] = recvPacket.ReadBit(); + playerGuid[4] = recvPacket.ReadBit(); + playerGuid[5] = recvPacket.ReadBit(); + playerGuid[3] = recvPacket.ReadBit(); + playerGuid[0] = recvPacket.ReadBit(); + playerGuid[7] = recvPacket.ReadBit(); + bool type = recvPacket.ReadBit(); // 0 == Officer, 1 == Public + playerGuid[6] = recvPacket.ReadBit(); + uint32 noteLength = recvPacket.ReadBits(8); + playerGuid[2] = recvPacket.ReadBit(); - if (normalizePlayerName(playerName)) - if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleSetMemberNote(this, playerName, publicNote, false); -} - -void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket) -{ - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_SET_OFFICER_NOTE"); + recvPacket.ReadByteSeq(playerGuid[4]); + recvPacket.ReadByteSeq(playerGuid[5]); + recvPacket.ReadByteSeq(playerGuid[0]); + recvPacket.ReadByteSeq(playerGuid[3]); + recvPacket.ReadByteSeq(playerGuid[1]); + recvPacket.ReadByteSeq(playerGuid[6]); + recvPacket.ReadByteSeq(playerGuid[7]); + std::string note = recvPacket.ReadString(noteLength); + recvPacket.ReadByteSeq(playerGuid[2]); - std::string playerName; - recvPacket >> playerName; - - std::string officerNote; - recvPacket >> officerNote; - - if (normalizePlayerName(playerName)) - if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleSetMemberNote(this, playerName, officerNote, true); + if (Guild* guild = _GetPlayerGuild(this, true)) + guild->HandleSetMemberNote(this, note, playerGuid, type); } -void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket) +void WorldSession::HandleGuildQueryRanksOpcode(WorldPacket& recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_RANK"); - - Guild* guild = _GetPlayerGuild(this, true); - if (!guild) - { - recvPacket.rpos(recvPacket.wpos()); - return; - } - - uint32 rankId; - recvPacket >> rankId; - - uint32 rights; - recvPacket >> rights; - - std::string rankName; - recvPacket >> rankName; + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_QUERY_RANKS"); - uint32 money; - recvPacket >> money; - - GuildBankRightsAndSlotsVec rightsAndSlots(GUILD_BANK_MAX_TABS); - for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) - { - uint32 bankRights; - uint32 slots; + ObjectGuid guildGuid; - recvPacket >> bankRights; - recvPacket >> slots; + guildGuid[2] = recvData.ReadBit(); + guildGuid[3] = recvData.ReadBit(); + guildGuid[0] = recvData.ReadBit(); + guildGuid[6] = recvData.ReadBit(); + guildGuid[4] = recvData.ReadBit(); + guildGuid[7] = recvData.ReadBit(); + guildGuid[5] = recvData.ReadBit(); + guildGuid[1] = recvData.ReadBit(); - rightsAndSlots[tabId] = GuildBankRightsAndSlots(uint8(bankRights), slots); - } + recvData.ReadByteSeq(guildGuid[3]); + recvData.ReadByteSeq(guildGuid[4]); + recvData.ReadByteSeq(guildGuid[5]); + recvData.ReadByteSeq(guildGuid[7]); + recvData.ReadByteSeq(guildGuid[1]); + recvData.ReadByteSeq(guildGuid[0]); + recvData.ReadByteSeq(guildGuid[6]); + recvData.ReadByteSeq(guildGuid[2]); - guild->HandleSetRankInfo(this, rankId, rankName, rights, money, rightsAndSlots); + if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid)) + if (guild->IsMember(_player->GetGUID())) + guild->HandleGuildRanks(this); } void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_ADD_RANK"); - std::string rankName; - recvPacket >> rankName; + uint32 rankId; + recvPacket >> rankId; + + uint32 length = recvPacket.ReadBits(7); + std::string rankName = recvPacket.ReadString(length); if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleAddNewRank(this, rankName); + guild->HandleAddNewRank(this, rankName); //, rankId); } -void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/) +void WorldSession::HandleGuildDelRankOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_DEL_RANK"); + uint32 rankId; + recvPacket >> rankId; + if (Guild* guild = _GetPlayerGuild(this, true)) - guild->HandleRemoveLowestRank(this); + guild->HandleRemoveRank(this, rankId); } void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_INFO_TEXT"); - std::string info; - recvPacket >> info; + uint32 length = recvPacket.ReadBits(12); + std::string info = recvPacket.ReadString(length); if (Guild* guild = _GetPlayerGuild(this, true)) guild->HandleSetInfo(this, info); @@ -328,7 +428,7 @@ void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */) guild->SendEventLog(this); } -void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket & /* recv_data */) +void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket & /* recvData */) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (MSG_GUILD_BANK_MONEY_WITHDRAWN)"); @@ -336,78 +436,78 @@ void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket & /* recv_data */) guild->SendMoneyInfo(this); } -void WorldSession::HandleGuildPermissions(WorldPacket& /* recv_data */) +void WorldSession::HandleGuildPermissions(WorldPacket& /* recvData */) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (MSG_GUILD_PERMISSIONS)"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_PERMISSIONS)"); if (Guild* guild = _GetPlayerGuild(this)) guild->SendPermissions(this); } // Called when clicking on Guild bank gameobject -void WorldSession::HandleGuildBankerActivate(WorldPacket & recv_data) +void WorldSession::HandleGuildBankerActivate(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANKER_ACTIVATE)"); uint64 GoGuid; - recv_data >> GoGuid; + recvData >> GoGuid; uint8 fullSlotList; - recv_data >> fullSlotList; // 0 = only slots updated in last operation are shown. 1 = all slots updated + recvData >> fullSlotList; // 0 = only slots updated in last operation are shown. 1 = all slots updated if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) { if (Guild* guild = _GetPlayerGuild(this)) guild->SendBankTabsInfo(this); else - Guild::SendCommandResult(this, GUILD_UNK1, ERR_GUILD_PLAYER_NOT_IN_GUILD); + Guild::SendCommandResult(this, GUILD_VIEW_TAB, ERR_GUILD_PLAYER_NOT_IN_GUILD); } } // Called when opening guild bank tab only (first one) -void WorldSession::HandleGuildBankQueryTab(WorldPacket & recv_data) +void WorldSession::HandleGuildBankQueryTab(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_QUERY_TAB)"); uint64 GoGuid; - recv_data >> GoGuid; + recvData >> GoGuid; uint8 tabId; - recv_data >> tabId; + recvData >> tabId; uint8 fullSlotList; - recv_data >> fullSlotList; // 0 = only slots updated in last operation are shown. 1 = all slots updated + recvData >> fullSlotList; // 0 = only slots updated in last operation are shown. 1 = all slots updated if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) if (Guild* guild = _GetPlayerGuild(this)) guild->SendBankTabData(this, tabId); } -void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recv_data) +void WorldSession::HandleGuildBankDepositMoney(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_DEPOSIT_MONEY)"); - uint64 GoGuid; - recv_data >> GoGuid; + uint64 goGuid; + recvData >> goGuid; - uint32 money; - recv_data >> money; + uint64 money; + recvData >> money; - if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (GetPlayer()->GetGameObjectIfCanInteractWith(goGuid, GAMEOBJECT_TYPE_GUILD_BANK)) if (money && GetPlayer()->HasEnoughMoney(money)) if (Guild* guild = _GetPlayerGuild(this)) guild->HandleMemberDepositMoney(this, money); } -void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket & recv_data) +void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_WITHDRAW_MONEY)"); uint64 GoGuid; - recv_data >> GoGuid; + recvData >> GoGuid; uint32 money; - recv_data >> money; + recvData >> money; if (money) if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) @@ -415,28 +515,28 @@ void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket & recv_data) guild->HandleMemberWithdrawMoney(this, money); } -void WorldSession::HandleGuildBankSwapItems(WorldPacket & recv_data) +void WorldSession::HandleGuildBankSwapItems(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_SWAP_ITEMS)"); uint64 GoGuid; - recv_data >> GoGuid; + recvData >> GoGuid; if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) { - recv_data.rfinish(); // Prevent additional spam at rejected packet + recvData.rfinish(); // Prevent additional spam at rejected packet return; } Guild* guild = _GetPlayerGuild(this); if (!guild) { - recv_data.rfinish(); // Prevent additional spam at rejected packet + recvData.rfinish(); // Prevent additional spam at rejected packet return; } uint8 bankToBank; - recv_data >> bankToBank; + recvData >> bankToBank; uint8 tabId; uint8 slotId; @@ -446,18 +546,19 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket & recv_data) if (bankToBank) { uint8 destTabId; - recv_data >> destTabId; + recvData >> destTabId; uint8 destSlotId; - recv_data >> destSlotId; - recv_data.read_skip<uint32>(); // Always 0 + recvData >> destSlotId; - recv_data >> tabId; - recv_data >> slotId; - recv_data >> itemEntry; - recv_data.read_skip<uint8>(); // Always 0 + uint32 destItemEntry; + recvData >> destItemEntry; - recv_data >> splitedAmount; + recvData >> tabId; + recvData >> slotId; + recvData >> itemEntry; + recvData.read_skip<uint8>(); // Always 0 + recvData >> splitedAmount; guild->SwapItems(GetPlayer(), tabId, slotId, destTabId, destSlotId, splitedAmount); } @@ -467,24 +568,24 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket & recv_data) uint8 playerSlotId = NULL_SLOT; uint8 toChar = 1; - recv_data >> tabId; - recv_data >> slotId; - recv_data >> itemEntry; + recvData >> tabId; + recvData >> slotId; + recvData >> itemEntry; uint8 autoStore; - recv_data >> autoStore; + recvData >> autoStore; if (autoStore) { - recv_data.read_skip<uint32>(); // autoStoreCount - recv_data.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in Bank -> Char) - recv_data.read_skip<uint32>(); // Always 0 + recvData.read_skip<uint32>(); // autoStoreCount + recvData.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in Bank -> Char) + recvData.read_skip<uint32>(); // Always 0 } else { - recv_data >> playerBag; - recv_data >> playerSlotId; - recv_data >> toChar; - recv_data >> splitedAmount; + recvData >> playerBag; + recvData >> playerSlotId; + recvData >> toChar; + recvData >> splitedAmount; } // Player <-> Bank @@ -496,36 +597,36 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket & recv_data) } } -void WorldSession::HandleGuildBankBuyTab(WorldPacket & recv_data) +void WorldSession::HandleGuildBankBuyTab(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_BUY_TAB)"); uint64 GoGuid; - recv_data >> GoGuid; + recvData >> GoGuid; uint8 tabId; - recv_data >> tabId; + recvData >> tabId; - if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) + if (!GoGuid || GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) if (Guild* guild = _GetPlayerGuild(this)) guild->HandleBuyBankTab(this, tabId); } -void WorldSession::HandleGuildBankUpdateTab(WorldPacket & recv_data) +void WorldSession::HandleGuildBankUpdateTab(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (CMSG_GUILD_BANK_UPDATE_TAB)"); uint64 GoGuid; - recv_data >> GoGuid; + recvData >> GoGuid; uint8 tabId; - recv_data >> tabId; + recvData >> tabId; std::string name; - recv_data >> name; + recvData >> name; std::string icon; - recv_data >> icon; + recvData >> icon; if (!name.empty() && !icon.empty()) if (GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK)) @@ -533,38 +634,107 @@ void WorldSession::HandleGuildBankUpdateTab(WorldPacket & recv_data) guild->HandleSetBankTabInfo(this, tabId, name, icon); } -void WorldSession::HandleGuildBankLogQuery(WorldPacket & recv_data) +void WorldSession::HandleGuildBankLogQuery(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received (MSG_GUILD_BANK_LOG_QUERY)"); uint8 tabId; - recv_data >> tabId; + recvData >> tabId; if (Guild* guild = _GetPlayerGuild(this)) guild->SendBankLog(this, tabId); } -void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recv_data) +void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_QUERY_GUILD_BANK_TEXT"); uint8 tabId; - recv_data >> tabId; + recvData >> tabId; if (Guild* guild = _GetPlayerGuild(this)) guild->SendBankTabText(this, tabId); } -void WorldSession::HandleSetGuildBankTabText(WorldPacket &recv_data) +void WorldSession::HandleSetGuildBankTabText(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_GUILD_BANK_TEXT"); uint8 tabId; - recv_data >> tabId; + recvData >> tabId; std::string text; - recv_data >> text; + recvData >> text; if (Guild* guild = _GetPlayerGuild(this)) guild->SetBankTabText(tabId, text); } + +void WorldSession::HandleGuildQueryXPOpcode(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUERY_GUILD_XP"); + + ObjectGuid guildGuid; + + guildGuid[2] = recvData.ReadBit(); + guildGuid[1] = recvData.ReadBit(); + guildGuid[0] = recvData.ReadBit(); + guildGuid[5] = recvData.ReadBit(); + guildGuid[4] = recvData.ReadBit(); + guildGuid[7] = recvData.ReadBit(); + guildGuid[6] = recvData.ReadBit(); + guildGuid[3] = recvData.ReadBit(); + + recvData.ReadByteSeq(guildGuid[7]); + recvData.ReadByteSeq(guildGuid[2]); + recvData.ReadByteSeq(guildGuid[3]); + recvData.ReadByteSeq(guildGuid[6]); + recvData.ReadByteSeq(guildGuid[1]); + recvData.ReadByteSeq(guildGuid[5]); + recvData.ReadByteSeq(guildGuid[0]); + recvData.ReadByteSeq(guildGuid[4]); + + //if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid)) + // guild->Send SMSG_GUILD_XP +} + +void WorldSession::HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GUILD_SET_RANK_PERMISSIONS"); + + Guild* guild = _GetPlayerGuild(this, true); + if (!guild) + { + recvPacket.rfinish(); + return; + } + + uint32 unk; + uint32 rankId; + uint32 oldRights; + uint32 newRights; + uint32 moneyPerDay; + + recvPacket >> unk; + recvPacket >> oldRights; + recvPacket >> newRights; + + GuildBankRightsAndSlotsVec rightsAndSlots(GUILD_BANK_MAX_TABS); + for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId) + { + uint32 bankRights; + uint32 slots; + + recvPacket >> bankRights; + recvPacket >> slots; + + rightsAndSlots[tabId] = GuildBankRightsAndSlots(uint8(bankRights), slots); + } + + recvPacket >> moneyPerDay; + recvPacket >> rankId; + uint32 nameLength = recvPacket.ReadBits(7); + std::string rankName = recvPacket.ReadString(nameLength); + + guild->HandleSetRankInfo(this, rankId, rankName, newRights, moneyPerDay, rightsAndSlots); +} diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 260220bb8d5..73c90498eaa 100755..100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -27,14 +27,15 @@ #include "UpdateData.h" #include "ObjectAccessor.h" #include "SpellInfo.h" +#include <vector> -void WorldSession::HandleSplitItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleSplitItemOpcode(WorldPacket & recvData) { //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_SPLIT_ITEM"); uint8 srcbag, srcslot, dstbag, dstslot; uint32 count; - recv_data >> srcbag >> srcslot >> dstbag >> dstslot >> count; + recvData >> srcbag >> srcslot >> dstbag >> dstslot >> count; //sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u, count = %u", srcbag, srcslot, dstbag, dstslot, count); uint16 src = ((srcbag << 8) | srcslot); @@ -61,12 +62,12 @@ void WorldSession::HandleSplitItemOpcode(WorldPacket & recv_data) _player->SplitItem(src, dst, count); } -void WorldSession::HandleSwapInvItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleSwapInvItemOpcode(WorldPacket & recvData) { //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_SWAP_INV_ITEM"); uint8 srcslot, dstslot; - recv_data >> dstslot >> srcslot; + recvData >> dstslot >> srcslot; //sLog->outDebug("STORAGE: receive srcslot = %u, dstslot = %u", srcslot, dstslot); // prevent attempt swap same item to current position generated by client at special checting sequence @@ -91,11 +92,11 @@ void WorldSession::HandleSwapInvItemOpcode(WorldPacket & recv_data) _player->SwapItem(src, dst); } -void WorldSession::HandleAutoEquipItemSlotOpcode(WorldPacket & recv_data) +void WorldSession::HandleAutoEquipItemSlotOpcode(WorldPacket& recvData) { uint64 itemguid; uint8 dstslot; - recv_data >> itemguid >> dstslot; + recvData >> itemguid >> dstslot; // cheating attempt, client should never send opcode in that case if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, dstslot)) @@ -110,12 +111,12 @@ void WorldSession::HandleAutoEquipItemSlotOpcode(WorldPacket & recv_data) _player->SwapItem(item->GetPos(), dstpos); } -void WorldSession::HandleSwapItem(WorldPacket & recv_data) +void WorldSession::HandleSwapItem(WorldPacket & recvData) { //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_SWAP_ITEM"); uint8 dstbag, dstslot, srcbag, srcslot; - recv_data >> dstbag >> dstslot >> srcbag >> srcslot; + recvData >> dstbag >> dstslot >> srcbag >> srcslot; //sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u", srcbag, srcslot, dstbag, dstslot); uint16 src = ((srcbag << 8) | srcslot); @@ -140,12 +141,12 @@ void WorldSession::HandleSwapItem(WorldPacket & recv_data) _player->SwapItem(src, dst); } -void WorldSession::HandleAutoEquipItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleAutoEquipItemOpcode(WorldPacket & recvData) { //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_AUTOEQUIP_ITEM"); uint8 srcbag, srcslot; - recv_data >> srcbag >> srcslot; + recvData >> srcbag >> srcslot; //sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot); Item* pSrcItem = _player->GetItemByPos(srcbag, srcslot); @@ -234,12 +235,12 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleDestroyItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleDestroyItemOpcode(WorldPacket & recvData) { - //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_DESTROYITEM"); + //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_DESTROY_ITEM"); uint8 bag, slot, count, data1, data2, data3; - recv_data >> bag >> slot >> count >> data1 >> data2 >> data3; + recvData >> bag >> slot >> count >> data1 >> data2 >> data3; //sLog->outDebug("STORAGE: receive bag = %u, slot = %u, count = %u", bag, slot, count); uint16 pos = (bag << 8) | slot; @@ -277,174 +278,176 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket & recv_data) _player->DestroyItem(bag, slot, true); } -// Only _static_ data send in this packet !!! -void WorldSession::HandleItemQuerySingleOpcode(WorldPacket & recv_data) +void WorldSession::SendItemDb2Reply(uint32 entry) { - //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_ITEM_QUERY_SINGLE"); - uint32 item; - recv_data >> item; - - sLog->outInfo(LOG_FILTER_NETWORKIO, "STORAGE: Item Query = %u", item); - - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item); - if (pProto) + WorldPacket data(SMSG_DB_REPLY, 44); + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(entry); + if (!proto) { - std::string Name = pProto->Name1; - std::string Description = pProto->Description; - - int loc_idx = GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - { - if (ItemLocale const* il = sObjectMgr->GetItemLocale(pProto->ItemId)) - { - ObjectMgr::GetLocaleString(il->Name, loc_idx, Name); - ObjectMgr::GetLocaleString(il->Description, loc_idx, Description); - } - } - // guess size - WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); - data << pProto->ItemId; - data << pProto->Class; - data << pProto->SubClass; - data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache? - data << Name; - data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... - data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); - data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00); - data << pProto->DisplayInfoID; - data << pProto->Quality; - data << pProto->Flags; - data << pProto->Flags2; - data << pProto->BuyPrice; - data << pProto->SellPrice; - data << pProto->InventoryType; - data << pProto->AllowableClass; - data << pProto->AllowableRace; - data << pProto->ItemLevel; - data << pProto->RequiredLevel; - data << pProto->RequiredSkill; - data << pProto->RequiredSkillRank; - data << pProto->RequiredSpell; - data << pProto->RequiredHonorRank; - data << pProto->RequiredCityRank; - data << pProto->RequiredReputationFaction; - data << pProto->RequiredReputationRank; - data << int32(pProto->MaxCount); - data << int32(pProto->Stackable); - data << pProto->ContainerSlots; - data << pProto->StatsCount; // item stats count - for (uint32 i = 0; i < pProto->StatsCount; ++i) - { - data << pProto->ItemStat[i].ItemStatType; - data << pProto->ItemStat[i].ItemStatValue; - } - data << pProto->ScalingStatDistribution; // scaling stats distribution - data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column - for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) - { - data << pProto->Damage[i].DamageMin; - data << pProto->Damage[i].DamageMax; - data << pProto->Damage[i].DamageType; - } + data << uint32(-1); // entry + data << uint32(DB2_REPLY_ITEM); + data << uint32(time(NULL)); // hotfix date + data << uint32(0); // size of next block + return; + } - // resistances (7) - data << pProto->Armor; - data << pProto->HolyRes; - data << pProto->FireRes; - data << pProto->NatureRes; - data << pProto->FrostRes; - data << pProto->ShadowRes; - data << pProto->ArcaneRes; + data << uint32(entry); + data << uint32(DB2_REPLY_ITEM); + data << uint32(sObjectMgr->GetHotfixDate(entry, DB2_REPLY_ITEM)); - data << pProto->Delay; - data << pProto->AmmoType; - data << pProto->RangedModRange; + ByteBuffer buff; + buff << uint32(entry); + buff << uint32(proto->Class); + buff << uint32(proto->SubClass); + buff << int32(proto->Unk0); + buff << uint32(proto->Material); + buff << uint32(proto->DisplayInfoID); + buff << uint32(proto->InventoryType); + buff << uint32(proto->Sheath); - for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) - { - // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown - // use `item_template` or if not set then only use spell cooldowns - SpellInfo const* spell = sSpellMgr->GetSpellInfo(pProto->Spells[s].SpellId); - if (spell) - { - bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0; + data << uint32(buff.size()); + data.append(buff); - data << pProto->Spells[s].SpellId; - data << pProto->Spells[s].SpellTrigger; - data << uint32(-abs(pProto->Spells[s].SpellCharges)); + SendPacket(&data); +} - if (db_data) - { - data << uint32(pProto->Spells[s].SpellCooldown); - data << uint32(pProto->Spells[s].SpellCategory); - data << uint32(pProto->Spells[s].SpellCategoryCooldown); - } - else - { - data << uint32(spell->RecoveryTime); - data << uint32(spell->Category); - data << uint32(spell->CategoryRecoveryTime); - } - } - else - { - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(-1); - data << uint32(0); - data << uint32(-1); - } - } - data << pProto->Bonding; - data << Description; - data << pProto->PageText; - data << pProto->LanguageID; - data << pProto->PageMaterial; - data << pProto->StartQuest; - data << pProto->LockID; - data << int32(pProto->Material); - data << pProto->Sheath; - data << pProto->RandomProperty; - data << pProto->RandomSuffix; - data << pProto->Block; - data << pProto->ItemSet; - data << pProto->MaxDurability; - data << pProto->Area; - data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch - data << pProto->BagFamily; - data << pProto->TotemCategory; - for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s) - { - data << pProto->Socket[s].Color; - data << pProto->Socket[s].Content; - } - data << pProto->socketBonus; - data << pProto->GemProperties; - data << pProto->RequiredDisenchantSkill; - data << pProto->ArmorDamageModifier; - data << pProto->Duration; // added in 2.4.2.8209, duration (seconds) - data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory - data << pProto->HolidayId; // Holiday.dbc? - SendPacket(&data); - } - else +void WorldSession::SendItemSparseDb2Reply(uint32 entry) +{ + WorldPacket data(SMSG_DB_REPLY, 526); + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(entry); + if (!proto) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item); - WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); - data << uint32(item | 0x80000000); - SendPacket(&data); + data << uint32(-1); // entry + data << uint32(DB2_REPLY_SPARSE); + data << uint32(time(NULL)); // hotfix date + data << uint32(0); // size of next block + return; } + + data << uint32(entry); + data << uint32(DB2_REPLY_SPARSE); + data << uint32(sObjectMgr->GetHotfixDate(entry, DB2_REPLY_SPARSE)); + + ByteBuffer buff; + buff << uint32(entry); + buff << uint32(proto->Quality); + buff << uint32(proto->Flags); + buff << uint32(proto->Flags2); + buff << float(proto->Unk430_1); + buff << float(proto->Unk430_2); + buff << uint32(proto->BuyCount); + buff << int32(proto->BuyPrice); + buff << uint32(proto->SellPrice); + buff << uint32(proto->InventoryType); + buff << int32(proto->AllowableClass); + buff << int32(proto->AllowableRace); + buff << uint32(proto->ItemLevel); + buff << uint32(proto->RequiredLevel); + buff << uint32(proto->RequiredSkill); + buff << uint32(proto->RequiredSkillRank); + buff << uint32(proto->RequiredSpell); + buff << uint32(proto->RequiredHonorRank); + buff << uint32(proto->RequiredCityRank); + buff << uint32(proto->RequiredReputationFaction); + buff << uint32(proto->RequiredReputationRank); + buff << int32(proto->MaxCount); + buff << int32(proto->Stackable); + buff << uint32(proto->ContainerSlots); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buff << uint32(proto->ItemStat[x].ItemStatType); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buff << int32(proto->ItemStat[x].ItemStatValue); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buff << int32(proto->ItemStat[x].ItemStatUnk1); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buff << int32(proto->ItemStat[x].ItemStatUnk2); + + buff << uint32(proto->ScalingStatDistribution); + buff << uint32(proto->DamageType); + buff << uint32(proto->Delay); + buff << float(proto->RangedModRange); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buff << int32(proto->Spells[x].SpellId); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buff << uint32(proto->Spells[x].SpellTrigger); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buff << int32(proto->Spells[x].SpellCharges); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buff << int32(proto->Spells[x].SpellCooldown); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buff << uint32(proto->Spells[x].SpellCategory); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buff << int32(proto->Spells[x].SpellCategoryCooldown); + + buff << uint32(proto->Bonding); + + // item name + std::string name = proto->Name1; + buff << uint16(name.length()); + if (name.length()) + buff << name; + + for (uint32 i = 0; i < 3; ++i) // other 3 names + buff << uint16(0); + + std::string desc = proto->Description; + buff << uint16(desc.length()); + if (desc.length()) + buff << desc; + + buff << uint32(proto->PageText); + buff << uint32(proto->LanguageID); + buff << uint32(proto->PageMaterial); + buff << uint32(proto->StartQuest); + buff << uint32(proto->LockID); + buff << int32(proto->Material); + buff << uint32(proto->Sheath); + buff << int32(proto->RandomProperty); + buff << int32(proto->RandomSuffix); + buff << uint32(proto->ItemSet); + + buff << uint32(proto->Area); + buff << uint32(proto->Map); + buff << uint32(proto->BagFamily); + buff << uint32(proto->TotemCategory); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) + buff << uint32(proto->Socket[x].Color); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) + buff << uint32(proto->Socket[x].Content); + + buff << uint32(proto->socketBonus); + buff << uint32(proto->GemProperties); + buff << float(proto->ArmorDamageModifier); + buff << int32(proto->Duration); + buff << uint32(proto->ItemLimitCategory); + buff << uint32(proto->HolidayId); + buff << float(proto->StatScalingFactor); // StatScalingFactor + buff << uint32(proto->CurrencySubstitutionId); + buff << uint32(proto->CurrencySubstitutionCount); + + data << uint32(buff.size()); + data.append(buff); + + SendPacket(&data); } -void WorldSession::HandleReadItem(WorldPacket & recv_data) +void WorldSession::HandleReadItem(WorldPacket& recvData) { - //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_READ_ITEM"); - uint8 bag, slot; - recv_data >> bag >> slot; + recvData >> bag >> slot; - //sLog->outInfo(LOG_FILTER_NETWORKIO, "STORAGE: Read bag = %u, slot = %u", bag, slot); Item* pItem = _player->GetItemByPos(bag, slot); if (pItem && pItem->GetTemplate()->PageText) @@ -454,7 +457,7 @@ void WorldSession::HandleReadItem(WorldPacket & recv_data) InventoryResult msg = _player->CanUseItem(pItem); if (msg == EQUIP_ERR_OK) { - data.Initialize (SMSG_READ_ITEM_OK, 8); + data.Initialize(SMSG_READ_ITEM_OK, 8); sLog->outInfo(LOG_FILTER_NETWORKIO, "STORAGE: Item page sent"); } else @@ -470,26 +473,26 @@ void WorldSession::HandleReadItem(WorldPacket & recv_data) _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); } -void WorldSession::HandlePageQuerySkippedOpcode(WorldPacket & recv_data) +void WorldSession::HandlePageQuerySkippedOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY"); uint32 itemid; uint64 guid; - recv_data >> itemid >> guid; + recvData >> itemid >> guid; sLog->outInfo(LOG_FILTER_NETWORKIO, "Packet Info: itemid: %u guidlow: %u guidentry: %u guidhigh: %u", itemid, GUID_LOPART(guid), GUID_ENPART(guid), GUID_HIPART(guid)); } -void WorldSession::HandleSellItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleSellItemOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SELL_ITEM"); uint64 vendorguid, itemguid; uint32 count; - recv_data >> vendorguid >> itemguid >> count; + recvData >> vendorguid >> itemguid >> count; if (!itemguid) return; @@ -586,7 +589,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket & recv_data) uint32 money = pProto->SellPrice * count; _player->ModifyMoney(money); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money); } else _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0); @@ -597,13 +600,13 @@ void WorldSession::HandleSellItemOpcode(WorldPacket & recv_data) return; } -void WorldSession::HandleBuybackItem(WorldPacket & recv_data) +void WorldSession::HandleBuybackItem(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUYBACK_ITEM"); uint64 vendorguid; uint32 slot; - recv_data >> vendorguid >> slot; + recvData >> vendorguid >> slot; Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!creature) @@ -621,7 +624,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data) if (pItem) { uint32 price = _player->GetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1 + slot - BUYBACK_SLOT_START); - if (!_player->HasEnoughMoney(price)) + if (!_player->HasEnoughMoney(uint64(price))) { _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, pItem->GetEntry(), 0); return; @@ -634,7 +637,7 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data) _player->ModifyMoney(-(int32)price); _player->RemoveItemFromBuyBackSlot(slot, false); _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount()); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, pItem->GetEntry(), pItem->GetCount()); _player->StoreItem(dest, pItem, true); } else @@ -645,14 +648,14 @@ void WorldSession::HandleBuybackItem(WorldPacket & recv_data) _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, 0, 0); } -void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket & recv_data) +void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUY_ITEM_IN_SLOT"); uint64 vendorguid, bagguid; uint32 item, slot, count; uint8 bagslot; - recv_data >> vendorguid >> item >> slot >> bagguid >> bagslot >> count; + recvData >> vendorguid >> item >> slot >> bagguid >> bagslot >> count; // client expects count starting at 1, and we send vendorslot+1 to client already if (slot > 0) @@ -661,24 +664,15 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket & recv_data) return; // cheating uint8 bag = NULL_BAG; // init for case invalid bagGUID - + Item* bagItem = NULL; // find bag slot by bag guid if (bagguid == _player->GetGUID()) bag = INVENTORY_SLOT_BAG_0; else - { - for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) - { - if (Bag* pBag = _player->GetBagByPos(i)) - { - if (bagguid == pBag->GetGUID()) - { - bag = i; - break; - } - } - } - } + bagItem = _player->GetItemByGuid(bagguid); + + if (bagItem && bagItem->IsBag()) + bag = bagItem->GetSlot(); // bag not found, cheating? if (bag == NULL_BAG) @@ -687,14 +681,15 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket & recv_data) GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot); } -void WorldSession::HandleBuyItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUY_ITEM"); - uint64 vendorguid; + uint64 vendorguid, bagGuid; uint32 item, slot, count; - uint8 unk1; + uint8 itemType; // 1 = item, 2 = currency (not implemented) + uint8 bagSlot; - recv_data >> vendorguid >> item >> slot >> count >> unk1; + recvData >> vendorguid >> itemType >> item >> slot >> count >> bagGuid >> bagSlot; // client expects count starting at 1, and we send vendorslot+1 to client already if (slot > 0) @@ -702,14 +697,20 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket & recv_data) else return; // cheating - GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT); + Item* bagItem = _player->GetItemByGuid(bagGuid); + + uint8 bag = NULL_BAG; + if (bagItem && bagItem->IsBag()) + bag = bagItem->GetSlot(); + + GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagSlot); } -void WorldSession::HandleListInventoryOpcode(WorldPacket & recv_data) +void WorldSession::HandleListInventoryOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; if (!GetPlayer()->isAlive()) return; @@ -739,80 +740,115 @@ void WorldSession::SendListInventory(uint64 vendorGuid) if (vendor->HasUnitState(UNIT_STATE_MOVING)) vendor->StopMoving(); - VendorItemData const* items = vendor->GetVendorItems(); - if (!items) - { - WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1); - data << uint64(vendorGuid); - data << uint8(0); // count == 0, next will be error code - data << uint8(0); // "Vendor has no inventory" - SendPacket(&data); - return; - } + VendorItemData const* vendorItems = vendor->GetVendorItems(); + uint8 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0; - uint8 itemCount = items->GetItemCount(); - uint8 count = 0; + //if (rawItemCount > 300), + // rawItemCount = 300; // client cap but uint8 max value is 255 - WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4); - data << uint64(vendorGuid); + ByteBuffer itemsData(32 * rawItemCount); + std::vector<bool> enablers; + enablers.reserve(2 * rawItemCount); - size_t countPos = data.wpos(); - data << uint8(count); + const float discountMod = _player->GetReputationPriceDiscount(vendor); + uint8 count = 0; + for (uint8 slot = 0; slot < rawItemCount; ++slot) + { + VendorItem const* vendorItem = vendorItems->GetItem(slot); + if (!vendorItem) continue; - float discountMod = _player->GetReputationPriceDiscount(vendor); + ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item); + if (!itemTemplate) continue; - for (uint8 slot = 0; slot < itemCount; ++slot) - { - if (VendorItem const* item = items->GetItem(slot)) + if (!_player->isGameMaster()) // ignore conditions if GM on { - if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item)) - { - if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->isGameMaster()) - continue; - // Only display items in vendor lists for the team the - // player is on. If GM on, display all items. - if (!_player->isGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))) - continue; - - // Items sold out are not displayed in list - uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item); - if (!_player->isGameMaster() && !leftInStock) - continue; + // Respect allowed class + if (!(itemTemplate->AllowableClass & _player->getClassMask())) + continue; + + // Do not sell BOP items + if (itemTemplate->Bonding == BIND_WHEN_PICKED_UP) + continue; + + // Only display items in vendor lists for the team the player is on + if ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) || + (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE)) + continue; + + // Items sold out are not displayed in list + uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); + if (leftInStock == 0) + continue; + } - ++count; + int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0; + uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); - // reputation discount - int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0; + itemsData << uint32(count++ + 1); // client expects counting to start at 1 + itemsData << uint32(itemTemplate->MaxDurability); - data << uint32(slot + 1); // client expects counting to start at 1 - data << uint32(item->item); - data << uint32(itemTemplate->DisplayInfoID); - data << int32(leftInStock); - data << uint32(price); - data << uint32(itemTemplate->MaxDurability); - data << uint32(itemTemplate->BuyCount); - data << uint32(item->ExtendedCost); - } + if (vendorItem->ExtendedCost != 0) + { + enablers.push_back(0); + itemsData << uint32(vendorItem->ExtendedCost); } + else + enablers.push_back(1); + enablers.push_back(1); // unk bit + + itemsData << uint32(vendorItem->item); + itemsData << uint32(1); // 1 is items, 2 is currency (FIXME: currency isn't implemented) + itemsData << uint32(price); + itemsData << uint32(itemTemplate->DisplayInfoID); + // if (!unk "enabler") data << uint32(something); + itemsData << int32(leftInStock); + itemsData << uint32(itemTemplate->BuyCount); } - if (count == 0) - { - data << uint8(0); - SendPacket(&data); - return; - } + uint8* guidBytes = (uint8*)&vendorGuid; + + WorldPacket data(SMSG_LIST_INVENTORY, 12 + itemsData.size()); + + data.WriteBit(guidBytes[1]); + data.WriteBit(guidBytes[0]); + + data.WriteBits(count, 21); // item count + + data.WriteBit(guidBytes[3]); + data.WriteBit(guidBytes[6]); + data.WriteBit(guidBytes[5]); + data.WriteBit(guidBytes[2]); + data.WriteBit(guidBytes[7]); + + for (std::vector<bool>::const_iterator itr = enablers.begin(); itr != enablers.end(); ++itr) + data.WriteBit(*itr); + + data.WriteBit(guidBytes[4]); + + data.FlushBits(); + data.append(itemsData); + + data.WriteByteSeq(guidBytes[5]); + data.WriteByteSeq(guidBytes[4]); + data.WriteByteSeq(guidBytes[1]); + data.WriteByteSeq(guidBytes[0]); + data.WriteByteSeq(guidBytes[6]); + + data << uint8(count == 0); // unk byte, item count 0: 1, item count != 0: 0 or some "random" value below 300 + + data.WriteByteSeq(guidBytes[2]); + data.WriteByteSeq(guidBytes[3]); + data.WriteByteSeq(guidBytes[7]); - data.put<uint8>(countPos, count); SendPacket(&data); } -void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) { //sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_AUTOSTORE_BAG_ITEM"); uint8 srcbag, srcslot, dstbag; - recv_data >> srcbag >> srcslot >> dstbag; + recvData >> srcbag >> srcslot >> dstbag; //sLog->outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u", srcbag, srcslot, dstbag); Item* pItem = _player->GetItemByPos(srcbag, srcslot); @@ -895,7 +931,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket) uint32 price = slotEntry->price; - if (!_player->HasEnoughMoney(price)) + if (!_player->HasEnoughMoney(uint64(price))) { data << uint32(ERR_BANKSLOT_INSUFFICIENT_FUNDS); SendPacket(&data); @@ -903,12 +939,12 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket) } _player->SetBankBagSlotCount(slot); - _player->ModifyMoney(-int32(price)); + _player->ModifyMoney(-int64(price)); data << uint32(ERR_BANKSLOT_OK); SendPacket(&data); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT); } void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket) @@ -983,25 +1019,6 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket) } } -void WorldSession::HandleSetAmmoOpcode(WorldPacket & recv_data) -{ - if (!GetPlayer()->isAlive()) - { - GetPlayer()->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, NULL, NULL); - return; - } - - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SET_AMMO"); - uint32 item; - - recv_data >> item; - - if (!item) - GetPlayer()->RemoveAmmo(); - else - GetPlayer()->SetAmmo(item); -} - void WorldSession::SendEnchantmentLog(uint64 Target, uint64 Caster, uint32 ItemID, uint32 SpellID) { WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4+1)); // last check 2.0.10 @@ -1024,38 +1041,14 @@ void WorldSession::SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid, SendPacket(&data); } -void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data) -{ - uint32 itemid; - recv_data >> itemid; - recv_data.read_skip<uint64>(); // guid - - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_ITEM_NAME_QUERY %u", itemid); - ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid); - if (pName) - { - std::string Name = pName->name; - int loc_idx = GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid)) - ObjectMgr::GetLocaleString(isnl->Name, loc_idx, Name); - - WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+Name.size()+1+4)); - data << uint32(itemid); - data << Name; - data << uint32(pName->InventoryType); - SendPacket(&data); - } -} - -void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) +void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_WRAP_ITEM"); uint8 gift_bag, gift_slot, item_bag, item_slot; - recv_data >> gift_bag >> gift_slot; // paper - recv_data >> item_bag >> item_slot; // item + recvData >> gift_bag >> gift_slot; // paper + recvData >> item_bag >> item_slot; // item sLog->outDebug(LOG_FILTER_NETWORKIO, "WRAP: receive gift_bag = %u, gift_slot = %u, item_bag = %u, item_slot = %u", gift_bag, gift_slot, item_bag, item_slot); @@ -1159,19 +1152,19 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) _player->DestroyItemCount(gift, count, true); } -void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) +void WorldSession::HandleSocketOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SOCKET_GEMS"); uint64 item_guid; uint64 gem_guids[MAX_GEM_SOCKETS]; - recv_data >> item_guid; + recvData >> item_guid; if (!item_guid) return; for (int i = 0; i < MAX_GEM_SOCKETS; ++i) - recv_data >> gem_guids[i]; + recvData >> gem_guids[i]; //cheat -> tried to socket same gem multiple times if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) || @@ -1223,6 +1216,14 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) // tried to put meta gem in normal socket if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META) return; + + // tried to put normal gem in cogwheel socket + if (itemProto->Socket[i].Color == SOCKET_COLOR_COGWHEEL && GemProps[i]->color != SOCKET_COLOR_COGWHEEL) + return; + + // tried to put cogwheel gem in normal socket + if (itemProto->Socket[i].Color != SOCKET_COLOR_COGWHEEL && GemProps[i]->color == SOCKET_COLOR_COGWHEEL) + return; } uint32 GemEnchants[MAX_GEM_SOCKETS]; @@ -1353,19 +1354,19 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag } -void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data) +void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT"); - uint32 eslot; + uint32 slot; - recv_data >> eslot; + recvData >> slot; // apply only to equipped item - if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, eslot)) + if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, slot)) return; - Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, eslot); + Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); if (!item) return; @@ -1377,12 +1378,12 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data) item->ClearEnchantment(TEMP_ENCHANTMENT_SLOT); } -void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data) +void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_ITEM_REFUND_INFO"); uint64 guid; - recv_data >> guid; // item guid + recvData >> guid; // item guid Item* item = _player->GetItemByGuid(guid); if (!item) @@ -1394,11 +1395,11 @@ void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data) GetPlayer()->SendRefundInfo(item); } -void WorldSession::HandleItemRefund(WorldPacket &recv_data) +void WorldSession::HandleItemRefund(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_ITEM_REFUND"); uint64 guid; - recv_data >> guid; // item guid + recvData >> guid; // item guid Item* item = _player->GetItemByGuid(guid); if (!item) @@ -1415,14 +1416,14 @@ void WorldSession::HandleItemRefund(WorldPacket &recv_data) * * This function is called when player clicks on item which has some flag set */ -void WorldSession::HandleItemTextQuery(WorldPacket & recv_data ) +void WorldSession::HandleItemTextQuery(WorldPacket & recvData ) { uint64 itemGuid; - recv_data >> itemGuid; + recvData >> itemGuid; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_ITEM_TEXT_QUERY item guid: %u", GUID_LOPART(itemGuid)); - WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10)); // guess size + WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 14); // guess size if (Item* item = _player->GetItemByGuid(itemGuid)) { @@ -1437,3 +1438,268 @@ void WorldSession::HandleItemTextQuery(WorldPacket & recv_data ) SendPacket(&data); } + +void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_TRANSMOGRIFY_ITEMS"); + Player* player = GetPlayer(); + + // Read data + uint32 count = recvData.ReadBits(22); + + if (count < EQUIPMENT_SLOT_START || count >= EQUIPMENT_SLOT_END) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) sent a wrong count (%u) when transmogrifying items.", player->GetGUIDLow(), player->GetName(), count); + recvData.rfinish(); + return; + } + + ObjectGuid* itemGuids = new ObjectGuid[count]; + uint32* newEntries = new uint32[count]; + uint32* slots = new uint32[count]; + + for (uint8 i = 0; i < count; ++i) + { + itemGuids[i][0] = recvData.ReadBit(); + itemGuids[i][5] = recvData.ReadBit(); + itemGuids[i][6] = recvData.ReadBit(); + itemGuids[i][2] = recvData.ReadBit(); + itemGuids[i][3] = recvData.ReadBit(); + itemGuids[i][7] = recvData.ReadBit(); + itemGuids[i][4] = recvData.ReadBit(); + itemGuids[i][1] = recvData.ReadBit(); + } + + ObjectGuid npcGuid; + npcGuid[7] = recvData.ReadBit(); + npcGuid[3] = recvData.ReadBit(); + npcGuid[5] = recvData.ReadBit(); + npcGuid[6] = recvData.ReadBit(); + npcGuid[1] = recvData.ReadBit(); + npcGuid[4] = recvData.ReadBit(); + npcGuid[0] = recvData.ReadBit(); + npcGuid[2] = recvData.ReadBit(); + + recvData.FlushBits(); + + for (uint32 i = 0; i < count; ++i) + { + recvData >> uint32(newEntries[i]); + + recvData.ReadByteSeq(itemGuids[i][1]); + recvData.ReadByteSeq(itemGuids[i][5]); + recvData.ReadByteSeq(itemGuids[i][0]); + recvData.ReadByteSeq(itemGuids[i][4]); + recvData.ReadByteSeq(itemGuids[i][6]); + recvData.ReadByteSeq(itemGuids[i][7]); + recvData.ReadByteSeq(itemGuids[i][3]); + recvData.ReadByteSeq(itemGuids[i][2]); + + recvData >> uint32(slots[i]); + } + + recvData.ReadByteSeq(npcGuid[7]); + recvData.ReadByteSeq(npcGuid[2]); + recvData.ReadByteSeq(npcGuid[5]); + recvData.ReadByteSeq(npcGuid[4]); + recvData.ReadByteSeq(npcGuid[3]); + recvData.ReadByteSeq(npcGuid[1]); + recvData.ReadByteSeq(npcGuid[6]); + recvData.ReadByteSeq(npcGuid[0]); + + // Validate + + if (!player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_TRANSMOGRIFIER)) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); + return; + } + + int32 cost = 0; + for (uint8 i = 0; i < count; ++i) + { + // slot of the transmogrified item + if (slots[i] < EQUIPMENT_SLOT_START || slots[i] >= EQUIPMENT_SLOT_END) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify an item (lowguid: %u) with a wrong slot (%u) when transmogrifying items.", player->GetGUIDLow(), player->GetName(), GUID_LOPART(itemGuids[i]), slots[i]); + return; + } + + // entry of the transmogrifier item, if it's not 0 + if (newEntries[i]) + { + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newEntries[i]); + if (!proto) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify to an invalid item (entry: %u).", player->GetGUIDLow(), player->GetName(), newEntries[i]); + return; + } + } + + Item* itemTransmogrifier = NULL; + // guid of the transmogrifier item, if it's not 0 + if (itemGuids[i]) + { + itemTransmogrifier = player->GetItemByGuid(itemGuids[i]); + if (!itemTransmogrifier) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify with an invalid item (guid: "UI64FMTD").", player->GetGUIDLow(), player->GetName(), itemGuids[i]); + return; + } + } + + // transmogrified item + Item* itemTransmogrified = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slots[i]); + if (!itemTransmogrified) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify an invalid item in a valid slot (slot: %u).", player->GetGUIDLow(), player->GetName(), slots[i]); + return; + } + + // uint16 tempDest; + //// has to be able to equip item transmogrified item + //if (!player->CanEquipItem(slots[i], tempDest, itemTransmogrified, true, true)) + //{ + // sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) can't equip the item to be transmogrified (slot: %u, entry: %u).", player->GetGUIDLow(), player->GetName(), slots[i], itemTransmogrified->GetEntry()); + // return; + //} + // + //// has to be able to equip item transmogrifier item + //if (!player->CanEquipItem(slots[i], tempDest, itemTransmogrifier, true, true)) + //{ + // sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) can't equip the transmogrifier item (slot: %u, entry: %u).", player->GetGUIDLow(), player->GetName(), slots[i], itemTransmogrifier->GetEntry()); + // return; + //} + + if (!newEntries[i]) // reset look + { + itemTransmogrified->ClearEnchantment(TRANSMOGRIFY_ENCHANTMENT_SLOT); + player->SetVisibleItemSlot(slots[i], itemTransmogrified); + } + else + { + if (!Item::CanTransmogrifyItemWithItem(itemTransmogrified, itemTransmogrifier)) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) failed CanTransmogrifyItemWithItem (%u with %u).", player->GetGUIDLow(), player->GetName(), itemTransmogrified->GetEntry(), itemTransmogrifier->GetEntry()); + return; + } + + // All okay, proceed + itemTransmogrified->SetEnchantment(TRANSMOGRIFY_ENCHANTMENT_SLOT, newEntries[i], 0, 0); + player->SetVisibleItemSlot(slots[i], itemTransmogrified); + + itemTransmogrified->UpdatePlayedTime(player); + + itemTransmogrified->SetOwnerGUID(player->GetGUID()); + itemTransmogrified->SetNotRefundable(player); + itemTransmogrified->ClearSoulboundTradeable(player); + + itemTransmogrifier->SetOwnerGUID(player->GetGUID()); + itemTransmogrifier->SetNotRefundable(player); + itemTransmogrifier->ClearSoulboundTradeable(player); + + cost += itemTransmogrified->GetSpecialPrice(); + } + } + + // trusting the client, if it got here it has to have enough money + // ... unless client was modified + if (cost) // 0 cost if reverting look + player->ModifyMoney(-cost); + + + delete[] itemGuids; + delete[] newEntries; + delete[] slots; +} + +void WorldSession::SendReforgeResult(bool success) +{ + WorldPacket data(SMSG_REFORGE_RESULT, 1); + data.WriteBit(success); + data.FlushBits(); + SendPacket(&data); +} + +void WorldSession::HandleReforgeItemOpcode(WorldPacket& recvData) +{ + uint32 slot, reforgeEntry; + ObjectGuid guid; + uint32 bag; + Player* player = GetPlayer(); + + recvData >> reforgeEntry >> slot >> bag; + + guid[2] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[5] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[5]); + + if (!player->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_REFORGER)) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleReforgeItemOpcode - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(guid)); + SendReforgeResult(false); + return; + } + + Item* item = player->GetItemByPos(bag, slot); + + if (!item) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleReforgeItemOpcode - Player (Guid: %u Name: %s) tried to reforge an invalid/non-existant item.", player->GetGUIDLow(), player->GetName()); + SendReforgeResult(false); + return; + } + + if (!reforgeEntry) + { + // Reset the item + if (item->IsEquipped()) + player->ApplyReforgeEnchantment(item, false); + item->ClearEnchantment(REFORGE_ENCHANTMENT_SLOT); + SendReforgeResult(true); + return; + } + + ItemReforgeEntry const* stats = sItemReforgeStore.LookupEntry(reforgeEntry); + if (!stats) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleReforgeItemOpcode - Player (Guid: %u Name: %s) tried to reforge an item with invalid reforge entry (%u).", player->GetGUIDLow(), player->GetName(), reforgeEntry); + SendReforgeResult(false); + return; + } + + if (!item->GetReforgableStat(ItemModType(stats->SourceStat)) || item->GetReforgableStat(ItemModType(stats->FinalStat))) // Cheating, you cant reforge to a stat that the item already has, nor reforge from a stat that the item does not have + { + SendReforgeResult(false); + return; + } + + if (!player->HasEnoughMoney(uint64(item->GetSpecialPrice()))) // cheating + { + SendReforgeResult(false); + return; + } + + player->ModifyMoney(-int64(item->GetSpecialPrice())); + + item->SetEnchantment(REFORGE_ENCHANTMENT_SLOT, reforgeEntry, 0, 0); + + SendReforgeResult(true); + + if (item->IsEquipped()) + player->ApplyReforgeEnchantment(item, true); +} diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index aa6d208ad3a..b4f74735568 100755 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -32,6 +32,8 @@ void BuildPlayerLockDungeonBlock(WorldPacket& data, const LfgLockMap& lock) { data << uint32(it->first); // Dungeon entry (id + type) data << uint32(it->second); // Lock status + data << uint32(0); // Unknown 4.2.2 + data << uint32(0); // Unknown 4.2.2 } } @@ -45,13 +47,13 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMa } } -void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { if (!sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) { - recv_data.rfinish(); + recvData.rfinish(); return; } @@ -59,32 +61,32 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data) uint32 dungeon; uint32 roles; - recv_data >> roles; - recv_data.read_skip<uint16>(); // uint8 (always 0) - uint8 (always 0) - recv_data >> numDungeons; + recvData >> roles; + recvData.read_skip<uint16>(); // uint8 (always 0) - uint8 (always 0) + recvData >> numDungeons; if (!numDungeons) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] no dungeons selected", GetPlayer()->GetGUID()); - recv_data.rfinish(); + recvData.rfinish(); return; } LfgDungeonSet newDungeons; for (int8 i = 0; i < numDungeons; ++i) { - recv_data >> dungeon; + recvData >> dungeon; newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry } - recv_data.read_skip<uint32>(); // for 0..uint8 (always 3) { uint8 (always 0) } + recvData.read_skip<uint32>(); // for 0..uint8 (always 3) { uint8 (always 0) } std::string comment; - recv_data >> comment; + recvData >> comment; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_JOIN [" UI64FMTD "] roles: %u, Dungeons: %u, Comment: %s", GetPlayer()->GetGUID(), roles, uint8(newDungeons.size()), comment.c_str()); sLFGMgr->Join(GetPlayer(), uint8(roles), newDungeons, comment); } -void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recvData*/) { Group* grp = GetPlayer()->GetGroup(); @@ -95,21 +97,21 @@ void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recv_data*/) sLFGMgr->Leave(GetPlayer(), grp); } -void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recvData) { uint32 lfgGroupID; // Internal lfgGroupID bool accept; // Accept to join? - recv_data >> lfgGroupID; - recv_data >> accept; + recvData >> lfgGroupID; + recvData >> accept; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_PROPOSAL_RESULT [" UI64FMTD "] proposal: %u accept: %u", GetPlayer()->GetGUID(), lfgGroupID, accept ? 1 : 0); sLFGMgr->UpdateProposal(lfgGroupID, GetPlayer()->GetGUID(), accept); } -void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData) { uint8 roles; - recv_data >> roles; // Player Group Roles + recvData >> roles; // Player Group Roles uint64 guid = GetPlayer()->GetGUID(); Group* grp = GetPlayer()->GetGroup(); if (!grp) @@ -122,35 +124,35 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recv_data) sLFGMgr->UpdateRoleCheck(gguid, guid, roles); } -void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recvData) { std::string comment; - recv_data >> comment; + recvData >> comment; uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_LFG_COMMENT [" UI64FMTD "] comment: %s", guid, comment.c_str()); sLFGMgr->SetComment(guid, comment); } -void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfgSetBootVoteOpcode(WorldPacket& recvData) { bool agree; // Agree to kick player - recv_data >> agree; + recvData >> agree; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_SET_BOOT_VOTE [" UI64FMTD "] agree: %u", GetPlayer()->GetGUID(), agree ? 1 : 0); sLFGMgr->UpdateBoot(GetPlayer(), agree); } -void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recvData) { bool out; - recv_data >> out; + recvData >> out; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFG_TELEPORT [" UI64FMTD "] out: %u", GetPlayer()->GetGUID(), out ? 1 : 0); sLFGMgr->TeleportPlayer(GetPlayer(), out, true); } -void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData*/) { uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); @@ -231,7 +233,7 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recv_data SendPacket(&data); } -void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData*/) { uint64 guid = GetPlayer()->GetGUID(); sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LFD_PARTY_LOCK_INFO_REQUEST [" UI64FMTD "]", guid); @@ -257,7 +259,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data uint32 size = 0; for (LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it) - size += 8 + 4 + uint32(it->second.size()) * (4 + 4); + size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_PARTY_INFO [" UI64FMTD "]", guid); WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size); @@ -265,18 +267,18 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recv_data SendPacket(&data); } -void WorldSession::HandleLfrSearchOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfrSearchOpcode(WorldPacket& recvData) { uint32 entry; // Raid id to search - recv_data >> entry; + recvData >> entry; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SEARCH_LFG_JOIN [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), entry); //SendLfrUpdateListOpcode(entry); } -void WorldSession::HandleLfrLeaveOpcode(WorldPacket& recv_data) +void WorldSession::HandleLfrLeaveOpcode(WorldPacket& recvData) { uint32 dungeonId; // Raid id queue to leave - recv_data >> dungeonId; + recvData >> dungeonId; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SEARCH_LFG_LEAVE [" UI64FMTD "] dungeonId: %u", GetPlayer()->GetGUID(), dungeonId); //sLFGMgr->LeaveLfr(GetPlayer(), dungeonId); } @@ -444,7 +446,7 @@ void WorldSession::SendLfgJoinResult(const LfgJoinResultData& joinData) { uint32 size = 0; for (LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it) - size += 8 + 4 + uint32(it->second.size()) * (4 + 4); + size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4); sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_JOIN_RESULT [" UI64FMTD "] checkResult: %u checkValue: %u", GetPlayer()->GetGUID(), joinData.result, joinData.state); WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size); @@ -531,6 +533,7 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot) data << uint8(pBoot->inProgress); // Vote in progress data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree + data << uint8(0); // Unknown 4.2.2 data << uint64(pBoot->victim); // Victim GUID data << uint32(votesNum); // Total Votes data << uint32(agreeNum); // Agree Count @@ -657,8 +660,8 @@ void WorldSession::SendLfgTeleportError(uint8 err) /* void WorldSession::SendLfrUpdateListOpcode(uint32 dungeonEntry) { - sLog->outDebug(LOG_FILTER_PACKETIO, "SMSG_UPDATE_LFG_LIST [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry); - WorldPacket data(SMSG_UPDATE_LFG_LIST); + sLog->outDebug(LOG_FILTER_PACKETIO, "SMSG_LFG_UPDATE_LIST [" UI64FMTD "] dungeon entry: %u", GetPlayer()->GetGUID(), dungeonEntry); + WorldPacket data(SMSG_LFG_UPDATE_LIST); SendPacket(&data); } */ diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 8259d0c4e9b..8641880db59 100755 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -30,7 +30,7 @@ #include "World.h" #include "Util.h" -void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); Player* player = GetPlayer(); @@ -38,7 +38,7 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket & recv_data) Loot* loot = NULL; uint8 lootSlot = 0; - recv_data >> lootSlot; + recvData >> lootSlot; if (IS_GAMEOBJECT_GUID(lguid)) { @@ -94,7 +94,7 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket & recv_data) player->StoreLootItem(lootSlot, loot); } -void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_MONEY"); @@ -179,7 +179,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i) { (*i)->ModifyMoney(goldPerPlayer); - (*i)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); + (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); @@ -190,7 +190,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) else { player->ModifyMoney(loot->gold); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold); WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(loot->gold); @@ -202,12 +202,12 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/) } } -void WorldSession::HandleLootOpcode(WorldPacket & recv_data) +void WorldSession::HandleLootOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT"); uint64 guid; - recv_data >> guid; + recvData >> guid; // Check possible cheat if (!_player->isAlive()) @@ -428,12 +428,12 @@ void WorldSession::DoLootRelease(uint64 lguid) loot->RemoveLooter(player->GetGUID()); } -void WorldSession::HandleLootMasterGiveOpcode(WorldPacket & recv_data) +void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) { uint8 slotid; uint64 lootguid, target_playerguid; - recv_data >> lootguid >> slotid >> target_playerguid; + recvData >> lootguid >> slotid >> target_playerguid; if (!_player->GetGroup() || _player->GetGroup()->GetLooterGuid() != _player->GetGUID()) { @@ -498,9 +498,9 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket & recv_data) // not move item from loot to target inventory Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters); target->SendNewItem(newitem, uint32(item.count), false, false, true); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count); - target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); // mark as looted item.count=0; diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 2cf27140720..c3c61d126da 100755..100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -29,44 +29,85 @@ #include "Item.h" #include "AccountMgr.h" -void WorldSession::HandleSendMail(WorldPacket & recv_data) +void WorldSession::HandleSendMail(WorldPacket& recvData) { - uint64 mailbox, unk3; + ObjectGuid mailbox; + uint64 money, COD; std::string receiver, subject, body; - uint32 unk1, unk2, money, COD; - uint8 unk4; - recv_data >> mailbox; - recv_data >> receiver; - - recv_data >> subject; - - recv_data >> body; - - recv_data >> unk1; // stationery? - recv_data >> unk2; // 0x00000000 - - uint8 items_count; - recv_data >> items_count; // attached items count - + uint32 bodyLength, subjectLength, receiverLength; + uint32 unk1, unk2; + + recvData >> unk1; + recvData >> unk2; // Stationery? + + recvData >> money >> COD; // money and cod + bodyLength = recvData.ReadBits(12); + subjectLength = recvData.ReadBits(9); + + uint8 items_count = recvData.ReadBits(5); // attached items count + if (items_count > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); - recv_data.rfinish(); // set to end to avoid warnings spam + recvData.rfinish(); // set to end to avoid warnings spam return; } + + mailbox[0] = recvData.ReadBit(); - uint64 itemGUIDs[MAX_MAIL_ITEMS]; + ObjectGuid itemGUIDs[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < items_count; ++i) { - recv_data.read_skip<uint8>(); // item slot in mail, not used - recv_data >> itemGUIDs[i]; + itemGUIDs[i][2] = recvData.ReadBit(); + itemGUIDs[i][6] = recvData.ReadBit(); + itemGUIDs[i][3] = recvData.ReadBit(); + itemGUIDs[i][7] = recvData.ReadBit(); + itemGUIDs[i][1] = recvData.ReadBit(); + itemGUIDs[i][0] = recvData.ReadBit(); + itemGUIDs[i][4] = recvData.ReadBit(); + itemGUIDs[i][5] = recvData.ReadBit(); } - - recv_data >> money >> COD; // money and cod - recv_data >> unk3; // const 0 - recv_data >> unk4; // const 0 - + + mailbox[3] = recvData.ReadBit(); + mailbox[4] = recvData.ReadBit(); + receiverLength = recvData.ReadBits(7); + mailbox[2] = recvData.ReadBit(); + mailbox[6] = recvData.ReadBit(); + mailbox[1] = recvData.ReadBit(); + mailbox[7] = recvData.ReadBit(); + mailbox[5] = recvData.ReadBit(); + + recvData.ReadByteSeq(mailbox[4]); + + for (uint8 i = 0; i < items_count; ++i) + { + recvData.ReadByteSeq(itemGUIDs[i][6]); + recvData.ReadByteSeq(itemGUIDs[i][1]); + recvData.ReadByteSeq(itemGUIDs[i][7]); + recvData.ReadByteSeq(itemGUIDs[i][2]); + recvData.read_skip<uint8>(); // item slot in mail, not used + recvData.ReadByteSeq(itemGUIDs[i][3]); + recvData.ReadByteSeq(itemGUIDs[i][0]); + recvData.ReadByteSeq(itemGUIDs[i][4]); + recvData.ReadByteSeq(itemGUIDs[i][5]); + } + + recvData.ReadByteSeq(mailbox[7]); + recvData.ReadByteSeq(mailbox[3]); + recvData.ReadByteSeq(mailbox[6]); + recvData.ReadByteSeq(mailbox[5]); + + subject = recvData.ReadString(subjectLength); + receiver = recvData.ReadString(receiverLength); + + recvData.ReadByteSeq(mailbox[2]); + recvData.ReadByteSeq(mailbox[0]); + + body = recvData.ReadString(bodyLength); + + recvData.ReadByteSeq(mailbox[1]); + // packet read complete, now do check if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) @@ -89,13 +130,13 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) if (!rc) { - sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", + sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } - sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); + sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); if (player->GetGUID() == rc) { @@ -105,7 +146,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client - uint32 reqmoney = cost + money; + uint64 reqmoney = cost + money; if (!player->HasEnoughMoney(reqmoney) && !player->isGameMaster()) { @@ -245,8 +286,8 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) player->SendMailResult(0, MAIL_SEND, MAIL_OK); - player->ModifyMoney(-int32(reqmoney)); - player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); + player->ModifyMoney(-int64(reqmoney)); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; @@ -302,12 +343,12 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data) } //called when mail is read -void WorldSession::HandleMailMarkAsRead(WorldPacket & recv_data) +void WorldSession::HandleMailMarkAsRead(WorldPacket & recvData) { uint64 mailbox; uint32 mailId; - recv_data >> mailbox; - recv_data >> mailId; + recvData >> mailbox; + recvData >> mailId; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -325,13 +366,13 @@ void WorldSession::HandleMailMarkAsRead(WorldPacket & recv_data) } //called when client deletes mail -void WorldSession::HandleMailDelete(WorldPacket & recv_data) +void WorldSession::HandleMailDelete(WorldPacket & recvData) { uint64 mailbox; uint32 mailId; - recv_data >> mailbox; - recv_data >> mailId; - recv_data.read_skip<uint32>(); // mailTemplateId + recvData >> mailbox; + recvData >> mailId; + recvData.read_skip<uint32>(); // mailTemplateId if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -353,13 +394,13 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data) player->SendMailResult(mailId, MAIL_DELETED, MAIL_OK); } -void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data) +void WorldSession::HandleMailReturnToSender(WorldPacket & recvData) { uint64 mailbox; uint32 mailId; - recv_data >> mailbox; - recv_data >> mailId; - recv_data.read_skip<uint64>(); // original sender GUID for return to, not used + recvData >> mailbox; + recvData >> mailId; + recvData.read_skip<uint64>(); // original sender GUID for return to, not used if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -417,14 +458,14 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data) } //called when player takes item attached in mail -void WorldSession::HandleMailTakeItem(WorldPacket & recv_data) +void WorldSession::HandleMailTakeItem(WorldPacket& recvData) { uint64 mailbox; uint32 mailId; uint32 itemId; - recv_data >> mailbox; - recv_data >> mailId; - recv_data >> itemId; // item guid low + recvData >> mailbox; + recvData >> mailId; + recvData >> itemId; // item guid low if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -439,7 +480,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data) } // prevent cheating with skip client money check - if (!player->HasEnoughMoney(m->COD)) + if (!player->HasEnoughMoney(uint64(m->COD))) { player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_NOT_ENOUGH_MONEY); return; @@ -512,12 +553,15 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data) player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_EQUIP_ERROR, msg); } -void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data) +void WorldSession::HandleMailTakeMoney(WorldPacket& recvData) { uint64 mailbox; + uint64 money; uint32 mailId; - recv_data >> mailbox; - recv_data >> mailId; + + recvData >> mailbox; + recvData >> mailId; + recvData >> money; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -525,7 +569,8 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data) Player* player = _player; Mail* m = player->GetMail(mailId); - if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + if ((!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) || + (money > 0 && m->money != money)) { player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_ERR_INTERNAL_ERROR); return; @@ -533,7 +578,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data) player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK); - player->ModifyMoney(m->money); + player->ModifyMoney(money); m->money = 0; m->state = MAIL_STATE_CHANGED; player->m_mailsUpdated = true; @@ -546,10 +591,10 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data) } //called when player lists his received mails -void WorldSession::HandleGetMailList(WorldPacket & recv_data) +void WorldSession::HandleGetMailList(WorldPacket & recvData) { uint64 mailbox; - recv_data >> mailbox; + recvData >> mailbox; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -613,10 +658,10 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data) break; } - data << uint32((*itr)->COD); // COD - data << uint32(0); // package (Package.dbc) + data << uint64((*itr)->COD); // COD + data << uint32(0); // probably changed in 3.3.3 data << uint32((*itr)->stationery); // stationery (Stationery.dbc) - data << uint32((*itr)->money); // Gold + data << uint64((*itr)->money); // Gold data << uint32((*itr)->checked); // flags data << float(((*itr)->expire_time-time(NULL))/DAY); // Time data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc) @@ -668,13 +713,13 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data) } //used when player copies mail body to his inventory -void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data) +void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) { uint64 mailbox; uint32 mailId; - recv_data >> mailbox; - recv_data >> mailId; + recvData >> mailbox; + recvData >> mailId; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; @@ -705,7 +750,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data) return; } - bodyItem->SetText(mailTemplateEntry->content[GetSessionDbcLocale()]); + bodyItem->SetText(mailTemplateEntry->content); } else bodyItem->SetText(m->body); @@ -734,7 +779,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data) } //TODO Fix me! ... this void has probably bad condition, but good data are sent -void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recv_data*/) +void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recvData*/) { WorldPacket data(MSG_QUERY_NEXT_MAIL_TIME, 8); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 02b0ef9fc05..34ed6a8ef15 100755..100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -53,11 +53,11 @@ #include "AccountMgr.h" #include "Spell.h" -void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data) +void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_REPOP_REQUEST Message"); - recv_data.read_skip<uint8>(); + recvData.read_skip<uint8>(); // FromLua ? if (GetPlayer()->isAlive() || GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) return; @@ -82,7 +82,7 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data) GetPlayer()->RepopAtGraveyard(); } -void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data) +void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GOSSIP_SELECT_OPTION"); @@ -91,10 +91,10 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data) uint64 guid; std::string code = ""; - recv_data >> guid >> menuId >> gossipListId; + recvData >> guid >> menuId >> gossipListId; if (_player->PlayerTalkClass->IsGossipOptionCoded(gossipListId)) - recv_data >> code; + recvData >> code; Creature* unit = NULL; GameObject* go = NULL; @@ -167,7 +167,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) +void WorldSession::HandleWhoOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_WHO Message"); @@ -182,15 +182,15 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) uint32 zoneids[10]; // 10 is client limit std::string player_name, guild_name; - recv_data >> level_min; // maximal player level, default 0 - recv_data >> level_max; // minimal player level, default 100 (MAX_LEVEL) - recv_data >> player_name; // player name, case sensitive... + recvData >> level_min; // maximal player level, default 0 + recvData >> level_max; // minimal player level, default 100 (MAX_LEVEL) + recvData >> player_name; // player name, case sensitive... - recv_data >> guild_name; // guild name, case sensitive... + recvData >> guild_name; // guild name, case sensitive... - recv_data >> racemask; // race mask - recv_data >> classmask; // class mask - recv_data >> zones_count; // zones count, client limit = 10 (2.0.10) + recvData >> racemask; // race mask + recvData >> classmask; // class mask + recvData >> zones_count; // zones count, client limit = 10 (2.0.10) if (zones_count > 10) return; // can't be received from real client or broken packet @@ -198,12 +198,12 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) for (uint32 i = 0; i < zones_count; ++i) { uint32 temp; - recv_data >> temp; // zone id, 0 if zone is unknown... + recvData >> temp; // zone id, 0 if zone is unknown... zoneids[i] = temp; sLog->outDebug(LOG_FILTER_NETWORKIO, "Zone %u: %u", i, zoneids[i]); } - recv_data >> str_count; // user entered strings count, client limit=4 (checked on 2.0.10) + recvData >> str_count; // user entered strings count, client limit=4 (checked on 2.0.10) if (str_count > 4) return; // can't be received from real client or broken packet @@ -214,7 +214,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) for (uint32 i = 0; i < str_count; ++i) { std::string temp; - recv_data >> temp; // user entered string, it used as universal search pattern(guild+player name)? + recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)? if (!Utf8toWStr(temp, str[i])) continue; @@ -364,14 +364,14 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Send SMSG_WHO Message"); } -void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - %u", GetSecurity()); if (uint64 lguid = GetPlayer()->GetLootGUID()) DoLootRelease(lguid); - uint8 reason = 0; + uint32 reason = 0; if (GetPlayer()->isInCombat()) reason = 1; @@ -383,8 +383,8 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recv_data*/) if (reason) { WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); - data << uint8(reason); - data << uint32(0); + data << uint32(reason); + data << uint8(0); SendPacket(&data); LogoutRequest(0); return; @@ -395,8 +395,8 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recv_data*/) GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))) { WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); - data << uint8(0); - data << uint32(16777216); + data << uint32(reason); + data << uint8(1); // instant logout SendPacket(&data); LogoutPlayer(true); return; @@ -406,27 +406,23 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recv_data*/) if (GetPlayer()->CanFreeMove()) { GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT); - - WorldPacket data(SMSG_FORCE_MOVE_ROOT, (8+4)); // guess size - data.append(GetPlayer()->GetPackGUID()); - data << (uint32)2; - SendPacket(&data); + GetPlayer()->SetRooted(true); GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } WorldPacket data(SMSG_LOGOUT_RESPONSE, 1+4); - data << uint8(0); data << uint32(0); + data << uint8(0); SendPacket(&data); LogoutRequest(time(NULL)); } -void WorldSession::HandlePlayerLogoutOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandlePlayerLogoutOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_PLAYER_LOGOUT Message"); } -void WorldSession::HandleLogoutCancelOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleLogoutCancelOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_LOGOUT_CANCEL Message"); @@ -443,10 +439,7 @@ void WorldSession::HandleLogoutCancelOpcode(WorldPacket & /*recv_data*/) if (GetPlayer()->CanFreeMove()) { //!we can move again - data.Initialize(SMSG_FORCE_MOVE_UNROOT, 8); // guess size - data.append(GetPlayer()->GetPackGUID()); - data << uint32(0); - SendPacket(&data); + GetPlayer()->SetRooted(false); //! Stand Up GetPlayer()->SetStandState(UNIT_STAND_STATE_STAND); @@ -458,13 +451,13 @@ void WorldSession::HandleLogoutCancelOpcode(WorldPacket & /*recv_data*/) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_LOGOUT_CANCEL_ACK Message"); } -void WorldSession::HandleTogglePvP(WorldPacket & recv_data) +void WorldSession::HandleTogglePvP(WorldPacket & recvData) { // this opcode can be used in two ways: Either set explicit new status or toggle old status - if (recv_data.size() == 1) + if (recvData.size() == 1) { bool newPvPStatus; - recv_data >> newPvPStatus; + recvData >> newPvPStatus; GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus); GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus); } @@ -489,10 +482,10 @@ void WorldSession::HandleTogglePvP(WorldPacket & recv_data) // pvp->HandlePlayerActivityChanged(_player); } -void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data) +void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recvData) { uint32 newZone; - recv_data >> newZone; + recvData >> newZone; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone); @@ -503,41 +496,47 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data) //GetPlayer()->SendInitWorldStates(true, newZone); } -void WorldSession::HandleSetSelectionOpcode(WorldPacket & recv_data) +void WorldSession::HandleReturnToGraveyard(WorldPacket& /*recvPacket*/) +{ + if (GetPlayer()->isAlive() || !GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + return; + GetPlayer()->RepopAtGraveyard(); +} + +void WorldSession::HandleSetSelectionOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; _player->SetSelection(guid); } -void WorldSession::HandleStandStateChangeOpcode(WorldPacket & recv_data) +void WorldSession::HandleStandStateChangeOpcode(WorldPacket & recvData) { // sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: Received CMSG_STANDSTATECHANGE"); -- too many spam in log at lags/debug stop uint32 animstate; - recv_data >> animstate; + recvData >> animstate; _player->SetStandState(animstate); } -void WorldSession::HandleContactListOpcode(WorldPacket & recv_data) +void WorldSession::HandleContactListOpcode(WorldPacket& recvData) { - uint32 unk; - recv_data >> unk; - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_CONTACT_LIST - Unk: %d", unk); + recvData.read_skip<uint32>(); // always 1 + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_CONTACT_LIST"); _player->GetSocial()->SendSocialList(_player); } -void WorldSession::HandleAddFriendOpcode(WorldPacket & recv_data) +void WorldSession::HandleAddFriendOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_FRIEND"); std::string friendName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); std::string friendNote; - recv_data >> friendName; + recvData >> friendName; - recv_data >> friendNote; + recvData >> friendNote; if (!normalizePlayerName(friendName)) return; @@ -606,13 +605,13 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent (SMSG_FRIEND_STATUS)"); } -void WorldSession::HandleDelFriendOpcode(WorldPacket & recv_data) +void WorldSession::HandleDelFriendOpcode(WorldPacket& recvData) { uint64 FriendGUID; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_DEL_FRIEND"); - recv_data >> FriendGUID; + recvData >> FriendGUID; _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(FriendGUID), false); @@ -621,13 +620,13 @@ void WorldSession::HandleDelFriendOpcode(WorldPacket & recv_data) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent motd (SMSG_FRIEND_STATUS)"); } -void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recv_data) +void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_IGNORE"); std::string ignoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN); - recv_data >> ignoreName; + recvData >> ignoreName; if (!normalizePlayerName(ignoreName)) return; @@ -679,13 +678,13 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent (SMSG_FRIEND_STATUS)"); } -void WorldSession::HandleDelIgnoreOpcode(WorldPacket & recv_data) +void WorldSession::HandleDelIgnoreOpcode(WorldPacket & recvData) { uint64 IgnoreGUID; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_DEL_IGNORE"); - recv_data >> IgnoreGUID; + recvData >> IgnoreGUID; _player->GetSocial()->RemoveFromSocialList(GUID_LOPART(IgnoreGUID), true); @@ -694,23 +693,23 @@ void WorldSession::HandleDelIgnoreOpcode(WorldPacket & recv_data) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent motd (SMSG_FRIEND_STATUS)"); } -void WorldSession::HandleSetContactNotesOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetContactNotesOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_CONTACT_NOTES"); uint64 guid; std::string note; - recv_data >> guid >> note; + recvData >> guid >> note; _player->GetSocial()->SetFriendNote(GUID_LOPART(guid), note); } -void WorldSession::HandleBugOpcode(WorldPacket & recv_data) +void WorldSession::HandleBugOpcode(WorldPacket & recvData) { uint32 suggestion, contentlen, typelen; std::string content, type; - recv_data >> suggestion >> contentlen >> content; + recvData >> suggestion >> contentlen >> content; - recv_data >> typelen >> type; + recvData >> typelen >> type; if (suggestion == 0) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BUG [Bug Report]"); @@ -728,12 +727,12 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data) CharacterDatabase.Execute(stmt); } -void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data) +void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE"); uint64 guid; - recv_data >> guid; + recvData >> guid; if (GetPlayer()->isAlive()) return; @@ -765,14 +764,14 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data) GetPlayer()->SpawnCorpseBones(); } -void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data) +void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE"); uint64 guid; uint8 status; - recv_data >> guid; - recv_data >> status; + recvData >> guid; + recvData >> status; if (GetPlayer()->isAlive()) return; @@ -806,10 +805,10 @@ void WorldSession::SendAreaTriggerMessage(const char* Text, ...) SendPacket(&data); } -void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) +void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) { uint32 triggerId; - recv_data >> triggerId; + recvData >> triggerId; sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_AREATRIGGER. Trigger ID: %u", triggerId); @@ -936,12 +935,12 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data) player->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, at->target_Orientation, TELE_TO_NOT_LEAVE_TRANSPORT); } -void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) +void WorldSession::HandleUpdateAccountData(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); uint32 type, timestamp, decompressedSize; - recv_data >> type >> timestamp >> decompressedSize; + recvData >> type >> timestamp >> decompressedSize; sLog->outDebug(LOG_FILTER_NETWORKIO, "UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize); @@ -962,7 +961,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) if (decompressedSize > 0xFFFF) { - recv_data.rfinish(); // unnneded warning spam in this case + recvData.rfinish(); // unnneded warning spam in this case sLog->outError(LOG_FILTER_NETWORKIO, "UAD: Account data packet too big, size %u", decompressedSize); return; } @@ -971,14 +970,14 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) dest.resize(decompressedSize); uLongf realSize = decompressedSize; - if (uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK) + if (uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recvData.contents() + recvData.rpos()), recvData.size() - recvData.rpos()) != Z_OK) { - recv_data.rfinish(); // unnneded warning spam in this case + recvData.rfinish(); // unnneded warning spam in this case sLog->outError(LOG_FILTER_NETWORKIO, "UAD: Failed to decompress account data"); return; } - recv_data.rfinish(); // uncompress read (recv_data.size() - recv_data.rpos()) + recvData.rfinish(); // uncompress read (recvData.size() - recvData.rpos()) std::string adata; dest >> adata; @@ -991,12 +990,12 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data) SendPacket(&data); } -void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) +void WorldSession::HandleRequestAccountData(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); uint32 type; - recv_data >> type; + recvData >> type; sLog->outDebug(LOG_FILTER_NETWORKIO, "RAD: type %u", type); @@ -1029,12 +1028,19 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) SendPacket(&data); } -void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) +int32 WorldSession::HandleEnableNagleAlgorithm() +{ + // Instructs the server we wish to receive few amounts of large packets (SMSG_MULTIPLE_PACKETS?) + // instead of large amount of small packets + return 0; +} + +void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_SET_ACTION_BUTTON"); uint8 button; uint32 packetData; - recv_data >> button >> packetData; + recvData >> button >> packetData; uint32 action = ACTION_BUTTON_ACTION(packetData); uint8 type = ACTION_BUTTON_TYPE(packetData); @@ -1070,29 +1076,49 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) } } -void WorldSession::HandleCompleteCinematic(WorldPacket & /*recv_data*/) +void WorldSession::HandleCompleteCinematic(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC"); } -void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recv_data*/) +void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA"); } -void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data) +void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recvData) { - /* WorldSession::Update(getMSTime());*/ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_MOVE_TIME_SKIPPED"); - uint64 guid; - recv_data.readPackGUID(guid); - recv_data.read_skip<uint32>(); + ObjectGuid guid; + uint32 time; + recvData >> time; + + guid[5] = recvData.ReadBit(); + guid[1] = recvData.ReadBit(); + guid[3] = recvData.ReadBit(); + guid[7] = recvData.ReadBit(); + guid[6] = recvData.ReadBit(); + guid[0] = recvData.ReadBit(); + guid[4] = recvData.ReadBit(); + guid[2] = recvData.ReadBit(); + + recvData.ReadByteSeq(guid[7]); + recvData.ReadByteSeq(guid[1]); + recvData.ReadByteSeq(guid[2]); + recvData.ReadByteSeq(guid[4]); + recvData.ReadByteSeq(guid[3]); + recvData.ReadByteSeq(guid[6]); + recvData.ReadByteSeq(guid[0]); + recvData.ReadByteSeq(guid[5]); + + //TODO! + /* uint64 guid; uint32 time_skipped; - recv_data >> guid; - recv_data >> time_skipped; + recvData >> guid; + recvData >> time_skipped; sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_MOVE_TIME_SKIPPED"); /// TODO @@ -1103,84 +1129,84 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data) */ } -void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data) +void WorldSession::HandleFeatherFallAck(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); // no used - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam } -void WorldSession::HandleMoveUnRootAck(WorldPacket& recv_data) +void WorldSession::HandleMoveUnRootAck(WorldPacket& recvData) { // no used - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam /* uint64 guid; - recv_data >> guid; + recvData >> guid; // now can skip not our packet if (_player->GetGUID() != guid) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK"); - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; movementInfo.guid = guid; - ReadMovementInfo(recv_data, &movementInfo); - recv_data.read_skip<float>(); // unk2 + ReadMovementInfo(recvData, &movementInfo); + recvData.read_skip<float>(); // unk2 */ } -void WorldSession::HandleMoveRootAck(WorldPacket& recv_data) +void WorldSession::HandleMoveRootAck(WorldPacket& recvData) { // no used - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam /* uint64 guid; - recv_data >> guid; + recvData >> guid; // now can skip not our packet if (_player->GetGUID() != guid) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_FORCE_MOVE_ROOT_ACK"); - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); */ } -void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data) +void WorldSession::HandleSetActionBarToggles(WorldPacket& recvPacket) { - uint8 ActionBar; + uint8 actionBar; - recv_data >> ActionBar; + recvPacket >> actionBar; if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED) { - if (ActionBar != 0) - sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetActionBarToggles in not logged state with value: %u, ignored", uint32(ActionBar)); + if (actionBar != 0) + sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::HandleSetActionBarToggles in not logged state with value: %u, ignored", uint32(actionBar)); return; } - GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, ActionBar); + GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, actionBar); } -void WorldSession::HandlePlayedTime(WorldPacket& recv_data) +void WorldSession::HandlePlayedTime(WorldPacket& recvData) { uint8 unk1; - recv_data >> unk1; // 0 or 1 expected + recvData >> unk1; // 0 or 1 expected WorldPacket data(SMSG_PLAYED_TIME, 4 + 4 + 1); data << uint32(_player->GetTotalPlayedTime()); @@ -1189,10 +1215,10 @@ void WorldSession::HandlePlayedTime(WorldPacket& recv_data) SendPacket(&data); } -void WorldSession::HandleInspectOpcode(WorldPacket& recv_data) +void WorldSession::HandleInspectOpcode(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT"); @@ -1205,15 +1231,12 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data) return; } - uint32 talent_points = 0x47; - uint32 guid_size = player->GetPackGUID().wpos(); - WorldPacket data(SMSG_INSPECT_TALENT, guid_size+4+talent_points); - data.append(player->GetPackGUID()); + uint32 talent_points = 41; + WorldPacket data(SMSG_INSPECT_TALENT, 8 + 4 + 1 + 1 + talent_points + 8 + 4 + 8 + 4); + data << player->GetGUID(); if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->isGameMaster()) - { player->BuildPlayerTalentsInfoData(&data); - } else { data << uint32(0); // unspentTalentPoints @@ -1222,13 +1245,20 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data) } player->BuildEnchantmentsInfoData(&data); + if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) + { + data << uint64(guild->GetGUID()); + data << uint32(guild->GetLevel()); + data << uint64(0/*guild->GetXP()*/); + data << uint32(0/*guild->GetMembersCount()*/); // number of members + } SendPacket(&data); } -void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data) +void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; Player* player = ObjectAccessor::FindPlayer(guid); @@ -1238,17 +1268,15 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data) return; } - WorldPacket data(MSG_INSPECT_HONOR_STATS, 8+1+4*4); - data << uint64(player->GetGUID()); - data << uint8(player->GetHonorPoints()); + WorldPacket data(SMSG_INSPECT_HONOR_STATS, 4+1+4+8); data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS)); - data << uint32(player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION)); - data << uint32(player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION)); + data << uint8(0); // rank data << uint32(player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS)); + data << uint64(player->GetGUID()); SendPacket(&data); } -void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) +void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData) { uint32 time; uint32 mapid; @@ -1257,12 +1285,12 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) float PositionZ; float Orientation; - recv_data >> time; // time in m.sec. - recv_data >> mapid; - recv_data >> PositionX; - recv_data >> PositionY; - recv_data >> PositionZ; - recv_data >> Orientation; // o (3.141593 = 180 degrees) + recvData >> time; // time in m.sec. + recvData >> mapid; + recvData >> PositionX; + recvData >> PositionY; + recvData >> PositionZ; + recvData >> Orientation; // o (3.141593 = 180 degrees) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT"); @@ -1280,11 +1308,11 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data) SendNotification(LANG_YOU_NOT_HAVE_PERMISSION); } -void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) +void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_WHOIS"); std::string charname; - recv_data >> charname; + recvData >> charname; if (!AccountMgr::IsAdminAccount(GetSecurity())) { @@ -1340,7 +1368,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data) sLog->outDebug(LOG_FILTER_NETWORKIO, "Received whois command from player %s for character %s", GetPlayer()->GetName(), charname.c_str()); } -void WorldSession::HandleComplainOpcode(WorldPacket & recv_data) +void WorldSession::HandleComplainOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_COMPLAIN"); @@ -1351,21 +1379,21 @@ void WorldSession::HandleComplainOpcode(WorldPacket & recv_data) uint32 unk3 = 0; uint32 unk4 = 0; std::string description = ""; - recv_data >> spam_type; // unk 0x01 const, may be spam type (mail/chat) - recv_data >> spammer_guid; // player guid + recvData >> spam_type; // unk 0x01 const, may be spam type (mail/chat) + recvData >> spammer_guid; // player guid switch (spam_type) { case 0: - recv_data >> unk1; // const 0 - recv_data >> unk2; // probably mail id - recv_data >> unk3; // const 0 + recvData >> unk1; // const 0 + recvData >> unk2; // probably mail id + recvData >> unk3; // const 0 break; case 1: - recv_data >> unk1; // probably language - recv_data >> unk2; // message type? - recv_data >> unk3; // probably channel id - recv_data >> unk4; // unk random value - recv_data >> description; // spam description string (messagetype, channel name, player name, message) + recvData >> unk1; // probably language + recvData >> unk2; // message type? + recvData >> unk3; // probably channel id + recvData >> unk4; // unk random value + recvData >> description; // spam description string (messagetype, channel name, player name, message) break; } @@ -1373,20 +1401,21 @@ void WorldSession::HandleComplainOpcode(WorldPacket & recv_data) // if it's mail spam - ALL mails from this spammer automatically removed by client // Complaint Received message - WorldPacket data(SMSG_COMPLAIN_RESULT, 1); - data << uint8(0); + WorldPacket data(SMSG_COMPLAIN_RESULT, 2); + data << uint8(0); // value 1 resets CGChat::m_complaintsSystemStatus in client. (unused?) + data << uint8(0); // value 0xC generates a "CalendarError" in client. SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "REPORT SPAM: type %u, guid %u, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", spam_type, GUID_LOPART(spammer_guid), unk1, unk2, unk3, unk4, description.c_str()); } -void WorldSession::HandleRealmSplitOpcode(WorldPacket & recv_data) +void WorldSession::HandleRealmSplitOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_REALM_SPLIT"); uint32 unk; std::string split_date = "01/01/01"; - recv_data >> unk; + recvData >> unk; WorldPacket data(SMSG_REALM_SPLIT, 4+4+split_date.size()+1); data << unk; @@ -1400,12 +1429,12 @@ void WorldSession::HandleRealmSplitOpcode(WorldPacket & recv_data) //sLog->outDebug("response sent %u", unk); } -void WorldSession::HandleFarSightOpcode(WorldPacket & recv_data) +void WorldSession::HandleFarSightOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_FAR_SIGHT"); uint8 apply; - recv_data >> apply; + recvData >> apply; switch (apply) { @@ -1428,12 +1457,12 @@ void WorldSession::HandleFarSightOpcode(WorldPacket & recv_data) GetPlayer()->UpdateVisibilityForPlayer(); } -void WorldSession::HandleSetTitleOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetTitleOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_SET_TITLE"); int32 title; - recv_data >> title; + recvData >> title; // -1 at none if (title > 0 && title < MAX_TITLE_INDEX) @@ -1447,12 +1476,12 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket & recv_data) GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title); } -void WorldSession::HandleTimeSyncResp(WorldPacket & recv_data) +void WorldSession::HandleTimeSyncResp(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_TIME_SYNC_RESP"); uint32 counter, clientTicks; - recv_data >> counter >> clientTicks; + recvData >> clientTicks >> counter; if (counter != _player->m_timeSyncCounter - 1) sLog->outDebug(LOG_FILTER_NETWORKIO, "Wrong time sync counter from player %s (cheater?)", _player->GetName()); @@ -1467,7 +1496,7 @@ void WorldSession::HandleTimeSyncResp(WorldPacket & recv_data) _player->m_timeSyncClient = clientTicks; } -void WorldSession::HandleResetInstancesOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleResetInstancesOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_RESET_INSTANCES"); @@ -1480,12 +1509,12 @@ void WorldSession::HandleResetInstancesOpcode(WorldPacket & /*recv_data*/) _player->ResetInstances(INSTANCE_RESET_ALL, false); } -void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_SET_DUNGEON_DIFFICULTY"); uint32 mode; - recv_data >> mode; + recvData >> mode; if (mode >= MAX_DUNGEON_DIFFICULTY) { @@ -1537,12 +1566,12 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_SET_RAID_DIFFICULTY"); uint32 mode; - recv_data >> mode; + recvData >> mode; if (mode >= MAX_RAID_DIFFICULTY) { @@ -1594,7 +1623,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CANCEL_MOUNT_AURA"); @@ -1615,54 +1644,63 @@ void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recv_data*/) _player->RemoveAurasByType(SPELL_AURA_MOUNTED); } -void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket & recv_data) +void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket & recvData) { // fly mode on/off sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_SET_CAN_FLY_ACK"); uint64 guid; // guid - unused - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; movementInfo.guid = guid; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); - recv_data.read_skip<float>(); // unk2 + recvData.read_skip<float>(); // unk2 _player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags(); } -void WorldSession::HandleRequestPetInfoOpcode(WorldPacket & /*recv_data */) +void WorldSession::HandleRequestPetInfoOpcode(WorldPacket & /*recvData */) { /* sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_REQUEST_PET_INFO"); - recv_data.hexlike(); + recvData.hexlike(); */ } -void WorldSession::HandleSetTaxiBenchmarkOpcode(WorldPacket & recv_data) +void WorldSession::HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData) { uint8 mode; - recv_data >> mode; + recvData >> mode; sLog->outDebug(LOG_FILTER_NETWORKIO, "Client used \"/timetest %d\" command", mode); } -void WorldSession::HandleQueryInspectAchievements(WorldPacket & recv_data) +void WorldSession::HandleQueryInspectAchievements(WorldPacket& recvData) { uint64 guid; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); Player* player = ObjectAccessor::FindPlayer(guid); if (!player) return; - player->GetAchievementMgr().SendRespondInspectAchievements(_player); + player->GetAchievementMgr().SendAchievementInfo(_player); } -void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recv_data*/) +void WorldSession::HandleGuildAchievementProgressQuery(WorldPacket& recvData) +{ + uint32 achievementId; + recvData >> achievementId; + + if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId())) + guild->GetAchievementMgr().SendAchievementInfo(_player, achievementId); +} + +void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recvData*/) { // empty opcode sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE"); @@ -1672,7 +1710,7 @@ void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recv_data*/) SendPacket(&data); } -void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recv_data*/) +void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/) { // empty opcode sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES"); @@ -1687,7 +1725,7 @@ void WorldSession::SendSetPhaseShift(uint32 PhaseShift) SendPacket(&data); } -void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/) +void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recvData*/) { if (_player->isInFlight()) return; @@ -1720,6 +1758,57 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) _player->SetPendingBind(0, 0); } +void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket) +{ + uint32 type, count; + recvPacket >> type; + + count = recvPacket.ReadBits(23); + + ObjectGuid* guids = new ObjectGuid[count]; + for (uint32 i = 0; i < count; ++i) + { + guids[i][0] = recvPacket.ReadBit(); + guids[i][4] = recvPacket.ReadBit(); + guids[i][7] = recvPacket.ReadBit(); + guids[i][2] = recvPacket.ReadBit(); + guids[i][5] = recvPacket.ReadBit(); + guids[i][3] = recvPacket.ReadBit(); + guids[i][6] = recvPacket.ReadBit(); + guids[i][1] = recvPacket.ReadBit(); + } + + uint32 entry; + for (uint32 i = 0; i < count; ++i) + { + recvPacket.ReadByteSeq(guids[i][5]); + recvPacket.ReadByteSeq(guids[i][6]); + recvPacket.ReadByteSeq(guids[i][7]); + recvPacket.ReadByteSeq(guids[i][0]); + recvPacket.ReadByteSeq(guids[i][1]); + recvPacket.ReadByteSeq(guids[i][3]); + recvPacket.ReadByteSeq(guids[i][4]); + recvPacket >> entry; + recvPacket.ReadByteSeq(guids[i][2]); + + switch (type) + { + case DB2_REPLY_ITEM: + SendItemDb2Reply(entry); + break; + case DB2_REPLY_SPARSE: + SendItemSparseDb2Reply(entry); + break; + default: + sLog->outError(LOG_FILTER_NETWORKIO, "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", type); + recvPacket.rfinish(); + break; + } + } + + delete[] guids; +} + void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY"); @@ -1759,7 +1848,39 @@ void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) { uint32 opcode; recvPacket >> opcode; - recvPacket.SetOpcode(opcode); + recvPacket.SetOpcode(MSG_MOVE_STOP); // always set to MSG_MOVE_STOP in client SetOpcode HandleMovementOpcodes(recvPacket); } } + void WorldSession::HandleViolenceLevel(WorldPacket& recvPacket) + { + uint8 violenceLevel; + recvPacket >> violenceLevel; + + // do something? + } + + void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket) + { + ObjectGuid guid; + guid[6] = recvPacket.ReadBit(); + guid[7] = recvPacket.ReadBit(); + guid[4] = recvPacket.ReadBit(); + guid[0] = recvPacket.ReadBit(); + guid[1] = recvPacket.ReadBit(); + guid[5] = recvPacket.ReadBit(); + guid[3] = recvPacket.ReadBit(); + guid[2] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(guid[6]); + recvPacket.ReadByteSeq(guid[7]); + recvPacket.ReadByteSeq(guid[2]); + recvPacket.ReadByteSeq(guid[3]); + recvPacket.ReadByteSeq(guid[1]); + recvPacket.ReadByteSeq(guid[4]); + recvPacket.ReadByteSeq(guid[0]); + recvPacket.ReadByteSeq(guid[5]); + + WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), guid); + sLog->outError(LOG_FILTER_NETWORKIO, "Object update failed for object "UI64FMTD" (%s) for player %s (%u)", uint64(guid), obj ? obj->GetName() : "object-not-found", GetPlayerName(), GetGuidLow()); + } diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 27b1f2eca3f..da2e7e5bfd2 100755..100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -30,8 +30,9 @@ #include "WaypointMovementGenerator.h" #include "InstanceSaveMgr.h" #include "ObjectMgr.h" +#include "MovementStructures.h" -void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket& /*recvPacket*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: got MSG_MOVE_WORLDPORT_ACK."); HandleMoveWorldportAckOpcode(); @@ -187,16 +188,33 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->ProcessDelayedOperations(); } -void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) +void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK"); - uint64 guid; - - recv_data.readPackGUID(guid); + ObjectGuid guid; uint32 flags, time; - recv_data >> flags >> time; - sLog->outDebug(LOG_FILTER_NETWORKIO, "Guid " UI64FMTD, guid); + recvPacket >> flags >> time; + + guid[5] = recvPacket.ReadBit(); + guid[0] = recvPacket.ReadBit(); + guid[1] = recvPacket.ReadBit(); + guid[6] = recvPacket.ReadBit(); + guid[3] = recvPacket.ReadBit(); + guid[7] = recvPacket.ReadBit(); + guid[2] = recvPacket.ReadBit(); + guid[4] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(guid[4]); + recvPacket.ReadByteSeq(guid[2]); + recvPacket.ReadByteSeq(guid[7]); + recvPacket.ReadByteSeq(guid[6]); + recvPacket.ReadByteSeq(guid[5]); + recvPacket.ReadByteSeq(guid[1]); + recvPacket.ReadByteSeq(guid[3]); + recvPacket.ReadByteSeq(guid[0]); + + sLog->outDebug(LOG_FILTER_NETWORKIO, "Guid " UI64FMTD, uint64(guid)); sLog->outDebug(LOG_FILTER_NETWORKIO, "Flags %u, time %u", flags, time/IN_MILLISECONDS); Player* plMover = _player->m_mover->ToPlayer(); @@ -238,9 +256,9 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) GetPlayer()->ProcessDelayedOperations(); } -void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) +void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket) { - uint16 opcode = recvData.GetOpcode(); + uint16 opcode = recvPacket.GetOpcode(); Unit* mover = _player->m_mover; @@ -251,46 +269,41 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck if (plrMover && plrMover->IsBeingTeleported()) { - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam return; } /* extract packet */ - uint64 guid; - - recvData.readPackGUID(guid); - MovementInfo movementInfo; - movementInfo.guid = guid; - ReadMovementInfo(recvData, &movementInfo); - - recvData.rfinish(); // prevent warnings spam + ReadMovementInfo(recvPacket, &movementInfo); // prevent tampered movement data - if (guid != mover->GetGUID()) + if (movementInfo.guid != mover->GetGUID()) + { + sLog->outError(LOG_FILTER_NETWORKIO, "HandleMovementOpcodes: guid error"); return; - + } if (!movementInfo.pos.IsPositionValid()) { - recvData.rfinish(); // prevent warnings spam + sLog->outError(LOG_FILTER_NETWORKIO, "HandleMovementOpcodes: Invalid Position"); return; } /* handle special cases */ - if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) + if (movementInfo.t_guid) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50) { - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam return; } if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation())) { - recvData.rfinish(); // prevent warnings spam + recvPacket.rfinish(); // prevent warnings spam return; } @@ -339,7 +352,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) { GameObject* go = mover->GetMap()->GetGameObject(movementInfo.t_guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) - movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT; + movementInfo.t_guid = 0; } } else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave @@ -364,10 +377,10 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) /*----------------------*/ /* process position-change */ - WorldPacket data(opcode, recvData.size()); + WorldPacket data(SMSG_PLAYER_MOVE, recvPacket.size()); movementInfo.time = getMSTime(); movementInfo.guid = mover->GetGUID(); - WriteMovementInfo(&data, &movementInfo); + WriteMovementInfo(data, &movementInfo); mover->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; @@ -406,34 +419,34 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData) } } -void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) +void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) { - uint32 opcode = recv_data.GetOpcode(); - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); + uint32 opcode = recvData.GetOpcode(); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(Opcodes(opcode)), opcode, opcode); /* extract packet */ uint64 guid; uint32 unk1; float newspeed; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); // now can skip not our packet if (_player->GetGUID() != guid) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } // continue parse packet - recv_data >> unk1; // counter or moveEvent + recvData >> unk1; // counter or moveEvent MovementInfo movementInfo; movementInfo.guid = guid; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); - recv_data >> newspeed; + recvData >> newspeed; /*----------------*/ // client ACK send one packet for mounted/run case and need skip all except last from its @@ -445,15 +458,15 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) switch (opcode) { - case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; - case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break; - case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break; - case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break; - case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break; - case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break; - case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break; - case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break; - case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break; + //case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break; + //case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break; + //case CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break; + //case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break; + //case CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break; + //case CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break; + //case CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break; + //case CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break; + //case CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break; default: sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); return; @@ -485,12 +498,29 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) } } -void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data) +void WorldSession::HandleSetActiveMoverOpcode(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); - uint64 guid; - recv_data >> guid; + ObjectGuid guid; + + guid[7] = recvPacket.ReadBit(); + guid[2] = recvPacket.ReadBit(); + guid[1] = recvPacket.ReadBit(); + guid[0] = recvPacket.ReadBit(); + guid[4] = recvPacket.ReadBit(); + guid[5] = recvPacket.ReadBit(); + guid[6] = recvPacket.ReadBit(); + guid[3] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(guid[3]); + recvPacket.ReadByteSeq(guid[2]); + recvPacket.ReadByteSeq(guid[4]); + recvPacket.ReadByteSeq(guid[0]); + recvPacket.ReadByteSeq(guid[5]); + recvPacket.ReadByteSeq(guid[1]); + recvPacket.ReadByteSeq(guid[6]); + recvPacket.ReadByteSeq(guid[7]); if (GetPlayer()->IsInWorld()) { @@ -499,22 +529,22 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data) } } -void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) +void WorldSession::HandleMoveNotActiveMover(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER"); uint64 old_mover_guid; - recv_data.readPackGUID(old_mover_guid); + recvData.readPackGUID(old_mover_guid); MovementInfo mi; - ReadMovementInfo(recv_data, &mi); + ReadMovementInfo(recvData, &mi); mi.guid = old_mover_guid; _player->m_movementInfo = mi; } -void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvData*/) { WorldPacket data(SMSG_MOUNTSPECIAL_ANIM, 8); data << uint64(GetPlayer()->GetGUID()); @@ -522,24 +552,24 @@ void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recv_data*/) GetPlayer()->SendMessageToSet(&data, false); } -void WorldSession::HandleMoveKnockBackAck(WorldPacket & recv_data) +void WorldSession::HandleMoveKnockBackAck(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_KNOCK_BACK_ACK"); uint64 guid; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); if (_player->m_mover->GetGUID() != guid) return; - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); _player->m_movementInfo = movementInfo; - WorldPacket data(MSG_MOVE_KNOCK_BACK, 66); + WorldPacket data(SMSG_MOVE_UPDATE_KNOCK_BACK, 66); data.appendPackGUID(guid); _player->BuildMovementPacket(&data); @@ -552,45 +582,518 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket & recv_data) _player->SendMessageToSet(&data, false); } -void WorldSession::HandleMoveHoverAck(WorldPacket& recv_data) +void WorldSession::HandleMoveHoverAck(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_HOVER_ACK"); uint64 guid; // guid - unused - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); - recv_data.read_skip<uint32>(); // unk2 + recvData.read_skip<uint32>(); // unk2 } -void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recv_data) +void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_WATER_WALK_ACK"); uint64 guid; // guid - unused - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); - recv_data.read_skip<uint32>(); // unk2 + recvData.read_skip<uint32>(); // unk2 } -void WorldSession::HandleSummonResponseOpcode(WorldPacket& recv_data) +void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData) { if (!_player->isAlive() || _player->isInCombat()) return; - uint64 summoner_guid; + uint64 summonerGuid; bool agree; - recv_data >> summoner_guid; - recv_data >> agree; + recvData >> summonerGuid; + recvData >> agree; _player->SummonIfPossible(agree); } + +void WorldSession::ReadMovementInfo(WorldPacket& data, MovementInfo* mi) +{ + bool hasMovementFlags = false; + bool hasMovementFlags2 = false; + bool hasTimestamp = false; + bool hasOrientation = false; + bool hasTransportData = false; + bool hasTransportTime2 = false; + bool hasTransportTime3 = false; + bool hasPitch = false; + bool hasFallData = false; + bool hasFallDirection = false; + bool hasSplineElevation = false; + bool hasSpline = false; + + MovementStatusElements* sequence = GetMovementStatusElementsSequence(data.GetOpcode()); + if (sequence == NULL) + { + sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::ReadMovementInfo: No movement sequence found for opcode 0x%04X", uint32(data.GetOpcode())); + return; + } + + ObjectGuid guid; + ObjectGuid tguid; + + for (uint32 i = 0; i < MSE_COUNT; ++i) + { + MovementStatusElements element = sequence[i]; + if (element == MSEEnd) + break; + + if (element >= MSEHasGuidByte0 && element <= MSEHasGuidByte7) + { + guid[element - MSEHasGuidByte0] = data.ReadBit(); + continue; + } + + if (element >= MSEHasTransportGuidByte0 && + element <= MSEHasTransportGuidByte7) + { + if (hasTransportData) + tguid[element - MSEHasTransportGuidByte0] = data.ReadBit(); + continue; + } + + if (element >= MSEGuidByte0 && element <= MSEGuidByte7) + { + data.ReadByteSeq(guid[element - MSEGuidByte0]); + continue; + } + + if (element >= MSETransportGuidByte0 && + element <= MSETransportGuidByte7) + { + if (hasTransportData) + data.ReadByteSeq(tguid[element - MSETransportGuidByte0]); + continue; + } + + switch (element) + { + case MSEHasMovementFlags: + hasMovementFlags = !data.ReadBit(); + break; + case MSEHasMovementFlags2: + hasMovementFlags2 = !data.ReadBit(); + break; + case MSEHasTimestamp: + hasTimestamp = !data.ReadBit(); + break; + case MSEHasOrientation: + hasOrientation = !data.ReadBit(); + break; + case MSEHasTransportData: + hasTransportData = data.ReadBit(); + break; + case MSEHasTransportTime2: + if (hasTransportData) + hasTransportTime2 = data.ReadBit(); + break; + case MSEHasTransportTime3: + if (hasTransportData) + hasTransportTime3 = data.ReadBit(); + break; + case MSEHasPitch: + hasPitch = !data.ReadBit(); + break; + case MSEHasFallData: + hasFallData = data.ReadBit(); + break; + case MSEHasFallDirection: + if (hasFallData) + hasFallDirection = data.ReadBit(); + break; + case MSEHasSplineElevation: + hasSplineElevation = !data.ReadBit(); + break; + case MSEHasSpline: + hasSpline = data.ReadBit(); + break; + case MSEMovementFlags: + if (hasMovementFlags) + mi->flags = data.ReadBits(30); + break; + case MSEMovementFlags2: + if (hasMovementFlags2) + mi->flags2 = data.ReadBits(12); + break; + case MSETimestamp: + if (hasTimestamp) + data >> mi->time; + break; + case MSEPositionX: + data >> mi->pos.m_positionX; + break; + case MSEPositionY: + data >> mi->pos.m_positionY; + break; + case MSEPositionZ: + data >> mi->pos.m_positionZ; + break; + case MSEOrientation: + if (hasOrientation) + data >> mi->pos.m_orientation; + break; + case MSETransportPositionX: + if (hasTransportData) + data >> mi->t_pos.m_positionX; + break; + case MSETransportPositionY: + if (hasTransportData) + data >> mi->t_pos.m_positionY; + break; + case MSETransportPositionZ: + if (hasTransportData) + data >> mi->t_pos.m_positionZ; + break; + case MSETransportOrientation: + if (hasTransportData) + data >> mi->t_pos.m_orientation; + break; + case MSETransportSeat: + if (hasTransportData) + data >> mi->t_seat; + break; + case MSETransportTime: + if (hasTransportData) + data >> mi->t_time; + break; + case MSETransportTime2: + if (hasTransportData && hasTransportTime2) + data >> mi->t_time2; + break; + case MSETransportTime3: + if (hasTransportData && hasTransportTime3) + data >> mi->t_time3; + break; + case MSEPitch: + if (hasPitch) + data >> mi->pitch; + break; + case MSEFallTime: + if (hasFallData) + data >> mi->fallTime; + break; + case MSEFallVerticalSpeed: + if (hasFallData) + data >> mi->j_zspeed; + break; + case MSEFallCosAngle: + if (hasFallData && hasFallDirection) + data >> mi->j_cosAngle; + break; + case MSEFallSinAngle: + if (hasFallData && hasFallDirection) + data >> mi->j_sinAngle; + break; + case MSEFallHorizontalSpeed: + if (hasFallData && hasFallDirection) + data >> mi->j_xyspeed; + break; + case MSESplineElevation: + if (hasSplineElevation) + data >> mi->splineElevation; + break; + case MSEZeroBit: + case MSEOneBit: + data.ReadBit(); + break; + default: + ASSERT(false && "Incorrect sequence element detected at ReadMovementInfo"); + break; + } + } + + mi->guid = guid; + mi->t_guid = tguid; + + if (hasTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX) + if (GetPlayer()->GetTransport()) + GetPlayer()->GetTransport()->UpdatePosition(mi); + + //! Anti-cheat checks. Please keep them in seperate if() blocks to maintain a clear overview. + //! Might be subject to latency, so just remove improper flags. + #ifdef TRINITY_DEBUG + #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \ + { \ + if (check) \ + { \ + sLog->outDebug(LOG_FILTER_UNITS, "WorldSession::ReadMovementInfo: Violation of MovementFlags found (%s). " \ + "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \ + STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUIDLow(), maskToRemove); \ + mi->RemoveMovementFlag((maskToRemove)); \ + } \ + } + #else + #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \ + if (check) \ + mi->RemoveMovementFlag((maskToRemove)); + #endif + + + /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid + in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. + It will freeze clients that receive this player's movement info. + */ + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), + MOVEMENTFLAG_ROOT); + + //! Cannot hover without SPELL_AURA_HOVER + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER), + MOVEMENTFLAG_HOVER); + + //! Cannot ascend and descend at the same time + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING), + MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING); + + //! Cannot move left and right at the same time + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT), + MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT); + + //! Cannot strafe left and right at the same time + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT), + MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT); + + //! Cannot pitch up and down at the same time + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN), + MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN); + + //! Cannot move forwards and backwards at the same time + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD), + MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD); + + //! Cannot walk on water without SPELL_AURA_WATER_WALK + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK), + MOVEMENTFLAG_WATERWALKING); + + //! Cannot feather fall without SPELL_AURA_FEATHER_FALL + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL), + MOVEMENTFLAG_FALLING_SLOW); + + /*! Cannot fly if no fly auras present. Exception is being a GM. + Note that we check for account level instead of Player::IsGameMaster() because in some + situations it may be feasable to use .gm fly on as a GM without having .gm on, + e.g. aerial combat. + */ + + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER && + !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) && + !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED), + MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY); + + #undef REMOVE_VIOLATING_FLAGS +} + +void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi) +{ + bool hasMovementFlags = mi->GetMovementFlags() != 0; + bool hasMovementFlags2 = mi->GetExtraMovementFlags() != 0; + bool hasTimestamp = mi->time != 0; + bool hasOrientation = !G3D::fuzzyEq(mi->pos.GetOrientation(), 0.0f); + bool hasTransportData = mi->t_guid != 0; + bool hasTransportTime2 = mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT); + bool hasTransportTime3 = false; + bool hasPitch = mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING); + bool hasFallData = mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_TURNING); + bool hasFallDirection = mi->HasMovementFlag(MOVEMENTFLAG_FALLING); + bool hasSplineElevation = mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); + bool hasSpline = false; + + MovementStatusElements* sequence = GetMovementStatusElementsSequence(data.GetOpcode()); + if (!sequence) + { + sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::WriteMovementInfo: No movement sequence found for opcode 0x%04X", uint32(data.GetOpcode())); + return; + } + + ObjectGuid guid = mi->guid; + ObjectGuid tguid = mi->t_guid; + + for(uint32 i = 0; i < MSE_COUNT; ++i) + { + MovementStatusElements element = sequence[i]; + if (element == MSEEnd) + break; + + if (element >= MSEHasGuidByte0 && element <= MSEHasGuidByte7) + { + data.WriteBit(guid[element - MSEHasGuidByte0]); + continue; + } + + if (element >= MSEHasTransportGuidByte0 && + element <= MSEHasTransportGuidByte7) + { + if (hasTransportData) + data.WriteBit(tguid[element - MSEHasTransportGuidByte0]); + continue; + } + + if (element >= MSEGuidByte0 && element <= MSEGuidByte7) + { + data.WriteByteSeq(guid[element - MSEGuidByte0]); + continue; + } + + if (element >= MSETransportGuidByte0 && + element <= MSETransportGuidByte7) + { + if (hasTransportData) + data.WriteByteSeq(tguid[element - MSETransportGuidByte0]); + continue; + } + + switch (element) + { + case MSEHasMovementFlags: + data.WriteBit(!hasMovementFlags); + break; + case MSEHasMovementFlags2: + data.WriteBit(!hasMovementFlags2); + break; + case MSEHasTimestamp: + data.WriteBit(!hasTimestamp); + break; + case MSEHasOrientation: + data.WriteBit(!hasOrientation); + break; + case MSEHasTransportData: + data.WriteBit(hasTransportData); + break; + case MSEHasTransportTime2: + if (hasTransportData) + data.WriteBit(hasTransportTime2); + break; + case MSEHasTransportTime3: + if (hasTransportData) + data.WriteBit(hasTransportTime3); + break; + case MSEHasPitch: + data.WriteBit(!hasPitch); + break; + case MSEHasFallData: + data.WriteBit(hasFallData); + break; + case MSEHasFallDirection: + if (hasFallData) + data.WriteBit(hasFallDirection); + break; + case MSEHasSplineElevation: + data.WriteBit(!hasSplineElevation); + break; + case MSEHasSpline: + data.WriteBit(hasSpline); + break; + case MSEMovementFlags: + if (hasMovementFlags) + data.WriteBits(mi->flags, 30); + break; + case MSEMovementFlags2: + if (hasMovementFlags2) + data.WriteBits(mi->flags2, 12); + break; + case MSETimestamp: + if (hasTimestamp) + data << mi->time; + break; + case MSEPositionX: + data << mi->pos.m_positionX; + break; + case MSEPositionY: + data << mi->pos.m_positionY; + break; + case MSEPositionZ: + data << mi->pos.m_positionZ; + break; + case MSEOrientation: + if (hasOrientation) + data << mi->pos.m_orientation; + break; + case MSETransportPositionX: + if (hasTransportData) + data << mi->t_pos.m_positionX; + break; + case MSETransportPositionY: + if (hasTransportData) + data << mi->t_pos.m_positionY; + break; + case MSETransportPositionZ: + if (hasTransportData) + data << mi->t_pos.m_positionZ; + break; + case MSETransportOrientation: + if (hasTransportData) + data << mi->t_pos.m_orientation; + break; + case MSETransportSeat: + if (hasTransportData) + data << mi->t_seat; + break; + case MSETransportTime: + if (hasTransportData) + data << mi->t_time; + break; + case MSETransportTime2: + if (hasTransportData && hasTransportTime2) + data << mi->t_time2; + break; + case MSETransportTime3: + if (hasTransportData && hasTransportTime3) + data << mi->t_time3; + break; + case MSEPitch: + if (hasPitch) + data << mi->pitch; + break; + case MSEFallTime: + if (hasFallData) + data << mi->fallTime; + break; + case MSEFallVerticalSpeed: + if (hasFallData) + data << mi->j_zspeed; + break; + case MSEFallCosAngle: + if (hasFallData && hasFallDirection) + data << mi->j_cosAngle; + break; + case MSEFallSinAngle: + if (hasFallData && hasFallDirection) + data << mi->j_sinAngle; + break; + case MSEFallHorizontalSpeed: + if (hasFallData && hasFallDirection) + data << mi->j_xyspeed; + break; + case MSESplineElevation: + if (hasSplineElevation) + data << mi->splineElevation; + break; + case MSEZeroBit: + data.WriteBit(0); + break; + case MSEOneBit: + data.WriteBit(1); + break; + default: + ASSERT(false && "Incorrect sequence element detected at ReadMovementInfo"); + break; + } + } +} diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index f0c3093aa25..8c959f454ff 100755 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -47,10 +47,10 @@ enum StableResultCode STABLE_ERR_EXOTIC = 0x0C, // "you are unable to control exotic creatures" }; -void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket & recv_data) +void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TABARDDESIGNER); if (!unit) @@ -73,13 +73,13 @@ void WorldSession::SendTabardVendorActivate(uint64 guid) SendPacket(&data); } -void WorldSession::HandleBankerActivateOpcode(WorldPacket & recv_data) +void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData) { uint64 guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_BANKER_ACTIVATE"); - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER); if (!unit) @@ -102,11 +102,11 @@ void WorldSession::SendShowBank(uint64 guid) SendPacket(&data); } -void WorldSession::HandleTrainerListOpcode(WorldPacket & recv_data) +void WorldSession::HandleTrainerListOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; SendTrainerList(guid); } @@ -154,6 +154,7 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle) WorldPacket data(SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1); data << guid; data << uint32(trainer_spells->trainerType); + data << uint32(0); size_t count_pos = data.wpos(); data << uint32(trainer_spells->spellList.size()); @@ -191,9 +192,6 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle) data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state); data << uint32(floor(tSpell->spellCost * fDiscountMod)); - data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0); - // primary prof. learn confirmation dialog - data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state data << uint8(tSpell->reqLevel); data << uint32(tSpell->reqSkill); data << uint32(tSpell->reqSkillValue); @@ -208,7 +206,7 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle) data << uint32(prevSpellId); ++maxReq; } - if (maxReq == 3) + if (maxReq == 2) break; SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->learnedSpell[i]); for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2) @@ -216,15 +214,19 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle) data << uint32(itr2->second); ++maxReq; } - if (maxReq == 3) + if (maxReq == 2) break; } - while (maxReq < 3) + while (maxReq < 2) { data << uint32(0); ++maxReq; } + data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0); + // primary prof. learn confirmation dialog + data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state + ++count; } @@ -234,12 +236,13 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle) SendPacket(&data); } -void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recv_data) +void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recvData) { uint64 guid; uint32 spellId = 0; + int32 unkInt; - recv_data >> guid >> spellId; + recvData >> guid >> unkInt >> spellId; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u", uint32(GUID_LOPART(guid)), spellId); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); @@ -274,10 +277,10 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recv_data) uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit))); // check money requirement - if (!_player->HasEnoughMoney(nSpellCost)) + if (!_player->HasEnoughMoney(uint64(nSpellCost))) return; - _player->ModifyMoney(-int32(nSpellCost)); + _player->ModifyMoney(-int64(nSpellCost)); unit->SendPlaySpellVisual(179); // 53 SpellCastDirected unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute @@ -291,15 +294,16 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket & recv_data) WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(guid); data << uint32(spellId); // should be same as in packet from client + data << uint32(0); // "Trainer service", 1 = "Not enough money for trainer service <TS>". 0 = "Trainer service <TS> unavailable" SendPacket(&data); } -void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) +void WorldSession::HandleGossipHelloOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GOSSIP_HELLO"); uint64 guid; - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); if (!unit) @@ -343,7 +347,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) unit->AI()->sGossipHello(_player); } -/*void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data) +/*void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_PACKETIO, "WORLD: CMSG_GOSSIP_SELECT_OPTION"); @@ -352,12 +356,12 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) uint64 guid; std::string code = ""; - recv_data >> guid >> unk >> option; + recvData >> guid >> unk >> option; if (_player->PlayerTalkClass->GossipOptionCoded(option)) { sLog->outDebug(LOG_FILTER_PACKETIO, "reading string"); - recv_data >> code; + recvData >> code; sLog->outDebug(LOG_FILTER_PACKETIO, "string read: %s", code.c_str()); } @@ -384,13 +388,13 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) } }*/ -void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket & recv_data) +void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE"); uint64 guid; - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_SPIRITHEALER); if (!unit) @@ -439,10 +443,10 @@ void WorldSession::SendSpiritResurrect() _player->UpdateObjectVisibility(); } -void WorldSession::HandleBinderActivateOpcode(WorldPacket & recv_data) +void WorldSession::HandleBinderActivateOpcode(WorldPacket& recvData) { uint64 npcGUID; - recv_data >> npcGUID; + recvData >> npcGUID; if (!GetPlayer()->IsInWorld() || !GetPlayer()->isAlive()) return; @@ -491,17 +495,18 @@ void WorldSession::SendBindPoint(Creature* npc) WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, (8+4)); data << uint64(npc->GetGUID()); data << uint32(bindspell); + data << uint32(0); // "Trainer service", 1 = "Not enough money for trainer service <TS>". 0 = "Trainer service <TS> unavailable" SendPacket(&data); _player->PlayerTalkClass->SendCloseGossip(); } -void WorldSession::HandleListStabledPetsOpcode(WorldPacket & recv_data) +void WorldSession::HandleListStabledPetsOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv MSG_LIST_STABLED_PETS"); uint64 npcGUID; - recv_data >> npcGUID; + recvData >> npcGUID; if (!CheckStableMaster(npcGUID)) return; @@ -552,6 +557,7 @@ void WorldSession::SendStablePetCallback(PreparedQueryResult result, uint64 guid // not let move dead pet in slot if (pet && pet->isAlive() && pet->getPetType() == HUNTER_PET) { + data << uint32(0); // 4.x unknown, some kind of order? data << uint32(pet->GetCharmInfo()->GetPetNumber()); data << uint32(pet->GetEntry()); data << uint32(pet->getLevel()); @@ -589,12 +595,12 @@ void WorldSession::SendStableResult(uint8 res) SendPacket(&data); } -void WorldSession::HandleStablePet(WorldPacket & recv_data) +void WorldSession::HandleStablePet(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_STABLE_PET"); uint64 npcGUID; - recv_data >> npcGUID; + recvData >> npcGUID; if (!GetPlayer()->isAlive()) { @@ -664,13 +670,13 @@ void WorldSession::HandleStablePetCallback(PreparedQueryResult result) SendStableResult(STABLE_ERR_STABLE); } -void WorldSession::HandleUnstablePet(WorldPacket & recv_data) +void WorldSession::HandleUnstablePet(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_UNSTABLE_PET."); uint64 npcGUID; uint32 petnumber; - recv_data >> npcGUID >> petnumber; + recvData >> npcGUID >> petnumber; if (!CheckStableMaster(npcGUID)) { @@ -745,12 +751,12 @@ void WorldSession::HandleUnstablePetCallback(PreparedQueryResult result, uint32 SendStableResult(STABLE_SUCCESS_UNSTABLE); } -void WorldSession::HandleBuyStableSlot(WorldPacket & recv_data) +void WorldSession::HandleBuyStableSlot(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_BUY_STABLE_SLOT."); uint64 npcGUID; - recv_data >> npcGUID; + recvData >> npcGUID; if (!CheckStableMaster(npcGUID)) { @@ -764,7 +770,7 @@ void WorldSession::HandleBuyStableSlot(WorldPacket & recv_data) if (GetPlayer()->m_stableSlots < MAX_PET_STABLES) { - StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1); + /*StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1); if (_player->HasEnoughMoney(SlotPrice->Price)) { ++GetPlayer()->m_stableSlots; @@ -772,24 +778,24 @@ void WorldSession::HandleBuyStableSlot(WorldPacket & recv_data) SendStableResult(STABLE_SUCCESS_BUY_SLOT); } else - SendStableResult(STABLE_ERR_MONEY); + SendStableResult(STABLE_ERR_MONEY);*/ } else SendStableResult(STABLE_ERR_STABLE); } -void WorldSession::HandleStableRevivePet(WorldPacket &/* recv_data */) +void WorldSession::HandleStableRevivePet(WorldPacket &/* recvData */) { sLog->outDebug(LOG_FILTER_NETWORKIO, "HandleStableRevivePet: Not implemented"); } -void WorldSession::HandleStableSwapPet(WorldPacket & recv_data) +void WorldSession::HandleStableSwapPet(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_STABLE_SWAP_PET."); uint64 npcGUID; uint32 petId; - recv_data >> npcGUID >> petId; + recvData >> npcGUID >> petId; if (!CheckStableMaster(npcGUID)) { @@ -875,14 +881,14 @@ void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint3 SendStableResult(STABLE_SUCCESS_UNSTABLE); } -void WorldSession::HandleRepairItemOpcode(WorldPacket & recv_data) +void WorldSession::HandleRepairItemOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_REPAIR_ITEM"); uint64 npcGUID, itemGUID; uint8 guildBank; // new in 2.3.2, bool that means from guild bank money - recv_data >> npcGUID >> itemGUID >> guildBank; + recvData >> npcGUID >> itemGUID >> guildBank; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_REPAIR); if (!unit) diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 3501b3bc068..c0345e17fcd 100755..100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -32,10 +32,10 @@ #include "Group.h" #include "SpellInfo.h" -void WorldSession::HandleDismissCritter(WorldPacket &recv_data) +void WorldSession::HandleDismissCritter(WorldPacket &recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_DISMISS_CRITTER for GUID " UI64FMTD, guid); @@ -55,14 +55,19 @@ void WorldSession::HandleDismissCritter(WorldPacket &recv_data) } } -void WorldSession::HandlePetAction(WorldPacket & recv_data) +void WorldSession::HandlePetAction(WorldPacket & recvData) { uint64 guid1; uint32 data; uint64 guid2; - recv_data >> guid1; //pet guid - recv_data >> data; - recv_data >> guid2; //tag guid + float x, y, z; + recvData >> guid1; //pet guid + recvData >> data; + recvData >> guid2; //tag guid + // Position + recvData >> x; + recvData >> y; + recvData >> z; uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 @@ -110,10 +115,10 @@ void WorldSession::HandlePetAction(WorldPacket & recv_data) } } -void WorldSession::HandlePetStopAttack(WorldPacket &recv_data) +void WorldSession::HandlePetStopAttack(WorldPacket &recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PET_STOP_ATTACK for GUID " UI64FMTD "", guid); @@ -401,15 +406,15 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid } } -void WorldSession::HandlePetNameQuery(WorldPacket & recv_data) +void WorldSession::HandlePetNameQuery(WorldPacket & recvData) { sLog->outInfo(LOG_FILTER_NETWORKIO, "HandlePetNameQuery. CMSG_PET_NAME_QUERY"); uint32 petnumber; uint64 petguid; - recv_data >> petnumber; - recv_data >> petguid; + recvData >> petnumber; + recvData >> petguid; SendPetNameQuery(petguid, petnumber); } @@ -470,14 +475,14 @@ bool WorldSession::CheckStableMaster(uint64 guid) return true; } -void WorldSession::HandlePetSetAction(WorldPacket & recv_data) +void WorldSession::HandlePetSetAction(WorldPacket & recvData) { sLog->outInfo(LOG_FILTER_NETWORKIO, "HandlePetSetAction. CMSG_PET_SET_ACTION"); uint64 petguid; uint8 count; - recv_data >> petguid; + recvData >> petguid; Unit* pet = ObjectAccessor::GetUnit(*_player, petguid); @@ -494,7 +499,7 @@ void WorldSession::HandlePetSetAction(WorldPacket & recv_data) return; } - count = (recv_data.size() == 24) ? 2 : 1; + count = (recvData.size() == 24) ? 2 : 1; uint32 position[2]; uint32 data[2]; @@ -502,8 +507,8 @@ void WorldSession::HandlePetSetAction(WorldPacket & recv_data) for (uint8 i = 0; i < count; ++i) { - recv_data >> position[i]; - recv_data >> data[i]; + recvData >> position[i]; + recvData >> data[i]; uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); @@ -586,7 +591,7 @@ void WorldSession::HandlePetSetAction(WorldPacket & recv_data) } } -void WorldSession::HandlePetRename(WorldPacket & recv_data) +void WorldSession::HandlePetRename(WorldPacket & recvData) { sLog->outInfo(LOG_FILTER_NETWORKIO, "HandlePetRename. CMSG_PET_RENAME"); @@ -596,9 +601,9 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data) std::string name; DeclinedName declinedname; - recv_data >> petguid; - recv_data >> name; - recv_data >> isdeclined; + recvData >> petguid; + recvData >> name; + recvData >> isdeclined; Pet* pet = ObjectAccessor::FindPet(petguid); // check it! @@ -632,7 +637,7 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data) { for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { - recv_data >> declinedname.name[i]; + recvData >> declinedname.name[i]; } std::wstring wname; @@ -671,10 +676,10 @@ void WorldSession::HandlePetRename(WorldPacket & recv_data) pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped } -void WorldSession::HandlePetAbandon(WorldPacket & recv_data) +void WorldSession::HandlePetAbandon(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; //pet guid + recvData >> guid; //pet guid sLog->outInfo(LOG_FILTER_NETWORKIO, "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid)); if (!_player->IsInWorld()) @@ -685,15 +690,7 @@ void WorldSession::HandlePetAbandon(WorldPacket & recv_data) if (pet) { if (pet->isPet()) - { - if (pet->GetGUID() == _player->GetPetGUID()) - { - uint32 feelty = pet->GetPower(POWER_HAPPINESS); - pet->SetPower(POWER_HAPPINESS, feelty > 50000 ? (feelty-50000) : 0); - } - _player->RemovePet((Pet*)pet, PET_SAVE_AS_DELETED); - } else if (pet->GetGUID() == _player->GetCharmGUID()) _player->StopCastingCharm(); } @@ -855,33 +852,33 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec SendPacket(&data); } -void WorldSession::HandlePetLearnTalent(WorldPacket & recv_data) +void WorldSession::HandlePetLearnTalent(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_LEARN_TALENT"); uint64 guid; - uint32 talent_id, requested_rank; - recv_data >> guid >> talent_id >> requested_rank; + uint32 talentId, requestedRank; + recvData >> guid >> talentId >> requestedRank; - _player->LearnPetTalent(guid, talent_id, requested_rank); + _player->LearnPetTalent(guid, talentId, requestedRank); _player->SendTalentsInfoData(true); } -void WorldSession::HandleLearnPreviewTalentsPet(WorldPacket & recv_data) +void WorldSession::HandleLearnPreviewTalentsPet(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LEARN_PREVIEW_TALENTS_PET"); uint64 guid; - recv_data >> guid; + recvData >> guid; uint32 talentsCount; - recv_data >> talentsCount; + recvData >> talentsCount; uint32 talentId, talentRank; for (uint32 i = 0; i < talentsCount; ++i) { - recv_data >> talentId >> talentRank; + recvData >> talentId >> talentRank; _player->LearnPetTalent(guid, talentId, talentRank); } diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 90af03113bf..c8b79a9da10 100755 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -56,7 +56,7 @@ enum CharterCosts ARENA_TEAM_CHARTER_5v5_COST = 2000000 }; -void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) +void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_BUY"); @@ -64,28 +64,28 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client std::string name; - recv_data >> guidNPC; // NPC GUID - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint64>(); // 0 - recv_data >> name; // name - recv_data.read_skip<std::string>(); // some string - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint16>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 - recv_data.read_skip<uint32>(); // 0 + recvData >> guidNPC; // NPC GUID + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint64>(); // 0 + recvData >> name; // name + recvData.read_skip<std::string>(); // some string + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint16>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 + recvData.read_skip<uint32>(); // 0 for (int i = 0; i < 10; ++i) - recv_data.read_skip<std::string>(); + recvData.read_skip<std::string>(); - recv_data >> clientIndex; // index - recv_data.read_skip<uint32>(); // 0 + recvData >> clientIndex; // index + recvData.read_skip<uint32>(); // 0 sLog->outDebug(LOG_FILTER_NETWORKIO, "Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str()); @@ -157,12 +157,12 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) { if (sGuildMgr->GetGuildByName(name)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, name); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, name); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NAME_INVALID, name); return; } } @@ -187,7 +187,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) return; } - if (!_player->HasEnoughMoney(cost)) + if (!_player->HasEnoughMoney(uint64(cost))) { //player hasn't got enough money _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0); return; @@ -250,13 +250,13 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) CharacterDatabase.CommitTransaction(trans); } -void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recv_data) +void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_SHOW_SIGNATURES"); uint8 signs = 0; uint64 petitionguid; - recv_data >> petitionguid; // petition guid + recvData >> petitionguid; // petition guid // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?) uint32 petitionGuidLow = GUID_LOPART(petitionguid); @@ -310,14 +310,14 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recv_data) SendPacket(&data); } -void WorldSession::HandlePetitionQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandlePetitionQueryOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_QUERY"); // ok uint32 guildguid; uint64 petitionguid; - recv_data >> guildguid; // in Trinity always same as GUID_LOPART(petitionguid) - recv_data >> petitionguid; // petition guid + recvData >> guildguid; // in Trinity always same as GUID_LOPART(petitionguid) + recvData >> petitionguid; // petition guid sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionguid), guildguid); SendPetitionQueryOpcode(petitionguid); @@ -355,8 +355,8 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) data << uint8(0); // some string if (type == GUILD_CHARTER_TYPE) { - data << uint32(9); - data << uint32(9); + data << uint32(4); + data << uint32(4); data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition } else @@ -387,16 +387,16 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) SendPacket(&data); } -void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) +void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recvData) { - sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode MSG_PETITION_RENAME"); // ok + sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode MSG_PETITION_RENAME"); uint64 petitionGuid; uint32 type; std::string newName; - recv_data >> petitionGuid; // guid - recv_data >> newName; // new name + recvData >> petitionGuid; // guid + recvData >> newName; // new name Item* item = _player->GetItemByGuid(petitionGuid); if (!item) @@ -423,12 +423,12 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) { if (sGuildMgr->GetGuildByName(newName)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, newName); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NAME_EXISTS_S, newName); return; } if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, newName); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NAME_INVALID, newName); return; } } @@ -460,15 +460,15 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) SendPacket(&data); } -void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) +void WorldSession::HandlePetitionSignOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_SIGN"); // ok Field* fields; uint64 petitionGuid; uint8 unk; - recv_data >> petitionGuid; // petition guid - recv_data >> unk; + recvData >> petitionGuid; // petition guid + recvData >> unk; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURES); @@ -498,7 +498,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) if (type != GUILD_CHARTER_TYPE) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NOT_ALLIED); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NOT_ALLIED); return; } @@ -530,12 +530,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) { if (_player->GetGuildId()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_IN_GUILD_S, _player->GetName()); + Guild::SendCommandResult(this, GUILD_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (_player->GetGuildIdInvited()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); + Guild::SendCommandResult(this, GUILD_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } } @@ -557,14 +557,10 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4)); data << uint64(petitionGuid); data << uint64(_player->GetGUID()); - data << (uint32)PETITION_SIGN_ALREADY_SIGNED; + data << uint32(PETITION_SIGN_ALREADY_SIGNED); // close at signer side SendPacket(&data); - - // update for owner if online - if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid)) - owner->GetSession()->SendPacket(&data); return; } @@ -597,13 +593,13 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) owner->GetSession()->SendPacket(&data); } -void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recv_data) +void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode MSG_PETITION_DECLINE"); // ok uint64 petitionguid; uint64 ownerguid; - recv_data >> petitionguid; // petition guid + recvData >> petitionguid; // petition guid sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition %u declined by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_OWNER_BY_GUID); @@ -627,7 +623,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) +void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_OFFER_PETITION"); // ok @@ -635,9 +631,9 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) uint64 petitionguid, plguid; uint32 type, junk; Player* player; - recv_data >> junk; // this is not petition type! - recv_data >> petitionguid; // petition guid - recv_data >> plguid; // player guid + recvData >> junk; // this is not petition type! + recvData >> petitionguid; // petition guid + recvData >> plguid; // player guid player = ObjectAccessor::FindPlayer(plguid); if (!player) @@ -662,7 +658,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) if (type != GUILD_CHARTER_TYPE) SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); else - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NOT_ALLIED); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NOT_ALLIED); return; } @@ -696,13 +692,13 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) { if (player->GetGuildId()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_IN_GUILD_S, _player->GetName()); + Guild::SendCommandResult(this, GUILD_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (player->GetGuildIdInvited()) { - Guild::SendCommandResult(this, GUILD_INVITE_S, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); + Guild::SendCommandResult(this, GUILD_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } } @@ -736,7 +732,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) player->GetSession()->SendPacket(&data); } -void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) +void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_TURN_IN_PETITION"); @@ -744,7 +740,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) WorldPacket data; uint64 petitionGuid; - recv_data >> petitionGuid; + recvData >> petitionGuid; // Check if player really has the required petition charter Item* item = _player->GetItemByGuid(petitionGuid); @@ -794,7 +790,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) // Check if guild name is already taken if (sGuildMgr->GetGuildByName(name)) { - Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, name); + Guild::SendCommandResult(this, GUILD_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } } @@ -878,7 +874,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) { // Receive the rest of the packet in arena team creation case uint32 background, icon, iconcolor, border, bordercolor; - recv_data >> background >> icon >> iconcolor >> border >> bordercolor; + recvData >> background >> icon >> iconcolor >> border >> bordercolor; // Create arena team ArenaTeam* arenaTeam = new ArenaTeam(); @@ -924,12 +920,12 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) SendPacket(&data); } -void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recv_data) +void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Received CMSG_PETITION_SHOWLIST"); uint64 guid; - recv_data >> guid; + recvData >> guid; SendPetitionShowList(guid); } @@ -954,7 +950,7 @@ void WorldSession::SendPetitionShowList(uint64 guid) data << uint32(CHARTER_DISPLAY_ID); // charter display id data << uint32(GUILD_CHARTER_COST); // charter cost data << uint32(0); // unknown - data << uint32(9); // required signs? + data << uint32(4); // required signs? } else { diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index d3f51867831..63035a5095f 100755 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -64,10 +64,10 @@ void WorldSession::SendNameQueryOpcode(uint64 guid) SendPacket(&data); } -void WorldSession::HandleNameQueryOpcode(WorldPacket& recv_data) +void WorldSession::HandleNameQueryOpcode(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; // This is disable by default to prevent lots of console spam // sLog->outInfo(LOG_FILTER_NETWORKIO, "HandleNameQueryOpcode %u", guid); @@ -75,7 +75,7 @@ void WorldSession::HandleNameQueryOpcode(WorldPacket& recv_data) SendNameQueryOpcode(guid); } -void WorldSession::HandleQueryTimeOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleQueryTimeOpcode(WorldPacket & /*recvData*/) { SendQueryTimeResponse(); } @@ -89,12 +89,12 @@ void WorldSession::SendQueryTimeResponse() } /// Only _static_ data is sent in this packet !!! -void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recvData) { uint32 entry; - recv_data >> entry; + recvData >> entry; uint64 guid; - recv_data >> guid; + recvData >> guid; CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry); if (ci) @@ -118,10 +118,14 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); data << uint32(entry); // creature entry data << Name; - data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty + + for (int i = 0; i < 7; i++) + data << uint8(0); // name2, ..., name8 + data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 data << uint32(ci->type_flags); // flags + data << uint32(ci->type_flags2); // unknown meaning data << uint32(ci->type); // CreatureType.dbc data << uint32(ci->family); // CreatureFamily.dbc data << uint32(ci->rank); // Creature Rank (elite, boss, etc) @@ -137,6 +141,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) data << uint32(ci->questItems[i]); // itemId[6], quest drop data << uint32(ci->movementId); // CreatureMovementInfo.dbc + data << uint32(ci->expansionUnknown); // unknown meaning SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } @@ -152,12 +157,12 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data) } /// Only _static_ data is sent in this packet !!! -void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recvData) { uint32 entry; - recv_data >> entry; + recvData >> entry; uint64 guid; - recv_data >> guid; + recvData >> guid; const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry); if (info) @@ -189,10 +194,11 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data) data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword) data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting") data << info->unk1; // 2.0.3, string - data.append(info->raw.data, 24); + data.append(info->raw.data, MAX_GAMEOBJECT_DATA); data << float(info->size); // go size for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) - data << uint32(info->questItems[i]); // itemId[6], quest drop + data << uint32(info->questItems[i]); // itemId[6], quest drop + data << int32(info->unkInt32); // 4.x, unknown SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE"); } @@ -207,7 +213,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY"); @@ -258,15 +264,15 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) SendPacket(&data); } -void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recvData) { uint32 textID; uint64 guid; - recv_data >> textID; + recvData >> textID; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID); - recv_data >> guid; + recvData >> guid; GetPlayer()->SetSelection(guid); GossipText const* pGossip = sObjectMgr->GetGossipText(textID); @@ -342,13 +348,13 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data) } /// Only _static_ data is sent in this packet !!! -void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY"); uint32 pageID; - recv_data >> pageID; - recv_data.read_skip<uint64>(); // guid + recvData >> pageID; + recvData.read_skip<uint64>(); // guid while (pageID) { @@ -382,12 +388,12 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleCorpseMapPositionQuery(WorldPacket & recv_data) +void WorldSession::HandleCorpseMapPositionQuery(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY"); uint32 unk; - recv_data >> unk; + recvData >> unk; WorldPacket data(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4+4+4+4); data << float(0); @@ -397,14 +403,14 @@ void WorldSession::HandleCorpseMapPositionQuery(WorldPacket & recv_data) SendPacket(&data); } -void WorldSession::HandleQuestPOIQuery(WorldPacket& recv_data) +void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) { uint32 count; - recv_data >> count; // quest count, max=25 + recvData >> count; // quest count, max=25 if (count >= MAX_QUEST_LOG_SIZE) { - recv_data.rfinish(); + recvData.rfinish(); return; } @@ -414,7 +420,7 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recv_data) for (uint32 i = 0; i < count; ++i) { uint32 questId; - recv_data >> questId; // quest id + recvData >> questId; // quest id bool questOk = false; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 7492edb35fe..8b7319b760b 100755..100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -33,12 +33,12 @@ #include "ScriptMgr.h" #include "GameObjectAI.h" -void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; - uint8 questStatus = DIALOG_STATUS_NONE; - uint8 defstatus = DIALOG_STATUS_NONE; + recvData >> guid; + uint32 questStatus = DIALOG_STATUS_NONE; + uint32 defstatus = DIALOG_STATUS_NONE; Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); if (!questgiver) @@ -79,10 +79,10 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recv_data) _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid); } -void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid)); @@ -109,12 +109,12 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data) creature->AI()->sGossipHello(_player); } -void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) { uint64 guid; uint32 questId; uint32 unk1; - recv_data >> guid >> questId >> unk1; + recvData >> guid >> questId >> unk1; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), questId, unk1); @@ -230,12 +230,12 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data) _player->PlayerTalkClass->SendCloseGossip(); } -void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket& recvData) { uint64 guid; uint32 questId; uint8 unk1; - recv_data >> guid >> questId >> unk1; + recvData >> guid >> questId >> unk1; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), questId, unk1); // Verify that the guid is valid and is a questgiver or involved in the requested quest @@ -268,24 +268,24 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleQuestQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestQueryOpcode(WorldPacket & recvData) { if (!_player) return; uint32 questId; - recv_data >> questId; + recvData >> questId; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUEST_QUERY quest = %u", questId); if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) _player->PlayerTalkClass->SendQuestQueryResponse(quest); } -void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) { uint32 questId, reward; uint64 guid; - recv_data >> guid >> questId >> reward; + recvData >> guid >> questId >> reward; if (reward >= QUEST_REWARD_CHOICES_COUNT) { @@ -365,11 +365,11 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data) } } -void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket & recv_data) +void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket & recvData) { uint32 questId; uint64 guid; - recv_data >> guid >> questId; + recvData >> guid >> questId; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId); @@ -391,17 +391,17 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket & recv_data) _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); } -void WorldSession::HandleQuestgiverCancel(WorldPacket& /*recv_data*/) +void WorldSession::HandleQuestgiverCancel(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_CANCEL"); _player->PlayerTalkClass->SendCloseGossip(); } -void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recv_data) +void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recvData) { uint8 slot1, slot2; - recv_data >> slot1 >> slot2; + recvData >> slot1 >> slot2; if (slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE) return; @@ -411,10 +411,10 @@ void WorldSession::HandleQuestLogSwapQuest(WorldPacket& recv_data) GetPlayer()->SwapQuestSlot(slot1, slot2); } -void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data) +void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) { uint8 slot; - recv_data >> slot; + recvData >> slot; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u", slot); @@ -440,16 +440,16 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data) _player->SetQuestSlot(slot, 0); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED, 1); } } -void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data) +void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData) { uint32 questId; - recv_data >> questId; + recvData >> questId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", questId); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT questId = %u", questId); if (const Quest* quest = sObjectMgr->GetQuestTemplate(questId)) { @@ -479,16 +479,16 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data) } } -void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data) +void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) { uint32 questId; - uint64 guid; - - recv_data >> guid >> questId; + uint64 playerGuid; + int8 unkByte; + recvData >> playerGuid >> questId >> unkByte; - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, questId = %u", uint32(GUID_LOPART(playerGuid)), questId); - Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, playerGuid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); if (!object || !object->hasInvolvedQuest(questId)) return; @@ -500,7 +500,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data) { if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) { - sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [guid: %u] tried to complete quest [entry: %u] without being in possession of the quest!", + sLog->outError(LOG_FILTER_NETWORKIO, "Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!", _player->GetName(), _player->GetGUIDLow(), questId); return; } @@ -513,16 +513,16 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data) if (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE) { if (quest->IsRepeatable()) - _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanCompleteRepeatableQuest(quest), false); + _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanCompleteRepeatableQuest(quest), false); else - _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false); + _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false); } else { if (quest->GetReqItemsCount()) // some items required - _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false); + _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false); else // no items required - _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true); + _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, playerGuid, true); } } } @@ -537,7 +537,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) uint32 questId; recvPacket >> questId; - sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY questId = %u", questId); if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { @@ -715,13 +715,13 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket uint32 count = 0; - WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4); + WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4 + 8 + 4); data << uint32(count); // placeholder for (Player::ClientGUIDs::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) { - uint8 questStatus = DIALOG_STATUS_NONE; - uint8 defstatus = DIALOG_STATUS_NONE; + uint32 questStatus = DIALOG_STATUS_NONE; + uint32 defstatus = DIALOG_STATUS_NONE; if (IS_CRE_OR_VEH_OR_PET_GUID(*itr)) { @@ -736,7 +736,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket questStatus = getDialogStatus(_player, questgiver, defstatus); data << uint64(questgiver->GetGUID()); - data << uint8(questStatus); + data << uint32(questStatus); ++count; } else if (IS_GAMEOBJECT_GUID(*itr)) @@ -751,7 +751,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket questStatus = getDialogStatus(_player, questgiver, defstatus); data << uint64(questgiver->GetGUID()); - data << uint8(questStatus); + data << uint32(questStatus); ++count; } } @@ -760,7 +760,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket SendPacket(&data); } -void WorldSession::HandleQueryQuestsCompleted(WorldPacket & /*recv_data*/) +void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/) { size_t rew_count = _player->GetRewardedQuestCount(); diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index 58d425ddf98..7822c38d390 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -21,12 +21,12 @@ #include "Opcodes.h" #include "Log.h" -void WorldSession::HandleGrantLevel(WorldPacket& recv_data) +void WorldSession::HandleGrantLevel(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GRANT_LEVEL"); uint64 guid; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); Player* target = ObjectAccessor::GetObjectInWorld(guid, _player); @@ -63,12 +63,12 @@ void WorldSession::HandleGrantLevel(WorldPacket& recv_data) target->GetSession()->SendPacket(&data2); } -void WorldSession::HandleAcceptGrantLevel(WorldPacket& recv_data) +void WorldSession::HandleAcceptGrantLevel(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_ACCEPT_LEVEL_GRANT"); uint64 guid; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); Player* other = ObjectAccessor::GetObjectInWorld(guid, _player); if (!(other && other->GetSession())) diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index f9731ba85db..bc02822c09d 100755 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -26,20 +26,36 @@ #include "ObjectAccessor.h" #include "UpdateMask.h" -void WorldSession::HandleLearnTalentOpcode(WorldPacket & recv_data) +void WorldSession::HandleLearnTalentOpcode(WorldPacket & recvData) { - uint32 talent_id, requested_rank; - recv_data >> talent_id >> requested_rank; + uint32 talentId, requestedRank; + recvData >> talentId >> requestedRank; - _player->LearnTalent(talent_id, requested_rank); - _player->SendTalentsInfoData(false); + if (_player->LearnTalent(talentId, requestedRank)) + _player->SendTalentsInfoData(false); } void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_LEARN_PREVIEW_TALENTS"); + int32 tabPage; uint32 talentsCount; + recvPacket >> tabPage; // talent tree + + // prevent cheating (selecting new tree with points already in another) + if (tabPage >= 0) // -1 if player already has specialization + { + if (TalentTabEntry const* talentTabEntry = sTalentTabStore.LookupEntry(_player->GetPrimaryTalentTree(_player->GetActiveSpec()))) + { + if (talentTabEntry->tabpage != tabPage) + { + recvPacket.rfinish(); + return; + } + } + } + recvPacket >> talentsCount; uint32 talentId, talentRank; @@ -48,17 +64,21 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket) { recvPacket >> talentId >> talentRank; - _player->LearnTalent(talentId, talentRank); + if (!_player->LearnTalent(talentId, talentRank)) + { + recvPacket.rfinish(); + break; + } } _player->SendTalentsInfoData(false); } -void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket & recv_data) +void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_TALENT_WIPE_CONFIRM"); uint64 guid; - recv_data >> guid; + recvData >> guid; Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER); if (!unit) @@ -71,7 +91,7 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket & recv_data) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - if (!(_player->resetTalents())) + if (!_player->ResetTalents()) { WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8+4); //you have not any talent data << uint64(0); @@ -84,9 +104,9 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket & recv_data) unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect" } -void WorldSession::HandleUnlearnSkillOpcode(WorldPacket & recv_data) +void WorldSession::HandleUnlearnSkillOpcode(WorldPacket& recvData) { - uint32 skill_id; - recv_data >> skill_id; - GetPlayer()->SetSkill(skill_id, 0, 0, 0); + uint32 skillId; + recvData >> skillId; + GetPlayer()->SetSkill(skillId, 0, 0, 0); } diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index d7bb10e8ba3..31cce5b7239 100755 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -21,6 +21,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "ObjectMgr.h" +#include "GuildMgr.h" #include "SpellMgr.h" #include "Log.h" #include "Opcodes.h" @@ -61,6 +62,27 @@ void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlag ReadMovementInfo(recvPacket, &movementInfo);*/ } } + else if (castFlags & 0x8) // Archaeology + { + uint32 count, entry, usedCount; + uint8 type; + recvPacket >> count; + for (uint32 i = 0; i < count; ++i) + { + recvPacket >> type; + switch (type) + { + case 2: // Keystones + recvPacket >> entry; // Item id + recvPacket >> usedCount; // Item count + break; + case 1: // Fragments + recvPacket >> entry; // Currency id + recvPacket >> usedCount; // Currency count + break; + } + } + } } void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) @@ -269,11 +291,11 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) pUser->SendLoot(item->GetGUID(), LOOT_CORPSE); } -void WorldSession::HandleGameObjectUseOpcode(WorldPacket & recv_data) +void WorldSession::HandleGameObjectUseOpcode(WorldPacket & recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid)); @@ -305,14 +327,18 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) go->AI()->GossipHello(_player); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry()); } void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { - uint32 spellId; + uint32 spellId, glyphIndex; uint8 castCount, castFlags; - recvPacket >> castCount >> spellId >> castFlags; + + recvPacket >> castCount; + recvPacket >> spellId; + recvPacket >> glyphIndex; + recvPacket >> castFlags; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u, data length = %u", castCount, spellId, castFlags, (uint32)recvPacket.size()); @@ -387,6 +413,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) Spell* spell = new Spell(mover, spellInfo, TRIGGERED_NONE, 0, false); spell->m_cast_count = castCount; // set count of casts + spell->m_glyphIndex = glyphIndex; spell->prepare(&targets); } @@ -484,9 +511,9 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode(WorldPacket& /*recvPacket*/ _player->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); } -void WorldSession::HandleCancelChanneling(WorldPacket & recv_data) +void WorldSession::HandleCancelChanneling(WorldPacket & recvData) { - recv_data.read_skip<uint32>(); // spellid, not used + recvData.read_skip<uint32>(); // spellid, not used // ignore for remote control state (for player case) Unit* mover = _player->m_mover; @@ -519,7 +546,7 @@ void WorldSession::HandleTotemDestroyed(WorldPacket& recvPacket) totem->ToTotem()->UnSummon(); } -void WorldSession::HandleSelfResOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleSelfResOpcode(WorldPacket & /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SELF_RES"); // empty opcode @@ -536,10 +563,10 @@ void WorldSession::HandleSelfResOpcode(WorldPacket & /*recv_data*/) } } -void WorldSession::HandleSpellClick(WorldPacket& recv_data) +void WorldSession::HandleSpellClick(WorldPacket& recvData) { uint64 guid; - recv_data >> guid; + recvData >> guid; // this will get something not in world. crash Creature* unit = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); @@ -554,11 +581,12 @@ void WorldSession::HandleSpellClick(WorldPacket& recv_data) unit->HandleSpellClick(_player); } -void WorldSession::HandleMirrorImageDataRequest(WorldPacket & recv_data) +void WorldSession::HandleMirrorImageDataRequest(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GET_MIRRORIMAGE_DATA"); uint64 guid; - recv_data >> guid; + recvData >> guid; + recvData.read_skip<uint32>(); // DisplayId ? // Get unit for which data is needed by client Unit* unit = ObjectAccessor::GetObjectInWorld(guid, (Unit*)NULL); @@ -583,12 +611,17 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket & recv_data) if (creator->GetTypeId() == TYPEID_PLAYER) { Player* player = creator->ToPlayer(); + Guild* guild = NULL; + + if (uint32 guildId = player->GetGuildId()) + guild = sGuildMgr->GetGuildById(guildId); + data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair - data << uint32(player->GetGuildId()); // unk + data << uint64(guild ? guild->GetGUID() : 0); static EquipmentSlots const itemSlots[] = { diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index b774fbcba70..16ffdfbc440 100755 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -28,13 +28,13 @@ #include "Path.h" #include "WaypointMovementGenerator.h" -void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket & recv_data) +void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_TAXINODE_STATUS_QUERY"); uint64 guid; - recv_data >> guid; + recvData >> guid; SendTaxiStatus(guid); } @@ -63,12 +63,12 @@ void WorldSession::SendTaxiStatus(uint64 guid) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_TAXINODE_STATUS"); } -void WorldSession::HandleTaxiQueryAvailableNodes(WorldPacket & recv_data) +void WorldSession::HandleTaxiQueryAvailableNodes(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES"); uint64 guid; - recv_data >> guid; + recvData >> guid; // cheating checks Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER); @@ -163,14 +163,14 @@ void WorldSession::SendDiscoverNewTaxiNode(uint32 nodeid) } } -void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket & recv_data) +void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ACTIVATETAXIEXPRESS"); uint64 guid; uint32 node_count; - recv_data >> guid >> node_count; + recvData >> guid >> node_count; Creature* npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER); if (!npc) @@ -183,7 +183,7 @@ void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket & recv_data) for (uint32 i = 0; i < node_count; ++i) { uint32 node; - recv_data >> node; + recvData >> node; nodes.push_back(node); } @@ -195,17 +195,17 @@ void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket & recv_data) GetPlayer()->ActivateTaxiPathTo(nodes, npc); } -void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) +void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_MOVE_SPLINE_DONE"); uint64 guid; // used only for proper packet read - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); MovementInfo movementInfo; // used only for proper packet read - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); - recv_data.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // unk // in taxi flight packet received in 2 case: // 1) end taxi path in far (multi-node) flight @@ -273,7 +273,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) GetPlayer()->CastSpell(GetPlayer(), 2479, true); } -void WorldSession::HandleActivateTaxiOpcode(WorldPacket & recv_data) +void WorldSession::HandleActivateTaxiOpcode(WorldPacket & recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ACTIVATETAXI"); @@ -281,7 +281,7 @@ void WorldSession::HandleActivateTaxiOpcode(WorldPacket & recv_data) std::vector<uint32> nodes; nodes.resize(2); - recv_data >> guid >> nodes[0] >> nodes[1]; + recvData >> guid >> nodes[0] >> nodes[1]; sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ACTIVATETAXI from %d to %d", nodes[0], nodes[1]); Creature* npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER); if (!npc) diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index d6675188f6e..e5618420ac5 100755 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -26,7 +26,7 @@ #include "WorldSession.h" #include "Util.h" -void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recv_data) +void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recvData) { // Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable) if (sTicketMgr->GetStatus() == GMTICKET_QUEUE_STATUS_DISABLED) @@ -42,7 +42,7 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recv_data) // Player must not have ticket if (!sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) { - GmTicket* ticket = new GmTicket(GetPlayer(), recv_data); + GmTicket* ticket = new GmTicket(GetPlayer(), recvData); sTicketMgr->AddTicket(ticket); sTicketMgr->UpdateLastChange(); @@ -56,10 +56,10 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket & recv_data) SendPacket(&data); } -void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket & recv_data) +void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket & recvData) { std::string message; - recv_data >> message; + recvData >> message; GMTicketResponse response = GMTICKET_RESPONSE_UPDATE_ERROR; if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) @@ -78,7 +78,7 @@ void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket & recv_data) SendPacket(&data); } -void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket & /*recvData*/) { if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) { @@ -93,7 +93,7 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket & /*recv_data*/) } } -void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket & /*recvData*/) { SendQueryTimeResponse(); @@ -108,7 +108,7 @@ void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket & /*recv_data*/) sTicketMgr->SendTicket(this, NULL); } -void WorldSession::HandleGMTicketSystemStatusOpcode(WorldPacket & /*recv_data*/) +void WorldSession::HandleGMTicketSystemStatusOpcode(WorldPacket & /*recvData*/) { // Note: This only disables the ticket UI at client side and is not fully reliable // are we sure this is a uint32? Should ask Zor @@ -117,25 +117,25 @@ void WorldSession::HandleGMTicketSystemStatusOpcode(WorldPacket & /*recv_data*/) SendPacket(&data); } -void WorldSession::HandleGMSurveySubmit(WorldPacket& recv_data) +void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData) { uint32 nextSurveyID = sTicketMgr->GetNextSurveyID(); // just put the survey into the database uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc - recv_data >> mainSurvey; + recvData >> mainSurvey; // sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10, for (uint8 i = 0; i < 10; i++) { uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc) - recv_data >> subSurveyId; + recvData >> subSurveyId; if (!subSurveyId) break; uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc - recv_data >> rank; + recvData >> rank; std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)") - recv_data >> comment; + recvData >> comment; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SUBSURVEY); stmt->setUInt32(0, nextSurveyID); @@ -146,7 +146,7 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recv_data) } std::string comment; // just a guess - recv_data >> comment; + recvData >> comment; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SURVEY); stmt->setUInt32(0, GUID_LOPART(GetPlayer()->GetGUID())); @@ -157,17 +157,17 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recv_data) CharacterDatabase.Execute(stmt); } -void WorldSession::HandleReportLag(WorldPacket& recv_data) +void WorldSession::HandleReportLag(WorldPacket& recvData) { // just put the lag report into the database... // can't think of anything else to do with it uint32 lagType, mapId; - recv_data >> lagType; - recv_data >> mapId; + recvData >> lagType; + recvData >> mapId; float x, y, z; - recv_data >> x; - recv_data >> y; - recv_data >> z; + recvData >> x; + recvData >> y; + recvData >> z; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_LAG_REPORT); stmt->setUInt32(0, GUID_LOPART(GetPlayer()->GetGUID())); diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index f50b9ebd311..13881d919f7 100755 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -34,34 +34,38 @@ void WorldSession::SendTradeStatus(TradeStatus status) { WorldPacket data; + data.Initialize(SMSG_TRADE_STATUS, 1+4+4); + data.WriteBit(0); // unk bit, usually 0 + data.WriteBits(status, 5); + switch (status) { case TRADE_STATUS_BEGIN_TRADE: - data.Initialize(SMSG_TRADE_STATUS, 4+8); - data << uint32(status); - data << uint64(0); + data.WriteBits(0, 8); // zero guid + data.FlushBits(); break; case TRADE_STATUS_OPEN_WINDOW: - data.Initialize(SMSG_TRADE_STATUS, 4+4); - data << uint32(status); - data << uint32(0); // added in 2.4.0 + data.FlushBits(); + data << uint32(0); // unk 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); + data.WriteBit(0); // unk + data.FlushBits(); + data << uint32(0); // unk + data << uint32(0); // unk break; case TRADE_STATUS_ONLY_CONJURED: case TRADE_STATUS_NOT_ELIGIBLE: - data.Initialize(SMSG_TRADE_STATUS, 4+1); - data << uint32(status); - data << uint8(0); + data.FlushBits(); + data << uint8(0); // unk break; + case TRADE_STATUS_CURRENCY: // Not implemented + case TRADE_STATUS_CURRENCY_NOT_TRADABLE: // Not implemented + data.FlushBits(); + data << uint32(0); // unk + data << uint32(0); // unk default: - data.Initialize(SMSG_TRADE_STATUS, 4); - data << uint32(status); + data.FlushBits(); break; } @@ -71,60 +75,117 @@ void WorldSession::SendTradeStatus(TradeStatus status) void WorldSession::HandleIgnoreTradeOpcode(WorldPacket& /*recvPacket*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Ignore Trade %u", _player->GetGUIDLow()); - // recvPacket.print_storage(); } void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Busy Trade %u", _player->GetGUIDLow()); - // recvPacket.print_storage(); } void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) { TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData(); - WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1+4+4+4+4+4+7*(1+4+4+4+4+8+4+4+4+4+8+4+4+4+4+4+4)); - data << uint8(trader_data); // 1 means traders data, 0 means own - 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?) + ByteBuffer itemData(7*2 + 7*4 + 3*4 + 3*4 + 1); + + uint8 count = 0; + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (view_trade->GetItem(TradeSlots(i))) + ++count; + + WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 4*6 + 8 + 1 + 3 + count * 70); + data << uint32(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(0); // unk 2 + data << uint64(view_trade->GetMoney()); // trader gold + data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases + data << uint32(0); // unk 5 + data << uint8(trader_data); // 1 means traders data, 0 means own data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases - data << uint32(view_trade->GetMoney()); // trader gold - data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item + data.WriteBits(count, 22); for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) { - data << uint8(i); // trade slot number, if not specified, then end of packet + Item* item = view_trade->GetItem(TradeSlots(i)); + if (!item) + continue; - if (Item* item = view_trade->GetItem(TradeSlots(i))) - { - data << uint32(item->GetTemplate()->ItemId); // entry - data << uint32(item->GetTemplate()->DisplayInfoID);// display id - data << uint32(item->GetCount()); // stack count - // wrapped: hide stats but show giftcreator name - data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED) ? 1 : 0); - data << uint64(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR)); - // perm. enchantment and gems - data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); - for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) - data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot))); - // creator - data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR)); - data << uint32(item->GetSpellCharges()); // charges - data << uint32(item->GetItemSuffixFactor()); // SuffixFactor - data << uint32(item->GetItemRandomPropertyId());// random properties id - data << uint32(item->GetTemplate()->LockID); // lock id - // max durability - data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); - // durability - data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); - } - else + ObjectGuid giftCreatorGuid = item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR); + ObjectGuid creatorGuid = item->GetUInt64Value(ITEM_FIELD_CREATOR); + + data.WriteBit(giftCreatorGuid[7]); + data.WriteBit(giftCreatorGuid[1]); + bool notWrapped = data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)); + data.WriteBit(giftCreatorGuid[3]); + + if (notWrapped) { - for (uint8 j = 0; j < 18; ++j) - data << uint32(0); + data.WriteBit(creatorGuid[7]); + data.WriteBit(creatorGuid[1]); + data.WriteBit(creatorGuid[4]); + data.WriteBit(creatorGuid[6]); + data.WriteBit(creatorGuid[2]); + data.WriteBit(creatorGuid[3]); + data.WriteBit(creatorGuid[5]); + data.WriteBit(item->GetTemplate()->LockID != 0); + data.WriteBit(creatorGuid[0]); + + itemData.WriteByteSeq(creatorGuid[1]); + + itemData << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); + for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS /*3*/; ++enchant_slot) + itemData << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot))); + itemData << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); + + itemData.WriteByteSeq(creatorGuid[6]); + itemData.WriteByteSeq(creatorGuid[2]); + itemData.WriteByteSeq(creatorGuid[7]); + itemData.WriteByteSeq(creatorGuid[4]); + + itemData << uint32(0); // reforge id, FIXME: not implemented + itemData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); + itemData << uint32(item->GetItemRandomPropertyId()); + + itemData.WriteByteSeq(creatorGuid[3]); + + itemData << uint32(0); // unk7 + + itemData.WriteByteSeq(creatorGuid[0]); + + itemData << uint32(item->GetSpellCharges()); + itemData << uint32(item->GetItemSuffixFactor()); + + itemData.WriteByteSeq(creatorGuid[5]); } + + data.WriteBit(giftCreatorGuid[6]); + data.WriteBit(giftCreatorGuid[4]); + data.WriteBit(giftCreatorGuid[2]); + data.WriteBit(giftCreatorGuid[0]); + data.WriteBit(giftCreatorGuid[5]); + + itemData.WriteByteSeq(giftCreatorGuid[6]); + itemData.WriteByteSeq(giftCreatorGuid[1]); + itemData.WriteByteSeq(giftCreatorGuid[7]); + itemData.WriteByteSeq(giftCreatorGuid[4]); + + itemData << uint32(item->GetTemplate()->ItemId); + + itemData.WriteByteSeq(giftCreatorGuid[0]); + + itemData << uint32(item->GetCount()); + + itemData.WriteByteSeq(giftCreatorGuid[5]); + + itemData << uint8(i); + + itemData.WriteByteSeq(giftCreatorGuid[2]); + itemData.WriteByteSeq(giftCreatorGuid[3]); } + + data.FlushBits(); + data.append(itemData); + SendPacket(&data); } @@ -477,9 +538,9 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) } // update money - _player->ModifyMoney(-int32(my_trade->GetMoney())); + _player->ModifyMoney(-int64(my_trade->GetMoney())); _player->ModifyMoney(his_trade->GetMoney()); - trader->ModifyMoney(-int32(his_trade->GetMoney())); + trader->ModifyMoney(-int64(his_trade->GetMoney())); trader->ModifyMoney(my_trade->GetMoney()); if (my_spell) @@ -539,15 +600,32 @@ void WorldSession::SendCancelTrade() void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) { - // sended also after LOGOUT COMPLETE + // sent also after LOGOUT COMPLETE if (_player) // needed because STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT _player->TradeCancel(true); } void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { - uint64 ID; - recvPacket >> ID; + ObjectGuid guid; + + guid[0] = recvPacket.ReadBit(); + guid[3] = recvPacket.ReadBit(); + guid[5] = recvPacket.ReadBit(); + guid[1] = recvPacket.ReadBit(); + guid[4] = recvPacket.ReadBit(); + guid[6] = recvPacket.ReadBit(); + guid[7] = recvPacket.ReadBit(); + guid[2] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(guid[7]); + recvPacket.ReadByteSeq(guid[4]); + recvPacket.ReadByteSeq(guid[3]); + recvPacket.ReadByteSeq(guid[5]); + recvPacket.ReadByteSeq(guid[1]); + recvPacket.ReadByteSeq(guid[2]); + recvPacket.ReadByteSeq(guid[6]); + recvPacket.ReadByteSeq(guid[0]); if (GetPlayer()->m_trade) return; @@ -582,7 +660,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) return; } - Player* pOther = ObjectAccessor::FindPlayer(ID); + Player* pOther = ObjectAccessor::FindPlayer(guid); if (!pOther) { @@ -648,15 +726,36 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) _player->m_trade = new TradeData(_player, pOther); pOther->m_trade = new TradeData(pOther, _player); - WorldPacket data(SMSG_TRADE_STATUS, 12); - data << uint32(TRADE_STATUS_BEGIN_TRADE); - data << uint64(_player->GetGUID()); + WorldPacket data(SMSG_TRADE_STATUS, 2+7); + data.WriteBit(0); // unk bit, usually 0 + data.WriteBits(TRADE_STATUS_BEGIN_TRADE, 5); + + ObjectGuid playerGuid = _player->GetGUID(); + // WTB StartBitStream... + data.WriteBit(playerGuid[2]); + data.WriteBit(playerGuid[4]); + data.WriteBit(playerGuid[6]); + data.WriteBit(playerGuid[0]); + data.WriteBit(playerGuid[1]); + data.WriteBit(playerGuid[3]); + data.WriteBit(playerGuid[7]); + data.WriteBit(playerGuid[5]); + + data.WriteByteSeq(playerGuid[4]); + data.WriteByteSeq(playerGuid[1]); + data.WriteByteSeq(playerGuid[2]); + data.WriteByteSeq(playerGuid[3]); + data.WriteByteSeq(playerGuid[0]); + data.WriteByteSeq(playerGuid[7]); + data.WriteByteSeq(playerGuid[6]); + data.WriteByteSeq(playerGuid[5]); + pOther->GetSession()->SendPacket(&data); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) { - uint32 gold; + uint64 gold; recvPacket >> gold; TradeData* my_trade = _player->GetTradeData(); @@ -674,9 +773,9 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) uint8 bag; uint8 slot; + recvPacket >> slot; recvPacket >> tradeSlot; recvPacket >> bag; - recvPacket >> slot; TradeData* my_trade = _player->GetTradeData(); if (!my_trade) diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp index f0ccfc44e60..c8fca388478 100644 --- a/src/server/game/Handlers/VehicleHandler.cpp +++ b/src/server/game/Handlers/VehicleHandler.cpp @@ -23,7 +23,7 @@ #include "Log.h" #include "ObjectAccessor.h" -void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) +void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); @@ -31,44 +31,44 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) if (!vehicleGUID) // something wrong here... { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } uint64 guid; - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); MovementInfo mi; mi.guid = guid; - ReadMovementInfo(recv_data, &mi); + ReadMovementInfo(recvData, &mi); _player->m_movementInfo = mi; _player->ExitVehicle(); } -void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) +void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE"); Unit* vehicle_base = GetPlayer()->GetVehicleBase(); if (!vehicle_base) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam return; } VehicleSeatEntry const* seat = GetPlayer()->GetVehicle()->GetSeatForPassenger(GetPlayer()); if (!seat->CanSwitchFromSeat()) { - recv_data.rfinish(); // prevent warnings spam + recvData.rfinish(); // prevent warnings spam sLog->outError(LOG_FILTER_NETWORKIO, "HandleChangeSeatsOnControlledVehicle, Opcode: %u, Player %u tried to switch seats but current seatflags %u don't permit that.", - recv_data.GetOpcode(), GetPlayer()->GetGUIDLow(), seat->m_flags); + recvData.GetOpcode(), GetPlayer()->GetGUIDLow(), seat->m_flags); return; } - - switch (recv_data.GetOpcode()) + /* + switch (recvData.GetOpcode()) { case CMSG_REQUEST_VEHICLE_PREV_SEAT: GetPlayer()->ChangeSeat(-1, false); @@ -79,17 +79,17 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: { uint64 guid; // current vehicle guid - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + ReadMovementInfo(recvData, &movementInfo); vehicle_base->m_movementInfo = movementInfo; uint64 accessory; // accessory guid - recv_data.readPackGUID(accessory); + recvData.readPackGUID(accessory); int8 seatId; - recv_data >> seatId; + recvData >> seatId; if (vehicle_base->GetGUID() != guid) return; @@ -107,10 +107,10 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: { uint64 guid; // current vehicle guid - recv_data.readPackGUID(guid); + recvData.readPackGUID(guid); int8 seatId; - recv_data >> seatId; + recvData >> seatId; if (vehicle_base->GetGUID() == guid) GetPlayer()->ChangeSeat(seatId); @@ -122,7 +122,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) } default: break; - } + }*/ } void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data) @@ -209,7 +209,7 @@ void WorldSession::HandleEjectPassenger(WorldPacket &data) sLog->outError(LOG_FILTER_NETWORKIO, "HandleEjectPassenger: Player %u tried to eject invalid GUID "UI64FMTD, GetPlayer()->GetGUIDLow(), guid); } -void WorldSession::HandleRequestVehicleExit(WorldPacket& /*recv_data*/) +void WorldSession::HandleRequestVehicleExit(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT"); diff --git a/src/server/game/Handlers/VoiceChatHandler.cpp b/src/server/game/Handlers/VoiceChatHandler.cpp index 34ad5ac3eae..92e6b45d225 100755 --- a/src/server/game/Handlers/VoiceChatHandler.cpp +++ b/src/server/game/Handlers/VoiceChatHandler.cpp @@ -22,24 +22,28 @@ #include "Opcodes.h" #include "Log.h" -void WorldSession::HandleVoiceSessionEnableOpcode(WorldPacket& recv_data) +void WorldSession::HandleVoiceSessionEnableOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_VOICE_SESSION_ENABLE"); // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled - recv_data.read_skip<uint8>(); - recv_data.read_skip<uint8>(); + recvData.read_skip<uint8>(); + recvData.read_skip<uint8>(); } -void WorldSession::HandleChannelVoiceOnOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleChannelVoiceOnOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CHANNEL_VOICE_ON"); // Enable Voice button in channel context menu + /* structure: + 8 bits -> channel name length + string -> channel name + */ } -void WorldSession::HandleSetActiveVoiceChannel(WorldPacket& recv_data) +void WorldSession::HandleSetActiveVoiceChannel(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SET_ACTIVE_VOICE_CHANNEL"); - recv_data.read_skip<uint32>(); - recv_data.read_skip<char*>(); + recvData.read_skip<uint32>(); + recvData.read_skip<char*>(); } diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp new file mode 100644 index 00000000000..d937656cf31 --- /dev/null +++ b/src/server/game/Handlers/VoidStorageHandler.cpp @@ -0,0 +1,620 @@ +/* + * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Common.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "World.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Log.h" +#include "Opcodes.h" +#include "Player.h" +#include <list> +#include <vector> +#include <utility> + +void WorldSession::SendVoidStorageTransferResult(VoidTransferError result) +{ + WorldPacket data(SMSG_VOID_TRANSFER_RESULT, 4); + data << uint32(result); + SendPacket(&data); +} + +void WorldSession::HandleVoidStorageUnlock(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_VOID_STORAGE_UNLOCK"); + Player* player = GetPlayer(); + + ObjectGuid npcGuid; + npcGuid[4] = recvData.ReadBit(); + npcGuid[5] = recvData.ReadBit(); + npcGuid[3] = recvData.ReadBit(); + npcGuid[0] = recvData.ReadBit(); + npcGuid[2] = recvData.ReadBit(); + npcGuid[1] = recvData.ReadBit(); + npcGuid[7] = recvData.ReadBit(); + npcGuid[6] = recvData.ReadBit(); + + recvData.ReadByteSeq(npcGuid[7]); + recvData.ReadByteSeq(npcGuid[1]); + recvData.ReadByteSeq(npcGuid[2]); + recvData.ReadByteSeq(npcGuid[3]); + recvData.ReadByteSeq(npcGuid[5]); + recvData.ReadByteSeq(npcGuid[0]); + recvData.ReadByteSeq(npcGuid[6]); + recvData.ReadByteSeq(npcGuid[4]); + + Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + if (!unit) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageUnlock - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); + return; + } + + if (player->IsVoidStorageUnlocked()) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageUnlock - Player (GUID: %u, name: %s) tried to unlock void storage a 2nd time.", player->GetGUIDLow(), player->GetName()); + return; + } + + player->ModifyMoney(-int64(VOID_STORAGE_UNLOCK)); + player->UnlockVoidStorage(); +} + +void WorldSession::HandleVoidStorageQuery(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_VOID_STORAGE_QUERY"); + Player* player = GetPlayer(); + + ObjectGuid npcGuid; + npcGuid[4] = recvData.ReadBit(); + npcGuid[0] = recvData.ReadBit(); + npcGuid[5] = recvData.ReadBit(); + npcGuid[7] = recvData.ReadBit(); + npcGuid[6] = recvData.ReadBit(); + npcGuid[3] = recvData.ReadBit(); + npcGuid[1] = recvData.ReadBit(); + npcGuid[2] = recvData.ReadBit(); + + recvData.ReadByteSeq(npcGuid[5]); + recvData.ReadByteSeq(npcGuid[6]); + recvData.ReadByteSeq(npcGuid[3]); + recvData.ReadByteSeq(npcGuid[7]); + recvData.ReadByteSeq(npcGuid[1]); + recvData.ReadByteSeq(npcGuid[0]); + recvData.ReadByteSeq(npcGuid[4]); + recvData.ReadByteSeq(npcGuid[2]); + + Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + if (!unit) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageQuery - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); + return; + } + + if (!player->IsVoidStorageUnlocked()) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageQuery - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName()); + return; + } + + uint8 count = 0; + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + if (player->GetVoidStorageItem(i)) + ++count; + + WorldPacket data(SMSG_VOID_STORAGE_CONTENTS, 2 * count + (14 + 4 + 4 + 4 + 4) * count); + + data.WriteBits(count, 8); + + ByteBuffer itemData((14 + 4 + 4 + 4 + 4) * count); + + for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) + { + VoidStorageItem* item = player->GetVoidStorageItem(i); + if (!item) + continue; + + ObjectGuid itemId = item->ItemId; + ObjectGuid creatorGuid = item->CreatorGuid; + + data.WriteBit(creatorGuid[3]); + data.WriteBit(itemId[5]); + data.WriteBit(creatorGuid[6]); + data.WriteBit(creatorGuid[1]); + data.WriteBit(itemId[1]); + data.WriteBit(itemId[3]); + data.WriteBit(itemId[6]); + data.WriteBit(creatorGuid[5]); + data.WriteBit(creatorGuid[2]); + data.WriteBit(itemId[2]); + data.WriteBit(creatorGuid[4]); + data.WriteBit(itemId[0]); + data.WriteBit(itemId[4]); + data.WriteBit(itemId[7]); + data.WriteBit(creatorGuid[0]); + data.WriteBit(creatorGuid[7]); + + itemData.WriteByteSeq(creatorGuid[3]); + + itemData << uint32(item->ItemSuffixFactor); + + itemData.WriteByteSeq(creatorGuid[4]); + + itemData << uint32(i); + + itemData.WriteByteSeq(itemId[0]); + itemData.WriteByteSeq(itemId[6]); + itemData.WriteByteSeq(creatorGuid[0]); + + itemData << uint32(item->ItemRandomPropertyId); + + itemData.WriteByteSeq(itemId[4]); + itemData.WriteByteSeq(itemId[5]); + itemData.WriteByteSeq(itemId[2]); + itemData.WriteByteSeq(creatorGuid[2]); + itemData.WriteByteSeq(creatorGuid[6]); + itemData.WriteByteSeq(itemId[1]); + itemData.WriteByteSeq(itemId[3]); + itemData.WriteByteSeq(creatorGuid[5]); + itemData.WriteByteSeq(creatorGuid[7]); + + itemData << uint32(item->ItemEntry); + + itemData.WriteByteSeq(itemId[7]); + } + + data.FlushBits(); + data.append(itemData); + + SendPacket(&data); +} + +void WorldSession::HandleVoidStorageTransfer(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_VOID_STORAGE_TRANSFER"); + Player* player = GetPlayer(); + + // Read everything + + ObjectGuid npcGuid; + npcGuid[1] = recvData.ReadBit(); + + uint32 countDeposit = recvData.ReadBits(26); + + if (countDeposit > 9) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit more than 9 items (%u).", player->GetGUIDLow(), player->GetName(), countDeposit); + return; + } + + std::vector<ObjectGuid> itemGuids(countDeposit); + for (uint32 i = 0; i < countDeposit; ++i) + { + itemGuids[i][4] = recvData.ReadBit(); + itemGuids[i][6] = recvData.ReadBit(); + itemGuids[i][7] = recvData.ReadBit(); + itemGuids[i][0] = recvData.ReadBit(); + itemGuids[i][1] = recvData.ReadBit(); + itemGuids[i][5] = recvData.ReadBit(); + itemGuids[i][3] = recvData.ReadBit(); + itemGuids[i][2] = recvData.ReadBit(); + } + + npcGuid[2] = recvData.ReadBit(); + npcGuid[0] = recvData.ReadBit(); + npcGuid[3] = recvData.ReadBit(); + npcGuid[5] = recvData.ReadBit(); + npcGuid[6] = recvData.ReadBit(); + npcGuid[4] = recvData.ReadBit(); + + uint32 countWithdraw = recvData.ReadBits(26); + + if (countWithdraw > 9) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to withdraw more than 9 items (%u).", player->GetGUIDLow(), player->GetName(), countWithdraw); + return; + } + + std::vector<ObjectGuid> itemIds(countWithdraw); + for (uint32 i = 0; i < countWithdraw; ++i) + { + itemIds[i][4] = recvData.ReadBit(); + itemIds[i][7] = recvData.ReadBit(); + itemIds[i][1] = recvData.ReadBit(); + itemIds[i][0] = recvData.ReadBit(); + itemIds[i][2] = recvData.ReadBit(); + itemIds[i][3] = recvData.ReadBit(); + itemIds[i][5] = recvData.ReadBit(); + itemIds[i][6] = recvData.ReadBit(); + } + + npcGuid[7] = recvData.ReadBit(); + + recvData.FlushBits(); + + for (uint32 i = 0; i < countDeposit; ++i) + { + recvData.ReadByteSeq(itemGuids[i][6]); + recvData.ReadByteSeq(itemGuids[i][1]); + recvData.ReadByteSeq(itemGuids[i][0]); + recvData.ReadByteSeq(itemGuids[i][2]); + recvData.ReadByteSeq(itemGuids[i][4]); + recvData.ReadByteSeq(itemGuids[i][5]); + recvData.ReadByteSeq(itemGuids[i][3]); + recvData.ReadByteSeq(itemGuids[i][7]); + } + + recvData.ReadByteSeq(npcGuid[5]); + recvData.ReadByteSeq(npcGuid[6]); + + for (uint32 i = 0; i < countWithdraw; ++i) + { + recvData.ReadByteSeq(itemIds[i][3]); + recvData.ReadByteSeq(itemIds[i][1]); + recvData.ReadByteSeq(itemIds[i][0]); + recvData.ReadByteSeq(itemIds[i][6]); + recvData.ReadByteSeq(itemIds[i][2]); + recvData.ReadByteSeq(itemIds[i][7]); + recvData.ReadByteSeq(itemIds[i][5]); + recvData.ReadByteSeq(itemIds[i][4]); + } + + recvData.ReadByteSeq(npcGuid[1]); + recvData.ReadByteSeq(npcGuid[4]); + recvData.ReadByteSeq(npcGuid[7]); + recvData.ReadByteSeq(npcGuid[3]); + recvData.ReadByteSeq(npcGuid[2]); + recvData.ReadByteSeq(npcGuid[0]); + + Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + if (!unit) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); + return; + } + + if (!player->IsVoidStorageUnlocked()) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName()); + return; + } + + if (itemGuids.size() > player->GetNumOfVoidStorageFreeSlots()) + { + SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL); + return; + } + + uint32 freeBagSlots = 0; + if (itemIds.size() != 0) + { + // make this a Player function + for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) + if (Bag* bag = player->GetBagByPos(i)) + freeBagSlots += bag->GetFreeSlots(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + if (!player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + ++freeBagSlots; + } + + if (itemIds.size() > freeBagSlots) + { + SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); + return; + } + + if (!player->HasEnoughMoney(uint64(itemGuids.size() * VOID_STORAGE_STORE_ITEM))) + { + SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY); + return; + } + + std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT]; + uint8 depositCount = 0; + for (std::vector<ObjectGuid>::iterator itr = itemGuids.begin(); itr != itemGuids.end(); ++itr) + { + Item* item = player->GetItemByGuid(*itr); + if (!item) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit an invalid item (item guid: %u).", player->GetGUIDLow(), player->GetName(), *itr); + continue; + } + + VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetUInt64Value(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor()); + + uint8 slot = player->AddVoidStorageItem(itemVS); + + depositItems[depositCount++] = std::make_pair(itemVS, slot); + + player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + } + + int64 cost = depositCount * VOID_STORAGE_STORE_ITEM; + + player->ModifyMoney(-cost); + + VoidStorageItem withdrawItems[VOID_STORAGE_MAX_WITHDRAW]; + uint8 withdrawCount = 0; + for (std::vector<ObjectGuid>::iterator itr = itemIds.begin(); itr != itemIds.end(); ++itr) + { + uint8 slot; + VoidStorageItem* itemVS = player->GetVoidStorageItem(*itr, slot); + if (!itemVS) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) tried to withdraw an invalid item (id: %u)", player->GetGUIDLow(), player->GetName(), *itr); + continue; + } + + ItemPosCountVec dest; + InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1); + if (msg != EQUIP_ERR_OK) + { + SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL); + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) couldn't withdraw item id %u because inventory was full.", player->GetGUIDLow(), player->GetName(), *itr); + return; + } + + Item* item = player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId); + item->SetUInt64Value(ITEM_FIELD_CREATOR, uint64(itemVS->CreatorGuid)); + item->SetBinding(true); + player->SendNewItem(item, 1, false, false, false); + + withdrawItems[withdrawCount++] = *itemVS; + + player->DeleteVoidStorageItem(slot); + } + + WorldPacket data(SMSG_VOID_STORAGE_TRANSFER_CHANGES, ((5 + 5 + (7 + 7) * depositCount + + 7 * withdrawCount) / 8) + 7 * withdrawCount + (7 + 7 + 4 * 4) * depositCount); + + data.WriteBits(depositCount, 5); + data.WriteBits(withdrawCount, 5); + + for (uint8 i = 0; i < depositCount; ++i) + { + ObjectGuid itemId = depositItems[i].first.ItemId; + ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid; + data.WriteBit(creatorGuid[7]); + data.WriteBit(itemId[7]); + data.WriteBit(itemId[4]); + data.WriteBit(creatorGuid[6]); + data.WriteBit(creatorGuid[5]); + data.WriteBit(itemId[3]); + data.WriteBit(itemId[5]); + data.WriteBit(creatorGuid[4]); + data.WriteBit(creatorGuid[2]); + data.WriteBit(creatorGuid[0]); + data.WriteBit(creatorGuid[3]); + data.WriteBit(creatorGuid[1]); + data.WriteBit(itemId[2]); + data.WriteBit(itemId[0]); + data.WriteBit(itemId[1]); + data.WriteBit(itemId[6]); + } + + for (uint8 i = 0; i < withdrawCount; ++i) + { + ObjectGuid itemId = withdrawItems[i].ItemId; + data.WriteBit(itemId[1]); + data.WriteBit(itemId[7]); + data.WriteBit(itemId[3]); + data.WriteBit(itemId[5]); + data.WriteBit(itemId[6]); + data.WriteBit(itemId[2]); + data.WriteBit(itemId[4]); + data.WriteBit(itemId[0]); + } + + data.FlushBits(); + + for (uint8 i = 0; i < withdrawCount; ++i) + { + ObjectGuid itemId = withdrawItems[i].ItemId; + data.WriteByteSeq(itemId[3]); + data.WriteByteSeq(itemId[1]); + data.WriteByteSeq(itemId[0]); + data.WriteByteSeq(itemId[2]); + data.WriteByteSeq(itemId[7]); + data.WriteByteSeq(itemId[5]); + data.WriteByteSeq(itemId[6]); + data.WriteByteSeq(itemId[4]); + } + + for (uint8 i = 0; i < depositCount; ++i) + { + ObjectGuid itemId = depositItems[i].first.ItemId; + ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid; + + data << uint32(depositItems[i].first.ItemSuffixFactor); + + data.WriteByteSeq(itemId[6]); + data.WriteByteSeq(itemId[4]); + data.WriteByteSeq(creatorGuid[4]); + data.WriteByteSeq(itemId[2]); + data.WriteByteSeq(creatorGuid[1]); + data.WriteByteSeq(creatorGuid[3]); + data.WriteByteSeq(itemId[3]); + data.WriteByteSeq(creatorGuid[0]); + data.WriteByteSeq(itemId[0]); + data.WriteByteSeq(creatorGuid[6]); + data.WriteByteSeq(itemId[5]); + data.WriteByteSeq(creatorGuid[5]); + data.WriteByteSeq(creatorGuid[7]); + + data << uint32(depositItems[i].first.ItemEntry); + + data.WriteByteSeq(itemId[1]); + + data << uint32(depositItems[i].second); // slot + + data.WriteByteSeq(creatorGuid[2]); + data.WriteByteSeq(itemId[7]); + + data << uint32(depositItems[i].first.ItemRandomPropertyId); + } + + SendPacket(&data); + + SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR); +} + +void WorldSession::HandleVoidSwapItem(WorldPacket& recvData) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_VOID_SWAP_ITEM"); + + Player* player = GetPlayer(); + uint32 newSlot; + ObjectGuid npcGuid; + ObjectGuid itemId; + + recvData >> uint32(newSlot); + + npcGuid[2] = recvData.ReadBit(); + npcGuid[4] = recvData.ReadBit(); + npcGuid[0] = recvData.ReadBit(); + itemId[2] = recvData.ReadBit(); + itemId[6] = recvData.ReadBit(); + itemId[5] = recvData.ReadBit(); + npcGuid[1] = recvData.ReadBit(); + npcGuid[7] = recvData.ReadBit(); + itemId[3] = recvData.ReadBit(); + itemId[7] = recvData.ReadBit(); + itemId[0] = recvData.ReadBit(); + npcGuid[6] = recvData.ReadBit(); + npcGuid[5] = recvData.ReadBit(); + npcGuid[3] = recvData.ReadBit(); + itemId[1] = recvData.ReadBit(); + itemId[4] = recvData.ReadBit(); + + recvData.ReadByteSeq(npcGuid[1]); + recvData.ReadByteSeq(itemId[3]); + recvData.ReadByteSeq(itemId[2]); + recvData.ReadByteSeq(itemId[4]); + recvData.ReadByteSeq(npcGuid[3]); + recvData.ReadByteSeq(npcGuid[0]); + recvData.ReadByteSeq(itemId[6]); + recvData.ReadByteSeq(itemId[1]); + recvData.ReadByteSeq(npcGuid[5]); + recvData.ReadByteSeq(itemId[5]); + recvData.ReadByteSeq(npcGuid[6]); + recvData.ReadByteSeq(itemId[0]); + recvData.ReadByteSeq(npcGuid[2]); + recvData.ReadByteSeq(npcGuid[7]); + recvData.ReadByteSeq(npcGuid[4]); + recvData.ReadByteSeq(itemId[7]); + + Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER); + if (!unit) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidSwapItem - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid)); + return; + } + + if (!player->IsVoidStorageUnlocked()) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName()); + return; + } + + uint8 oldSlot; + if (!player->GetVoidStorageItem(itemId, oldSlot)) + { + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) requested swapping an invalid item (slot: %u, itemid: %u).", player->GetGUIDLow(), player->GetName(), newSlot, itemId); + return; + } + + bool usedSrcSlot = player->GetVoidStorageItem(oldSlot) != NULL; // should be always true + bool usedDestSlot = player->GetVoidStorageItem(newSlot) != NULL; + ObjectGuid itemIdDest; + if (usedDestSlot) + itemIdDest = player->GetVoidStorageItem(newSlot)->ItemId; + + if (!player->SwapVoidStorageItem(oldSlot, newSlot)) + { + SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1); + return; + } + + WorldPacket data(SMSG_VOID_ITEM_SWAP_RESPONSE, 1 + (usedSrcSlot + usedDestSlot) * (1 + 7 + 4)); + + data.WriteBit(!usedDestSlot); + data.WriteBit(!usedSrcSlot); + + if (usedSrcSlot) + { + data.WriteBit(itemId[5]); + data.WriteBit(itemId[2]); + data.WriteBit(itemId[1]); + data.WriteBit(itemId[4]); + data.WriteBit(itemId[0]); + data.WriteBit(itemId[6]); + data.WriteBit(itemId[7]); + data.WriteBit(itemId[3]); + } + + data.WriteBit(!usedDestSlot); // unk + + if (usedDestSlot) + { + data.WriteBit(itemIdDest[7]); + data.WriteBit(itemIdDest[3]); + data.WriteBit(itemIdDest[4]); + data.WriteBit(itemIdDest[0]); + data.WriteBit(itemIdDest[5]); + data.WriteBit(itemIdDest[1]); + data.WriteBit(itemIdDest[2]); + data.WriteBit(itemIdDest[6]); + } + + data.WriteBit(!usedSrcSlot); // unk + + data.FlushBits(); + + if (usedDestSlot) + { + data.WriteByteSeq(itemIdDest[4]); + data.WriteByteSeq(itemIdDest[6]); + data.WriteByteSeq(itemIdDest[5]); + data.WriteByteSeq(itemIdDest[2]); + data.WriteByteSeq(itemIdDest[3]); + data.WriteByteSeq(itemIdDest[1]); + data.WriteByteSeq(itemIdDest[7]); + data.WriteByteSeq(itemIdDest[0]); + } + + if (usedSrcSlot) + { + data.WriteByteSeq(itemId[6]); + data.WriteByteSeq(itemId[3]); + data.WriteByteSeq(itemId[5]); + data.WriteByteSeq(itemId[0]); + data.WriteByteSeq(itemId[1]); + data.WriteByteSeq(itemId[2]); + data.WriteByteSeq(itemId[4]); + data.WriteByteSeq(itemId[7]); + } + + if (usedDestSlot) + data << uint32(oldSlot); + + if (usedSrcSlot) + data << uint32(newSlot); + + SendPacket(&data); +} diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index be9ee67b341..6888f77916a 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -400,12 +400,15 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 case ENCOUNTER_FRAME_ENGAGE: case ENCOUNTER_FRAME_DISENGAGE: case ENCOUNTER_FRAME_UPDATE_PRIORITY: + if (!unit) + return; data.append(unit->GetPackGUID()); data << uint8(param1); break; case ENCOUNTER_FRAME_ADD_TIMER: case ENCOUNTER_FRAME_ENABLE_OBJECTIVE: case ENCOUNTER_FRAME_DISABLE_OBJECTIVE: + case ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT: data << uint8(param1); break; case ENCOUNTER_FRAME_UPDATE_OBJECTIVE: @@ -413,6 +416,8 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 data << uint8(param2); break; case ENCOUNTER_FRAME_UNK7: + case ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT: + case ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT: default: break; } @@ -431,7 +436,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi if ((*itr)->creditType == type && (*itr)->creditEntry == creditEntry) { completedEncounters |= 1 << (*itr)->dbcEntry->encounterIndex; - sLog->outDebug(LOG_FILTER_TSCR, "Instance %s (instanceId %u) completed encounter %s", instance->GetMapName(), instance->GetInstanceId(), (*itr)->dbcEntry->encounterName[0]); + sLog->outDebug(LOG_FILTER_TSCR, "Instance %s (instanceId %u) completed encounter %s", instance->GetMapName(), instance->GetInstanceId(), (*itr)->dbcEntry->encounterName); if (uint32 dungeonId = (*itr)->lastEncounterDungeon) { Map::PlayerList const& players = instance->GetPlayers(); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index ba6d327e631..130e06b67c0 100755 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -42,14 +42,17 @@ typedef std::set<Creature*> MinionSet; enum EncounterFrameType { - ENCOUNTER_FRAME_ENGAGE = 0, - ENCOUNTER_FRAME_DISENGAGE = 1, - ENCOUNTER_FRAME_UPDATE_PRIORITY = 2, - ENCOUNTER_FRAME_ADD_TIMER = 3, - ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 4, - ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 5, - ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 6, - ENCOUNTER_FRAME_UNK7 = 7, // Seems to have something to do with sorting the encounter units + ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT = 0, + ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT = 1, + ENCOUNTER_FRAME_ENGAGE = 2, + ENCOUNTER_FRAME_DISENGAGE = 3, + ENCOUNTER_FRAME_UPDATE_PRIORITY = 4, + ENCOUNTER_FRAME_ADD_TIMER = 5, + ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 6, + ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 7, + ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 8, + ENCOUNTER_FRAME_UNK7 = 9, // Seems to have something to do with sorting the encounter units + ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT = 10, }; enum EncounterState diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 6f49a555950..275e8f93d8b 100755 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -808,6 +808,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) size_t count_pos = b.wpos(); // pos of item count byte b << uint8(0); // item count placeholder + b << uint8(0); // 4.x unknown switch (lv.permission) { @@ -1493,16 +1494,17 @@ void LoadLootTemplates_Disenchant() LootIdSet lootIdSet, lootIdSetUsed; uint32 count = LootTemplates_Disenchant.LoadAndCollectLootIds(lootIdSet); - ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); - for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) + for (uint32 i = 0; i < sItemDisenchantLootStore.GetNumRows(); ++i) { - if (uint32 lootid = itr->second.DisenchantID) - { - if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Disenchant.ReportNotExistedId(lootid); - else - lootIdSetUsed.insert(lootid); - } + ItemDisenchantLootEntry const* disenchant = sItemDisenchantLootStore.LookupEntry(i); + if (!disenchant) + continue; + + uint32 lootid = disenchant->Id; + if (lootIdSet.find(lootid) == lootIdSet.end()) + LootTemplates_Disenchant.ReportNotExistedId(lootid); + else + lootIdSetUsed.insert(lootid); } for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr) diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h index 8efb33bda9a..7ae8f659788 100755 --- a/src/server/game/Mails/Mail.h +++ b/src/server/game/Mails/Mail.h @@ -124,13 +124,13 @@ class MailDraft public: // Accessors uint16 GetMailTemplateId() const { return m_mailTemplateId; } std::string const& GetSubject() const { return m_subject; } - uint32 GetMoney() const { return m_money; } - uint32 GetCOD() const { return m_COD; } + uint64 GetMoney() const { return m_money; } + uint64 GetCOD() const { return m_COD; } std::string const& GetBody() const { return m_body; } public: // modifiers MailDraft& AddItem(Item* item); - MailDraft& AddMoney(uint32 money) { m_money = money; return *this; } + MailDraft& AddMoney(uint64 money) { m_money = money; return *this; } MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; } public: // finishers @@ -148,8 +148,8 @@ class MailDraft MailItemMap m_items; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid - uint32 m_money; - uint32 m_COD; + uint64 m_money; + uint64 m_COD; }; struct MailItemInfo @@ -165,7 +165,7 @@ struct Mail uint8 messageType; uint8 stationery; uint16 mailTemplateId; - uint32 sender; + uint32 sender; // TODO: change to uint64 and store full guids uint32 receiver; std::string subject; std::string body; @@ -173,8 +173,8 @@ struct Mail std::vector<uint32> removedItems; time_t expire_time; time_t deliver_time; - uint32 money; - uint32 COD; + uint64 money; + uint64 COD; uint32 checked; MailState state; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 53b2f9cf437..c1510bef543 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1960,7 +1960,7 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const char const* Map::GetMapName() const { - return i_mapEntry ? i_mapEntry->name[sWorld->GetDefaultDbcLocale()] : "UNNAMEDMAP\x0"; + return i_mapEntry ? i_mapEntry->name : "UNNAMEDMAP\x0"; } void Map::UpdateObjectVisibility(WorldObject* obj, Cell cell, CellCoord cellpair) @@ -1989,7 +1989,7 @@ void Map::SendInitSelf(Player* player) { sLog->outInfo(LOG_FILTER_MAPS, "Creating player data for himself %u", player->GetGUIDLow()); - UpdateData data; + UpdateData data(player->GetMapId()); // attach to player data current transport data if (Transport* transport = player->GetTransport()) @@ -2026,7 +2026,7 @@ void Map::SendInitTransports(Player* player) if (tmap.find(player->GetMapId()) == tmap.end()) return; - UpdateData transData; + UpdateData transData(player->GetMapId()); MapManager::TransportSet& tset = tmap[player->GetMapId()]; @@ -2053,7 +2053,7 @@ void Map::SendRemoveTransports(Player* player) if (tmap.find(player->GetMapId()) == tmap.end()) return; - UpdateData transData; + UpdateData transData(player->GetMapId()); MapManager::TransportSet& tset = tmap[player->GetMapId()]; @@ -2446,10 +2446,11 @@ bool InstanceMap::AddPlayerToMap(Player* player) // players also become permanently bound when they enter if (groupBind->perm) { - WorldPacket data(SMSG_INSTANCE_LOCK_WARNING_QUERY, 9); + WorldPacket data(SMSG_INSTANCE_LOCK_WARNING_QUERY, 10); data << uint32(60000); data << uint32(i_data ? i_data->GetCompletedEncounterMask() : 0); data << uint8(0); + data << uint8(0); // events it throws: 1 : INSTANCE_LOCK_WARNING 0 : INSTANCE_LOCK_STOP / INSTANCE_LOCK_START player->GetSession()->SendPacket(&data); player->SetPendingBind(mapSave->GetInstanceId(), 60000); } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 6d526f23a94..5eb11416fdd 100755 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -444,6 +444,7 @@ class Map : public GridRefManager<NGridType> bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);} bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist); + virtual uint32 GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return 0; } /* RESPAWN TIMES */ diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index b49d7db0a27..4c272430266 100755 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -181,7 +181,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) if (player->isGameMaster()) return true; - char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()]; + char const* mapName = entry->name; Group* group = player->GetGroup(); if (entry->IsRaid()) diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index dac5b1ef9a2..212c391d186 100755 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -126,6 +126,9 @@ namespace Trinity case CONTENT_71_80: nBaseExp = 580; break; + case CONTENT_81_85: + nBaseExp = 1878; + break; default: sLog->outError(LOG_FILTER_GENERAL, "BaseGain: Unsupported content level %u", content); nBaseExp = 45; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index f74d6c44be7..13225985644 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -22,6 +22,8 @@ #include "Define.h" #include <cassert> +#define MAX_CREATURE_BASE_HP 4 + enum SpellEffIndex { EFFECT_0 = 0, @@ -33,14 +35,15 @@ enum SpellEffIndex #define EFFECT_FIRST_FOUND 254 #define EFFECT_ALL 255 + // loot modes for creatures and gameobjects, bitmask! enum LootModes { - LOOT_MODE_DEFAULT = 1, - LOOT_MODE_HARD_MODE_1 = 2, - LOOT_MODE_HARD_MODE_2 = 4, - LOOT_MODE_HARD_MODE_3 = 8, - LOOT_MODE_HARD_MODE_4 = 16 + LOOT_MODE_DEFAULT = 0x1, + LOOT_MODE_HARD_MODE_1 = 0x2, + LOOT_MODE_HARD_MODE_2 = 0x4, + LOOT_MODE_HARD_MODE_3 = 0x8, + LOOT_MODE_HARD_MODE_4 = 0x10 }; enum Gender @@ -53,42 +56,44 @@ enum Gender // Race value is index in ChrRaces.dbc enum Races { - RACE_NONE = 0, - RACE_HUMAN = 1, - RACE_ORC = 2, - RACE_DWARF = 3, - RACE_NIGHTELF = 4, - RACE_UNDEAD_PLAYER = 5, - RACE_TAUREN = 6, - RACE_GNOME = 7, - RACE_TROLL = 8, - //RACE_GOBLIN = 9, - RACE_BLOODELF = 10, - RACE_DRAENEI = 11 - //RACE_FEL_ORC = 12, - //RACE_NAGA = 13, - //RACE_BROKEN = 14, - //RACE_SKELETON = 15, - //RACE_VRYKUL = 16, - //RACE_TUSKARR = 17, - //RACE_FOREST_TROLL = 18, - //RACE_TAUNKA = 19, + RACE_NONE = 0, + RACE_HUMAN = 1, + RACE_ORC = 2, + RACE_DWARF = 3, + RACE_NIGHTELF = 4, + RACE_UNDEAD_PLAYER = 5, + RACE_TAUREN = 6, + RACE_GNOME = 7, + RACE_TROLL = 8, + RACE_GOBLIN = 9, + RACE_BLOODELF = 10, + RACE_DRAENEI = 11, + //RACE_FEL_ORC = 12, + //RACE_NAGA = 13, + //RACE_BROKEN = 14, + //RACE_SKELETON = 15, + //RACE_VRYKUL = 16, + //RACE_TUSKARR = 17, + //RACE_FOREST_TROLL = 18, + //RACE_TAUNKA = 19, //RACE_NORTHREND_SKELETON = 20, - //RACE_ICE_TROLL = 21 + //RACE_ICE_TROLL = 21, + RACE_WORGEN = 22, + //RACE_GILNEAN = 23 }; // max+1 for player race -#define MAX_RACES 12 +#define MAX_RACES 23 #define RACEMASK_ALL_PLAYABLE \ ((1<<(RACE_HUMAN-1)) |(1<<(RACE_ORC-1)) |(1<<(RACE_DWARF-1)) | \ - (1<<(RACE_NIGHTELF-1))|(1<<(RACE_UNDEAD_PLAYER-1))|(1<<(RACE_TAUREN-1)) | \ - (1<<(RACE_GNOME-1)) |(1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1))| \ - (1<<(RACE_DRAENEI-1))) + (1<<(RACE_NIGHTELF-1))|(1<<(RACE_UNDEAD_PLAYER-1))|(1<<(RACE_TAUREN-1)) | \ + (1<<(RACE_GNOME-1)) |(1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1))| \ + (1<<(RACE_DRAENEI-1)) |(1<<(RACE_GOBLIN-1)) |(1<<(RACE_WORGEN-1))) #define RACEMASK_ALLIANCE \ ((1<<(RACE_HUMAN-1)) | (1<<(RACE_DWARF-1)) | (1<<(RACE_NIGHTELF-1)) | \ - (1<<(RACE_GNOME-1)) | (1<<(RACE_DRAENEI-1))) + (1<<(RACE_GNOME-1)) | (1<<(RACE_DRAENEI-1)) | (1<<(RACE_WORGEN-1))) #define RACEMASK_HORDE RACEMASK_ALL_PLAYABLE & ~RACEMASK_ALLIANCE @@ -174,14 +179,19 @@ enum Powers POWER_RAGE = 1, POWER_FOCUS = 2, POWER_ENERGY = 3, - POWER_HAPPINESS = 4, POWER_RUNE = 5, POWER_RUNIC_POWER = 6, - MAX_POWERS = 7, - POWER_ALL = 127, // default for class? + POWER_SOULSHARD = 7, + POWER_ECLIPSE = 8, + POWER_HOLY_POWER = 9, + POWER_ALTERNATIVE = 10, // Used in some quests + MAX_POWERS = 11, + POWER_ALL = 127, // default for class? POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value) }; +#define MAX_STORED_POWERS 5 + enum SpellSchools { SPELL_SCHOOL_NORMAL = 0, @@ -556,7 +566,8 @@ enum SpellAttr7 #define MAX_TALENT_SPEC 1 #define MIN_TALENT_SPECS 1 #define MAX_TALENT_SPECS 2 -#define MAX_GLYPH_SLOT_INDEX 6 +#define MAX_GLYPH_SLOT_INDEX 9 +#define REQ_PRIMARY_TREE_TALENTS 31 // Custom values enum SpellClickUserTypes @@ -633,10 +644,12 @@ enum Language LANG_ZOMBIE = 36, LANG_GNOMISH_BINARY = 37, LANG_GOBLIN_BINARY = 38, + LANG_WORGEN = 39, + LANG_GOBLIN = 40, LANG_ADDON = 0xFFFFFFFF // used by addons, in 2.4.0 not exist, replaced by messagetype? }; -#define LANGUAGES_COUNT 19 +#define LANGUAGES_COUNT 21 enum TeamId { @@ -662,7 +675,7 @@ enum SpellEffects SPELL_EFFECT_INSTAKILL = 1, SPELL_EFFECT_SCHOOL_DAMAGE = 2, SPELL_EFFECT_DUMMY = 3, - SPELL_EFFECT_PORTAL_TELEPORT = 4, + SPELL_EFFECT_PORTAL_TELEPORT = 4, // Unused (4.2.2) SPELL_EFFECT_TELEPORT_UNITS = 5, SPELL_EFFECT_APPLY_AURA = 6, SPELL_EFFECT_ENVIRONMENTAL_DAMAGE = 7, @@ -671,9 +684,9 @@ enum SpellEffects SPELL_EFFECT_HEAL = 10, SPELL_EFFECT_BIND = 11, SPELL_EFFECT_PORTAL = 12, - SPELL_EFFECT_RITUAL_BASE = 13, - SPELL_EFFECT_RITUAL_SPECIALIZE = 14, - SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL = 15, + SPELL_EFFECT_RITUAL_BASE = 13, // Unused (4.2.2) + SPELL_EFFECT_RITUAL_SPECIALIZE = 14, // Unused (4.2.2) + SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL = 15, // Unused (4.2.2) SPELL_EFFECT_QUEST_COMPLETE = 16, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL = 17, SPELL_EFFECT_RESURRECT = 18, @@ -709,8 +722,8 @@ enum SpellEffects SPELL_EFFECT_STEALTH = 48, SPELL_EFFECT_DETECT = 49, SPELL_EFFECT_TRANS_DOOR = 50, - SPELL_EFFECT_FORCE_CRITICAL_HIT = 51, - SPELL_EFFECT_GUARANTEE_HIT = 52, + SPELL_EFFECT_FORCE_CRITICAL_HIT = 51, // Unused (4.2.2) + SPELL_EFFECT_GUARANTEE_HIT = 52, // Unused (4.2.2) SPELL_EFFECT_ENCHANT_ITEM = 53, SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY = 54, SPELL_EFFECT_TAMECREATURE = 55, @@ -780,7 +793,7 @@ enum SpellEffects SPELL_EFFECT_APPLY_AREA_AURA_PET = 119, SPELL_EFFECT_TELEPORT_GRAVEYARD = 120, SPELL_EFFECT_NORMALIZED_WEAPON_DMG = 121, - SPELL_EFFECT_122 = 122, + SPELL_EFFECT_122 = 122, // Unused (4.2.2) SPELL_EFFECT_SEND_TAXI = 123, SPELL_EFFECT_PULL_TOWARDS = 124, SPELL_EFFECT_MODIFY_THREAT_PERCENT = 125, @@ -821,203 +834,231 @@ enum SpellEffects SPELL_EFFECT_160 = 160, SPELL_EFFECT_TALENT_SPEC_COUNT = 161, SPELL_EFFECT_TALENT_SPEC_SELECT = 162, - SPELL_EFFECT_163 = 163, + SPELL_EFFECT_163 = 163, // Unused (4.2.2) SPELL_EFFECT_REMOVE_AURA = 164, - TOTAL_SPELL_EFFECTS = 165 + SPELL_EFFECT_165 = 165, + SPELL_EFFECT_166 = 166, + SPELL_EFFECT_167 = 167, + SPELL_EFFECT_168 = 168, + SPELL_EFFECT_169 = 169, + SPELL_EFFECT_170 = 170, + SPELL_EFFECT_171 = 171, // Summons gamebject + SPELL_EFFECT_172 = 172, // Aoe ressurection + SPELL_EFFECT_173 = 173, // Guild tab unlocked (guild perk) + SPELL_EFFECT_174 = 174, // + SPELL_EFFECT_175 = 175, // Unused (4.2.2) + SPELL_EFFECT_176 = 176, // Some kind of sanctuary effect (Vanish) + SPELL_EFFECT_177 = 177, + TOTAL_SPELL_EFFECTS = 178, }; enum SpellCastResult { - SPELL_FAILED_SUCCESS = 0, - SPELL_FAILED_AFFECTING_COMBAT = 1, - SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 2, - SPELL_FAILED_ALREADY_AT_FULL_MANA = 3, - SPELL_FAILED_ALREADY_AT_FULL_POWER = 4, - SPELL_FAILED_ALREADY_BEING_TAMED = 5, - SPELL_FAILED_ALREADY_HAVE_CHARM = 6, - SPELL_FAILED_ALREADY_HAVE_SUMMON = 7, - SPELL_FAILED_ALREADY_OPEN = 8, - SPELL_FAILED_AURA_BOUNCED = 9, - SPELL_FAILED_AUTOTRACK_INTERRUPTED = 10, - SPELL_FAILED_BAD_IMPLICIT_TARGETS = 11, - SPELL_FAILED_BAD_TARGETS = 12, - SPELL_FAILED_CANT_BE_CHARMED = 13, - SPELL_FAILED_CANT_BE_DISENCHANTED = 14, - SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 15, - SPELL_FAILED_CANT_BE_MILLED = 16, - SPELL_FAILED_CANT_BE_PROSPECTED = 17, - SPELL_FAILED_CANT_CAST_ON_TAPPED = 18, - SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 19, - SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 20, - SPELL_FAILED_CANT_STEALTH = 21, - SPELL_FAILED_CASTER_AURASTATE = 22, - SPELL_FAILED_CASTER_DEAD = 23, - SPELL_FAILED_CHARMED = 24, - SPELL_FAILED_CHEST_IN_USE = 25, - SPELL_FAILED_CONFUSED = 26, - SPELL_FAILED_DONT_REPORT = 27, - SPELL_FAILED_EQUIPPED_ITEM = 28, - SPELL_FAILED_EQUIPPED_ITEM_CLASS = 29, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 30, - SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 31, - SPELL_FAILED_ERROR = 32, - SPELL_FAILED_FIZZLE = 33, - SPELL_FAILED_FLEEING = 34, - SPELL_FAILED_FOOD_LOWLEVEL = 35, - SPELL_FAILED_HIGHLEVEL = 36, - SPELL_FAILED_HUNGER_SATIATED = 37, - SPELL_FAILED_IMMUNE = 38, - SPELL_FAILED_INCORRECT_AREA = 39, - SPELL_FAILED_INTERRUPTED = 40, - SPELL_FAILED_INTERRUPTED_COMBAT = 41, - SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 42, - SPELL_FAILED_ITEM_GONE = 43, - SPELL_FAILED_ITEM_NOT_FOUND = 44, - SPELL_FAILED_ITEM_NOT_READY = 45, - SPELL_FAILED_LEVEL_REQUIREMENT = 46, - SPELL_FAILED_LINE_OF_SIGHT = 47, - SPELL_FAILED_LOWLEVEL = 48, - SPELL_FAILED_LOW_CASTLEVEL = 49, - SPELL_FAILED_MAINHAND_EMPTY = 50, - SPELL_FAILED_MOVING = 51, - SPELL_FAILED_NEED_AMMO = 52, - SPELL_FAILED_NEED_AMMO_POUCH = 53, - SPELL_FAILED_NEED_EXOTIC_AMMO = 54, - SPELL_FAILED_NEED_MORE_ITEMS = 55, - SPELL_FAILED_NOPATH = 56, - SPELL_FAILED_NOT_BEHIND = 57, - SPELL_FAILED_NOT_FISHABLE = 58, - SPELL_FAILED_NOT_FLYING = 59, - SPELL_FAILED_NOT_HERE = 60, - SPELL_FAILED_NOT_INFRONT = 61, - SPELL_FAILED_NOT_IN_CONTROL = 62, - SPELL_FAILED_NOT_KNOWN = 63, - SPELL_FAILED_NOT_MOUNTED = 64, - SPELL_FAILED_NOT_ON_TAXI = 65, - SPELL_FAILED_NOT_ON_TRANSPORT = 66, - SPELL_FAILED_NOT_READY = 67, - SPELL_FAILED_NOT_SHAPESHIFT = 68, - SPELL_FAILED_NOT_STANDING = 69, - SPELL_FAILED_NOT_TRADEABLE = 70, - SPELL_FAILED_NOT_TRADING = 71, - SPELL_FAILED_NOT_UNSHEATHED = 72, - SPELL_FAILED_NOT_WHILE_GHOST = 73, - SPELL_FAILED_NOT_WHILE_LOOTING = 74, - SPELL_FAILED_NO_AMMO = 75, - SPELL_FAILED_NO_CHARGES_REMAIN = 76, - SPELL_FAILED_NO_CHAMPION = 77, - SPELL_FAILED_NO_COMBO_POINTS = 78, - SPELL_FAILED_NO_DUELING = 79, - SPELL_FAILED_NO_ENDURANCE = 80, - SPELL_FAILED_NO_FISH = 81, - SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 82, - SPELL_FAILED_NO_MOUNTS_ALLOWED = 83, - SPELL_FAILED_NO_PET = 84, - SPELL_FAILED_NO_POWER = 85, - SPELL_FAILED_NOTHING_TO_DISPEL = 86, - SPELL_FAILED_NOTHING_TO_STEAL = 87, - SPELL_FAILED_ONLY_ABOVEWATER = 88, - SPELL_FAILED_ONLY_DAYTIME = 89, - SPELL_FAILED_ONLY_INDOORS = 90, - SPELL_FAILED_ONLY_MOUNTED = 91, - SPELL_FAILED_ONLY_NIGHTTIME = 92, - SPELL_FAILED_ONLY_OUTDOORS = 93, - SPELL_FAILED_ONLY_SHAPESHIFT = 94, - SPELL_FAILED_ONLY_STEALTHED = 95, - SPELL_FAILED_ONLY_UNDERWATER = 96, - SPELL_FAILED_OUT_OF_RANGE = 97, - SPELL_FAILED_PACIFIED = 98, - SPELL_FAILED_POSSESSED = 99, - SPELL_FAILED_REAGENTS = 100, - SPELL_FAILED_REQUIRES_AREA = 101, - SPELL_FAILED_REQUIRES_SPELL_FOCUS = 102, - SPELL_FAILED_ROOTED = 103, - SPELL_FAILED_SILENCED = 104, - SPELL_FAILED_SPELL_IN_PROGRESS = 105, - SPELL_FAILED_SPELL_LEARNED = 106, - SPELL_FAILED_SPELL_UNAVAILABLE = 107, - SPELL_FAILED_STUNNED = 108, - SPELL_FAILED_TARGETS_DEAD = 109, - SPELL_FAILED_TARGET_AFFECTING_COMBAT = 110, - SPELL_FAILED_TARGET_AURASTATE = 111, - SPELL_FAILED_TARGET_DUELING = 112, - SPELL_FAILED_TARGET_ENEMY = 113, - SPELL_FAILED_TARGET_ENRAGED = 114, - SPELL_FAILED_TARGET_FRIENDLY = 115, - SPELL_FAILED_TARGET_IN_COMBAT = 116, - SPELL_FAILED_TARGET_IS_PLAYER = 117, - SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 118, - SPELL_FAILED_TARGET_NOT_DEAD = 119, - SPELL_FAILED_TARGET_NOT_IN_PARTY = 120, - SPELL_FAILED_TARGET_NOT_LOOTED = 121, - SPELL_FAILED_TARGET_NOT_PLAYER = 122, - SPELL_FAILED_TARGET_NO_POCKETS = 123, - SPELL_FAILED_TARGET_NO_WEAPONS = 124, - SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 125, - SPELL_FAILED_TARGET_UNSKINNABLE = 126, - SPELL_FAILED_THIRST_SATIATED = 127, - SPELL_FAILED_TOO_CLOSE = 128, - SPELL_FAILED_TOO_MANY_OF_ITEM = 129, - SPELL_FAILED_TOTEM_CATEGORY = 130, - SPELL_FAILED_TOTEMS = 131, - SPELL_FAILED_TRY_AGAIN = 132, - SPELL_FAILED_UNIT_NOT_BEHIND = 133, - SPELL_FAILED_UNIT_NOT_INFRONT = 134, - SPELL_FAILED_WRONG_PET_FOOD = 135, - SPELL_FAILED_NOT_WHILE_FATIGUED = 136, - SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 137, - SPELL_FAILED_NOT_WHILE_TRADING = 138, - SPELL_FAILED_TARGET_NOT_IN_RAID = 139, - SPELL_FAILED_TARGET_FREEFORALL = 140, - SPELL_FAILED_NO_EDIBLE_CORPSES = 141, - SPELL_FAILED_ONLY_BATTLEGROUNDS = 142, - SPELL_FAILED_TARGET_NOT_GHOST = 143, - SPELL_FAILED_TRANSFORM_UNUSABLE = 144, - SPELL_FAILED_WRONG_WEATHER = 145, - SPELL_FAILED_DAMAGE_IMMUNE = 146, - SPELL_FAILED_PREVENTED_BY_MECHANIC = 147, - SPELL_FAILED_PLAY_TIME = 148, - SPELL_FAILED_REPUTATION = 149, - SPELL_FAILED_MIN_SKILL = 150, - SPELL_FAILED_NOT_IN_ARENA = 151, - SPELL_FAILED_NOT_ON_SHAPESHIFT = 152, - SPELL_FAILED_NOT_ON_STEALTHED = 153, - SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 154, - SPELL_FAILED_NOT_ON_MOUNTED = 155, - SPELL_FAILED_TOO_SHALLOW = 156, - SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 157, - SPELL_FAILED_TARGET_IS_TRIVIAL = 158, - SPELL_FAILED_BM_OR_INVISGOD = 159, - SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 160, - SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 161, - SPELL_FAILED_NOT_IDLE = 162, - SPELL_FAILED_NOT_INACTIVE = 163, - SPELL_FAILED_PARTIAL_PLAYTIME = 164, - SPELL_FAILED_NO_PLAYTIME = 165, - SPELL_FAILED_NOT_IN_BATTLEGROUND = 166, - SPELL_FAILED_NOT_IN_RAID_INSTANCE = 167, - SPELL_FAILED_ONLY_IN_ARENA = 168, - SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 169, - SPELL_FAILED_ON_USE_ENCHANT = 170, - SPELL_FAILED_NOT_ON_GROUND = 171, - SPELL_FAILED_CUSTOM_ERROR = 172, - SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 173, - SPELL_FAILED_TOO_MANY_SOCKETS = 174, - SPELL_FAILED_INVALID_GLYPH = 175, - SPELL_FAILED_UNIQUE_GLYPH = 176, - SPELL_FAILED_GLYPH_SOCKET_LOCKED = 177, - SPELL_FAILED_NO_VALID_TARGETS = 178, - SPELL_FAILED_ITEM_AT_MAX_CHARGES = 179, - SPELL_FAILED_NOT_IN_BARBERSHOP = 180, - SPELL_FAILED_FISHING_TOO_LOW = 181, - SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 182, - SPELL_FAILED_SUMMON_PENDING = 183, - SPELL_FAILED_MAX_SOCKETS = 184, - SPELL_FAILED_PET_CAN_RENAME = 185, - SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 186, - SPELL_FAILED_UNKNOWN = 187, // actually doesn't exist in client - - SPELL_CAST_OK = 255 // custom value, must not be sent to client + SPELL_FAILED_SUCCESS = 0, + SPELL_FAILED_AFFECTING_COMBAT = 1, + SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 2, + SPELL_FAILED_ALREADY_AT_FULL_MANA = 3, + SPELL_FAILED_ALREADY_AT_FULL_POWER = 4, + SPELL_FAILED_ALREADY_BEING_TAMED = 5, + SPELL_FAILED_ALREADY_HAVE_CHARM = 6, + SPELL_FAILED_ALREADY_HAVE_SUMMON = 7, + SPELL_FAILED_ALREADY_HAVE_PET = 8, + SPELL_FAILED_ALREADY_OPEN = 9, + SPELL_FAILED_AURA_BOUNCED = 10, + SPELL_FAILED_AUTOTRACK_INTERRUPTED = 11, + SPELL_FAILED_BAD_IMPLICIT_TARGETS = 12, + SPELL_FAILED_BAD_TARGETS = 13, + SPELL_FAILED_CANT_BE_CHARMED = 14, + SPELL_FAILED_CANT_BE_DISENCHANTED = 15, + SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 16, + SPELL_FAILED_CANT_BE_MILLED = 17, + SPELL_FAILED_CANT_BE_PROSPECTED = 18, + SPELL_FAILED_CANT_CAST_ON_TAPPED = 19, + SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 20, + SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 21, + SPELL_FAILED_CANT_STEALTH = 22, + SPELL_FAILED_CASTER_AURASTATE = 23, + SPELL_FAILED_CASTER_DEAD = 24, + SPELL_FAILED_CHARMED = 25, + SPELL_FAILED_CHEST_IN_USE = 26, + SPELL_FAILED_CONFUSED = 27, + SPELL_FAILED_DONT_REPORT = 28, + SPELL_FAILED_EQUIPPED_ITEM = 29, + SPELL_FAILED_EQUIPPED_ITEM_CLASS = 30, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 31, + SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 32, + SPELL_FAILED_ERROR = 33, + SPELL_FAILED_FALLING = 34, + SPELL_FAILED_FIZZLE = 35, + SPELL_FAILED_FLEEING = 36, + SPELL_FAILED_FOOD_LOWLEVEL = 37, + SPELL_FAILED_HIGHLEVEL = 38, + SPELL_FAILED_HUNGER_SATIATED = 39, + SPELL_FAILED_IMMUNE = 40, + SPELL_FAILED_INCORRECT_AREA = 41, + SPELL_FAILED_INTERRUPTED = 42, + SPELL_FAILED_INTERRUPTED_COMBAT = 43, + SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 44, + SPELL_FAILED_ITEM_GONE = 45, + SPELL_FAILED_ITEM_NOT_FOUND = 46, + SPELL_FAILED_ITEM_NOT_READY = 47, + SPELL_FAILED_LEVEL_REQUIREMENT = 48, + SPELL_FAILED_LINE_OF_SIGHT = 49, + SPELL_FAILED_LOWLEVEL = 50, + SPELL_FAILED_LOW_CASTLEVEL = 51, + SPELL_FAILED_MAINHAND_EMPTY = 52, + SPELL_FAILED_MOVING = 53, + SPELL_FAILED_NEED_AMMO = 54, + SPELL_FAILED_NEED_AMMO_POUCH = 55, + SPELL_FAILED_NEED_EXOTIC_AMMO = 56, + SPELL_FAILED_NEED_MORE_ITEMS = 57, + SPELL_FAILED_NOPATH = 58, + SPELL_FAILED_NOT_BEHIND = 59, + SPELL_FAILED_NOT_FISHABLE = 60, + SPELL_FAILED_NOT_FLYING = 61, + SPELL_FAILED_NOT_HERE = 62, + SPELL_FAILED_NOT_INFRONT = 63, + SPELL_FAILED_NOT_IN_CONTROL = 64, + SPELL_FAILED_NOT_KNOWN = 65, + SPELL_FAILED_NOT_MOUNTED = 66, + SPELL_FAILED_NOT_ON_TAXI = 67, + SPELL_FAILED_NOT_ON_TRANSPORT = 68, + SPELL_FAILED_NOT_READY = 69, + SPELL_FAILED_NOT_SHAPESHIFT = 70, + SPELL_FAILED_NOT_STANDING = 71, + SPELL_FAILED_NOT_TRADEABLE = 72, + SPELL_FAILED_NOT_TRADING = 73, + SPELL_FAILED_NOT_UNSHEATHED = 74, + SPELL_FAILED_NOT_WHILE_GHOST = 75, + SPELL_FAILED_NOT_WHILE_LOOTING = 76, + SPELL_FAILED_NO_AMMO = 77, + SPELL_FAILED_NO_CHARGES_REMAIN = 78, + SPELL_FAILED_NO_CHAMPION = 79, + SPELL_FAILED_NO_COMBO_POINTS = 80, + SPELL_FAILED_NO_DUELING = 81, + SPELL_FAILED_NO_ENDURANCE = 82, + SPELL_FAILED_NO_FISH = 83, + SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 84, + SPELL_FAILED_NO_MOUNTS_ALLOWED = 85, + SPELL_FAILED_NO_PET = 86, + SPELL_FAILED_NO_POWER = 87, + SPELL_FAILED_NOTHING_TO_DISPEL = 88, + SPELL_FAILED_NOTHING_TO_STEAL = 89, + SPELL_FAILED_ONLY_ABOVEWATER = 90, + SPELL_FAILED_ONLY_DAYTIME = 91, + SPELL_FAILED_ONLY_INDOORS = 92, + SPELL_FAILED_ONLY_MOUNTED = 93, + SPELL_FAILED_ONLY_NIGHTTIME = 94, + SPELL_FAILED_ONLY_OUTDOORS = 95, + SPELL_FAILED_ONLY_SHAPESHIFT = 96, + SPELL_FAILED_ONLY_STEALTHED = 97, + SPELL_FAILED_ONLY_UNDERWATER = 98, + SPELL_FAILED_OUT_OF_RANGE = 99, + SPELL_FAILED_PACIFIED = 100, + SPELL_FAILED_POSSESSED = 101, + SPELL_FAILED_REAGENTS = 102, + SPELL_FAILED_REQUIRES_AREA = 103, + SPELL_FAILED_REQUIRES_SPELL_FOCUS = 104, + SPELL_FAILED_ROOTED = 105, + SPELL_FAILED_SILENCED = 106, + SPELL_FAILED_SPELL_IN_PROGRESS = 107, + SPELL_FAILED_SPELL_LEARNED = 108, + SPELL_FAILED_SPELL_UNAVAILABLE = 109, + SPELL_FAILED_STUNNED = 110, + SPELL_FAILED_TARGETS_DEAD = 111, + SPELL_FAILED_TARGET_AFFECTING_COMBAT = 112, + SPELL_FAILED_TARGET_AURASTATE = 113, + SPELL_FAILED_TARGET_DUELING = 114, + SPELL_FAILED_TARGET_ENEMY = 115, + SPELL_FAILED_TARGET_ENRAGED = 116, + SPELL_FAILED_TARGET_FRIENDLY = 117, + SPELL_FAILED_TARGET_IN_COMBAT = 118, + SPELL_FAILED_TARGET_IS_PLAYER = 119, + SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 120, + SPELL_FAILED_TARGET_NOT_DEAD = 121, + SPELL_FAILED_TARGET_NOT_IN_PARTY = 122, + SPELL_FAILED_TARGET_NOT_LOOTED = 123, + SPELL_FAILED_TARGET_NOT_PLAYER = 124, + SPELL_FAILED_TARGET_NO_POCKETS = 125, + SPELL_FAILED_TARGET_NO_WEAPONS = 126, + SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 127, + SPELL_FAILED_TARGET_UNSKINNABLE = 128, + SPELL_FAILED_THIRST_SATIATED = 129, + SPELL_FAILED_TOO_CLOSE = 130, + SPELL_FAILED_TOO_MANY_OF_ITEM = 131, + SPELL_FAILED_TOTEM_CATEGORY = 132, + SPELL_FAILED_TOTEMS = 133, + SPELL_FAILED_TRY_AGAIN = 134, + SPELL_FAILED_UNIT_NOT_BEHIND = 135, + SPELL_FAILED_UNIT_NOT_INFRONT = 136, + SPELL_FAILED_VISION_OBSCURED = 137, + SPELL_FAILED_WRONG_PET_FOOD = 138, + SPELL_FAILED_NOT_WHILE_FATIGUED = 139, + SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 140, + SPELL_FAILED_NOT_WHILE_TRADING = 141, + SPELL_FAILED_TARGET_NOT_IN_RAID = 142, + SPELL_FAILED_TARGET_FREEFORALL = 143, + SPELL_FAILED_NO_EDIBLE_CORPSES = 144, + SPELL_FAILED_ONLY_BATTLEGROUNDS = 145, + SPELL_FAILED_TARGET_NOT_GHOST = 146, + SPELL_FAILED_TRANSFORM_UNUSABLE = 147, + SPELL_FAILED_WRONG_WEATHER = 148, + SPELL_FAILED_DAMAGE_IMMUNE = 149, + SPELL_FAILED_PREVENTED_BY_MECHANIC = 150, + SPELL_FAILED_PLAY_TIME = 151, + SPELL_FAILED_REPUTATION = 152, + SPELL_FAILED_MIN_SKILL = 153, + SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND = 154, + SPELL_FAILED_NOT_ON_SHAPESHIFT = 155, + SPELL_FAILED_NOT_ON_STEALTHED = 156, + SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 157, + SPELL_FAILED_NOT_ON_MOUNTED = 158, + SPELL_FAILED_TOO_SHALLOW = 159, + SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 160, + SPELL_FAILED_TARGET_IS_TRIVIAL = 161, + SPELL_FAILED_BM_OR_INVISGOD = 162, + SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 163, + SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 164, + SPELL_FAILED_NOT_IDLE = 165, + SPELL_FAILED_NOT_INACTIVE = 166, + SPELL_FAILED_PARTIAL_PLAYTIME = 167, + SPELL_FAILED_NO_PLAYTIME = 168, + SPELL_FAILED_NOT_IN_BATTLEGROUND = 169, + SPELL_FAILED_NOT_IN_RAID_INSTANCE = 170, + SPELL_FAILED_ONLY_IN_ARENA = 171, + SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 172, + SPELL_FAILED_ON_USE_ENCHANT = 173, + SPELL_FAILED_NOT_ON_GROUND = 174, + SPELL_FAILED_CUSTOM_ERROR = 175, + SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 176, + SPELL_FAILED_TOO_MANY_SOCKETS = 177, + SPELL_FAILED_INVALID_GLYPH = 178, + SPELL_FAILED_UNIQUE_GLYPH = 179, + SPELL_FAILED_GLYPH_SOCKET_LOCKED = 180, + SPELL_FAILED_NO_VALID_TARGETS = 181, + SPELL_FAILED_ITEM_AT_MAX_CHARGES = 182, + SPELL_FAILED_NOT_IN_BARBERSHOP = 183, + SPELL_FAILED_FISHING_TOO_LOW = 184, + SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 185, + SPELL_FAILED_SUMMON_PENDING = 186, + SPELL_FAILED_MAX_SOCKETS = 187, + SPELL_FAILED_PET_CAN_RENAME = 188, + SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 189, + SPELL_FAILED_NO_ACTIONS = 190, + SPELL_FAILED_CURRENCY_WEIGHT_MISMATCH = 191, + SPELL_FAILED_WEIGHT_NOT_ENOUGH = 192, + SPELL_FAILED_WEIGHT_TOO_MUCH = 193, + SPELL_FAILED_NO_VACANT_SEAT = 194, + SPELL_FAILED_NO_LIQUID = 195, + SPELL_FAILED_ONLY_NOT_SWIMMING = 196, + SPELL_FAILED_BY_NOT_MOVING = 197, + SPELL_FAILED_IN_COMBAT_RES_LIMIT_REACHED = 198, + SPELL_FAILED_NOT_IN_ARENA = 199, + SPELL_FAILED_TARGET_NOT_GROUNDED = 200, + SPELL_FAILED_EXCEEDED_WEEKLY_USAGE = 201, + SPELL_FAILED_NOT_IN_LFG_DUNGEON = 202, + SPELL_FAILED_UNKNOWN = 254, // custom value, default case + SPELL_CAST_OK = 255, // custom value, must not be sent to client }; enum SpellCustomErrors @@ -1090,38 +1131,60 @@ enum SpellCustomErrors SPELL_CUSTOM_ERROR_GM_ONLY = 65, // Only GMs may use that. Your account has been reported for investigation. SPELL_CUSTOM_ERROR_REQUIRES_LEVEL_58 = 66, // You must reach level 58 to use this portal. SPELL_CUSTOM_ERROR_AT_HONOR_CAP = 67, // You already have the maximum amount of honor. - SPELL_CUSTOM_ERROR_68 = 68, // "" - SPELL_CUSTOM_ERROR_69 = 69, // "" - SPELL_CUSTOM_ERROR_70 = 70, // "" - SPELL_CUSTOM_ERROR_71 = 71, // "" - SPELL_CUSTOM_ERROR_72 = 72, // "" - SPELL_CUSTOM_ERROR_73 = 73, // "" - SPELL_CUSTOM_ERROR_74 = 74, // "" + SPELL_CUSTOM_ERROR_HAVE_HOT_ROD = 68, // You already have a Hot Rod. + SPELL_CUSTOM_ERROR_PARTYGOER_MORE_BUBBLY = 69, // This partygoer wants some more bubbly + SPELL_CUSTOM_ERROR_PARTYGOER_NEED_BUCKET = 70, // This partygoer needs a bucket! + SPELL_CUSTOM_ERROR_PARTYGOER_WANT_TO_DANCE = 71, // This partygoer wants to dance with you. + SPELL_CUSTOM_ERROR_PARTYGOER_WANT_FIREWORKS = 72, // This partygoer wants to see some fireworks. + SPELL_CUSTOM_ERROR_PARTYGOER_WANT_APPETIZER = 73, // This partygoer wants some more hors d'oeuvres. + SPELL_CUSTOM_ERROR_GOBLIN_BATTERY_DEPLETED = 74, // The Goblin All-In-1-Der Belt's battery is depleted. SPELL_CUSTOM_ERROR_MUST_HAVE_DEMONIC_CIRCLE = 75, // You must have a demonic circle active. SPELL_CUSTOM_ERROR_AT_MAX_RAGE = 76, // You already have maximum rage SPELL_CUSTOM_ERROR_REQUIRES_350_ENGINEERING = 77, // Requires Engineering (350) SPELL_CUSTOM_ERROR_SOUL_BELONGS_TO_LICH_KING = 78, // Your soul belongs to the Lich King SPELL_CUSTOM_ERROR_ATTENDANT_HAS_PONY = 79, // Your attendant already has an Argent Pony - SPELL_CUSTOM_ERROR_80 = 80, // "" - SPELL_CUSTOM_ERROR_81 = 81, // "" - SPELL_CUSTOM_ERROR_82 = 82, // "" + SPELL_CUSTOM_ERROR_GOBLIN_STARTING_MISSION = 80, // First, Overload the Defective Generator, Activate the Leaky Stove, and Drop a Cigar on the Flammable Bed. + SPELL_CUSTOM_ERROR_GASBOT_ALREADY_SENT = 81, // You've already sent in the Gasbot and destroyed headquarters! + SPELL_CUSTOM_ERROR_GOBLIN_IS_PARTIED_OUT = 82, // This goblin is all partied out! SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM = 83, // You must have a Fire Totem active. SPELL_CUSTOM_ERROR_CANT_TARGET_VAMPIRES = 84, // You may not bite other vampires. SPELL_CUSTOM_ERROR_PET_ALREADY_AT_YOUR_LEVEL = 85, // Your pet is already at your level. SPELL_CUSTOM_ERROR_MISSING_ITEM_REQUIREMENS = 86, // You do not meet the level requirements for this item. SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS = 87, // There are too many Mutated Abominations. SPELL_CUSTOM_ERROR_ALL_POTIONS_USED = 88, // The potions have all been depleted by Professor Putricide. - SPELL_CUSTOM_ERROR_89 = 89, // "" + SPELL_CUSTOM_ERROR_DEFEATED_ENOUGH_ALREADY = 89, // You have already defeated enough of them. SPELL_CUSTOM_ERROR_REQUIRES_LEVEL_65 = 90, // Requires level 65 - SPELL_CUSTOM_ERROR_91 = 91, // "" - SPELL_CUSTOM_ERROR_92 = 92, // "" - SPELL_CUSTOM_ERROR_93 = 93, // "" - SPELL_CUSTOM_ERROR_94 = 94, // "" - SPELL_CUSTOM_ERROR_95 = 95, // "" + SPELL_CUSTOM_ERROR_DESTROYED_KTC_OIL_PLATFORM = 91, // You have already destroyed the KTC Oil Platform. + SPELL_CUSTOM_ERROR_LAUNCHED_ENOUGH_CAGES = 92, // You have already launched enough cages. + SPELL_CUSTOM_ERROR_REQUIRES_BOOSTER_ROCKETS = 93, // Requires Single-Stage Booster Rockets. Return to Hobart Grapplehammer to get more. + SPELL_CUSTOM_ERROR_ENOUGH_WILD_CLUCKERS = 94, // You have already captured enough wild cluckers. + SPELL_CUSTOM_ERROR_REQUIRES_CONTROL_FIREWORKS = 95, // Requires Remote Control Fireworks. Return to Hobart Grapplehammer to get more. SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_RECRUITS = 96, // You already have the max number of recruits. SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_VOLUNTEERS = 97, // You already have the max number of volunteers. SPELL_CUSTOM_ERROR_FROSTMOURNE_RENDERED_RESSURECT = 98, // Frostmourne has rendered you unable to ressurect. SPELL_CUSTOM_ERROR_CANT_MOUNT_WITH_SHAPESHIFT = 99, // You can't mount while affected by that shapeshift. + SPELL_CUSTOM_ERROR_FAWNS_ALREADY_FOLLOWING = 100, // Three fawns are already following you! + SPELL_CUSTOM_ERROR_ALREADY_HAVE_RIVER_BOAT = 101, // You already have a River Boat. + SPELL_CUSTOM_ERROR_NO_ACTIVE_ENCHANTMENT = 102, // You have no active enchantment to unleash. + SPELL_CUSTOM_ERROR_ENOUGH_HIGHBOURNE_SOULS = 103, // You have bound enough Highborne souls. Return to Arcanist Valdurian. + SPELL_CUSTOM_ERROR_ATLEAST_40YD_FROM_OIL_DRILLING = 104, // You must be at least 40 yards away from all other Oil Drilling Rigs. + SPELL_CUSTOM_ERROR_ABOVE_ENSLAVED_PEARL_MINER = 105, // You must be above the Enslaved Pearl Miner. + SPELL_CUSTOM_ERROR_MUST_TARGET_CORPSE_SPECIAL_1 = 106, // You must target the corpse of a Seabrush Terrapin, Scourgut Remora, or Spinescale Hammerhead. + SPELL_CUSTOM_ERROR_SLAGHAMMER_ALREADY_PRISONER = 107, // Ambassador Slaghammer is already your prisoner. + SPELL_CUSTOM_ERROR_REQUIRE_ATTUNED_LOCATION_1 = 108, // Requires a location that is attuned with the Naz'jar Battlemaiden. + SPELL_CUSTOM_ERROR_NEED_TO_FREE_DRAKE_FIRST = 109, // Free the Drake from the net first! + SPELL_CUSTOM_ERROR_DRAGONMAW_ALLIES_ALREADY_FOLLOW = 110, // You already have three Dragonmaw allies following you. + SPELL_CUSTOM_ERROR_REQUIRE_OPPOSABLE_THUMBS = 111, // Requires Opposable Thumbs. + SPELL_CUSTOM_ERROR_NOT_ENOUGH_HEALTH_2 = 112, // Not enough health + SPELL_CUSTOM_ERROR_ENOUGH_FORSAKEN_TROOPERS = 113, // You already have enough Forsaken Troopers. + SPELL_CUSTOM_ERROR_CANNOT_JUMP_TO_BOULDER = 114, // You cannot jump to another boulder yet. + SPELL_CUSTOM_ERROR_SKILL_TOO_HIGH = 115, // Skill too high. + SPELL_CUSTOM_ERROR_ALREADY_6_SURVIVORS_RESCUED = 116, // You have already rescued 6 Survivors. + SPELL_CUSTOM_ERROR_MUST_FACE_SHIPS_FROM_BALLOON = 117, // You need to be facing the ships from the rescue balloon. + SPELL_CUSTOM_ERROR_CANNOT_SUPERVISE_MORE_CULTISTS = 118, // You cannot supervise more than 5 Arrested Cultists at a time. + SPELL_CUSTOM_ERROR_REQUIRES_LEVEL_85 = 119, // You must reach level 85 to use this portal. + SPELL_CUSTOM_ERROR_MUST_BE_BELOW_35_HEALTH = 120, // Your target must be below 35% health. + SPELL_CUSTOM_ERROR_MUST_SELECT_TALENT_SPECIAL = 121, // You must select a talent specialization first. }; enum StealthType @@ -1232,7 +1295,8 @@ enum Mechanics MECHANIC_DISCOVERY = 28, MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block MECHANIC_SAPPED = 30, - MECHANIC_ENRAGED = 31 + MECHANIC_ENRAGED = 31, + MECHANIC_WOUNDED = 32, }; // Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967ca6) @@ -1473,7 +1537,7 @@ enum GameobjectTypes }; #define MAX_GAMEOBJECT_TYPE 36 // sending to client this or greater value can crash client. -#define MAX_GAMEOBJECT_DATA 24 // Max number of uint32 vars in gameobject_template data field +#define MAX_GAMEOBJECT_DATA 32 // Max number of uint32 vars in gameobject_template data field enum GameObjectFlags { @@ -2519,47 +2583,58 @@ uint32 const CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL = (1 << (CREATURE_TYPE_ME // CreatureFamily.dbc enum CreatureFamily { - CREATURE_FAMILY_WOLF = 1, - CREATURE_FAMILY_CAT = 2, - CREATURE_FAMILY_SPIDER = 3, - CREATURE_FAMILY_BEAR = 4, - CREATURE_FAMILY_BOAR = 5, - CREATURE_FAMILY_CROCOLISK = 6, - CREATURE_FAMILY_CARRION_BIRD = 7, - CREATURE_FAMILY_CRAB = 8, - CREATURE_FAMILY_GORILLA = 9, - CREATURE_FAMILY_HORSE_CUSTOM = 10, // not exist in DBC but used for horse like beasts in DB - CREATURE_FAMILY_RAPTOR = 11, - CREATURE_FAMILY_TALLSTRIDER = 12, - CREATURE_FAMILY_FELHUNTER = 15, - CREATURE_FAMILY_VOIDWALKER = 16, - CREATURE_FAMILY_SUCCUBUS = 17, - CREATURE_FAMILY_DOOMGUARD = 19, - CREATURE_FAMILY_SCORPID = 20, - CREATURE_FAMILY_TURTLE = 21, - CREATURE_FAMILY_IMP = 23, - CREATURE_FAMILY_BAT = 24, - CREATURE_FAMILY_HYENA = 25, - CREATURE_FAMILY_BIRD_OF_PREY = 26, - CREATURE_FAMILY_WIND_SERPENT = 27, - CREATURE_FAMILY_REMOTE_CONTROL = 28, - CREATURE_FAMILY_FELGUARD = 29, - CREATURE_FAMILY_DRAGONHAWK = 30, - CREATURE_FAMILY_RAVAGER = 31, - CREATURE_FAMILY_WARP_STALKER = 32, - CREATURE_FAMILY_SPOREBAT = 33, - CREATURE_FAMILY_NETHER_RAY = 34, - CREATURE_FAMILY_SERPENT = 35, - CREATURE_FAMILY_MOTH = 37, - CREATURE_FAMILY_CHIMAERA = 38, - CREATURE_FAMILY_DEVILSAUR = 39, - CREATURE_FAMILY_GHOUL = 40, - CREATURE_FAMILY_SILITHID = 41, - CREATURE_FAMILY_WORM = 42, - CREATURE_FAMILY_RHINO = 43, - CREATURE_FAMILY_WASP = 44, - CREATURE_FAMILY_CORE_HOUND = 45, - CREATURE_FAMILY_SPIRIT_BEAST = 46 + CREATURE_FAMILY_WOLF = 1, + CREATURE_FAMILY_CAT = 2, + CREATURE_FAMILY_SPIDER = 3, + CREATURE_FAMILY_BEAR = 4, + CREATURE_FAMILY_BOAR = 5, + CREATURE_FAMILY_CROCOLISK = 6, + CREATURE_FAMILY_CARRION_BIRD = 7, + CREATURE_FAMILY_CRAB = 8, + CREATURE_FAMILY_GORILLA = 9, + CREATURE_FAMILY_HORSE_CUSTOM = 10, // Does not exist in DBC but used for horse like beasts in DB + CREATURE_FAMILY_RAPTOR = 11, + CREATURE_FAMILY_TALLSTRIDER = 12, + CREATURE_FAMILY_FELHUNTER = 15, + CREATURE_FAMILY_VOIDWALKER = 16, + CREATURE_FAMILY_SUCCUBUS = 17, + CREATURE_FAMILY_DOOMGUARD = 19, + CREATURE_FAMILY_SCORPID = 20, + CREATURE_FAMILY_TURTLE = 21, + CREATURE_FAMILY_IMP = 23, + CREATURE_FAMILY_BAT = 24, + CREATURE_FAMILY_HYENA = 25, + CREATURE_FAMILY_BIRD_OF_PREY = 26, + CREATURE_FAMILY_WIND_SERPENT = 27, + CREATURE_FAMILY_REMOTE_CONTROL = 28, + CREATURE_FAMILY_FELGUARD = 29, + CREATURE_FAMILY_DRAGONHAWK = 30, + CREATURE_FAMILY_RAVAGER = 31, + CREATURE_FAMILY_WARP_STALKER = 32, + CREATURE_FAMILY_SPOREBAT = 33, + CREATURE_FAMILY_NETHER_RAY = 34, + CREATURE_FAMILY_SERPENT = 35, + CREATURE_FAMILY_MOTH = 37, + CREATURE_FAMILY_CHIMAERA = 38, + CREATURE_FAMILY_DEVILSAUR = 39, + CREATURE_FAMILY_GHOUL = 40, + CREATURE_FAMILY_SILITHID = 41, + CREATURE_FAMILY_WORM = 42, + CREATURE_FAMILY_RHINO = 43, + CREATURE_FAMILY_WASP = 44, + CREATURE_FAMILY_CORE_HOUND = 45, + CREATURE_FAMILY_SPIRIT_BEAST = 46, + CREATURE_FAMILY_WATER_ELEMENTAL = 49, + CREATURE_FAMILY_FOX = 50, + CREATURE_FAMILY_MONKEY = 51, + CREATURE_FAMILY_DOG = 52, + CREATURE_FAMILY_BEETLE = 53, + CREATURE_FAMILY_SHALE_SPIDER = 55, + CREATURE_FAMILY_ZOMBIE = 56, + CREATURE_FAMILY_BEETLE_OLD = 57, + CREATURE_FAMILY_SILITHID_2 = 59, + CREATURE_FAMILY_WASP_2 = 66, + CREATURE_FAMILY_HYDRA = 68, }; enum CreatureTypeFlags @@ -2598,6 +2673,18 @@ enum CreatureTypeFlags CREATURE_TYPEFLAGS_UNK31 = 0x80000000, }; +enum CreatureTypeFlags2 +{ + CREATURE_TYPEFLAGS_2_UNK1 = 0x00000001, + CREATURE_TYPEFLAGS_2_UNK2 = 0x00000002, + CREATURE_TYPEFLAGS_2_UNK3 = 0x00000004, + CREATURE_TYPEFLAGS_2_UNK4 = 0x00000008, + CREATURE_TYPEFLAGS_2_UNK5 = 0x00000010, + CREATURE_TYPEFLAGS_2_UNK6 = 0x00000020, + CREATURE_TYPEFLAGS_2_UNK7 = 0x00000040, + CREATURE_TYPEFLAGS_2_UNK8 = 0x00000080, +}; + enum CreatureEliteType { CREATURE_ELITE_NORMAL = 0, @@ -2638,7 +2725,12 @@ enum HolidayIds HOLIDAY_DAY_OF_DEAD = 409, HOLIDAY_CALL_TO_ARMS_IC = 420, HOLIDAY_LOVE_IS_IN_THE_AIR = 423, - HOLIDAY_KALU_AK_FISHING_DERBY = 424 + HOLIDAY_KALU_AK_FISHING_DERBY = 424, + HOLIDAY_CALL_TO_ARMS_BFG = 435, + HOLIDAY_CALL_TO_ARMS_TP = 436, + HOLIDAY_RATED_BG_15_VS_15 = 442, + HOLIDAY_RATED_BG_25_VS_25 = 443, + HOLIDAY_ANNIVERSARY_7_YEARS = 467, }; // values based at QuestInfo.dbc @@ -2701,6 +2793,11 @@ enum QuestSort QUEST_SORT_NOBLEGARDEN = 374, QUEST_SORT_PILGRIMS_BOUNTY = 375, QUEST_SORT_LOVE_IS_IN_THE_AIR = 376, + QUEST_SORT_ARCHAEOLOGY = 377, + QUEST_SORT_CHILDRENS_WEEK = 378, + QUEST_SORT_FIRELANDS_INVASION = 379, + QUEST_SORT_ZANDALARI = 380, + QUEST_SORT_ELEMENTAL_BONDS = 381, }; inline uint8 ClassByQuestSort(int32 QuestSort) @@ -2846,7 +2943,7 @@ enum SkillType SKILL_RACIAL_HUMAN = 754, SKILL_JEWELCRAFTING = 755, SKILL_RACIAL_BLOODELF = 756, - SKILL_PET_EVENT_RC = 758, + SKILL_PET_EVENT_RC = 758, // SkillCategory = -1 SKILL_LANG_DRAENEI = 759, SKILL_RACIAL_DRAENEI = 760, SKILL_PET_FELGUARD = 761, @@ -2874,10 +2971,34 @@ enum SkillType SKILL_PET_WASP = 785, SKILL_PET_EXOTIC_RHINO = 786, SKILL_PET_EXOTIC_CORE_HOUND = 787, - SKILL_PET_EXOTIC_SPIRIT_BEAST = 788 -}; - -#define MAX_SKILL_TYPE 789 + SKILL_PET_EXOTIC_SPIRIT_BEAST = 788, + SKILL_RACIAL_WORGEN = 789, + SKILL_RACIAL_GOBLIN = 790, + SKILL_LANG_WORGEN = 791, + SKILL_LANG_GOBLIN = 792, + SKILL_ARCHAEOLOGY = 794, + SKILL_GENERAL_HUNTER = 795, + SKILL_GENERAL_DEATH_KNIGHT = 796, + SKILL_GENERAL_ROGUE = 797, + SKILL_GENERAL_DRUID = 798, + SKILL_GENERAL_MAGE = 799, + SKILL_GENERAL_PALADIN = 800, + SKILL_GENERAL_SHAMAN = 801, + SKILL_GENERAL_WARLOCK = 802, + SKILL_GENERAL_WARRIOR = 803, + SKILL_GENERAL_PRIEST = 804, + SKILL_PET_WATER_ELEMENTAL = 805, + SKILL_PET_FOX = 808, + SKILL_ALL_GLYPHS = 810, + SKILL_PET_DOG = 811, + SKILL_PET_MONKEY = 815, + SKILL_PET_SHALE_SPIDER = 817, + SKILL_PET_BEETLE = 818, + SKILL_ALL_GUILD_PERKS = 821, + SKILL_PET_HYDRA = 824, +}; + +#define MAX_SKILL_TYPE 825 inline SkillType SkillByLockType(LockType locktype) { @@ -2908,12 +3029,14 @@ inline uint32 SkillByQuestSort(int32 QuestSort) case QUEST_SORT_FIRST_AID: return SKILL_FIRST_AID; case QUEST_SORT_JEWELCRAFTING: return SKILL_JEWELCRAFTING; case QUEST_SORT_INSCRIPTION: return SKILL_INSCRIPTION; + case QUEST_SORT_ARCHAEOLOGY: return SKILL_ARCHAEOLOGY; } return 0; } enum SkillCategory { + SKILL_CATEGORY_UNK1 = 0, SKILL_CATEGORY_ATTRIBUTES = 5, SKILL_CATEGORY_WEAPON = 6, SKILL_CATEGORY_CLASS = 7, @@ -2957,7 +3080,9 @@ enum TotemCategory TC_BLADED_PICKAXE = 168, TC_FLINT_AND_TINDER = 169, TC_RUNED_COBALT_ROD = 189, - TC_RUNED_TITANIUM_ROD = 190 + TC_RUNED_TITANIUM_ROD = 190, + TC_RUNED_ELEMENTIUM_ROD = 209, + TC_HIGH_POWERED_BOLT_GUN = 210, }; enum UnitDynFlags @@ -2992,7 +3117,7 @@ enum WeatherType enum ChatMsg { - CHAT_MSG_ADDON = 0xFFFFFFFF, + CHAT_MSG_ADDON = 0xFFFFFFFF, // -1 CHAT_MSG_SYSTEM = 0x00, CHAT_MSG_SAY = 0x01, CHAT_MSG_PARTY = 0x02, @@ -3016,6 +3141,7 @@ enum ChatMsg CHAT_MSG_CHANNEL_LIST = 0x14, CHAT_MSG_CHANNEL_NOTICE = 0x15, CHAT_MSG_CHANNEL_NOTICE_USER = 0x16, + // CHAT_MSG_TARGETICONS CHAT_MSG_AFK = 0x17, CHAT_MSG_DND = 0x18, CHAT_MSG_IGNORED = 0x19, @@ -3044,7 +3170,7 @@ enum ChatMsg CHAT_MSG_ACHIEVEMENT = 0x30, CHAT_MSG_GUILD_ACHIEVEMENT = 0x31, CHAT_MSG_ARENA_POINTS = 0x32, - CHAT_MSG_PARTY_LEADER = 0x33 + CHAT_MSG_PARTY_LEADER = 0x33, }; #define MAX_CHAT_MSG_TYPE 0x34 @@ -3062,14 +3188,14 @@ enum ChatLinkColors // Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask enum PetDiet { - PET_DIET_MEAT = 1, - PET_DIET_FISH = 2, - PET_DIET_CHEESE = 3, - PET_DIET_BREAD = 4, - PET_DIET_FUNGAS = 5, - PET_DIET_FRUIT = 6, - PET_DIET_RAW_MEAT = 7, - PET_DIET_RAW_FISH = 8 + PET_DIET_MEAT = 1, + PET_DIET_FISH = 2, + PET_DIET_CHEESE = 3, + PET_DIET_BREAD = 4, + PET_DIET_FUNGAS = 5, + PET_DIET_FRUIT = 6, + PET_DIET_RAW_MEAT = 7, + PET_DIET_RAW_FISH = 8 }; #define MAX_PET_DIET 9 @@ -3147,6 +3273,8 @@ enum SummonType SUMMON_TYPE_VEHICLE = 9, SUMMON_TYPE_VEHICLE2 = 10, SUMMON_TYPE_OBJECT = 11, + SUMMON_TYPE_UNK12 = 12, + SUMMON_TYPE_UNK13 = 13, }; enum EventId @@ -3156,121 +3284,121 @@ enum EventId 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, - - 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_LOCKED_ENFORCED = 0x22, - - 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 = 0x28, - ACCOUNT_CREATE_SUCCESS = 0x29, - ACCOUNT_CREATE_FAILED = 0x2A, - - 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_EXPANSION_CLASS = 0x3A, - CHAR_CREATE_LEVEL_REQUIREMENT = 0x3B, - CHAR_CREATE_UNIQUE_CLASS_LIMIT = 0x3C, - CHAR_CREATE_CHARACTER_IN_GUILD = 0x3D, - CHAR_CREATE_RESTRICTED_RACECLASS = 0x3E, - CHAR_CREATE_CHARACTER_CHOOSE_RACE = 0x3F, - CHAR_CREATE_CHARACTER_ARENA_LEADER = 0x40, - CHAR_CREATE_CHARACTER_DELETE_MAIL = 0x41, - CHAR_CREATE_CHARACTER_SWAP_FACTION = 0x42, - CHAR_CREATE_CHARACTER_RACE_ONLY = 0x43, - - CHAR_CREATE_CHARACTER_GOLD_LIMIT = 0x44, - - CHAR_CREATE_FORCE_LOGIN = 0x45, - - CHAR_DELETE_IN_PROGRESS = 0x46, - CHAR_DELETE_SUCCESS = 0x47, - CHAR_DELETE_FAILED = 0x48, - CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 0x49, - CHAR_DELETE_FAILED_GUILD_LEADER = 0x4A, - CHAR_DELETE_FAILED_ARENA_CAPTAIN = 0x4B, - - CHAR_LOGIN_IN_PROGRESS = 0x4C, - CHAR_LOGIN_SUCCESS = 0x4D, - CHAR_LOGIN_NO_WORLD = 0x4E, - CHAR_LOGIN_DUPLICATE_CHARACTER = 0x4F, - CHAR_LOGIN_NO_INSTANCES = 0x50, - CHAR_LOGIN_FAILED = 0x51, - CHAR_LOGIN_DISABLED = 0x52, - CHAR_LOGIN_NO_CHARACTER = 0x53, - CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x54, - CHAR_LOGIN_LOCKED_BY_BILLING = 0x55, - CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 0x56, - - CHAR_NAME_SUCCESS = 0x57, - CHAR_NAME_FAILURE = 0x58, - CHAR_NAME_NO_NAME = 0x59, - CHAR_NAME_TOO_SHORT = 0x5A, - CHAR_NAME_TOO_LONG = 0x5B, - CHAR_NAME_INVALID_CHARACTER = 0x5C, - CHAR_NAME_MIXED_LANGUAGES = 0x5D, - CHAR_NAME_PROFANE = 0x5E, - CHAR_NAME_RESERVED = 0x5F, - CHAR_NAME_INVALID_APOSTROPHE = 0x60, - CHAR_NAME_MULTIPLE_APOSTROPHES = 0x61, - CHAR_NAME_THREE_CONSECUTIVE = 0x62, - CHAR_NAME_INVALID_SPACE = 0x63, - CHAR_NAME_CONSECUTIVE_SPACES = 0x64, - CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x65, - CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x66, - CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x67 + RESPONSE_SUCCESS = 0, + RESPONSE_FAILURE = 1, + RESPONSE_CANCELLED = 2, + RESPONSE_DISCONNECTED = 3, + RESPONSE_FAILED_TO_CONNECT = 4, + RESPONSE_CONNECTED = 5, + RESPONSE_VERSION_MISMATCH = 6, + + CSTATUS_CONNECTING = 7, + CSTATUS_NEGOTIATING_SECURITY = 8, + CSTATUS_NEGOTIATION_COMPLETE = 9, + CSTATUS_NEGOTIATION_FAILED = 10, + CSTATUS_AUTHENTICATING = 11, + + AUTH_OK = 12, + AUTH_FAILED = 13, + AUTH_REJECT = 14, + AUTH_BAD_SERVER_PROOF = 15, + AUTH_UNAVAILABLE = 16, + AUTH_SYSTEM_ERROR = 17, + AUTH_BILLING_ERROR = 18, + AUTH_BILLING_EXPIRED = 19, + AUTH_VERSION_MISMATCH = 20, + AUTH_UNKNOWN_ACCOUNT = 21, + AUTH_INCORRECT_PASSWORD = 22, + AUTH_SESSION_EXPIRED = 23, + AUTH_SERVER_SHUTTING_DOWN = 24, + AUTH_ALREADY_LOGGING_IN = 25, + AUTH_LOGIN_SERVER_NOT_FOUND = 26, + AUTH_WAIT_QUEUE = 27, + AUTH_BANNED = 28, + AUTH_ALREADY_ONLINE = 29, + AUTH_NO_TIME = 30, + AUTH_DB_BUSY = 31, + AUTH_SUSPENDED = 32, + AUTH_PARENTAL_CONTROL = 33, + AUTH_LOCKED_ENFORCED = 34, + + REALM_LIST_IN_PROGRESS = 35, + REALM_LIST_SUCCESS = 36, + REALM_LIST_FAILED = 37, + REALM_LIST_INVALID = 38, + REALM_LIST_REALM_NOT_FOUND = 39, + + ACCOUNT_CREATE_IN_PROGRESS = 40, + ACCOUNT_CREATE_SUCCESS = 41, + ACCOUNT_CREATE_FAILED = 42, + + CHAR_LIST_RETRIEVING = 43, + CHAR_LIST_RETRIEVED = 44, + CHAR_LIST_FAILED = 45, + + CHAR_CREATE_IN_PROGRESS = 46, + CHAR_CREATE_SUCCESS = 47, + CHAR_CREATE_ERROR = 48, + CHAR_CREATE_FAILED = 49, + CHAR_CREATE_NAME_IN_USE = 50, + CHAR_CREATE_DISABLED = 51, + CHAR_CREATE_PVP_TEAMS_VIOLATION = 52, + CHAR_CREATE_SERVER_LIMIT = 53, + CHAR_CREATE_ACCOUNT_LIMIT = 54, + CHAR_CREATE_SERVER_QUEUE = 55, + CHAR_CREATE_ONLY_EXISTING = 56, + CHAR_CREATE_EXPANSION = 57, + CHAR_CREATE_EXPANSION_CLASS = 58, + CHAR_CREATE_LEVEL_REQUIREMENT = 59, + CHAR_CREATE_UNIQUE_CLASS_LIMIT = 60, + CHAR_CREATE_CHARACTER_IN_GUILD = 61, + CHAR_CREATE_RESTRICTED_RACECLASS = 62, + CHAR_CREATE_CHARACTER_CHOOSE_RACE = 63, + CHAR_CREATE_CHARACTER_ARENA_LEADER = 64, + CHAR_CREATE_CHARACTER_DELETE_MAIL = 65, + CHAR_CREATE_CHARACTER_SWAP_FACTION = 66, + CHAR_CREATE_CHARACTER_RACE_ONLY = 67, + CHAR_CREATE_CHARACTER_GOLD_LIMIT = 68, + CHAR_CREATE_FORCE_LOGIN = 69, + + CHAR_DELETE_IN_PROGRESS = 70, + CHAR_DELETE_SUCCESS = 71, + CHAR_DELETE_FAILED = 72, + CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 73, + CHAR_DELETE_FAILED_GUILD_LEADER = 74, + CHAR_DELETE_FAILED_ARENA_CAPTAIN = 75, + CHAR_DELETE_FAILED_HAS_HEIRLOOM_OR_MAIL = 76, + + CHAR_LOGIN_IN_PROGRESS = 77, + CHAR_LOGIN_SUCCESS = 78, + CHAR_LOGIN_NO_WORLD = 79, + CHAR_LOGIN_DUPLICATE_CHARACTER = 80, + CHAR_LOGIN_NO_INSTANCES = 81, + CHAR_LOGIN_FAILED = 82, + CHAR_LOGIN_DISABLED = 83, + CHAR_LOGIN_NO_CHARACTER = 84, + CHAR_LOGIN_LOCKED_FOR_TRANSFER = 85, + CHAR_LOGIN_LOCKED_BY_BILLING = 86, + CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 87, + CHAR_LOGIN_TEMPORARY_GM_LOCK = 88, + + CHAR_NAME_SUCCESS = 89, + CHAR_NAME_FAILURE = 90, + CHAR_NAME_NO_NAME = 91, + CHAR_NAME_TOO_SHORT = 92, + CHAR_NAME_TOO_LONG = 93, + CHAR_NAME_INVALID_CHARACTER = 94, + CHAR_NAME_MIXED_LANGUAGES = 95, + CHAR_NAME_PROFANE = 96, + CHAR_NAME_RESERVED = 97, + CHAR_NAME_INVALID_APOSTROPHE = 98, + CHAR_NAME_MULTIPLE_APOSTROPHES = 99, + CHAR_NAME_THREE_CONSECUTIVE = 100, + CHAR_NAME_INVALID_SPACE = 101, + CHAR_NAME_CONSECUTIVE_SPACES = 102, + CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 103, + CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 104, + CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 105, }; /// Ban function modes @@ -3292,23 +3420,31 @@ enum BanReturn // indexes of BattlemasterList.dbc enum BattlegroundTypeId { - BATTLEGROUND_TYPE_NONE = 0, // None - BATTLEGROUND_AV = 1, // Alterac Valley - BATTLEGROUND_WS = 2, // Warsong Gulch - BATTLEGROUND_AB = 3, // Arathi Basin - BATTLEGROUND_NA = 4, // Nagrand Arena - BATTLEGROUND_BE = 5, // Blade's Edge Arena - BATTLEGROUND_AA = 6, // All Arenas - BATTLEGROUND_EY = 7, // Eye of the Storm - BATTLEGROUND_RL = 8, // Ruins of Lordaernon - BATTLEGROUND_SA = 9, // Strand of the Ancients - BATTLEGROUND_DS = 10, // Dalaran Sewers - BATTLEGROUND_RV = 11, // Ring of Valor - BATTLEGROUND_IC = 30, // Isle of Conquest - BATTLEGROUND_RB = 32 // Random Battleground -}; - -#define MAX_BATTLEGROUND_TYPE_ID 33 + BATTLEGROUND_TYPE_NONE = 0, // None + BATTLEGROUND_AV = 1, // Alterac Valley + BATTLEGROUND_WS = 2, // Warsong Gulch + BATTLEGROUND_AB = 3, // Arathi Basin + BATTLEGROUND_NA = 4, // Nagrand Arena + BATTLEGROUND_BE = 5, // Blade's Edge Arena + BATTLEGROUND_AA = 6, // All Arenas + BATTLEGROUND_EY = 7, // Eye of the Storm + BATTLEGROUND_RL = 8, // Ruins of Lordaernon + BATTLEGROUND_SA = 9, // Strand of the Ancients + BATTLEGROUND_DS = 10, // Dalaran Sewers + BATTLEGROUND_RV = 11, // Ring of Valor + BATTLEGROUND_IC = 30, // Isle of Conquest + BATTLEGROUND_RB = 32, // Random Battleground + BATTLEGROUND_RATED_10_VS_10 = 100, // Rated BG 10 vs 10 + BATTLEGROUND_RATED_15_VS_15 = 101, // Rated BG 15 vs 15 + BATTLEGROUND_RATED_25_VS_25 = 102, // Rated BG 25 vs 25 + BATTLEGROUND_TP = 108, // Twin Peaks + BATTLEGROUND_BFG = 120, // Battle For Gilneas + // 441 = "Icecrown Citadel" + // 443 = "The Ruby Sanctum" + // 656 = "Rated Eye of the Storm" +}; + +#define MAX_BATTLEGROUND_TYPE_ID 121 enum MailResponseType { @@ -3357,35 +3493,44 @@ enum SpellFamilyNames // 14 - unused SPELLFAMILY_DEATHKNIGHT = 15, // 16 - unused - SPELLFAMILY_PET = 17 + SPELLFAMILY_PET = 17, + SPELLFAMILY_UNK3 = 50, }; enum TradeStatus { - TRADE_STATUS_BUSY = 0, - TRADE_STATUS_BEGIN_TRADE = 1, - TRADE_STATUS_OPEN_WINDOW = 2, - TRADE_STATUS_TRADE_CANCELED = 3, - TRADE_STATUS_TRADE_ACCEPT = 4, - TRADE_STATUS_BUSY_2 = 5, - TRADE_STATUS_NO_TARGET = 6, - TRADE_STATUS_BACK_TO_TRADE = 7, - TRADE_STATUS_TRADE_COMPLETE = 8, - // 9? - TRADE_STATUS_TARGET_TO_FAR = 10, - TRADE_STATUS_WRONG_FACTION = 11, - TRADE_STATUS_CLOSE_WINDOW = 12, - // 13? - TRADE_STATUS_IGNORE_YOU = 14, - TRADE_STATUS_YOU_STUNNED = 15, - TRADE_STATUS_TARGET_STUNNED = 16, - TRADE_STATUS_YOU_DEAD = 17, - TRADE_STATUS_TARGET_DEAD = 18, - TRADE_STATUS_YOU_LOGOUT = 19, - TRADE_STATUS_TARGET_LOGOUT = 20, - TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action - TRADE_STATUS_ONLY_CONJURED = 22, // You can only trade conjured items... (cross realm BG related). - TRADE_STATUS_NOT_ELIGIBLE = 23 // Related to trading soulbound loot items + TRADE_STATUS_OPEN_WINDOW = 0, + // 1 - Related to EVENT_PLAYER_MONEY + TRADE_STATUS_NOT_ELIGIBLE = 2, // Related to trading soulbound loot items + TRADE_STATUS_YOU_LOGOUT = 3, + TRADE_STATUS_IGNORE_YOU = 4, + TRADE_STATUS_TARGET_DEAD = 5, + TRADE_STATUS_TRADE_ACCEPT = 6, + TRADE_STATUS_TARGET_LOGOUT = 7, + // 8 - nonexistent + TRADE_STATUS_TRADE_COMPLETE = 9, + TRADE_STATUS_TRIAL_ACCOUNT = 10, // Trial accounts can not perform that action + // 11 - nonexistent + TRADE_STATUS_BEGIN_TRADE = 12, + TRADE_STATUS_YOU_DEAD = 13, + // 14 - nonexistent + // 15 - nonexistent + TRADE_STATUS_TARGET_TO_FAR = 16, + TRADE_STATUS_NO_TARGET = 17, + TRADE_STATUS_BUSY_2 = 18, + TRADE_STATUS_CURRENCY_NOT_TRADABLE = 19, // new 4.x + TRADE_STATUS_WRONG_FACTION = 20, + TRADE_STATUS_BUSY = 21, + // 22 - equivalent to 335 unk status 9 + TRADE_STATUS_TRADE_CANCELED = 23, + TRADE_STATUS_CURRENCY = 24, // new 4.x + TRADE_STATUS_BACK_TO_TRADE = 25, + TRADE_STATUS_ONLY_CONJURED = 26, // You can only trade conjured items... (cross realm BG related). + TRADE_STATUS_YOU_STUNNED = 27, + // 28 - nonexistent + TRADE_STATUS_TARGET_STUNNED = 29, + // 30 - nonexistent + TRADE_STATUS_CLOSE_WINDOW = 31, }; enum XPColorChar @@ -3522,4 +3667,24 @@ enum CalendarError // Calendar - end +#define VOID_STORAGE_UNLOCK 100*GOLD +#define VOID_STORAGE_STORE_ITEM 25*GOLD +#define VOID_STORAGE_MAX_DEPOSIT 9 +#define VOID_STORAGE_MAX_WITHDRAW 9 +#define VOID_STORAGE_MAX_SLOT 80 + +enum VoidTransferError +{ + VOID_TRANSFER_ERROR_NO_ERROR = 0, + VOID_TRANSFER_ERROR_INTERNAL_ERROR_1 = 1, + VOID_TRANSFER_ERROR_INTERNAL_ERROR_2 = 2, + VOID_TRANSFER_ERROR_FULL = 3, + VOID_TRANSFER_ERROR_INTERNAL_ERROR_3 = 4, + VOID_TRANSFER_ERROR_INTERNAL_ERROR_4 = 5, + VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY = 6, + VOID_TRANSFER_ERROR_INVENTORY_FULL = 7, + VOID_TRANSFER_ERROR_INTERNAL_ERROR_5 = 8, + VOID_TRANSFER_ERROR_TRANSFER_UNKNOWN = 9, +}; + #endif diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 12b85b10922..6de76a1d9bc 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -237,6 +237,8 @@ void FlightPathMovementGenerator::Reset(Player & player) } init.SetFirstPointId(GetCurrentNode()); init.SetFly(); + init.SetSmooth(); + init.SetWalk(true); init.SetVelocity(PLAYER_FLIGHT_SPEED); init.Launch(); } diff --git a/src/server/game/Movement/MovementStructures.h b/src/server/game/Movement/MovementStructures.h new file mode 100644 index 00000000000..0241edc1706 --- /dev/null +++ b/src/server/game/Movement/MovementStructures.h @@ -0,0 +1,1916 @@ +/* +* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/> +* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _MOVEMENT_STRUCTURES_H +#define _MOVEMENT_STRUCTURES_H + +enum MovementStatusElements +{ + MSEHasGuidByte0, + MSEHasGuidByte1, + MSEHasGuidByte2, + MSEHasGuidByte3, + MSEHasGuidByte4, + MSEHasGuidByte5, + MSEHasGuidByte6, + MSEHasGuidByte7, + MSEHasMovementFlags, + MSEHasMovementFlags2, + MSEHasTimestamp, + MSEHasOrientation, + MSEHasTransportData, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte7, + MSEHasTransportTime2, + MSEHasTransportTime3, + MSEHasPitch, + MSEHasFallData, + MSEHasFallDirection, + MSEHasSplineElevation, + MSEHasSpline, + + MSEGuidByte0, + MSEGuidByte1, + MSEGuidByte2, + MSEGuidByte3, + MSEGuidByte4, + MSEGuidByte5, + MSEGuidByte6, + MSEGuidByte7, + MSEMovementFlags, + MSEMovementFlags2, + MSETimestamp, + MSEPositionX, + MSEPositionY, + MSEPositionZ, + MSEOrientation, + MSETransportGuidByte0, + MSETransportGuidByte1, + MSETransportGuidByte2, + MSETransportGuidByte3, + MSETransportGuidByte4, + MSETransportGuidByte5, + MSETransportGuidByte6, + MSETransportGuidByte7, + MSETransportPositionX, + MSETransportPositionY, + MSETransportPositionZ, + MSETransportOrientation, + MSETransportSeat, + MSETransportTime, + MSETransportTime2, + MSETransportTime3, + MSEPitch, + MSEFallTime, + MSEFallVerticalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSESplineElevation, + + // Special + MSEZeroBit, // writes bit value 1 or skips read bit + MSEOneBit, // writes bit value 0 or skips read bit + MSEEnd, // marks end of parsing + MSE_COUNT +}; + +//4.3.4 +MovementStatusElements PlayerMoveSequence[] = +{ + MSEHasFallData, + MSEHasGuidByte3, + MSEHasGuidByte6, + MSEHasMovementFlags2, + MSEHasSpline, + MSEHasTimestamp, + MSEHasGuidByte0, + MSEHasGuidByte1, + MSEMovementFlags2, + MSEHasGuidByte7, + MSEHasMovementFlags, + MSEHasOrientation, + MSEHasGuidByte2, + MSEHasSplineElevation, + MSEZeroBit, + MSEHasGuidByte4, + MSEHasFallDirection, + MSEHasGuidByte5, + MSEHasTransportData, + MSEMovementFlags, + MSEHasTransportGuidByte3, + MSEHasTransportTime3, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte4, + MSEHasTransportTime2, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte2, + MSEHasPitch, + MSEGuidByte5, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallVerticalSpeed, + MSEFallTime, + MSESplineElevation, + MSEGuidByte7, + MSEPositionY, + MSEGuidByte3, + MSETransportTime3, + MSETransportGuidByte6, + MSETransportSeat, + MSETransportGuidByte5, + MSETransportPositionX, + MSETransportGuidByte1, + MSETransportOrientation, + MSETransportGuidByte2, + MSETransportTime2, + MSETransportGuidByte0, + MSETransportPositionZ, + MSETransportGuidByte7, + MSETransportGuidByte4, + MSETransportGuidByte3, + MSETransportPositionY, + MSETransportTime, + MSEGuidByte4, + MSEPositionX, + MSEGuidByte6, + MSEPositionZ, + MSETimestamp, + MSEGuidByte2, + MSEPitch, + MSEGuidByte0, + MSEOrientation, + MSEGuidByte1, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementFallLandSequence[] = +{ + MSEPositionX, + MSEPositionY, + MSEPositionZ, + MSEHasTransportData, + MSEHasGuidByte7, + MSEHasGuidByte1, + MSEHasMovementFlags2, + MSEHasGuidByte3, + MSEHasSplineElevation, + MSEHasOrientation, + MSEHasGuidByte6, + MSEHasTimestamp, + MSEZeroBit, + MSEHasPitch, + MSEHasGuidByte4, + MSEHasSpline, + MSEHasGuidByte5, + MSEHasMovementFlags, + MSEHasFallData, + MSEHasGuidByte0, + MSEHasGuidByte2, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte2, + MSEHasTransportTime3, + MSEHasTransportTime2, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte7, + MSEMovementFlags2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte1, + MSEGuidByte7, + MSEGuidByte4, + MSEGuidByte3, + MSEGuidByte6, + MSEGuidByte0, + MSEGuidByte2, + MSEGuidByte5, + MSETransportTime, + MSETransportPositionZ, + MSETransportPositionY, + MSETransportPositionX, + MSETransportGuidByte5, + MSETransportTime3, + MSETransportGuidByte1, + MSETransportSeat, + MSETransportTime2, + MSETransportGuidByte4, + MSETransportOrientation, + MSETransportGuidByte0, + MSETransportGuidByte7, + MSETransportGuidByte3, + MSETransportGuidByte6, + MSETransportGuidByte2, + MSEFallVerticalSpeed, + MSEFallTime, + MSEFallCosAngle, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSESplineElevation, + MSETimestamp, + MSEPitch, + MSEOrientation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementHeartBeatSequence[] = +{ + MSEPositionZ, + MSEPositionX, + MSEPositionY, + MSEHasPitch, + MSEHasTimestamp, + MSEHasFallData, + MSEHasMovementFlags2, + MSEHasTransportData, + MSEHasGuidByte7, + MSEHasGuidByte1, + MSEHasGuidByte0, + MSEHasGuidByte4, + MSEHasGuidByte2, + MSEHasOrientation, + MSEHasGuidByte5, + MSEHasGuidByte3, + MSEHasSplineElevation, + MSEHasSpline, + MSEZeroBit, + MSEHasGuidByte6, + MSEHasMovementFlags, + MSEHasTransportTime3, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte2, + MSEHasTransportTime2, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte1, + MSEHasFallDirection, + MSEMovementFlags, + MSEMovementFlags2, + MSEGuidByte3, + MSEGuidByte6, + MSEGuidByte1, + MSEGuidByte7, + MSEGuidByte2, + MSEGuidByte5, + MSEGuidByte0, + MSEGuidByte4, + MSETransportPositionZ, + MSETransportSeat, + MSETransportOrientation, + MSETransportGuidByte4, + MSETransportPositionY, + MSETransportTime, + MSETransportPositionX, + MSETransportGuidByte5, + MSETransportGuidByte1, + MSETransportGuidByte3, + MSETransportGuidByte7, + MSETransportTime3, + MSETransportTime2, + MSETransportGuidByte2, + MSETransportGuidByte0, + MSETransportGuidByte6, + MSEOrientation, + MSEFallVerticalSpeed, + MSEFallTime, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallCosAngle, + MSEPitch, + MSESplineElevation, + MSETimestamp, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementJumpSequence[] = +{ + MSEPositionY, + MSEPositionX, + MSEPositionZ, + MSEHasTimestamp, + MSEHasGuidByte5, + MSEHasMovementFlags, + MSEHasGuidByte4, + MSEHasGuidByte6, + MSEHasMovementFlags2, + MSEHasGuidByte0, + MSEHasTransportData, + MSEHasGuidByte3, + MSEHasPitch, + MSEHasGuidByte7, + MSEHasFallData, + MSEHasSpline, + MSEHasOrientation, + MSEHasGuidByte1, + MSEHasSplineElevation, + MSEZeroBit, + MSEHasGuidByte2, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte4, + MSEHasTransportTime3, + MSEHasTransportTime2, + MSEHasTransportGuidByte2, + MSEHasFallDirection, + MSEMovementFlags, + MSEMovementFlags2, + MSEGuidByte6, + MSEGuidByte5, + MSEGuidByte4, + MSEGuidByte0, + MSEGuidByte2, + MSEGuidByte3, + MSEGuidByte7, + MSEGuidByte1, + MSETransportGuidByte1, + MSETransportGuidByte7, + MSETransportPositionX, + MSETransportGuidByte4, + MSETransportTime3, + MSETransportGuidByte0, + MSETransportOrientation, + MSETransportTime2, + MSETransportTime, + MSETransportGuidByte6, + MSETransportPositionZ, + MSETransportSeat, + MSETransportPositionY, + MSETransportGuidByte3, + MSETransportGuidByte2, + MSETransportGuidByte5, + MSEPitch, + MSETimestamp, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallVerticalSpeed, + MSEFallTime, + MSESplineElevation, + MSEOrientation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementSetFacingSequence[] = +{ + MSEPositionX, + MSEPositionY, + MSEPositionZ, + MSEHasGuidByte6, + MSEHasTransportData, + MSEHasGuidByte4, + MSEHasSpline, + MSEHasGuidByte0, + MSEHasOrientation, + MSEHasTimestamp, + MSEHasPitch, + MSEHasMovementFlags2, + MSEHasGuidByte5, + MSEHasGuidByte7, + MSEHasGuidByte2, + MSEHasFallData, + MSEHasSplineElevation, + MSEHasMovementFlags, + MSEHasGuidByte3, + MSEZeroBit, + MSEHasGuidByte1, + MSEHasTransportTime3, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte0, + MSEHasTransportTime2, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte1, + MSEHasFallDirection, + MSEMovementFlags2, + MSEMovementFlags, + MSEGuidByte6, + MSEGuidByte7, + MSEGuidByte2, + MSEGuidByte0, + MSEGuidByte4, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte3, + MSETransportGuidByte0, + MSETransportPositionX, + MSETransportGuidByte1, + MSETransportTime2, + MSETransportGuidByte4, + MSETransportPositionZ, + MSETransportOrientation, + MSETransportGuidByte2, + MSETransportTime3, + MSETransportGuidByte3, + MSETransportSeat, + MSETransportPositionY, + MSETransportGuidByte5, + MSETransportGuidByte6, + MSETransportTime, + MSETransportGuidByte7, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallCosAngle, + MSEFallTime, + MSEFallVerticalSpeed, + MSESplineElevation, + MSEOrientation, + MSETimestamp, + MSEPitch, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementSetPitchSequence[] = +{ + MSEPositionX, + MSEPositionZ, + MSEPositionY, + MSEHasFallData, + MSEHasMovementFlags, + MSEHasGuidByte1, + MSEHasOrientation, + MSEHasGuidByte7, + MSEHasGuidByte3, + MSEHasMovementFlags2, + MSEHasTransportData, + MSEHasSplineElevation, + MSEHasGuidByte6, + MSEHasPitch, + MSEHasGuidByte4, + MSEHasSpline, + MSEHasGuidByte2, + MSEZeroBit, + MSEHasTimestamp, + MSEHasGuidByte0, + MSEHasGuidByte5, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte5, + MSEHasTransportTime3, + MSEHasTransportGuidByte7, + MSEHasTransportTime2, + MSEMovementFlags2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte3, + MSEGuidByte7, + MSEGuidByte1, + MSEGuidByte6, + MSEGuidByte0, + MSEGuidByte5, + MSEGuidByte2, + MSEGuidByte4, + MSETransportGuidByte4, + MSETransportGuidByte3, + MSETransportGuidByte6, + MSETransportOrientation, + MSETransportGuidByte1, + MSETransportTime3, + MSETransportTime, + MSETransportGuidByte2, + MSETransportPositionZ, + MSETransportGuidByte0, + MSETransportTime2, + MSETransportPositionY, + MSETransportGuidByte5, + MSETransportSeat, + MSETransportGuidByte7, + MSETransportPositionX, + MSEFallVerticalSpeed, + MSEFallTime, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEPitch, + MSESplineElevation, + MSETimestamp, + MSEOrientation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartBackwardSequence[] = +{ + MSEPositionX, + MSEPositionZ, + MSEPositionY, + MSEHasTransportData, + MSEHasGuidByte3, + MSEHasGuidByte0, + MSEHasGuidByte2, + MSEHasTimestamp, + MSEHasGuidByte7, + MSEHasPitch, + MSEZeroBit, + MSEHasMovementFlags, + MSEHasOrientation, + MSEHasSpline, + MSEHasMovementFlags2, + MSEHasFallData, + MSEHasGuidByte5, + MSEHasGuidByte1, + MSEHasGuidByte4, + MSEHasGuidByte6, + MSEHasSplineElevation, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte1, + MSEHasTransportTime2, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte4, + MSEHasTransportTime3, + MSEMovementFlags, + MSEMovementFlags2, + MSEHasFallDirection, + MSEGuidByte6, + MSEGuidByte7, + MSEGuidByte4, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte0, + MSEGuidByte2, + MSEGuidByte3, + MSETransportPositionZ, + MSETransportGuidByte2, + MSETransportTime3, + MSETransportGuidByte0, + MSETransportGuidByte5, + MSETransportPositionY, + MSETransportGuidByte1, + MSETransportPositionX, + MSETransportTime2, + MSETransportGuidByte4, + MSETransportOrientation, + MSETransportSeat, + MSETransportGuidByte7, + MSETransportTime, + MSETransportGuidByte6, + MSETransportGuidByte3, + MSEPitch, + MSETimestamp, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallCosAngle, + MSEFallVerticalSpeed, + MSEFallTime, + MSEOrientation, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartForwardSequence[] = +{ + MSEPositionY, + MSEPositionZ, + MSEPositionX, + MSEHasGuidByte5, + MSEHasGuidByte2, + MSEHasGuidByte0, + MSEZeroBit, + MSEHasMovementFlags, + MSEHasGuidByte7, + MSEHasGuidByte3, + MSEHasGuidByte1, + MSEHasOrientation, + MSEHasGuidByte6, + MSEHasSpline, + MSEHasSplineElevation, + MSEHasGuidByte4, + MSEHasTransportData, + MSEHasTimestamp, + MSEHasPitch, + MSEHasMovementFlags2, + MSEHasFallData, + MSEMovementFlags, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte1, + MSEHasTransportTime3, + MSEHasTransportTime2, + MSEHasFallDirection, + MSEMovementFlags2, + MSEGuidByte2, + MSEGuidByte4, + MSEGuidByte6, + MSEGuidByte1, + MSEGuidByte7, + MSEGuidByte3, + MSEGuidByte5, + MSEGuidByte0, + MSEFallVerticalSpeed, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallTime, + MSETransportGuidByte3, + MSETransportPositionY, + MSETransportPositionZ, + MSETransportGuidByte1, + MSETransportGuidByte4, + MSETransportGuidByte7, + MSETransportOrientation, + MSETransportGuidByte2, + MSETransportPositionX, + MSETransportGuidByte5, + MSETransportTime3, + MSETransportTime, + MSETransportGuidByte6, + MSETransportGuidByte0, + MSETransportSeat, + MSETransportTime2, + MSESplineElevation, + MSEPitch, + MSEOrientation, + MSETimestamp, + + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartStrafeLeftSequence[] = +{ + MSEPositionZ, + MSEPositionX, + MSEPositionY, + MSEHasSplineElevation, + MSEHasGuidByte5, + MSEHasPitch, + MSEHasGuidByte6, + MSEHasTimestamp, + MSEHasGuidByte1, + MSEZeroBit, + MSEHasGuidByte4, + MSEHasGuidByte0, + MSEHasGuidByte2, + MSEHasFallData, + MSEHasOrientation, + MSEHasGuidByte3, + MSEHasMovementFlags2, + MSEHasGuidByte7, + MSEHasSpline, + MSEHasMovementFlags, + MSEHasTransportData, + MSEHasFallDirection, + MSEHasTransportTime2, + MSEHasTransportGuidByte7, + MSEHasTransportTime3, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte0, + MSEMovementFlags, + MSEMovementFlags2, + MSEGuidByte2, + MSEGuidByte6, + MSEGuidByte3, + MSEGuidByte1, + MSEGuidByte0, + MSEGuidByte7, + MSEGuidByte4, + MSEGuidByte5, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallTime, + MSEFallVerticalSpeed, + MSETransportSeat, + MSETransportGuidByte2, + MSETransportTime2, + MSETransportGuidByte3, + MSETransportPositionZ, + MSETransportTime3, + MSETransportGuidByte0, + MSETransportGuidByte7, + MSETransportPositionY, + MSETransportGuidByte5, + MSETransportGuidByte1, + MSETransportOrientation, + MSETransportTime, + MSETransportGuidByte6, + MSETransportGuidByte4, + MSETransportPositionX, + MSETimestamp, + MSEOrientation, + MSEPitch, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartStrafeRightSequence[] = +{ + MSEPositionY, + MSEPositionX, + MSEPositionZ, + MSEHasPitch, + MSEHasGuidByte1, + MSEHasOrientation, + MSEHasGuidByte4, + MSEHasSpline, + MSEZeroBit, + MSEHasGuidByte5, + MSEHasFallData, + MSEHasSplineElevation, + MSEHasTimestamp, + MSEHasMovementFlags, + MSEHasGuidByte2, + MSEHasGuidByte7, + MSEHasGuidByte6, + MSEHasGuidByte3, + MSEHasMovementFlags2, + MSEHasTransportData, + MSEHasGuidByte0, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte0, + MSEHasTransportTime2, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte4, + MSEHasTransportTime3, + MSEMovementFlags2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte7, + MSEGuidByte5, + MSEGuidByte3, + MSEGuidByte1, + MSEGuidByte2, + MSEGuidByte4, + MSEGuidByte6, + MSEGuidByte0, + MSETransportGuidByte5, + MSETransportGuidByte1, + MSETransportGuidByte6, + MSETransportPositionY, + MSETransportOrientation, + MSETransportGuidByte0, + MSETransportGuidByte2, + MSETransportSeat, + MSETransportPositionX, + MSETransportTime3, + MSETransportTime, + MSETransportGuidByte4, + MSETransportGuidByte7, + MSETransportTime2, + MSETransportPositionZ, + MSETransportGuidByte3, + MSEPitch, + MSEOrientation, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallTime, + MSEFallVerticalSpeed, + MSETimestamp, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartTurnLeftSequence[] = +{ + MSEPositionY, + MSEPositionX, + MSEPositionZ, + MSEZeroBit, + MSEHasGuidByte1, + MSEHasOrientation, + MSEHasSpline, + MSEHasMovementFlags, + MSEHasGuidByte4, + MSEHasGuidByte2, + MSEHasMovementFlags2, + MSEHasGuidByte5, + MSEHasGuidByte7, + MSEHasTransportData, + MSEHasGuidByte6, + MSEHasSplineElevation, + MSEHasGuidByte0, + MSEHasGuidByte3, + MSEHasPitch, + MSEHasTimestamp, + MSEHasFallData, + MSEMovementFlags2, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte0, + MSEHasTransportTime2, + MSEHasTransportGuidByte2, + MSEHasTransportTime3, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte6, + MSEHasFallDirection, + MSEMovementFlags, + MSEGuidByte0, + MSEGuidByte4, + MSEGuidByte7, + MSEGuidByte5, + MSEGuidByte6, + MSEGuidByte3, + MSEGuidByte2, + MSEGuidByte1, + MSEFallSinAngle, + MSEFallCosAngle, + MSEFallHorizontalSpeed, + MSEFallVerticalSpeed, + MSEFallTime, + MSETransportGuidByte0, + MSETransportPositionX, + MSETransportTime, + MSETransportSeat, + MSETransportPositionZ, + MSETransportGuidByte4, + MSETransportOrientation, + MSETransportGuidByte2, + MSETransportGuidByte6, + MSETransportGuidByte1, + MSETransportGuidByte3, + MSETransportPositionY, + MSETransportTime3, + MSETransportTime2, + MSETransportGuidByte5, + MSETransportGuidByte7, + MSETimestamp, + MSEPitch, + MSEOrientation, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartTurnRightSequence[] = +{ + MSEPositionX, + MSEPositionZ, + MSEPositionY, + MSEHasGuidByte3, + MSEHasGuidByte5, + MSEHasMovementFlags, + MSEHasSpline, + MSEHasGuidByte0, + MSEHasOrientation, + MSEHasTransportData, + MSEHasGuidByte7, + MSEZeroBit, + MSEHasMovementFlags2, + MSEHasGuidByte1, + MSEHasTimestamp, + MSEHasGuidByte6, + MSEHasGuidByte2, + MSEHasGuidByte4, + MSEHasSplineElevation, + MSEHasPitch, + MSEHasFallData, + MSEHasTransportGuidByte1, + MSEHasTransportTime2, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte7, + MSEHasTransportTime3, + MSEMovementFlags2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte5, + MSEGuidByte0, + MSEGuidByte7, + MSEGuidByte3, + MSEGuidByte2, + MSEGuidByte1, + MSEGuidByte4, + MSEGuidByte6, + MSETransportPositionY, + MSETransportGuidByte0, + MSETransportGuidByte4, + MSETransportGuidByte1, + MSETransportGuidByte6, + MSETransportGuidByte2, + MSETransportSeat, + MSETransportOrientation, + MSETransportGuidByte5, + MSETransportTime3, + MSETransportPositionZ, + MSETransportPositionX, + MSETransportTime, + MSETransportGuidByte7, + MSETransportGuidByte3, + MSETransportTime2, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallCosAngle, + MSEFallTime, + MSEFallVerticalSpeed, + MSEPitch, + MSEOrientation, + MSESplineElevation, + MSETimestamp, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStopSequence[] = +{ + MSEPositionX, + MSEPositionY, + MSEPositionZ, + MSEHasGuidByte3, + MSEHasGuidByte6, + MSEHasSplineElevation, + MSEHasSpline, + MSEHasOrientation, + MSEHasGuidByte7, + MSEHasMovementFlags, + MSEHasGuidByte5, + MSEHasFallData, + MSEHasMovementFlags2, + MSEHasTransportData, + MSEHasTimestamp, + MSEHasGuidByte4, + MSEHasGuidByte1, + MSEZeroBit, + MSEHasGuidByte2, + MSEHasGuidByte0, + MSEHasPitch, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte5, + MSEHasTransportTime2, + MSEHasTransportTime3, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte2, + MSEMovementFlags, + MSEMovementFlags2, + MSEHasFallDirection, + MSEGuidByte6, + MSEGuidByte3, + MSEGuidByte0, + MSEGuidByte4, + MSEGuidByte2, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte7, + MSETransportGuidByte4, + MSETransportGuidByte7, + MSETransportTime, + MSETransportSeat, + MSETransportPositionZ, + MSETransportTime3, + MSETransportGuidByte2, + MSETransportGuidByte0, + MSETransportPositionY, + MSETransportGuidByte1, + MSETransportGuidByte3, + MSETransportTime2, + MSETransportPositionX, + MSETransportOrientation, + MSETransportGuidByte5, + MSETransportGuidByte6, + MSETimestamp, + MSEOrientation, + MSEPitch, + MSESplineElevation, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallVerticalSpeed, + MSEFallTime, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStopStrafeSequence[] = +{ + MSEPositionY, + MSEPositionZ, + MSEPositionX, + MSEHasPitch, + MSEHasTimestamp, + MSEHasGuidByte2, + MSEHasFallData, + MSEHasGuidByte7, + MSEHasSplineElevation, + MSEHasGuidByte3, + MSEHasOrientation, + MSEHasMovementFlags2, + MSEHasTransportData, + MSEHasMovementFlags, + MSEHasSpline, + MSEHasGuidByte0, + MSEZeroBit, + MSEHasGuidByte6, + MSEHasGuidByte5, + MSEHasGuidByte1, + MSEHasGuidByte4, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte5, + MSEHasTransportTime2, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte3, + MSEHasTransportTime3, + MSEMovementFlags, + MSEHasFallDirection, + MSEMovementFlags2, + MSEGuidByte2, + MSEGuidByte7, + MSEGuidByte3, + MSEGuidByte4, + MSEGuidByte5, + MSEGuidByte6, + MSEGuidByte1, + MSEGuidByte0, + MSETransportSeat, + MSETransportGuidByte6, + MSETransportPositionZ, + MSETransportTime3, + MSETransportGuidByte1, + MSETransportGuidByte3, + MSETransportGuidByte2, + MSETransportGuidByte4, + MSETransportGuidByte5, + MSETransportTime, + MSETransportOrientation, + MSETransportPositionX, + MSETransportGuidByte0, + MSETransportPositionY, + MSETransportTime2, + MSETransportGuidByte7, + MSEFallCosAngle, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallTime, + MSEFallVerticalSpeed, + MSESplineElevation, + MSEOrientation, + MSEPitch, + MSETimestamp, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStopTurnSequence[] = +{ + MSEPositionX, + MSEPositionZ, + MSEPositionY, + MSEHasGuidByte5, + MSEHasGuidByte4, + MSEHasFallData, + MSEZeroBit, + MSEHasGuidByte1, + MSEHasGuidByte0, + MSEHasSpline, + MSEHasMovementFlags, + MSEHasGuidByte2, + MSEHasGuidByte6, + MSEHasPitch, + MSEHasTransportData, + MSEHasGuidByte3, + MSEHasSplineElevation, + MSEHasTimestamp, + MSEHasMovementFlags2, + MSEHasOrientation, + MSEHasGuidByte7, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte7, + MSEHasTransportTime3, + MSEHasTransportGuidByte4, + MSEHasTransportTime2, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte1, + MSEHasFallDirection, + MSEMovementFlags, + MSEMovementFlags2, + MSEGuidByte3, + MSEGuidByte2, + MSEGuidByte6, + MSEGuidByte4, + MSEGuidByte0, + MSEGuidByte7, + MSEGuidByte1, + MSEGuidByte5, + MSESplineElevation, + MSETransportPositionX, + MSETransportGuidByte5, + MSETransportSeat, + MSETransportGuidByte2, + MSETransportGuidByte3, + MSETransportOrientation, + MSETransportTime2, + MSETransportTime3, + MSETransportGuidByte7, + MSETransportGuidByte1, + MSETransportGuidByte0, + MSETransportGuidByte4, + MSETransportPositionY, + MSETransportPositionZ, + MSETransportTime, + MSETransportGuidByte6, + MSEFallTime, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallVerticalSpeed, + MSETimestamp, + MSEPitch, + MSEOrientation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartAscendSequence[] = +{ + MSEPositionX, + MSEPositionY, + MSEPositionZ, + MSEHasGuidByte0, + MSEHasGuidByte1, + MSEHasGuidByte7, + MSEZeroBit, + MSEHasGuidByte5, + MSEHasTransportData, + MSEHasGuidByte2, + MSEHasSplineElevation, + MSEHasFallData, + MSEHasSpline, + MSEHasGuidByte3, + MSEHasMovementFlags2, + MSEHasGuidByte6, + MSEHasMovementFlags, + MSEHasPitch, + MSEHasTimestamp, + MSEHasOrientation, + MSEHasGuidByte4, + MSEMovementFlags, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte2, + MSEHasTransportTime3, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte4, + MSEHasTransportTime2, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte7, + MSEMovementFlags2, + MSEHasFallDirection, + MSEGuidByte6, + MSEGuidByte3, + MSEGuidByte1, + MSEGuidByte4, + MSEGuidByte2, + MSEGuidByte0, + MSEGuidByte5, + MSEGuidByte7, + MSETransportGuidByte3, + MSETransportGuidByte5, + MSETransportGuidByte4, + MSETransportSeat, + MSETransportGuidByte2, + MSETransportOrientation, + MSETransportPositionY, + MSETransportGuidByte7, + MSETransportTime2, + MSETransportPositionZ, + MSETransportTime3, + MSETransportGuidByte6, + MSETransportTime, + MSETransportGuidByte0, + MSETransportGuidByte1, + MSETransportPositionX, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallTime, + MSEFallVerticalSpeed, + MSEOrientation, + MSEPitch, + MSETimestamp, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartDescendSequence[] = +{ + MSEPositionY, + MSEPositionZ, + MSEPositionX, + MSEHasGuidByte0, + MSEHasPitch, + MSEHasFallData, + MSEHasGuidByte4, + MSEHasOrientation, + MSEHasTimestamp, + MSEHasMovementFlags2, + MSEHasMovementFlags, + MSEHasGuidByte6, + MSEZeroBit, + MSEHasGuidByte1, + MSEHasTransportData, + MSEHasSpline, + MSEHasSplineElevation, + MSEHasGuidByte5, + MSEHasGuidByte3, + MSEHasGuidByte7, + MSEHasGuidByte2, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte2, + MSEHasTransportTime3, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte6, + MSEHasTransportTime2, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte5, + MSEMovementFlags2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte2, + MSEGuidByte7, + MSEGuidByte6, + MSEGuidByte0, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte4, + MSEGuidByte3, + MSEPitch, + MSETransportPositionZ, + MSETransportSeat, + MSETransportTime3, + MSETransportGuidByte6, + MSETransportTime2, + MSETransportGuidByte1, + MSETransportTime, + MSETransportGuidByte4, + MSETransportPositionY, + MSETransportPositionX, + MSETransportGuidByte7, + MSETransportGuidByte3, + MSETransportGuidByte5, + MSETransportGuidByte2, + MSETransportOrientation, + MSETransportGuidByte0, + MSEFallTime, + MSEFallSinAngle, + MSEFallCosAngle, + MSEFallHorizontalSpeed, + MSEFallVerticalSpeed, + MSETimestamp, + MSEOrientation, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartSwimSequence[] = +{ + MSEPositionZ, + MSEPositionX, + MSEPositionY, + MSEHasGuidByte3, + MSEHasSplineElevation, + MSEHasGuidByte4, + MSEHasGuidByte7, + MSEZeroBit, + MSEHasPitch, + MSEHasGuidByte0, + MSEHasOrientation, + MSEHasMovementFlags, + MSEHasFallData, + MSEHasGuidByte5, + MSEHasTransportData, + MSEHasMovementFlags2, + MSEHasTimestamp, + MSEHasGuidByte6, + MSEHasGuidByte1, + MSEHasSpline, + MSEHasGuidByte2, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte0, + MSEHasTransportTime2, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte1, + MSEHasTransportTime3, + MSEMovementFlags, + MSEHasFallDirection, + MSEMovementFlags2, + MSEGuidByte0, + MSEGuidByte2, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte4, + MSEGuidByte6, + MSEGuidByte3, + MSEGuidByte7, + MSEPitch, + MSETransportTime2, + MSETransportGuidByte2, + MSETransportPositionY, + MSETransportGuidByte3, + MSETransportTime, + MSETransportPositionX, + MSETransportOrientation, + MSETransportTime3, + MSETransportGuidByte6, + MSETransportGuidByte5, + MSETransportGuidByte4, + MSETransportPositionZ, + MSETransportGuidByte1, + MSETransportGuidByte7, + MSETransportGuidByte0, + MSETransportSeat, + MSEFallCosAngle, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallVerticalSpeed, + MSEFallTime, + MSEOrientation, + MSETimestamp, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStopSwimSequence[] = +{ + MSEPositionX, + MSEPositionY, + MSEPositionZ, + MSEHasSpline, + MSEHasPitch, + MSEHasGuidByte5, + MSEHasGuidByte3, + MSEHasGuidByte7, + MSEHasSplineElevation, + MSEHasMovementFlags, + MSEHasGuidByte4, + MSEHasMovementFlags2, + MSEHasGuidByte2, + MSEHasGuidByte6, + MSEHasTransportData, + MSEHasOrientation, + MSEZeroBit, + MSEHasTimestamp, + MSEHasGuidByte1, + MSEHasGuidByte0, + MSEHasFallData, + MSEHasTransportTime3, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte0, + MSEHasTransportTime2, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte5, + MSEMovementFlags, + MSEMovementFlags2, + MSEHasFallDirection, + MSEGuidByte0, + MSEGuidByte4, + MSEGuidByte3, + MSEGuidByte6, + MSEGuidByte7, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte2, + MSETransportTime3, + MSETransportGuidByte4, + MSETransportTime, + MSETransportPositionZ, + MSETransportSeat, + MSETransportGuidByte3, + MSETransportGuidByte2, + MSETransportPositionY, + MSETransportGuidByte7, + MSETransportGuidByte1, + MSETransportGuidByte6, + MSETransportGuidByte5, + MSETransportTime2, + MSETransportPositionX, + MSETransportGuidByte0, + MSETransportOrientation, + MSEFallVerticalSpeed, + MSEFallCosAngle, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallTime, + MSETimestamp, + MSEPitch, + MSEOrientation, + MSESplineElevation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStopAscendSequence[] = +{ + MSEPositionZ, + MSEPositionY, + MSEPositionX, + MSEHasGuidByte3, + MSEHasGuidByte2, + MSEHasFallData, + MSEHasGuidByte7, + MSEHasOrientation, + MSEHasPitch, + MSEHasSpline, + MSEZeroBit, + MSEHasGuidByte1, + MSEHasGuidByte4, + MSEHasMovementFlags, + MSEHasGuidByte0, + MSEHasGuidByte6, + MSEHasSplineElevation, + MSEHasTransportData, + MSEHasMovementFlags2, + MSEHasTimestamp, + MSEHasGuidByte5, + MSEHasTransportTime2, + MSEHasTransportTime3, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte2, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte0, + MSEMovementFlags2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte7, + MSEGuidByte5, + MSEGuidByte4, + MSEGuidByte3, + MSEGuidByte2, + MSEGuidByte1, + MSEGuidByte0, + MSEGuidByte6, + MSETransportGuidByte5, + MSETransportPositionY, + MSETransportGuidByte7, + MSETransportGuidByte2, + MSETransportGuidByte6, + MSETransportTime2, + MSETransportTime3, + MSETransportOrientation, + MSETransportGuidByte3, + MSETransportGuidByte4, + MSETransportSeat, + MSETransportGuidByte1, + MSETransportTime, + MSETransportGuidByte0, + MSETransportPositionX, + MSETransportPositionZ, + MSEFallTime, + MSEFallVerticalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEPitch, + MSESplineElevation, + MSETimestamp, + MSEOrientation, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStopPitchSequence[] = +{ + MSEPositionY, + MSEPositionX, + MSEPositionZ, + MSEHasGuidByte0, + MSEHasGuidByte5, + MSEHasGuidByte3, + MSEHasFallData, + MSEHasGuidByte2, + MSEHasGuidByte4, + MSEHasGuidByte7, + MSEHasPitch, + MSEHasSpline, + MSEHasOrientation, + MSEZeroBit, + MSEHasMovementFlags2, + MSEHasSplineElevation, + MSEHasGuidByte6, + MSEHasGuidByte1, + MSEHasTimestamp, + MSEHasTransportData, + MSEHasMovementFlags, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte2, + MSEHasTransportTime3, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte3, + MSEHasTransportTime2, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte1, + MSEHasFallDirection, + MSEMovementFlags2, + MSEMovementFlags, + MSEGuidByte1, + MSEGuidByte7, + MSEGuidByte0, + MSEGuidByte6, + MSEGuidByte4, + MSEGuidByte3, + MSEGuidByte5, + MSEGuidByte2, + MSETimestamp, + MSEFallHorizontalSpeed, + MSEFallSinAngle, + MSEFallCosAngle, + MSEFallVerticalSpeed, + MSEFallTime, + MSETransportGuidByte5, + MSETransportGuidByte2, + MSETransportTime2, + MSETransportPositionX, + MSETransportOrientation, + MSETransportGuidByte6, + MSETransportGuidByte3, + MSETransportGuidByte1, + MSETransportPositionZ, + MSETransportTime3, + MSETransportGuidByte0, + MSETransportGuidByte4, + MSETransportTime, + MSETransportPositionY, + MSETransportSeat, + MSETransportGuidByte7, + MSESplineElevation, + MSEOrientation, + MSEPitch, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartPitchDownSequence[] = +{ + MSEPositionX, + MSEPositionZ, + MSEPositionY, + MSEHasMovementFlags, + MSEHasGuidByte7, + MSEHasGuidByte6, + MSEHasPitch, + MSEZeroBit, + MSEHasGuidByte1, + MSEHasGuidByte4, + MSEHasTimestamp, + MSEHasSplineElevation, + MSEHasMovementFlags2, + MSEHasTransportData, + MSEHasGuidByte0, + MSEHasGuidByte5, + MSEHasGuidByte3, + MSEHasSpline, + MSEHasOrientation, + MSEHasFallData, + MSEHasGuidByte2, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte5, + MSEHasTransportTime3, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte6, + MSEHasTransportTime2, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte2, + MSEMovementFlags2, + MSEHasFallDirection, + MSEMovementFlags, + MSEGuidByte3, + MSEGuidByte7, + MSEGuidByte0, + MSEGuidByte5, + MSEGuidByte2, + MSEGuidByte6, + MSEGuidByte4, + MSEGuidByte1, + MSETransportTime3, + MSETransportGuidByte3, + MSETransportTime2, + MSETransportGuidByte5, + MSETransportGuidByte1, + MSETransportPositionY, + MSETransportGuidByte6, + MSETransportGuidByte4, + MSETransportTime, + MSETransportPositionZ, + MSETransportPositionX, + MSETransportGuidByte0, + MSETransportSeat, + MSETransportGuidByte2, + MSETransportGuidByte7, + MSETransportOrientation, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallVerticalSpeed, + MSEFallTime, + MSEPitch, + MSEOrientation, + MSESplineElevation, + MSETimestamp, + MSEEnd, +}; + +//4.3.4 +MovementStatusElements MovementStartPitchUpSequence[] = +{ + MSEPositionZ, + MSEPositionY, + MSEPositionX, + MSEHasGuidByte4, + MSEHasMovementFlags, + MSEHasMovementFlags2, + MSEHasSpline, + MSEHasGuidByte2, + MSEHasGuidByte6, + MSEHasGuidByte3, + MSEZeroBit, + MSEHasSplineElevation, + MSEHasFallData, + MSEHasGuidByte0, + MSEHasTransportData, + MSEHasGuidByte1, + MSEHasGuidByte5, + MSEHasPitch, + MSEHasTimestamp, + MSEHasOrientation, + MSEHasGuidByte7, + MSEMovementFlags2, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte3, + MSEHasTransportGuidByte1, + MSEHasTransportTime2, + MSEHasTransportGuidByte4, + MSEHasTransportTime3, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte5, + MSEHasTransportGuidByte2, + MSEMovementFlags, + MSEHasFallDirection, + MSEGuidByte0, + MSEGuidByte3, + MSEGuidByte4, + MSEGuidByte6, + MSEGuidByte7, + MSEGuidByte1, + MSEGuidByte5, + MSEGuidByte2, + MSETransportPositionX, + MSETransportGuidByte1, + MSETransportGuidByte3, + MSETransportGuidByte2, + MSETransportGuidByte0, + MSETransportTime, + MSETransportPositionZ, + MSETransportOrientation, + MSETransportGuidByte7, + MSETransportTime2, + MSETransportSeat, + MSETransportGuidByte6, + MSETransportGuidByte5, + MSETransportTime3, + MSETransportPositionY, + MSETransportGuidByte4, + MSEFallTime, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallHorizontalSpeed, + MSEFallVerticalSpeed, + MSEOrientation, + MSESplineElevation, + MSEPitch, + MSETimestamp, + MSEEnd, +}; + +MovementStatusElements MoveChngTransport[]= +{ + MSEPositionY, + MSEPositionX, + MSEPositionZ, + MSEHasGuidByte4, + MSEHasGuidByte0, + MSEHasGuidByte2, + MSEHasTransportData, + MSEHasSpline, + MSEHasOrientation, + MSEHasGuidByte6, + MSEHasTimestamp, + MSEHasGuidByte5, + MSEHasGuidByte7, + MSEHasPitch, + MSEZeroBit, + MSEHasGuidByte3, + MSEHasSplineElevation, + MSEHasGuidByte1, + MSEHasFallData, + MSEHasMovementFlags, + MSEHasMovementFlags2, + + MSEHasTransportGuidByte3, + MSEHasTransportTime3, + MSEHasTransportGuidByte4, + MSEHasTransportGuidByte1, + MSEHasTransportGuidByte6, + MSEHasTransportGuidByte2, + MSEHasTransportTime2, + MSEHasTransportGuidByte0, + MSEHasTransportGuidByte7, + MSEHasTransportGuidByte5, + + MSEMovementFlags, + MSEMovementFlags2, + MSEHasFallDirection, + + MSEGuidByte7, + MSEGuidByte5, + MSEGuidByte1, + MSEGuidByte2, + MSEGuidByte6, + MSEGuidByte4, + MSEGuidByte0, + MSEGuidByte3, + + MSETransportPositionY, + MSETransportSeat, + MSETransportGuidByte1, + MSETransportGuidByte0, + MSETransportGuidByte2, + MSETransportGuidByte3, + MSETransportGuidByte6, + MSETransportPositionZ, + MSETransportPositionX, + MSETransportTime3, + MSETransportTime, + MSETransportGuidByte7, + MSETransportGuidByte5, + MSETransportGuidByte4, + MSETransportOrientation, + MSETransportTime2, + + MSEFallTime, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallVerticalSpeed, + + MSEOrientation, + MSEPitch, + MSESplineElevation, + MSETimestamp, + MSEEnd, +}; + +MovementStatusElements* GetMovementStatusElementsSequence(Opcodes opcode) +{ + switch (opcode) + { + case MSG_MOVE_FALL_LAND: + return MovementFallLandSequence; + case MSG_MOVE_HEARTBEAT: + return MovementHeartBeatSequence; + case MSG_MOVE_JUMP: + return MovementJumpSequence; + case MSG_MOVE_SET_FACING: + return MovementSetFacingSequence; + case MSG_MOVE_SET_PITCH: + return MovementSetPitchSequence; + case MSG_MOVE_START_ASCEND: + return MovementStartAscendSequence; + case MSG_MOVE_START_BACKWARD: + return MovementStartBackwardSequence; + case MSG_MOVE_START_DESCEND: + return MovementStartDescendSequence; + case MSG_MOVE_START_FORWARD: + return MovementStartForwardSequence; + case MSG_MOVE_START_PITCH_DOWN: + return MovementStartPitchDownSequence; + case MSG_MOVE_START_PITCH_UP: + return MovementStartPitchUpSequence; + case MSG_MOVE_START_STRAFE_LEFT: + return MovementStartStrafeLeftSequence; + case MSG_MOVE_START_STRAFE_RIGHT: + return MovementStartStrafeRightSequence; + case MSG_MOVE_START_SWIM: + return MovementStartSwimSequence; + case MSG_MOVE_START_TURN_LEFT: + return MovementStartTurnLeftSequence; + case MSG_MOVE_START_TURN_RIGHT: + return MovementStartTurnRightSequence; + case MSG_MOVE_STOP: + return MovementStopSequence; + case MSG_MOVE_STOP_ASCEND: + return MovementStopAscendSequence; + case MSG_MOVE_STOP_PITCH: + return MovementStopPitchSequence; + case MSG_MOVE_STOP_STRAFE: + return MovementStopStrafeSequence; + case MSG_MOVE_STOP_SWIM: + return MovementStopSwimSequence; + case MSG_MOVE_STOP_TURN: + return MovementStopTurnSequence; + case SMSG_PLAYER_MOVE: + return PlayerMoveSequence; + case CMSG_MOVE_CHNG_TRANSPORT: + return MoveChngTransport; + default: + break; + } + + return NULL; +} + +#endif diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 61bd3900b9d..c020dc2a653 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -50,15 +50,15 @@ Location MoveSpline::ComputePosition() const if (splineflags.final_angle) c.orientation = facing.angle; else if (splineflags.final_point) - c.orientation = atan2(facing.f.y-c.y, facing.f.x-c.x); + c.orientation = atan2(facing.f.y - c.y, facing.f.x - c.x); //nothing to do for MoveSplineFlag::Final_Target flag } else { - if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed|MoveSplineFlag::Falling)) + if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed | MoveSplineFlag::Falling | MoveSplineFlag::Unknown0)) { Vector3 hermite; - spline.evaluate_derivative(point_Idx,u,hermite); + spline.evaluate_derivative(point_Idx, u, hermite); c.orientation = atan2(hermite.y, hermite.x); } @@ -214,7 +214,7 @@ bool MoveSplineInitArgs::Validate() const // each vertex offset packed into 11 bytes bool MoveSplineInitArgs::_checkPathBounds() const { - if (!(flags & MoveSplineFlag::Mask_CatmullRom) && path.size() > 2) + if (!(flags & MoveSplineFlag::Catmullrom) && path.size() > 2) { enum{ MAX_OFFSET = (1 << 11) / 2, diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index cfc2fdee450..40c07f14440 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -35,46 +35,49 @@ namespace Movement public: enum eFlags{ None = 0x00000000, - // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag - Done = 0x00000100, - Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag - No_Spline = 0x00000400, - Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag - Walkmode = 0x00001000, - Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation - OrientationFixed = 0x00004000, // Model orientation fixed - Final_Point = 0x00008000, - Final_Target = 0x00010000, - Final_Angle = 0x00020000, - Catmullrom = 0x00040000, // Used Catmullrom interpolation mode - Cyclic = 0x00080000, // Movement by cycled spline - Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done - Animation = 0x00200000, // Plays animation after some time passed - Frozen = 0x00400000, // Will never arrive - TransportEnter = 0x00800000, - TransportExit = 0x01000000, - Unknown7 = 0x02000000, - Unknown8 = 0x04000000, - OrientationInversed = 0x08000000, - Unknown10 = 0x10000000, - Unknown11 = 0x20000000, - Unknown12 = 0x40000000, - Unknown13 = 0x80000000, + // x00-x07 used as animation Ids storage in pair with Animation flag + Unknown0 = 0x00000008, // NOT VERIFIED + FallingSlow = 0x00000010, + Done = 0x00000020, + Falling = 0x00000040, // Affects elevation computation, can't be combined with Parabolic flag + No_Spline = 0x00000080, + Unknown2 = 0x00000100, // NOT VERIFIED + Flying = 0x00000200, // Smooth movement(Catmullrom interpolation mode), flying animation + OrientationFixed = 0x00000400, // Model orientation fixed + Catmullrom = 0x00000800, // Used Catmullrom interpolation mode + Cyclic = 0x00001000, // Movement by cycled spline + Enter_Cycle = 0x00002000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done + Frozen = 0x00004000, // Will never arrive + TransportEnter = 0x00008000, + TransportExit = 0x00010000, + Unknown3 = 0x00020000, // NOT VERIFIED + Unknown4 = 0x00040000, // NOT VERIFIED + OrientationInversed = 0x00080000, + SmoothGroundPath = 0x00100000, + Walkmode = 0x00200000, + UncompressedPath = 0x00400000, + Unknown6 = 0x00800000, // NOT VERIFIED + Animation = 0x01000000, // Plays animation after some time passed + Parabolic = 0x02000000, // Affects elevation computation, can't be combined with Falling flag + Final_Point = 0x04000000, + Final_Target = 0x08000000, + Final_Angle = 0x10000000, + Unknown7 = 0x20000000, // NOT VERIFIED + Unknown8 = 0x40000000, // NOT VERIFIED + Unknown9 = 0x80000000, // NOT VERIFIED // Masks Mask_Final_Facing = Final_Point | Final_Target | Final_Angle, // animation ids stored here, see AnimType enum, used with Animation flag - Mask_Animations = 0xFF, + Mask_Animations = 0x7, // flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done, - // CatmullRom interpolation mode used - Mask_CatmullRom = Flying | Catmullrom, // Unused, not suported flags - Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13, + Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown0|FallingSlow|Unknown2|Unknown3|Unknown4|SmoothGroundPath|Unknown6|Unknown7|Unknown8|Unknown9, }; - inline uint32& raw() { return (uint32&)*this;} - inline const uint32& raw() const { return (const uint32&)*this;} + inline uint32& raw() { return (uint32&)*this; } + inline const uint32& raw() const { return (const uint32&)*this; } MoveSplineFlag() { raw() = 0; } MoveSplineFlag(uint32 f) { raw() = f; } @@ -82,58 +85,62 @@ namespace Movement // Constant interface - bool isSmooth() const { return raw() & Mask_CatmullRom;} - bool isLinear() const { return !isSmooth();} - bool isFacing() const { return raw() & Mask_Final_Facing;} + bool isSmooth() const { return raw() & Catmullrom; } + bool isLinear() const { return !isSmooth(); } + bool isFacing() const { return raw() & Mask_Final_Facing; } - uint8 getAnimationId() const { return animId;} - bool hasAllFlags(uint32 f) const { return (raw() & f) == f;} - bool hasFlag(uint32 f) const { return (raw() & f) != 0;} - uint32 operator & (uint32 f) const { return (raw() & f);} - uint32 operator | (uint32 f) const { return (raw() | f);} + uint8 getAnimationId() const { return animId; } + bool hasAllFlags(uint32 f) const { return (raw() & f) == f; } + bool hasFlag(uint32 f) const { return (raw() & f) != 0; } + uint32 operator & (uint32 f) const { return (raw() & f); } + uint32 operator | (uint32 f) const { return (raw() | f); } std::string ToString() const; // Not constant interface - void operator &= (uint32 f) { raw() &= f;} - void operator |= (uint32 f) { raw() |= f;} + void operator &= (uint32 f) { raw() &= f; } + void operator |= (uint32 f) { raw() |= f; } - void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim; } - void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic; } + void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic | FallingSlow)) | Animation | (anim & Mask_Animations); } + void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation | FallingSlow)) | Parabolic; } void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling; } - void EnableFlying() { raw() = (raw() & ~Catmullrom) | Flying; } - void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; } + void EnableCatmullRom() { raw() = (raw() & ~SmoothGroundPath) | Catmullrom | UncompressedPath; } void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; } void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; } void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; } void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; } void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; } - uint8 animId : 8; - bool done : 1; - bool falling : 1; - bool no_spline : 1; - bool parabolic : 1; - bool walkmode : 1; - bool flying : 1; - bool orientationFixed : 1; - bool final_point : 1; - bool final_target : 1; - bool final_angle : 1; - bool catmullrom : 1; - bool cyclic : 1; - bool enter_cycle : 1; - bool animation : 1; - bool frozen : 1; - bool transportEnter: 1; - bool transportExit : 1; - bool unknown7 : 1; - bool unknown8 : 1; + uint8 animId : 3; + bool unknown0 : 1; + bool fallingSlow : 1; + bool done : 1; + bool falling : 1; + bool no_spline : 1; + bool unknown2 : 1; + bool flying : 1; + bool orientationFixed : 1; + bool catmullrom : 1; + bool cyclic : 1; + bool enter_cycle : 1; + bool frozen : 1; + bool transportEnter : 1; + bool transportExit : 1; + bool unknown3 : 1; + bool unknown4 : 1; bool orientationInversed : 1; - bool unknown10 : 1; - bool unknown11 : 1; - bool unknown12 : 1; - bool unknown13 : 1; + bool smoothGroundPath : 1; + bool walkmode : 1; + bool uncompressedPath : 1; + bool unknown6 : 1; + bool animation : 1; + bool parabolic : 1; + bool final_point : 1; + bool final_target : 1; + bool final_angle : 1; + bool unknown7 : 1; + bool unknown8 : 1; + bool unknown9 : 1; }; #if defined( __GNUC__ ) #pragma pack() diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index c539dd3cc39..780b341f6f2 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -63,7 +63,7 @@ namespace Movement bool transport = false; Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID()) + if (unit.GetTransGUID()) { transport = true; real_position.x = unit.GetTransOffsetX(); @@ -91,7 +91,7 @@ namespace Movement else moveFlags &= ~MOVEMENTFLAG_WALKING; - moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); + moveFlags |= MOVEMENTFLAG_FORWARD; if (!args.HasVelocity) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); @@ -120,10 +120,10 @@ namespace Movement MoveSplineInit::MoveSplineInit(Unit& m) : unit(m) { // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes - args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID(); + args.TransformForTransport = unit.GetTransGUID(); // mix existing state into new args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); - args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_DISABLE_GRAVITY)); + args.flags.flying = unit.m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY)); } void MoveSplineInit::SetFacing(const Unit * target) diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index ef847809ac8..2350bdc5207 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -102,6 +102,10 @@ namespace Movement void SetFly(); /* Enables walk mode. Disabled by default */ + void EnableTaxiFlight(); + /* Flags used in taxi + */ + void SetWalk(bool enable); /* Makes movement cyclic. Disabled by default */ @@ -140,16 +144,16 @@ namespace Movement Unit& unit; }; - inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); } - inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable;} - inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();} - inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;} - inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();} + inline void MoveSplineInit::SetFly() { args.flags.flying = true; } + inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable; } + inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); } + inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true; } + inline void MoveSplineInit::SetFall() { args.flags.EnableFalling(); } inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; } inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;} inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); } inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); } - inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;} + inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable; } inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset) { diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index 8aef671d2d1..19a250f7885 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -19,6 +19,7 @@ #include "MovementPacketBuilder.h" #include "MoveSpline.h" #include "WorldPacket.h" +#include "Object.h" namespace Movement { @@ -128,7 +129,7 @@ namespace Movement const Spline<int32>& spline = move_spline.spline; MoveSplineFlag splineflags = move_spline.splineflags; - if (splineflags & MoveSplineFlag::Mask_CatmullRom) + if (splineflags & MoveSplineFlag::UncompressedPath) { if (splineflags.cyclic) WriteCatmullRomCyclicPath(spline, data); @@ -139,44 +140,101 @@ namespace Movement WriteLinearPath(spline, data); } - void PacketBuilder::WriteCreate(const MoveSpline& move_spline, ByteBuffer& data) + void PacketBuilder::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data, bool& fullData) { - //WriteClientStatus(mov,data); - //data.append<float>(&mov.m_float_values[SpeedWalk], SpeedMaxCount); - //if (mov.SplineEnabled()) + fullData = data.WriteBit(!moveSpline.Finalized()); + if (!fullData) + return; + + data.WriteBits(uint8(moveSpline.spline.mode()), 2); + data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation)); + data.WriteBits(moveSpline.getPath().size(), 22); + switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing) { - MoveSplineFlag splineFlags = move_spline.splineflags; + case MoveSplineFlag::Final_Target: + { + ObjectGuid targetGuid = moveSpline.facing.target; + data.WriteBits(2, 2); + data.WriteBit(targetGuid[4]); + data.WriteBit(targetGuid[3]); + data.WriteBit(targetGuid[7]); + data.WriteBit(targetGuid[2]); + data.WriteBit(targetGuid[6]); + data.WriteBit(targetGuid[1]); + data.WriteBit(targetGuid[0]); + data.WriteBit(targetGuid[5]); + break; + } + case MoveSplineFlag::Final_Angle: + data.WriteBits(0, 2); + break; + case MoveSplineFlag::Final_Point: + data.WriteBits(1, 2); + break; + default: + data.WriteBits(3, 2); + break; + } - data << splineFlags.raw(); + data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration()); + data.WriteBits(moveSpline.splineflags.raw(), 25); + } + + void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data, bool fullData) + { + if (fullData) + { + MoveSplineFlag splineFlags = moveSpline.splineflags; + + if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration()) + data << moveSpline.vertical_acceleration; // added in 3.1 + + data << moveSpline.timePassed(); if (splineFlags.final_angle) - { - data << move_spline.facing.angle; - } + data << moveSpline.facing.angle; else if (splineFlags.final_target) { - data << move_spline.facing.target; + ObjectGuid facingGuid = moveSpline.facing.target; + data.WriteByteSeq(facingGuid[5]); + data.WriteByteSeq(facingGuid[3]); + data.WriteByteSeq(facingGuid[7]); + data.WriteByteSeq(facingGuid[1]); + data.WriteByteSeq(facingGuid[6]); + data.WriteByteSeq(facingGuid[4]); + data.WriteByteSeq(facingGuid[2]); + data.WriteByteSeq(facingGuid[0]); } - else if (splineFlags.final_point) + + uint32 nodes = moveSpline.getPath().size(); + for (uint32 i = 0; i < nodes; ++i) { - data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z; + data << float(moveSpline.getPath()[i].z); + data << float(moveSpline.getPath()[i].x); + data << float(moveSpline.getPath()[i].y); } - data << move_spline.timePassed(); - data << move_spline.Duration(); - data << move_spline.GetId(); + if (splineFlags.final_point) + data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y; - data << float(1.f); // splineInfo.duration_mod; added in 3.1 data << float(1.f); // splineInfo.duration_mod_next; added in 3.1 + data << moveSpline.Duration(); + if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation)) + data << moveSpline.effect_start_time; // added in 3.1 - data << move_spline.vertical_acceleration; // added in 3.1 - data << move_spline.effect_start_time; // added in 3.1 + data << float(1.f); // splineInfo.duration_mod; added in 3.1 + } - uint32 nodes = move_spline.getPath().size(); - data << nodes; - data.append<Vector3>(&move_spline.getPath()[0], nodes); - data << uint8(move_spline.spline.mode()); // added in 3.1 - data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination()); + if (!moveSpline.isCyclic()) + { + Vector3 dest = moveSpline.FinalDestination(); + data << float(dest.z); + data << float(dest.x); + data << float(dest.y); } + else + data << Vector3::zero(); + + data << moveSpline.GetId(); } } diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 92a414e9b3b..1b8506c5161 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -31,7 +31,8 @@ namespace Movement public: static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data); - static void WriteCreate(const MoveSpline& mov, ByteBuffer& data); + static void WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data, bool& fullData); + static void WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data, bool fullData); }; } #endif // TRINITYSERVER_PACKET_BUILDER_H diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp index f0ed01c4676..d0582baa7f9 100644 --- a/src/server/game/Movement/Spline/MovementUtil.cpp +++ b/src/server/game/Movement/Spline/MovementUtil.cpp @@ -100,7 +100,7 @@ namespace Movement #define STR(x) #x - const char * g_MovementFlag_names[]= + const char* g_MovementFlag_names[]= { STR(Forward ),// 0x00000001, STR(Backward ),// 0x00000002, @@ -112,29 +112,29 @@ namespace Movement STR(Pitch_Down ),// 0x00000080, STR(Walk ),// 0x00000100, // Walking - STR(Ontransport ),// 0x00000200, - STR(Levitation ),// 0x00000400, - STR(Root ),// 0x00000800, - STR(Falling ),// 0x00001000, - STR(Fallingfar ),// 0x00002000, - STR(Pendingstop ),// 0x00004000, - STR(PendingSTRafestop ),// 0x00008000, - STR(Pendingforward ),// 0x00010000, - STR(Pendingbackward ),// 0x00020000, - STR(PendingSTRafeleft ),// 0x00040000, - STR(PendingSTRaferight ),// 0x00080000, - STR(Pendingroot ),// 0x00100000, - STR(Swimming ),// 0x00200000, // Appears With Fly Flag Also - STR(Ascending ),// 0x00400000, // Swim Up Also - STR(Descending ),// 0x00800000, // Swim Down Also - STR(Can_Fly ),// 0x01000000, // Can Fly In 3.3? - STR(Flying ),// 0x02000000, // Actual Flying Mode - STR(Spline_Elevation ),// 0x04000000, // Used For Flight Paths - STR(Spline_Enabled ),// 0x08000000, // Used For Flight Paths - STR(Waterwalking ),// 0x10000000, // Prevent Unit From Falling Through Water - STR(Safe_Fall ),// 0x20000000, // Active Rogue Safe Fall Spell (Passive) - STR(Hover ),// 0x40000000 - STR(Unknown13 ),// 0x80000000 + STR(Levitation ),// 0x00000200, + STR(Root ),// 0x00000400, + STR(Falling ),// 0x00000800, + STR(Fallingfar ),// 0x00001000, + STR(Pendingstop ),// 0x00002000, + STR(PendingSTRafestop ),// 0x00004000, + STR(Pendingforward ),// 0x00008000, + STR(Pendingbackward ),// 0x00010000, + STR(PendingSTRafeleft ),// 0x00020000, + STR(PendingSTRaferight ),// 0x00040000, + STR(Pendingroot ),// 0x00080000, + STR(Swimming ),// 0x00100000, // Appears With Fly Flag Also + STR(Ascending ),// 0x00200000, // Swim Up Also + STR(Descending ),// 0x00400000, // Swim Down Also + STR(Can_Fly ),// 0x00800000, // Can Fly In 3.3? + STR(Flying ),// 0x01000000, // Actual Flying Mode + STR(Spline_Elevation ),// 0x02000000, // Used For Flight Paths + STR(Waterwalking ),// 0x04000000, // Prevent Unit From Falling Through Water + STR(Safe_Fall ),// 0x08000000, // Active Rogue Safe Fall Spell (Passive) + STR(Hover ),// 0x10000000 + STR(Local_Dirty ),// 0x20000000 + STR(None31 ),// 0x40000000 + STR(None32 ),// 0x80000000 STR(Unk1 ), STR(Unk2 ), STR(Unk3 ), @@ -155,38 +155,38 @@ namespace Movement const char * g_SplineFlag_names[32]= { - STR(AnimBit1 ),// 0x00000001, - STR(AnimBit2 ),// 0x00000002, - STR(AnimBit3 ),// 0x00000004, - STR(AnimBit4 ),// 0x00000008, - STR(AnimBit5 ),// 0x00000010, - STR(AnimBit6 ),// 0x00000020, - STR(AnimBit7 ),// 0x00000040, - STR(AnimBit8 ),// 0x00000080, - STR(Done ),// 0x00000100, - STR(Falling ),// 0x00000200, // Not Compartible With Trajectory Movement - STR(No_Spline ),// 0x00000400, - STR(Trajectory ),// 0x00000800, // Not Compartible With Fall Movement - STR(Walkmode ),// 0x00001000, - STR(Flying ),// 0x00002000, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation - STR(Knockback ),// 0x00004000, // Model Orientation Fixed - STR(Final_Point ),// 0x00008000, - STR(Final_Target ),// 0x00010000, - STR(Final_Angle ),// 0x00020000, - STR(Catmullrom ),// 0x00040000, // Used Catmullrom Interpolation Mode - STR(Cyclic ),// 0x00080000, // Movement By Cycled Spline - STR(Enter_Cycle ),// 0x00100000, // Everytime Appears With Cyclic Flag In Monster Move Packet - STR(Animation ),// 0x00200000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement - STR(Unknown4 ),// 0x00400000, // Disables Movement By Path - STR(Unknown5 ),// 0x00800000, - STR(Unknown6 ),// 0x01000000, - STR(Unknown7 ),// 0x02000000, - STR(Unknown8 ),// 0x04000000, - STR(OrientationInversed ),// 0x08000000, // Appears With Runmode Flag, Nodes ),// 1, Handles Orientation - STR(Unknown10 ),// 0x10000000, - STR(Unknown11 ),// 0x20000000, - STR(Unknown12 ),// 0x40000000, - STR(Unknown13 ),// 0x80000000, + STR(AnimBit1 ),// 0x00000001, + STR(AnimBit2 ),// 0x00000002, + STR(AnimBit3 ),// 0x00000004, + STR(Unknown0 ),// 0x00000008, + STR(FallingSlow ),// 0x00000010, + STR(Done ),// 0x00000020, + STR(Falling ),// 0x00000040, // Not Compartible With Trajectory Movement + STR(No_Spline ),// 0x00000080, + STR(Unknown2 ),// 0x00000100, + STR(Flying ),// 0x00000200, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation + STR(OrientationFixed ),// 0x00000400, // Model Orientation Fixed + STR(Catmullrom ),// 0x00000800, // Used Catmullrom Interpolation Mode + STR(Cyclic ),// 0x00001000, // Movement By Cycled Spline + STR(Enter_Cycle ),// 0x00002000, // Everytime Appears With Cyclic Flag In Monster Move Packet + STR(Frozen ),// 0x00004000, + STR(TransportEnter ),// 0x00008000 + STR(TransportExit ),// 0x00010000 + STR(Unknown3 ),// 0x00020000, + STR(Unknown4 ),// 0x00040000, + STR(OrientationInversed),// 0x00080000, // Appears With Runmode Flag, Nodes ),// 1, Handles Orientation + STR(SmoothGroundPath ),// 0x00100000, + STR(Walkmode ),// 0x00200000, + STR(UncompressedPath ),// 0x00400000, + STR(Unknown6 ),// 0x00800000, + STR(Animation ),// 0x01000000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement + STR(Parabolic ),// 0x02000000, // Not Compartible With Fall Movement + STR(Final_Point ),// 0x04000000, + STR(Final_Target ),// 0x08000000, + STR(Final_Angle ),// 0x10000000, + STR(Unknown7 ),// 0x20000000, + STR(Unknown8 ),// 0x40000000, + STR(Unknown9 ),// 0x80000000, }; template<class Flags, int N> @@ -202,7 +202,7 @@ namespace Movement std::string MoveSplineFlag::ToString() const { std::string str; - print_flags(raw(),g_SplineFlag_names,str); + print_flags(raw(), g_SplineFlag_names, str); return str; } } diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 9221da53003..32dc58e582b 100755 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -19,6 +19,7 @@ #include "QuestDef.h" #include "Player.h" #include "World.h" +#include "ObjectMgr.h" Quest::Quest(Field* questRecord) { @@ -61,114 +62,150 @@ Quest::Quest(Field* questRecord) SourceSpellid = questRecord[36].GetUInt32(); Flags = questRecord[37].GetUInt32(); uint32 SpecialFlags = questRecord[38].GetUInt8(); - RewardTitleId = questRecord[39].GetUInt8(); - RequiredPlayerKills = questRecord[40].GetUInt8(); - RewardTalents = questRecord[41].GetUInt8(); - RewardArenaPoints = questRecord[42].GetUInt16(); + MinimapTargetMark = questRecord[39].GetUInt8(); + RewardTitleId = questRecord[40].GetUInt8(); + RequiredPlayerKills = questRecord[41].GetUInt8(); + RewardTalents = questRecord[42].GetUInt8(); + RewardArenaPoints = questRecord[43].GetUInt16(); + RewardSkillId = questRecord[44].GetUInt16(); + RewardSkillPoints = questRecord[45].GetUInt8(); + RewardReputationMask = questRecord[46].GetUInt8(); + QuestGiverPortrait = questRecord[47].GetUInt32(); + QuestTurnInPortrait = questRecord[48].GetUInt32(); for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) - RewardItemId[i] = questRecord[43+i].GetUInt32(); + RewardItemId[i] = questRecord[49+i].GetUInt32(); for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) - RewardItemIdCount[i] = questRecord[47+i].GetUInt16(); + RewardItemIdCount[i] = questRecord[53+i].GetUInt16(); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) - RewardChoiceItemId[i] = questRecord[51+i].GetUInt32(); + RewardChoiceItemId[i] = questRecord[57+i].GetUInt32(); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) - RewardChoiceItemCount[i] = questRecord[57+i].GetUInt16(); + RewardChoiceItemCount[i] = questRecord[63+i].GetUInt16(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - RewardFactionId[i] = questRecord[63+i].GetUInt16(); + RewardFactionId[i] = questRecord[69+i].GetUInt16(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - RewardFactionValueId[i] = questRecord[68+i].GetInt32(); + RewardFactionValueId[i] = questRecord[74+i].GetInt32(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) - RewardFactionValueIdOverride[i] = questRecord[73+i].GetInt32(); - - PointMapId = questRecord[78].GetUInt16(); - PointX = questRecord[79].GetFloat(); - PointY = questRecord[80].GetFloat(); - PointOption = questRecord[81].GetUInt32(); - Title = questRecord[82].GetString(); - Objectives = questRecord[83].GetString(); - Details = questRecord[84].GetString(); - EndText = questRecord[85].GetString(); - OfferRewardText = questRecord[86].GetString(); - RequestItemsText = questRecord[87].GetString(); - CompletedText = questRecord[88].GetString(); + RewardFactionValueIdOverride[i] = questRecord[79+i].GetInt32(); + + PointMapId = questRecord[84].GetUInt16(); + PointX = questRecord[85].GetFloat(); + PointY = questRecord[86].GetFloat(); + PointOption = questRecord[87].GetUInt32(); + Title = questRecord[88].GetString(); + Objectives = questRecord[89].GetString(); + Details = questRecord[90].GetString(); + EndText = questRecord[91].GetString(); + CompletedText = questRecord[92].GetString(); + OfferRewardText = questRecord[93].GetString(); + RequestItemsText = questRecord[94].GetString(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - RequiredNpcOrGo[i] = questRecord[89+i].GetInt32(); + RequiredNpcOrGo[i] = questRecord[95+i].GetInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - RequiredNpcOrGoCount[i] = questRecord[93+i].GetUInt16(); + RequiredNpcOrGoCount[i] = questRecord[99+i].GetUInt16(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - RequiredSourceItemId[i] = questRecord[97+i].GetUInt32(); + RequiredSourceItemId[i] = questRecord[103+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - RequiredSourceItemCount[i] = questRecord[101+i].GetUInt16(); + RequiredSourceItemCount[i] = questRecord[107+i].GetUInt16(); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) - RequiredItemId[i] = questRecord[105+i].GetUInt32(); + RequiredItemId[i] = questRecord[111+i].GetUInt32(); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) - RequiredItemCount[i] = questRecord[111+i].GetUInt16(); + RequiredItemCount[i] = questRecord[117+i].GetUInt16(); - for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - RequiredSpellCast[i] = questRecord[117+i].GetUInt32(); + RequiredSpell = questRecord[123].GetUInt32(); - // int8 Unknown0 = questRecord[121].GetUInt8(); + for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) // To be removed + RequiredSpellCast[i] = questRecord[124+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) - ObjectiveText[i] = questRecord[122+i].GetString(); + ObjectiveText[i] = questRecord[128+i].GetString(); + + for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) + RewardCurrencyId[i] = questRecord[132+i].GetUInt16(); + + for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) + RewardCurrencyCount[i] = questRecord[136+i].GetUInt8(); + + for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) + RequiredCurrencyId[i] = questRecord[140+i].GetUInt16(); + + for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) + RequiredCurrencyCount[i] = questRecord[144+i].GetUInt8(); + + QuestGiverTextWindow = questRecord[148].GetString(); + QuestGiverTargetName = questRecord[149].GetString(); + QuestTurnTextWindow = questRecord[150].GetString(); + QuestTurnTargetName = questRecord[151].GetString(); + SoundAccept = questRecord[152].GetUInt16(); + SoundTurnIn = questRecord[153].GetUInt16(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - DetailsEmote[i] = questRecord[126+i].GetUInt16(); + DetailsEmote[i] = questRecord[154+i].GetUInt16(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - DetailsEmoteDelay[i] = questRecord[130+i].GetUInt32(); + DetailsEmoteDelay[i] = questRecord[158+i].GetUInt32(); - EmoteOnIncomplete = questRecord[134].GetUInt16(); - EmoteOnComplete = questRecord[135].GetUInt16(); + EmoteOnIncomplete = questRecord[162].GetUInt16(); + EmoteOnComplete = questRecord[163].GetUInt16(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - OfferRewardEmote[i] = questRecord[136+i].GetInt16(); + OfferRewardEmote[i] = questRecord[164+i].GetInt16(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) - OfferRewardEmoteDelay[i] = questRecord[140+i].GetInt32(); + OfferRewardEmoteDelay[i] = questRecord[168+i].GetInt32(); - StartScript = questRecord[144].GetUInt32(); - CompleteScript = questRecord[145].GetUInt32(); + StartScript = questRecord[172].GetUInt32(); + CompleteScript = questRecord[173].GetUInt32(); - // int32 WDBVerified = questRecord[146].GetInt32(); + // int32 WDBVerified = questRecord[174].GetInt32(); Flags |= SpecialFlags << 20; if (Flags & QUEST_TRINITY_FLAGS_AUTO_ACCEPT) Flags |= QUEST_FLAGS_AUTO_ACCEPT; - m_reqitemscount = 0; - m_reqCreatureOrGOcount = 0; - m_rewitemscount = 0; - m_rewchoiceitemscount = 0; + m_reqItemsCount = 0; + m_reqNpcOrGoCount = 0; + m_rewItemsCount = 0; + m_rewChoiceItemsCount = 0; + m_rewCurrencyCount = 0; + m_reqCurrencyCount = 0; for (int i=0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) if (RequiredItemId[i]) - ++m_reqitemscount; + ++m_reqItemsCount; for (int i=0; i < QUEST_OBJECTIVES_COUNT; ++i) if (RequiredNpcOrGo[i]) - ++m_reqCreatureOrGOcount; + ++m_reqNpcOrGoCount; for (int i=0; i < QUEST_REWARDS_COUNT; ++i) if (RewardItemId[i]) - ++m_rewitemscount; + ++m_rewItemsCount; for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; ++i) if (RewardChoiceItemId[i]) - ++m_rewchoiceitemscount; + ++m_rewChoiceItemsCount; + + for (int i=0; i < QUEST_REWARD_CURRENCY_COUNT; ++i) + if (RewardCurrencyId[i]) + ++m_rewCurrencyCount; + + for (int i=0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) + if (RequiredCurrencyId[i]) + ++m_reqCurrencyCount; + } uint32 Quest::XPValue(Player* player) const @@ -210,6 +247,102 @@ int32 Quest::GetRewOrReqMoney() const return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_DROP_MONEY)); } +uint32 Quest::GetRewChoiceItemsEffectiveCount() const +{ + uint32 count = 0; + for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + if (RewardChoiceItemId[i] > 0) + count++; + + return count; +} + +uint32 Quest::GetRewItemsEffectiveCount() const +{ + uint32 count = 0; + for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) + if (RewardItemId[i] > 0) + count++; + + return count; +} + +void Quest::BuildExtraQuestInfo(WorldPacket& data, Player* player) const +{ + if (HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) + { + data << uint32(0); // Rewarded chosen items hidden + data << uint32(0); // Rewarded items hidden + data << uint32(0); // Rewarded money hidden + data << uint32(0); // Rewarded XP hidden + } + else + { + data << uint32(GetRewChoiceItemsEffectiveCount()); + for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + data << uint32(RewardChoiceItemId[i]); + for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + data << uint32(RewardChoiceItemCount[i]); + for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) + { + if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(RewardChoiceItemId[i])) + data << uint32(itemTemplate->DisplayInfoID); + else + data << uint32(0); + } + + data << uint32(GetRewChoiceItemsEffectiveCount()); + for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) + data << uint32(RewardItemId[i]); + for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) + data << uint32(RewardItemIdCount[i]); + for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i) + { + if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(RewardItemId[i])) + data << uint32(itemTemplate->DisplayInfoID); + else + data << uint32(0); + } + + data << uint32(GetRewOrReqMoney()); + data << uint32(XPValue(player) * sWorld->getRate(RATE_XP_QUEST)); + } + + data << uint32(GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) + data << uint32(0); // 4.x Unk + data << float(0); // 4.x Unk + data << uint32(GetBonusTalents()); // bonus talents + data << uint32(0); // 4.x Unk + data << uint32(0); // 4.x Unk + + /* These are probably some of the unks above + // rewarded honor points. Multiply with 10 to satisfy client + data << 10 * Trinity::Honor::hk_honor_at_level(_session->GetPlayer()->getLevel(), quest->GetRewHonorMultiplier()); + data << float(0.0f); // new 3.3.0, honor multiplier? + data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) // unk + */ + + for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) + data << uint32(RewardFactionId[i]); + + for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) + data << int32(RewardFactionValueId[i]); + + for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) + data << int32(RewardFactionValueIdOverride[i]); + + data << uint32(GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0) + data << int32(GetRewSpellCast()); // casted spell + + for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; i++) + data << uint32(RewardCurrencyId[i]); // 4.x Unk + for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; i++) + data << uint32(RewardCurrencyCount[i]); // 4.x Unk + + data << uint32(0); // 4.x Unk + data << uint32(0); // 4.x Unk +} + bool Quest::IsAutoAccept() const { return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? false : (Flags & QUEST_FLAGS_AUTO_ACCEPT); @@ -235,7 +368,7 @@ uint32 Quest::CalculateHonorGain(uint8 level) const uint32 honor = 0; - if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f) + /*if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f) { // values stored from 0.. for 1... TeamContributionPointsEntry const* tc = sTeamContributionPointsStore.LookupEntry(level-1); @@ -243,7 +376,7 @@ uint32 Quest::CalculateHonorGain(uint8 level) const return 0; honor = uint32(tc->value * GetRewHonorMultiplier() * 0.1000000014901161); honor += GetRewHonorAddition(); - } + }*/ return honor; } diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 7f22b441afe..b72956ce313 100755 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -22,6 +22,7 @@ #include "Define.h" #include "DatabaseEnv.h" #include "SharedDefines.h" +#include "WorldPacket.h" #include <string> #include <vector> @@ -41,6 +42,8 @@ class ObjectMgr; #define QUEST_REPUTATIONS_COUNT 5 #define QUEST_EMOTE_COUNT 4 #define QUEST_PVP_KILL_SLOT 0 +#define QUEST_REWARD_CURRENCY_COUNT 4 +#define QUEST_REQUIRED_CURRENCY_COUNT 4 enum QuestFailedReasons { @@ -107,17 +110,18 @@ enum QuestStatus enum __QuestGiverStatus { - DIALOG_STATUS_NONE = 0, - DIALOG_STATUS_UNAVAILABLE = 1, - DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 2, - DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 3, - DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 4, - DIALOG_STATUS_INCOMPLETE = 5, - DIALOG_STATUS_REWARD_REP = 6, - DIALOG_STATUS_AVAILABLE_REP = 7, - DIALOG_STATUS_AVAILABLE = 8, - DIALOG_STATUS_REWARD2 = 9, // no yellow dot on minimap - DIALOG_STATUS_REWARD = 10 // yellow dot on minimap + DIALOG_STATUS_NONE = 0x000, + DIALOG_STATUS_UNK = 0x001, + DIALOG_STATUS_UNAVAILABLE = 0x002, + DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 0x004, + DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 0x008, + DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 0x010, + DIALOG_STATUS_INCOMPLETE = 0x020, + DIALOG_STATUS_REWARD_REP = 0x040, + DIALOG_STATUS_AVAILABLE_REP = 0x080, + DIALOG_STATUS_AVAILABLE = 0x100, + DIALOG_STATUS_REWARD2 = 0x200, // no yellow dot on minimap + DIALOG_STATUS_REWARD = 0x400 // yellow dot on minimap }; enum __QuestFlags @@ -173,6 +177,11 @@ struct QuestLocale StringVector EndText; StringVector CompletedText; std::vector< StringVector > ObjectiveText; + // new on 4.x + StringVector QuestGiverTextWindow; + StringVector QuestGiverTargetName; + StringVector QuestTurnTextWindow; + StringVector QuestTurnTargetName; }; // This Quest class provides a convenient way to access a few pretotaled (cached) quest details, @@ -229,11 +238,14 @@ class Quest std::string GetRequestItemsText() const { return RequestItemsText; } std::string GetEndText() const { return EndText; } std::string GetCompletedText() const { return CompletedText; } + std::string GetQuestGiverTextWindow() const { return QuestGiverTextWindow; } + std::string GetQuestGiverTargetName() const { return QuestGiverTargetName; } + std::string GetQuestTurnTextWindow() const { return QuestTurnTextWindow; } + std::string GetQuestTurnTargetName() const { return QuestTurnTargetName; } int32 GetRewOrReqMoney() const; uint32 GetRewHonorAddition() const { return RewardHonor; } float GetRewHonorMultiplier() const { return RewardHonorMultiplier; } - uint32 GetRewMoneyMaxLevel() const { return RewardMoneyMaxLevel; } - // use in XP calculation at client + uint32 GetRewMoneyMaxLevel() const { return RewardMoneyMaxLevel; } // use in XP calculation at client uint32 GetRewSpell() const { return RewardSpell; } int32 GetRewSpellCast() const { return RewardSpellCast; } uint32 GetRewMailTemplateId() const { return RewardMailTemplateId; } @@ -242,6 +254,9 @@ class Quest float GetPointX() const { return PointX; } float GetPointY() const { return PointY; } uint32 GetPointOpt() const { return PointOption; } + uint32 GetRequiredSpell() const { return RequiredSpell; } + uint32 GetSoundAccept() const { return SoundAccept; } + uint32 GetSoundTurnIn() const { return SoundTurnIn; } uint32 GetIncompleteEmote() const { return EmoteOnIncomplete; } uint32 GetCompleteEmote() const { return EmoteOnComplete; } uint32 GetQuestStartScript() const { return StartScript; } @@ -250,6 +265,12 @@ class Quest bool IsAutoAccept() const; bool IsAutoComplete() const; uint32 GetFlags() const { return Flags; } + uint32 GetMinimapTargetMark() const { return MinimapTargetMark; } + uint32 GetRewardSkillId() const { return RewardSkillId; } + uint32 GetRewardSkillPoints() const { return RewardSkillPoints; } + uint32 GetRewardReputationMask() const { return RewardReputationMask; } + uint32 GetQuestGiverPortrait() const { return QuestGiverPortrait; } + uint32 GetQuestTurnInPortrait() const { return QuestTurnInPortrait; } bool IsDaily() const { return Flags & QUEST_FLAGS_DAILY; } bool IsWeekly() const { return Flags & QUEST_FLAGS_WEEKLY; } bool IsSeasonal() const { return (ZoneOrSort == -QUEST_SORT_SEASONAL || ZoneOrSort == -QUEST_SORT_SPECIAL || ZoneOrSort == -QUEST_SORT_LUNAR_FESTIVAL || ZoneOrSort == -QUEST_SORT_MIDSUMMER || ZoneOrSort == -QUEST_SORT_BREWFEST || ZoneOrSort == -QUEST_SORT_LOVE_IS_IN_THE_AIR || ZoneOrSort == -QUEST_SORT_NOBLEGARDEN) && !IsRepeatable(); } @@ -279,11 +300,20 @@ class Quest uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT]; uint32 OfferRewardEmote[QUEST_EMOTE_COUNT]; uint32 OfferRewardEmoteDelay[QUEST_EMOTE_COUNT]; + // 4.x + uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT]; + uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT]; + uint32 RequiredCurrencyId[QUEST_REQUIRED_CURRENCY_COUNT]; + uint32 RequiredCurrencyCount[QUEST_REQUIRED_CURRENCY_COUNT]; - uint32 GetReqItemsCount() const { return m_reqitemscount; } - uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; } - uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; } - uint32 GetRewItemsCount() const { return m_rewitemscount; } + uint32 GetReqItemsCount() const { return m_reqItemsCount; } + uint32 GetRewItemsEffectiveCount() const; + uint32 GetReqCreatureOrGOcount() const { return m_reqNpcOrGoCount; } + uint32 GetRewChoiceItemsCount() const { return m_rewChoiceItemsCount; } + uint32 GetRewChoiceItemsEffectiveCount() const; + uint32 GetRewItemsCount() const { return m_rewItemsCount; } + + void BuildExtraQuestInfo(WorldPacket& data, Player* player) const; typedef std::vector<int32> PrevQuests; PrevQuests prevQuests; @@ -292,10 +322,12 @@ class Quest // cached data private: - uint32 m_reqitemscount; - uint32 m_reqCreatureOrGOcount; - uint32 m_rewchoiceitemscount; - uint32 m_rewitemscount; + uint32 m_reqItemsCount; + uint32 m_reqNpcOrGoCount; + uint32 m_rewChoiceItemsCount; + uint32 m_rewItemsCount; + uint32 m_rewCurrencyCount; + uint32 m_reqCurrencyCount; // table data protected: @@ -356,6 +388,20 @@ class Quest uint32 EmoteOnComplete; uint32 StartScript; uint32 CompleteScript; + // new in 4.x + uint32 MinimapTargetMark; + uint32 RewardSkillId; + uint32 RewardSkillPoints; + uint32 RewardReputationMask; + uint32 QuestGiverPortrait; + uint32 QuestTurnInPortrait; + uint32 RequiredSpell; + std::string QuestGiverTextWindow; + std::string QuestGiverTargetName; + std::string QuestTurnTextWindow; + std::string QuestTurnTargetName; + uint32 SoundAccept; + uint32 SoundTurnIn; }; struct QuestStatusData diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 05b224fb024..edb4c0c1cf4 100755 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -197,23 +197,23 @@ void ReputationMgr::SendState(FactionState const* faction) void ReputationMgr::SendInitialReputations() { - WorldPacket data(SMSG_INITIALIZE_FACTIONS, (4+128*5)); - data << uint32 (0x00000080); + WorldPacket data(SMSG_INITIALIZE_FACTIONS, (4+256*5)); + data << uint32(256); // count RepListID a = 0; for (FactionStateList::iterator itr = _factions.begin(); itr != _factions.end(); ++itr) { // fill in absent fields - for (; a != itr->first; a++) + for (; a != itr->first; ++a) { - data << uint8 (0x00); - data << uint32 (0x00000000); + data << uint8(0); + data << uint32(0); } // fill in encountered data - data << uint8 (itr->second.Flags); - data << uint32 (itr->second.Standing); + data << uint8(itr->second.Flags); + data << uint32(itr->second.Standing); itr->second.needSend = false; @@ -221,7 +221,7 @@ void ReputationMgr::SendInitialReputations() } // fill in absent fields - for (; a != 128; a++) + for (; a != 256; ++a) { data << uint8 (0x00); data << uint32 (0x00000000); @@ -388,11 +388,11 @@ bool ReputationMgr::SetOneFactionReputation(FactionEntry const* factionEntry, in UpdateRankCounters(old_rank, new_rank); _player->ReputationChanged(factionEntry); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION, factionEntry->ID); + _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION, factionEntry->ID); return true; } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index f5adf67a9ab..480ab8ef4ae 100755 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1227,7 +1227,7 @@ void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost) FOREACH_SCRIPT(PlayerScript)->OnTalentsReset(player, noCost); } -void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount) +void ScriptMgr::OnPlayerMoneyChanged(Player* player, int64& amount) { FOREACH_SCRIPT(PlayerScript)->OnMoneyChanged(player, amount); } diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 3c2ee81afff..b16b877eded 100755 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -684,7 +684,7 @@ class PlayerScript : public ScriptObject virtual void OnTalentsReset(Player* /*player*/, bool /*noCost*/) { } // Called when a player's money is modified (before the modification is done) - virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { } + virtual void OnMoneyChanged(Player* /*player*/, int64& /*amount*/) { } // Called when a player gains XP (before anything is given) virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { } @@ -990,7 +990,7 @@ class ScriptMgr void OnPlayerLevelChanged(Player* player, uint8 oldLevel); void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints); void OnPlayerTalentsReset(Player* player, bool noCost); - void OnPlayerMoneyChanged(Player* player, int32& amount); + void OnPlayerMoneyChanged(Player* player, int64& amount); void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim); void OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental); void OnPlayerDuelRequest(Player* target, Player* challenger); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 8fb8ea0298b..8098dfd85dc 100755..100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -23,1318 +23,1682 @@ #include "Opcodes.h" #include "WorldSession.h" +OpcodeHandler* opcodeTable[NUM_OPCODE_HANDLERS] = { }; + /// Correspondence between opcodes and their names -OpcodeHandler opcodeTable[NUM_MSG_TYPES] = +void InitOpcodes() { - /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode }, - /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x00D*/ { "CMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x00E*/ { "SMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x01E*/ { "SMSG_REFER_A_FRIEND_EXPIRED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCreateOpcode }, - /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode }, - /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharDeleteOpcode }, - /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLoginOpcode }, - /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLogoutOpcode }, - /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutRequestOpcode }, - /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode }, - /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNameQueryOpcode }, - /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery }, - /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode }, - /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleItemQuerySingleOpcode }, - /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePageTextQueryOpcode }, - /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode }, - /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGameObjectQueryOpcode }, - /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleCreatureQueryOpcode }, - /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode }, - /*0x063*/ { "SMSG_WHO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode }, - /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleContactListOpcode }, - /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddFriendOpcode }, - /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode }, - /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetContactNotesOpcode }, - /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddIgnoreOpcode }, - /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode }, - /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode }, - /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAcceptOpcode }, - /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDeclineOpcode }, - /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode }, - /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteGuidOpcode }, - /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode }, - /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMethodOpcode }, - /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDisbandOpcode }, - /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildCreateOpcode }, - /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode }, - /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode }, - /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeclineOpcode }, - /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInfoOpcode }, - /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRosterOpcode }, - /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode }, - /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode }, - /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode }, - /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode }, - /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode }, - /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaderOpcode }, - /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode }, - /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode }, - /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleJoinChannel }, - /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveChannel }, - /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelList }, - /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelPassword }, - /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelSetOwner }, - /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelOwner }, - /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerator }, - /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmoderator }, - /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelMute }, - /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmute }, - /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelInvite }, - /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelKick }, - /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelBan }, - /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnban }, - /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncements }, - /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL }, - /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode }, - /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode }, - /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem }, - /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameObjectUseOpcode }, - /*0x0B2*/ { "CMSG_DESTROY_ITEMS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaTriggerOpcode }, - /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck }, - /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode }, - /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0E0*/ { "CMSG_MOVE_CHARM_PORT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveRootAck }, - /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveUnRootAck }, - /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveKnockBackAck }, - /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveHoverAck }, - /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera }, - /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCompleteCinematic }, - /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag }, - /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear }, - /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialReset }, - /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStandStateChangeOpcode }, - /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEmoteOpcode }, - /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTextEmoteOpcode }, - /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode }, - /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode }, - /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode }, - /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapItem }, - /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapInvItemOpcode }, - /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSplitItemOpcode }, - /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode }, - /*0x110*/ { "CMSG_UNCLAIM_LICENSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDestroyItemOpcode }, - /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode }, - /*0x115*/ { "SMSG_INSPECT_RESULTS_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode }, - /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode }, - /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode }, - /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode }, - /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode }, - /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode }, - /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode }, - /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode }, - /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode }, - /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode }, - /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar }, - /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionCheat }, - /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionButtonOpcode }, - /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode }, - /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode }, - /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode }, - /*0x137*/ { "SMSG_EQUIPMENT_SET_SAVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling }, - /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode }, - /*0x13E*/ { "CMSG_DELETEEQUIPMENT_SET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete }, - /*0x13F*/ { "CMSG_INSTANCE_LOCK_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse }, - /*0x140*/ { "CMSG_DEBUG_PASSIVE_AURA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode }, - /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode }, - /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x147*/ { "SMSG_INSTANCE_LOCK_WARNING_QUERY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x14B*/ { "SMSG_BATTLEFIELD_PORT_DENIED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x14C*/ { "CMSG_PERFORM_ACTION_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x14D*/ { "SMSG_RESUME_CAST_BAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x152*/ { "SMSG_BREAK_TARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepopRequestOpcode }, - /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResurrectResponseOpcode }, - /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootOpcode }, - /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMoneyOpcode }, - /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootReleaseOpcode }, - /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelAcceptedOpcode }, - /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelCancelledOpcode }, - /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x170*/ { "SMSG_REMOVED_FROM_PVP_QUEUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode }, - /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction }, - /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction }, - /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon }, - /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename }, - /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode }, - /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode }, - /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode }, - /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode}, - /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode }, - /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode}, - /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQuestAutoLaunch }, - /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode}, - /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCompleteQuest }, - /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode}, - /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverChooseRewardOpcode}, - /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCancel }, - /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogSwapQuest }, - /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest }, - /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept }, - /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty }, - /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode }, - /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSellItemOpcode }, - /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemOpcode }, - /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemInSlotOpcode }, - /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode }, - /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes }, - /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode }, - /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode }, - /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode }, - /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode }, - /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode }, - /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode }, - /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowListOpcode }, - /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuyOpcode }, - /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowSignOpcode }, - /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionSignOpcode }, - /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionDeclineOpcode }, - /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode }, - /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode }, - /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionQueryOpcode }, - /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode }, - /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayedTime }, - /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryTimeOpcode }, - /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReclaimCorpseOpcode }, - /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode }, - /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode }, - /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess }, - /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode }, - /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1E3*/ { "CMSG_QUEST_POI_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery }, - /*0x1E4*/ { "SMSG_QUEST_POI_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess }, - /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode }, - /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode }, - /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode}, - /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleZoneUpdateOpcode }, - /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomRollOpcode }, - /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1FD*/ { "CMSG_CHANGEPLAYER_DIFFICULTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x1FF*/ { "SMSG_LFG_PLAYER_REWARD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x200*/ { "SMSG_LFG_TELEPORT_DENIED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode }, - /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketCreateOpcode }, - /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode }, - /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData }, - /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData }, - /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x20E*/ { "SMSG_CHANGEPLAYER_DIFFICULTY_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketGetTicketOpcode }, - /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x214*/ { "SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode }, - /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteOpcode }, - /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode}, - /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpiritHealerActivateOpcode}, - /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x21E*/ { "SMSG_QUEST_FORCE_REMOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode }, - /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRankOpcode }, - /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAddRankOpcode }, - /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDelRankOpcode }, - /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetPublicNoteOpcode }, - /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetOfficerNoteOpcode }, - /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendMail }, - /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetMailList }, - /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode }, - /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x23F*/ { "SMSG_FORCE_SET_VEHICLE_REC_ID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x240*/ { "CMSG_SET_VEHICLE_REC_ID_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery }, - /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeMoney }, - /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeItem }, - /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailMarkAsRead }, - /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailReturnToSender }, - /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailDelete }, - /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailCreateTextItem }, - /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnTalentOpcode }, - /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP }, - /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode }, - /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem }, - /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionRemoveItem }, - /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems }, - /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListOwnerItems }, - /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionPlaceBid }, - /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x261*/ { "SMSG_COMBAT_EVENT_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems }, - /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetAmmoOpcode }, - /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveMoverOpcode }, - /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode }, - /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode}, - /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode }, - /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStablePet }, - /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnstablePet }, - /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyStableSlot }, - /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableRevivePet }, - /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableSwapPet }, - /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult }, - /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode }, - /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleFarSightOpcode }, - /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupChangeSubGroupOpcode }, - /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode}, - /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode }, - /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankItemOpcode }, - /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryNextMailTime }, - /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode }, - /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode}, - /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem }, - /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x293*/ { "SMSG_LFG_OFFER_CONTINUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x294*/ { "CMSG_TEST_DROP_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x295*/ { "SMSG_TEST_DROP_RATE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x296*/ { "CMSG_LFG_GET_STATUS", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x297*/ { "SMSG_SHOW_MAILBOX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x298*/ { "SMSG_RESET_RANGED_COMBAT_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x29A*/ { "SMSG_CHAT_NOT_IN_PARTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode }, - /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootRoll }, - /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode }, - /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepairItemOpcode }, - /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTalentWipeConfirmOpcode }, - /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSummonResponseOpcode }, - /*0x2AD*/ { "MSG_DEV_SHOWLABEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSelfResOpcode }, - /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2B9*/ { "CMSG_SHOWING_HELM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode }, - /*0x2BA*/ { "CMSG_SHOWING_CLOAK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode }, - /*0x2BB*/ { "SMSG_LFG_ROLE_CHOSEN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarToggles }, - /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameOpcode }, - /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemNameQueryOpcode }, - /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharRenameOpcode }, - /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSplineDoneOpcode }, - /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode }, - /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode }, - /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck }, - /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck }, - /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveNotActiveMover }, - /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode }, - /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode }, - /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectHonorStatsOpcode }, - /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterHelloOpcode }, - /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode }, - /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveBattlefieldOpcode }, - /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, - /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, - /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_AUTHED, PROCESS_THREADSAFE, &WorldSession::HandleWardenDataOpcode }, - /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode}, - /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetStopAttack }, - /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinOpcode }, - /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSpellAutocastOpcode }, - /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode }, - /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiExpressOpcode }, - /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode }, - /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetWatchedFactionOpcode }, - /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResetInstancesOpcode }, - /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode }, - /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode }, - /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetDungeonDifficultyOpcode}, - /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMSurveySubmit }, - /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x33E*/ { "SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x33F*/ { "SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x340*/ { "CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode }, - /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSocketOpcode }, - /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x34A*/ { "MSG_MOVE_UPDATE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamQueryOpcode }, - /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRosterOpcode }, - /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamInviteOpcode }, - /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamAcceptOpcode }, - /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDeclineOpcode }, - /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaveOpcode }, - /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRemoveOpcode }, - /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDisbandOpcode }, - /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaderOpcode }, - /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena }, - /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode }, - /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode }, - /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrSearchOpcode }, - /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrLeaveOpcode }, - /*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x361*/ { "SMSG_LFG_PROPOSAL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgProposalResultOpcode }, - /*0x363*/ { "SMSG_LFG_ROLE_CHECK_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x364*/ { "SMSG_LFG_JOIN_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x365*/ { "SMSG_LFG_QUEUE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetCommentOpcode }, - /*0x367*/ { "SMSG_LFG_UPDATE_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x368*/ { "SMSG_LFG_UPDATE_PARTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x369*/ { "SMSG_LFG_UPDATE_SEARCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetRolesOpcode }, - /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetBootVoteOpcode }, - /*0x36D*/ { "SMSG_LFG_BOOT_PROPOSAL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPlayerLockInfoRequestOpcode}, - /*0x36F*/ { "SMSG_LFG_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgTeleportOpcode }, - /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPartyLockInfoRequestOpcode}, - /*0x372*/ { "SMSG_LFG_PARTY_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTitleOpcode }, - /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelMountAuraOpcode }, - /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode }, - /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode}, - /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck }, - /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode }, - /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode }, - /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode }, - /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeSyncResp }, - /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes }, - /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode }, - /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3B2*/ { "CMSG_GM_WHISPER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3B3*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3B4*/ { "MSG_GM_GEARRATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3B5*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3B6*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3B7*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3B8*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3B9*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3BA*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3BB*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3BC*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3BD*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3BE*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3BF*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3C0*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3C1*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3C3*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3C4*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3C5*/ { "SMSG_KICK_REASON", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3C6*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckFinishedOpcode}, - /*0x3C7*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleComplainOpcode }, - /*0x3C8*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3C9*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3CA*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3CB*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3CD*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3CF*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3D0*/ { "CMSG_TARGET_CAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3D1*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3D2*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelDisplayListQuery }, - /*0x3D3*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel }, - /*0x3D4*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetChannelMemberCount }, - /*0x3D5*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3D6*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode }, - /*0x3D7*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3D8*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3D9*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3DA*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3DB*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3DC*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3DD*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3DE*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3DF*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3E0*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3E1*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3E4*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK }, - /*0x3E5*/ { "SMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate }, - /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab }, - /*0x3E8*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3E9*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankSwapItems }, - /*0x3EA*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab }, - /*0x3EB*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankUpdateTab }, - /*0x3EC*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankDepositMoney }, - /*0x3ED*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankWithdrawMoney }, - /*0x3EE*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery }, - /*0x3EF*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetChannelWatch }, - /*0x3F0*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3F1*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3F2*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3F3*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3F4*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3F5*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3F6*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3F7*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3F8*/ { "CMSG_SPELLCLICK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick }, - /*0x3F9*/ { "SMSG_LOOT_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3FA*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3FB*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x3FC*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x3FD*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions }, - /*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn }, - /*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode }, - /*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMirrorImageDataRequest }, - /*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x406*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x407*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess }, - /*0x408*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x409*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode }, - /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText }, - /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText }, - /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel }, - /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleChannelDeclineInvite }, - /*0x411*/ { "SMSG_GROUPACTION_THROTTLED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x414*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed }, - /*0x415*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x416*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x417*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery}, - /*0x418*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x419*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames }, - /*0x41A*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x41B*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x41C*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x41D*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel }, - /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x424*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance }, - /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x428*/ { "SMSG_BARBER_SHOP_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetCalendar }, - /*0x42A*/ { "CMSG_CALENDAR_GET_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetEvent }, - /*0x42B*/ { "CMSG_CALENDAR_GUILD_FILTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter }, - /*0x42C*/ { "CMSG_CALENDAR_ARENA_TEAM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarArenaTeam }, - /*0x42D*/ { "CMSG_CALENDAR_ADD_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent }, - /*0x42E*/ { "CMSG_CALENDAR_UPDATE_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent }, - /*0x42F*/ { "CMSG_CALENDAR_REMOVE_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent }, - /*0x430*/ { "CMSG_CALENDAR_COPY_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarCopyEvent }, - /*0x431*/ { "CMSG_CALENDAR_EVENT_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventInvite }, - /*0x432*/ { "CMSG_CALENDAR_EVENT_RSVP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRsvp }, - /*0x433*/ { "CMSG_CALENDAR_EVENT_REMOVE_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRemoveInvite }, - /*0x434*/ { "CMSG_CALENDAR_EVENT_STATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventStatus }, - /*0x435*/ { "CMSG_CALENDAR_EVENT_MODERATOR_STATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventModeratorStatus}, - /*0x436*/ { "SMSG_CALENDAR_SEND_CALENDAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x437*/ { "SMSG_CALENDAR_SEND_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x438*/ { "SMSG_CALENDAR_FILTER_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x439*/ { "SMSG_CALENDAR_ARENA_TEAM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x43A*/ { "SMSG_CALENDAR_EVENT_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x43B*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x43C*/ { "SMSG_CALENDAR_EVENT_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x43D*/ { "SMSG_CALENDAR_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x43E*/ { "SMSG_CALENDAR_RAID_LOCKOUT_ADDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x43F*/ { "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x440*/ { "SMSG_CALENDAR_EVENT_INVITE_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x441*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x442*/ { "SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x443*/ { "SMSG_CALENDAR_EVENT_REMOVED_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x444*/ { "SMSG_CALENDAR_EVENT_UPDATED_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x445*/ { "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x446*/ { "CMSG_CALENDAR_COMPLAIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarComplain }, - /*0x447*/ { "CMSG_CALENDAR_GET_NUM_PENDING", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetNumPending }, - /*0x448*/ { "SMSG_CALENDAR_SEND_NUM_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x449*/ { "CMSG_SAVE_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x44A*/ { "SMSG_NOTIFY_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x44B*/ { "CMSG_PLAY_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x44C*/ { "SMSG_PLAY_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x44D*/ { "CMSG_LOAD_DANCES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x44E*/ { "CMSG_STOP_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x44F*/ { "SMSG_STOP_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x450*/ { "CMSG_SYNC_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x451*/ { "CMSG_DANCE_QUERY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x452*/ { "SMSG_DANCE_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x453*/ { "SMSG_INVALIDATE_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x454*/ { "CMSG_DELETE_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x455*/ { "SMSG_LEARNED_DANCE_MOVES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x456*/ { "CMSG_LEARN_DANCE_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x457*/ { "CMSG_UNLEARN_DANCE_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x458*/ { "CMSG_SET_RUNE_COUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x459*/ { "CMSG_SET_RUNE_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x45A*/ { "MSG_MOVE_SET_PITCH_RATE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x45B*/ { "MSG_MOVE_SET_PITCH_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x45C*/ { "SMSG_FORCE_PITCH_RATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x45F*/ { "CMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x460*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x461*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory }, - /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x466*/ { "CMSG_SET_GLYPH_SLOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x467*/ { "CMSG_SET_GLYPH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x468*/ { "SMSG_ACHIEVEMENT_EARNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x469*/ { "SMSG_DYNAMIC_DROP_ROLL_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x46A*/ { "SMSG_CRITERIA_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x46B*/ { "CMSG_QUERY_INSPECT_ACHIEVEMENTS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements }, - /*0x46C*/ { "SMSG_RESPOND_INSPECT_ACHIEVEMENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x46D*/ { "CMSG_DISMISS_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissControlledVehicle }, - /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x471*/ { "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCustomize }, - /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestVehicleExit }, - /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle}, - /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle}, - /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle}, - /*0x47A*/ { "CMSG_PET_LEARN_TALENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent }, - /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x47C*/ { "SMSG_SET_PHASE_SHIFT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x47D*/ { "SMSG_ALL_ACHIEVEMENT_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x47E*/ { "CMSG_FORCE_SAY_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x47F*/ { "SMSG_HEALTH_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x480*/ { "SMSG_POWER_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x481*/ { "CMSG_GAMEOBJ_REPORT_USE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameobjectReportUse }, - /*0x482*/ { "SMSG_HIGHEST_THREAT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x483*/ { "SMSG_THREAT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x484*/ { "SMSG_THREAT_REMOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x485*/ { "SMSG_THREAT_CLEAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x486*/ { "SMSG_CONVERT_RUNE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x487*/ { "SMSG_RESYNC_RUNES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x488*/ { "SMSG_ADD_RUNE_POWER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x489*/ { "CMSG_START_QUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x48A*/ { "CMSG_REMOVE_GLYPH", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRemoveGlyph }, - /*0x48B*/ { "CMSG_DUMP_OBJECTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x48C*/ { "SMSG_DUMP_OBJECTS_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x48D*/ { "CMSG_DISMISS_CRITTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter }, - /*0x48E*/ { "SMSG_NOTIFY_DEST_LOC_SPELL_CAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x48F*/ { "CMSG_AUCTION_LIST_PENDING_SALES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListPendingSales }, - /*0x490*/ { "SMSG_AUCTION_LIST_PENDING_SALES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x491*/ { "SMSG_MODIFY_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x492*/ { "SMSG_PET_UPDATE_COMBO_POINTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x493*/ { "CMSG_ENABLETAXI", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes }, - /*0x494*/ { "SMSG_PRE_RESURRECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x495*/ { "SMSG_AURA_UPDATE_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x496*/ { "SMSG_AURA_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x497*/ { "CMSG_FLOOD_GRACE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle}, - /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect }, - /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4A0*/ { "CMSG_SERVER_INFO_QUERY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4A1*/ { "SMSG_SERVER_INFO_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4A2*/ { "CMSG_CHECK_LOGIN_CRITERIA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4A4*/ { "CMSG_SET_BREATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4A5*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4A6*/ { "SMSG_BATTLEGROUND_INFO_THROTTLED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEnterPlayerVehicle }, - /*0x4A9*/ { "CMSG_CONTROLLER_EJECT_PASSENGER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEjectPassenger }, - /*0x4AA*/ { "SMSG_PET_GUIDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4AC*/ { "CMSG_CHANGE_GDF_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4AD*/ { "CMSG_SET_ARENA_TEAM_RATING_BY_INDEX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4AE*/ { "CMSG_SET_ARENA_TEAM_WEEKLY_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4AF*/ { "CMSG_SET_ARENA_TEAM_SEASON_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4B0*/ { "CMSG_SET_ARENA_MEMBER_WEEKLY_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4B1*/ { "CMSG_SET_ARENA_MEMBER_SEASON_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4B2*/ { "SMSG_ITEM_REFUND_INFO_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4B3*/ { "CMSG_ITEM_REFUND_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest }, - /*0x4B4*/ { "CMSG_ITEM_REFUND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund }, - /*0x4B5*/ { "SMSG_ITEM_REFUND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4B6*/ { "CMSG_CORPSE_MAP_POSITION_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery }, - /*0x4B7*/ { "SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4B8*/ { "CMSG_UNUSED5", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL }, - /*0x4B9*/ { "CMSG_UNUSED6", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4BA*/ { "CMSG_CALENDAR_EVENT_SIGNUP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventSignup }, - /*0x4BB*/ { "SMSG_CALENDAR_CLEAR_PENDING_ACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4BC*/ { "SMSG_EQUIPMENT_SET_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4BD*/ { "CMSG_EQUIPMENT_SET_SAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave }, - /*0x4BE*/ { "CMSG_UPDATE_PROJECTILE_POSITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition }, - /*0x4BF*/ { "SMSG_SET_PROJECTILE_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4C0*/ { "SMSG_TALENTS_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4C1*/ { "CMSG_LEARN_PREVIEW_TALENTS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalents }, - /*0x4C2*/ { "CMSG_LEARN_PREVIEW_TALENTS_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalentsPet }, - /*0x4C3*/ { "CMSG_SET_ACTIVE_TALENT_GROUP_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4C4*/ { "CMSG_GM_GRANT_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4C5*/ { "CMSG_GM_REMOVE_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4C6*/ { "CMSG_GM_SET_CRITERIA_FOR_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4C7*/ { "SMSG_ARENA_OPPONENT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4C8*/ { "SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4C9*/ { "CMSG_PROFILEDATA_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4CA*/ { "SMSG_PROFILEDATA_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4CB*/ { "CMSG_START_BATTLEFIELD_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4CC*/ { "CMSG_END_BATTLEFIELD_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4CE*/ { "SMSG_MOVE_GRAVITY_DISABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4CF*/ { "CMSG_MOVE_GRAVITY_DISABLE_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4D0*/ { "SMSG_MOVE_GRAVITY_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4D1*/ { "CMSG_MOVE_GRAVITY_ENABLE_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4D2*/ { "MSG_MOVE_GRAVITY_CHNG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4D3*/ { "SMSG_SPLINE_MOVE_GRAVITY_DISABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4D4*/ { "SMSG_SPLINE_MOVE_GRAVITY_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse }, - /*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4D7*/ { "CMSG_FORCE_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4D8*/ { "SMSG_FORCE_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4D9*/ { "CMSG_CHAR_FACTION_CHANGE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange }, - /*0x4DA*/ { "SMSG_CHAR_FACTION_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4DB*/ { "CMSG_PVP_QUEUE_STATS_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4DC*/ { "SMSG_PVP_QUEUE_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4DD*/ { "CMSG_SET_PAID_SERVICE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4E3*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4E4*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4E5*/ { "SMSG_BATTLEFIELD_MGR_EJECT_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4E6*/ { "SMSG_BATTLEFIELD_MGR_EJECTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4E7*/ { "CMSG_BATTLEFIELD_MGR_EXIT_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4E8*/ { "SMSG_BATTLEFIELD_MGR_STATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4E9*/ { "CMSG_BATTLEFIELD_MANAGER_ADVANCE_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4EA*/ { "CMSG_BATTLEFIELD_MANAGER_SET_NEXT_TRANSITION_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4EB*/ { "MSG_SET_RAID_DIFFICULTY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode }, - /*0x4EC*/ { "CMSG_TOGGLE_XP_GAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4ED*/ { "SMSG_TOGGLE_XP_GAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4EE*/ { "SMSG_GMRESPONSE_DB_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4EF*/ { "SMSG_GMRESPONSE_RECEIVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4F0*/ { "CMSG_GMRESPONSE_RESOLVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMResponseResolve }, - /*0x4F1*/ { "SMSG_GMRESPONSE_STATUS_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4F2*/ { "SMSG_GMRESPONSE_CREATE_TICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4F3*/ { "CMSG_GMRESPONSE_CREATE_TICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4F4*/ { "CMSG_SERVERINFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4F5*/ { "SMSG_SERVERINFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4F6*/ { "CMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate }, - /*0x4F7*/ { "SMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4F8*/ { "CMSG_CHAR_RACE_CHANGE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange }, - /*0x4F9*/ { "MSG_VIEW_PHASE_SHIFT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4FA*/ { "SMSG_TALENTS_INVOLUNTARILY_RESET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4FB*/ { "CMSG_DEBUG_SERVER_GEO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4FC*/ { "SMSG_DEBUG_SERVER_GEO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4FD*/ { "SMSG_LOOT_SLOT_CHANGED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x4FE*/ { "UMSG_UPDATE_GROUP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x4FF*/ { "CMSG_READY_FOR_ACCOUNT_DATA_TIMES", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadyForAccountDataTimes }, - /*0x500*/ { "CMSG_QUERY_QUESTS_COMPLETED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted }, - /*0x501*/ { "SMSG_QUERY_QUESTS_COMPLETED_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x502*/ { "CMSG_GM_REPORT_LAG", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag }, - /*0x503*/ { "CMSG_AFK_MONITOR_INFO_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x504*/ { "SMSG_AFK_MONITOR_INFO_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x505*/ { "CMSG_AFK_MONITOR_INFO_CLEAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x506*/ { "SMSG_CORPSE_IS_NOT_IN_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x507*/ { "CMSG_GM_NUKE_CHARACTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x508*/ { "CMSG_SET_ALLOW_LOW_LEVEL_RAID1", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x509*/ { "CMSG_SET_ALLOW_LOW_LEVEL_RAID2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x50A*/ { "SMSG_CAMERA_SHAKE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x50B*/ { "SMSG_UPDATE_ITEM_ENCHANTMENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x50C*/ { "CMSG_SET_CHARACTER_MODEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x50D*/ { "SMSG_REDIRECT_CLIENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x50E*/ { "CMSG_REDIRECTION_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x50F*/ { "SMSG_SUSPEND_COMMS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x510*/ { "CMSG_SUSPEND_COMMS_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x511*/ { "SMSG_FORCE_SEND_QUEUED_PACKETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x512*/ { "CMSG_REDIRECTION_AUTH_PROOF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x513*/ { "CMSG_DROP_NEW_CONNECTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x514*/ { "SMSG_SEND_ALL_COMBAT_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x515*/ { "SMSG_OPEN_LFG_DUNGEON_FINDER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x516*/ { "SMSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x517*/ { "CMSG_MOVE_SET_COLLISION_HGT_ACK", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x518*/ { "MSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x519*/ { "CMSG_CLEAR_RANDOM_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x51A*/ { "CMSG_CLEAR_HOLIDAY_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x51B*/ { "CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x51C*/ { "SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x51D*/ { "SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x51E*/ { "SMSG_COMPRESSED_UNKNOWN_1310", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, +#define DEFINE_OPCODE_HANDLER(opcode, status, processing, handler) \ + if (opcode == 0) \ + sLog->outError(LOG_FILTER_NETWORKIO, "Opcode %s got value 0", #opcode); \ + if (opcode < NUM_OPCODE_HANDLERS) { \ + if (opcodeTable[opcode] != NULL) \ + { \ + sLog->outError(LOG_FILTER_NETWORKIO, "Tried to override handler of %s with %s (opcode %u)", \ + opcodeTable[opcode]->name, #opcode, opcode); \ + } \ + else opcodeTable[opcode] = new OpcodeHandler(#opcode, #opcode##"_COMPRESSED", status, processing, handler); \ + } + + memset(opcodeTable, 0, sizeof(opcodeTable)); + + DEFINE_OPCODE_HANDLER(CMSG_ACCEPT_LEVEL_GRANT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel ); + DEFINE_OPCODE_HANDLER(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_ACTIVATETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_ACTIVATETAXIEXPRESS, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiExpressOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ADDON_REGISTERED_PREFIXES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_ADD_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddFriendOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_ADD_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddIgnoreOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ADD_VOICE_IGNORE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_ALTER_APPEARANCE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance ); + DEFINE_OPCODE_HANDLER(CMSG_AREATRIGGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaTriggerOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_AREA_SPIRIT_HEALER_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode); + DEFINE_OPCODE_HANDLER(CMSG_AREA_SPIRIT_HEALER_QUEUE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamAcceptOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_CREATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDeclineOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDisbandOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamInviteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaderOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamQueryOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_REMOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRemoveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRosterOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_ATTACKSTOP, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_ATTACKSWING, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_OWNER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListOwnerItems ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_PENDING_SALES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListPendingSales ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_PLACE_BID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionPlaceBid ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_REMOVE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionRemoveItem ); + //DEFINE_OPCODE_HANDLER(CMSG_AUCTION_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem ); + DEFINE_OPCODE_HANDLER(CMSG_AUTH_SESSION, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTOBANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTOEQUIP_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_AUTOEQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_AUTOEQUIP_ITEM_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_BANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_JOIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LEAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_PORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_REQUEST_SCORE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); Need to send the response + DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN_ARENA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN_RATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BOT_DETECTED2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BUG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_BUSY_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_BUYBACK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem ); + DEFINE_OPCODE_HANDLER(CMSG_BUY_BANK_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_ADD_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_ARENA_TEAM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarArenaTeam ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_COMPLAIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarComplain ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_COPY_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarCopyEvent ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventInvite ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_MODERATOR_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventModeratorStatus); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_REMOVE_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRemoveInvite ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_RSVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRsvp ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_SIGNUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventStatus ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GET_CALENDAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetCalendar ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GET_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetEvent ); + DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GET_NUM_PENDING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetNumPending ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GUILD_FILTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_REMOVE_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_UPDATE_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent ); + DEFINE_OPCODE_HANDLER(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CANCEL_AUTO_REPEAT_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode); + DEFINE_OPCODE_HANDLER(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CANCEL_CHANNELLING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling ); + //DEFINE_OPCODE_HANDLER(CMSG_CANCEL_GROWTH_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_CANCEL_MOUNT_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelMountAuraOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CANCEL_QUEUED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CANCEL_TEMP_ENCHANTMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode); + DEFINE_OPCODE_HANDLER(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode); + DEFINE_OPCODE_HANDLER(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANGEPLAYER_DIFFICULTY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_ANNOUNCEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncements ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_BAN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelBan ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_DISPLAY_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelDisplayListQuery ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelInvite ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_KICK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelKick ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelList ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_MODERATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_MODERATOR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerator ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_MUTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelMute ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_OWNER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelOwner ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_PASSWORD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelPassword ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_ROSTER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_SET_OWNER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelSetOwner ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_SILENCE_ALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_SILENCE_VOICE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNBAN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnban ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNMODERATOR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmoderator ); + DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNMUTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmute ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNSILENCE_ALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNSILENCE_VOICE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_VOICE_OFF, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_VOICE_ON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_CREATE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCreateOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCustomize ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharDeleteOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_FACTION_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_RACE_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange ); + DEFINE_OPCODE_HANDLER(CMSG_CHAR_RENAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharRenameOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CHAT_FILTERED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHAT_IGNORED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_CHANNEL_WATCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_ENTER_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_EXIT_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_GET_MAP_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_GET_PARTY_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_GET_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_INSTANCE_COMMAND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_START_WARGAME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMPLAIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleComplainOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_COMPLETE_CINEMATIC, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCompleteCinematic ); + //DEFINE_OPCODE_HANDLER(CMSG_COMPLETE_MOVIE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CONNECT_TO_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_CONTACT_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleContactListOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_CORPSE_MAP_POSITION_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery ); + DEFINE_OPCODE_HANDLER(CMSG_CREATURE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleCreatureQueryOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_DANCE_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DECLINE_CHANNEL_INVITE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleChannelDeclineInvite ); + //DEFINE_OPCODE_HANDLER(CMSG_DELETEEQUIPMENT_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_DEL_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_DEL_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_DEL_VOICE_IGNORE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_DESTROY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDestroyItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_DESTROY_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DISMISS_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissControlledVehicle ); + //DEFINE_OPCODE_HANDLER(CMSG_DISMISS_CRITTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter ); + DEFINE_OPCODE_HANDLER(CMSG_DUEL_ACCEPTED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelAcceptedOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_DUEL_CANCELLED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelCancelledOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_DUNGEON_FINDER_GET_SYSTEM_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_EJECT_PASSENGER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEmoteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_ENABLETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes ); + DEFINE_OPCODE_HANDLER(CMSG_ENABLE_NAGLE, STATUS_NEVER , PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess ); + //DEFINE_OPCODE_HANDLER(CMSG_EQUIPMENT_SET_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete ); + //DEFINE_OPCODE_HANDLER(CMSG_EQUIPMENT_SET_SAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave ); + //DEFINE_OPCODE_HANDLER(CMSG_EQUIPMENT_SET_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse ); + //DEFINE_OPCODE_HANDLER(CMSG_FAR_SIGHT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleFarSightOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCE_MOVE_ROOT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveRootAck ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCE_MOVE_UNROOT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveUnRootAck ); + DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJECT_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGameObjectQueryOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJ_REPORT_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameobjectReportUse ); + DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJ_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameObjectUseOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GAMESPEED_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GAMETIME_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GETDEATHBINDZONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GET_MAIL_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetMailList ); + DEFINE_OPCODE_HANDLER(CMSG_GET_MIRRORIMAGE_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMirrorImageDataRequest ); + //DEFINE_OPCODE_HANDLER(CMSG_GHOST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GMRESPONSE_RESOLVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMResponseResolve ); + //DEFINE_OPCODE_HANDLER(CMSG_GMSURVEY_SUBMIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMSurveySubmit ); + //DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_CREATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketCreateOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_DELETETICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_GETTICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketGetTicketOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_SYSTEMSTATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_UPDATETEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_INVIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_NUKE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_REPORT_LAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_SET_SECURITY_GROUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GOSSIP_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GOSSIP_SELECT_OPTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GRANT_LEVEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel ); + DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteResponseOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_ASSISTANT_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_CANCEL, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_CHANGE_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupChangeSubGroupOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDisbandOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_RAID_CONVERT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_REQUEST_JOIN_UPDATES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_ROLES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_SWAP_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSwapSubGroupOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE_GUID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteGuidOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACHIEVEMENT_PROGRESS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAchievementProgressQuery); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAddRankOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAssignRankOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankDepositMoney ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_NOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_REM_MONEY_WITHDRAW_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_SET_TAB_TEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankSwapItems ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankUpdateTab ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankWithdrawMoney ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_CHANGE_NAME_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_CREATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildCreateOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeclineOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEL_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDelRankOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInfoOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaderOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_MEMBER_SEND_SOR_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_MOTD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_PROMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_RANKS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryRanksOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_REMOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_REQUEST_CHALLENGE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_REQUEST_MAX_DAILY_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRosterOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_ACHIEVEMENT_TRACKING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_GUILD_MASTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_NOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetNoteOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_RANK_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetRankPermissionsOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_GUILD_SWITCH_RANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect ); + DEFINE_OPCODE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_WARNING_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_ITEM_REFUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund ); + DEFINE_OPCODE_HANDLER(CMSG_ITEM_REFUND_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest ); + //DEFINE_OPCODE_HANDLER(CMSG_ITEM_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery ); + DEFINE_OPCODE_HANDLER(CMSG_JOIN_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleJoinChannel ); + DEFINE_OPCODE_HANDLER(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess ); + DEFINE_OPCODE_HANDLER(CMSG_LEARN_PREVIEW_TALENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalents ); + DEFINE_OPCODE_HANDLER(CMSG_LEARN_PREVIEW_TALENTS_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalentsPet ); + DEFINE_OPCODE_HANDLER(CMSG_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnTalentOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LEAVE_BATTLEFIELD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveBattlefieldOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LEAVE_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveChannel ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_GET_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_GET_STATUS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_LFR_JOIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_LFR_LEAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_PARTY_LOCK_INFO_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_PROPOSAL_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgProposalResultOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_BOOT_VOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetBootVoteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_COMMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_ROLES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetRolesOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_TELEPORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgTeleportOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_ADD_RECRUIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_BROWSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_DECLINE_RECRUIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_APPLICATIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_RECRUITS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_JOIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_POST_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleLoadScreenOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOGOUT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutRequestOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOG_DISCONNECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess ); + DEFINE_OPCODE_HANDLER(CMSG_LOOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_LOOT_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_LOOT_MASTER_GIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOOT_METHOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMethodOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOOT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMoneyOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOOT_RELEASE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootReleaseOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_LOOT_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootRoll ); + DEFINE_OPCODE_HANDLER(CMSG_MAIL_CREATE_TEXT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailCreateTextItem ); + DEFINE_OPCODE_HANDLER(CMSG_MAIL_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailDelete ); + DEFINE_OPCODE_HANDLER(CMSG_MAIL_MARK_AS_READ, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailMarkAsRead ); + DEFINE_OPCODE_HANDLER(CMSG_MAIL_RETURN_TO_SENDER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailReturnToSender ); + DEFINE_OPCODE_HANDLER(CMSG_MAIL_TAKE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeItem ); + DEFINE_OPCODE_HANDLER(CMSG_MAIL_TAKE_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeMoney ); + //DEFINE_OPCODE_HANDLER(CMSG_MEETINGSTONE_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_BATTLEGROUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_AFK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_BATTLEGROUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_DND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_SAY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_YELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_MINIGAME_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_MOUNTSPECIAL_ANIM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHNG_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FALL_RESET, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveHoverAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_KNOCK_BACK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveKnockBackAck ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_NOT_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveNotActiveMover ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_COLLISION_HEIGHT_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_RELATIVE_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_VEHICLE_REC_ID_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SPLINE_DONE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSplineDoneOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_MOVE_TIME_SKIPPED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_TOGGLE_COLLISION_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_WATER_WALK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck ); + DEFINE_OPCODE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNameQueryOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_NEW_SPELL_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera ); + DEFINE_OPCODE_HANDLER(CMSG_NPC_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_OBJECT_UPDATE_FAILED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_OBJECT_UPDATE_RESCUED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_OFFER_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_OPENING_CINEMATIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_OPT_OUT_OF_LOOT, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PAGE_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePageTextQueryOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PARTY_SILENCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PARTY_UNSILENCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuyOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_PETITION_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionQueryOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_PETITION_SHOWLIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowListOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowSignOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_PETITION_SIGN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionSignOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_ABANDON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_ACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_PET_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_NAME_CACHE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_RENAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_SET_ACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_SPELL_AUTOCAST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSpellAutocastOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_STOP_ATTACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetStopAttack ); + DEFINE_OPCODE_HANDLER(CMSG_PING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess ); + DEFINE_OPCODE_HANDLER(CMSG_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayedTime ); + //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_DIFFICULTY_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_PLAYER_LOGIN, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLoginOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_LOGOUT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLogoutOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_VEHICLE_ENTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEnterPlayerVehicle ); + //DEFINE_OPCODE_HANDLER(CMSG_PLAY_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_PUSHQUESTTOPARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty ); + //DEFINE_OPCODE_HANDLER(CMSG_PVP_LOG_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_BATTLEFIELD_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_COMPLETION_NPC_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MAX_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBER_RECIPES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_RECIPES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_REWARDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_XP, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryXPOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements ); + DEFINE_OPCODE_HANDLER(CMSG_QUERY_QUESTS_COMPLETED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted ); + DEFINE_OPCODE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryTimeOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_ACCEPT_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCancel ); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverChooseRewardOpcode); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_COMPLETE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCompleteQuest ); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_QUEST_AUTOLAUNCH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQuestAutoLaunch ); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery); + DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode); + DEFINE_OPCODE_HANDLER(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest ); + //DEFINE_OPCODE_HANDLER(CMSG_QUESTLOG_SWAP_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogSwapQuest ); + DEFINE_OPCODE_HANDLER(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept ); + //DEFINE_OPCODE_HANDLER(CMSG_QUEST_NPC_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_QUEST_POI_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery ); + //DEFINE_OPCODE_HANDLER(CMSG_QUEST_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomizeCharNameOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_READY_FOR_ACCOUNT_DATA_TIMES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadyForAccountDataTimes ); + DEFINE_OPCODE_HANDLER(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem ); + DEFINE_OPCODE_HANDLER(CMSG_REALM_SPLIT, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_RECLAIM_CORPSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReclaimCorpseOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_REDIRECTION_AUTH_PROOF, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_REFORGE_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleReforgeItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_REORDER_CHARACTERS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_REPAIR_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepairItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_REPLACE_ACCOUNT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_REPOP_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepopRequestOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_REPORT_PVP_AFK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK ); + DEFINE_OPCODE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_CEMETERY_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_GUILD_PARTY_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_REQUEST_HOTFIX, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_INSPECT_RATED_BG_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PET_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PVP_OPTIONS_ENABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PVP_REWARDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RAID_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RATED_BG_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RATED_BG_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RESEARCH_HISTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_EXIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestVehicleExit ); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_NEXT_SEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_PREV_SEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle); + //DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_SWITCH_SEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle); + //DEFINE_OPCODE_HANDLER(CMSG_RESET_FACTION_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_RESET_INSTANCES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResetInstancesOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_RESURRECT_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResurrectResponseOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_RETURN_TO_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReturnToGraveyard ); + //DEFINE_OPCODE_HANDLER(CMSG_ROLE_POLL_BEGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SAVE_CUF_PROFILES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SAVE_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SEARCH_LFG_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrSearchOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SEARCH_LFG_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrLeaveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SELF_RES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSelfResOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSellItemOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SEND_MAIL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendMail ); + //DEFINE_OPCODE_HANDLER(CMSG_SEND_SOR_REQUEST_VIA_ADDRESS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SEND_SOR_REQUEST_VIA_BNET_ACCOUNT_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SERVERTIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SETDEATHBINDPOINT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SETSHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIONBAR_TOGGLES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarToggles ); + DEFINE_OPCODE_HANDLER(CMSG_SET_ACTION_BUTTON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionButtonOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveMoverOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ALLOW_LOW_LEVEL_RAID1, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ALLOW_LOW_LEVEL_RAID2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_CHANNEL_WATCH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetChannelWatch ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_CONTACT_NOTES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetContactNotesOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_CURRENCY_FLAGS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_ATWAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_CHEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionCheat ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_INACTIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_LFG_COMMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetCommentOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PET_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PREFERED_CEMETERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PRIMARY_TALENT_TREE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_RELATIVE_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_SKILL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SET_TITLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTitleOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_TRADE_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SET_TRADE_GOLD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SET_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_VEHICLE_REC_ID_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SET_WATCHED_FACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetWatchedFactionOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SHOWING_CLOAK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SHOWING_HELM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SOCKET_GEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSocketOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_SPELLCLICK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick ); + //DEFINE_OPCODE_HANDLER(CMSG_SPIRIT_HEALER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpiritHealerActivateOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_SPLIT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSplitItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_STANDSTATECHANGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStandStateChangeOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_START_QUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_STOP_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_STORE_LOOT_IN_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SUBMIT_BUG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SUBMIT_COMPLAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SUGGESTION_SUBMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SUMMON_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSummonResponseOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SUSPEND_TOKEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapInvItemOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapItem ); + //DEFINE_OPCODE_HANDLER(CMSG_SYNC_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXICLEARALLNODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXIENABLEALLNODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXINODE_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXIQUERYAVAILABLENODES, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXISHOWNODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TELEPORT_TO_UNIT, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TEXT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTextEmoteOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_TIME_ADJUSTMENT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_TIME_SYNC_RESP, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeSyncResp ); + //DEFINE_OPCODE_HANDLER(CMSG_TIME_SYNC_RESP_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TOGGLE_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP ); + //DEFINE_OPCODE_HANDLER(CMSG_TOTEM_DESTROYED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed ); + //DEFINE_OPCODE_HANDLER(CMSG_TRAINER_BUY_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_TRANSMOGRIFY_ITEMS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTransmogrifyItems ); + //DEFINE_OPCODE_HANDLER(CMSG_TRIGGER_CINEMATIC_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_TUTORIAL_CLEAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear ); + DEFINE_OPCODE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag ); + //DEFINE_OPCODE_HANDLER(CMSG_TUTORIAL_RESET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialReset ); + DEFINE_OPCODE_HANDLER(CMSG_UNACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SKILL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SPECIALIZATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNREGISTER_ALL_ADDON_PREFIXES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData ); + //DEFINE_OPCODE_HANDLER(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); + //DEFINE_OPCODE_HANDLER(CMSG_UPDATE_PROJECTILE_POSITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); + //DEFINE_OPCODE_HANDLER(CMSG_USED_FOLLOW, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_VIOLENCE_LEVEL, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleViolenceLevel ); + DEFINE_OPCODE_HANDLER(CMSG_VOICE_SESSION_ENABLE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_VOID_STORAGE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidStorageQuery ); + DEFINE_OPCODE_HANDLER(CMSG_VOID_STORAGE_TRANSFER, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidStorageTransfer ); + DEFINE_OPCODE_HANDLER(CMSG_VOID_STORAGE_UNLOCK, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidStorageUnlock ); + DEFINE_OPCODE_HANDLER(CMSG_VOID_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidSwapItem ); + //DEFINE_OPCODE_HANDLER(CMSG_WARDEN_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleWardenDataOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_WARGAME_ACCEPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_WARGAME_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_WHO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_WHOIS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate ); + //DEFINE_OPCODE_HANDLER(CMSG_WORLD_TELEPORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_WRAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode ); + DEFINE_OPCODE_HANDLER(CMSG_ZONEUPDATE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleZoneUpdateOpcode ); + DEFINE_OPCODE_HANDLER(MSG_AUCTION_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode); + DEFINE_OPCODE_HANDLER(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_CHANNEL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_CORPSE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_GM_BIND_OTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_SUMMON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GUILD_BANK_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery ); + //DEFINE_OPCODE_HANDLER(MSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_INSPECT_ARENA_TEAMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_LIST_STABLED_PETS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_FALL_LAND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_GRAVITY_CHNG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_HEARTBEAT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_JUMP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_ALL_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FACING, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FLIGHT_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_PITCH, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RAW_POSITION_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_SWIM_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_TURN_RATE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_WALK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_ASCEND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_BACKWARD, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_DESCEND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_FORWARD, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_PITCH_DOWN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_PITCH_UP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_STRAFE_LEFT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_STRAFE_RIGHT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_TURN_LEFT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_START_TURN_RIGHT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_ASCEND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_PITCH, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_STRAFE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_TURN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_TIME_SKIPPED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_FALL_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_MOUSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_NOTIFY_PARTY_SQUELCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_PARTY_ASSIGNMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode ); + DEFINE_OPCODE_HANDLER(MSG_PETITION_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionDeclineOpcode ); + DEFINE_OPCODE_HANDLER(MSG_PETITION_RENAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_QUERY_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText ); + DEFINE_OPCODE_HANDLER(MSG_QUERY_NEXT_MAIL_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryNextMailTime ); + DEFINE_OPCODE_HANDLER(MSG_QUEST_PUSH_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult ); + DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_FINISHED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckFinishedOpcode); + //DEFINE_OPCODE_HANDLER(MSG_RAID_TARGET_UPDATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomRollOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode ); + DEFINE_OPCODE_HANDLER(MSG_SET_DUNGEON_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetDungeonDifficultyOpcode); + DEFINE_OPCODE_HANDLER(MSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_START_MOVE_FORWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_TABARDVENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode); + DEFINE_OPCODE_HANDLER(MSG_TALENT_WIPE_CONFIRM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTalentWipeConfirmOpcode ); + DEFINE_OPCODE_HANDLER(MSG_VERIFY_CONNECTIVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess ); + DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MOVEMENT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_OPPONENT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_NOTINRANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_OWNER_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_OWNER_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AUCTION_REMOVED_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AURA_POINTS_DEPLETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_AURA_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_AURA_UPDATE_ALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_AUTH_CHALLENGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_AUTH_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AVAILABLE_VOICE_CHANNEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_AVERAGE_ITEM_LEVEL_INFORM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BARBER_SHOP_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECT_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_STATE_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PLAYER_POSITIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PORT_DENIED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_RATED_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS1, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS3, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS4, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_BUY_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_ACTION_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_REMOVED_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_UPDATED_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_FILTER_GUILD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_ADDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_SEND_CALENDAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_SEND_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_SEND_NUM_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_UPDATE_INVITE_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CAMERA_SHAKE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CANCEL_AUTO_REPEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CANCEL_COMBAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHANNEL_MEMBER_COUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHAR_DELETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHAR_ENUM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_NOT_IN_PARTY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_PLAYER_NOT_FOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_RESTRICTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_SERVER_DISCONNECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_SERVER_RECONNECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHAT_WRONG_FACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHECK_FOR_BOTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_BOSS_EMOTES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_COMBAT_EVENT_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMBAT_LOG_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_PARTY_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_STATE_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPLAIN_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPLETION_NPC_RESPONCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPLETION_NPC_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_CHAR_ENUM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_GUILD_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_MOVES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMSAT_CONNECT_FAIL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMSAT_DISCONNECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMSAT_RECONNECT_TRY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CORPSE_NOT_IN_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CREATURE_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_RESTORED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CUSTOM_LOAD_SCREEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DAMAGE_DONE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DESTROY_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DIFFERENT_INSTANCE_FROM_PARTY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DISENCHANT_CREDIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DISMOUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DISMOUNTRESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DISPEL_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DISPLAY_GAME_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DROP_NEW_CONNECTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DUEL_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DUEL_COUNTDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DUEL_INBOUNDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DUEL_OUTOFBOUNDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DUEL_REQUESTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_DUEL_WINNER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DUMP_RIDE_TICKETS_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ECHO_PARTY_SQUELCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_EMOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ENCHANTMENTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ENVIRONMENTALDAMAGELOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_USE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FAILED_PLAYER_CONDITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FEIGN_DEATH_RESISTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FLOOD_DETECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORCEACTIONSHOW, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORCE_DISPLAY_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORCE_SEND_QUEUED_PACKETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORCE_SET_VEHICLE_REC_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORGE_MASTER_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_CUSTOM_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_PAGETEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_RESET_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GAMESPEED_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GAMETIME_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GAMETIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GAME_EVENT_DEBUG_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_DB_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_RECEIVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_STATUS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_CREATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_DELETETICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_GETTICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_SYSTEMSTATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_UPDATETEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GM_MESSAGECHAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GM_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GM_TICKET_STATUS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GROUP_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_JOINED_BATTLEGROUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_LEADER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_ROLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_REM_MONEY_WITHDRAW_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT_2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_INVITE_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_KNOWN_RECIPES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MAX_DAILY_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_FOR_RECIPE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_RANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_RANKS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_RECIPES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_RENAMED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_SET_NOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_TRADESKILL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_UPDATE_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSPECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSPECT_RESULTS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSPECT_TALENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_DIFFICULTY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_LOCK_WARNING_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INVALIDATE_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_ADD_PASSIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ITEM_REFUND_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_REFUND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_REMOVE_PASSIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_SEND_PASSIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_TEXT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_JOINED_BATTLEGROUND_QUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LEVELUP_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_DISABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_OFFER_CONTINUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_OPEN_FROM_GOSSIP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_PARTY_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_PLAYER_REWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_PROPOSAL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_QUEUE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_ROLE_CHECK_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_ROLE_CHOSEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_SLOT_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_TELEPORT_DENIED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_PARTY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_SEARCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS_NONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_BROWSE_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_SEARCH_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_CANCEL_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_ALL_PASSED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_CLEAR_MONEY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LOOT_CONTENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LOOT_ITEM_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_MASTER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_MONEY_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_RELEASE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LOOT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_ROLL_WON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_SLOT_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOOT_START_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_IN_PROGRESS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_MEMBER_ADDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_SETQUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_SETUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MIRRORIMAGE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MOUNTSPECIAL_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_COLLISION_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_COLLISION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_DISABLE_COLLISION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_DISABLE_GRAVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_ENABLE_COLLISION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_ENABLE_GRAVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_VEHICLE_REC_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_IN_AIR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_WALK_IN_AIR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_NEW_TAXI_PATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_NEW_WORLD_ABORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_NOTIFY_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_NPC_WONT_TALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PARTYKILLLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PERIODICAURALOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PETGODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PETITION_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PETITION_SHOWLIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_ACTION_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_ADDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_BROKEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_GUIDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_NAME_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PET_REMOVED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_RENAMEABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_SLOT_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PET_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PET_UPDATE_COMBO_POINTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PLAYERBINDERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAYERBOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PLAYER_DIFFICULTY_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAYER_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PLAYER_UNK_DEAD_ALIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAYER_VEHICLE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_MUSIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_IMPACT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PONG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PRE_RESURRECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_PROCRESIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PUREMOUNT_CANCELLED_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILEDTIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_THROTTLED_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RAID_SUMMON_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RATED_BG_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RATED_BG_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_READ_ITEM_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_READ_ITEM_OK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_REALM_SPLIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REAL_GROUP_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_RECEIVED_MAIL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REDIRECT_CLIENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_EXPIRED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_REFORGE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_REMOVED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REPORT_PVP_AFK_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REQUEST_PVP_REWARDS_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESEARCH_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESEARCH_SETUP_HISTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESISTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ROLE_POLL_BEGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RWHOIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SELL_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVER_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVER_PERF, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SETUP_RESEARCH_HISTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_FACTION_ATWAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SHOW_RATINGS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SOR_START_EXPERIENCE_INCOMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLBREAKLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLDAMAGESHIELD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLDISPELLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLENERGIZELOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLHEALLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLINSTAKILLLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLINTERRUPTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLLOGEXECUTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLLOGMISS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLNONMELEEDAMAGELOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLORDAMAGE_IMMUNE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELLSTEALLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPELL_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPELL_GO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_START_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_STOP_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_STOP_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_STREAMING_MOVIE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SUMMON_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SUMMON_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SUPERCEDED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TAXINODE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TEST_DROP_RATE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_THREAT_CLEAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TIME_ADJUSTMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TOGGLE_XP_GAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UNIT_HEALTH_FREQUENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UNIT_SPELLCAST_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_COMBO_POINTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UPDATE_ITEM_ENCHANTMENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICESESSION_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_CHAT_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_PARENTAL_CONTROLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_LEAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ROSTER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SET_TALKER_MUTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_VOID_ITEM_SWAP_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_CONTENTS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_TRANSFER_CHANGES, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_VOID_TRANSFER_RESULT, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WAIT_QUEUE_FINISH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WAIT_QUEUE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WARGAME_CHECK_ENTRY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WARGAME_REQUEST_SENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_WEATHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_LAST_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_RESET_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_WHO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_WHOIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_XP_GAIN_ABORTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ZONE_UNDER_ATTACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + + // These opcodes are not in WPP + + //DEFINE_OPCODE_HANDLER(CMSG_ACTIVE_PVP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_ADD_PVP_MEDAL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_ADVANCE_SPAWN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_AFK_MONITOR_INFO_CLEAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_AFK_MONITOR_INFO_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_BEGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_PROOF, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_RECODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MANAGER_ADVANCE_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MANAGER_SET_NEXT_TRANSITION_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterHelloOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BEASTMASTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BOOTME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BOT_DETECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BUY_ITEM_IN_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemInSlotOpcode ); + //DEFINE_OPCODE_HANDLER(CMSG_BUY_LOTTERY_TICKET_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_BUY_STABLE_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyStableSlot ); + //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANGE_GDF_ARENA_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHANGE_PERSONAL_ARENA_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHARACTER_POINT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_PLAYER_LOGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_PLAYER_LOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_SETMONEY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_SET_ARENA_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_SET_HONOR_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CHECK_LOGIN_CRITERIA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_EXPLORATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_HOLIDAY_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_QUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_RANDOM_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_COMPLETE_ACHIEVEMENT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CONTROLLER_EJECT_PASSENGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEjectPassenger ); + //DEFINE_OPCODE_HANDLER(CMSG_COOLDOWN_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CREATEGAMEOBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CREATEITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_CREATEMONSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DBLOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_ACTIONS_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_ACTIONS_STOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_AISTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_CHANGECELLZONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_LIST_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_PASSIVE_AURA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_SERVER_GEO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DECHARGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DELETE_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DEL_PVP_MEDAL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DESTROYMONSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DISABLE_PVP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DROP_NEW_CONNECTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_DUMP_OBJECTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_ENABLE_DAMAGE_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_END_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_EXPIRE_RAID_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FLAG_QUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FLAG_QUEST_FINISH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FLOOD_GRACE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCEACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCEACTIONONOTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCEACTIONSHOW, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCE_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_FORCE_SAY_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GET_CHANNEL_MEMBER_COUNT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetChannelMemberCount ); + //DEFINE_OPCODE_HANDLER(CMSG_GMRESPONSE_CREATE_TICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_CHARACTER_RESTORE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_CHARACTER_SAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_CREATE_ITEM_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_DESTROY_ONLINE_CORPSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_FREEZE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_GRANT_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_MOVECORPSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_NUKE_ACCOUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_NUKE_CHARACTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_REMOVE_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_REQUEST_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_RESURRECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_REVEALTO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_SET_CRITERIA_FOR_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_SHOW_COMPLAINTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_SILENCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_SUMMONMOB, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_TEACH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_UBERINVIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_UNSQUELCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_UNTEACH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_UPDATE_TICKET_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_VISION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GM_WHISPER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_GODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_KNOCKBACK_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_REQUIREMENTS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse ); + //DEFINE_OPCODE_HANDLER(CMSG_LEARN_DANCE_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LEARN_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LEVEL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LFD_PARTY_LOCK_INFO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPartyLockInfoRequestOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_LFD_PLAYER_LOCK_INFO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPlayerLockInfoRequestOpcode); + //DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_NEEDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LOAD_DANCES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LOTTERY_QUERY_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_LUA_USAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MAELSTROM_GM_SENT_MAIL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MAELSTROM_INVALIDATE_CACHE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MAELSTROM_RENAME_GUILD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MAKEMONSTERATTACKGUID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARACTER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARM_PORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_FLY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_START_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_NO_SPELL_VARIANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PERFORM_ACTION_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PETGODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_LEVEL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_UNLEARN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PET_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_AI_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PROFILEDATA_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_PVP_QUEUE_STATS_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_OBJECT_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_OBJECT_ROTATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_QUERY_VEHICLE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_RECHARGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REDIRECTION_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REFER_A_FRIEND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_REMOVE_GLYPH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRemoveGlyph ); + //DEFINE_OPCODE_HANDLER(CMSG_RUN_SCRIPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SAVE_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SEND_COMBAT_TRIGGER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SEND_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SEND_GENERAL_TRIGGER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SEND_LOCAL_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SERVERINFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SERVER_BROADCAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SERVER_COMMAND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SERVER_INFO_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIVE_TALENT_GROUP_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_MEMBER_SEASON_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_MEMBER_WEEKLY_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_TEAM_RATING_BY_INDEX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_TEAM_SEASON_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_TEAM_WEEKLY_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_BREATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_CHARACTER_MODEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_CRITERIA_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_DURABILITY_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_EXPLORATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_EXPLORATION_ALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_GLYPH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_GLYPH_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_GRANTABLE_LEVELS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PAID_SERVICE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PVP_RANK_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_PVP_TITLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_RUNE_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_RUNE_COUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_STAT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_TITLE_SUFFIX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SET_WORLDSTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SKILL_BUY_RANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SKILL_BUY_STEP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_STABLE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStablePet ); + //DEFINE_OPCODE_HANDLER(CMSG_STABLE_REVIVE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableRevivePet ); + //DEFINE_OPCODE_HANDLER(CMSG_STABLE_SWAP_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableSwapPet ); + //DEFINE_OPCODE_HANDLER(CMSG_START_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_SUSPEND_COMMS_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TARGET_CAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TARGET_SCRIPT_CAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXICLEARNODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TAXIENABLENODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TEST_DROP_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_TOGGLE_XP_GAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNCLAIM_LICENSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNDRESSPLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNITANIMTIER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_DANCE_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNSTABLE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnstablePet ); + //DEFINE_OPCODE_HANDLER(CMSG_UNUSED5, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_UNUSED6, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_USE_SKILL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_VOICE_SET_TALKER_MUTED_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_WEATHER_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_XP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(CMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_DELAY_GHOST_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_DEV_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_ACCOUNT_ONLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_CHANGE_ARENA_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_DESTROY_CORPSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_GEARRATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_GM_RESETINSTANCELIMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_INSPECT_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectHonorStatsOpcode ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_PITCH_RATE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_START_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_NULL_ACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(MSG_VIEW_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + //DEFINE_OPCODE_HANDLER(SMSG_AFK_MONITOR_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHANGEPLAYER_DIFFICULTY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHARACTER_PROFILE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHARACTER_PROFILE_REALM_CONNECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CHEAT_PLAYER_LOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_GET_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_UNKNOWN_1310, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_CORPSE_IS_NOT_IN_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DBLOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEBUGAURAPROC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_AISTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_LIST_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_SERVER_GEO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DUMP_OBJECTS_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_DYNAMIC_DROP_ROLL_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GAMETIMEBIAS_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GHOSTEE_GONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_CREATE_TICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_GOGOGO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_IGNORE_REQUIREMENTS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LOTTERY_QUERY_RESULT_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_LOTTERY_RESULT_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_MOVE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_CHARACTER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PET_UNLEARN_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PROFILEDATA_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_PVP_QUEUE_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUERY_OBJECT_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_QUERY_OBJECT_ROTATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_REMOVED_FROM_PVP_QUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESET_RANGED_COMBAT_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESUME_CAST_BAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_RESURRECT_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SCRIPT_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SEND_ALL_COMBAT_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVERINFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_PROC_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_RESIST_PUSHBACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ADJUST_PRIORITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + //DEFINE_OPCODE_HANDLER(SMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + +#undef DEFINE_OPCODE_HANDLER }; diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 65e7b3597ce..4a07e4752a8 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -25,1327 +25,1395 @@ #include "Common.h" -// Note: this include need for be sure have full definition of class WorldSession -// if this class definition not complete then VS for x64 release use different size for -// struct OpcodeHandler in this header and Opcode.cpp and get totally wrong data from -// table opcodeTable in source when Opcode.h included but WorldSession.h not included -#include "WorldSession.h" - /// List of Opcodes enum Opcodes { - MSG_NULL_ACTION = 0x000, - CMSG_BOOTME = 0x001, - CMSG_DBLOOKUP = 0x002, - SMSG_DBLOOKUP = 0x003, - CMSG_QUERY_OBJECT_POSITION = 0x004, - SMSG_QUERY_OBJECT_POSITION = 0x005, - CMSG_QUERY_OBJECT_ROTATION = 0x006, - SMSG_QUERY_OBJECT_ROTATION = 0x007, - CMSG_WORLD_TELEPORT = 0x008, - CMSG_TELEPORT_TO_UNIT = 0x009, - CMSG_ZONE_MAP = 0x00A, - SMSG_ZONE_MAP = 0x00B, - CMSG_DEBUG_CHANGECELLZONE = 0x00C, - CMSG_MOVE_CHARACTER_CHEAT = 0x00D, - SMSG_MOVE_CHARACTER_CHEAT = 0x00E, - CMSG_RECHARGE = 0x00F, - CMSG_LEARN_SPELL = 0x010, - CMSG_CREATEMONSTER = 0x011, - CMSG_DESTROYMONSTER = 0x012, - CMSG_CREATEITEM = 0x013, - CMSG_CREATEGAMEOBJECT = 0x014, - SMSG_CHECK_FOR_BOTS = 0x015, - CMSG_MAKEMONSTERATTACKGUID = 0x016, - CMSG_BOT_DETECTED2 = 0x017, - CMSG_FORCEACTION = 0x018, - CMSG_FORCEACTIONONOTHER = 0x019, - CMSG_FORCEACTIONSHOW = 0x01A, - SMSG_FORCEACTIONSHOW = 0x01B, - CMSG_PETGODMODE = 0x01C, - SMSG_PETGODMODE = 0x01D, - SMSG_REFER_A_FRIEND_EXPIRED = 0x01E, - CMSG_WEATHER_SPEED_CHEAT = 0x01F, - CMSG_UNDRESSPLAYER = 0x020, - CMSG_BEASTMASTER = 0x021, - CMSG_GODMODE = 0x022, - SMSG_GODMODE = 0x023, - CMSG_CHEAT_SETMONEY = 0x024, - CMSG_LEVEL_CHEAT = 0x025, - CMSG_PET_LEVEL_CHEAT = 0x026, - CMSG_SET_WORLDSTATE = 0x027, - CMSG_COOLDOWN_CHEAT = 0x028, - CMSG_USE_SKILL_CHEAT = 0x029, - CMSG_FLAG_QUEST = 0x02A, - CMSG_FLAG_QUEST_FINISH = 0x02B, - CMSG_CLEAR_QUEST = 0x02C, - CMSG_SEND_EVENT = 0x02D, - CMSG_DEBUG_AISTATE = 0x02E, - SMSG_DEBUG_AISTATE = 0x02F, - CMSG_DISABLE_PVP_CHEAT = 0x030, - CMSG_ADVANCE_SPAWN_TIME = 0x031, - SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x032, - CMSG_AUTH_SRP6_BEGIN = 0x033, - CMSG_AUTH_SRP6_PROOF = 0x034, - CMSG_AUTH_SRP6_RECODE = 0x035, - CMSG_CHAR_CREATE = 0x036, - CMSG_CHAR_ENUM = 0x037, - CMSG_CHAR_DELETE = 0x038, - SMSG_AUTH_SRP6_RESPONSE = 0x039, - SMSG_CHAR_CREATE = 0x03A, - SMSG_CHAR_ENUM = 0x03B, - SMSG_CHAR_DELETE = 0x03C, - CMSG_PLAYER_LOGIN = 0x03D, - SMSG_NEW_WORLD = 0x03E, - SMSG_TRANSFER_PENDING = 0x03F, - SMSG_TRANSFER_ABORTED = 0x040, - SMSG_CHARACTER_LOGIN_FAILED = 0x041, - SMSG_LOGIN_SETTIMESPEED = 0x042, - SMSG_GAMETIME_UPDATE = 0x043, - CMSG_GAMETIME_SET = 0x044, - SMSG_GAMETIME_SET = 0x045, - CMSG_GAMESPEED_SET = 0x046, - SMSG_GAMESPEED_SET = 0x047, - CMSG_SERVERTIME = 0x048, - SMSG_SERVERTIME = 0x049, - CMSG_PLAYER_LOGOUT = 0x04A, - CMSG_LOGOUT_REQUEST = 0x04B, - SMSG_LOGOUT_RESPONSE = 0x04C, - SMSG_LOGOUT_COMPLETE = 0x04D, - CMSG_LOGOUT_CANCEL = 0x04E, - SMSG_LOGOUT_CANCEL_ACK = 0x04F, - CMSG_NAME_QUERY = 0x050, - SMSG_NAME_QUERY_RESPONSE = 0x051, - CMSG_PET_NAME_QUERY = 0x052, - SMSG_PET_NAME_QUERY_RESPONSE = 0x053, - CMSG_GUILD_QUERY = 0x054, - SMSG_GUILD_QUERY_RESPONSE = 0x055, - CMSG_ITEM_QUERY_SINGLE = 0x056, - CMSG_ITEM_QUERY_MULTIPLE = 0x057, - SMSG_ITEM_QUERY_SINGLE_RESPONSE = 0x058, - SMSG_ITEM_QUERY_MULTIPLE_RESPONSE = 0x059, - CMSG_PAGE_TEXT_QUERY = 0x05A, - SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x05B, - CMSG_QUEST_QUERY = 0x05C, - SMSG_QUEST_QUERY_RESPONSE = 0x05D, - CMSG_GAMEOBJECT_QUERY = 0x05E, - SMSG_GAMEOBJECT_QUERY_RESPONSE = 0x05F, - CMSG_CREATURE_QUERY = 0x060, - SMSG_CREATURE_QUERY_RESPONSE = 0x061, - CMSG_WHO = 0x062, - SMSG_WHO = 0x063, - CMSG_WHOIS = 0x064, - SMSG_WHOIS = 0x065, - CMSG_CONTACT_LIST = 0x066, - SMSG_CONTACT_LIST = 0x067, - SMSG_FRIEND_STATUS = 0x068, - CMSG_ADD_FRIEND = 0x069, - CMSG_DEL_FRIEND = 0x06A, - CMSG_SET_CONTACT_NOTES = 0x06B, - CMSG_ADD_IGNORE = 0x06C, - CMSG_DEL_IGNORE = 0x06D, - CMSG_GROUP_INVITE = 0x06E, - SMSG_GROUP_INVITE = 0x06F, - CMSG_GROUP_CANCEL = 0x070, - SMSG_GROUP_CANCEL = 0x071, - CMSG_GROUP_ACCEPT = 0x072, - CMSG_GROUP_DECLINE = 0x073, - SMSG_GROUP_DECLINE = 0x074, - CMSG_GROUP_UNINVITE = 0x075, - CMSG_GROUP_UNINVITE_GUID = 0x076, - SMSG_GROUP_UNINVITE = 0x077, - CMSG_GROUP_SET_LEADER = 0x078, - SMSG_GROUP_SET_LEADER = 0x079, - CMSG_LOOT_METHOD = 0x07A, - CMSG_GROUP_DISBAND = 0x07B, - SMSG_GROUP_DESTROYED = 0x07C, - SMSG_GROUP_LIST = 0x07D, - SMSG_PARTY_MEMBER_STATS = 0x07E, - SMSG_PARTY_COMMAND_RESULT = 0x07F, - UMSG_UPDATE_GROUP_MEMBERS = 0x080, - CMSG_GUILD_CREATE = 0x081, - CMSG_GUILD_INVITE = 0x082, - SMSG_GUILD_INVITE = 0x083, - CMSG_GUILD_ACCEPT = 0x084, - CMSG_GUILD_DECLINE = 0x085, - SMSG_GUILD_DECLINE = 0x086, - CMSG_GUILD_INFO = 0x087, - SMSG_GUILD_INFO = 0x088, - CMSG_GUILD_ROSTER = 0x089, - SMSG_GUILD_ROSTER = 0x08A, - CMSG_GUILD_PROMOTE = 0x08B, - CMSG_GUILD_DEMOTE = 0x08C, - CMSG_GUILD_LEAVE = 0x08D, - CMSG_GUILD_REMOVE = 0x08E, - CMSG_GUILD_DISBAND = 0x08F, - CMSG_GUILD_LEADER = 0x090, - CMSG_GUILD_MOTD = 0x091, - SMSG_GUILD_EVENT = 0x092, - SMSG_GUILD_COMMAND_RESULT = 0x093, - UMSG_UPDATE_GUILD = 0x094, - CMSG_MESSAGECHAT = 0x095, - SMSG_MESSAGECHAT = 0x096, - CMSG_JOIN_CHANNEL = 0x097, - CMSG_LEAVE_CHANNEL = 0x098, - SMSG_CHANNEL_NOTIFY = 0x099, - CMSG_CHANNEL_LIST = 0x09A, - SMSG_CHANNEL_LIST = 0x09B, - CMSG_CHANNEL_PASSWORD = 0x09C, - CMSG_CHANNEL_SET_OWNER = 0x09D, - CMSG_CHANNEL_OWNER = 0x09E, - CMSG_CHANNEL_MODERATOR = 0x09F, - CMSG_CHANNEL_UNMODERATOR = 0x0A0, - CMSG_CHANNEL_MUTE = 0x0A1, - CMSG_CHANNEL_UNMUTE = 0x0A2, - CMSG_CHANNEL_INVITE = 0x0A3, - CMSG_CHANNEL_KICK = 0x0A4, - CMSG_CHANNEL_BAN = 0x0A5, - CMSG_CHANNEL_UNBAN = 0x0A6, - CMSG_CHANNEL_ANNOUNCEMENTS = 0x0A7, - CMSG_CHANNEL_MODERATE = 0x0A8, - SMSG_UPDATE_OBJECT = 0x0A9, - SMSG_DESTROY_OBJECT = 0x0AA, - CMSG_USE_ITEM = 0x0AB, - CMSG_OPEN_ITEM = 0x0AC, - CMSG_READ_ITEM = 0x0AD, - SMSG_READ_ITEM_OK = 0x0AE, - SMSG_READ_ITEM_FAILED = 0x0AF, - SMSG_ITEM_COOLDOWN = 0x0B0, - CMSG_GAMEOBJ_USE = 0x0B1, - CMSG_DESTROY_ITEMS = 0x0B2, - SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3, - CMSG_AREATRIGGER = 0x0B4, - MSG_MOVE_START_FORWARD = 0x0B5, - MSG_MOVE_START_BACKWARD = 0x0B6, - MSG_MOVE_STOP = 0x0B7, - MSG_MOVE_START_STRAFE_LEFT = 0x0B8, - MSG_MOVE_START_STRAFE_RIGHT = 0x0B9, - MSG_MOVE_STOP_STRAFE = 0x0BA, - MSG_MOVE_JUMP = 0x0BB, - MSG_MOVE_START_TURN_LEFT = 0x0BC, - MSG_MOVE_START_TURN_RIGHT = 0x0BD, - MSG_MOVE_STOP_TURN = 0x0BE, - MSG_MOVE_START_PITCH_UP = 0x0BF, - MSG_MOVE_START_PITCH_DOWN = 0x0C0, - MSG_MOVE_STOP_PITCH = 0x0C1, - MSG_MOVE_SET_RUN_MODE = 0x0C2, - MSG_MOVE_SET_WALK_MODE = 0x0C3, - MSG_MOVE_TOGGLE_LOGGING = 0x0C4, - MSG_MOVE_TELEPORT = 0x0C5, - MSG_MOVE_TELEPORT_CHEAT = 0x0C6, - MSG_MOVE_TELEPORT_ACK = 0x0C7, - MSG_MOVE_TOGGLE_FALL_LOGGING = 0x0C8, - MSG_MOVE_FALL_LAND = 0x0C9, - MSG_MOVE_START_SWIM = 0x0CA, - MSG_MOVE_STOP_SWIM = 0x0CB, - MSG_MOVE_SET_RUN_SPEED_CHEAT = 0x0CC, - MSG_MOVE_SET_RUN_SPEED = 0x0CD, - MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT = 0x0CE, - MSG_MOVE_SET_RUN_BACK_SPEED = 0x0CF, - MSG_MOVE_SET_WALK_SPEED_CHEAT = 0x0D0, - MSG_MOVE_SET_WALK_SPEED = 0x0D1, - MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0x0D2, - MSG_MOVE_SET_SWIM_SPEED = 0x0D3, - MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT = 0x0D4, - MSG_MOVE_SET_SWIM_BACK_SPEED = 0x0D5, - MSG_MOVE_SET_ALL_SPEED_CHEAT = 0x0D6, - MSG_MOVE_SET_TURN_RATE_CHEAT = 0x0D7, - MSG_MOVE_SET_TURN_RATE = 0x0D8, - MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0x0D9, - MSG_MOVE_SET_FACING = 0x0DA, - MSG_MOVE_SET_PITCH = 0x0DB, - MSG_MOVE_WORLDPORT_ACK = 0x0DC, - SMSG_MONSTER_MOVE = 0x0DD, - SMSG_MOVE_WATER_WALK = 0x0DE, - SMSG_MOVE_LAND_WALK = 0x0DF, - CMSG_MOVE_CHARM_PORT_CHEAT = 0x0E0, - CMSG_MOVE_SET_RAW_POSITION = 0x0E1, - SMSG_FORCE_RUN_SPEED_CHANGE = 0x0E2, - CMSG_FORCE_RUN_SPEED_CHANGE_ACK = 0x0E3, - SMSG_FORCE_RUN_BACK_SPEED_CHANGE = 0x0E4, - CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK = 0x0E5, - SMSG_FORCE_SWIM_SPEED_CHANGE = 0x0E6, - CMSG_FORCE_SWIM_SPEED_CHANGE_ACK = 0x0E7, - SMSG_FORCE_MOVE_ROOT = 0x0E8, - CMSG_FORCE_MOVE_ROOT_ACK = 0x0E9, - SMSG_FORCE_MOVE_UNROOT = 0x0EA, - CMSG_FORCE_MOVE_UNROOT_ACK = 0x0EB, - MSG_MOVE_ROOT = 0x0EC, - MSG_MOVE_UNROOT = 0x0ED, - MSG_MOVE_HEARTBEAT = 0x0EE, - SMSG_MOVE_KNOCK_BACK = 0x0EF, - CMSG_MOVE_KNOCK_BACK_ACK = 0x0F0, - MSG_MOVE_KNOCK_BACK = 0x0F1, - SMSG_MOVE_FEATHER_FALL = 0x0F2, - SMSG_MOVE_NORMAL_FALL = 0x0F3, - SMSG_MOVE_SET_HOVER = 0x0F4, - SMSG_MOVE_UNSET_HOVER = 0x0F5, - CMSG_MOVE_HOVER_ACK = 0x0F6, - MSG_MOVE_HOVER = 0x0F7, - CMSG_TRIGGER_CINEMATIC_CHEAT = 0x0F8, - CMSG_OPENING_CINEMATIC = 0x0F9, - SMSG_TRIGGER_CINEMATIC = 0x0FA, - CMSG_NEXT_CINEMATIC_CAMERA = 0x0FB, - CMSG_COMPLETE_CINEMATIC = 0x0FC, - SMSG_TUTORIAL_FLAGS = 0x0FD, - CMSG_TUTORIAL_FLAG = 0x0FE, - CMSG_TUTORIAL_CLEAR = 0x0FF, - CMSG_TUTORIAL_RESET = 0x100, - CMSG_STANDSTATECHANGE = 0x101, - CMSG_EMOTE = 0x102, - SMSG_EMOTE = 0x103, - CMSG_TEXT_EMOTE = 0x104, - SMSG_TEXT_EMOTE = 0x105, - CMSG_AUTOEQUIP_GROUND_ITEM = 0x106, - CMSG_AUTOSTORE_GROUND_ITEM = 0x107, - CMSG_AUTOSTORE_LOOT_ITEM = 0x108, - CMSG_STORE_LOOT_IN_SLOT = 0x109, - CMSG_AUTOEQUIP_ITEM = 0x10A, - CMSG_AUTOSTORE_BAG_ITEM = 0x10B, - CMSG_SWAP_ITEM = 0x10C, - CMSG_SWAP_INV_ITEM = 0x10D, - CMSG_SPLIT_ITEM = 0x10E, - CMSG_AUTOEQUIP_ITEM_SLOT = 0x10F, - CMSG_UNCLAIM_LICENSE = 0x110, - CMSG_DESTROYITEM = 0x111, - SMSG_INVENTORY_CHANGE_FAILURE = 0x112, - SMSG_OPEN_CONTAINER = 0x113, - CMSG_INSPECT = 0x114, - SMSG_INSPECT_RESULTS_UPDATE = 0x115, - CMSG_INITIATE_TRADE = 0x116, - CMSG_BEGIN_TRADE = 0x117, - CMSG_BUSY_TRADE = 0x118, - CMSG_IGNORE_TRADE = 0x119, - CMSG_ACCEPT_TRADE = 0x11A, - CMSG_UNACCEPT_TRADE = 0x11B, - CMSG_CANCEL_TRADE = 0x11C, - CMSG_SET_TRADE_ITEM = 0x11D, - CMSG_CLEAR_TRADE_ITEM = 0x11E, - CMSG_SET_TRADE_GOLD = 0x11F, - SMSG_TRADE_STATUS = 0x120, - SMSG_TRADE_STATUS_EXTENDED = 0x121, - SMSG_INITIALIZE_FACTIONS = 0x122, - SMSG_SET_FACTION_VISIBLE = 0x123, - SMSG_SET_FACTION_STANDING = 0x124, - CMSG_SET_FACTION_ATWAR = 0x125, - CMSG_SET_FACTION_CHEAT = 0x126, - SMSG_SET_PROFICIENCY = 0x127, - CMSG_SET_ACTION_BUTTON = 0x128, - SMSG_ACTION_BUTTONS = 0x129, - SMSG_INITIAL_SPELLS = 0x12A, - SMSG_LEARNED_SPELL = 0x12B, - SMSG_SUPERCEDED_SPELL = 0x12C, - CMSG_NEW_SPELL_SLOT = 0x12D, - CMSG_CAST_SPELL = 0x12E, - CMSG_CANCEL_CAST = 0x12F, - SMSG_CAST_FAILED = 0x130, - SMSG_SPELL_START = 0x131, - SMSG_SPELL_GO = 0x132, - SMSG_SPELL_FAILURE = 0x133, - SMSG_SPELL_COOLDOWN = 0x134, - SMSG_COOLDOWN_EVENT = 0x135, - CMSG_CANCEL_AURA = 0x136, - SMSG_EQUIPMENT_SET_SAVED = 0x137, - SMSG_PET_CAST_FAILED = 0x138, - MSG_CHANNEL_START = 0x139, - MSG_CHANNEL_UPDATE = 0x13A, - CMSG_CANCEL_CHANNELLING = 0x13B, - SMSG_AI_REACTION = 0x13C, - CMSG_SET_SELECTION = 0x13D, - CMSG_DELETEEQUIPMENT_SET = 0x13E, - CMSG_INSTANCE_LOCK_RESPONSE = 0x13F, - CMSG_DEBUG_PASSIVE_AURA = 0x140, - CMSG_ATTACKSWING = 0x141, - CMSG_ATTACKSTOP = 0x142, - SMSG_ATTACKSTART = 0x143, - SMSG_ATTACKSTOP = 0x144, - SMSG_ATTACKSWING_NOTINRANGE = 0x145, - SMSG_ATTACKSWING_BADFACING = 0x146, - SMSG_INSTANCE_LOCK_WARNING_QUERY = 0x147, - SMSG_ATTACKSWING_DEADTARGET = 0x148, - SMSG_ATTACKSWING_CANT_ATTACK = 0x149, - SMSG_ATTACKERSTATEUPDATE = 0x14A, - SMSG_BATTLEFIELD_PORT_DENIED = 0x14B, - CMSG_PERFORM_ACTION_SET = 0x14C, - SMSG_RESUME_CAST_BAR = 0x14D, - SMSG_CANCEL_COMBAT = 0x14E, - SMSG_SPELLBREAKLOG = 0x14F, - SMSG_SPELLHEALLOG = 0x150, - SMSG_SPELLENERGIZELOG = 0x151, - SMSG_BREAK_TARGET = 0x152, - CMSG_SAVE_PLAYER = 0x153, - CMSG_SETDEATHBINDPOINT = 0x154, - SMSG_BINDPOINTUPDATE = 0x155, - CMSG_GETDEATHBINDZONE = 0x156, - SMSG_BINDZONEREPLY = 0x157, - SMSG_PLAYERBOUND = 0x158, - SMSG_CLIENT_CONTROL_UPDATE = 0x159, - CMSG_REPOP_REQUEST = 0x15A, - SMSG_RESURRECT_REQUEST = 0x15B, - CMSG_RESURRECT_RESPONSE = 0x15C, - CMSG_LOOT = 0x15D, - CMSG_LOOT_MONEY = 0x15E, - CMSG_LOOT_RELEASE = 0x15F, - SMSG_LOOT_RESPONSE = 0x160, - SMSG_LOOT_RELEASE_RESPONSE = 0x161, - SMSG_LOOT_REMOVED = 0x162, - SMSG_LOOT_MONEY_NOTIFY = 0x163, - SMSG_LOOT_ITEM_NOTIFY = 0x164, - SMSG_LOOT_CLEAR_MONEY = 0x165, - SMSG_ITEM_PUSH_RESULT = 0x166, - SMSG_DUEL_REQUESTED = 0x167, - SMSG_DUEL_OUTOFBOUNDS = 0x168, - SMSG_DUEL_INBOUNDS = 0x169, - SMSG_DUEL_COMPLETE = 0x16A, - SMSG_DUEL_WINNER = 0x16B, - CMSG_DUEL_ACCEPTED = 0x16C, - CMSG_DUEL_CANCELLED = 0x16D, - SMSG_MOUNTRESULT = 0x16E, - SMSG_DISMOUNTRESULT = 0x16F, - SMSG_REMOVED_FROM_PVP_QUEUE = 0x170, - CMSG_MOUNTSPECIAL_ANIM = 0x171, - SMSG_MOUNTSPECIAL_ANIM = 0x172, - SMSG_PET_TAME_FAILURE = 0x173, - CMSG_PET_SET_ACTION = 0x174, - CMSG_PET_ACTION = 0x175, - CMSG_PET_ABANDON = 0x176, - CMSG_PET_RENAME = 0x177, - SMSG_PET_NAME_INVALID = 0x178, - SMSG_PET_SPELLS = 0x179, - SMSG_PET_MODE = 0x17A, - CMSG_GOSSIP_HELLO = 0x17B, - CMSG_GOSSIP_SELECT_OPTION = 0x17C, - SMSG_GOSSIP_MESSAGE = 0x17D, - SMSG_GOSSIP_COMPLETE = 0x17E, - CMSG_NPC_TEXT_QUERY = 0x17F, - SMSG_NPC_TEXT_UPDATE = 0x180, - SMSG_NPC_WONT_TALK = 0x181, - CMSG_QUESTGIVER_STATUS_QUERY = 0x182, - SMSG_QUESTGIVER_STATUS = 0x183, - CMSG_QUESTGIVER_HELLO = 0x184, - SMSG_QUESTGIVER_QUEST_LIST = 0x185, - CMSG_QUESTGIVER_QUERY_QUEST = 0x186, - CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0x187, - SMSG_QUESTGIVER_QUEST_DETAILS = 0x188, - CMSG_QUESTGIVER_ACCEPT_QUEST = 0x189, - CMSG_QUESTGIVER_COMPLETE_QUEST = 0x18A, - SMSG_QUESTGIVER_REQUEST_ITEMS = 0x18B, - CMSG_QUESTGIVER_REQUEST_REWARD = 0x18C, - SMSG_QUESTGIVER_OFFER_REWARD = 0x18D, - CMSG_QUESTGIVER_CHOOSE_REWARD = 0x18E, - SMSG_QUESTGIVER_QUEST_INVALID = 0x18F, - CMSG_QUESTGIVER_CANCEL = 0x190, - SMSG_QUESTGIVER_QUEST_COMPLETE = 0x191, - SMSG_QUESTGIVER_QUEST_FAILED = 0x192, - CMSG_QUESTLOG_SWAP_QUEST = 0x193, - CMSG_QUESTLOG_REMOVE_QUEST = 0x194, - SMSG_QUESTLOG_FULL = 0x195, - SMSG_QUESTUPDATE_FAILED = 0x196, - SMSG_QUESTUPDATE_FAILEDTIMER = 0x197, - SMSG_QUESTUPDATE_COMPLETE = 0x198, - SMSG_QUESTUPDATE_ADD_KILL = 0x199, - SMSG_QUESTUPDATE_ADD_ITEM = 0x19A, - CMSG_QUEST_CONFIRM_ACCEPT = 0x19B, - SMSG_QUEST_CONFIRM_ACCEPT = 0x19C, - CMSG_PUSHQUESTTOPARTY = 0x19D, - CMSG_LIST_INVENTORY = 0x19E, - SMSG_LIST_INVENTORY = 0x19F, - CMSG_SELL_ITEM = 0x1A0, - SMSG_SELL_ITEM = 0x1A1, - CMSG_BUY_ITEM = 0x1A2, - CMSG_BUY_ITEM_IN_SLOT = 0x1A3, - SMSG_BUY_ITEM = 0x1A4, - SMSG_BUY_FAILED = 0x1A5, - CMSG_TAXICLEARALLNODES = 0x1A6, - CMSG_TAXIENABLEALLNODES = 0x1A7, - CMSG_TAXISHOWNODES = 0x1A8, - SMSG_SHOWTAXINODES = 0x1A9, - CMSG_TAXINODE_STATUS_QUERY = 0x1AA, - SMSG_TAXINODE_STATUS = 0x1AB, - CMSG_TAXIQUERYAVAILABLENODES = 0x1AC, - CMSG_ACTIVATETAXI = 0x1AD, - SMSG_ACTIVATETAXIREPLY = 0x1AE, - SMSG_NEW_TAXI_PATH = 0x1AF, - CMSG_TRAINER_LIST = 0x1B0, - SMSG_TRAINER_LIST = 0x1B1, - CMSG_TRAINER_BUY_SPELL = 0x1B2, - SMSG_TRAINER_BUY_SUCCEEDED = 0x1B3, - SMSG_TRAINER_BUY_FAILED = 0x1B4, - CMSG_BINDER_ACTIVATE = 0x1B5, - SMSG_PLAYERBINDERROR = 0x1B6, - CMSG_BANKER_ACTIVATE = 0x1B7, - SMSG_SHOW_BANK = 0x1B8, - CMSG_BUY_BANK_SLOT = 0x1B9, - SMSG_BUY_BANK_SLOT_RESULT = 0x1BA, - CMSG_PETITION_SHOWLIST = 0x1BB, - SMSG_PETITION_SHOWLIST = 0x1BC, - CMSG_PETITION_BUY = 0x1BD, - CMSG_PETITION_SHOW_SIGNATURES = 0x1BE, - SMSG_PETITION_SHOW_SIGNATURES = 0x1BF, - CMSG_PETITION_SIGN = 0x1C0, - SMSG_PETITION_SIGN_RESULTS = 0x1C1, - MSG_PETITION_DECLINE = 0x1C2, - CMSG_OFFER_PETITION = 0x1C3, - CMSG_TURN_IN_PETITION = 0x1C4, - SMSG_TURN_IN_PETITION_RESULTS = 0x1C5, - CMSG_PETITION_QUERY = 0x1C6, - SMSG_PETITION_QUERY_RESPONSE = 0x1C7, - SMSG_FISH_NOT_HOOKED = 0x1C8, - SMSG_FISH_ESCAPED = 0x1C9, - CMSG_BUG = 0x1CA, - SMSG_NOTIFICATION = 0x1CB, - CMSG_PLAYED_TIME = 0x1CC, - SMSG_PLAYED_TIME = 0x1CD, - CMSG_QUERY_TIME = 0x1CE, - SMSG_QUERY_TIME_RESPONSE = 0x1CF, - SMSG_LOG_XPGAIN = 0x1D0, - SMSG_AURACASTLOG = 0x1D1, - CMSG_RECLAIM_CORPSE = 0x1D2, - CMSG_WRAP_ITEM = 0x1D3, - SMSG_LEVELUP_INFO = 0x1D4, - MSG_MINIMAP_PING = 0x1D5, - SMSG_RESISTLOG = 0x1D6, - SMSG_ENCHANTMENTLOG = 0x1D7, - CMSG_SET_SKILL_CHEAT = 0x1D8, - SMSG_START_MIRROR_TIMER = 0x1D9, - SMSG_PAUSE_MIRROR_TIMER = 0x1DA, - SMSG_STOP_MIRROR_TIMER = 0x1DB, - CMSG_PING = 0x1DC, - SMSG_PONG = 0x1DD, - SMSG_CLEAR_COOLDOWN = 0x1DE, - SMSG_GAMEOBJECT_PAGETEXT = 0x1DF, - CMSG_SETSHEATHED = 0x1E0, - SMSG_COOLDOWN_CHEAT = 0x1E1, - SMSG_SPELL_DELAYED = 0x1E2, - CMSG_QUEST_POI_QUERY = 0x1E3, - SMSG_QUEST_POI_QUERY_RESPONSE = 0x1E4, - CMSG_GHOST = 0x1E5, - CMSG_GM_INVIS = 0x1E6, - SMSG_INVALID_PROMOTION_CODE = 0x1E7, - MSG_GM_BIND_OTHER = 0x1E8, - MSG_GM_SUMMON = 0x1E9, - SMSG_ITEM_TIME_UPDATE = 0x1EA, - SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x1EB, - SMSG_AUTH_CHALLENGE = 0x1EC, - CMSG_AUTH_SESSION = 0x1ED, - SMSG_AUTH_RESPONSE = 0x1EE, - MSG_GM_SHOWLABEL = 0x1EF, - CMSG_PET_CAST_SPELL = 0x1F0, - MSG_SAVE_GUILD_EMBLEM = 0x1F1, - MSG_TABARDVENDOR_ACTIVATE = 0x1F2, - SMSG_PLAY_SPELL_VISUAL = 0x1F3, - CMSG_ZONEUPDATE = 0x1F4, - SMSG_PARTYKILLLOG = 0x1F5, - SMSG_COMPRESSED_UPDATE_OBJECT = 0x1F6, - SMSG_PLAY_SPELL_IMPACT = 0x1F7, - SMSG_EXPLORATION_EXPERIENCE = 0x1F8, - CMSG_GM_SET_SECURITY_GROUP = 0x1F9, - CMSG_GM_NUKE = 0x1FA, - MSG_RANDOM_ROLL = 0x1FB, - SMSG_ENVIRONMENTALDAMAGELOG = 0x1FC, - CMSG_CHANGEPLAYER_DIFFICULTY = 0x1FD, - SMSG_RWHOIS = 0x1FE, - SMSG_LFG_PLAYER_REWARD = 0x1FF, // uint32, uint8, uint32, uint32, uint32, uint32, uint32, uint8, for (uint8) {uint32, uint32, uint32} - SMSG_LFG_TELEPORT_DENIED = 0x200, // uint32 (1, 2, 4, 6;0, 5, 7) - CMSG_UNLEARN_SPELL = 0x201, - CMSG_UNLEARN_SKILL = 0x202, - SMSG_REMOVED_SPELL = 0x203, - CMSG_DECHARGE = 0x204, - CMSG_GMTICKET_CREATE = 0x205, - SMSG_GMTICKET_CREATE = 0x206, - CMSG_GMTICKET_UPDATETEXT = 0x207, - SMSG_GMTICKET_UPDATETEXT = 0x208, - SMSG_ACCOUNT_DATA_TIMES = 0x209, - CMSG_REQUEST_ACCOUNT_DATA = 0x20A, - CMSG_UPDATE_ACCOUNT_DATA = 0x20B, - SMSG_UPDATE_ACCOUNT_DATA = 0x20C, - SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x20D, - SMSG_CHANGEPLAYER_DIFFICULTY_RESULT = 0x20E, - CMSG_GM_TEACH = 0x20F, - CMSG_GM_CREATE_ITEM_TARGET = 0x210, - CMSG_GMTICKET_GETTICKET = 0x211, - SMSG_GMTICKET_GETTICKET = 0x212, - CMSG_UNLEARN_TALENTS = 0x213, - SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x214, - SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x215, - MSG_CORPSE_QUERY = 0x216, - CMSG_GMTICKET_DELETETICKET = 0x217, - SMSG_GMTICKET_DELETETICKET = 0x218, - SMSG_CHAT_WRONG_FACTION = 0x219, - CMSG_GMTICKET_SYSTEMSTATUS = 0x21A, - SMSG_GMTICKET_SYSTEMSTATUS = 0x21B, - CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C, - CMSG_SET_STAT_CHEAT = 0x21D, - SMSG_QUEST_FORCE_REMOVE = 0x21E, // uint32 questid - CMSG_SKILL_BUY_STEP = 0x21F, - CMSG_SKILL_BUY_RANK = 0x220, - CMSG_XP_CHEAT = 0x221, - SMSG_SPIRIT_HEALER_CONFIRM = 0x222, - CMSG_CHARACTER_POINT_CHEAT = 0x223, - SMSG_GOSSIP_POI = 0x224, - CMSG_CHAT_IGNORED = 0x225, - CMSG_GM_VISION = 0x226, - CMSG_SERVER_COMMAND = 0x227, - CMSG_GM_SILENCE = 0x228, - CMSG_GM_REVEALTO = 0x229, - CMSG_GM_RESURRECT = 0x22A, - CMSG_GM_SUMMONMOB = 0x22B, - CMSG_GM_MOVECORPSE = 0x22C, - CMSG_GM_FREEZE = 0x22D, - CMSG_GM_UBERINVIS = 0x22E, - CMSG_GM_REQUEST_PLAYER_INFO = 0x22F, - SMSG_GM_PLAYER_INFO = 0x230, - CMSG_GUILD_RANK = 0x231, - CMSG_GUILD_ADD_RANK = 0x232, - CMSG_GUILD_DEL_RANK = 0x233, - CMSG_GUILD_SET_PUBLIC_NOTE = 0x234, - CMSG_GUILD_SET_OFFICER_NOTE = 0x235, - SMSG_LOGIN_VERIFY_WORLD = 0x236, - CMSG_CLEAR_EXPLORATION = 0x237, - CMSG_SEND_MAIL = 0x238, - SMSG_SEND_MAIL_RESULT = 0x239, - CMSG_GET_MAIL_LIST = 0x23A, - SMSG_MAIL_LIST_RESULT = 0x23B, - CMSG_BATTLEFIELD_LIST = 0x23C, - SMSG_BATTLEFIELD_LIST = 0x23D, - CMSG_BATTLEFIELD_JOIN = 0x23E, - SMSG_FORCE_SET_VEHICLE_REC_ID = 0x23F, - CMSG_SET_VEHICLE_REC_ID_ACK = 0x240, - CMSG_TAXICLEARNODE = 0x241, - CMSG_TAXIENABLENODE = 0x242, - CMSG_ITEM_TEXT_QUERY = 0x243, - SMSG_ITEM_TEXT_QUERY_RESPONSE = 0x244, - CMSG_MAIL_TAKE_MONEY = 0x245, - CMSG_MAIL_TAKE_ITEM = 0x246, - CMSG_MAIL_MARK_AS_READ = 0x247, - CMSG_MAIL_RETURN_TO_SENDER = 0x248, - CMSG_MAIL_DELETE = 0x249, - CMSG_MAIL_CREATE_TEXT_ITEM = 0x24A, - SMSG_SPELLLOGMISS = 0x24B, - SMSG_SPELLLOGEXECUTE = 0x24C, - SMSG_DEBUGAURAPROC = 0x24D, - SMSG_PERIODICAURALOG = 0x24E, - SMSG_SPELLDAMAGESHIELD = 0x24F, - SMSG_SPELLNONMELEEDAMAGELOG = 0x250, - CMSG_LEARN_TALENT = 0x251, - SMSG_RESURRECT_FAILED = 0x252, - CMSG_TOGGLE_PVP = 0x253, - SMSG_ZONE_UNDER_ATTACK = 0x254, - MSG_AUCTION_HELLO = 0x255, - CMSG_AUCTION_SELL_ITEM = 0x256, - CMSG_AUCTION_REMOVE_ITEM = 0x257, - CMSG_AUCTION_LIST_ITEMS = 0x258, - CMSG_AUCTION_LIST_OWNER_ITEMS = 0x259, - CMSG_AUCTION_PLACE_BID = 0x25A, - SMSG_AUCTION_COMMAND_RESULT = 0x25B, - SMSG_AUCTION_LIST_RESULT = 0x25C, - SMSG_AUCTION_OWNER_LIST_RESULT = 0x25D, - SMSG_AUCTION_BIDDER_NOTIFICATION = 0x25E, - SMSG_AUCTION_OWNER_NOTIFICATION = 0x25F, - SMSG_PROCRESIST = 0x260, - SMSG_COMBAT_EVENT_FAILED = 0x261, - SMSG_DISPEL_FAILED = 0x262, - SMSG_SPELLORDAMAGE_IMMUNE = 0x263, - CMSG_AUCTION_LIST_BIDDER_ITEMS = 0x264, - SMSG_AUCTION_BIDDER_LIST_RESULT = 0x265, - SMSG_SET_FLAT_SPELL_MODIFIER = 0x266, - SMSG_SET_PCT_SPELL_MODIFIER = 0x267, - CMSG_SET_AMMO = 0x268, - SMSG_CORPSE_RECLAIM_DELAY = 0x269, - CMSG_SET_ACTIVE_MOVER = 0x26A, - CMSG_PET_CANCEL_AURA = 0x26B, - CMSG_PLAYER_AI_CHEAT = 0x26C, - CMSG_CANCEL_AUTO_REPEAT_SPELL = 0x26D, - MSG_GM_ACCOUNT_ONLINE = 0x26E, - MSG_LIST_STABLED_PETS = 0x26F, - CMSG_STABLE_PET = 0x270, - CMSG_UNSTABLE_PET = 0x271, - CMSG_BUY_STABLE_SLOT = 0x272, - SMSG_STABLE_RESULT = 0x273, - CMSG_STABLE_REVIVE_PET = 0x274, - CMSG_STABLE_SWAP_PET = 0x275, - MSG_QUEST_PUSH_RESULT = 0x276, - SMSG_PLAY_MUSIC = 0x277, - SMSG_PLAY_OBJECT_SOUND = 0x278, - CMSG_REQUEST_PET_INFO = 0x279, - CMSG_FAR_SIGHT = 0x27A, - SMSG_SPELLDISPELLOG = 0x27B, - SMSG_DAMAGE_CALC_LOG = 0x27C, - CMSG_ENABLE_DAMAGE_LOG = 0x27D, - CMSG_GROUP_CHANGE_SUB_GROUP = 0x27E, - CMSG_REQUEST_PARTY_MEMBER_STATS = 0x27F, - CMSG_GROUP_SWAP_SUB_GROUP = 0x280, - CMSG_RESET_FACTION_CHEAT = 0x281, - CMSG_AUTOSTORE_BANK_ITEM = 0x282, - CMSG_AUTOBANK_ITEM = 0x283, - MSG_QUERY_NEXT_MAIL_TIME = 0x284, - SMSG_RECEIVED_MAIL = 0x285, - SMSG_RAID_GROUP_ONLY = 0x286, - CMSG_SET_DURABILITY_CHEAT = 0x287, - CMSG_SET_PVP_RANK_CHEAT = 0x288, - CMSG_ADD_PVP_MEDAL_CHEAT = 0x289, - CMSG_DEL_PVP_MEDAL_CHEAT = 0x28A, - CMSG_SET_PVP_TITLE = 0x28B, - SMSG_PVP_CREDIT = 0x28C, - SMSG_AUCTION_REMOVED_NOTIFICATION = 0x28D, - CMSG_GROUP_RAID_CONVERT = 0x28E, - CMSG_GROUP_ASSISTANT_LEADER = 0x28F, - CMSG_BUYBACK_ITEM = 0x290, - SMSG_SERVER_MESSAGE = 0x291, - CMSG_SET_SAVED_INSTANCE_EXTEND = 0x292, - SMSG_LFG_OFFER_CONTINUE = 0x293, - CMSG_TEST_DROP_RATE = 0x294, - SMSG_TEST_DROP_RATE_RESULT = 0x295, - CMSG_LFG_GET_STATUS = 0x296, - SMSG_SHOW_MAILBOX = 0x297, - SMSG_RESET_RANGED_COMBAT_TIMER = 0x298, - SMSG_CHAT_NOT_IN_PARTY = 0x299, // uint32, errors: ERR_NOT_IN_GROUP (2, 51) and ERR_NOT_IN_RAID (3, 39, 40) - CMSG_GMTICKETSYSTEM_TOGGLE = 0x29A, - CMSG_CANCEL_GROWTH_AURA = 0x29B, - SMSG_CANCEL_AUTO_REPEAT = 0x29C, - SMSG_STANDSTATE_UPDATE = 0x29D, - SMSG_LOOT_ALL_PASSED = 0x29E, - SMSG_LOOT_ROLL_WON = 0x29F, - CMSG_LOOT_ROLL = 0x2A0, - SMSG_LOOT_START_ROLL = 0x2A1, - SMSG_LOOT_ROLL = 0x2A2, - CMSG_LOOT_MASTER_GIVE = 0x2A3, - SMSG_LOOT_MASTER_LIST = 0x2A4, - SMSG_SET_FORCED_REACTIONS = 0x2A5, - SMSG_SPELL_FAILED_OTHER = 0x2A6, - SMSG_GAMEOBJECT_RESET_STATE = 0x2A7, - CMSG_REPAIR_ITEM = 0x2A8, - SMSG_CHAT_PLAYER_NOT_FOUND = 0x2A9, - MSG_TALENT_WIPE_CONFIRM = 0x2AA, - SMSG_SUMMON_REQUEST = 0x2AB, - CMSG_SUMMON_RESPONSE = 0x2AC, - MSG_DEV_SHOWLABEL = 0x2AD, - SMSG_MONSTER_MOVE_TRANSPORT = 0x2AE, - SMSG_PET_BROKEN = 0x2AF, - MSG_MOVE_FEATHER_FALL = 0x2B0, - MSG_MOVE_WATER_WALK = 0x2B1, - CMSG_SERVER_BROADCAST = 0x2B2, - CMSG_SELF_RES = 0x2B3, - SMSG_FEIGN_DEATH_RESISTED = 0x2B4, - CMSG_RUN_SCRIPT = 0x2B5, - SMSG_SCRIPT_MESSAGE = 0x2B6, - SMSG_DUEL_COUNTDOWN = 0x2B7, - SMSG_AREA_TRIGGER_MESSAGE = 0x2B8, - CMSG_SHOWING_HELM = 0x2B9, - CMSG_SHOWING_CLOAK = 0x2BA, - SMSG_LFG_ROLE_CHOSEN = 0x2BB, - SMSG_PLAYER_SKINNED = 0x2BC, - SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD, - CMSG_SET_EXPLORATION = 0x2BE, - CMSG_SET_ACTIONBAR_TOGGLES = 0x2BF, - UMSG_DELETE_GUILD_CHARTER = 0x2C0, - MSG_PETITION_RENAME = 0x2C1, - SMSG_INIT_WORLD_STATES = 0x2C2, - SMSG_UPDATE_WORLD_STATE = 0x2C3, - CMSG_ITEM_NAME_QUERY = 0x2C4, - SMSG_ITEM_NAME_QUERY_RESPONSE = 0x2C5, - SMSG_PET_ACTION_FEEDBACK = 0x2C6, - CMSG_CHAR_RENAME = 0x2C7, - SMSG_CHAR_RENAME = 0x2C8, - CMSG_MOVE_SPLINE_DONE = 0x2C9, - CMSG_MOVE_FALL_RESET = 0x2CA, - SMSG_INSTANCE_SAVE_CREATED = 0x2CB, - SMSG_RAID_INSTANCE_INFO = 0x2CC, - CMSG_REQUEST_RAID_INFO = 0x2CD, - CMSG_MOVE_TIME_SKIPPED = 0x2CE, - CMSG_MOVE_FEATHER_FALL_ACK = 0x2CF, - CMSG_MOVE_WATER_WALK_ACK = 0x2D0, - CMSG_MOVE_NOT_ACTIVE_MOVER = 0x2D1, - SMSG_PLAY_SOUND = 0x2D2, - CMSG_BATTLEFIELD_STATUS = 0x2D3, - SMSG_BATTLEFIELD_STATUS = 0x2D4, - CMSG_BATTLEFIELD_PORT = 0x2D5, - MSG_INSPECT_HONOR_STATS = 0x2D6, - CMSG_BATTLEMASTER_HELLO = 0x2D7, - CMSG_MOVE_START_SWIM_CHEAT = 0x2D8, - CMSG_MOVE_STOP_SWIM_CHEAT = 0x2D9, - SMSG_FORCE_WALK_SPEED_CHANGE = 0x2DA, - CMSG_FORCE_WALK_SPEED_CHANGE_ACK = 0x2DB, - SMSG_FORCE_SWIM_BACK_SPEED_CHANGE = 0x2DC, - CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK = 0x2DD, - SMSG_FORCE_TURN_RATE_CHANGE = 0x2DE, - CMSG_FORCE_TURN_RATE_CHANGE_ACK = 0x2DF, - MSG_PVP_LOG_DATA = 0x2E0, - CMSG_LEAVE_BATTLEFIELD = 0x2E1, - CMSG_AREA_SPIRIT_HEALER_QUERY = 0x2E2, - CMSG_AREA_SPIRIT_HEALER_QUEUE = 0x2E3, - SMSG_AREA_SPIRIT_HEALER_TIME = 0x2E4, - CMSG_GM_UNTEACH = 0x2E5, - SMSG_WARDEN_DATA = 0x2E6, - CMSG_WARDEN_DATA = 0x2E7, - SMSG_GROUP_JOINED_BATTLEGROUND = 0x2E8, - MSG_BATTLEGROUND_PLAYER_POSITIONS = 0x2E9, - CMSG_PET_STOP_ATTACK = 0x2EA, - SMSG_BINDER_CONFIRM = 0x2EB, - SMSG_BATTLEGROUND_PLAYER_JOINED = 0x2EC, - SMSG_BATTLEGROUND_PLAYER_LEFT = 0x2ED, - CMSG_BATTLEMASTER_JOIN = 0x2EE, - SMSG_ADDON_INFO = 0x2EF, - CMSG_PET_UNLEARN = 0x2F0, // Deprecated 3.x - SMSG_PET_UNLEARN_CONFIRM = 0x2F1, // Deprecated 3.x - SMSG_PARTY_MEMBER_STATS_FULL = 0x2F2, - CMSG_PET_SPELL_AUTOCAST = 0x2F3, - SMSG_WEATHER = 0x2F4, - SMSG_PLAY_TIME_WARNING = 0x2F5, - SMSG_MINIGAME_SETUP = 0x2F6, - SMSG_MINIGAME_STATE = 0x2F7, - CMSG_MINIGAME_MOVE = 0x2F8, - SMSG_MINIGAME_MOVE_FAILED = 0x2F9, - SMSG_RAID_INSTANCE_MESSAGE = 0x2FA, - SMSG_COMPRESSED_MOVES = 0x2FB, - CMSG_GUILD_INFO_TEXT = 0x2FC, - SMSG_CHAT_RESTRICTED = 0x2FD, - SMSG_SPLINE_SET_RUN_SPEED = 0x2FE, - SMSG_SPLINE_SET_RUN_BACK_SPEED = 0x2FF, - SMSG_SPLINE_SET_SWIM_SPEED = 0x300, - SMSG_SPLINE_SET_WALK_SPEED = 0x301, - SMSG_SPLINE_SET_SWIM_BACK_SPEED = 0x302, - SMSG_SPLINE_SET_TURN_RATE = 0x303, - SMSG_SPLINE_MOVE_UNROOT = 0x304, - SMSG_SPLINE_MOVE_FEATHER_FALL = 0x305, - SMSG_SPLINE_MOVE_NORMAL_FALL = 0x306, - SMSG_SPLINE_MOVE_SET_HOVER = 0x307, - SMSG_SPLINE_MOVE_UNSET_HOVER = 0x308, - SMSG_SPLINE_MOVE_WATER_WALK = 0x309, - SMSG_SPLINE_MOVE_LAND_WALK = 0x30A, - SMSG_SPLINE_MOVE_START_SWIM = 0x30B, - SMSG_SPLINE_MOVE_STOP_SWIM = 0x30C, - SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x30D, - SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x30E, - CMSG_GM_NUKE_ACCOUNT = 0x30F, - MSG_GM_DESTROY_CORPSE = 0x310, - CMSG_GM_DESTROY_ONLINE_CORPSE = 0x311, - CMSG_ACTIVATETAXIEXPRESS = 0x312, - SMSG_SET_FACTION_ATWAR = 0x313, - SMSG_GAMETIMEBIAS_SET = 0x314, - CMSG_DEBUG_ACTIONS_START = 0x315, - CMSG_DEBUG_ACTIONS_STOP = 0x316, - CMSG_SET_FACTION_INACTIVE = 0x317, - CMSG_SET_WATCHED_FACTION = 0x318, - MSG_MOVE_TIME_SKIPPED = 0x319, - SMSG_SPLINE_MOVE_ROOT = 0x31A, - CMSG_SET_EXPLORATION_ALL = 0x31B, - SMSG_INVALIDATE_PLAYER = 0x31C, - CMSG_RESET_INSTANCES = 0x31D, - SMSG_INSTANCE_RESET = 0x31E, - SMSG_INSTANCE_RESET_FAILED = 0x31F, - SMSG_UPDATE_LAST_INSTANCE = 0x320, - MSG_RAID_TARGET_UPDATE = 0x321, - MSG_RAID_READY_CHECK = 0x322, - CMSG_LUA_USAGE = 0x323, - SMSG_PET_ACTION_SOUND = 0x324, - SMSG_PET_DISMISS_SOUND = 0x325, - SMSG_GHOSTEE_GONE = 0x326, - CMSG_GM_UPDATE_TICKET_STATUS = 0x327, - SMSG_GM_TICKET_STATUS_UPDATE = 0x328, - MSG_SET_DUNGEON_DIFFICULTY = 0x329, - CMSG_GMSURVEY_SUBMIT = 0x32A, - SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x32B, - CMSG_IGNORE_KNOCKBACK_CHEAT = 0x32C, - SMSG_CHAT_PLAYER_AMBIGUOUS = 0x32D, - MSG_DELAY_GHOST_TELEPORT = 0x32E, - SMSG_SPELLINSTAKILLLOG = 0x32F, - SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x330, - CMSG_CHAT_FILTERED = 0x331, - SMSG_EXPECTED_SPAM_RECORDS = 0x332, - SMSG_SPELLSTEALLOG = 0x333, - CMSG_LOTTERY_QUERY_OBSOLETE = 0x334, - SMSG_LOTTERY_QUERY_RESULT_OBSOLETE = 0x335, - CMSG_BUY_LOTTERY_TICKET_OBSOLETE = 0x336, - SMSG_LOTTERY_RESULT_OBSOLETE = 0x337, - SMSG_CHARACTER_PROFILE = 0x338, - SMSG_CHARACTER_PROFILE_REALM_CONNECTED = 0x339, - SMSG_DEFENSE_MESSAGE = 0x33A, - SMSG_INSTANCE_DIFFICULTY = 0x33B, - MSG_GM_RESETINSTANCELIMIT = 0x33C, - SMSG_MOTD = 0x33D, - SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY= 0x33E, - SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY= 0x33F, - CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK= 0x340, - MSG_MOVE_START_SWIM_CHEAT = 0x341, - MSG_MOVE_STOP_SWIM_CHEAT = 0x342, - SMSG_MOVE_SET_CAN_FLY = 0x343, - SMSG_MOVE_UNSET_CAN_FLY = 0x344, - CMSG_MOVE_SET_CAN_FLY_ACK = 0x345, - CMSG_MOVE_SET_FLY = 0x346, - CMSG_SOCKET_GEMS = 0x347, - CMSG_ARENA_TEAM_CREATE = 0x348, - SMSG_ARENA_TEAM_COMMAND_RESULT = 0x349, - MSG_MOVE_UPDATE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY= 0x34A, - CMSG_ARENA_TEAM_QUERY = 0x34B, - SMSG_ARENA_TEAM_QUERY_RESPONSE = 0x34C, - CMSG_ARENA_TEAM_ROSTER = 0x34D, - SMSG_ARENA_TEAM_ROSTER = 0x34E, - CMSG_ARENA_TEAM_INVITE = 0x34F, - SMSG_ARENA_TEAM_INVITE = 0x350, - CMSG_ARENA_TEAM_ACCEPT = 0x351, - CMSG_ARENA_TEAM_DECLINE = 0x352, - CMSG_ARENA_TEAM_LEAVE = 0x353, - CMSG_ARENA_TEAM_REMOVE = 0x354, - CMSG_ARENA_TEAM_DISBAND = 0x355, - CMSG_ARENA_TEAM_LEADER = 0x356, - SMSG_ARENA_TEAM_EVENT = 0x357, - CMSG_BATTLEMASTER_JOIN_ARENA = 0x358, - MSG_MOVE_START_ASCEND = 0x359, - MSG_MOVE_STOP_ASCEND = 0x35A, - SMSG_ARENA_TEAM_STATS = 0x35B, - CMSG_LFG_JOIN = 0x35C, - CMSG_LFG_LEAVE = 0x35D, - CMSG_SEARCH_LFG_JOIN = 0x35E, - CMSG_SEARCH_LFG_LEAVE = 0x35F, - SMSG_UPDATE_LFG_LIST = 0x360, // uint32, uint32, if (uint8) { uint32 count, for (count) { uint64} }, uint32 count2, uint32, for (count2) { uint64, uint32 flags, if (flags & 0x2) {string}, if (flags & 0x10) {for (3) uint8}, if (flags & 0x80) {uint64, uint32}}, uint32 count3, uint32, for (count3) {uint64, uint32 flags, if (flags & 0x1) {uint8, uint8, uint8, for (3) uint8, uint32, uint32, uint32, uint32, uint32, uint32, float, float, uint32, uint32, uint32, uint32, uint32, float, uint32, uint32, uint32, uint32, uint32, uint32}, if (flags&0x2) string, if (flags&0x4) uint8, if (flags&0x8) uint64, if (flags&0x10) uint8, if (flags&0x20) uint32, if (flags&0x40) uint8, if (flags& 0x80) {uint64, uint32}} - SMSG_LFG_PROPOSAL_UPDATE = 0x361, // uint32, uint8, uint32, uint32, uint8, for (uint8) {uint32, uint8, uint8, uint8, uint8} - CMSG_LFG_PROPOSAL_RESULT = 0x362, - SMSG_LFG_ROLE_CHECK_UPDATE = 0x363, // uint32, uint8, for (uint8) uint32, uint8, for (uint8) { uint64, uint8, uint32, uint8, } - SMSG_LFG_JOIN_RESULT = 0x364, // uint32 unk, uint32, if (unk == 6) { uint8 count, for (count) uint64 } - SMSG_LFG_QUEUE_STATUS = 0x365, // uint32 dungeon, uint32 lfgtype, uint32, uint32, uint32, uint32, uint8, uint8, uint8, uint8 - CMSG_SET_LFG_COMMENT = 0x366, - SMSG_LFG_UPDATE_PLAYER = 0x367, // uint8, if (uint8) { uint8, uint8, uint8, uint8, if (uint8) for (uint8) uint32, string} - SMSG_LFG_UPDATE_PARTY = 0x368, // uint8, if (uint8) { uint8, uint8, uint8, for (3) uint8, uint8, if (uint8) for (uint8) uint32, string} - SMSG_LFG_UPDATE_SEARCH = 0x369, // uint8 - CMSG_LFG_SET_ROLES = 0x36A, - CMSG_LFG_SET_NEEDS = 0x36B, - CMSG_LFG_SET_BOOT_VOTE = 0x36C, - SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x36D, // uint8, uint8, uint8, uint64, uint32, uint32, uint32, uint32 - CMSG_LFD_PLAYER_LOCK_INFO_REQUEST = 0x36E, - SMSG_LFG_PLAYER_INFO = 0x36F, // uint8, for (uint8) { uint32, uint8, uint32, uint32, uint32, uint32, uint8, for (uint8) {uint32, uint32, uint32}}, uint32, for (uint32) {uint32, uint32} - CMSG_LFG_TELEPORT = 0x370, - CMSG_LFD_PARTY_LOCK_INFO_REQUEST = 0x371, - SMSG_LFG_PARTY_INFO = 0x372, // uint8, for (uint8) uint64 - SMSG_TITLE_EARNED = 0x373, - CMSG_SET_TITLE = 0x374, - CMSG_CANCEL_MOUNT_AURA = 0x375, - SMSG_ARENA_ERROR = 0x376, - MSG_INSPECT_ARENA_TEAMS = 0x377, - SMSG_DEATH_RELEASE_LOC = 0x378, - CMSG_CANCEL_TEMP_ENCHANTMENT = 0x379, - SMSG_FORCED_DEATH_UPDATE = 0x37A, - CMSG_CHEAT_SET_HONOR_CURRENCY = 0x37B, - CMSG_CHEAT_SET_ARENA_CURRENCY = 0x37C, - MSG_MOVE_SET_FLIGHT_SPEED_CHEAT = 0x37D, - MSG_MOVE_SET_FLIGHT_SPEED = 0x37E, - MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT = 0x37F, - MSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x380, - SMSG_FORCE_FLIGHT_SPEED_CHANGE = 0x381, - CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0x382, - SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE = 0x383, - CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK = 0x384, - SMSG_SPLINE_SET_FLIGHT_SPEED = 0x385, - SMSG_SPLINE_SET_FLIGHT_BACK_SPEED = 0x386, - CMSG_MAELSTROM_INVALIDATE_CACHE = 0x387, - SMSG_FLIGHT_SPLINE_SYNC = 0x388, - CMSG_SET_TAXI_BENCHMARK_MODE = 0x389, - SMSG_JOINED_BATTLEGROUND_QUEUE = 0x38A, - SMSG_REALM_SPLIT = 0x38B, - CMSG_REALM_SPLIT = 0x38C, - CMSG_MOVE_CHNG_TRANSPORT = 0x38D, - MSG_PARTY_ASSIGNMENT = 0x38E, - SMSG_OFFER_PETITION_ERROR = 0x38F, - SMSG_TIME_SYNC_REQ = 0x390, - CMSG_TIME_SYNC_RESP = 0x391, - CMSG_SEND_LOCAL_EVENT = 0x392, - CMSG_SEND_GENERAL_TRIGGER = 0x393, - CMSG_SEND_COMBAT_TRIGGER = 0x394, - CMSG_MAELSTROM_GM_SENT_MAIL = 0x395, - SMSG_RESET_FAILED_NOTIFY = 0x396, - SMSG_REAL_GROUP_UPDATE = 0x397, - SMSG_LFG_DISABLED = 0x398, - CMSG_ACTIVE_PVP_CHEAT = 0x399, - CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY = 0x39A, - SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE = 0x39B, - SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE = 0x39C, - SMSG_UPDATE_COMBO_POINTS = 0x39D, - SMSG_VOICE_SESSION_ROSTER_UPDATE = 0x39E, - SMSG_VOICE_SESSION_LEAVE = 0x39F, - SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0, - CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1, - SMSG_VOICE_SET_TALKER_MUTED = 0x3A2, - SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE = 0x3A3, - SMSG_SET_EXTRA_AURA_INFO_OBSOLETE = 0x3A4, - SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE = 0x3A5, - SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE = 0x3A6, - MSG_MOVE_START_DESCEND = 0x3A7, - CMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A8, - SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A9, - SMSG_SPELL_CHANCE_PROC_LOG = 0x3AA, - CMSG_MOVE_SET_RUN_SPEED = 0x3AB, - SMSG_DISMOUNT = 0x3AC, - MSG_MOVE_UPDATE_CAN_FLY = 0x3AD, - MSG_RAID_READY_CHECK_CONFIRM = 0x3AE, - CMSG_VOICE_SESSION_ENABLE = 0x3AF, - SMSG_VOICE_SESSION_ENABLE = 0x3B0, - SMSG_VOICE_PARENTAL_CONTROLS = 0x3B1, - CMSG_GM_WHISPER = 0x3B2, - SMSG_GM_MESSAGECHAT = 0x3B3, - MSG_GM_GEARRATING = 0x3B4, - CMSG_COMMENTATOR_ENABLE = 0x3B5, - SMSG_COMMENTATOR_STATE_CHANGED = 0x3B6, - CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B7, - SMSG_COMMENTATOR_MAP_INFO = 0x3B8, - CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9, - SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3BA, - SMSG_COMMENTATOR_PLAYER_INFO = 0x3BB, - CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BC, - CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BD, - CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BE, - SMSG_CLEAR_TARGET = 0x3BF, - CMSG_BOT_DETECTED = 0x3C0, - SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C1, - CMSG_CHEAT_PLAYER_LOGIN = 0x3C2, - CMSG_CHEAT_PLAYER_LOOKUP = 0x3C3, - SMSG_CHEAT_PLAYER_LOOKUP = 0x3C4, - SMSG_KICK_REASON = 0x3C5, - MSG_RAID_READY_CHECK_FINISHED = 0x3C6, - CMSG_COMPLAIN = 0x3C7, - SMSG_COMPLAIN_RESULT = 0x3C8, - SMSG_FEATURE_SYSTEM_STATUS = 0x3C9, - CMSG_GM_SHOW_COMPLAINTS = 0x3CA, - CMSG_GM_UNSQUELCH = 0x3CB, - CMSG_CHANNEL_SILENCE_VOICE = 0x3CC, - CMSG_CHANNEL_SILENCE_ALL = 0x3CD, - CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CE, - CMSG_CHANNEL_UNSILENCE_ALL = 0x3CF, - CMSG_TARGET_CAST = 0x3D0, - CMSG_TARGET_SCRIPT_CAST = 0x3D1, - CMSG_CHANNEL_DISPLAY_LIST = 0x3D2, - CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D3, - CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D4, - SMSG_CHANNEL_MEMBER_COUNT = 0x3D5, - CMSG_CHANNEL_VOICE_ON = 0x3D6, - CMSG_CHANNEL_VOICE_OFF = 0x3D7, - CMSG_DEBUG_LIST_TARGETS = 0x3D8, - SMSG_DEBUG_LIST_TARGETS = 0x3D9, - SMSG_AVAILABLE_VOICE_CHANNEL = 0x3DA, - CMSG_ADD_VOICE_IGNORE = 0x3DB, - CMSG_DEL_VOICE_IGNORE = 0x3DC, - CMSG_PARTY_SILENCE = 0x3DD, - CMSG_PARTY_UNSILENCE = 0x3DE, - MSG_NOTIFY_PARTY_SQUELCH = 0x3DF, - SMSG_COMSAT_RECONNECT_TRY = 0x3E0, - SMSG_COMSAT_DISCONNECT = 0x3E1, - SMSG_COMSAT_CONNECT_FAIL = 0x3E2, - SMSG_VOICE_CHAT_STATUS = 0x3E3, - CMSG_REPORT_PVP_AFK = 0x3E4, - SMSG_REPORT_PVP_AFK_RESULT = 0x3E5, - CMSG_GUILD_BANKER_ACTIVATE = 0x3E6, - CMSG_GUILD_BANK_QUERY_TAB = 0x3E7, - SMSG_GUILD_BANK_LIST = 0x3E8, - CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E9, - CMSG_GUILD_BANK_BUY_TAB = 0x3EA, - CMSG_GUILD_BANK_UPDATE_TAB = 0x3EB, - CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EC, - CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3ED, - MSG_GUILD_BANK_LOG_QUERY = 0x3EE, - CMSG_SET_CHANNEL_WATCH = 0x3EF, - SMSG_USERLIST_ADD = 0x3F0, - SMSG_USERLIST_REMOVE = 0x3F1, - SMSG_USERLIST_UPDATE = 0x3F2, - CMSG_CLEAR_CHANNEL_WATCH = 0x3F3, - SMSG_INSPECT_TALENT = 0x3F4, - SMSG_GOGOGO_OBSOLETE = 0x3F5, - SMSG_ECHO_PARTY_SQUELCH = 0x3F6, - CMSG_SET_TITLE_SUFFIX = 0x3F7, - CMSG_SPELLCLICK = 0x3F8, - SMSG_LOOT_LIST = 0x3F9, - CMSG_GM_CHARACTER_RESTORE = 0x3FA, - CMSG_GM_CHARACTER_SAVE = 0x3FB, - SMSG_VOICESESSION_FULL = 0x3FC, - MSG_GUILD_PERMISSIONS = 0x3FD, - MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FE, - MSG_GUILD_EVENT_LOG_QUERY = 0x3FF, - CMSG_MAELSTROM_RENAME_GUILD = 0x400, - CMSG_GET_MIRRORIMAGE_DATA = 0x401, - SMSG_MIRRORIMAGE_DATA = 0x402, - SMSG_FORCE_DISPLAY_UPDATE = 0x403, - SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x404, - CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405, - SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x406, - CMSG_KEEP_ALIVE = 0x407, - SMSG_RAID_READY_CHECK_ERROR = 0x408, - CMSG_OPT_OUT_OF_LOOT = 0x409, - MSG_QUERY_GUILD_BANK_TEXT = 0x40A, - CMSG_SET_GUILD_BANK_TEXT = 0x40B, - CMSG_SET_GRANTABLE_LEVELS = 0x40C, - CMSG_GRANT_LEVEL = 0x40D, - CMSG_REFER_A_FRIEND = 0x40E, - MSG_GM_CHANGE_ARENA_RATING = 0x40F, - CMSG_DECLINE_CHANNEL_INVITE = 0x410, - SMSG_GROUPACTION_THROTTLED = 0x411, - SMSG_OVERRIDE_LIGHT = 0x412, // uint32 defaultMapLight, uint32 overrideLight, uint32 transitionTimeMs - SMSG_TOTEM_CREATED = 0x413, - CMSG_TOTEM_DESTROYED = 0x414, - CMSG_EXPIRE_RAID_INSTANCE = 0x415, - CMSG_NO_SPELL_VARIANCE = 0x416, - CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x417, - SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x418, - CMSG_SET_PLAYER_DECLINED_NAMES = 0x419, - SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x41A, - CMSG_QUERY_SERVER_BUCK_DATA = 0x41B, - CMSG_CLEAR_SERVER_BUCK_DATA = 0x41C, - SMSG_SERVER_BUCK_DATA = 0x41D, - SMSG_SEND_UNLEARN_SPELLS = 0x41E, - SMSG_PROPOSE_LEVEL_GRANT = 0x41F, - CMSG_ACCEPT_LEVEL_GRANT = 0x420, - SMSG_REFER_A_FRIEND_FAILURE = 0x421, - SMSG_SPLINE_MOVE_SET_FLYING = 0x422, - SMSG_SPLINE_MOVE_UNSET_FLYING = 0x423, - SMSG_SUMMON_CANCEL = 0x424, - CMSG_CHANGE_PERSONAL_ARENA_RATING = 0x425, - CMSG_ALTER_APPEARANCE = 0x426, - SMSG_ENABLE_BARBER_SHOP = 0x427, - SMSG_BARBER_SHOP_RESULT = 0x428, - CMSG_CALENDAR_GET_CALENDAR = 0x429, - CMSG_CALENDAR_GET_EVENT = 0x42A, - CMSG_CALENDAR_GUILD_FILTER = 0x42B, - CMSG_CALENDAR_ARENA_TEAM = 0x42C, - CMSG_CALENDAR_ADD_EVENT = 0x42D, - CMSG_CALENDAR_UPDATE_EVENT = 0x42E, - CMSG_CALENDAR_REMOVE_EVENT = 0x42F, - CMSG_CALENDAR_COPY_EVENT = 0x430, - CMSG_CALENDAR_EVENT_INVITE = 0x431, - CMSG_CALENDAR_EVENT_RSVP = 0x432, - CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x433, - CMSG_CALENDAR_EVENT_STATUS = 0x434, - CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x435, - SMSG_CALENDAR_SEND_CALENDAR = 0x436, - SMSG_CALENDAR_SEND_EVENT = 0x437, - SMSG_CALENDAR_FILTER_GUILD = 0x438, - SMSG_CALENDAR_ARENA_TEAM = 0x439, - SMSG_CALENDAR_EVENT_INVITE = 0x43A, - SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x43B, - SMSG_CALENDAR_EVENT_STATUS = 0x43C, - SMSG_CALENDAR_COMMAND_RESULT = 0x43D, - SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x43E, - SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x43F, - SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x440, - SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x441, - SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x442, - SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x443, - SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x444, - SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x445, - CMSG_CALENDAR_COMPLAIN = 0x446, - CMSG_CALENDAR_GET_NUM_PENDING = 0x447, - SMSG_CALENDAR_SEND_NUM_PENDING = 0x448, - CMSG_SAVE_DANCE = 0x449, - SMSG_NOTIFY_DANCE = 0x44A, - CMSG_PLAY_DANCE = 0x44B, - SMSG_PLAY_DANCE = 0x44C, - CMSG_LOAD_DANCES = 0x44D, - CMSG_STOP_DANCE = 0x44E, - SMSG_STOP_DANCE = 0x44F, - CMSG_SYNC_DANCE = 0x450, - CMSG_DANCE_QUERY = 0x451, - SMSG_DANCE_QUERY_RESPONSE = 0x452, - SMSG_INVALIDATE_DANCE = 0x453, - CMSG_DELETE_DANCE = 0x454, - SMSG_LEARNED_DANCE_MOVES = 0x455, - CMSG_LEARN_DANCE_MOVE = 0x456, - CMSG_UNLEARN_DANCE_MOVE = 0x457, - CMSG_SET_RUNE_COUNT = 0x458, - CMSG_SET_RUNE_COOLDOWN = 0x459, - MSG_MOVE_SET_PITCH_RATE_CHEAT = 0x45A, - MSG_MOVE_SET_PITCH_RATE = 0x45B, - SMSG_FORCE_PITCH_RATE_CHANGE = 0x45C, - CMSG_FORCE_PITCH_RATE_CHANGE_ACK = 0x45D, - SMSG_SPLINE_SET_PITCH_RATE = 0x45E, - CMSG_CALENDAR_EVENT_INVITE_NOTES = 0x45F, - SMSG_CALENDAR_EVENT_INVITE_NOTES = 0x460, - SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT = 0x461, - CMSG_UPDATE_MISSILE_TRAJECTORY = 0x462, - SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x463, - SMSG_TRIGGER_MOVIE = 0x464, - CMSG_COMPLETE_MOVIE = 0x465, - CMSG_SET_GLYPH_SLOT = 0x466, - CMSG_SET_GLYPH = 0x467, - SMSG_ACHIEVEMENT_EARNED = 0x468, - SMSG_DYNAMIC_DROP_ROLL_RESULT = 0x469, - SMSG_CRITERIA_UPDATE = 0x46A, - CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x46B, - SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x46C, - CMSG_DISMISS_CONTROLLED_VEHICLE = 0x46D, - CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x46E, - SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x46F, - CMSG_SET_CRITERIA_CHEAT = 0x470, - SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0x471, - CMSG_UNITANIMTIER_CHEAT = 0x472, - CMSG_CHAR_CUSTOMIZE = 0x473, - SMSG_CHAR_CUSTOMIZE = 0x474, - SMSG_PET_RENAMEABLE = 0x475, - CMSG_REQUEST_VEHICLE_EXIT = 0x476, - CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x477, - CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x478, - CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x479, - CMSG_PET_LEARN_TALENT = 0x47A, - CMSG_PET_UNLEARN_TALENTS = 0x47B, - SMSG_SET_PHASE_SHIFT = 0x47C, - SMSG_ALL_ACHIEVEMENT_DATA = 0x47D, - CMSG_FORCE_SAY_CHEAT = 0x47E, - SMSG_HEALTH_UPDATE = 0x47F, - SMSG_POWER_UPDATE = 0x480, - CMSG_GAMEOBJ_REPORT_USE = 0x481, - SMSG_HIGHEST_THREAT_UPDATE = 0x482, - SMSG_THREAT_UPDATE = 0x483, - SMSG_THREAT_REMOVE = 0x484, - SMSG_THREAT_CLEAR = 0x485, - SMSG_CONVERT_RUNE = 0x486, - SMSG_RESYNC_RUNES = 0x487, - SMSG_ADD_RUNE_POWER = 0x488, - CMSG_START_QUEST = 0x489, - CMSG_REMOVE_GLYPH = 0x48A, - CMSG_DUMP_OBJECTS = 0x48B, - SMSG_DUMP_OBJECTS_DATA = 0x48C, - CMSG_DISMISS_CRITTER = 0x48D, - SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x48E, - CMSG_AUCTION_LIST_PENDING_SALES = 0x48F, - SMSG_AUCTION_LIST_PENDING_SALES = 0x490, - SMSG_MODIFY_COOLDOWN = 0x491, - SMSG_PET_UPDATE_COMBO_POINTS = 0x492, - CMSG_ENABLETAXI = 0x493, - SMSG_PRE_RESURRECT = 0x494, - SMSG_AURA_UPDATE_ALL = 0x495, - SMSG_AURA_UPDATE = 0x496, - CMSG_FLOOD_GRACE_CHEAT = 0x497, - SMSG_SERVER_FIRST_ACHIEVEMENT = 0x498, - SMSG_PET_LEARNED_SPELL = 0x499, - SMSG_PET_REMOVED_SPELL = 0x49A, - CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x49B, - CMSG_HEARTH_AND_RESURRECT = 0x49C, - SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x49D, - SMSG_CRITERIA_DELETED = 0x49E, - SMSG_ACHIEVEMENT_DELETED = 0x49F, - CMSG_SERVER_INFO_QUERY = 0x4A0, - SMSG_SERVER_INFO_RESPONSE = 0x4A1, - CMSG_CHECK_LOGIN_CRITERIA = 0x4A2, - SMSG_SERVER_BUCK_DATA_START = 0x4A3, - CMSG_SET_BREATH = 0x4A4, - CMSG_QUERY_VEHICLE_STATUS = 0x4A5, - SMSG_BATTLEGROUND_INFO_THROTTLED = 0x4A6, // empty, "You can't do that yet" - SMSG_PLAYER_VEHICLE_DATA = 0x4A7, // guid+uint32 (vehicle) - CMSG_PLAYER_VEHICLE_ENTER = 0x4A8, // uint64 - CMSG_CONTROLLER_EJECT_PASSENGER = 0x4A9, // uint64 - SMSG_PET_GUIDS = 0x4AA, - SMSG_CLIENTCACHE_VERSION = 0x4AB, - CMSG_CHANGE_GDF_ARENA_RATING = 0x4AC, - CMSG_SET_ARENA_TEAM_RATING_BY_INDEX = 0x4AD, - CMSG_SET_ARENA_TEAM_WEEKLY_GAMES = 0x4AE, - CMSG_SET_ARENA_TEAM_SEASON_GAMES = 0x4AF, - CMSG_SET_ARENA_MEMBER_WEEKLY_GAMES = 0x4B0, - CMSG_SET_ARENA_MEMBER_SEASON_GAMES = 0x4B1, - SMSG_ITEM_REFUND_INFO_RESPONSE = 0x4B2, - CMSG_ITEM_REFUND_INFO = 0x4B3, - CMSG_ITEM_REFUND = 0x4B4, // lua: ContainerRefundItemPurchase - SMSG_ITEM_REFUND_RESULT = 0x4B5, - CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // uint32 - SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // 3*float+float - CMSG_UNUSED5 = 0x4B8, - CMSG_UNUSED6 = 0x4B9, - CMSG_CALENDAR_EVENT_SIGNUP = 0x4BA, // uint64 - SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x4BB, - SMSG_EQUIPMENT_SET_LIST = 0x4BC, // equipment manager list? - CMSG_EQUIPMENT_SET_SAVE = 0x4BD, - CMSG_UPDATE_PROJECTILE_POSITION = 0x4BE, - SMSG_SET_PROJECTILE_POSITION = 0x4BF, - SMSG_TALENTS_INFO = 0x4C0, - CMSG_LEARN_PREVIEW_TALENTS = 0x4C1, - CMSG_LEARN_PREVIEW_TALENTS_PET = 0x4C2, - CMSG_SET_ACTIVE_TALENT_GROUP_OBSOLETE = 0x4C3, - CMSG_GM_GRANT_ACHIEVEMENT = 0x4C4, - CMSG_GM_REMOVE_ACHIEVEMENT = 0x4C5, - CMSG_GM_SET_CRITERIA_FOR_PLAYER = 0x4C6, - SMSG_ARENA_OPPONENT_UPDATE = 0x4C7, // uint64 - SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0x4C8, // uint32 "Can't modify arena team while queued or in a match." - CMSG_PROFILEDATA_REQUEST = 0x4C9, - SMSG_PROFILEDATA_RESPONSE = 0x4CA, - CMSG_START_BATTLEFIELD_CHEAT = 0x4CB, - CMSG_END_BATTLEFIELD_CHEAT = 0x4CC, - SMSG_MULTIPLE_PACKETS = 0x4CD, - SMSG_MOVE_GRAVITY_DISABLE = 0x4CE, - CMSG_MOVE_GRAVITY_DISABLE_ACK = 0x4CF, - SMSG_MOVE_GRAVITY_ENABLE = 0x4D0, - CMSG_MOVE_GRAVITY_ENABLE_ACK = 0x4D1, - MSG_MOVE_GRAVITY_CHNG = 0x4D2, - SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x4D3, - SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0x4D4, - CMSG_EQUIPMENT_SET_USE = 0x4D5, - SMSG_EQUIPMENT_SET_USE_RESULT = 0x4D6, - CMSG_FORCE_ANIM = 0x4D7, - SMSG_FORCE_ANIM = 0x4D8, - CMSG_CHAR_FACTION_CHANGE = 0x4D9, - SMSG_CHAR_FACTION_CHANGE = 0x4DA, - CMSG_PVP_QUEUE_STATS_REQUEST = 0x4DB, - SMSG_PVP_QUEUE_STATS = 0x4DC, - CMSG_SET_PAID_SERVICE_CHEAT = 0x4DD, - SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0x4DE, // uint32 - CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0x4DF, - SMSG_BATTLEFIELD_MGR_ENTERED = 0x4E0, // uint32, uint8, uint8 - SMSG_BATTLEFIELD_MGR_QUEUE_INVITE = 0x4E1, // uint32 - CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0x4E2, - CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST = 0x4E3, - SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0x4E4, // uint32, uint8 - SMSG_BATTLEFIELD_MGR_EJECT_PENDING = 0x4E5, // uint32 - SMSG_BATTLEFIELD_MGR_EJECTED = 0x4E6, // uint32, uint32, uint8 - CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x4E7, - SMSG_BATTLEFIELD_MGR_STATE_CHANGE = 0x4E8, // uint32, uint32 - CMSG_BATTLEFIELD_MANAGER_ADVANCE_STATE = 0x4E9, - CMSG_BATTLEFIELD_MANAGER_SET_NEXT_TRANSITION_TIME= 0x4EA, - MSG_SET_RAID_DIFFICULTY = 0x4EB, - CMSG_TOGGLE_XP_GAIN = 0x4EC, - SMSG_TOGGLE_XP_GAIN = 0x4ED, // enable/disable XP gain console message - SMSG_GMRESPONSE_DB_ERROR = 0x4EE, // empty - SMSG_GMRESPONSE_RECEIVED = 0x4EF, // uint32, uint32, string[2000], string[4000][4] - CMSG_GMRESPONSE_RESOLVE = 0x4F0, - SMSG_GMRESPONSE_STATUS_UPDATE = 0x4F1, // uint8 (1 - EVENT_GMSURVEY_DISPLAY, 0 - EVENT_UPDATE_TICKET) - SMSG_GMRESPONSE_CREATE_TICKET = 0x4F2, - CMSG_GMRESPONSE_CREATE_TICKET = 0x4F3, - CMSG_SERVERINFO = 0x4F4, - SMSG_SERVERINFO = 0x4F5, - CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F6, - SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F7, - CMSG_CHAR_RACE_CHANGE = 0x4F8, - MSG_VIEW_PHASE_SHIFT = 0x4F9, - SMSG_TALENTS_INVOLUNTARILY_RESET = 0x4FA, // uint8 - CMSG_DEBUG_SERVER_GEO = 0x4FB, - SMSG_DEBUG_SERVER_GEO = 0x4FC, - SMSG_LOOT_SLOT_CHANGED = 0x4FD, - UMSG_UPDATE_GROUP_INFO = 0x4FE, - CMSG_READY_FOR_ACCOUNT_DATA_TIMES = 0x4FF, - CMSG_QUERY_QUESTS_COMPLETED = 0x500, - SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0x501, - CMSG_GM_REPORT_LAG = 0x502, - CMSG_AFK_MONITOR_INFO_REQUEST = 0x503, - SMSG_AFK_MONITOR_INFO_RESPONSE = 0x504, - CMSG_AFK_MONITOR_INFO_CLEAR = 0x505, - SMSG_CORPSE_NOT_IN_INSTANCE = 0x506, - CMSG_GM_NUKE_CHARACTER = 0x507, - CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0x508, - CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0x509, - SMSG_CAMERA_SHAKE = 0x50A, // uint32 SpellEffectCameraShakes.dbc index, uint32 - SMSG_UPDATE_ITEM_ENCHANTMENTS = 0x50B, // some item update packet? - CMSG_SET_CHARACTER_MODEL = 0x50C, - SMSG_REDIRECT_CLIENT = 0x50D, // uint32 ip, uint16 port, uint32 unk, uint8[20] hash (ip + port, seed=sessionkey) - CMSG_REDIRECTION_FAILED = 0x50E, // something with networking - SMSG_SUSPEND_COMMS = 0x50F, - CMSG_SUSPEND_COMMS_ACK = 0x510, - SMSG_FORCE_SEND_QUEUED_PACKETS = 0x511, - CMSG_REDIRECTION_AUTH_PROOF = 0x512, - CMSG_DROP_NEW_CONNECTION = 0x513, - SMSG_SEND_ALL_COMBAT_LOG = 0x514, - SMSG_OPEN_LFG_DUNGEON_FINDER = 0x515, - SMSG_MOVE_SET_COLLISION_HGT = 0x516, - CMSG_MOVE_SET_COLLISION_HGT_ACK = 0x517, - MSG_MOVE_SET_COLLISION_HGT = 0x518, - CMSG_CLEAR_RANDOM_BG_WIN_TIME = 0x519, - CMSG_CLEAR_HOLIDAY_BG_WIN_TIME = 0x51A, - CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x51B, - SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1 = 0x51C, - SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0x51D, - SMSG_MULTIPLE_MOVES = 0x51E, // uncompressed version of SMSG_COMPRESSED_MOVES - NUM_MSG_TYPES = 0x51F + NUM_OPCODE_HANDLERS = (0x7FFF+1), + UNKNOWN_OPCODE = (0xFFFF+1), + NULL_OPCODE = 0, + COMPRESSED_OPCODE_MASK = 0x8000, + + CMSG_ACCEPT_LEVEL_GRANT = 0x0205, + CMSG_ACCEPT_TRADE = 0x7110, + CMSG_ACTIVATETAXI = 0x6E06, + CMSG_ACTIVATETAXIEXPRESS = 0x0515, + CMSG_ADDON_REGISTERED_PREFIXES = 0x0954, + CMSG_ADD_FRIEND = 0x6527, + CMSG_ADD_IGNORE = 0x4726, + CMSG_ADD_VOICE_IGNORE = 0x0F06, + CMSG_ALTER_APPEARANCE = 0x0914, + CMSG_AREATRIGGER = 0x0937, + CMSG_AREA_SPIRIT_HEALER_QUERY = 0x4907, + CMSG_AREA_SPIRIT_HEALER_QUEUE = 0x4815, + CMSG_ARENA_TEAM_ACCEPT = 0x2A25, + CMSG_ARENA_TEAM_CREATE = 0x04A1, + CMSG_ARENA_TEAM_DECLINE = 0x6925, + CMSG_ARENA_TEAM_DISBAND = 0x6504, + CMSG_ARENA_TEAM_INVITE = 0x2F27, + CMSG_ARENA_TEAM_LEADER = 0x4204, + CMSG_ARENA_TEAM_LEAVE = 0x0E16, + CMSG_ARENA_TEAM_QUERY = 0x0514, + CMSG_ARENA_TEAM_REMOVE = 0x2F05, + CMSG_ARENA_TEAM_ROSTER = 0x6F37, + CMSG_ATTACKSTOP = 0x4106, + CMSG_ATTACKSWING = 0x0926, + CMSG_AUCTION_LIST_BIDDER_ITEMS = 0x6937, + CMSG_AUCTION_LIST_ITEMS = 0x0324, + CMSG_AUCTION_LIST_OWNER_ITEMS = 0x0206, + CMSG_AUCTION_LIST_PENDING_SALES = 0x2C17, + CMSG_AUCTION_PLACE_BID = 0x2306, + CMSG_AUCTION_REMOVE_ITEM = 0x6426, + CMSG_AUCTION_SELL_ITEM = 0x4A06, + CMSG_AUTH_SESSION = 0x0449, + CMSG_AUTOBANK_ITEM = 0x2537, + CMSG_AUTOEQUIP_GROUND_ITEM = 0x0000, + CMSG_AUTOEQUIP_ITEM = 0x4304, + CMSG_AUTOEQUIP_ITEM_SLOT = 0x4A17, + CMSG_AUTOSTORE_BAG_ITEM = 0x0236, + CMSG_AUTOSTORE_BANK_ITEM = 0x0607, + CMSG_AUTOSTORE_GROUND_ITEM = 0x0000, + CMSG_AUTOSTORE_LOOT_ITEM = 0x0E34, + CMSG_AUTO_DECLINE_GUILD_INVITES = 0x2034, + CMSG_BANKER_ACTIVATE = 0x0005, + CMSG_BATTLEFIELD_JOIN = 0x0000, + CMSG_BATTLEFIELD_LEAVE = 0x3018, + CMSG_BATTLEFIELD_LIST = 0x3814, + CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0x05A3, + CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x2490, + CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0x0413, + CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST = 0x710C, + CMSG_BATTLEFIELD_PORT = 0x711A, + CMSG_BATTLEFIELD_REQUEST_SCORE_DATA = 0x0000, + CMSG_BATTLEFIELD_STATUS = 0x2500, + CMSG_BATTLEGROUND_PLAYER_POSITIONS = 0x3902, + CMSG_BATTLEMASTER_JOIN = 0x7902, + CMSG_BATTLEMASTER_JOIN_ARENA = 0x701C, + CMSG_BATTLEMASTER_JOIN_RATED = 0x3B18, + CMSG_BEGIN_TRADE = 0x721E, + CMSG_BINDER_ACTIVATE = 0x4006, + CMSG_BOT_DETECTED2 = 0x0000, + CMSG_BUG = 0x4035, + CMSG_BUSY_TRADE = 0x331C, + CMSG_BUYBACK_ITEM = 0x6C17, + CMSG_BUY_BANK_SLOT = 0x0425, + CMSG_BUY_ITEM = 0x0736, + CMSG_CALENDAR_ADD_EVENT = 0x0726, + CMSG_CALENDAR_ARENA_TEAM = 0x0204, + CMSG_CALENDAR_COMPLAIN = 0x4C36, + CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x0000, + CMSG_CALENDAR_COPY_EVENT = 0x0207, + CMSG_CALENDAR_EVENT_INVITE = 0x2435, + CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x6B35, + CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x4337, + CMSG_CALENDAR_EVENT_RSVP = 0x0227, + CMSG_CALENDAR_EVENT_SIGNUP = 0x6606, + CMSG_CALENDAR_EVENT_STATUS = 0x2D24, + CMSG_CALENDAR_GET_CALENDAR = 0x2814, + CMSG_CALENDAR_GET_EVENT = 0x6416, + CMSG_CALENDAR_GET_NUM_PENDING = 0x4D05, + CMSG_CALENDAR_GUILD_FILTER = 0x4A16, + CMSG_CALENDAR_REMOVE_EVENT = 0x6636, + CMSG_CALENDAR_UPDATE_EVENT = 0x2114, + CMSG_CANCEL_AURA = 0x0E26, + CMSG_CANCEL_AUTO_REPEAT_SPELL = 0x6C35, + CMSG_CANCEL_CAST = 0x0115, + CMSG_CANCEL_CHANNELLING = 0x6C25, + CMSG_CANCEL_GROWTH_AURA = 0x0000, + CMSG_CANCEL_MOUNT_AURA = 0x0635, + CMSG_CANCEL_QUEUED_SPELL = 0x7B1C, + CMSG_CANCEL_TEMP_ENCHANTMENT = 0x6C37, + CMSG_CANCEL_TRADE = 0x731E, + CMSG_CAST_SPELL = 0x4C07, + CMSG_CHANGEPLAYER_DIFFICULTY = 0x6107, + CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x7310, + CMSG_CHANNEL_ANNOUNCEMENTS = 0x1146, + CMSG_CHANNEL_BAN = 0x3D56, + CMSG_CHANNEL_DISPLAY_LIST = 0x2144, + CMSG_CHANNEL_INVITE = 0x0144, + CMSG_CHANNEL_KICK = 0x3156, + CMSG_CHANNEL_LIST = 0x1556, + CMSG_CHANNEL_MODERATE = 0x2944, + CMSG_CHANNEL_MODERATOR = 0x0146, + CMSG_CHANNEL_MUTE = 0x2554, + CMSG_CHANNEL_OWNER = 0x3D44, + CMSG_CHANNEL_PASSWORD = 0x2556, + CMSG_CHANNEL_ROSTER_INFO = 0x3546, + CMSG_CHANNEL_SET_OWNER = 0x3556, + CMSG_CHANNEL_SILENCE_ALL = 0x2154, + CMSG_CHANNEL_SILENCE_VOICE = 0x2D54, + CMSG_CHANNEL_UNBAN = 0x2D46, + CMSG_CHANNEL_UNMODERATOR = 0x1954, + CMSG_CHANNEL_UNMUTE = 0x3554, + CMSG_CHANNEL_UNSILENCE_ALL = 0x2546, + CMSG_CHANNEL_UNSILENCE_VOICE = 0x3146, + CMSG_CHANNEL_VOICE_OFF = 0x3144, + CMSG_CHANNEL_VOICE_ON = 0x1144, + CMSG_CHAR_CREATE = 0x4A36, + CMSG_CHAR_CUSTOMIZE = 0x2C34, + CMSG_CHAR_DELETE = 0x6425, + CMSG_CHAR_ENUM = 0x0502, + CMSG_CHAR_FACTION_CHANGE = 0x2735, + CMSG_CHAR_RACE_CHANGE = 0x0D24, + CMSG_CHAR_RENAME = 0x2327, + CMSG_CHAT_FILTERED = 0x0946, + CMSG_CHAT_IGNORED = 0x0D54, + CMSG_CLEAR_CHANNEL_WATCH = 0x2604, + CMSG_CLEAR_RAID_MARKER = 0x7300, + CMSG_CLEAR_TRADE_ITEM = 0x7018, + CMSG_COMMENTATOR_ENABLE = 0x0B07, + CMSG_COMMENTATOR_ENTER_INSTANCE = 0x4105, + CMSG_COMMENTATOR_EXIT_INSTANCE = 0x6136, + CMSG_COMMENTATOR_GET_MAP_INFO = 0x0026, + CMSG_COMMENTATOR_GET_PARTY_INFO = 0x2412, + CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x0D14, + CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x0917, + CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x0025, + CMSG_COMMENTATOR_START_WARGAME = 0x25A0, + CMSG_COMPLAIN = 0x0427, + CMSG_COMPLETE_CINEMATIC = 0x2116, + CMSG_COMPLETE_MOVIE = 0x4136, + CMSG_CONNECT_TO_FAILED = 0x2533, + CMSG_CONTACT_LIST = 0x4534, + CMSG_CORPSE_MAP_POSITION_QUERY = 0x6205, + CMSG_CREATURE_QUERY = 0x2706, + CMSG_DANCE_QUERY = 0x4E07, + CMSG_DECLINE_CHANNEL_INVITE = 0x0000, + CMSG_DELETEEQUIPMENT_SET = 0x4D07, + CMSG_DEL_FRIEND = 0x6A15, + CMSG_DEL_IGNORE = 0x4727, + CMSG_DEL_VOICE_IGNORE = 0x0024, + CMSG_DESTROY_ITEM = 0x4A27, + CMSG_DESTROY_ITEMS = 0x0000, + CMSG_DISMISS_CONTROLLED_VEHICLE = 0x3218, + CMSG_DISMISS_CRITTER = 0x4227, + CMSG_DUEL_ACCEPTED = 0x2136, + CMSG_DUEL_CANCELLED = 0x6624, + CMSG_DUNGEON_FINDER_GET_SYSTEM_INFO = 0x0412, + CMSG_EJECT_PASSENGER = 0x6927, + CMSG_EMOTE = 0x4C26, + CMSG_ENABLETAXI = 0x0C16, + CMSG_ENABLE_NAGLE = 0x4449, + CMSG_EQUIPMENT_SET_DELETE = 0x0000, + CMSG_EQUIPMENT_SET_SAVE = 0x4F27, + CMSG_EQUIPMENT_SET_USE = 0x0417, + CMSG_FAR_SIGHT = 0x4835, + CMSG_FORCE_MOVE_ROOT_ACK = 0x701E, + CMSG_FORCE_MOVE_UNROOT_ACK = 0x7808, + CMSG_GAMEOBJECT_QUERY = 0x4017, + CMSG_GAMEOBJ_REPORT_USE = 0x4827, + CMSG_GAMEOBJ_USE = 0x4E17, + CMSG_GAMESPEED_SET = 0x0000, + CMSG_GAMETIME_SET = 0x0000, + CMSG_GETDEATHBINDZONE = 0x0000, + CMSG_GET_MAIL_LIST = 0x4D37, + CMSG_GET_MIRRORIMAGE_DATA = 0x0C25, + CMSG_GHOST = 0x0000, + CMSG_GMRESPONSE_RESOLVE = 0x6506, + CMSG_GMSURVEY_SUBMIT = 0x2724, + CMSG_GMTICKET_CREATE = 0x0137, + CMSG_GMTICKET_DELETETICKET = 0x6B14, + CMSG_GMTICKET_GETTICKET = 0x0326, + CMSG_GMTICKET_SYSTEMSTATUS = 0x4205, + CMSG_GMTICKET_UPDATETEXT = 0x0636, + CMSG_GM_INVIS = 0x0000, + CMSG_GM_NUKE = 0x0000, + CMSG_GM_REPORT_LAG = 0x6726, + CMSG_GM_SET_SECURITY_GROUP = 0x0000, + CMSG_GOSSIP_HELLO = 0x4525, + CMSG_GOSSIP_SELECT_OPTION = 0x0216, + CMSG_GRANT_LEVEL = 0x6D16, + CMSG_GROUP_ACCEPT = 0x0000, + CMSG_GROUP_ASSISTANT_LEADER = 0x6025, + CMSG_GROUP_CANCEL = 0x0000, + CMSG_GROUP_CHANGE_SUB_GROUP = 0x4124, + CMSG_GROUP_DECLINE = 0x0000, + CMSG_GROUP_DISBAND = 0x2804, + CMSG_GROUP_INVITE = 0x0513, + CMSG_GROUP_INVITE_RESPONSE = 0x0410, + CMSG_GROUP_RAID_CONVERT = 0x6E27, + CMSG_GROUP_REQUEST_JOIN_UPDATES = 0x2583, + CMSG_GROUP_SET_LEADER = 0x4C17, + CMSG_GROUP_SET_ROLES = 0x25B1, + CMSG_GROUP_SWAP_SUB_GROUP = 0x0034, + CMSG_GROUP_UNINVITE = 0x0000, + CMSG_GROUP_UNINVITE_GUID = 0x2E07, + CMSG_GUILD_ACCEPT = 0x2531, + CMSG_GUILD_ACHIEVEMENT_MEMBERS = 0x3025, + CMSG_GUILD_ACHIEVEMENT_PROGRESS_QUERY = 0x3235, + CMSG_GUILD_ADD_RANK = 0x3030, + CMSG_GUILD_ASSIGN_MEMBER_RANK = 0x3032, + CMSG_GUILD_BANKER_ACTIVATE = 0x2E37, + CMSG_GUILD_BANK_BUY_TAB = 0x0C37, + CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x0707, + CMSG_GUILD_BANK_LOG_QUERY = 0x3224, + CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY = 0x0000, + CMSG_GUILD_BANK_NOTE = 0x0000, + CMSG_GUILD_BANK_QUERY_TAB = 0x2E35, + CMSG_GUILD_BANK_QUERY_TEXT = 0x3220, + CMSG_GUILD_BANK_REM_MONEY_WITHDRAW_QUERY = 0x1225, + CMSG_GUILD_BANK_SET_TAB_TEXT = 0x3023, + CMSG_GUILD_BANK_SWAP_ITEMS = 0x2315, + CMSG_GUILD_BANK_UPDATE_TAB = 0x0106, + CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x0037, + CMSG_GUILD_CHANGE_NAME_REQUEST = 0x1232, + CMSG_GUILD_CREATE = 0x0000, + CMSG_GUILD_DECLINE = 0x3231, + CMSG_GUILD_DEL_RANK = 0x3234, + CMSG_GUILD_DEMOTE = 0x1020, + CMSG_GUILD_DISBAND = 0x3226, + CMSG_GUILD_EVENT_LOG_QUERY = 0x1220, + CMSG_GUILD_INFO = 0x0000, + CMSG_GUILD_INFO_TEXT = 0x3227, + CMSG_GUILD_INVITE = 0x24B0, + CMSG_GUILD_LEADER = 0x0000, + CMSG_GUILD_LEAVE = 0x1021, + CMSG_GUILD_MEMBER_SEND_SOR_REQUEST = 0x3225, + CMSG_GUILD_MOTD = 0x1035, + CMSG_GUILD_NEWS_UPDATE_STICKY = 0x3223, + CMSG_GUILD_PERMISSIONS = 0x3022, + CMSG_GUILD_PROMOTE = 0x1030, + CMSG_GUILD_QUERY = 0x4426, + CMSG_GUILD_QUERY_NEWS = 0x3020, + CMSG_GUILD_QUERY_RANKS = 0x1026, + CMSG_GUILD_REMOVE = 0x1231, + CMSG_GUILD_REPLACE_GUILD_MASTER = 0x1034, + CMSG_GUILD_REQUEST_CHALLENGE_UPDATE = 0x1224, + CMSG_GUILD_REQUEST_MAX_DAILY_XP = 0x3232, + CMSG_GUILD_ROSTER = 0x1226, + CMSG_GUILD_SET_ACHIEVEMENT_TRACKING = 0x1027, + CMSG_GUILD_SET_GUILD_MASTER = 0x3034, + CMSG_GUILD_SET_NOTE = 0x1233, + CMSG_GUILD_SET_RANK_PERMISSIONS = 0x1024, + CMSG_GUILD_SWITCH_RANK = 0x1221, + CMSG_HEARTH_AND_RESURRECT = 0x4B34, + CMSG_IGNORE_TRADE = 0x7112, + CMSG_INITIATE_TRADE = 0x7916, + CMSG_INSPECT = 0x0927, + CMSG_INSTANCE_LOCK_WARNING_RESPONSE = 0x6234, + CMSG_ITEM_REFUND = 0x6134, + CMSG_ITEM_REFUND_INFO = 0x2206, + CMSG_ITEM_TEXT_QUERY = 0x2406, + CMSG_JOIN_CHANNEL = 0x0156, + CMSG_KEEP_ALIVE = 0x0015, + CMSG_LEARN_PREVIEW_TALENTS = 0x2415, + CMSG_LEARN_PREVIEW_TALENTS_PET = 0x6E24, + CMSG_LEARN_TALENT = 0x0306, + CMSG_LEAVE_BATTLEFIELD = 0x0000, + CMSG_LEAVE_CHANNEL = 0x2D56, + CMSG_LFG_GET_PLAYER_INFO = 0x0000, + CMSG_LFG_GET_STATUS = 0x2581, + CMSG_LFG_JOIN = 0x2430, + CMSG_LFG_LEAVE = 0x2433, + CMSG_LFG_LFR_JOIN = 0x0531, + CMSG_LFG_LFR_LEAVE = 0x0500, + CMSG_LFG_PARTY_LOCK_INFO_REQUEST = 0x0000, + CMSG_LFG_PROPOSAL_RESULT = 0x0403, + CMSG_LFG_SET_BOOT_VOTE = 0x04B3, + CMSG_LFG_SET_COMMENT = 0x0530, + CMSG_LFG_SET_ROLES = 0x0480, + CMSG_LFG_TELEPORT = 0x2482, + CMSG_LF_GUILD_ADD_RECRUIT = 0x4448, + CMSG_LF_GUILD_BROWSE = 0x0548, + CMSG_LF_GUILD_DECLINE_RECRUIT = 0x1031, + CMSG_LF_GUILD_GET_APPLICATIONS = 0x1230, + CMSG_LF_GUILD_GET_RECRUITS = 0x3230, + CMSG_LF_GUILD_JOIN = 0x0000, + CMSG_LF_GUILD_POST_REQUEST = 0x3237, + CMSG_LF_GUILD_REMOVE_RECRUIT = 0x3027, + CMSG_LF_GUILD_SET_GUILD_POST = 0x0448, + CMSG_LIST_INVENTORY = 0x2806, + CMSG_LOAD_SCREEN = 0x2422, + CMSG_LOGOUT_CANCEL = 0x2324, + CMSG_LOGOUT_REQUEST = 0x0A25, + CMSG_LOG_DISCONNECT = 0x446D, + CMSG_LOOT = 0x0127, + CMSG_LOOT_CURRENCY = 0x781C, + CMSG_LOOT_MASTER_GIVE = 0x4F35, + CMSG_LOOT_METHOD = 0x2F24, + CMSG_LOOT_MONEY = 0x6227, + CMSG_LOOT_RELEASE = 0x2007, + CMSG_LOOT_ROLL = 0x6934, + CMSG_MAIL_CREATE_TEXT_ITEM = 0x0B14, + CMSG_MAIL_DELETE = 0x6104, + CMSG_MAIL_MARK_AS_READ = 0x0C07, + CMSG_MAIL_RETURN_TO_SENDER = 0x0816, + CMSG_MAIL_TAKE_ITEM = 0x2B06, + CMSG_MAIL_TAKE_MONEY = 0x4034, + CMSG_MEETINGSTONE_INFO = 0x0000, + CMSG_MESSAGECHAT_ADDON_BATTLEGROUND = 0x0D46, + CMSG_MESSAGECHAT_ADDON_GUILD = 0x0544, + CMSG_MESSAGECHAT_ADDON_OFFICER = 0x3954, + CMSG_MESSAGECHAT_ADDON_PARTY = 0x0546, + CMSG_MESSAGECHAT_ADDON_RAID = 0x1D56, + CMSG_MESSAGECHAT_ADDON_WHISPER = 0x2146, + CMSG_MESSAGECHAT_AFK = 0x0D44, + CMSG_MESSAGECHAT_BATTLEGROUND = 0x2156, + CMSG_MESSAGECHAT_CHANNEL = 0x1D44, + CMSG_MESSAGECHAT_DND = 0x2946, + CMSG_MESSAGECHAT_EMOTE = 0x1156, + CMSG_MESSAGECHAT_GUILD = 0x3956, + CMSG_MESSAGECHAT_OFFICER = 0x1946, + CMSG_MESSAGECHAT_PARTY = 0x1D46, + CMSG_MESSAGECHAT_RAID = 0x2D44, + CMSG_MESSAGECHAT_RAID_WARNING = 0x0944, + CMSG_MESSAGECHAT_SAY = 0x1154, + CMSG_MESSAGECHAT_WHISPER = 0x0D56, + CMSG_MESSAGECHAT_YELL = 0x3544, + CMSG_MINIGAME_MOVE = 0x2A34, + CMSG_MOUNTSPECIAL_ANIM = 0x2807, + CMSG_MOVE_CHARM_TELEPORT_CHEAT = 0x0000, + CMSG_MOVE_CHNG_TRANSPORT = 0x3102, + CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK = 0x0000, + CMSG_MOVE_FALL_RESET = 0x310A, + CMSG_MOVE_FEATHER_FALL_ACK = 0x3110, + CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK = 0x310E, + CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0x7314, + CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK = 0x3100, + CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK = 0x3216, + CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK = 0x7818, + CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK = 0x7A16, + CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK = 0x7A10, + CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK = 0x7316, + CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK = 0x7210, + CMSG_MOVE_GRAVITY_DISABLE_ACK = 0x3118, + CMSG_MOVE_GRAVITY_ENABLE_ACK = 0x700A, + CMSG_MOVE_HOVER_ACK = 0x3318, + CMSG_MOVE_KNOCK_BACK_ACK = 0x721C, + CMSG_MOVE_NOT_ACTIVE_MOVER = 0x7A1A, + CMSG_MOVE_SET_CAN_FLY = 0x720E, + CMSG_MOVE_SET_CAN_FLY_ACK = 0x790C, + CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK = 0x3014, + CMSG_MOVE_SET_COLLISION_HEIGHT_ACK = 0x7114, + CMSG_MOVE_SET_RELATIVE_POSITION = 0x0000, + CMSG_MOVE_SET_VEHICLE_REC_ID_ACK = 0x0000, + CMSG_MOVE_SPLINE_DONE = 0x790E, + CMSG_MOVE_TIME_SKIPPED = 0x7A0A, + CMSG_MOVE_TOGGLE_COLLISION_ACK = 0x0000, + CMSG_MOVE_WATER_WALK_ACK = 0x3B00, + CMSG_NAME_QUERY = 0x2224, + CMSG_NEW_SPELL_SLOT = 0x0000, + CMSG_NEXT_CINEMATIC_CAMERA = 0x2014, + CMSG_NPC_TEXT_QUERY = 0x4E24, + CMSG_OBJECT_UPDATE_FAILED = 0x3808, + CMSG_OBJECT_UPDATE_RESCUED = 0x3906, + CMSG_OFFER_PETITION = 0x4817, + CMSG_OPENING_CINEMATIC = 0x0A16, + CMSG_OPEN_ITEM = 0x6A34, + CMSG_OPT_OUT_OF_LOOT = 0x6B16, + CMSG_PAGE_TEXT_QUERY = 0x6614, + CMSG_PARTY_SILENCE = 0x6B26, + CMSG_PARTY_UNSILENCE = 0x4D24, + CMSG_PETITION_BUY = 0x4E05, + CMSG_PETITION_QUERY = 0x4424, + CMSG_PETITION_SHOWLIST = 0x4617, + CMSG_PETITION_SHOW_SIGNATURES = 0x4F15, + CMSG_PETITION_SIGN = 0x0E04, + CMSG_PET_ABANDON = 0x0C24, + CMSG_PET_ACTION = 0x0226, + CMSG_PET_CANCEL_AURA = 0x4B25, + CMSG_PET_CAST_SPELL = 0x6337, + CMSG_PET_LEARN_TALENT = 0x6725, + CMSG_PET_NAME_CACHE = 0x0000, + CMSG_PET_NAME_QUERY = 0x6F24, + CMSG_PET_RENAME = 0x6406, + CMSG_PET_SET_ACTION = 0x6904, + CMSG_PET_SPELL_AUTOCAST = 0x2514, + CMSG_PET_STOP_ATTACK = 0x6C14, + CMSG_PING = 0x444D, + CMSG_PLAYED_TIME = 0x0804, + CMSG_PLAYER_DIFFICULTY_CHANGE = 0x0000, + CMSG_PLAYER_LOGIN = 0x05B1, + CMSG_PLAYER_LOGOUT = 0x0000, + CMSG_PLAYER_VEHICLE_ENTER = 0x2705, + CMSG_PLAY_DANCE = 0x6914, + CMSG_PUSHQUESTTOPARTY = 0x4B14, + CMSG_PVP_LOG_DATA = 0x7308, + CMSG_QUERY_BATTLEFIELD_STATE = 0x7202, + CMSG_QUERY_COMPLETION_NPC_RESPONSE = 0x7302, + CMSG_QUERY_GUILD_MAX_XP = 0x0000, + CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE = 0x1036, + CMSG_QUERY_GUILD_MEMBER_RECIPES = 0x1037, + CMSG_QUERY_GUILD_RECIPES = 0x3033, + CMSG_QUERY_GUILD_REWARDS = 0x3012, + CMSG_QUERY_GUILD_XP = 0x1237, + CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x4D27, + CMSG_QUERY_QUESTS_COMPLETED = 0x2317, + CMSG_QUERY_TIME = 0x0A36, + CMSG_QUESTGIVER_ACCEPT_QUEST = 0x6B37, + CMSG_QUESTGIVER_CANCEL = 0x0000, + CMSG_QUESTGIVER_CHOOSE_REWARD = 0x2125, + CMSG_QUESTGIVER_COMPLETE_QUEST = 0x0114, + CMSG_QUESTGIVER_HELLO = 0x0D17, + CMSG_QUESTGIVER_QUERY_QUEST = 0x2F14, + CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0x0000, + CMSG_QUESTGIVER_REQUEST_REWARD = 0x2534, + CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x6305, + CMSG_QUESTGIVER_STATUS_QUERY = 0x4407, + CMSG_QUESTLOG_REMOVE_QUEST = 0x0D16, + CMSG_QUESTLOG_SWAP_QUEST = 0x0000, + CMSG_QUEST_CONFIRM_ACCEPT = 0x0D15, + CMSG_QUEST_NPC_QUERY = 0x0000, + CMSG_QUEST_POI_QUERY = 0x4037, + CMSG_QUEST_QUERY = 0x0D06, + CMSG_RANDOMIZE_CHAR_NAME = 0x2413, + CMSG_READY_FOR_ACCOUNT_DATA_TIMES = 0x2B16, + CMSG_READ_ITEM = 0x2F16, + CMSG_REALM_SPLIT = 0x2906, + CMSG_RECLAIM_CORPSE = 0x4036, + CMSG_REDIRECTION_AUTH_PROOF = 0x044D, + CMSG_REFORGE_ITEM = 0x331A, + CMSG_REORDER_CHARACTERS = 0x0593, + CMSG_REPAIR_ITEM = 0x2917, + CMSG_REPLACE_ACCOUNT_DATA = 0x0000, + CMSG_REPOP_REQUEST = 0x6235, + CMSG_REPORT_PVP_AFK = 0x6734, + CMSG_REQUEST_ACCOUNT_DATA = 0x6505, + CMSG_REQUEST_CATEGORY_COOLDOWNS = 0x7102, + CMSG_REQUEST_CEMETERY_LIST = 0x720A, + CMSG_REQUEST_GUILD_PARTY_STATE = 0x3900, + CMSG_REQUEST_HONOR_STATS = 0x791E, + CMSG_REQUEST_HOTFIX = 0x2401, + CMSG_REQUEST_INSPECT_RATED_BG_STATS = 0x3010, + CMSG_REQUEST_PARTY_MEMBER_STATS = 0x0C04, + CMSG_REQUEST_PET_INFO = 0x4924, + CMSG_REQUEST_PVP_OPTIONS_ENABLED = 0x24A1, + CMSG_REQUEST_PVP_REWARDS = 0x780C, + CMSG_REQUEST_RAID_INFO = 0x2F26, + CMSG_REQUEST_RATED_BG_INFO = 0x2423, + CMSG_REQUEST_RATED_BG_STATS = 0x05B3, + CMSG_REQUEST_RESEARCH_HISTORY = 0x3306, + CMSG_REQUEST_VEHICLE_EXIT = 0x2B35, + CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x4434, + CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x4C04, + CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x4C14, + CMSG_RESET_FACTION_CHEAT = 0x4469, + CMSG_RESET_INSTANCES = 0x6E14, + CMSG_RESURRECT_RESPONSE = 0x6827, + CMSG_RETURN_TO_GRAVEYARD = 0x301E, + CMSG_ROLE_POLL_BEGIN = 0x0430, + CMSG_SAVE_CUF_PROFILES = 0x730E, + CMSG_SAVE_PLAYER = 0x0000, + CMSG_SEARCH_LFG_JOIN = 0x0000, + CMSG_SEARCH_LFG_LEAVE = 0x0000, + CMSG_SELF_RES = 0x6115, + CMSG_SELL_ITEM = 0x4E15, + CMSG_SEND_MAIL = 0x0523, + CMSG_SEND_SOR_REQUEST_VIA_ADDRESS = 0x0420, + CMSG_SEND_SOR_REQUEST_VIA_BNET_ACCOUNT_ID = 0x0482, + CMSG_SERVERTIME = 0x0000, + CMSG_SETDEATHBINDPOINT = 0x0000, + CMSG_SETSHEATHED = 0x4326, + CMSG_SET_ACTIONBAR_TOGGLES = 0x2506, + CMSG_SET_ACTION_BUTTON = 0x6F06, + CMSG_SET_ACTIVE_MOVER = 0x3314, + CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x4305, + CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0x4435, + CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0x0536, + CMSG_SET_CHANNEL_WATCH = 0x4517, + CMSG_SET_CONTACT_NOTES = 0x6135, + CMSG_SET_CURRENCY_FLAGS = 0x7306, + CMSG_SET_EVERYONE_IS_ASSISTANT = 0x2530, + CMSG_SET_FACTION_ATWAR = 0x0706, + CMSG_SET_FACTION_CHEAT = 0x0000, + CMSG_SET_FACTION_INACTIVE = 0x0E37, + CMSG_SET_GUILD_BANK_TEXT = 0x0000, + CMSG_SET_LFG_COMMENT = 0x0000, + CMSG_SET_PET_SLOT = 0x3A04, + CMSG_SET_PLAYER_DECLINED_NAMES = 0x6316, + CMSG_SET_PREFERED_CEMETERY = 0x311E, + CMSG_SET_PRIMARY_TALENT_TREE = 0x4524, + CMSG_SET_RELATIVE_POSITION = 0x311A, + CMSG_SET_SAVED_INSTANCE_EXTEND = 0x6706, + CMSG_SET_SELECTION = 0x0506, + CMSG_SET_SKILL_CHEAT = 0x0000, + CMSG_SET_TAXI_BENCHMARK_MODE = 0x4314, + CMSG_SET_TITLE = 0x2117, + CMSG_SET_TRADE_CURRENCY = 0x3312, + CMSG_SET_TRADE_GOLD = 0x3008, + CMSG_SET_TRADE_ITEM = 0x7B0C, + CMSG_SET_VEHICLE_REC_ID_ACK = 0x3108, + CMSG_SET_WATCHED_FACTION = 0x2434, + CMSG_SHOWING_CLOAK = 0x4135, + CMSG_SHOWING_HELM = 0x0735, + CMSG_SOCKET_GEMS = 0x2F04, + CMSG_SPELLCLICK = 0x0805, + CMSG_SPIRIT_HEALER_ACTIVATE = 0x2E26, + CMSG_SPLIT_ITEM = 0x0F17, + CMSG_STANDSTATECHANGE = 0x0535, + CMSG_START_QUEST = 0x0000, + CMSG_STOP_DANCE = 0x2907, + CMSG_STORE_LOOT_IN_SLOT = 0x0000, + CMSG_SUBMIT_BUG = 0x2520, + CMSG_SUBMIT_COMPLAIN = 0x2501, + CMSG_SUGGESTION_SUBMIT = 0x2512, + CMSG_SUMMON_RESPONSE = 0x6F27, + CMSG_SUSPEND_TOKEN = 0x046D, + CMSG_SWAP_INV_ITEM = 0x2614, + CMSG_SWAP_ITEM = 0x6326, + CMSG_SYNC_DANCE = 0x0036, + CMSG_TAXICLEARALLNODES = 0x0000, + CMSG_TAXIENABLEALLNODES = 0x0000, + CMSG_TAXINODE_STATUS_QUERY = 0x2F25, + CMSG_TAXIQUERYAVAILABLENODES = 0x6C06, + CMSG_TAXISHOWNODES = 0x0000, + CMSG_TELEPORT_TO_UNIT = 0x4206, + CMSG_TEXT_EMOTE = 0x2E24, + CMSG_TIME_ADJUSTMENT_RESPONSE = 0x3818, + CMSG_TIME_SYNC_RESP = 0x3B0C, + CMSG_TIME_SYNC_RESP_FAILED = 0x710A, + CMSG_TOGGLE_PVP = 0x6815, + CMSG_TOTEM_DESTROYED = 0x4207, + CMSG_TRAINER_BUY_SPELL = 0x4415, + CMSG_TRAINER_LIST = 0x2336, + CMSG_TRANSMOGRIFY_ITEMS = 0x3B0E, + CMSG_TRIGGER_CINEMATIC_CHEAT = 0x0000, + CMSG_TURN_IN_PETITION = 0x0B27, + CMSG_TUTORIAL_CLEAR = 0x6515, + CMSG_TUTORIAL_FLAG = 0x6C26, + CMSG_TUTORIAL_RESET = 0x2726, + CMSG_UNACCEPT_TRADE = 0x391A, + CMSG_UNLEARN_SKILL = 0x6106, + CMSG_UNLEARN_SPECIALIZATION = 0x3210, + CMSG_UNREGISTER_ALL_ADDON_PREFIXES = 0x3D54, + CMSG_UPDATE_ACCOUNT_DATA = 0x4736, + CMSG_UPDATE_MISSILE_TRAJECTORY = 0x781E, + CMSG_UPDATE_PROJECTILE_POSITION = 0x0E24, + CMSG_USED_FOLLOW = 0x7912, + CMSG_USE_ITEM = 0x2C06, + CMSG_VIOLENCE_LEVEL = 0x7816, + CMSG_VOICE_SESSION_ENABLE = 0x2314, + CMSG_VOID_STORAGE_QUERY = 0x790A, + CMSG_VOID_STORAGE_TRANSFER = 0x380E, + CMSG_VOID_STORAGE_UNLOCK = 0x7B14, + CMSG_VOID_SWAP_ITEM = 0x3204, + CMSG_WARDEN_DATA = 0x25A2, + CMSG_WARGAME_ACCEPT = 0x2410, + CMSG_WARGAME_START = 0x05A0, + CMSG_WHO = 0x6C15, + CMSG_WHOIS = 0x6B05, + CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4605, + CMSG_WORLD_TELEPORT = 0x24B2, + CMSG_WRAP_ITEM = 0x4F06, + CMSG_ZONEUPDATE = 0x4F37, + MSG_AUCTION_HELLO = 0x2307, + MSG_BATTLEGROUND_PLAYER_POSITIONS = 0x0000, + MSG_CHANNEL_START = 0x0A15, // SMSG only? + MSG_CHANNEL_UPDATE = 0x2417, // SMSG only? + MSG_CORPSE_QUERY = 0x4336, + MSG_GM_BIND_OTHER = 0x0000, + MSG_GM_SHOWLABEL = 0x0000, + MSG_GM_SUMMON = 0x0000, + MSG_GUILD_BANK_LOG_QUERY = 0x0000, + MSG_GUILD_EVENT_LOG_QUERY = 0x0000, + MSG_INSPECT_ARENA_TEAMS = 0x2704, + MSG_LIST_STABLED_PETS = 0x0834, + MSG_MINIMAP_PING = 0x6635, + MSG_MOVE_CHARM_TELEPORT_CHEAT = 0x7A08, + MSG_MOVE_FALL_LAND = 0x380A, + MSG_MOVE_FEATHER_FALL = 0x0000, + MSG_MOVE_GRAVITY_CHNG = 0x0000, + MSG_MOVE_HEARTBEAT = 0x3914, + MSG_MOVE_HOVER = 0x0000, + MSG_MOVE_JUMP = 0x7A06, + MSG_MOVE_SET_ALL_SPEED_CHEAT = 0x0000, + MSG_MOVE_SET_COLLISION_HEIGHT = 0x0000, + MSG_MOVE_SET_FACING = 0x7914, + MSG_MOVE_SET_FLIGHT_SPEED_CHEAT = 0x0000, + MSG_MOVE_SET_PITCH = 0x7312, + MSG_MOVE_SET_RAW_POSITION_ACK = 0x0000, + MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT = 0x0000, + MSG_MOVE_SET_RUN_MODE = 0x791A, + MSG_MOVE_SET_RUN_SPEED_CHEAT = 0x0000, + MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT = 0x0000, + MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0x0000, + MSG_MOVE_SET_TURN_RATE_CHEAT = 0x0000, + MSG_MOVE_SET_WALK_MODE = 0x7002, + MSG_MOVE_SET_WALK_SPEED_CHEAT = 0x0000, + MSG_MOVE_START_ASCEND = 0x390A, + MSG_MOVE_START_BACKWARD = 0x330A, + MSG_MOVE_START_DESCEND = 0x3800, + MSG_MOVE_START_FORWARD = 0x7814, + MSG_MOVE_START_PITCH_DOWN = 0x3908, + MSG_MOVE_START_PITCH_UP = 0x3304, + MSG_MOVE_START_STRAFE_LEFT = 0x3A16, + MSG_MOVE_START_STRAFE_RIGHT = 0x3A02, + MSG_MOVE_START_SWIM = 0x3206, + MSG_MOVE_START_TURN_LEFT = 0x700C, + MSG_MOVE_START_TURN_RIGHT = 0x7000, + MSG_MOVE_STOP = 0x320A, + MSG_MOVE_STOP_ASCEND = 0x7B00, + MSG_MOVE_STOP_PITCH = 0x7216, + MSG_MOVE_STOP_STRAFE = 0x3002, + MSG_MOVE_STOP_SWIM = 0x3802, + MSG_MOVE_STOP_TURN = 0x331E, + MSG_MOVE_TELEPORT = 0x55A0, + MSG_MOVE_TELEPORT_ACK = 0x390C, + MSG_MOVE_TELEPORT_CHEAT = 0x3A10, + MSG_MOVE_TIME_SKIPPED = 0x19B3, + MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0x7B04, + MSG_MOVE_TOGGLE_FALL_LOGGING = 0x0000, + MSG_MOVE_TOGGLE_LOGGING = 0x0000, + MSG_MOVE_UNROOT = 0x7DB4, + MSG_MOVE_UPDATE_CAN_FLY = 0x0000, + MSG_MOVE_UPDATE_FLIGHT_SPEED = 0x30B1, + MSG_MOVE_UPDATE_MOUSE = 0x0000, + MSG_MOVE_UPDATE_RUN_SPEED = 0x14A6, + MSG_MOVE_UPDATE_TELEPORT = 0x50B2, + MSG_MOVE_WATER_WALK = 0x0000, + MSG_MOVE_WORLDPORT_ACK = 0x2411, + MSG_NOTIFY_PARTY_SQUELCH = 0x4D06, + MSG_PARTY_ASSIGNMENT = 0x0424, + MSG_PETITION_DECLINE = 0x4905, + MSG_PETITION_RENAME = 0x4005, + MSG_PVP_LOG_DATA = 0x0000, + MSG_QUERY_GUILD_BANK_TEXT = 0x0000, + MSG_QUERY_NEXT_MAIL_TIME = 0x0F04, + MSG_QUEST_PUSH_RESULT = 0x4515, + MSG_RAID_READY_CHECK = 0x2304, + MSG_RAID_READY_CHECK_CONFIRM = 0x4F05, + MSG_RAID_READY_CHECK_FINISHED = 0x2E15, + MSG_RAID_TARGET_UPDATE = 0x2C36, + MSG_RANDOM_ROLL = 0x0905, + MSG_SAVE_GUILD_EMBLEM = 0x2404, + MSG_SET_DUNGEON_DIFFICULTY = 0x4925, + MSG_SET_RAID_DIFFICULTY = 0x0614, + MSG_START_MOVE_FORWARD = 0x0000, + MSG_TABARDVENDOR_ACTIVATE = 0x6926, + MSG_TALENT_WIPE_CONFIRM = 0x0107, + MSG_VERIFY_CONNECTIVITY = 0x4F57, + SMSG_ACCOUNT_DATA_TIMES = 0x4B05, + SMSG_ACCOUNT_INFO_RESPONSE = 0x10A7, + SMSG_ACCOUNT_RESTRICTED_WARNING = 0x51A7, + SMSG_ACHIEVEMENT_DELETED = 0x6A16, + SMSG_ACHIEVEMENT_EARNED = 0x4405, + SMSG_ACTION_BUTTONS = 0x38B5, + SMSG_ACTIVATETAXIREPLY = 0x6A37, + SMSG_ADDON_INFO = 0x2C14, + SMSG_ADD_RUNE_POWER = 0x6915, + SMSG_AI_REACTION = 0x0637, + SMSG_ALL_ACHIEVEMENT_DATA = 0x58B1, + SMSG_AREA_SPIRIT_HEALER_TIME = 0x0734, + SMSG_AREA_TRIGGER_MESSAGE = 0x4505, + SMSG_AREA_TRIGGER_MOVEMENT_UPDATE = 0x3DB1, + SMSG_ARENA_ERROR = 0x2D17, + SMSG_ARENA_OPPONENT_UPDATE = 0x2637, + SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0x6E34, + SMSG_ARENA_TEAM_COMMAND_RESULT = 0x39B3, + SMSG_ARENA_TEAM_EVENT = 0x0617, + SMSG_ARENA_TEAM_INVITE = 0x0F36, + SMSG_ARENA_TEAM_QUERY_RESPONSE = 0x6336, + SMSG_ARENA_TEAM_ROSTER = 0x2717, + SMSG_ARENA_TEAM_STATS = 0x4425, + SMSG_ATTACKERSTATEUPDATE = 0x0B25, + SMSG_ATTACKSTART = 0x2D15, + SMSG_ATTACKSTOP = 0x0934, + SMSG_ATTACKSWING_BADFACING = 0x0B36, + SMSG_ATTACKSWING_CANT_ATTACK = 0x0016, + SMSG_ATTACKSWING_DEADTARGET = 0x2B26, + SMSG_ATTACKSWING_NOTINRANGE = 0x6C07, + SMSG_AUCTION_BIDDER_LIST_RESULT = 0x6637, + SMSG_AUCTION_BIDDER_NOTIFICATION = 0x4E27, + SMSG_AUCTION_COMMAND_RESULT = 0x4C25, + SMSG_AUCTION_LIST_PENDING_SALES = 0x6A27, + SMSG_AUCTION_LIST_RESULT = 0x0027, + SMSG_AUCTION_OWNER_LIST_RESULT = 0x6C34, + SMSG_AUCTION_OWNER_NOTIFICATION = 0x4116, + SMSG_AUCTION_REMOVED_NOTIFICATION = 0x2334, + SMSG_AURACASTLOG = 0x0000, + SMSG_AURA_POINTS_DEPLETED = 0x7CB7, + SMSG_AURA_UPDATE = 0x4707, + SMSG_AURA_UPDATE_ALL = 0x6916, + SMSG_AUTH_CHALLENGE = 0x4542, + SMSG_AUTH_RESPONSE = 0x5DB6, + SMSG_AVAILABLE_VOICE_CHANNEL = 0x2E16, + SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0x5DA7, + SMSG_BARBER_SHOP_RESULT = 0x6125, + SMSG_BATTLEFIELD_LIST = 0x71B5, + SMSG_BATTLEFIELD_MGR_EJECTED = 0x7DB7, + SMSG_BATTLEFIELD_MGR_EJECT_PENDING = 0x34A2, + SMSG_BATTLEFIELD_MGR_ENTERED = 0x5CA0, + SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0x34B3, + SMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x51B1, + SMSG_BATTLEFIELD_MGR_QUEUE_INVITE = 0x15A6, + SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0x79B6, + SMSG_BATTLEFIELD_MGR_STATE_CHANGE = 0x35B4, + SMSG_BATTLEFIELD_PLAYER_POSITIONS = 0x58B4, + SMSG_BATTLEFIELD_PORT_DENIED = 0x35A3, + SMSG_BATTLEFIELD_RATED_INFO = 0x54A3, + SMSG_BATTLEFIELD_STATUS = 0x7DA1, + SMSG_BATTLEFIELD_STATUS1 = 0x0000, + SMSG_BATTLEFIELD_STATUS2 = 0x74A4, + SMSG_BATTLEFIELD_STATUS3 = 0x59A0, + SMSG_BATTLEFIELD_STATUS4 = 0x75A2, + SMSG_BATTLEFIELD_STATUS_FAILED = 0x71A7, + SMSG_BATTLEGROUND_INFO_THROTTLED = 0x34B2, + SMSG_BATTLEGROUND_PLAYER_JOINED = 0x50B0, + SMSG_BATTLEGROUND_PLAYER_LEFT = 0x59A6, + SMSG_BATTLEGROUND_PLAYER_POSITIONS = 0x0000, + SMSG_BINDER_CONFIRM = 0x2835, + SMSG_BINDPOINTUPDATE = 0x0527, + SMSG_BINDZONEREPLY = 0x0000, + SMSG_BREAK_TARGET = 0x0105, + SMSG_BUY_BANK_SLOT_RESULT = 0x0000, + SMSG_BUY_FAILED = 0x6435, + SMSG_BUY_ITEM = 0x0F26, + SMSG_CALENDAR_ACTION_PENDING = 0x0000, + SMSG_CALENDAR_ARENA_TEAM = 0x0615, + SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x2106, + SMSG_CALENDAR_COMMAND_RESULT = 0x6F36, + SMSG_CALENDAR_EVENT_INVITE = 0x4E16, + SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x2A05, + SMSG_CALENDAR_EVENT_INVITE_NOTES = 0x0E17, + SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT = 0x2535, + SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x0725, + SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x2617, + SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x6625, + SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x6B06, + SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x6D35, + SMSG_CALENDAR_EVENT_STATUS = 0x2A27, + SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x0907, + SMSG_CALENDAR_FILTER_GUILD = 0x4A26, + SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x2305, + SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x2E25, + SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0x4636, + SMSG_CALENDAR_SEND_CALENDAR = 0x6805, + SMSG_CALENDAR_SEND_EVENT = 0x0C35, + SMSG_CALENDAR_SEND_NUM_PENDING = 0x0C17, + SMSG_CALENDAR_UPDATE_INVITE_LIST = 0x0000, + SMSG_CAMERA_SHAKE = 0x4214, + SMSG_CANCEL_AUTO_REPEAT = 0x6436, + SMSG_CANCEL_COMBAT = 0x4F04, + SMSG_CAST_FAILED = 0x4D16, + SMSG_CHANNEL_LIST = 0x2214, + SMSG_CHANNEL_MEMBER_COUNT = 0x6414, + SMSG_CHANNEL_NOTIFY = 0x0825, + SMSG_CHARACTER_LOGIN_FAILED = 0x4417, + SMSG_CHAR_CREATE = 0x2D05, + SMSG_CHAR_CUSTOMIZE = 0x4F16, + SMSG_CHAR_DELETE = 0x0304, + SMSG_CHAR_ENUM = 0x10B0, + SMSG_CHAR_FACTION_CHANGE = 0x4C06, + SMSG_CHAR_RENAME = 0x2024, + SMSG_CHAT_IGNORED_ACCOUNT_MUTED = 0x15A4, + SMSG_CHAT_NOT_IN_PARTY = 0x6A14, + SMSG_CHAT_PLAYER_AMBIGUOUS = 0x2F34, + SMSG_CHAT_PLAYER_NOT_FOUND = 0x2526, + SMSG_CHAT_RESTRICTED = 0x6536, + SMSG_CHAT_SERVER_DISCONNECTED = 0x6D34, + SMSG_CHAT_SERVER_RECONNECTED = 0x6905, + SMSG_CHAT_WRONG_FACTION = 0x6724, + SMSG_CHECK_FOR_BOTS = 0x0000, + SMSG_CLEAR_BOSS_EMOTES = 0x19A3, + SMSG_CLEAR_COOLDOWN = 0x0000, + SMSG_CLEAR_COOLDOWNS = 0x59B4, + SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x2A04, + SMSG_CLEAR_TARGET = 0x4B26, + SMSG_CLIENTCACHE_VERSION = 0x2734, + SMSG_CLIENT_CONTROL_UPDATE = 0x2837, + SMSG_COMBAT_EVENT_FAILED = 0x2B07, + SMSG_COMBAT_LOG_MULTIPLE = 0x0000, + SMSG_COMMENTATOR_MAP_INFO = 0x0327, + SMSG_COMMENTATOR_PARTY_INFO = 0x38B0, + SMSG_COMMENTATOR_PLAYER_INFO = 0x2F36, + SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1 = 0x2126, + SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0x6814, + SMSG_COMMENTATOR_STATE_CHANGED = 0x0737, + SMSG_COMPLAIN_RESULT = 0x6D24, + SMSG_COMPLETION_NPC_RESPONCE = 0x0000, + SMSG_COMPLETION_NPC_RESPONSE = 0x75A1, + SMSG_COMPRESSED_ACHIEVEMENT_DATA = 0x0000, + SMSG_COMPRESSED_CHAR_ENUM = 0x0000, + SMSG_COMPRESSED_GUILD_ROSTER = 0x0000, + SMSG_COMPRESSED_MOVES = 0x0517, + SMSG_COMPRESSED_UPDATE_OBJECT = 0x0000, + SMSG_COMSAT_CONNECT_FAIL = 0x6317, + SMSG_COMSAT_DISCONNECT = 0x0316, + SMSG_COMSAT_RECONNECT_TRY = 0x4D35, + SMSG_CONTACT_LIST = 0x6017, + SMSG_CONVERT_RUNE = 0x4F14, + SMSG_COOLDOWN_CHEAT = 0x0627, + SMSG_COOLDOWN_EVENT = 0x4F26, + SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x0E35, + SMSG_CORPSE_NOT_IN_INSTANCE = 0x2A14, + SMSG_CORPSE_RECLAIM_DELAY = 0x0D34, + SMSG_CREATURE_QUERY_RESPONSE = 0x6024, + SMSG_CRITERIA_DELETED = 0x2915, + SMSG_CRITERIA_UPDATE = 0x6E37, + SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x2036, + SMSG_CURRENCY_LOOT_REMOVED = 0x1DB4, + SMSG_CURRENCY_LOOT_RESTORED = 0x30A0, + SMSG_CUSTOM_LOAD_SCREEN = 0x1DB6, + SMSG_DAMAGE_CALC_LOG = 0x2436, + SMSG_DAMAGE_DONE_OBSOLETE = 0x0000, + SMSG_DANCE_QUERY_RESPONSE = 0x2F06, + SMSG_DB_REPLY = 0x38A4, + SMSG_DEATH_RELEASE_LOC = 0x2F07, + SMSG_DEBUG_RUNE_REGEN = 0x31B3, + SMSG_DEFENSE_MESSAGE = 0x0314, + SMSG_DESTROY_OBJECT = 0x4724, + SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x4825, + SMSG_DIFFERENT_INSTANCE_FROM_PARTY = 0x15B1, + SMSG_DISENCHANT_CREDIT = 0x55A2, + SMSG_DISMOUNT = 0x2135, + SMSG_DISMOUNTRESULT = 0x0D25, + SMSG_DISPEL_FAILED = 0x0307, + SMSG_DISPLAY_GAME_ERROR = 0x31A6, + SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR = 0x38A2, + SMSG_DROP_NEW_CONNECTION = 0x4D40, + SMSG_DUEL_COMPLETE = 0x2527, + SMSG_DUEL_COUNTDOWN = 0x4836, + SMSG_DUEL_INBOUNDS = 0x0A27, + SMSG_DUEL_OUTOFBOUNDS = 0x0C26, + SMSG_DUEL_REQUESTED = 0x4504, + SMSG_DUEL_WINNER = 0x2D36, + SMSG_DUMP_RIDE_TICKETS_RESPONSE = 0x11A3, + SMSG_DURABILITY_DAMAGE_DEATH = 0x4C27, + SMSG_ECHO_PARTY_SQUELCH = 0x0814, + SMSG_EMOTE = 0x0A34, + SMSG_ENABLE_BARBER_SHOP = 0x2D16, + SMSG_ENCHANTMENTLOG = 0x6035, + SMSG_ENVIRONMENTALDAMAGELOG = 0x6C05, + SMSG_EQUIPMENT_SET_LIST = 0x2E04, + SMSG_EQUIPMENT_SET_SAVED = 0x2216, + SMSG_EQUIPMENT_SET_USE_RESULT = 0x2424, + SMSG_EXPECTED_SPAM_RECORDS = 0x4D36, + SMSG_EXPLORATION_EXPERIENCE = 0x6716, + SMSG_FAILED_PLAYER_CONDITION = 0x19A4, + SMSG_FEATURE_SYSTEM_STATUS = 0x3DB7, + SMSG_FEIGN_DEATH_RESISTED = 0x0D05, + SMSG_FISH_ESCAPED = 0x2205, + SMSG_FISH_NOT_HOOKED = 0x0A17, + SMSG_FLIGHT_SPLINE_SYNC = 0x0924, + SMSG_FLOOD_DETECTED = 0x0542, + SMSG_FORCEACTIONSHOW = 0x0000, + SMSG_FORCED_DEATH_UPDATE = 0x2606, + SMSG_FORCE_DISPLAY_UPDATE = 0x0000, + SMSG_FORCE_SEND_QUEUED_PACKETS = 0x0140, + SMSG_FORCE_SET_VEHICLE_REC_ID = 0x70A1, + SMSG_FORGE_MASTER_SET = 0x70B7, + SMSG_FRIEND_STATUS = 0x0717, + SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x4936, + SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x6735, + SMSG_GAMEOBJECT_PAGETEXT = 0x2925, + SMSG_GAMEOBJECT_QUERY_RESPONSE = 0x0915, + SMSG_GAMEOBJECT_RESET_STATE = 0x2A16, + SMSG_GAMESPEED_SET = 0x4E34, + SMSG_GAMETIME_SET = 0x0014, + SMSG_GAMETIME_UPDATE = 0x4127, + SMSG_GAME_EVENT_DEBUG_LOG = 0x31A7, + SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT = 0x14A3, + SMSG_GMRESPONSE_DB_ERROR = 0x0006, + SMSG_GMRESPONSE_RECEIVED = 0x2E34, + SMSG_GMRESPONSE_STATUS_UPDATE = 0x0A04, + SMSG_GMTICKET_CREATE = 0x2107, + SMSG_GMTICKET_DELETETICKET = 0x6D17, + SMSG_GMTICKET_GETTICKET = 0x2C15, + SMSG_GMTICKET_SYSTEMSTATUS = 0x0D35, + SMSG_GMTICKET_UPDATETEXT = 0x6535, + SMSG_GM_MESSAGECHAT = 0x6434, + SMSG_GM_PLAYER_INFO = 0x4A15, + SMSG_GM_TICKET_STATUS_UPDATE = 0x2C25, + SMSG_GODMODE = 0x0405, + SMSG_GOSSIP_COMPLETE = 0x0806, + SMSG_GOSSIP_MESSAGE = 0x2035, + SMSG_GOSSIP_POI = 0x4316, + SMSG_GROUPACTION_THROTTLED = 0x6524, + SMSG_GROUP_CANCEL = 0x4D25, + SMSG_GROUP_DECLINE = 0x6835, + SMSG_GROUP_DESTROYED = 0x2207, + SMSG_GROUP_INVITE = 0x31B2, + SMSG_GROUP_JOINED_BATTLEGROUND = 0x35A1, + SMSG_GROUP_LIST = 0x4C24, + SMSG_GROUP_SET_LEADER = 0x0526, + SMSG_GROUP_SET_ROLE = 0x39A6, + SMSG_GROUP_UNINVITE = 0x0A07, + SMSG_GUILD_ACHIEVEMENT_DATA = 0x54B7, + SMSG_GUILD_ACHIEVEMENT_DELETED = 0x35A0, + SMSG_GUILD_ACHIEVEMENT_EARNED = 0x50B5, + SMSG_GUILD_ACHIEVEMENT_MEMBERS = 0x38A5, + SMSG_GUILD_BANK_LIST = 0x78A5, + SMSG_GUILD_BANK_LOG_QUERY_RESULTS = 0x30B2, + SMSG_GUILD_BANK_MONEY_WITHDRAWN = 0x0000, + SMSG_GUILD_BANK_QUERY_TEXT_RESULTS = 0x75A3, + SMSG_GUILD_BANK_REM_MONEY_WITHDRAW_QUERY = 0x5DB4, + SMSG_GUILD_CANCEL = 0x0000, + SMSG_GUILD_CHALLENGE_COMPLETED = 0x39A3, + SMSG_GUILD_CHALLENGE_UPDATED = 0x18B1, + SMSG_GUILD_CHANGE_NAME_RESULT = 0x3CB1, + SMSG_GUILD_COMMAND_RESULT = 0x7DB3, + SMSG_GUILD_COMMAND_RESULT_2 = 0x2707, + SMSG_GUILD_CRITERIA_DATA = 0x14B4, + SMSG_GUILD_CRITERIA_DELETED = 0x55B1, + SMSG_GUILD_DECLINE = 0x2C07, + SMSG_GUILD_EVENT = 0x0705, + SMSG_GUILD_EVENT_LOG_QUERY = 0x10B2, + SMSG_GUILD_FLAGGED_FOR_RENAME = 0x30B6, + SMSG_GUILD_INFO = 0x0000, + SMSG_GUILD_INVITE = 0x14A2, + SMSG_GUILD_INVITE_CANCEL = 0x0606, + SMSG_GUILD_KNOWN_RECIPES = 0x0000, + SMSG_GUILD_MAX_DAILY_XP = 0x79B5, + SMSG_GUILD_MEMBERS_FOR_RECIPE = 0x1CB7, + SMSG_GUILD_MEMBER_DAILY_RESET = 0x10A5, + SMSG_GUILD_MEMBER_RECIPES = 0x1CB0, + SMSG_GUILD_MEMBER_UPDATE_NOTE = 0x7CA0, + SMSG_GUILD_MOVE_COMPLETE = 0x11B2, + SMSG_GUILD_MOVE_STARTING = 0x70A4, + SMSG_GUILD_NEWS_DELETED = 0x74A7, + SMSG_GUILD_NEWS_UPDATE = 0x35A7, + SMSG_GUILD_PARTY_STATE_RESPONSE = 0x50A6, + SMSG_GUILD_PERMISSIONS_QUERY_RESULTS = 0x34A3, + SMSG_GUILD_QUERY_RESPONSE = 0x0E06, + SMSG_GUILD_RANK = 0x30B4, + SMSG_GUILD_RANKS_UPDATE = 0x5DA0, + SMSG_GUILD_RECIPES = 0x10B3, + SMSG_GUILD_RENAMED = 0x74A6, + SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0x74B0, + SMSG_GUILD_REPUTATION_WEEKLY_CAP = 0x30B7, + SMSG_GUILD_RESET = 0x1CB5, + SMSG_GUILD_REWARDS_LIST = 0x1DB0, + SMSG_GUILD_ROSTER = 0x3DA3, + SMSG_GUILD_SET_NOTE = 0x0000, + SMSG_GUILD_TRADESKILL_UPDATE = 0x0000, + SMSG_GUILD_UPDATE_ROSTER = 0x18B0, + SMSG_GUILD_XP = 0x3DB0, + SMSG_GUILD_XP_GAIN = 0x14A1, + SMSG_GUILD_XP_UPDATE = 0x0000, + SMSG_HEALTH_UPDATE = 0x4734, + SMSG_HIGHEST_THREAT_UPDATE = 0x4104, + SMSG_HOTFIX_INFO = 0x19B5, + SMSG_HOTFIX_NOTIFY = 0x55A7, + SMSG_INITIALIZE_FACTIONS = 0x4634, + SMSG_INITIAL_SPELLS = 0x0104, + SMSG_INIT_CURRENCY = 0x15A5, + SMSG_INIT_WORLD_STATES = 0x4C15, + SMSG_INSPECT = 0x0000, + SMSG_INSPECT_HONOR_STATS = 0x79A5, + SMSG_INSPECT_RATED_BG_STATS = 0x19A5, + SMSG_INSPECT_RESULTS_UPDATE = 0x0C14, + SMSG_INSPECT_TALENT = 0x4014, + SMSG_INSTANCE_DIFFICULTY = 0x0000, + SMSG_INSTANCE_LOCK_WARNING_QUERY = 0x4F17, + SMSG_INSTANCE_RESET = 0x6F05, + SMSG_INSTANCE_RESET_FAILED = 0x4725, + SMSG_INSTANCE_SAVE_CREATED = 0x0124, + SMSG_INVALIDATE_DANCE = 0x0E27, + SMSG_INVALIDATE_PLAYER = 0x6325, + SMSG_INVALID_PROMOTION_CODE = 0x6F25, + SMSG_INVENTORY_CHANGE_FAILURE = 0x2236, + SMSG_ITEM_ADD_PASSIVE = 0x7CB4, + SMSG_ITEM_COOLDOWN = 0x4D14, + SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x0F27, + SMSG_ITEM_EXPIRE_PURCHASE_REFUND = 0x1CA0, + SMSG_ITEM_PUSH_RESULT = 0x0E15, + SMSG_ITEM_REFUND_INFO_RESPONSE = 0x15A3, + SMSG_ITEM_REFUND_RESULT = 0x5DB1, + SMSG_ITEM_REMOVE_PASSIVE = 0x39A1, + SMSG_ITEM_SEND_PASSIVE = 0x70B1, + SMSG_ITEM_TEXT_QUERY_RESPONSE = 0x2725, + SMSG_ITEM_TIME_UPDATE = 0x2407, + SMSG_JOINED_BATTLEGROUND_QUEUE = 0x0000, + SMSG_KICK_REASON = 0x0000, + SMSG_LEARNED_DANCE_MOVES = 0x0E05, + SMSG_LEARNED_SPELL = 0x58A2, + SMSG_LEVELUP_INFO = 0x0435, + SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x0F05, + SMSG_LFG_DISABLED = 0x0815, + SMSG_LFG_JOIN_RESULT = 0x38B6, + SMSG_LFG_OFFER_CONTINUE = 0x6B27, + SMSG_LFG_OPEN_FROM_GOSSIP = 0x0000, + SMSG_LFG_PARTY_INFO = 0x2325, + SMSG_LFG_PLAYER_INFO = 0x4B36, + SMSG_LFG_PLAYER_REWARD = 0x6834, + SMSG_LFG_PROPOSAL_UPDATE = 0x7DA6, + SMSG_LFG_QUEUE_STATUS = 0x78B4, + SMSG_LFG_ROLE_CHECK_UPDATE = 0x0336, + SMSG_LFG_ROLE_CHOSEN = 0x6A26, + SMSG_LFG_SLOT_INVALID = 0x54B5, + SMSG_LFG_TELEPORT_DENIED = 0x0E14, + SMSG_LFG_UPDATE_LIST = 0x0000, + SMSG_LFG_UPDATE_PARTY = 0x0000, + SMSG_LFG_UPDATE_PLAYER = 0x0000, + SMSG_LFG_UPDATE_SEARCH = 0x54A1, + SMSG_LFG_UPDATE_STATUS = 0x31A4, + SMSG_LFG_UPDATE_STATUS_NONE = 0x7CA1, + SMSG_LF_GUILD_APPLICANT_LIST_UPDATED = 0x10A4, + SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED = 0x71A5, + SMSG_LF_GUILD_BROWSE_UPDATED = 0x1DA3, + SMSG_LF_GUILD_COMMAND_RESULT = 0x54A6, + SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED = 0x1CA5, + SMSG_LF_GUILD_POST_UPDATED = 0x35B7, + SMSG_LF_GUILD_RECRUIT_LIST_UPDATED = 0x1CB2, + SMSG_LF_GUILD_SEARCH_RESULT = 0x0000, + SMSG_LIST_INVENTORY = 0x7CB0, + SMSG_LOAD_CUF_PROFILES = 0x50B1, + SMSG_LOGIN_SETTIMESPEED = 0x4D15, + SMSG_LOGIN_VERIFY_WORLD = 0x2005, + SMSG_LOGOUT_CANCEL_ACK = 0x6514, + SMSG_LOGOUT_COMPLETE = 0x2137, + SMSG_LOGOUT_RESPONSE = 0x0524, + SMSG_LOG_XPGAIN = 0x4514, + SMSG_LOOT_ALL_PASSED = 0x6237, + SMSG_LOOT_CLEAR_MONEY = 0x2B37, + SMSG_LOOT_CONTENTS = 0x11B1, + SMSG_LOOT_ITEM_NOTIFY = 0x6D15, + SMSG_LOOT_LIST = 0x6807, + SMSG_LOOT_MASTER_LIST = 0x0325, + SMSG_LOOT_MONEY_NOTIFY = 0x2836, + SMSG_LOOT_RELEASE_RESPONSE = 0x6D25, + SMSG_LOOT_REMOVED = 0x6817, + SMSG_LOOT_RESPONSE = 0x4C16, + SMSG_LOOT_ROLL = 0x6507, + SMSG_LOOT_ROLL_WON = 0x6617, + SMSG_LOOT_SLOT_CHANGED = 0x2935, + SMSG_LOOT_START_ROLL = 0x2227, + SMSG_MAIL_LIST_RESULT = 0x4217, + SMSG_MAP_OBJ_EVENTS = 0x54B2, + SMSG_MEETINGSTONE_COMPLETE = 0x2524, + SMSG_MEETINGSTONE_IN_PROGRESS = 0x2D35, + SMSG_MEETINGSTONE_MEMBER_ADDED = 0x0000, + SMSG_MEETINGSTONE_SETQUEUE = 0x0000, + SMSG_MESSAGECHAT = 0x2026, + SMSG_MESSAGE_BOX = 0x30A1, + SMSG_MINIGAME_SETUP = 0x6727, + SMSG_MINIGAME_STATE = 0x2E17, + SMSG_MIRRORIMAGE_DATA = 0x2634, + SMSG_MISSILE_CANCEL = 0x3DB4, + SMSG_MODIFY_COOLDOWN = 0x6016, + SMSG_MONEY_NOTIFY = 0x55B6, + SMSG_MONSTER_MOVE = 0x6E17, + SMSG_MONSTER_MOVE_TRANSPORT = 0x2004, + SMSG_MOTD = 0x0A35, + SMSG_MOUNTRESULT = 0x2225, + SMSG_MOUNTSPECIAL_ANIM = 0x0217, + SMSG_MOVE_COLLISION_DISABLE = 0x31B0, + SMSG_MOVE_COLLISION_ENABLE = 0x11A7, + SMSG_MOVE_DISABLE_COLLISION = 0x0000, + SMSG_MOVE_DISABLE_GRAVITY = 0x0000, + SMSG_MOVE_ENABLE_COLLISION = 0x0000, + SMSG_MOVE_ENABLE_GRAVITY = 0x0000, + SMSG_MOVE_FEATHER_FALL = 0x79B0, + SMSG_MOVE_GRAVITY_DISABLE = 0x75B2, + SMSG_MOVE_GRAVITY_ENABLE = 0x30B3, + SMSG_MOVE_KNOCK_BACK = 0x5CB4, + SMSG_MOVE_LAND_WALK = 0x34B7, + SMSG_MOVE_NORMAL_FALL = 0x51B6, + SMSG_MOVE_ROOT = 0x7DA0, + SMSG_MOVE_SET_ACTIVE_MOVER = 0x11B3, + SMSG_MOVE_SET_CAN_FLY = 0x3DA1, + SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x59A2, + SMSG_MOVE_SET_COLLISION_HEIGHT = 0x11B0, + SMSG_MOVE_SET_COMPOUND_STATE = 0x75A0, + SMSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x30A2, + SMSG_MOVE_SET_FLIGHT_SPEED = 0x71A6, + SMSG_MOVE_SET_HOVER = 0x5CB3, + SMSG_MOVE_SET_PITCH_RATE = 0x75B0, + SMSG_MOVE_SET_RUN_BACK_SPEED = 0x71B1, + SMSG_MOVE_SET_RUN_SPEED = 0x3DB5, + SMSG_MOVE_SET_SWIM_BACK_SPEED = 0x5CA6, + SMSG_MOVE_SET_SWIM_SPEED = 0x15A7, + SMSG_MOVE_SET_TURN_RATE = 0x30A5, + SMSG_MOVE_SET_VEHICLE_REC_ID = 0x0000, + SMSG_MOVE_SET_WALK_IN_AIR = 0x0000, + SMSG_MOVE_SET_WALK_SPEED = 0x1DA4, + SMSG_MOVE_UNROOT = 0x7DB4, + SMSG_MOVE_UNSET_CAN_FLY = 0x15A2, + SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x7DB2, + SMSG_MOVE_UNSET_HOVER = 0x51B3, + SMSG_MOVE_UNSET_WALK_IN_AIR = 0x0000, + SMSG_MOVE_UPDATE_COLLISION_HEIGHT = 0x59A3, + SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED = 0x74A0, + SMSG_MOVE_UPDATE_KNOCK_BACK = 0x3DB2, + SMSG_MOVE_UPDATE_PITCH_RATE = 0x1DB5, + SMSG_MOVE_UPDATE_RUN_BACK_SPEED = 0x3DA6, + SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0x30B5, + SMSG_MOVE_UPDATE_SWIM_SPEED = 0x59B5, + SMSG_MOVE_UPDATE_TELEPORT = 0x0000, + SMSG_MOVE_UPDATE_TURN_RATE = 0x5DA1, + SMSG_MOVE_UPDATE_WALK_SPEED = 0x54A2, + SMSG_MOVE_WATER_WALK = 0x75B1, + SMSG_MULTIPLE_PACKETS = 0x6736, + SMSG_NAME_QUERY_RESPONSE = 0x6E04, + SMSG_NEW_TAXI_PATH = 0x4B35, + SMSG_NEW_WORLD = 0x79B1, + SMSG_NEW_WORLD_ABORT = 0x14B7, + SMSG_NOTIFICATION = 0x14A0, + SMSG_NOTIFY_DANCE = 0x4904, + SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x6204, + SMSG_NPC_TEXT_UPDATE = 0x4436, + SMSG_NPC_WONT_TALK = 0x0000, + SMSG_OFFER_PETITION_ERROR = 0x2716, + SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x4D34, + SMSG_OPEN_CONTAINER = 0x4714, + SMSG_OPEN_LFG_DUNGEON_FINDER = 0x2C37, + SMSG_OVERRIDE_LIGHT = 0x4225, + SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x2B14, + SMSG_PARTYKILLLOG = 0x4937, + SMSG_PARTY_COMMAND_RESULT = 0x6E07, + SMSG_PARTY_MEMBER_STATS = 0x2104, + SMSG_PARTY_MEMBER_STATS_FULL = 0x0215, + SMSG_PAUSE_MIRROR_TIMER = 0x4015, + SMSG_PERIODICAURALOG = 0x0416, + SMSG_PETGODMODE = 0x2E36, + SMSG_PETITION_ALREADY_SIGNED = 0x5DA3, + SMSG_PETITION_QUERY_RESPONSE = 0x4B37, + SMSG_PETITION_SHOWLIST = 0x6405, + SMSG_PETITION_SHOW_SIGNATURES = 0x0716, + SMSG_PETITION_SIGN_RESULTS = 0x6217, + SMSG_PET_ACTION_FEEDBACK = 0x0807, + SMSG_PET_ACTION_SOUND = 0x4324, + SMSG_PET_ADDED = 0x3CA5, + SMSG_PET_BROKEN = 0x2E27, + SMSG_PET_CAST_FAILED = 0x2B15, + SMSG_PET_DISMISS_SOUND = 0x2B05, + SMSG_PET_GUIDS = 0x2D26, + SMSG_PET_LEARNED_SPELL = 0x0507, + SMSG_PET_MODE = 0x2235, + SMSG_PET_NAME_INVALID = 0x6007, + SMSG_PET_NAME_QUERY_RESPONSE = 0x4C37, + SMSG_PET_REMOVED_SPELL = 0x6A04, + SMSG_PET_RENAMEABLE = 0x2B27, + SMSG_PET_SLOT_UPDATED = 0x51A3, + SMSG_PET_SPELLS = 0x4114, + SMSG_PET_TAME_FAILURE = 0x6B24, + SMSG_PET_UPDATE_COMBO_POINTS = 0x4325, + SMSG_PLAYED_TIME = 0x6037, + SMSG_PLAYERBINDERROR = 0x6A24, + SMSG_PLAYERBOUND = 0x2516, + SMSG_PLAYER_DIFFICULTY_CHANGE = 0x2217, + SMSG_PLAYER_MOVE = 0x79A2, + SMSG_PLAYER_SKINNED = 0x0116, + SMSG_PLAYER_UNK_DEAD_ALIVE = 0x0000, + SMSG_PLAYER_VEHICLE_DATA = 0x4115, + SMSG_PLAY_DANCE = 0x4704, + SMSG_PLAY_MUSIC = 0x4B06, + SMSG_PLAY_OBJECT_SOUND = 0x2635, + SMSG_PLAY_SOUND = 0x2134, + SMSG_PLAY_SPELL_IMPACT = 0x0000, + SMSG_PLAY_SPELL_VISUAL = 0x10B1, + SMSG_PLAY_SPELL_VISUAL_KIT = 0x55A5, + SMSG_PLAY_TIME_WARNING = 0x4814, + SMSG_PONG = 0x4D42, + SMSG_POWER_UPDATE = 0x4A07, + SMSG_PRE_RESURRECT = 0x6C36, + SMSG_PROCRESIST = 0x0426, + SMSG_PROPOSE_LEVEL_GRANT = 0x6114, + SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 0x0000, + SMSG_PVP_CREDIT = 0x6015, + SMSG_PVP_LOG_DATA = 0x5CB2, + SMSG_PVP_OPTIONS_ENABLED = 0x50A1, + SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0x6314, + SMSG_QUERY_TIME_RESPONSE = 0x2124, + SMSG_QUESTGIVER_OFFER_REWARD = 0x2427, + SMSG_QUESTGIVER_QUEST_COMPLETE = 0x55A4, + SMSG_QUESTGIVER_QUEST_DETAILS = 0x2425, + SMSG_QUESTGIVER_QUEST_FAILED = 0x4236, + SMSG_QUESTGIVER_QUEST_INVALID = 0x4016, + SMSG_QUESTGIVER_QUEST_LIST = 0x0134, + SMSG_QUESTGIVER_REQUEST_ITEMS = 0x6236, + SMSG_QUESTGIVER_STATUS = 0x2115, + SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x4F25, + SMSG_QUESTLOG_FULL = 0x0E36, + SMSG_QUESTUPDATE_ADD_ITEM = 0x0000, + SMSG_QUESTUPDATE_ADD_KILL = 0x0D27, + SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x4416, + SMSG_QUESTUPDATE_COMPLETE = 0x2937, + SMSG_QUESTUPDATE_FAILED = 0x6324, + SMSG_QUESTUPDATE_FAILEDTIMER = 0x6427, + SMSG_QUEST_CONFIRM_ACCEPT = 0x6F07, + SMSG_QUEST_FORCE_REMOVE = 0x6605, + SMSG_QUEST_POI_QUERY_RESPONSE = 0x6304, + SMSG_QUEST_QUERY_RESPONSE = 0x6936, + SMSG_RAID_GROUP_ONLY = 0x0837, + SMSG_RAID_INSTANCE_INFO = 0x6626, + SMSG_RAID_INSTANCE_MESSAGE = 0x6E15, + SMSG_RAID_MARKERS_CHANGED = 0x10A1, + SMSG_RAID_READY_CHECK_THROTTLED_ERROR = 0x2607, + SMSG_RAID_SUMMON_FAILED = 0x18B6, + SMSG_RANDOMIZE_CHAR_NAME = 0x38B1, + SMSG_RATED_BG_RATING = 0x15A1, + SMSG_RATED_BG_STATS = 0x34A1, + SMSG_READ_ITEM_FAILED = 0x0F16, + SMSG_READ_ITEM_OK = 0x2605, + SMSG_REALM_SPLIT = 0x2714, + SMSG_REAL_GROUP_UPDATE = 0x0F34, + SMSG_RECEIVED_MAIL = 0x2924, + SMSG_REDIRECT_CLIENT = 0x0942, + SMSG_REFER_A_FRIEND_EXPIRED = 0x4934, + SMSG_REFER_A_FRIEND_FAILURE = 0x2037, + SMSG_REFORGE_RESULT = 0x58A4, + SMSG_REMOVED_SPELL = 0x4804, + SMSG_REPORT_PVP_AFK_RESULT = 0x2D06, + SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x30A7, + SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0x5DA4, + SMSG_RESEARCH_COMPLETE = 0x35A6, + SMSG_RESEARCH_SETUP_HISTORY = 0x10B6, + SMSG_RESET_COMPRESSION_CONTEXT = 0x0142, + SMSG_RESET_FAILED_NOTIFY = 0x4616, + SMSG_RESISTLOG = 0x0000, + SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x15B0, + SMSG_RESURRECT_REQUEST = 0x2905, + SMSG_RESYNC_RUNES = 0x6224, + SMSG_ROLE_POLL_BEGIN = 0x70B0, + SMSG_RWHOIS = 0x2437, + SMSG_SELL_ITEM = 0x6105, + SMSG_SEND_MAIL_RESULT = 0x4927, + SMSG_SEND_UNLEARN_SPELLS = 0x4E25, + SMSG_SERVERTIME = 0x6327, + SMSG_SERVER_FIRST_ACHIEVEMENT = 0x6424, + SMSG_SERVER_INFO_RESPONSE = 0x74B5, + SMSG_SERVER_MESSAGE = 0x6C04, + SMSG_SERVER_PERF = 0x74B6, + SMSG_SETUP_RESEARCH_HISTORY = 0x0000, + SMSG_SET_DF_FAST_LAUNCH_RESULT = 0x35B6, + SMSG_SET_FACTION_ATWAR = 0x4216, + SMSG_SET_FACTION_STANDING = 0x0126, + SMSG_SET_FACTION_VISIBLE = 0x2525, + SMSG_SET_FLAT_SPELL_MODIFIER = 0x2834, + SMSG_SET_FORCED_REACTIONS = 0x4615, + SMSG_SET_PCT_SPELL_MODIFIER = 0x0224, + SMSG_SET_PHASE_SHIFT = 0x70A0, + SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x2B25, + SMSG_SET_PLAY_HOVER_ANIM = 0x30A6, + SMSG_SET_PROFICIENCY = 0x6207, + SMSG_SET_PROJECTILE_POSITION = 0x2616, + SMSG_SHOWTAXINODES = 0x2A36, + SMSG_SHOW_BANK = 0x2627, + SMSG_SHOW_RATINGS = 0x11B4, + SMSG_SOR_START_EXPERIENCE_INCOMPLETE = 0x7CA7, + SMSG_SPELLBREAKLOG = 0x6B17, + SMSG_SPELLDAMAGESHIELD = 0x2927, + SMSG_SPELLDISPELLOG = 0x4516, + SMSG_SPELLENERGIZELOG = 0x0414, + SMSG_SPELLHEALLOG = 0x2816, + SMSG_SPELLINSTAKILLLOG = 0x6216, + SMSG_SPELLINTERRUPTLOG = 0x1DA7, + SMSG_SPELLLOGEXECUTE = 0x0626, + SMSG_SPELLLOGMISS = 0x0625, + SMSG_SPELLNONMELEEDAMAGELOG = 0x4315, + SMSG_SPELLORDAMAGE_IMMUNE = 0x4507, + SMSG_SPELLSTEALLOG = 0x4E26, + SMSG_SPELL_CATEGORY_COOLDOWN = 0x71B6, + SMSG_SPELL_COOLDOWN = 0x4B16, + SMSG_SPELL_DELAYED = 0x0715, + SMSG_SPELL_FAILED_OTHER = 0x0C34, + SMSG_SPELL_FAILURE = 0x4535, + SMSG_SPELL_GO = 0x6E16, + SMSG_SPELL_START = 0x6415, + SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x6006, + SMSG_SPIRIT_HEALER_CONFIRM = 0x4917, + SMSG_SPLINE_MOVE_COLLISION_DISABLE = 0x35B1, + SMSG_SPLINE_MOVE_COLLISION_ENABLE = 0x3CB0, + SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x5DB5, + SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0x3CA6, + SMSG_SPLINE_MOVE_ROOT = 0x51B4, + SMSG_SPLINE_MOVE_SET_FEATHER_FALL = 0x3DA5, + SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED = 0x38B3, + SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED = 0x39A0, + SMSG_SPLINE_MOVE_SET_FLYING = 0x31B5, + SMSG_SPLINE_MOVE_SET_HOVER = 0x14B6, + SMSG_SPLINE_MOVE_SET_LAND_WALK = 0x3DA7, + SMSG_SPLINE_MOVE_SET_NORMAL_FALL = 0x38B2, + SMSG_SPLINE_MOVE_SET_PITCH_RATE = 0x14B0, + SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED = 0x3DB3, + SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x75A7, + SMSG_SPLINE_MOVE_SET_RUN_SPEED = 0x51B7, + SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED = 0x59A1, + SMSG_SPLINE_MOVE_SET_SWIM_SPEED = 0x39A4, + SMSG_SPLINE_MOVE_SET_TURN_RATE = 0x78B5, + SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x54B6, + SMSG_SPLINE_MOVE_SET_WALK_SPEED = 0x34A5, + SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x0000, + SMSG_SPLINE_MOVE_START_SWIM = 0x31A5, + SMSG_SPLINE_MOVE_STOP_SWIM = 0x1DA2, + SMSG_SPLINE_MOVE_UNROOT = 0x75B6, + SMSG_SPLINE_MOVE_UNSET_FLYING = 0x58A6, + SMSG_SPLINE_MOVE_UNSET_HOVER = 0x7DA5, + SMSG_SPLINE_MOVE_WATER_WALK = 0x50A2, + SMSG_STABLE_RESULT = 0x2204, + SMSG_STANDSTATE_UPDATE = 0x6F04, + SMSG_START_MIRROR_TIMER = 0x6824, + SMSG_START_TIMER = 0x59A5, + SMSG_STOP_DANCE = 0x4637, + SMSG_STOP_MIRROR_TIMER = 0x0B06, + SMSG_STREAMING_MOVIE = 0x15B7, + SMSG_SUMMON_CANCEL = 0x0B34, + SMSG_SUMMON_REQUEST = 0x2A07, + SMSG_SUPERCEDED_SPELL = 0x35B0, + SMSG_SUPPRESS_NPC_GREETINGS = 0x74B1, + SMSG_SUSPEND_COMMS = 0x4140, + SMSG_SUSPEND_TOKEN_RESPONSE = 0x14B1, + SMSG_TALENTS_ERROR = 0x0916, + SMSG_TALENTS_INFO = 0x6F26, + SMSG_TALENTS_INVOLUNTARILY_RESET = 0x2C27, + SMSG_TAXINODE_STATUS = 0x2936, + SMSG_TEST_DROP_RATE_RESULT = 0x6816, + SMSG_TEXT_EMOTE = 0x0B05, + SMSG_THREAT_CLEAR = 0x6437, + SMSG_THREAT_REMOVE = 0x2E05, + SMSG_THREAT_UPDATE = 0x4735, + SMSG_TIME_ADJUSTMENT = 0x79B7, + SMSG_TIME_SYNC_REQ = 0x3CA4, + SMSG_TITLE_EARNED = 0x2426, + SMSG_TOGGLE_XP_GAIN = 0x6704, + SMSG_TOTEM_CREATED = 0x2414, + SMSG_TRADE_STATUS = 0x5CA3, + SMSG_TRADE_STATUS_EXTENDED = 0x70A2, + SMSG_TRAINER_BUY_FAILED = 0x0004, + SMSG_TRAINER_BUY_RESULT = 0x0000, + SMSG_TRAINER_BUY_SUCCEEDED = 0x6A05, + SMSG_TRAINER_LIST = 0x4414, + SMSG_TRANSFER_ABORTED = 0x0537, + SMSG_TRANSFER_PENDING = 0x18A6, + SMSG_TRIGGER_CINEMATIC = 0x6C27, + SMSG_TRIGGER_MOVIE = 0x4625, + SMSG_TURN_IN_PETITION_RESULTS = 0x0F07, + SMSG_TUTORIAL_FLAGS = 0x0B35, + SMSG_UNIT_HEALTH_FREQUENT = 0x2C26, + SMSG_UNIT_SPELLCAST_START = 0x2517, + SMSG_UPDATE_ACCOUNT_DATA = 0x6837, + SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x2015, + SMSG_UPDATE_COMBO_POINTS = 0x6B34, + SMSG_UPDATE_CURRENCY = 0x59B0, + SMSG_UPDATE_CURRENCY_WEEK_LIMIT = 0x70A7, + SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT = 0x3CB5, + SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x4007, + SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x4915, + SMSG_UPDATE_ITEM_ENCHANTMENTS = 0x6014, + SMSG_UPDATE_LAST_INSTANCE = 0x0437, + SMSG_UPDATE_OBJECT = 0x4715, + SMSG_UPDATE_SERVER_PLAYER_POSITION = 0x74A3, + SMSG_UPDATE_WORLD_STATE = 0x4816, + SMSG_USERLIST_ADD = 0x0F37, + SMSG_USERLIST_REMOVE = 0x2006, + SMSG_USERLIST_UPDATE = 0x0135, + SMSG_VOICESESSION_FULL = 0x6225, + SMSG_VOICE_CHAT_STATUS = 0x0F15, + SMSG_VOICE_PARENTAL_CONTROLS = 0x0534, + SMSG_VOICE_SESSION_LEAVE = 0x2A24, + SMSG_VOICE_SESSION_ROSTER_UPDATE = 0x2A17, + SMSG_VOICE_SET_TALKER_MUTED = 0x6E35, + SMSG_VOID_ITEM_SWAP_RESPONSE = 0x78A2, + SMSG_VOID_STORAGE_CONTENTS = 0x75B4, + SMSG_VOID_STORAGE_FAILED = 0x18A7, + SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0x51A6, + SMSG_VOID_TRANSFER_RESULT = 0x1DA6, + SMSG_WAIT_QUEUE_FINISH = 0x75B7, + SMSG_WAIT_QUEUE_UPDATE = 0x58A1, + SMSG_WARDEN_DATA = 0x31A0, + SMSG_WARGAME_CHECK_ENTRY = 0x3DA4, + SMSG_WARGAME_REQUEST_SENT = 0x59B2, + SMSG_WEATHER = 0x2904, + SMSG_WEEKLY_LAST_RESET = 0x50A5, + SMSG_WEEKLY_RESET_CURRENCY = 0x3CA1, + SMSG_WEEKLY_SPELL_USAGE = 0x39B7, + SMSG_WEEKLY_SPELL_USAGE_UPDATE = 0x11B5, + SMSG_WHO = 0x6907, + SMSG_WHOIS = 0x6917, + SMSG_WORLD_SERVER_INFO = 0x31A2, + SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4A14, + SMSG_XP_GAIN_ABORTED = 0x50B4, + SMSG_ZONE_UNDER_ATTACK = 0x0A06, }; /// Player state @@ -1367,23 +1435,39 @@ enum PacketProcessing }; class WorldPacket; +class WorldSession; + +typedef void(WorldSession::*pOpcodeHandler)(WorldPacket& recvPacket); struct OpcodeHandler { + OpcodeHandler() {} + OpcodeHandler(char const* _name, char const* _compressedName, SessionStatus _status, PacketProcessing _processing, pOpcodeHandler _handler) + : name(_name), compressedName(_compressedName), status(_status), packetProcessing(_processing), handler(_handler) {} + char const* name; + char const* compressedName; SessionStatus status; PacketProcessing packetProcessing; - void (WorldSession::*handler)(WorldPacket& recvPacket); + pOpcodeHandler handler; }; -extern OpcodeHandler opcodeTable[NUM_MSG_TYPES]; +extern OpcodeHandler* opcodeTable[NUM_OPCODE_HANDLERS]; +void InitOpcodes(); /// Lookup opcode name for human understandable logging -inline const char* LookupOpcodeName(uint16 id) +inline const char* LookupOpcodeName(Opcodes id) { - if (id >= NUM_MSG_TYPES) - return "Received unknown opcode, it's more than max!"; - return opcodeTable[id].name; + if (id < UNKNOWN_OPCODE) + { + bool isCompressed = uint32(id) & COMPRESSED_OPCODE_MASK; + if (OpcodeHandler* handler = opcodeTable[uint32(id) & 0x7FFF]) + return isCompressed ? handler->compressedName : handler->name; + + return "UNKNOWN OPCODE"; + } + + return "INVALID OPCODE"; } #endif /// @} diff --git a/src/server/game/Server/WorldPacket.cpp b/src/server/game/Server/WorldPacket.cpp new file mode 100644 index 00000000000..c8a971743af --- /dev/null +++ b/src/server/game/Server/WorldPacket.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2011 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <zlib.h> +#include "WorldPacket.h" +#include "World.h" + +//! Compresses packet in place +void WorldPacket::Compress(z_stream* compressionStream) +{ + Opcodes uncompressedOpcode = GetOpcode(); + if (uncompressedOpcode & COMPRESSED_OPCODE_MASK) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Packet with opcode 0x%04X is already compressed!", uncompressedOpcode); + return; + } + + Opcodes opcode = Opcodes(uncompressedOpcode | COMPRESSED_OPCODE_MASK); + uint32 size = wpos(); + uint32 destsize = compressBound(size); + + std::vector<uint8> storage(destsize); + + _compressionStream = compressionStream; + Compress(static_cast<void*>(&storage[0]), &destsize, static_cast<const void*>(contents()), size); + if (destsize == 0) + return; + + clear(); + reserve(destsize + sizeof(uint32)); + *this << uint32(size); + append(&storage[0], destsize); + SetOpcode(opcode); + + sLog->outInfo(LOG_FILTER_NETWORKIO, "Successfully compressed opcode %u (len %u) to %u (len %u)", uncompressedOpcode, size, opcode, destsize); +} + +//! Compresses another packet and stores it in self (source left intact) +void WorldPacket::Compress(z_stream* compressionStream, WorldPacket const* source) +{ + ASSERT(source != this); + + Opcodes uncompressedOpcode = source->GetOpcode(); + if (uncompressedOpcode & COMPRESSED_OPCODE_MASK) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Packet with opcode 0x%04X is already compressed!", uncompressedOpcode); + return; + } + + Opcodes opcode = Opcodes(uncompressedOpcode | COMPRESSED_OPCODE_MASK); + uint32 size = source->size(); + uint32 destsize = compressBound(size); + + size_t sizePos = 0; + resize(destsize + sizeof(uint32)); + + _compressionStream = compressionStream; + Compress(static_cast<void*>(&_storage[0] + sizeof(uint32)), &destsize, static_cast<const void*>(source->contents()), size); + if (destsize == 0) + return; + + put<uint32>(sizePos, size); + resize(destsize + sizeof(uint32)); + + SetOpcode(opcode); + + sLog->outInfo(LOG_FILTER_NETWORKIO, "Successfully compressed opcode %u (len %u) to %u (len %u)", uncompressedOpcode, size, opcode, destsize); +} + +void WorldPacket::Compress(void* dst, uint32 *dst_size, const void* src, int src_size) +{ + _compressionStream->next_out = (Bytef*)dst; + _compressionStream->avail_out = *dst_size; + _compressionStream->next_in = (Bytef*)src; + _compressionStream->avail_in = (uInt)src_size; + + int32 z_res = deflate(_compressionStream, Z_SYNC_FLUSH); + if (z_res != Z_OK) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Can't compress packet (zlib: deflate) Error code: %i (%s, msg: %s)", z_res, zError(z_res), _compressionStream->msg); + *dst_size = 0; + return; + } + + if (_compressionStream->avail_in != 0) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Can't compress packet (zlib: deflate not greedy)"); + *dst_size = 0; + return; + } + + *dst_size -= _compressionStream->avail_out; +} diff --git a/src/server/shared/Packets/WorldPacket.h b/src/server/game/Server/WorldPacket.h index 7ab95bc496d..c695c16ed3b 100755..100644 --- a/src/server/shared/Packets/WorldPacket.h +++ b/src/server/game/Server/WorldPacket.h @@ -20,33 +20,43 @@ #define TRINITYCORE_WORLDPACKET_H #include "Common.h" +#include "Opcodes.h" #include "ByteBuffer.h" +struct z_stream_s; + class WorldPacket : public ByteBuffer { public: // just container for later use - WorldPacket() : ByteBuffer(0), m_opcode(0) + WorldPacket() : ByteBuffer(0), m_opcode(UNKNOWN_OPCODE) + { + } + + WorldPacket(Opcodes opcode, size_t res = 200) : ByteBuffer(res), m_opcode(opcode) { } - explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { } // copy constructor - WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode) + WorldPacket(WorldPacket const& packet) : ByteBuffer(packet), m_opcode(packet.m_opcode) { } - void Initialize(uint16 opcode, size_t newres=200) + void Initialize(Opcodes opcode, size_t newres = 200) { clear(); _storage.reserve(newres); m_opcode = opcode; } - uint16 GetOpcode() const { return m_opcode; } - void SetOpcode(uint16 opcode) { m_opcode = opcode; } + Opcodes GetOpcode() const { return m_opcode; } + void SetOpcode(Opcodes opcode) { m_opcode = opcode; } + void Compress(z_stream_s* compressionStream); + void Compress(z_stream_s* compressionStream, WorldPacket const* source); protected: - uint16 m_opcode; + Opcodes m_opcode; + void Compress(void* dst, uint32 *dst_size, const void* src, int src_size); + z_stream_s* _compressionStream; }; #endif diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 118b0d68d5d..87cd026c244 100755..100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -21,6 +21,7 @@ */ #include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it +#include <zlib.h> #include "Common.h" #include "DatabaseEnv.h" #include "Log.h" @@ -47,14 +48,15 @@ bool MapSessionFilter::Process(WorldPacket* packet) { - OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()]; + Opcodes opcode = DropHighBytes(packet->GetOpcode()); + OpcodeHandler const* opHandle = opcodeTable[opcode]; //let's check if our opcode can be really processed in Map::Update() - if (opHandle.packetProcessing == PROCESS_INPLACE) + if (opHandle->packetProcessing == PROCESS_INPLACE) return true; //we do not process thread-unsafe packets - if (opHandle.packetProcessing == PROCESS_THREADUNSAFE) + if (opHandle->packetProcessing == PROCESS_THREADUNSAFE) return false; Player* player = m_pSession->GetPlayer(); @@ -69,13 +71,14 @@ bool MapSessionFilter::Process(WorldPacket* packet) //OR packet handler is not thread-safe! bool WorldSessionFilter::Process(WorldPacket* packet) { - OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()]; + Opcodes opcode = DropHighBytes(packet->GetOpcode()); + OpcodeHandler const* opHandle = opcodeTable[opcode]; //check if packet handler is supposed to be safe - if (opHandle.packetProcessing == PROCESS_INPLACE) + if (opHandle->packetProcessing == PROCESS_INPLACE) return true; //thread-unsafe packets should be processed in World::UpdateSessions() - if (opHandle.packetProcessing == PROCESS_THREADUNSAFE) + if (opHandle->packetProcessing == PROCESS_THREADUNSAFE) return true; //no player attached? -> our client! ^^ @@ -109,6 +112,19 @@ isRecruiter(isARecruiter), timeLastWhoCommand(0) } InitializeQueryCallbackParameters(); + + _compressionStream = new z_stream(); + _compressionStream->zalloc = (alloc_func)NULL; + _compressionStream->zfree = (free_func)NULL; + _compressionStream->opaque = (voidpf)NULL; + _compressionStream->avail_in = 0; + _compressionStream->next_in = NULL; + int32 z_res = deflateInit(_compressionStream, sWorld->getIntConfig(CONFIG_COMPRESSION)); + if (z_res != Z_OK) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res)); + return; + } } /// WorldSession destructor @@ -135,6 +151,15 @@ WorldSession::~WorldSession() delete packet; LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); // One-time query + + int32 z_res = deflateEnd(_compressionStream); + if (z_res != Z_OK && z_res != Z_DATA_ERROR) // Z_DATA_ERROR signals that internal state was BUSY + { + sLog->outError(LOG_FILTER_NETWORKIO, "Can't close packet compression stream (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res)); + return; + } + + delete _compressionStream; } void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const @@ -156,11 +181,26 @@ uint32 WorldSession::GetGuidLow() const } /// Send a packet to the client -void WorldSession::SendPacket(WorldPacket const* packet) +void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/) { if (!m_Socket) return; + if (packet->GetOpcode() == NULL_OPCODE || packet->GetOpcode() == UNKNOWN_OPCODE) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Prevented sending of %s", packet->GetOpcode() == NULL_OPCODE ? "NULL_OPCODE" : "UNKNOWN_OPCODE"); + return; + } + + if (!forced) + { + if (!opcodeTable[packet->GetOpcode()]) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Prevented sending disabled opcode %d (hex 0x%04X)", packet->GetOpcode(), packet->GetOpcode()); + return; + } + } + #ifdef TRINITY_DEBUG // Code for network use statistic static uint64 sendPacketCount = 0; @@ -248,107 +288,101 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { - if (packet->GetOpcode() >= NUM_MSG_TYPES) + const OpcodeHandler* opHandle = opcodeTable[packet->GetOpcode()]; + try { - sLog->outError(LOG_FILTER_GENERAL, "SESSION: received non-existed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); - sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet)); - } - else - { - OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()]; - try + switch (opHandle->status) { - switch (opHandle.status) - { - case STATUS_LOGGEDIN: - if (!_player) - { - // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets - //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize - //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. - if (!m_playerRecentlyLogout) - { - //! Prevent infinite loop - if (!firstDelayedPacket) - firstDelayedPacket = packet; - //! Because checking a bool is faster than reallocating memory - deletePacket = false; - QueuePacket(packet); - //! Log - sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. " - "Player is currently not in world yet.", opHandle.name, packet->GetOpcode()); - } - - } - else if (_player->IsInWorld()) + case STATUS_LOGGEDIN: + if (!_player) + { + // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets + //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize + //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. + if (!m_playerRecentlyLogout) { - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle.handler)(*packet); - if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) - LogUnprocessedTail(packet); + //! Prevent infinite loop + if (!firstDelayedPacket) + firstDelayedPacket = packet; + //! Because checking a bool is faster than reallocating memory + deletePacket = false; + QueuePacket(packet); + //! Log + sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. " + "Player is currently not in world yet.", opHandle->name, packet->GetOpcode()); } - // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer - break; - case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: - if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout - LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", - "the player has not logged in yet and not recently logout"); - else - { - // not expected _player or must checked in packet handler - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle.handler)(*packet); - if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) - LogUnprocessedTail(packet); - } - break; - case STATUS_TRANSFER: - if (!_player) - LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); - else if (_player->IsInWorld()) - LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); - else - { - sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle.handler)(*packet); - if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) - LogUnprocessedTail(packet); - } - break; - case STATUS_AUTHED: - // prevent cheating with skip queue wait - if (m_inQueue) - { - LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); - break; - } - - // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes - // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. - if (packet->GetOpcode() == CMSG_CHAR_ENUM) - m_playerRecentlyLogout = false; - + } + else if (_player->IsInWorld()) + { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); - (this->*opHandle.handler)(*packet); + (this->*opHandle->handler)(*packet); if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); + } + // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer + break; + case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: + if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout + LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", + "the player has not logged in yet and not recently logout"); + else + { + // not expected _player or must checked in packet hanlder + sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + (this->*opHandle->handler)(*packet); + if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) + LogUnprocessedTail(packet); + } + break; + case STATUS_TRANSFER: + if (!_player) + LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); + else if (_player->IsInWorld()) + LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); + else + { + sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + (this->*opHandle->handler)(*packet); + if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) + LogUnprocessedTail(packet); + } + break; + case STATUS_AUTHED: + // prevent cheating with skip queue wait + if (m_inQueue) + { + LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; - case STATUS_NEVER: - sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)", - GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", - LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); - break; - case STATUS_UNHANDLED: - sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not handled opcode %s (0x%.4X)", - GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", - LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); - break; - } + } + + // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes + // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. + if (packet->GetOpcode() == CMSG_CHAR_ENUM) + m_playerRecentlyLogout = false; + + sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); + (this->*opHandle->handler)(*packet); + if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) + LogUnprocessedTail(packet); + break; + case STATUS_NEVER: + sLog->outError(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)", + GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", + LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); + break; + case STATUS_UNHANDLED: + sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not handled opcode %s (0x%.4X)", + GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", + LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); + break; } - catch(ByteBufferException &) + } + catch(ByteBufferException &) + { + sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", + packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); + if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE)) { - sLog->outError(LOG_FILTER_GENERAL, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", - packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); sLog->outTrace(LOG_FILTER_NETWORKIO, "Dumping error causing packet:"); packet->hexlike(); } @@ -576,8 +610,11 @@ void WorldSession::SendNotification(const char *format, ...) vsnprintf(szStr, 1024, format, ap); va_end(ap); - WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1)); - data << szStr; + size_t len = strlen(szStr); + WorldPacket data(SMSG_NOTIFICATION, 2 + len); + data.WriteBits(len, 13); + data.FlushBits(); + data.append(szStr, len); SendPacket(&data); } } @@ -594,8 +631,11 @@ void WorldSession::SendNotification(uint32 string_id, ...) vsnprintf(szStr, 1024, format, ap); va_end(ap); - WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1)); - data << szStr; + size_t len = strlen(szStr); + WorldPacket data(SMSG_NOTIFICATION, 2 + len); + data.WriteBits(len, 13); + data.FlushBits(); + data.append(szStr, len); SendPacket(&data); } } @@ -638,15 +678,21 @@ void WorldSession::SendAuthWaitQue(uint32 position) if (position == 0) { WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info + packet.FlushBits(); packet << uint8(AUTH_OK); SendPacket(&packet); } else { WorldPacket packet(SMSG_AUTH_RESPONSE, 6); + packet.WriteBit(1); // has queue info + packet.WriteBit(0); // unk queue bool + packet.WriteBit(0); // has account info + packet.FlushBits(); packet << uint8(AUTH_WAIT_QUEUE); packet << uint32(position); - packet << uint8(0); // unk SendPacket(&packet); } } @@ -723,8 +769,8 @@ void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string d void WorldSession::SendAccountDataTimes(uint32 mask) { - WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK - data << uint32(time(NULL)); // unix time of something + WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+NUM_ACCOUNT_DATA_TYPES*4); + data << uint32(time(NULL)); // Server time data << uint8(1); data << uint32(mask); // type mask for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) @@ -772,156 +818,6 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans) m_TutorialsChanged = false; } -void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi) -{ - data >> mi->flags; - data >> mi->flags2; - data >> mi->time; - data >> mi->pos.PositionXYZOStream(); - - if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) - { - data.readPackGUID(mi->t_guid); - - data >> mi->t_pos.PositionXYZOStream(); - data >> mi->t_time; - data >> mi->t_seat; - - if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)) - data >> mi->t_time2; - - if (mi->pos.m_positionX != mi->t_pos.m_positionX) - if (GetPlayer()->GetTransport()) - GetPlayer()->GetTransport()->UpdatePosition(mi); - } - - if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))) - data >> mi->pitch; - - data >> mi->fallTime; - - if (mi->HasMovementFlag(MOVEMENTFLAG_FALLING)) - { - data >> mi->j_zspeed; - data >> mi->j_sinAngle; - data >> mi->j_cosAngle; - data >> mi->j_xyspeed; - } - - if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION)) - data >> mi->splineElevation; - - //! Anti-cheat checks. Please keep them in seperate if() blocks to maintain a clear overview. - //! Might be subject to latency, so just remove improper flags. - #ifdef TRINITY_DEBUG - #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \ - { \ - if (check) \ - { \ - sLog->outDebug(LOG_FILTER_UNITS, "WorldSession::ReadMovementInfo: Violation of MovementFlags found (%s). " \ - "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \ - STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUIDLow(), maskToRemove); \ - mi->RemoveMovementFlag((maskToRemove)); \ - } \ - } - #else - #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \ - if (check) \ - mi->RemoveMovementFlag((maskToRemove)); - #endif - - - /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid - in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. - It will freeze clients that receive this player's movement info. - */ - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), - MOVEMENTFLAG_ROOT); - - //! Cannot hover without SPELL_AURA_HOVER - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER), - MOVEMENTFLAG_HOVER); - - //! Cannot ascend and descend at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING), - MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING); - - //! Cannot move left and right at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT), - MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT); - - //! Cannot strafe left and right at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT), - MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT); - - //! Cannot pitch up and down at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN), - MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN); - - //! Cannot move forwards and backwards at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD), - MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD); - - //! Cannot walk on water without SPELL_AURA_WATER_WALK - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK), - MOVEMENTFLAG_WATERWALKING); - - //! Cannot feather fall without SPELL_AURA_FEATHER_FALL - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL), - MOVEMENTFLAG_FALLING_SLOW); - - /*! Cannot fly if no fly auras present. Exception is being a GM. - Note that we check for account level instead of Player::IsGameMaster() because in some - situations it may be feasable to use .gm fly on as a GM without having .gm on, - e.g. aerial combat. - */ - - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER && - !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) && - !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED), - MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY); - - #undef REMOVE_VIOLATING_FLAGS -} - -void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi) -{ - data->appendPackGUID(mi->guid); - - *data << mi->flags; - *data << mi->flags2; - *data << mi->time; - *data << mi->pos.PositionXYZOStream(); - - if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) - { - data->appendPackGUID(mi->t_guid); - - *data << mi->t_pos.PositionXYZOStream(); - *data << mi->t_time; - *data << mi->t_seat; - - if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)) - *data << mi->t_time2; - } - - if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)) - *data << mi->pitch; - - *data << mi->fallTime; - - if (mi->HasMovementFlag(MOVEMENTFLAG_FALLING)) - { - *data << mi->j_zspeed; - *data << mi->j_sinAngle; - *data << mi->j_cosAngle; - *data << mi->j_xyspeed; - } - - if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION)) - *data << mi->splineElevation; -} - void WorldSession::ReadAddonsInfo(WorldPacket &data) { if (data.rpos() + 4 > data.size()) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index b8b09531082..58ad4287ee8 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -30,6 +30,7 @@ #include "World.h" #include "WorldPacket.h" #include "Cryptography/BigNumber.h" +#include "Opcodes.h" class CalendarEvent; class CalendarInvite; @@ -135,12 +136,15 @@ enum ChatRestrictionType enum CharterTypes { - GUILD_CHARTER_TYPE = 9, + GUILD_CHARTER_TYPE = 4, ARENA_TEAM_CHARTER_2v2_TYPE = 2, ARENA_TEAM_CHARTER_3v3_TYPE = 3, - ARENA_TEAM_CHARTER_5v5_TYPE = 5 + ARENA_TEAM_CHARTER_5v5_TYPE = 5, }; +#define DB2_REPLY_SPARSE 2442913102 +#define DB2_REPLY_ITEM 1344507586 + //class to deal with packet processing //allows to determine if next packet is safe to be processed class PacketFilter @@ -151,6 +155,7 @@ public: virtual bool Process(WorldPacket* /*packet*/) { return true; } virtual bool ProcessLogout() const { return true; } + static Opcodes DropHighBytes(Opcodes opcode) { return Opcodes(opcode & 0xFFFF); } protected: WorldSession* const m_pSession; @@ -229,9 +234,9 @@ class WorldSession void SendAddonsInfo(); void ReadMovementInfo(WorldPacket& data, MovementInfo* mi); - void WriteMovementInfo(WorldPacket* data, MovementInfo* mi); + void WriteMovementInfo(WorldPacket &data, MovementInfo* mi); - void SendPacket(WorldPacket const* packet); + void SendPacket(WorldPacket const* packet, bool forced = false); void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3); void SendNotification(uint32 string_id, ...); void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName); @@ -240,7 +245,7 @@ class WorldSession void SendSetPhaseShift(uint32 phaseShift); void SendQueryTimeResponse(); - void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0); + void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); void SendClientCacheVersion(uint32 version); AccountTypes GetSecurity() const { return _security; } @@ -393,6 +398,8 @@ class WorldSession uint32 GetRecruiterId() const { return recruiterId; } bool IsARecruiter() const { return isRecruiter; } + z_stream_s* GetCompressionStream() { return _compressionStream; } + public: // opcodes handlers void Handle_NULL(WorldPacket& recvPacket); // not used @@ -405,9 +412,12 @@ class WorldSession void HandleCharCreateOpcode(WorldPacket& recvPacket); void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo* createInfo); void HandlePlayerLoginOpcode(WorldPacket& recvPacket); + void HandleLoadScreenOpcode(WorldPacket& recvPacket); void HandleCharEnum(PreparedQueryResult result); void HandlePlayerLogin(LoginQueryHolder * holder); - void HandleCharFactionOrRaceChange(WorldPacket& recv_data); + void HandleCharFactionOrRaceChange(WorldPacket& recvData); + void HandleRandomizeCharNameOpcode(WorldPacket& recvData); + // played time void HandlePlayedTime(WorldPacket& recvPacket); @@ -416,6 +426,7 @@ class WorldSession void HandleMoveUnRootAck(WorldPacket& recvPacket); void HandleMoveRootAck(WorldPacket& recvPacket); void HandleLookingForGroup(WorldPacket& recvPacket); + void HandleReturnToGraveyard(WorldPacket& recvPacket); // new inspect void HandleInspectOpcode(WorldPacket& recvPacket); @@ -424,15 +435,15 @@ class WorldSession void HandleInspectHonorStatsOpcode(WorldPacket& recvPacket); void HandleMoveWaterWalkAck(WorldPacket& recvPacket); - void HandleFeatherFallAck(WorldPacket& recv_data); + void HandleFeatherFallAck(WorldPacket& recvData); - void HandleMoveHoverAck(WorldPacket& recv_data); + void HandleMoveHoverAck(WorldPacket& recvData); void HandleMountSpecialAnimOpcode(WorldPacket& recvdata); // character view - void HandleShowingHelmOpcode(WorldPacket& recv_data); - void HandleShowingCloakOpcode(WorldPacket& recv_data); + void HandleShowingHelmOpcode(WorldPacket& recvData); + void HandleShowingCloakOpcode(WorldPacket& recvData); // repair void HandleRepairItemOpcode(WorldPacket& recvPacket); @@ -441,7 +452,7 @@ class WorldSession void HandleMoveKnockBackAck(WorldPacket& recvPacket); void HandleMoveTeleportAck(WorldPacket& recvPacket); - void HandleForceSpeedChangeAck(WorldPacket& recv_data); + void HandleForceSpeedChangeAck(WorldPacket& recvData); void HandlePingOpcode(WorldPacket& recvPacket); void HandleAuthSessionOpcode(WorldPacket& recvPacket); @@ -481,15 +492,13 @@ class WorldSession void HandleDelIgnoreOpcode(WorldPacket& recvPacket); void HandleSetContactNotesOpcode(WorldPacket& recvPacket); void HandleBugOpcode(WorldPacket& recvPacket); - void HandleSetAmmoOpcode(WorldPacket& recvPacket); - void HandleItemNameQueryOpcode(WorldPacket& recvPacket); void HandleAreaTriggerOpcode(WorldPacket& recvPacket); - void HandleSetFactionAtWar(WorldPacket& recv_data); - void HandleSetFactionCheat(WorldPacket& recv_data); - void HandleSetWatchedFactionOpcode(WorldPacket& recv_data); - void HandleSetFactionInactiveOpcode(WorldPacket& recv_data); + void HandleSetFactionAtWar(WorldPacket& recvData); + void HandleSetFactionCheat(WorldPacket& recvData); + void HandleSetWatchedFactionOpcode(WorldPacket& recvData); + void HandleSetFactionInactiveOpcode(WorldPacket& recvData); void HandleUpdateAccountData(WorldPacket& recvPacket); void HandleRequestAccountData(WorldPacket& recvPacket); @@ -511,46 +520,46 @@ class WorldSession void HandleMoveWorldportAckOpcode(); // for server-side calls void HandleMovementOpcodes(WorldPacket& recvPacket); - void HandleSetActiveMoverOpcode(WorldPacket& recv_data); - void HandleMoveNotActiveMover(WorldPacket& recv_data); - void HandleDismissControlledVehicle(WorldPacket& recv_data); - void HandleRequestVehicleExit(WorldPacket& recv_data); - void HandleChangeSeatsOnControlledVehicle(WorldPacket& recv_data); - void HandleMoveTimeSkippedOpcode(WorldPacket& recv_data); + void HandleSetActiveMoverOpcode(WorldPacket& recvData); + void HandleMoveNotActiveMover(WorldPacket& recvData); + void HandleDismissControlledVehicle(WorldPacket& recvData); + void HandleRequestVehicleExit(WorldPacket& recvData); + void HandleChangeSeatsOnControlledVehicle(WorldPacket& recvData); + void HandleMoveTimeSkippedOpcode(WorldPacket& recvData); - void HandleRequestRaidInfoOpcode(WorldPacket& recv_data); + void HandleRequestRaidInfoOpcode(WorldPacket& recvData); - void HandleBattlefieldStatusOpcode(WorldPacket& recv_data); - void HandleBattleMasterHelloOpcode(WorldPacket& recv_data); + void HandleBattlefieldStatusOpcode(WorldPacket& recvData); + void HandleBattleMasterHelloOpcode(WorldPacket& recvData); void HandleGroupInviteOpcode(WorldPacket& recvPacket); //void HandleGroupCancelOpcode(WorldPacket& recvPacket); - void HandleGroupAcceptOpcode(WorldPacket& recvPacket); - void HandleGroupDeclineOpcode(WorldPacket& recvPacket); + void HandleGroupInviteResponseOpcode(WorldPacket& recvPacket); void HandleGroupUninviteOpcode(WorldPacket& recvPacket); void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket); void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); void HandleGroupDisbandOpcode(WorldPacket& recvPacket); - void HandleOptOutOfLootOpcode(WorldPacket& recv_data); + void HandleOptOutOfLootOpcode(WorldPacket& recvData); void HandleLootMethodOpcode(WorldPacket& recvPacket); - void HandleLootRoll(WorldPacket& recv_data); - void HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data); - void HandleRaidTargetUpdateOpcode(WorldPacket& recv_data); - void HandleRaidReadyCheckOpcode(WorldPacket& recv_data); - void HandleRaidReadyCheckFinishedOpcode(WorldPacket& recv_data); - void HandleGroupRaidConvertOpcode(WorldPacket& recv_data); - void HandleGroupChangeSubGroupOpcode(WorldPacket& recv_data); - void HandleGroupAssistantLeaderOpcode(WorldPacket& recv_data); - void HandlePartyAssignmentOpcode(WorldPacket& recv_data); - - void HandlePetitionBuyOpcode(WorldPacket& recv_data); - void HandlePetitionShowSignOpcode(WorldPacket& recv_data); - void HandlePetitionQueryOpcode(WorldPacket& recv_data); - void HandlePetitionRenameOpcode(WorldPacket& recv_data); - void HandlePetitionSignOpcode(WorldPacket& recv_data); - void HandlePetitionDeclineOpcode(WorldPacket& recv_data); - void HandleOfferPetitionOpcode(WorldPacket& recv_data); - void HandleTurnInPetitionOpcode(WorldPacket& recv_data); + void HandleLootRoll(WorldPacket& recvData); + void HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData); + void HandleRaidTargetUpdateOpcode(WorldPacket& recvData); + void HandleRaidReadyCheckOpcode(WorldPacket& recvData); + void HandleRaidReadyCheckFinishedOpcode(WorldPacket& recvData); + void HandleGroupRaidConvertOpcode(WorldPacket& recvData); + void HandleGroupChangeSubGroupOpcode(WorldPacket& recvData); + void HandleGroupSwapSubGroupOpcode(WorldPacket& recvData); + void HandleGroupAssistantLeaderOpcode(WorldPacket& recvData); + void HandlePartyAssignmentOpcode(WorldPacket& recvData); + + void HandlePetitionBuyOpcode(WorldPacket& recvData); + void HandlePetitionShowSignOpcode(WorldPacket& recvData); + void HandlePetitionQueryOpcode(WorldPacket& recvData); + void HandlePetitionRenameOpcode(WorldPacket& recvData); + void HandlePetitionSignOpcode(WorldPacket& recvData); + void HandlePetitionDeclineOpcode(WorldPacket& recvData); + void HandleOfferPetitionOpcode(WorldPacket& recvData); + void HandleTurnInPetitionOpcode(WorldPacket& recvData); void HandleGuildQueryOpcode(WorldPacket& recvPacket); void HandleGuildCreateOpcode(WorldPacket& recvPacket); @@ -563,13 +572,14 @@ class WorldSession void HandleGuildRosterOpcode(WorldPacket& recvPacket); void HandleGuildPromoteOpcode(WorldPacket& recvPacket); void HandleGuildDemoteOpcode(WorldPacket& recvPacket); + void HandleGuildAssignRankOpcode(WorldPacket& recvPacket); void HandleGuildLeaveOpcode(WorldPacket& recvPacket); void HandleGuildDisbandOpcode(WorldPacket& recvPacket); void HandleGuildLeaderOpcode(WorldPacket& recvPacket); void HandleGuildMOTDOpcode(WorldPacket& recvPacket); - void HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket); - void HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket); - void HandleGuildRankOpcode(WorldPacket& recvPacket); + void HandleGuildSetNoteOpcode(WorldPacket& recvPacket); + void HandleGuildQueryRanksOpcode(WorldPacket& recvPacket); + void HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket); void HandleGuildAddRankOpcode(WorldPacket& recvPacket); void HandleGuildDelRankOpcode(WorldPacket& recvPacket); void HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket); @@ -618,32 +628,33 @@ class WorldSession void HandleUnacceptTradeOpcode(WorldPacket& recvPacket); void HandleAuctionHelloOpcode(WorldPacket& recvPacket); - void HandleAuctionListItems(WorldPacket& recv_data); - void HandleAuctionListBidderItems(WorldPacket& recv_data); - void HandleAuctionSellItem(WorldPacket& recv_data); - void HandleAuctionRemoveItem(WorldPacket& recv_data); - void HandleAuctionListOwnerItems(WorldPacket& recv_data); - void HandleAuctionPlaceBid(WorldPacket& recv_data); - void HandleAuctionListPendingSales(WorldPacket& recv_data); - - void HandleGetMailList(WorldPacket& recv_data); - void HandleSendMail(WorldPacket& recv_data); - void HandleMailTakeMoney(WorldPacket& recv_data); - void HandleMailTakeItem(WorldPacket& recv_data); - void HandleMailMarkAsRead(WorldPacket& recv_data); - void HandleMailReturnToSender(WorldPacket& recv_data); - void HandleMailDelete(WorldPacket& recv_data); - void HandleItemTextQuery(WorldPacket& recv_data); - void HandleMailCreateTextItem(WorldPacket& recv_data); - void HandleQueryNextMailTime(WorldPacket& recv_data); - void HandleCancelChanneling(WorldPacket& recv_data); + void HandleAuctionListItems(WorldPacket& recvData); + void HandleAuctionListBidderItems(WorldPacket& recvData); + void HandleAuctionSellItem(WorldPacket& recvData); + void HandleAuctionRemoveItem(WorldPacket& recvData); + void HandleAuctionListOwnerItems(WorldPacket& recvData); + void HandleAuctionPlaceBid(WorldPacket& recvData); + void HandleAuctionListPendingSales(WorldPacket& recvData); + + void HandleGetMailList(WorldPacket& recvData); + void HandleSendMail(WorldPacket& recvData); + void HandleMailTakeMoney(WorldPacket& recvData); + void HandleMailTakeItem(WorldPacket& recvData); + void HandleMailMarkAsRead(WorldPacket& recvData); + void HandleMailReturnToSender(WorldPacket& recvData); + void HandleMailDelete(WorldPacket& recvData); + void HandleItemTextQuery(WorldPacket& recvData); + void HandleMailCreateTextItem(WorldPacket& recvData); + void HandleQueryNextMailTime(WorldPacket& recvData); + void HandleCancelChanneling(WorldPacket& recvData); void SendItemPageInfo(ItemTemplate* itemProto); void HandleSplitItemOpcode(WorldPacket& recvPacket); void HandleSwapInvItemOpcode(WorldPacket& recvPacket); void HandleDestroyItemOpcode(WorldPacket& recvPacket); void HandleAutoEquipItemOpcode(WorldPacket& recvPacket); - void HandleItemQuerySingleOpcode(WorldPacket& recvPacket); + void SendItemDb2Reply(uint32 entry); + void SendItemSparseDb2Reply(uint32 entry); void HandleSellItemOpcode(WorldPacket& recvPacket); void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket); void HandleBuyItemOpcode(WorldPacket& recvPacket); @@ -682,17 +693,18 @@ class WorldSession void HandleQuestgiverChooseRewardOpcode(WorldPacket& recvPacket); void HandleQuestgiverRequestRewardOpcode(WorldPacket& recvPacket); void HandleQuestQueryOpcode(WorldPacket& recvPacket); - void HandleQuestgiverCancel(WorldPacket& recv_data); - void HandleQuestLogSwapQuest(WorldPacket& recv_data); - void HandleQuestLogRemoveQuest(WorldPacket& recv_data); - void HandleQuestConfirmAccept(WorldPacket& recv_data); - void HandleQuestgiverCompleteQuest(WorldPacket& recv_data); + void HandleQuestgiverCancel(WorldPacket& recvData); + void HandleQuestLogSwapQuest(WorldPacket& recvData); + void HandleQuestLogRemoveQuest(WorldPacket& recvData); + void HandleQuestConfirmAccept(WorldPacket& recvData); + void HandleQuestgiverCompleteQuest(WorldPacket& recvData); void HandleQuestgiverQuestAutoLaunch(WorldPacket& recvPacket); void HandlePushQuestToParty(WorldPacket& recvPacket); void HandleQuestPushResult(WorldPacket& recvPacket); bool processChatmessageFurtherAfterSecurityChecks(std::string&, uint32); void HandleMessagechatOpcode(WorldPacket& recvPacket); + void HandleAddonMessagechatOpcode(WorldPacket& recvPacket); void SendPlayerNotFoundNotice(std::string name); void SendPlayerAmbiguousNotice(std::string name); void SendWrongFactionNotice(); @@ -704,7 +716,7 @@ class WorldSession void HandleCorpseQueryOpcode(WorldPacket& recvPacket); void HandleCorpseMapPositionQuery(WorldPacket& recvPacket); void HandleResurrectResponseOpcode(WorldPacket& recvPacket); - void HandleSummonResponseOpcode(WorldPacket& recv_data); + void HandleSummonResponseOpcode(WorldPacket& recvData); void HandleJoinChannel(WorldPacket& recvPacket); void HandleLeaveChannel(WorldPacket& recvPacket); @@ -733,73 +745,73 @@ class WorldSession void HandlePageQuerySkippedOpcode(WorldPacket& recvPacket); void HandlePageTextQueryOpcode(WorldPacket& recvPacket); - void HandleTutorialFlag (WorldPacket& recv_data); - void HandleTutorialClear(WorldPacket& recv_data); - void HandleTutorialReset(WorldPacket& recv_data); + void HandleTutorialFlag (WorldPacket& recvData); + void HandleTutorialClear(WorldPacket& recvData); + void HandleTutorialReset(WorldPacket& recvData); //Pet - void HandlePetAction(WorldPacket& recv_data); - void HandlePetStopAttack(WorldPacket& recv_data); + void HandlePetAction(WorldPacket& recvData); + void HandlePetStopAttack(WorldPacket& recvData); void HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid, uint16 flag, uint64 guid2); - void HandlePetNameQuery(WorldPacket& recv_data); - void HandlePetSetAction(WorldPacket& recv_data); - void HandlePetAbandon(WorldPacket& recv_data); - void HandlePetRename(WorldPacket& recv_data); + void HandlePetNameQuery(WorldPacket& recvData); + void HandlePetSetAction(WorldPacket& recvData); + void HandlePetAbandon(WorldPacket& recvData); + void HandlePetRename(WorldPacket& recvData); void HandlePetCancelAuraOpcode(WorldPacket& recvPacket); void HandlePetSpellAutocastOpcode(WorldPacket& recvPacket); void HandlePetCastSpellOpcode(WorldPacket& recvPacket); void HandlePetLearnTalent(WorldPacket& recvPacket); void HandleLearnPreviewTalentsPet(WorldPacket& recvPacket); - void HandleSetActionBarToggles(WorldPacket& recv_data); + void HandleSetActionBarToggles(WorldPacket& recvData); - void HandleCharRenameOpcode(WorldPacket& recv_data); + void HandleCharRenameOpcode(WorldPacket& recvData); void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName); - void HandleSetPlayerDeclinedNames(WorldPacket& recv_data); + void HandleSetPlayerDeclinedNames(WorldPacket& recvData); - void HandleTotemDestroyed(WorldPacket& recv_data); - void HandleDismissCritter(WorldPacket& recv_data); + void HandleTotemDestroyed(WorldPacket& recvData); + void HandleDismissCritter(WorldPacket& recvData); //Battleground - void HandleBattlemasterHelloOpcode(WorldPacket& recv_data); - void HandleBattlemasterJoinOpcode(WorldPacket& recv_data); - void HandleBattlegroundPlayerPositionsOpcode(WorldPacket& recv_data); - void HandlePVPLogDataOpcode(WorldPacket& recv_data); - void HandleBattleFieldPortOpcode(WorldPacket& recv_data); - void HandleBattlefieldListOpcode(WorldPacket& recv_data); - void HandleLeaveBattlefieldOpcode(WorldPacket& recv_data); - void HandleBattlemasterJoinArena(WorldPacket& recv_data); - void HandleReportPvPAFK(WorldPacket& recv_data); - - void HandleWardenDataOpcode(WorldPacket& recv_data); - void HandleWorldTeleportOpcode(WorldPacket& recv_data); - void HandleMinimapPingOpcode(WorldPacket& recv_data); - void HandleRandomRollOpcode(WorldPacket& recv_data); - void HandleFarSightOpcode(WorldPacket& recv_data); - void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data); - void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data); - void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data); - void HandleSetTitleOpcode(WorldPacket& recv_data); - void HandleRealmSplitOpcode(WorldPacket& recv_data); - void HandleTimeSyncResp(WorldPacket& recv_data); - void HandleWhoisOpcode(WorldPacket& recv_data); - void HandleResetInstancesOpcode(WorldPacket& recv_data); - void HandleHearthAndResurrect(WorldPacket& recv_data); + void HandleBattlemasterHelloOpcode(WorldPacket& recvData); + void HandleBattlemasterJoinOpcode(WorldPacket& recvData); + void HandleBattlegroundPlayerPositionsOpcode(WorldPacket& recvData); + void HandlePVPLogDataOpcode(WorldPacket& recvData); + void HandleBattleFieldPortOpcode(WorldPacket& recvData); + void HandleBattlefieldListOpcode(WorldPacket& recvData); + void HandleLeaveBattlefieldOpcode(WorldPacket& recvData); + void HandleBattlemasterJoinArena(WorldPacket& recvData); + void HandleReportPvPAFK(WorldPacket& recvData); + + void HandleWardenDataOpcode(WorldPacket& recvData); + void HandleWorldTeleportOpcode(WorldPacket& recvData); + void HandleMinimapPingOpcode(WorldPacket& recvData); + void HandleRandomRollOpcode(WorldPacket& recvData); + void HandleFarSightOpcode(WorldPacket& recvData); + void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData); + void HandleSetRaidDifficultyOpcode(WorldPacket& recvData); + void HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData); + void HandleSetTitleOpcode(WorldPacket& recvData); + void HandleRealmSplitOpcode(WorldPacket& recvData); + void HandleTimeSyncResp(WorldPacket& recvData); + void HandleWhoisOpcode(WorldPacket& recvData); + void HandleResetInstancesOpcode(WorldPacket& recvData); + void HandleHearthAndResurrect(WorldPacket& recvData); void HandleInstanceLockResponse(WorldPacket& recvPacket); void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); // Looking for Dungeon/Raid - void HandleLfgSetCommentOpcode(WorldPacket& recv_data); - void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recv_data); - void HandleLfgPartyLockInfoRequestOpcode(WorldPacket& recv_data); - void HandleLfgJoinOpcode(WorldPacket& recv_data); - void HandleLfgLeaveOpcode(WorldPacket& recv_data); - void HandleLfgSetRolesOpcode(WorldPacket& recv_data); - void HandleLfgProposalResultOpcode(WorldPacket& recv_data); - void HandleLfgSetBootVoteOpcode(WorldPacket& recv_data); - void HandleLfgTeleportOpcode(WorldPacket& recv_data); - void HandleLfrSearchOpcode(WorldPacket& recv_data); - void HandleLfrLeaveOpcode(WorldPacket& recv_data); + void HandleLfgSetCommentOpcode(WorldPacket& recvData); + void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recvData); + void HandleLfgPartyLockInfoRequestOpcode(WorldPacket& recvData); + void HandleLfgJoinOpcode(WorldPacket& recvData); + void HandleLfgLeaveOpcode(WorldPacket& recvData); + void HandleLfgSetRolesOpcode(WorldPacket& recvData); + void HandleLfgProposalResultOpcode(WorldPacket& recvData); + void HandleLfgSetBootVoteOpcode(WorldPacket& recvData); + void HandleLfgTeleportOpcode(WorldPacket& recvData); + void HandleLfrSearchOpcode(WorldPacket& recvData); + void HandleLfrLeaveOpcode(WorldPacket& recvData); void SendLfgUpdatePlayer(const LfgUpdateData& updateData); void SendLfgUpdateParty(const LfgUpdateData& updateData); @@ -816,55 +828,56 @@ class WorldSession void SendLfgTeleportError(uint8 err); // Arena Team - void HandleInspectArenaTeamsOpcode(WorldPacket& recv_data); - void HandleArenaTeamQueryOpcode(WorldPacket& recv_data); - void HandleArenaTeamRosterOpcode(WorldPacket& recv_data); - void HandleArenaTeamInviteOpcode(WorldPacket& recv_data); - void HandleArenaTeamAcceptOpcode(WorldPacket& recv_data); - void HandleArenaTeamDeclineOpcode(WorldPacket& recv_data); - void HandleArenaTeamLeaveOpcode(WorldPacket& recv_data); - void HandleArenaTeamRemoveOpcode(WorldPacket& recv_data); - void HandleArenaTeamDisbandOpcode(WorldPacket& recv_data); - void HandleArenaTeamLeaderOpcode(WorldPacket& recv_data); - - void HandleAreaSpiritHealerQueryOpcode(WorldPacket& recv_data); - void HandleAreaSpiritHealerQueueOpcode(WorldPacket& recv_data); - void HandleCancelMountAuraOpcode(WorldPacket& recv_data); - void HandleSelfResOpcode(WorldPacket& recv_data); - void HandleComplainOpcode(WorldPacket& recv_data); - void HandleRequestPetInfoOpcode(WorldPacket& recv_data); + void HandleInspectArenaTeamsOpcode(WorldPacket& recvData); + void HandleArenaTeamQueryOpcode(WorldPacket& recvData); + void HandleArenaTeamRosterOpcode(WorldPacket& recvData); + void HandleArenaTeamInviteOpcode(WorldPacket& recvData); + void HandleArenaTeamAcceptOpcode(WorldPacket& recvData); + void HandleArenaTeamDeclineOpcode(WorldPacket& recvData); + void HandleArenaTeamLeaveOpcode(WorldPacket& recvData); + void HandleArenaTeamRemoveOpcode(WorldPacket& recvData); + void HandleArenaTeamDisbandOpcode(WorldPacket& recvData); + void HandleArenaTeamLeaderOpcode(WorldPacket& recvData); + + void HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData); + void HandleAreaSpiritHealerQueueOpcode(WorldPacket& recvData); + void HandleCancelMountAuraOpcode(WorldPacket& recvData); + void HandleSelfResOpcode(WorldPacket& recvData); + void HandleComplainOpcode(WorldPacket& recvData); + void HandleRequestPetInfoOpcode(WorldPacket& recvData); // Socket gem - void HandleSocketOpcode(WorldPacket& recv_data); + void HandleSocketOpcode(WorldPacket& recvData); - void HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data); + void HandleCancelTempEnchantmentOpcode(WorldPacket& recvData); - void HandleItemRefundInfoRequest(WorldPacket& recv_data); - void HandleItemRefund(WorldPacket& recv_data); + void HandleItemRefundInfoRequest(WorldPacket& recvData); + void HandleItemRefund(WorldPacket& recvData); - void HandleChannelVoiceOnOpcode(WorldPacket& recv_data); - void HandleVoiceSessionEnableOpcode(WorldPacket& recv_data); - void HandleSetActiveVoiceChannel(WorldPacket& recv_data); - void HandleSetTaxiBenchmarkOpcode(WorldPacket& recv_data); + void HandleChannelVoiceOnOpcode(WorldPacket& recvData); + void HandleVoiceSessionEnableOpcode(WorldPacket& recvData); + void HandleSetActiveVoiceChannel(WorldPacket& recvData); + void HandleSetTaxiBenchmarkOpcode(WorldPacket& recvData); // Guild Bank - void HandleGuildPermissions(WorldPacket& recv_data); - void HandleGuildBankMoneyWithdrawn(WorldPacket& recv_data); - void HandleGuildBankerActivate(WorldPacket& recv_data); - void HandleGuildBankQueryTab(WorldPacket& recv_data); - void HandleGuildBankLogQuery(WorldPacket& recv_data); - void HandleGuildBankDepositMoney(WorldPacket& recv_data); - void HandleGuildBankWithdrawMoney(WorldPacket& recv_data); - void HandleGuildBankSwapItems(WorldPacket& recv_data); - - void HandleGuildBankUpdateTab(WorldPacket& recv_data); - void HandleGuildBankBuyTab(WorldPacket& recv_data); - void HandleQueryGuildBankTabText(WorldPacket& recv_data); - void HandleSetGuildBankTabText(WorldPacket& recv_data); + void HandleGuildPermissions(WorldPacket& recvData); + void HandleGuildBankMoneyWithdrawn(WorldPacket& recvData); + void HandleGuildBankerActivate(WorldPacket& recvData); + void HandleGuildBankQueryTab(WorldPacket& recvData); + void HandleGuildBankLogQuery(WorldPacket& recvData); + void HandleGuildBankDepositMoney(WorldPacket& recvData); + void HandleGuildBankWithdrawMoney(WorldPacket& recvData); + void HandleGuildBankSwapItems(WorldPacket& recvData); + + void HandleGuildBankUpdateTab(WorldPacket& recvData); + void HandleGuildBankBuyTab(WorldPacket& recvData); + void HandleQueryGuildBankTabText(WorldPacket& recvData); + void HandleSetGuildBankTabText(WorldPacket& recvData); + void HandleGuildQueryXPOpcode(WorldPacket& recvData); // Refer-a-Friend - void HandleGrantLevel(WorldPacket& recv_data); - void HandleAcceptGrantLevel(WorldPacket& recv_data); + void HandleGrantLevel(WorldPacket& recvData); + void HandleAcceptGrantLevel(WorldPacket& recvData); // Calendar void HandleCalendarGetCalendar(WorldPacket& recvData); @@ -898,22 +911,42 @@ class WorldSession void SendCalendarRaidLockoutUpdated(InstanceSave const* save); void SendCalendarCommandResult(CalendarError err, char const* param = NULL); - void HandleSpellClick(WorldPacket& recv_data); - void HandleMirrorImageDataRequest(WorldPacket& recv_data); - void HandleAlterAppearance(WorldPacket& recv_data); - void HandleRemoveGlyph(WorldPacket& recv_data); - void HandleCharCustomize(WorldPacket& recv_data); - void HandleQueryInspectAchievements(WorldPacket& recv_data); - void HandleEquipmentSetSave(WorldPacket& recv_data); - void HandleEquipmentSetDelete(WorldPacket& recv_data); - void HandleEquipmentSetUse(WorldPacket& recv_data); - void HandleWorldStateUITimerUpdate(WorldPacket& recv_data); - void HandleReadyForAccountDataTimes(WorldPacket& recv_data); - void HandleQueryQuestsCompleted(WorldPacket& recv_data); - void HandleQuestPOIQuery(WorldPacket& recv_data); + // Void Storage + void HandleVoidStorageUnlock(WorldPacket& recvData); + void HandleVoidStorageQuery(WorldPacket& recvData); + void HandleVoidStorageTransfer(WorldPacket& recvData); + void HandleVoidSwapItem(WorldPacket& recvData); + void SendVoidStorageTransferResult(VoidTransferError result); + + // Transmogrification + void HandleTransmogrifyItems(WorldPacket& recvData); + + // Reforge + void HandleReforgeItemOpcode(WorldPacket& recvData); + void SendReforgeResult(bool success); + + // Miscellaneous + void HandleSpellClick(WorldPacket& recvData); + void HandleMirrorImageDataRequest(WorldPacket& recvData); + void HandleAlterAppearance(WorldPacket& recvData); + void HandleRemoveGlyph(WorldPacket& recvData); + void HandleCharCustomize(WorldPacket& recvData); + void HandleQueryInspectAchievements(WorldPacket& recvData); + void HandleGuildAchievementProgressQuery(WorldPacket& recvData); + void HandleEquipmentSetSave(WorldPacket& recvData); + void HandleEquipmentSetDelete(WorldPacket& recvData); + void HandleEquipmentSetUse(WorldPacket& recvData); + void HandleWorldStateUITimerUpdate(WorldPacket& recvData); + void HandleReadyForAccountDataTimes(WorldPacket& recvData); + void HandleQueryQuestsCompleted(WorldPacket& recvData); + void HandleQuestPOIQuery(WorldPacket& recvData); void HandleEjectPassenger(WorldPacket& data); void HandleEnterPlayerVehicle(WorldPacket& data); void HandleUpdateProjectilePosition(WorldPacket& recvPacket); + void HandleRequestHotfix(WorldPacket& recvPacket); + void HandleViolenceLevel(WorldPacket& recvPacket); + void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket); + int32 HandleEnableNagleAlgorithm(); private: void InitializeQueryCallbackParameters(); @@ -979,6 +1012,7 @@ class WorldSession bool isRecruiter; ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue; time_t timeLastWhoCommand; + z_stream_s* _compressionStream; }; #endif /// @} diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 5b04c3dc714..213206083bc 100755..100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -158,7 +158,7 @@ int WorldSocket::SendPacket(WorldPacket const& pct) if (closing_) return -1; - // Dump outgoing packet. + // Dump outgoing packet if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE)) { char buff[250]; @@ -184,20 +184,31 @@ int WorldSocket::SendPacket(WorldPacket const& pct) sLog->outTrace(LOG_FILTER_NETWORKIO, "%s", data.c_str()); } - // Create a copy of the original packet; this is to avoid issues if a hook modifies it. - sScriptMgr->OnPacketSend(this, WorldPacket(pct)); + WorldPacket const* pkt = &pct; - ServerPktHeader header(pct.size()+2, pct.GetOpcode()); + // Empty buffer used in case packet should be compressed + WorldPacket buff; + if (m_Session && pkt->size() > 0x400) + { + buff.Compress(m_Session->GetCompressionStream(), pkt); + pkt = &buff; + } + + sLog->outOpCode(uint32(pkt->GetOpcode()), LookupOpcodeName(pkt->GetOpcode()), true); + + sScriptMgr->OnPacketSend(this, *pkt); + + ServerPktHeader header(pkt->size()+2, pkt->GetOpcode()); m_Crypt.EncryptSend ((uint8*)header.header, header.getHeaderLength()); - if (m_OutBuffer->space() >= pct.size() + header.getHeaderLength() && msg_queue()->is_empty()) + if (m_OutBuffer->space() >= pkt->size() + header.getHeaderLength() && msg_queue()->is_empty()) { // Put the packet on the buffer. if (m_OutBuffer->copy((char*) header.header, header.getHeaderLength()) == -1) ACE_ASSERT (false); - if (!pct.empty()) - if (m_OutBuffer->copy((char*) pct.contents(), pct.size()) == -1) + if (!pkt->empty()) + if (m_OutBuffer->copy((char*) pkt->contents(), pkt->size()) == -1) ACE_ASSERT (false); } else @@ -205,12 +216,12 @@ int WorldSocket::SendPacket(WorldPacket const& pct) // Enqueue the packet. ACE_Message_Block* mb; - ACE_NEW_RETURN(mb, ACE_Message_Block(pct.size() + header.getHeaderLength()), -1); + ACE_NEW_RETURN(mb, ACE_Message_Block(pkt->size() + header.getHeaderLength()), -1); mb->copy((char*) header.header, header.getHeaderLength()); - if (!pct.empty()) - mb->copy((const char*)pct.contents(), pct.size()); + if (!pkt->empty()) + mb->copy((const char*)pkt->contents(), pkt->size()); if (msg_queue()->enqueue_tail(mb, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1) { @@ -263,18 +274,10 @@ int WorldSocket::open (void *a) m_Address = remote_addr.get_host_addr(); - // Send startup packet. - WorldPacket packet (SMSG_AUTH_CHALLENGE, 24); - packet << uint32(1); // 1...31 - packet << m_Seed; - - BigNumber seed1; - seed1.SetRand(16 * 8); - packet.append(seed1.AsByteArray(16), 16); // new encryption seeds - - BigNumber seed2; - seed2.SetRand(16 * 8); - packet.append(seed2.AsByteArray(16), 16); // new encryption seeds + // not an opcode. this packet sends raw string WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT" + // because of our implementation, bytes "WO" become the opcode + WorldPacket packet(MSG_VERIFY_CONNECTIVITY); + packet << "RLD OF WARCRAFT CONNECTION - SERVER TO CLIENT"; if (SendPacket(packet) == -1) return -1; @@ -479,7 +482,7 @@ int WorldSocket::Update (void) int ret; do - ret = handle_output (get_handle()); + ret = handle_output(get_handle()); while (ret > 0); return ret; @@ -487,18 +490,18 @@ int WorldSocket::Update (void) int WorldSocket::handle_input_header (void) { - ACE_ASSERT (m_RecvWPct == NULL); + ACE_ASSERT(m_RecvWPct == NULL); - ACE_ASSERT (m_Header.length() == sizeof(ClientPktHeader)); + ACE_ASSERT(m_Header.length() == sizeof(ClientPktHeader)); - m_Crypt.DecryptRecv ((uint8*) m_Header.rd_ptr(), sizeof(ClientPktHeader)); + m_Crypt.DecryptRecv ((uint8*)m_Header.rd_ptr(), sizeof(ClientPktHeader)); - ClientPktHeader& header = *((ClientPktHeader*) m_Header.rd_ptr()); + ClientPktHeader& header = *((ClientPktHeader*)m_Header.rd_ptr()); EndianConvertReverse(header.size); EndianConvert(header.cmd); - if ((header.size < 4) || (header.size > 10240) || (header.cmd > 10240)) + if ((header.size < 4) || (header.size > 10240) || (header.cmd > 0xFFFF && (header.cmd >> 16) != 0x4C52)) // LR (from MSG_VERIFY_CONNECTIVITY) { Player* _player = m_Session ? m_Session->GetPlayer() : NULL; sLog->outError(LOG_FILTER_GENERAL, "WorldSocket::handle_input_header(): client (account: %u, char [GUID: %u, name: %s]) sent malformed packet (size: %d, cmd: %d)", @@ -513,11 +516,11 @@ int WorldSocket::handle_input_header (void) header.size -= 4; - ACE_NEW_RETURN (m_RecvWPct, WorldPacket ((uint16) header.cmd, header.size), -1); + ACE_NEW_RETURN(m_RecvWPct, WorldPacket (PacketFilter::DropHighBytes(Opcodes(header.cmd)), header.size), -1); if (header.size > 0) { - m_RecvWPct->resize (header.size); + m_RecvWPct->resize(header.size); m_RecvPct.base ((char*) m_RecvWPct->contents(), m_RecvWPct->size()); } else @@ -684,9 +687,9 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct) ACE_ASSERT (new_pct); // manage memory ;) - ACE_Auto_Ptr<WorldPacket> aptr (new_pct); + ACE_Auto_Ptr<WorldPacket> aptr(new_pct); - const ACE_UINT16 opcode = new_pct->GetOpcode(); + const ACE_UINT16 opcode = PacketFilter::DropHighBytes(new_pct->GetOpcode()); if (closing_) return -1; @@ -716,29 +719,57 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct) sLog->outTrace(LOG_FILTER_NETWORKIO, "%s", data.c_str()); } + sLog->outOpCode(uint32(Opcodes(opcode)), LookupOpcodeName(Opcodes(opcode)), false); + try { switch (opcode) { case CMSG_PING: - return HandlePing (*new_pct); + return HandlePing(*new_pct); case CMSG_AUTH_SESSION: if (m_Session) { - sLog->outError(LOG_FILTER_GENERAL, "WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again"); + sLog->outError(LOG_FILTER_NETWORKIO, "WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again"); return -1; } sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct)); - return HandleAuthSession (*new_pct); + return HandleAuthSession(*new_pct); case CMSG_KEEP_ALIVE: - sLog->outDebug(LOG_FILTER_GENERAL, "CMSG_KEEP_ALIVE, size: " UI64FMTD, uint64(new_pct->size())); + sLog->outInfo(LOG_FILTER_NETWORKIO, "CMSG_KEEP_ALIVE, size: " UI64FMTD, uint64(new_pct->size())); sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct)); return 0; + case CMSG_LOG_DISCONNECT: + new_pct->rfinish(); // contains uint32 disconnectReason; + sLog->outInfo(LOG_FILTER_NETWORKIO, "CMSG_LOG_DISCONNECT , size: " UI64FMTD, uint64(new_pct->size())); + sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct)); + return 0; + // not an opcode, client sends string "WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER" without opcode + // first 4 bytes become the opcode (2 dropped) + case MSG_VERIFY_CONNECTIVITY: + { + sLog->outInfo(LOG_FILTER_NETWORKIO, "MSG_VERIFY_CONNECTIVITY , size: " UI64FMTD, uint64(new_pct->size())); + sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct)); + std::string str; + *new_pct >> str; + if (str != "D OF WARCRAFT CONNECTION - CLIENT TO SERVER") + return -1; + return HandleSendAuthSession(); + } + case CMSG_ENABLE_NAGLE: + { + sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct)); + return m_Session ? m_Session->HandleEnableNagleAlgorithm() : -1; + } default: { - ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1); - + ACE_GUARD_RETURN(LockType, Guard, m_SessionLock, -1); + if (!opcodeTable[Opcodes(opcode)]) + { + sLog->outError(LOG_FILTER_NETWORKIO, "Opcode with no defined handler received from client: %u", new_pct->GetOpcode()); + return 0; + } if (m_Session != NULL) { // Our Idle timer will reset on any non PING opcodes. @@ -749,7 +780,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct) aptr.release(); // WARNINIG here we call it with locks held. // Its possible to cause deadlock if QueuePacket calls back - m_Session->QueuePacket (new_pct); + m_Session->QueuePacket(new_pct); return 0; } else @@ -776,27 +807,80 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct) ACE_NOTREACHED (return 0); } +int WorldSocket::HandleSendAuthSession() +{ + WorldPacket packet(SMSG_AUTH_CHALLENGE, 37); + BigNumber seed1; + seed1.SetRand(16 * 8); + packet.append(seed1.AsByteArray(16), 16); // new encryption seeds + + BigNumber seed2; + seed2.SetRand(16 * 8); + packet.append(seed2.AsByteArray(16), 16); // new encryption seeds + + packet << m_Seed; + packet << uint8(1); + return SendPacket(packet); +} + int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { - // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed; - uint32 unk2, unk3, unk5, unk6, unk7; - uint64 unk4; - uint32 BuiltNumberClient; - uint32 id, security; - //uint8 expansion = 0; + uint16 clientBuild, security; + uint32 id; + uint32 addonSize; LocaleConstant locale; std::string account; SHA1Hash sha; - BigNumber v, s, g, N; - WorldPacket packet, SendAddonPacked; - BigNumber k; + WorldPacket addonsData; + + recvPacket.read_skip<uint32>(); + recvPacket.read_skip<uint32>(); + recvPacket.read_skip<uint8>(); + recvPacket >> digest[10]; + recvPacket >> digest[18]; + recvPacket >> digest[12]; + recvPacket >> digest[5]; + recvPacket.read_skip<uint64>(); + recvPacket >> digest[15]; + recvPacket >> digest[9]; + recvPacket >> digest[19]; + recvPacket >> digest[4]; + recvPacket >> digest[7]; + recvPacket >> digest[16]; + recvPacket >> digest[3]; + recvPacket >> clientBuild; + recvPacket >> digest[8]; + recvPacket.read_skip<uint32>(); + recvPacket.read_skip<uint8>(); + recvPacket >> digest[17]; + recvPacket >> digest[6]; + recvPacket >> digest[0]; + recvPacket >> digest[1]; + recvPacket >> digest[11]; + recvPacket >> clientSeed; + recvPacket >> digest[2]; + recvPacket.read_skip<uint32>(); + recvPacket >> digest[14]; + recvPacket >> digest[13]; + + recvPacket >> addonSize; + addonsData.resize(addonSize); + recvPacket.read((uint8*)addonsData.contents(), addonSize); + + uint8 highBitsAccountLen; + uint8 lowBitsAccountLen; + recvPacket >> highBitsAccountLen; + recvPacket >> lowBitsAccountLen; + account = recvPacket.ReadString(((highBitsAccountLen << 5) & 0xFF) | (lowBitsAccountLen >> 3)); if (sWorld->IsClosed()) { - packet.Initialize(SMSG_AUTH_RESPONSE, 1); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info packet << uint8(AUTH_REJECT); SendPacket(packet); @@ -804,23 +888,6 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) return -1; } - // Read the content of the packet - recvPacket >> BuiltNumberClient; // for now no use - recvPacket >> unk2; - recvPacket >> account; - recvPacket >> unk3; - recvPacket >> clientSeed; - recvPacket >> unk5 >> unk6 >> unk7; - recvPacket >> unk4; - recvPacket.read(digest, 20); - - sLog->outDebug(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, unk3 %u, clientseed %u", - BuiltNumberClient, - unk2, - account.c_str(), - unk3, - clientSeed); - // Get the account information from the realmd database PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); @@ -831,8 +898,10 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // Stop if the account is not found if (!result) { - packet.Initialize (SMSG_AUTH_RESPONSE, 1); - packet << uint8 (AUTH_UNKNOWN_ACCOUNT); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info + packet << uint8(AUTH_UNKNOWN_ACCOUNT); SendPacket(packet); @@ -847,29 +916,19 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) if (expansion > world_expansion) expansion = world_expansion; - N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); - g.SetDword (7); - - v.SetHexStr(fields[4].GetCString()); - s.SetHexStr (fields[5].GetCString()); - - const char* sStr = s.AsHexStr(); //Must be freed by OPENSSL_free() - const char* vStr = v.AsHexStr(); //Must be freed by OPENSSL_free() - - sLog->outDebug(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: (s, v) check s: %s v: %s", - sStr, - vStr); - - OPENSSL_free ((void*) sStr); - OPENSSL_free ((void*) vStr); + sLog->outDebug(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", + fields[5].GetCString(), + fields[4].GetCString()); ///- Re-check ip locking (same check as in realmd). if (fields[3].GetUInt8() == 1) // if ip is locked { if (strcmp (fields[2].GetCString(), GetRemoteAddress().c_str())) { - packet.Initialize (SMSG_AUTH_RESPONSE, 1); - packet << uint8 (AUTH_FAILED); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info + packet << uint8(AUTH_FAILED); SendPacket(packet); sLog->outDebug(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); @@ -883,7 +942,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) security = SEC_ADMINISTRATOR; */ - k.SetHexStr (fields[1].GetCString()); + k.SetHexStr(fields[1].GetCString()); int64 mutetime = fields[7].GetInt64(); //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. @@ -932,8 +991,10 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) if (banresult) // if account banned { - packet.Initialize (SMSG_AUTH_RESPONSE, 1); - packet << uint8 (AUTH_BANNED); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info + packet << uint8(AUTH_BANNED); SendPacket(packet); sLog->outError(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); @@ -943,10 +1004,12 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // Check locked state for server AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); sLog->outDebug(LOG_FILTER_NETWORKIO, "Allowed Level: %u Player Level %u", allowedAccountType, AccountTypes(security)); - if (AccountTypes(security) < allowedAccountType) + if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { - WorldPacket Packet (SMSG_AUTH_RESPONSE, 1); - Packet << uint8 (AUTH_UNAVAILABLE); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info + packet << uint8(AUTH_UNAVAILABLE); SendPacket(packet); @@ -958,20 +1021,21 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) uint32 t = 0; uint32 seed = m_Seed; - sha.UpdateData (account); - sha.UpdateData ((uint8 *) & t, 4); - sha.UpdateData ((uint8 *) & clientSeed, 4); - sha.UpdateData ((uint8 *) & seed, 4); - sha.UpdateBigNumbers (&k, NULL); + sha.UpdateData(account); + sha.UpdateData((uint8*)&t, 4); + sha.UpdateData((uint8*)&clientSeed, 4); + sha.UpdateData((uint8*)&seed, 4); + sha.UpdateBigNumbers(&k, NULL); sha.Finalize(); std::string address = GetRemoteAddress(); - if (memcmp (sha.GetDigest(), digest, 20)) + if (memcmp(sha.GetDigest(), digest, 20)) { - packet.Initialize (SMSG_AUTH_RESPONSE, 1); - packet << uint8 (AUTH_FAILED); - + WorldPacket packet(SMSG_AUTH_RESPONSE, 1); + packet.WriteBit(0); // has queue info + packet.WriteBit(0); // has account info + packet << uint8(AUTH_FAILED); SendPacket(packet); sLog->outError(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str()); @@ -979,8 +1043,8 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) } sLog->outDebug(LOG_FILTER_GENERAL, "WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", - account.c_str(), - address.c_str()); + account.c_str(), + address.c_str()); // Check if this user is by any chance a recruiter stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_RECRUITER); @@ -1003,13 +1067,13 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) LoginDatabase.Execute(stmt); // NOTE ATM the socket is single-threaded, have this in mind ... - ACE_NEW_RETURN (m_Session, WorldSession (id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); + ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); m_Crypt.Init(&k); m_Session->LoadGlobalAccountData(); m_Session->LoadTutorialsData(); - m_Session->ReadAddonsInfo(recvPacket); + m_Session->ReadAddonsInfo(addonsData); // Initialize Warden system only if it is enabled by config if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED)) @@ -1017,10 +1081,9 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // Sleep this Network thread for uint32 sleepTime = sWorld->getIntConfig(CONFIG_SESSION_ADD_DELAY); - ACE_OS::sleep (ACE_Time_Value (0, sleepTime)); - - sWorld->AddSession (m_Session); + ACE_OS::sleep(ACE_Time_Value(0, sleepTime)); + sWorld->AddSession(m_Session); return 0; } @@ -1030,8 +1093,8 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) uint32 latency; // Get the ping packet content - recvPacket >> ping; recvPacket >> latency; + recvPacket >> ping; if (m_LastPingTime == ACE_Time_Value::zero) m_LastPingTime = ACE_OS::gettimeofday(); // for 1st ping @@ -1085,7 +1148,7 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket) } } - WorldPacket packet (SMSG_PONG, 4); + WorldPacket packet(SMSG_PONG, 4); packet << ping; return SendPacket(packet); } diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index b8080b128f2..3a256c07095 100755 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -161,6 +161,9 @@ class WorldSocket : public WorldHandler /// Called by ProcessIncoming() on CMSG_PING. int HandlePing (WorldPacket& recvPacket); + /// Called by CMSG_VERIFY_CONNECTIVITY_RESPONSE + int HandleSendAuthSession(); + private: /// Time in which the last ping was received ACE_Time_Value m_LastPingTime; diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index ddb230d6773..c8e41d1fcfa 100755 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -59,324 +59,370 @@ enum DAMAGE_ABSORB_TYPE enum AuraType { - SPELL_AURA_NONE = 0, - SPELL_AURA_BIND_SIGHT = 1, - SPELL_AURA_MOD_POSSESS = 2, - SPELL_AURA_PERIODIC_DAMAGE = 3, - SPELL_AURA_DUMMY = 4, - SPELL_AURA_MOD_CONFUSE = 5, - SPELL_AURA_MOD_CHARM = 6, - SPELL_AURA_MOD_FEAR = 7, - SPELL_AURA_PERIODIC_HEAL = 8, - SPELL_AURA_MOD_ATTACKSPEED = 9, - SPELL_AURA_MOD_THREAT = 10, - SPELL_AURA_MOD_TAUNT = 11, - SPELL_AURA_MOD_STUN = 12, - SPELL_AURA_MOD_DAMAGE_DONE = 13, - SPELL_AURA_MOD_DAMAGE_TAKEN = 14, - SPELL_AURA_DAMAGE_SHIELD = 15, - SPELL_AURA_MOD_STEALTH = 16, - SPELL_AURA_MOD_STEALTH_DETECT = 17, - SPELL_AURA_MOD_INVISIBILITY = 18, - SPELL_AURA_MOD_INVISIBILITY_DETECT = 19, - SPELL_AURA_OBS_MOD_HEALTH = 20, //20, 21 unofficial - SPELL_AURA_OBS_MOD_POWER = 21, - SPELL_AURA_MOD_RESISTANCE = 22, - SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23, - SPELL_AURA_PERIODIC_ENERGIZE = 24, - SPELL_AURA_MOD_PACIFY = 25, - SPELL_AURA_MOD_ROOT = 26, - SPELL_AURA_MOD_SILENCE = 27, - SPELL_AURA_REFLECT_SPELLS = 28, - SPELL_AURA_MOD_STAT = 29, - SPELL_AURA_MOD_SKILL = 30, - SPELL_AURA_MOD_INCREASE_SPEED = 31, - SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32, - SPELL_AURA_MOD_DECREASE_SPEED = 33, - SPELL_AURA_MOD_INCREASE_HEALTH = 34, - SPELL_AURA_MOD_INCREASE_ENERGY = 35, - SPELL_AURA_MOD_SHAPESHIFT = 36, - SPELL_AURA_EFFECT_IMMUNITY = 37, - SPELL_AURA_STATE_IMMUNITY = 38, - SPELL_AURA_SCHOOL_IMMUNITY = 39, - SPELL_AURA_DAMAGE_IMMUNITY = 40, - SPELL_AURA_DISPEL_IMMUNITY = 41, - SPELL_AURA_PROC_TRIGGER_SPELL = 42, - SPELL_AURA_PROC_TRIGGER_DAMAGE = 43, - SPELL_AURA_TRACK_CREATURES = 44, - SPELL_AURA_TRACK_RESOURCES = 45, - SPELL_AURA_46 = 46, // Ignore all Gear test spells - SPELL_AURA_MOD_PARRY_PERCENT = 47, - SPELL_AURA_48 = 48, // One periodic spell - SPELL_AURA_MOD_DODGE_PERCENT = 49, - SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50, - SPELL_AURA_MOD_BLOCK_PERCENT = 51, - SPELL_AURA_MOD_WEAPON_CRIT_PERCENT = 52, - SPELL_AURA_PERIODIC_LEECH = 53, - SPELL_AURA_MOD_HIT_CHANCE = 54, - SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55, - SPELL_AURA_TRANSFORM = 56, - SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57, - SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58, - SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59, - SPELL_AURA_MOD_PACIFY_SILENCE = 60, - SPELL_AURA_MOD_SCALE = 61, - SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62, - SPELL_AURA_63 = 63, // old SPELL_AURA_PERIODIC_MANA_FUNNEL - SPELL_AURA_PERIODIC_MANA_LEECH = 64, - SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65, - SPELL_AURA_FEIGN_DEATH = 66, - SPELL_AURA_MOD_DISARM = 67, - SPELL_AURA_MOD_STALKED = 68, - SPELL_AURA_SCHOOL_ABSORB = 69, - SPELL_AURA_EXTRA_ATTACKS = 70, - SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71, - SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT = 72, - SPELL_AURA_MOD_POWER_COST_SCHOOL = 73, - SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74, - SPELL_AURA_MOD_LANGUAGE = 75, - SPELL_AURA_FAR_SIGHT = 76, - SPELL_AURA_MECHANIC_IMMUNITY = 77, - SPELL_AURA_MOUNTED = 78, - SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79, - SPELL_AURA_MOD_PERCENT_STAT = 80, - SPELL_AURA_SPLIT_DAMAGE_PCT = 81, - SPELL_AURA_WATER_BREATHING = 82, - SPELL_AURA_MOD_BASE_RESISTANCE = 83, - SPELL_AURA_MOD_REGEN = 84, - SPELL_AURA_MOD_POWER_REGEN = 85, - SPELL_AURA_CHANNEL_DEATH_ITEM = 86, - SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87, - SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88, - SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89, - SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE - SPELL_AURA_MOD_DETECT_RANGE = 91, - SPELL_AURA_PREVENTS_FLEEING = 92, - SPELL_AURA_MOD_UNATTACKABLE = 93, - SPELL_AURA_INTERRUPT_REGEN = 94, - SPELL_AURA_GHOST = 95, - SPELL_AURA_SPELL_MAGNET = 96, - SPELL_AURA_MANA_SHIELD = 97, - SPELL_AURA_MOD_SKILL_TALENT = 98, - SPELL_AURA_MOD_ATTACK_POWER = 99, - SPELL_AURA_AURAS_VISIBLE = 100, - SPELL_AURA_MOD_RESISTANCE_PCT = 101, - SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS = 102, - SPELL_AURA_MOD_TOTAL_THREAT = 103, - SPELL_AURA_WATER_WALK = 104, - SPELL_AURA_FEATHER_FALL = 105, - SPELL_AURA_HOVER = 106, - SPELL_AURA_ADD_FLAT_MODIFIER = 107, - SPELL_AURA_ADD_PCT_MODIFIER = 108, - SPELL_AURA_ADD_TARGET_TRIGGER = 109, - SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110, - SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111, - SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112, - SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113, - SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114, - SPELL_AURA_MOD_HEALING = 115, - SPELL_AURA_MOD_REGEN_DURING_COMBAT = 116, - SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117, - SPELL_AURA_MOD_HEALING_PCT = 118, - SPELL_AURA_119 = 119, // old SPELL_AURA_SHARE_PET_TRACKING - SPELL_AURA_UNTRACKABLE = 120, - SPELL_AURA_EMPATHY = 121, - SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122, - SPELL_AURA_MOD_TARGET_RESISTANCE = 123, - SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124, - SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125, - SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126, - SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127, - SPELL_AURA_MOD_POSSESS_PET = 128, - SPELL_AURA_MOD_SPEED_ALWAYS = 129, - SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130, - SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS = 131, - SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132, - SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133, - SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134, - SPELL_AURA_MOD_HEALING_DONE = 135, - SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136, - SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137, - SPELL_AURA_MOD_MELEE_HASTE = 138, - SPELL_AURA_FORCE_REACTION = 139, - SPELL_AURA_MOD_RANGED_HASTE = 140, - SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141, - SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142, - SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143, - SPELL_AURA_SAFE_FALL = 144, - SPELL_AURA_MOD_PET_TALENT_POINTS = 145, - SPELL_AURA_ALLOW_TAME_PET_TYPE = 146, - SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147, - SPELL_AURA_RETAIN_COMBO_POINTS = 148, - SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback - SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, - SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed - SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range - SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat - SPELL_AURA_MOD_STEALTH_LEVEL = 154, // Stealth Level Modifier - SPELL_AURA_MOD_WATER_BREATHING = 155, // Mod Water Breathing - SPELL_AURA_MOD_REPUTATION_GAIN = 156, // Mod Reputation Gain - SPELL_AURA_PET_DAMAGE_MULTI = 157, // Mod Pet Damage - SPELL_AURA_MOD_SHIELD_BLOCKVALUE = 158, - SPELL_AURA_NO_PVP_CREDIT = 159, - SPELL_AURA_MOD_AOE_AVOIDANCE = 160, - SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161, - SPELL_AURA_POWER_BURN = 162, - SPELL_AURA_MOD_CRIT_DAMAGE_BONUS = 163, - SPELL_AURA_164 = 164, - SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS = 165, - SPELL_AURA_MOD_ATTACK_POWER_PCT = 166, - SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT = 167, - SPELL_AURA_MOD_DAMAGE_DONE_VERSUS = 168, - SPELL_AURA_MOD_CRIT_PERCENT_VERSUS = 169, - SPELL_AURA_DETECT_AMORE = 170, - SPELL_AURA_MOD_SPEED_NOT_STACK = 171, - SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172, - SPELL_AURA_173 = 173, // old SPELL_AURA_ALLOW_CHAMPION_SPELLS - SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT - SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175, - SPELL_AURA_SPIRIT_OF_REDEMPTION = 176, - SPELL_AURA_AOE_CHARM = 177, - SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178, - SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179, - SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180, - SPELL_AURA_181 = 181, // old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS - possible flat spell crit damage versus - SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT = 182, - SPELL_AURA_MOD_CRITICAL_THREAT = 183, - SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE = 184, - SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE= 185, - SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE = 186, - SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE = 187, - SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE = 188, - SPELL_AURA_MOD_RATING = 189, - SPELL_AURA_MOD_FACTION_REPUTATION_GAIN = 190, - SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191, - SPELL_AURA_MOD_MELEE_RANGED_HASTE = 192, - SPELL_AURA_MELEE_SLOW = 193, - SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194, - SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195, - SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath - SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197, - SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS - SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199, - SPELL_AURA_MOD_XP_PCT = 200, - SPELL_AURA_FLY = 201, - SPELL_AURA_IGNORE_COMBAT_RESULT = 202, - SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE = 203, - SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE = 204, - SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN = 205, - SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED = 206, - SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED = 207, - SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 208, - SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS = 209, - SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS = 210, - SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK = 211, - SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT = 212, - SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT = 213, - SPELL_AURA_214 = 214, - SPELL_AURA_ARENA_PREPARATION = 215, - SPELL_AURA_HASTE_SPELLS = 216, - SPELL_AURA_MOD_MELEE_HASTE_2 = 217, // NYI - SPELL_AURA_HASTE_RANGED = 218, - SPELL_AURA_MOD_MANA_REGEN_FROM_STAT = 219, - SPELL_AURA_MOD_RATING_FROM_STAT = 220, - SPELL_AURA_MOD_DETAUNT = 221, - SPELL_AURA_222 = 222, - SPELL_AURA_RAID_PROC_FROM_CHARGE = 223, - SPELL_AURA_224 = 224, - SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE = 225, - SPELL_AURA_PERIODIC_DUMMY = 226, - SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227, - SPELL_AURA_DETECT_STEALTH = 228, - SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229, - SPELL_AURA_230 = 230, - SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231, - SPELL_AURA_MECHANIC_DURATION_MOD = 232, - SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS = 233, // client-side only - SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234, - SPELL_AURA_MOD_DISPEL_RESIST = 235, - SPELL_AURA_CONTROL_VEHICLE = 236, - SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237, - SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238, - SPELL_AURA_MOD_SCALE_2 = 239, - SPELL_AURA_MOD_EXPERTISE = 240, - SPELL_AURA_FORCE_MOVE_FORWARD = 241, - SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242, - SPELL_AURA_MOD_FACTION = 243, - SPELL_AURA_COMPREHEND_LANGUAGE = 244, - SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245, - SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246, - SPELL_AURA_CLONE_CASTER = 247, - SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248, - SPELL_AURA_CONVERT_RUNE = 249, - SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250, - SPELL_AURA_MOD_ENEMY_DODGE = 251, - SPELL_AURA_MOD_SPEED_SLOW_ALL = 252, - SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253, - SPELL_AURA_MOD_DISARM_OFFHAND = 254, - SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255, - SPELL_AURA_NO_REAGENT_USE = 256, - SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257, - SPELL_AURA_258 = 258, - SPELL_AURA_MOD_HOT_PCT = 259, - SPELL_AURA_SCREEN_EFFECT = 260, - SPELL_AURA_PHASE = 261, - SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262, - SPELL_AURA_ALLOW_ONLY_ABILITY = 263, - SPELL_AURA_264 = 264, - SPELL_AURA_265 = 265, - SPELL_AURA_266 = 266, - SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267, - SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, - SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269, - SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive - SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271, - SPELL_AURA_IGNORE_MELEE_RESET = 272, - SPELL_AURA_X_RAY = 273, - SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274, - SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275, - SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC = 276, // NYI - SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277, - SPELL_AURA_MOD_DISARM_RANGED = 278, - SPELL_AURA_INITIALIZE_IMAGES = 279, - SPELL_AURA_MOD_ARMOR_PENETRATION_PCT = 280, - SPELL_AURA_MOD_HONOR_GAIN_PCT = 281, - SPELL_AURA_MOD_BASE_HEALTH_PCT = 282, - SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells - SPELL_AURA_LINKED = 284, - SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR = 285, - SPELL_AURA_ABILITY_PERIODIC_CRIT = 286, - SPELL_AURA_DEFLECT_SPELLS = 287, - SPELL_AURA_IGNORE_HIT_DIRECTION = 288, - SPELL_AURA_289 = 289, - SPELL_AURA_MOD_CRIT_PCT = 290, - SPELL_AURA_MOD_XP_QUEST_PCT = 291, - SPELL_AURA_OPEN_STABLE = 292, - SPELL_AURA_OVERRIDE_SPELLS = 293, - SPELL_AURA_PREVENT_REGENERATE_POWER = 294, - SPELL_AURA_295 = 295, - SPELL_AURA_SET_VEHICLE_ID = 296, - SPELL_AURA_BLOCK_SPELL_FAMILY = 297, - SPELL_AURA_STRANGULATE = 298, - SPELL_AURA_299 = 299, - SPELL_AURA_SHARE_DAMAGE_PCT = 300, - SPELL_AURA_SCHOOL_HEAL_ABSORB = 301, - SPELL_AURA_302 = 302, - SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE = 303, - SPELL_AURA_MOD_FAKE_INEBRIATE = 304, - SPELL_AURA_MOD_MINIMUM_SPEED = 305, - SPELL_AURA_306 = 306, - SPELL_AURA_HEAL_ABSORB_TEST = 307, - SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER = 308, // NYI - SPELL_AURA_309 = 309, - SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE = 310, - SPELL_AURA_311 = 311, - SPELL_AURA_312 = 312, - SPELL_AURA_313 = 313, - SPELL_AURA_PREVENT_RESURRECTION = 314, - SPELL_AURA_UNDERWATER_WALKING = 315, - SPELL_AURA_PERIODIC_HASTE = 316, - TOTAL_AURAS = 317 + SPELL_AURA_NONE = 0, + SPELL_AURA_BIND_SIGHT = 1, + SPELL_AURA_MOD_POSSESS = 2, + SPELL_AURA_PERIODIC_DAMAGE = 3, + SPELL_AURA_DUMMY = 4, + SPELL_AURA_MOD_CONFUSE = 5, + SPELL_AURA_MOD_CHARM = 6, + SPELL_AURA_MOD_FEAR = 7, + SPELL_AURA_PERIODIC_HEAL = 8, + SPELL_AURA_MOD_ATTACKSPEED = 9, + SPELL_AURA_MOD_THREAT = 10, + SPELL_AURA_MOD_TAUNT = 11, + SPELL_AURA_MOD_STUN = 12, + SPELL_AURA_MOD_DAMAGE_DONE = 13, + SPELL_AURA_MOD_DAMAGE_TAKEN = 14, + SPELL_AURA_DAMAGE_SHIELD = 15, + SPELL_AURA_MOD_STEALTH = 16, + SPELL_AURA_MOD_STEALTH_DETECT = 17, + SPELL_AURA_MOD_INVISIBILITY = 18, + SPELL_AURA_MOD_INVISIBILITY_DETECT = 19, + SPELL_AURA_OBS_MOD_HEALTH = 20, // 20, 21 unofficial + SPELL_AURA_OBS_MOD_POWER = 21, + SPELL_AURA_MOD_RESISTANCE = 22, + SPELL_AURA_PERIODIC_TRIGGER_SPELL = 23, + SPELL_AURA_PERIODIC_ENERGIZE = 24, + SPELL_AURA_MOD_PACIFY = 25, + SPELL_AURA_MOD_ROOT = 26, + SPELL_AURA_MOD_SILENCE = 27, + SPELL_AURA_REFLECT_SPELLS = 28, + SPELL_AURA_MOD_STAT = 29, + SPELL_AURA_MOD_SKILL = 30, + SPELL_AURA_MOD_INCREASE_SPEED = 31, + SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED = 32, + SPELL_AURA_MOD_DECREASE_SPEED = 33, + SPELL_AURA_MOD_INCREASE_HEALTH = 34, + SPELL_AURA_MOD_INCREASE_ENERGY = 35, + SPELL_AURA_MOD_SHAPESHIFT = 36, + SPELL_AURA_EFFECT_IMMUNITY = 37, + SPELL_AURA_STATE_IMMUNITY = 38, + SPELL_AURA_SCHOOL_IMMUNITY = 39, + SPELL_AURA_DAMAGE_IMMUNITY = 40, + SPELL_AURA_DISPEL_IMMUNITY = 41, + SPELL_AURA_PROC_TRIGGER_SPELL = 42, + SPELL_AURA_PROC_TRIGGER_DAMAGE = 43, + SPELL_AURA_TRACK_CREATURES = 44, + SPELL_AURA_TRACK_RESOURCES = 45, + SPELL_AURA_46 = 46, // Ignore all Gear test spells + SPELL_AURA_MOD_PARRY_PERCENT = 47, + SPELL_AURA_48 = 48, // One periodic spell + SPELL_AURA_MOD_DODGE_PERCENT = 49, + SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50, + SPELL_AURA_MOD_BLOCK_PERCENT = 51, + SPELL_AURA_MOD_WEAPON_CRIT_PERCENT = 52, + SPELL_AURA_PERIODIC_LEECH = 53, + SPELL_AURA_MOD_HIT_CHANCE = 54, + SPELL_AURA_MOD_SPELL_HIT_CHANCE = 55, + SPELL_AURA_TRANSFORM = 56, + SPELL_AURA_MOD_SPELL_CRIT_CHANCE = 57, + SPELL_AURA_MOD_INCREASE_SWIM_SPEED = 58, + SPELL_AURA_MOD_DAMAGE_DONE_CREATURE = 59, + SPELL_AURA_MOD_PACIFY_SILENCE = 60, + SPELL_AURA_MOD_SCALE = 61, + SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62, + SPELL_AURA_63 = 63, // old SPELL_AURA_PERIODIC_MANA_FUNNEL + SPELL_AURA_PERIODIC_MANA_LEECH = 64, + SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65, + SPELL_AURA_FEIGN_DEATH = 66, + SPELL_AURA_MOD_DISARM = 67, + SPELL_AURA_MOD_STALKED = 68, + SPELL_AURA_SCHOOL_ABSORB = 69, + SPELL_AURA_EXTRA_ATTACKS = 70, + SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL = 71, + SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT = 72, + SPELL_AURA_MOD_POWER_COST_SCHOOL = 73, + SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74, + SPELL_AURA_MOD_LANGUAGE = 75, + SPELL_AURA_FAR_SIGHT = 76, + SPELL_AURA_MECHANIC_IMMUNITY = 77, + SPELL_AURA_MOUNTED = 78, + SPELL_AURA_MOD_DAMAGE_PERCENT_DONE = 79, + SPELL_AURA_MOD_PERCENT_STAT = 80, + SPELL_AURA_SPLIT_DAMAGE_PCT = 81, + SPELL_AURA_WATER_BREATHING = 82, + SPELL_AURA_MOD_BASE_RESISTANCE = 83, + SPELL_AURA_MOD_REGEN = 84, + SPELL_AURA_MOD_POWER_REGEN = 85, + SPELL_AURA_CHANNEL_DEATH_ITEM = 86, + SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN = 87, + SPELL_AURA_MOD_HEALTH_REGEN_PERCENT = 88, + SPELL_AURA_PERIODIC_DAMAGE_PERCENT = 89, + SPELL_AURA_90 = 90, // old SPELL_AURA_MOD_RESIST_CHANCE + SPELL_AURA_MOD_DETECT_RANGE = 91, + SPELL_AURA_PREVENTS_FLEEING = 92, + SPELL_AURA_MOD_UNATTACKABLE = 93, + SPELL_AURA_INTERRUPT_REGEN = 94, + SPELL_AURA_GHOST = 95, + SPELL_AURA_SPELL_MAGNET = 96, + SPELL_AURA_MANA_SHIELD = 97, + SPELL_AURA_MOD_SKILL_TALENT = 98, + SPELL_AURA_MOD_ATTACK_POWER = 99, + SPELL_AURA_AURAS_VISIBLE = 100, + SPELL_AURA_MOD_RESISTANCE_PCT = 101, + SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS = 102, + SPELL_AURA_MOD_TOTAL_THREAT = 103, + SPELL_AURA_WATER_WALK = 104, + SPELL_AURA_FEATHER_FALL = 105, + SPELL_AURA_HOVER = 106, + SPELL_AURA_ADD_FLAT_MODIFIER = 107, + SPELL_AURA_ADD_PCT_MODIFIER = 108, + SPELL_AURA_ADD_TARGET_TRIGGER = 109, + SPELL_AURA_MOD_POWER_REGEN_PERCENT = 110, + SPELL_AURA_ADD_CASTER_HIT_TRIGGER = 111, + SPELL_AURA_OVERRIDE_CLASS_SCRIPTS = 112, + SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN = 113, + SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT = 114, + SPELL_AURA_MOD_HEALING = 115, + SPELL_AURA_MOD_REGEN_DURING_COMBAT = 116, + SPELL_AURA_MOD_MECHANIC_RESISTANCE = 117, + SPELL_AURA_MOD_HEALING_PCT = 118, + SPELL_AURA_119 = 119, // old SPELL_AURA_SHARE_PET_TRACKING + SPELL_AURA_UNTRACKABLE = 120, + SPELL_AURA_EMPATHY = 121, + SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT = 122, + SPELL_AURA_MOD_TARGET_RESISTANCE = 123, + SPELL_AURA_MOD_RANGED_ATTACK_POWER = 124, + SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN = 125, + SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT = 126, + SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS = 127, + SPELL_AURA_MOD_POSSESS_PET = 128, + SPELL_AURA_MOD_SPEED_ALWAYS = 129, + SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS = 130, + SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS = 131, + SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT = 132, + SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT = 133, + SPELL_AURA_MOD_MANA_REGEN_INTERRUPT = 134, + SPELL_AURA_MOD_HEALING_DONE = 135, + SPELL_AURA_MOD_HEALING_DONE_PERCENT = 136, + SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE = 137, + SPELL_AURA_MOD_MELEE_HASTE = 138, + SPELL_AURA_FORCE_REACTION = 139, + SPELL_AURA_MOD_RANGED_HASTE = 140, + SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141, + SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142, + SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143, + SPELL_AURA_SAFE_FALL = 144, + SPELL_AURA_MOD_PET_TALENT_POINTS = 145, + SPELL_AURA_ALLOW_TAME_PET_TYPE = 146, + SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147, + SPELL_AURA_RETAIN_COMBO_POINTS = 148, + SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback + SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, + SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed + SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range + SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat + SPELL_AURA_MOD_STEALTH_LEVEL = 154, // Stealth Level Modifier + SPELL_AURA_MOD_WATER_BREATHING = 155, // Mod Water Breathing + SPELL_AURA_MOD_REPUTATION_GAIN = 156, // Mod Reputation Gain + SPELL_AURA_PET_DAMAGE_MULTI = 157, // Mod Pet Damage + SPELL_AURA_MOD_SHIELD_BLOCKVALUE = 158, + SPELL_AURA_NO_PVP_CREDIT = 159, + SPELL_AURA_MOD_AOE_AVOIDANCE = 160, + SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161, + SPELL_AURA_POWER_BURN = 162, + SPELL_AURA_MOD_CRIT_DAMAGE_BONUS = 163, + SPELL_AURA_164 = 164, + SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS = 165, + SPELL_AURA_MOD_ATTACK_POWER_PCT = 166, + SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT = 167, + SPELL_AURA_MOD_DAMAGE_DONE_VERSUS = 168, + SPELL_AURA_MOD_CRIT_PERCENT_VERSUS = 169, + SPELL_AURA_DETECT_AMORE = 170, + SPELL_AURA_MOD_SPEED_NOT_STACK = 171, + SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172, + SPELL_AURA_173 = 173, // old SPELL_AURA_ALLOW_CHAMPION_SPELLS + SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT + SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175, + SPELL_AURA_SPIRIT_OF_REDEMPTION = 176, + SPELL_AURA_AOE_CHARM = 177, + SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178, + SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179, + SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180, + SPELL_AURA_181 = 181, // old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS - possible flat spell crit damage versus + SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT = 182, + SPELL_AURA_MOD_CRITICAL_THREAT = 183, + SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE = 184, + SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE = 185, + SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE = 186, + SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE = 187, + SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE = 188, + SPELL_AURA_MOD_RATING = 189, + SPELL_AURA_MOD_FACTION_REPUTATION_GAIN = 190, + SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191, + SPELL_AURA_MOD_MELEE_RANGED_HASTE = 192, + SPELL_AURA_MELEE_SLOW = 193, + SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL = 194, + SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL = 195, + SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath + SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197, + SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS + SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199, + SPELL_AURA_MOD_XP_PCT = 200, + SPELL_AURA_FLY = 201, + SPELL_AURA_IGNORE_COMBAT_RESULT = 202, + SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE = 203, + SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE = 204, + SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN = 205, + SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED = 206, + SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED = 207, + SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 208, + SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS = 209, + SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS = 210, + SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK = 211, + SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT = 212, + SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT = 213, + SPELL_AURA_214 = 214, + SPELL_AURA_ARENA_PREPARATION = 215, + SPELL_AURA_HASTE_SPELLS = 216, + SPELL_AURA_MOD_MELEE_HASTE_2 = 217, // NYI + SPELL_AURA_HASTE_RANGED = 218, + SPELL_AURA_MOD_MANA_REGEN_FROM_STAT = 219, + SPELL_AURA_MOD_RATING_FROM_STAT = 220, + SPELL_AURA_MOD_DETAUNT = 221, + SPELL_AURA_222 = 222, + SPELL_AURA_RAID_PROC_FROM_CHARGE = 223, + SPELL_AURA_224 = 224, + SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE = 225, + SPELL_AURA_PERIODIC_DUMMY = 226, + SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227, + SPELL_AURA_DETECT_STEALTH = 228, + SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229, + SPELL_AURA_230 = 230, + SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231, + SPELL_AURA_MECHANIC_DURATION_MOD = 232, + SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS = 233, // client-side only + SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234, + SPELL_AURA_MOD_DISPEL_RESIST = 235, + SPELL_AURA_CONTROL_VEHICLE = 236, + SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237, + SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238, + SPELL_AURA_MOD_SCALE_2 = 239, + SPELL_AURA_MOD_EXPERTISE = 240, + SPELL_AURA_FORCE_MOVE_FORWARD = 241, + SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242, + SPELL_AURA_MOD_FACTION = 243, + SPELL_AURA_COMPREHEND_LANGUAGE = 244, + SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL = 245, + SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK = 246, + SPELL_AURA_CLONE_CASTER = 247, + SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248, + SPELL_AURA_CONVERT_RUNE = 249, + SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250, + SPELL_AURA_MOD_ENEMY_DODGE = 251, + SPELL_AURA_MOD_SPEED_SLOW_ALL = 252, + SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253, + SPELL_AURA_MOD_DISARM_OFFHAND = 254, + SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255, + SPELL_AURA_NO_REAGENT_USE = 256, + SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257, + SPELL_AURA_258 = 258, + SPELL_AURA_MOD_HOT_PCT = 259, + SPELL_AURA_SCREEN_EFFECT = 260, + SPELL_AURA_PHASE = 261, + SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262, + SPELL_AURA_ALLOW_ONLY_ABILITY = 263, + SPELL_AURA_264 = 264, + SPELL_AURA_265 = 265, + SPELL_AURA_266 = 266, + SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267, + SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, + SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269, + SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive + SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271, + SPELL_AURA_IGNORE_MELEE_RESET = 272, + SPELL_AURA_X_RAY = 273, + SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274, + SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275, + SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC = 276, // NYI + SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277, + SPELL_AURA_MOD_DISARM_RANGED = 278, + SPELL_AURA_INITIALIZE_IMAGES = 279, + SPELL_AURA_MOD_ARMOR_PENETRATION_PCT = 280, + SPELL_AURA_MOD_HONOR_GAIN_PCT = 281, + SPELL_AURA_MOD_BASE_HEALTH_PCT = 282, + SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells + SPELL_AURA_LINKED = 284, + SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR = 285, + SPELL_AURA_ABILITY_PERIODIC_CRIT = 286, + SPELL_AURA_DEFLECT_SPELLS = 287, + SPELL_AURA_IGNORE_HIT_DIRECTION = 288, + SPELL_AURA_289 = 289, + SPELL_AURA_MOD_CRIT_PCT = 290, + SPELL_AURA_MOD_XP_QUEST_PCT = 291, + SPELL_AURA_OPEN_STABLE = 292, + SPELL_AURA_OVERRIDE_SPELLS = 293, + SPELL_AURA_PREVENT_REGENERATE_POWER = 294, + SPELL_AURA_295 = 295, + SPELL_AURA_SET_VEHICLE_ID = 296, + SPELL_AURA_BLOCK_SPELL_FAMILY = 297, + SPELL_AURA_STRANGULATE = 298, + SPELL_AURA_299 = 299, + SPELL_AURA_SHARE_DAMAGE_PCT = 300, + SPELL_AURA_SCHOOL_HEAL_ABSORB = 301, + SPELL_AURA_302 = 302, + SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE = 303, + SPELL_AURA_MOD_FAKE_INEBRIATE = 304, + SPELL_AURA_MOD_MINIMUM_SPEED = 305, + SPELL_AURA_306 = 306, + SPELL_AURA_HEAL_ABSORB_TEST = 307, + SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER = 308, + SPELL_AURA_309 = 309, + SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE = 310, + SPELL_AURA_311 = 311, + SPELL_AURA_312 = 312, + SPELL_AURA_313 = 313, + SPELL_AURA_PREVENT_RESURRECTION = 314, + SPELL_AURA_UNDERWATER_WALKING = 315, + SPELL_AURA_PERIODIC_HASTE = 316, + SPELL_AURA_MOD_SPELL_POWER_PCT = 317, + SPELL_AURA_MASTERY = 318, + SPELL_AURA_319 = 319, // (melee?) attack speed + SPELL_AURA_MOD_RANGED_ATTACK_SPEED = 320, // NYI + SPELL_AURA_321 = 321, + SPELL_AURA_INTERFERE_TARGETTING = 322, // NYI + SPELL_AURA_323 = 323, + SPELL_AURA_324 = 324, // spell critical chance (probably by school mask) + SPELL_AURA_325 = 325, + SPELL_AURA_326 = 326, // phase related + SPELL_AURA_327 = 327, + SPELL_AURA_328 = 328, + SPELL_AURA_MOD_RUNE_REGEN_SPEED = 329, // NYI + SPELL_AURA_CAST_WHILE_WALKING = 330, // NYI + SPELL_AURA_331 = 331, + SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS = 332, // NYI + SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2 = 333, // NYI + SPELL_AURA_334 = 334, + SPELL_AURA_335 = 335, + SPELL_AURA_MOD_FLYING_RESTRICTIONS = 336, // NYI + SPELL_AURA_MOD_VENDOR_ITEMS_PRICES = 337, // NYI + SPELL_AURA_MOD_DURABILITY_LOSS = 338, + SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE = 339, // NYI + SPELL_AURA_340 = 340, + SPELL_AURA_341 = 341, // cooldown decrease + SPELL_AURA_MOD_TIME_BETWEEN_ATTACKS = 342, // (attack speed) NYI + SPELL_AURA_343 = 343, + SPELL_AURA_MOD_AUTOATTACK_DAMAGE = 344, + SPELL_AURA_BYPASS_ARMOR_FOR_CASTER = 345, + SPELL_AURA_PROGRESS_BAR = 346, // NYI + SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE = 347, // NYI + SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT = 348, // NYI + SPELL_AURA_MOD_CURRENCY_GAIN = 349, // NYI + SPELL_AURA_MOD_GATHERING_ITEMS_GAINED_PERCENT = 350, // NYI + SPELL_AURA_351 = 351, + SPELL_AURA_352 = 352, + SPELL_AURA_MOD_CAMOUFLAGE = 353, // NYI + SPELL_AURA_354 = 354, + SPELL_AURA_355 = 355, + SPELL_AURA_356 = 356, + SPELL_AURA_357 = 357, + SPELL_AURA_358 = 358, + SPELL_AURA_359 = 359, + SPELL_AURA_360 = 360, + SPELL_AURA_361 = 361, + SPELL_AURA_362 = 362, + TOTAL_AURAS = 363 // 4.2.2 }; enum AuraObjectType diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 610cd7d1533..eb81e1f7412 100755..100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -370,6 +370,52 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandlePreventResurrection, //314 SPELL_AURA_PREVENT_RESURRECTION todo &AuraEffect::HandleNoImmediateEffect, //315 SPELL_AURA_UNDERWATER_WALKING todo &AuraEffect::HandleNoImmediateEffect, //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic + &AuraEffect::HandleNULL, //317 SPELL_AURA_MOD_SPELL_POWER_PCT + &AuraEffect::HandleNULL, //318 SPELL_AURA_MASTERY + &AuraEffect::HandleNULL, //319 SPELL_AURA_319 + &AuraEffect::HandleNULL, //320 SPELL_AURA_MOD_RANGED_ATTACK_SPEED + &AuraEffect::HandleNULL, //321 SPELL_AURA_321 + &AuraEffect::HandleNULL, //322 SPELL_AURA_INTERFERE_TARGETTING + &AuraEffect::HandleNULL, //323 SPELL_AURA_323 + &AuraEffect::HandleNULL, //324 SPELL_AURA_324 + &AuraEffect::HandleNULL, //325 SPELL_AURA_325 + &AuraEffect::HandleNULL, //326 SPELL_AURA_326 + &AuraEffect::HandleNULL, //327 SPELL_AURA_327 + &AuraEffect::HandleNULL, //328 SPELL_AURA_328 + &AuraEffect::HandleNULL, //329 SPELL_AURA_MOD_RUNE_REGEN_SPEED + &AuraEffect::HandleNULL, //330 SPELL_AURA_CAST_WHILE_WALKING + &AuraEffect::HandleNULL, //331 SPELL_AURA_331 + &AuraEffect::HandleNULL, //332 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS + &AuraEffect::HandleNULL, //333 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2 + &AuraEffect::HandleNULL, //334 SPELL_AURA_334 + &AuraEffect::HandleNULL, //335 SPELL_AURA_335 + &AuraEffect::HandleNULL, //336 SPELL_AURA_MOD_FLYING_RESTRICTIONS + &AuraEffect::HandleNULL, //337 SPELL_AURA_MOD_VENDOR_ITEMS_PRICES + &AuraEffect::HandleNULL, //338 SPELL_AURA_MOD_DURABILITY_LOSS + &AuraEffect::HandleNULL, //339 SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE + &AuraEffect::HandleNULL, //340 SPELL_AURA_340 + &AuraEffect::HandleNULL, //341 SPELL_AURA_341 + &AuraEffect::HandleNULL, //342 SPELL_AURA_MOD_TIME_BETWEEN_ATTACKS + &AuraEffect::HandleNULL, //343 SPELL_AURA_343 + &AuraEffect::HandleNULL, //344 SPELL_AURA_MOD_AUTOATTACK_DAMAGE + &AuraEffect::HandleNULL, //345 SPELL_AURA_BYPASS_ARMOR_FOR_CASTER + &AuraEffect::HandleNULL, //346 SPELL_AURA_PROGRESS_BAR + &AuraEffect::HandleNULL, //347 SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE + &AuraEffect::HandleNULL, //348 SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT + &AuraEffect::HandleNULL, //349 SPELL_AURA_MOD_CURRENCY_GAIN + &AuraEffect::HandleNULL, //350 SPELL_AURA_MOD_GATHERING_ITEMS_GAINED_PERCENT + &AuraEffect::HandleNULL, //351 SPELL_AURA_351 + &AuraEffect::HandleNULL, //352 SPELL_AURA_352 + &AuraEffect::HandleNULL, //353 SPELL_AURA_MOD_CAMOUFLAGE + &AuraEffect::HandleNULL, //353 SPELL_AURA_354 + &AuraEffect::HandleNULL, //354 SPELL_AURA_355 + &AuraEffect::HandleNULL, //356 SPELL_AURA_356 + &AuraEffect::HandleNULL, //357 SPELL_AURA_357 + &AuraEffect::HandleNULL, //358 SPELL_AURA_358 + &AuraEffect::HandleNULL, //359 SPELL_AURA_359 + &AuraEffect::HandleNULL, //360 SPELL_AURA_360 + &AuraEffect::HandleNULL, //361 SPELL_AURA_361 + &AuraEffect::HandleNULL, //362 SPELL_AURA_362 }; AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* caster): @@ -467,7 +513,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) Unit::AuraEffectList const& overrideClassScripts = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (Unit::AuraEffectList::const_iterator itr = overrideClassScripts.begin(); itr != overrideClassScripts.end(); ++itr) { - if ((*itr)->IsAffectedOnSpell(m_spellInfo)) + if ((*itr)->IsAffectingSpell(m_spellInfo)) { // Glyph of Fear, Glyph of Frost nova and similar auras if ((*itr)->GetMiscValue() == 7801) @@ -757,6 +803,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster) if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo()->SpellFamilyFlags[2] & 0x00000008) amount = GetBase()->GetUnitOwner()->GetShapeshiftForm() == FORM_CAT ? amount : 0; break; + case SPELL_AURA_MOUNTED: + if (MountCapabilityEntry const* mountCapability = GetBase()->GetUnitOwner()->GetMountCapability(uint32(GetMiscValueB()))) + amount = mountCapability->Id; + break; default: break; } @@ -1201,7 +1251,7 @@ bool AuraEffect::IsPeriodicTickCrit(Unit* target, Unit const* caster) const Unit::AuraEffectList const& mPeriodicCritAuras= caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_PERIODIC_CRIT); for (Unit::AuraEffectList::const_iterator itr = mPeriodicCritAuras.begin(); itr != mPeriodicCritAuras.end(); ++itr) { - if ((*itr)->IsAffectedOnSpell(m_spellInfo) && caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask())) + if ((*itr)->IsAffectingSpell(m_spellInfo) && caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask())) return true; } @@ -1212,7 +1262,7 @@ bool AuraEffect::IsPeriodicTickCrit(Unit* target, Unit const* caster) const return false; } -bool AuraEffect::IsAffectedOnSpell(SpellInfo const* spell) const +bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const { if (!spell) return false; @@ -1426,7 +1476,9 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const if (target->GetTypeId() == TYPEID_PLAYER) { - const PlayerSpellMap& sp_list = target->ToPlayer()->GetSpellMap(); + Player* plrTarget = target->ToPlayer(); + + PlayerSpellMap const& sp_list = plrTarget->GetSpellMap(); for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) { if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled) @@ -1446,13 +1498,14 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const // Also do it for Glyphs for (uint32 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i) { - if (uint32 glyphId = target->ToPlayer()->GetGlyph(i)) + if (uint32 glyphId = plrTarget->GetGlyph(plrTarget->GetActiveSpec(), i)) { if (GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId)) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(glyph->SpellId); if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE))) continue; + if (spellInfo->Stances & (1<<(GetMiscValue()-1))) target->CastSpell(target, glyph->SpellId, true, NULL, this); } @@ -1460,19 +1513,21 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const } // Leader of the Pack - if (target->ToPlayer()->HasSpell(17007)) + if (plrTarget->HasSpell(17007)) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24932); if (spellInfo && spellInfo->Stances & (1<<(GetMiscValue()-1))) target->CastSpell(target, 24932, true, NULL, this); } + // Improved Barkskin - apply/remove armor bonus due to shapeshift - if (target->ToPlayer()->HasSpell(63410) || target->ToPlayer()->HasSpell(63411)) + if (plrTarget->HasSpell(63410) || target->ToPlayer()->HasSpell(63411)) { target->RemoveAurasDueToSpell(66530); if (GetMiscValue() == FORM_TRAVEL || GetMiscValue() == FORM_NONE) // "while in Travel Form or while not shapeshifted" target->CastSpell(target, 66530, true); } + // Heart of the Wild if (HotWSpellId) { // hacky, but the only way as spell family is not SPELLFAMILY_DRUID @@ -1977,7 +2032,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo if (PowerType != POWER_MANA) { - uint32 oldPower = target->GetPower(PowerType); + int32 oldPower = target->GetPower(PowerType); // reset power to default values only at power change if (target->getPowerType() != PowerType) target->setPowerType(PowerType); @@ -1989,7 +2044,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo case FORM_DIREBEAR: { // get furor proc chance - uint32 FurorChance = 0; + int32 FurorChance = 0; if (AuraEffect const* dummy = target->GetDummyAuraEffect(SPELLFAMILY_DRUID, 238, 0)) FurorChance = std::max(dummy->GetAmount(), 0); @@ -1997,18 +2052,18 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo { case FORM_CAT: { - int32 basePoints = int32(std::min(oldPower, FurorChance)); + int32 basePoints = std::min<int32>(oldPower, FurorChance); target->SetPower(POWER_ENERGY, 0); target->CastCustomSpell(target, 17099, &basePoints, NULL, NULL, true, NULL, this); } break; case FORM_BEAR: case FORM_DIREBEAR: - if (urand(0, 99) < FurorChance) + if (irand(0, 99) < FurorChance) target->CastSpell(target, 17057, true); default: { - uint32 newEnergy = std::min(target->GetPower(POWER_ENERGY), FurorChance); + int32 newEnergy = std::min(target->GetPower(POWER_ENERGY), FurorChance); target->SetPower(POWER_ENERGY, newEnergy); } break; @@ -2061,7 +2116,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo case FORM_DEFENSIVESTANCE: case FORM_BERSERKERSTANCE: { - uint32 Rage_val = 0; + int32 Rage_val = 0; // Defensive Tactics if (form == FORM_DEFENSIVESTANCE) { @@ -2122,7 +2177,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo if (target->GetTypeId() == TYPEID_PLAYER) { - SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form); + SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form); // Learn spells for shapeshift form - no need to send action bars or add spells to spellbook for (uint8 i = 0; i<MAX_SHAPESHIFT_SPELLS; ++i) { @@ -2767,17 +2822,17 @@ void AuraEffect::HandleAuraModSkill(AuraApplication const* aurApp, uint8 mode, b { if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SKILL))) return; - Unit* target = aurApp->GetTarget(); - if (target->GetTypeId() != TYPEID_PLAYER) + Player* target = aurApp->GetTarget()->ToPlayer(); + if (!target) return; uint32 prot = GetMiscValue(); int32 points = GetAmount(); - target->ToPlayer()->ModifySkillBonus(prot, ((apply) ? points: -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT); + target->ModifySkillBonus(prot, (apply ? points : -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT); if (prot == SKILL_DEFENSE) - target->ToPlayer()->UpdateDefenseBonusesMod(); + target->UpdateDefenseBonusesMod(); } /****************************/ @@ -2815,7 +2870,7 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo if (target->GetTypeId() == TYPEID_PLAYER) team = target->ToPlayer()->GetTeam(); - uint32 displayID = sObjectMgr->ChooseDisplayId(team, ci); + uint32 displayID = ObjectMgr::ChooseDisplayId(team, ci); sObjectMgr->GetCreatureModelRandomGender(&displayID); //some spell has one aura of mount and one of vehicle @@ -2825,6 +2880,10 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo displayID = 0; target->Mount(displayID, ci->VehicleId, GetMiscValue()); + + // cast speed aura + if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(uint32(GetMiscValueB()))) + target->CastSpell(target, mountCapability->SpeedModSpell, true); } else { @@ -2833,7 +2892,13 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo // need to remove ALL arura related to mounts, this will stop client crash with broom stick // and never endless flying after using Headless Horseman's Mount if (mode & AURA_EFFECT_HANDLE_REAL) + { target->RemoveAurasByType(SPELL_AURA_MOUNTED); + + // remove speed aura + if (MountCapabilityEntry const* mountCapability = target->GetMountCapability(uint32(GetMiscValueB()))) + target->RemoveAurasDueToSpell(mountCapability->SpeedModSpell, target->GetGUID()); + } } } @@ -4005,19 +4070,13 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8 Unit* target = aurApp->GetTarget(); - if (GetMiscValue() < -1 || GetMiscValue() > 4) - { - sLog->outError(LOG_FILTER_SPELLS_AURAS, "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid"); - return; - } - // save current health state float healthPct = target->GetHealthPct(); bool alive = target->isAlive(); for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++) { - if (GetMiscValue() == i || GetMiscValue() == -1) + if (GetMiscValueB() & 1 << i || !GetMiscValueB()) // 0 is also used for all stats { target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetAmount()), apply); if (target->GetTypeId() == TYPEID_PLAYER || target->ToCreature()->isPet()) @@ -4027,7 +4086,7 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8 // recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_UNK4 0x00000010 flag) // this check is total bullshit i think - if (GetMiscValue() == STAT_STAMINA && (m_spellInfo->Attributes & SPELL_ATTR0_ABILITY)) + if (GetMiscValueB() & 1 << STAT_STAMINA && (m_spellInfo->Attributes & SPELL_ATTR0_ABILITY)) target->SetHealth(std::max<uint32>(uint32(healthPct * target->GetMaxHealth() * 0.01f), (alive ? 1 : 0))); } @@ -4957,10 +5016,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (caster) target->GetMotionMaster()->MoveFall(); break; - case 46699: // Requires No Ammo - if (target->GetTypeId() == TYPEID_PLAYER) - target->ToPlayer()->RemoveAmmo(); // not use ammo and not allow use - break; case 52916: // Honor Among Thieves if (target->GetTypeId() == TYPEID_PLAYER) if (Unit* spellTarget = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget())) @@ -5578,7 +5633,7 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode, Unit* target = aurApp->GetTarget(); - if (target->GetTypeId() != TYPEID_PLAYER || !target->IsInWorld()) + if (!target->IsInWorld()) return; uint32 vehicleId = GetMiscValue(); @@ -5591,6 +5646,9 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode, else if (target->GetVehicleKit()) target->RemoveVehicleKit(); + if (target->GetTypeId() != TYPEID_PLAYER) + return; + WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, target->GetPackGUID().size()+4); data.appendPackGUID(target->GetGUID()); data << uint32(apply ? vehicleId : 0); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 64079918638..28a5beafa2c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -79,7 +79,7 @@ class AuraEffect bool IsPeriodic() const { return m_isPeriodic; } void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; } - bool IsAffectedOnSpell(SpellInfo const* spell) const; + bool IsAffectingSpell(SpellInfo const* spell) const; bool HasSpellClassMask() const { return m_spellInfo->Effects[m_effIndex].SpellClassMask; } void SendTickImmune(Unit* target, Unit* caster) const; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 9ee05b9a2a4..3394d46fadf 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -147,6 +147,16 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask) } _flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE; } + + // there are more auras that require this flag, this is just the beginning + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (((1 << i) & effMask) && GetBase()->GetSpellInfo()->Effects[i].ApplyAuraName == SPELL_AURA_MOUNTED) + { + _flags |= AFLAG_ANY_EFFECT_AMOUNT_SENT; + break; + } + } } void AuraApplication::_HandleEffect(uint8 effIndex, bool apply) @@ -192,7 +202,7 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const uint32 flags = _flags; if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION)) flags |= AFLAG_DURATION; - data << uint8(flags); + data << uint16(flags); data << uint8(aura->GetCasterLevel()); // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges // stack amount has priority over charges (checked on retail with spell 50262) @@ -206,6 +216,11 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const data << uint32(aura->GetMaxDuration()); data << uint32(aura->GetDuration()); } + + if (flags & AFLAG_ANY_EFFECT_AMOUNT_SENT) + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (AuraEffect const* eff = aura->GetEffect(i)) // NULL if effect flag not set + data << int32(eff->GetAmount()); } void AuraApplication::ClientUpdate(bool remove) @@ -337,7 +352,7 @@ m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0), m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1), m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false) { - if (m_spellInfo->ManaPerSecond || m_spellInfo->ManaPerSecondPerLevel) + if (m_spellInfo->ManaPerSecond) m_timeCla = 1 * IN_MILLISECONDS; m_maxDuration = CalcMaxDuration(caster); @@ -672,7 +687,7 @@ void Aura::Update(uint32 diff, Unit* caster) m_timeCla -= diff; else if (caster) { - if (int32 manaPerSecond = m_spellInfo->ManaPerSecond + m_spellInfo->ManaPerSecondPerLevel * caster->getLevel()) + if (int32 manaPerSecond = m_spellInfo->ManaPerSecond) { m_timeCla += 1000 - diff; @@ -741,7 +756,7 @@ void Aura::RefreshDuration() { SetDuration(GetMaxDuration()); - if (m_spellInfo->ManaPerSecond || m_spellInfo->ManaPerSecondPerLevel) + if (m_spellInfo->ManaPerSecond) m_timeCla = 1 * IN_MILLISECONDS; } @@ -2471,4 +2486,3 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster* } } } - diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 2f50d47a79b..36398bafa97 100755 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -166,7 +166,7 @@ class Aura void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount); // helpers for aura effects - bool HasEffect(uint8 effIndex) const { return bool(GetEffect(effIndex)); } + bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != NULL; } bool HasEffectType(AuraType type) const; AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; } uint8 GetEffectMask() const { uint8 effMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<<i; return effMask; } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 1dedf8ba916..391a52b8aa5 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -53,6 +53,7 @@ #include "SpellScript.h" #include "InstanceScript.h" #include "SpellInfo.h" +#include "DB2Stores.h" extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; @@ -531,7 +532,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme // wand case if ((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId() == TYPEID_PLAYER) if (Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK)) - m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType); + m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->DamageType); if (originalCasterGUID) m_originalCasterGUID = originalCasterGUID; @@ -1062,7 +1063,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge { Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS); for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j) - if ((*j)->IsAffectedOnSpell(m_spellInfo)) + if ((*j)->IsAffectingSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); Trinity::Containers::RandomResizeList(targets, maxTargets); @@ -1349,7 +1350,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge { Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS); for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j) - if ((*j)->IsAffectedOnSpell(m_spellInfo)) + if ((*j)->IsAffectingSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); Trinity::Containers::RandomResizeList(unitTargets, maxTargets); @@ -1365,7 +1366,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge { Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS); for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j) - if ((*j)->IsAffectedOnSpell(m_spellInfo)) + if ((*j)->IsAffectingSpell(m_spellInfo)) maxTargets += (*j)->GetAmount(); Trinity::Containers::RandomResizeList(gObjTargets, maxTargets); @@ -2501,6 +2502,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) } + m_damage = damageInfo.damage; caster->DealSpellDamage(&damageInfo, true); @@ -2603,14 +2605,14 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA if (unit->GetTypeId() == TYPEID_PLAYER) { unit->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id); - unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster); - unit->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); + unit->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster); + unit->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); } if (m_caster->GetTypeId() == TYPEID_PLAYER) { m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id); - m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); + m_caster->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); } if (m_caster != unit) @@ -3252,10 +3254,10 @@ void Spell::cast(bool skipCheck) if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_ITEM) && m_CastItem) { m_caster->ToPlayer()->GetAchievementMgr().StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_ITEM, m_CastItem->GetEntry()); - m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); + m_caster->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); } - m_caster->ToPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); + m_caster->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); } if (!(_triggeredCastFlags & TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)) @@ -3682,7 +3684,7 @@ void Spell::finish(bool ok) Unit::AuraEffectList const& vIgnoreReset = m_caster->GetAuraEffectsByType(SPELL_AURA_IGNORE_MELEE_RESET); for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i) { - if ((*i)->IsAffectedOnSpell(m_spellInfo)) + if ((*i)->IsAffectingSpell(m_spellInfo)) { found = true; break; @@ -3743,6 +3745,9 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas data << uint8(result); // problem switch (result) { + case SPELL_FAILED_NOT_READY: + data << uint32(0); // unknown (value 1 update cooldowns on client flag) + break; case SPELL_FAILED_REQUIRES_SPELL_FOCUS: data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id break; @@ -3795,9 +3800,29 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas data << uint32(proto->ItemLimitCategory); break; } + case SPELL_FAILED_PREVENTED_BY_MECHANIC: + data << uint32(spellInfo->GetAllEffectsMechanicMask()); // SpellMechanic.dbc id + break; + case SPELL_FAILED_NEED_EXOTIC_AMMO: + data << uint32(spellInfo->EquippedItemSubClassMask); // seems correct... + break; + case SPELL_FAILED_NEED_MORE_ITEMS: + data << uint32(0); // Item id + data << uint32(0); // Item count? + break; + case SPELL_FAILED_MIN_SKILL: + data << uint32(0); // SkillLine.dbc id + data << uint32(0); // required skill value + break; + case SPELL_FAILED_FISHING_TOO_LOW: + data << uint32(0); // required fishing skill + break; case SPELL_FAILED_CUSTOM_ERROR: data << uint32(customError); break; + case SPELL_FAILED_SILENCED: + data << uint32(0); // Unknown + break; case SPELL_FAILED_REAGENTS: { uint32 missingItem = 0; @@ -3819,23 +3844,7 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas data << uint32(missingItem); // first missing item break; } - case SPELL_FAILED_PREVENTED_BY_MECHANIC: - data << uint32(spellInfo->Mechanic); - break; - case SPELL_FAILED_NEED_EXOTIC_AMMO: - data << uint32(spellInfo->EquippedItemSubClassMask); - break; - case SPELL_FAILED_NEED_MORE_ITEMS: - data << uint32(0); // Item entry - data << uint32(0); // Count - break; - case SPELL_FAILED_MIN_SKILL: - data << uint32(0); // SkillLine.dbc Id - data << uint32(0); // Amount - break; - case SPELL_FAILED_FISHING_TOO_LOW: - data << uint32(0); // Skill level - break; + // TODO: SPELL_FAILED_NOT_STANDING default: break; } @@ -3849,13 +3858,11 @@ void Spell::SendSpellStart() //sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id); - uint32 castFlags = CAST_FLAG_UNKNOWN_2; + uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY; if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell) castFlags |= CAST_FLAG_PENDING; - if (m_spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO) - castFlags |= CAST_FLAG_AMMO; if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet())) && m_spellInfo->PowerType != POWER_HEALTH) @@ -3874,20 +3881,56 @@ void Spell::SendSpellStart() data << uint8(m_cast_count); // pending spell cast? data << uint32(m_spellInfo->Id); // spellId data << uint32(castFlags); // cast flags - data << int32(m_timer); // delay? + data << uint32(m_timer); // delay? + data << uint32(m_casttime); m_targets.Write(data); if (castFlags & CAST_FLAG_POWER_LEFT_SELF) data << uint32(m_caster->GetPower((Powers)m_spellInfo->PowerType)); - if (castFlags & CAST_FLAG_AMMO) - WriteAmmoToPacket(&data); + if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list + { + //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature + //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster + if (Player* player = m_caster->ToPlayer()) + { + data << uint8(m_runesState); // runes state before + data << uint8(player->GetRunesState()); // runes state after + for (uint8 i = 0; i < MAX_RUNES; ++i) + { + // float casts ensure the division is performed on floats as we need float result + float baseCd = float(player->GetRuneBaseCooldown(i)); + data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed + } + } + else + { + data << uint8(0); + data << uint8(0); + for (uint8 i = 0; i < MAX_RUNES; ++i) + data << uint8(0); + } + } - if (castFlags & CAST_FLAG_UNKNOWN_23) + if (castFlags & CAST_FLAG_PROJECTILE) { + data << uint32(0); // Ammo display ID + data << uint32(0); // Inventory Type + } + + if (castFlags & CAST_FLAG_IMMUNITY) + { + data << uint32(0); data << uint32(0); + } + + if (castFlags & CAST_FLAG_HEAL_PREDICTION) + { data << uint32(0); + data << uint8(0); // unkByte + // if (unkByte == 2) + // data.append(0); } m_caster->SendMessageToSet(&data, true); @@ -3907,8 +3950,7 @@ void Spell::SendSpellGo() if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell) castFlags |= CAST_FLAG_PENDING; - if (m_spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO) - castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual + if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet())) @@ -3944,6 +3986,7 @@ void Spell::SendSpellGo() data << uint8(m_cast_count); // pending spell cast? data << uint32(m_spellInfo->Id); // spellId data << uint32(castFlags); // cast flags + data << uint32(m_timer); data << uint32(getMSTime()); // timestamp WriteSpellGoTargets(&data); @@ -3959,30 +4002,28 @@ void Spell::SendSpellGo() //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster if (Player* player = m_caster->ToPlayer()) { - uint8 runeMaskInitial = m_runesState; - uint8 runeMaskAfterCast = player->GetRunesState(); - data << uint8(runeMaskInitial); // runes state before - data << uint8(runeMaskAfterCast); // runes state after + data << uint8(m_runesState); // runes state before + data << uint8(player->GetRunesState()); // runes state after for (uint8 i = 0; i < MAX_RUNES; ++i) { - uint8 mask = (1 << i); - if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now... - { - // float casts ensure the division is performed on floats as we need float result - float baseCd = float(player->GetRuneBaseCooldown(i)); - data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed - } + // float casts ensure the division is performed on floats as we need float result + float baseCd = float(player->GetRuneBaseCooldown(i)); + data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed } } } + if (castFlags & CAST_FLAG_ADJUST_MISSILE) { data << m_targets.GetElevation(); data << uint32(m_delayMoment); } - if (castFlags & CAST_FLAG_AMMO) - WriteAmmoToPacket(&data); + if (castFlags & CAST_FLAG_PROJECTILE) + { + data << uint32(0); // Ammo display ID + data << uint32(0); // Inventory Type + } if (castFlags & CAST_FLAG_VISUAL_CHAIN) { @@ -3995,79 +4036,21 @@ void Spell::SendSpellGo() data << uint8(0); } - m_caster->SendMessageToSet(&data, true); -} - -void Spell::WriteAmmoToPacket(WorldPacket* data) -{ - uint32 ammoInventoryType = 0; - uint32 ammoDisplayID = 0; - - if (m_caster->GetTypeId() == TYPEID_PLAYER) - { - Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK); - if (pItem) - { - ammoInventoryType = pItem->GetTemplate()->InventoryType; - if (ammoInventoryType == INVTYPE_THROWN) - ammoDisplayID = pItem->GetTemplate()->DisplayInfoID; - else - { - uint32 ammoID = m_caster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID); - if (ammoID) - { - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID); - if (pProto) - { - ammoDisplayID = pProto->DisplayInfoID; - ammoInventoryType = pProto->InventoryType; - } - } - else if (m_caster->HasAura(46699)) // Requires No Ammo - { - ammoDisplayID = 5996; // normal arrow - ammoInventoryType = INVTYPE_AMMO; - } - } - } - } - else + if (m_targets.GetTargetMask() & TARGET_FLAG_EXTRA_TARGETS) { - for (uint8 i = 0; i < 3; ++i) + data << uint32(0); // Extra targets count + /* + for (uint8 i = 0; i < count; ++i) { - if (uint32 item_id = m_caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i)) - { - if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id)) - { - if (itemEntry->Class == ITEM_CLASS_WEAPON) - { - switch (itemEntry->SubClass) - { - case ITEM_SUBCLASS_WEAPON_THROWN: - ammoDisplayID = itemEntry->DisplayId; - ammoInventoryType = itemEntry->InventoryType; - break; - case ITEM_SUBCLASS_WEAPON_BOW: - case ITEM_SUBCLASS_WEAPON_CROSSBOW: - ammoDisplayID = 5996; // is this need fixing? - ammoInventoryType = INVTYPE_AMMO; - break; - case ITEM_SUBCLASS_WEAPON_GUN: - ammoDisplayID = 5998; // is this need fixing? - ammoInventoryType = INVTYPE_AMMO; - break; - } - - if (ammoDisplayID) - break; - } - } - } + data << float(0); // Target Position X + data << float(0); // Target Position Y + data << float(0); // Target Position Z + data << uint64(0); // Target Guid } + */ } - *data << uint32(ammoDisplayID); - *data << uint32(ammoInventoryType); + m_caster->SendMessageToSet(&data, true); } void Spell::WriteSpellGoTargets(WorldPacket* data) @@ -4260,7 +4243,25 @@ void Spell::SendChannelStart(uint32 duration) data.append(m_caster->GetPackGUID()); data << uint32(m_spellInfo->Id); data << uint32(duration); - + data << uint8(0); // immunity (castflag & 0x04000000) + /* + if (immunity) + { + data << uint32(); // CastSchoolImmunities + data << uint32(); // CastImmunities + } + */ + data << uint8(0); // healPrediction (castflag & 0x40000000) + /* + if (healPrediction) + { + data.appendPackGUID(channelTarget); // target packguid + data << uint32(); // spellid + data << uint8(0); // unk3 + if (unk3 == 2) + data.append(); // unk packed guid (unused ?) + } + */ m_caster->SendMessageToSet(&data, true); m_timer = duration; @@ -4281,12 +4282,12 @@ void Spell::SendResurrectRequest(Player* target) data << uint32(strlen(resurrectorName) + 1); data << resurrectorName; - data << uint8(0); // null terminator + data << uint8(0); // use timer according to client symbols data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness" // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute - if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_RESURRECTION_TIMER) - data << uint32(0); + // 4.2.2 edit : id of the spell used to resurect. (used client-side for Mass Resurect) + data << uint32(m_spellInfo->Id); target->GetSession()->SendPacket(&data); } @@ -4433,8 +4434,6 @@ void Spell::TakeAmmo() m_caster->ToPlayer()->DestroyItemCount(pItem, count, true); } } - else if (uint32 ammo = m_caster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID)) - m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true); } } @@ -4730,7 +4729,7 @@ SpellCastResult Spell::CheckCast(bool strict) Unit::AuraEffectList const& ignore = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT); for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(m_spellInfo)) + if (!(*i)->IsAffectingSpell(m_spellInfo)) continue; checkForm = false; break; @@ -4756,7 +4755,7 @@ SpellCastResult Spell::CheckCast(bool strict) Unit::AuraEffectList const& stateAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE); for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j) { - if ((*j)->IsAffectedOnSpell(m_spellInfo)) + if ((*j)->IsAffectingSpell(m_spellInfo)) { m_needComboPoints = false; if ((*j)->GetMiscValue() == 1) @@ -4806,7 +4805,7 @@ SpellCastResult Spell::CheckCast(bool strict) SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex]; if (effInfo->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT) { - SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(effInfo->MiscValue); + SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue); if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED; break; @@ -4985,6 +4984,7 @@ SpellCastResult Spell::CheckCast(bool strict) bool hasNonDispelEffect = false; uint32 dispelMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL) { if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->AttributesEx & SPELL_ATTR1_MELEE_COMBAT_START) @@ -5000,6 +5000,7 @@ SpellCastResult Spell::CheckCast(bool strict) hasNonDispelEffect = true; break; } + } if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered()) { @@ -5017,6 +5018,26 @@ SpellCastResult Spell::CheckCast(bool strict) // for effects of spells that have only one target switch (m_spellInfo->Effects[i].Effect) { + case SPELL_EFFECT_DUMMY: + { + if (m_spellInfo->Id == 19938) // Awaken Peon + { + Unit* unit = m_targets.GetUnitTarget(); + if (!unit || !unit->HasAura(17743)) + return SPELL_FAILED_BAD_TARGETS; + } + else if (m_spellInfo->Id == 31789) // Righteous Defense + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_DONT_REPORT; + + Unit* target = m_targets.GetUnitTarget(); + if (!target || !target->IsFriendlyTo(m_caster) || target->getAttackers().empty()) + return SPELL_FAILED_BAD_TARGETS; + + } + break; + } case SPELL_EFFECT_LEARN_SPELL: { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -6202,46 +6223,6 @@ SpellCastResult Spell::CheckItems() case ITEM_SUBCLASS_WEAPON_GUN: case ITEM_SUBCLASS_WEAPON_BOW: case ITEM_SUBCLASS_WEAPON_CROSSBOW: - { - uint32 ammo = m_caster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID); - if (!ammo) - { - // Requires No Ammo - if (m_caster->HasAura(46699)) - break; // skip other checks - - return SPELL_FAILED_NO_AMMO; - } - - ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo); - if (!ammoProto) - return SPELL_FAILED_NO_AMMO; - - if (ammoProto->Class != ITEM_CLASS_PROJECTILE) - return SPELL_FAILED_NO_AMMO; - - // check ammo ws. weapon compatibility - switch (pItem->GetTemplate()->SubClass) - { - case ITEM_SUBCLASS_WEAPON_BOW: - case ITEM_SUBCLASS_WEAPON_CROSSBOW: - if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW) - return SPELL_FAILED_NO_AMMO; - break; - case ITEM_SUBCLASS_WEAPON_GUN: - if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET) - return SPELL_FAILED_NO_AMMO; - break; - default: - return SPELL_FAILED_NO_AMMO; - } - - if (!m_caster->ToPlayer()->HasItemCount(ammo, 1)) - { - m_caster->ToPlayer()->SetUInt32Value(PLAYER_AMMO_ID, 0); - return SPELL_FAILED_NO_AMMO; - } - }; break; case ITEM_SUBCLASS_WEAPON_WAND: break; default: @@ -6689,7 +6670,7 @@ void Spell::HandleLaunchPhase() Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO); for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j) { - if ((*j)->IsAffectedOnSpell(m_spellInfo)) + if ((*j)->IsAffectingSpell(m_spellInfo)) usesAmmo=false; } @@ -7146,7 +7127,7 @@ void Spell::PrepareTriggersExecutedOnHit() Unit::AuraEffectList const& targetTriggers = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER); for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i) { - if (!(*i)->IsAffectedOnSpell(m_spellInfo)) + if (!(*i)->IsAffectingSpell(m_spellInfo)) continue; SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo(); uint32 auraSpellIdx = (*i)->GetEffIndex(); diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 1376b0fbd40..cb9a5fdef4d 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -39,11 +39,11 @@ enum SpellCastFlags { CAST_FLAG_NONE = 0x00000000, CAST_FLAG_PENDING = 0x00000001, // aoe combat log? - CAST_FLAG_UNKNOWN_2 = 0x00000002, + CAST_FLAG_HAS_TRAJECTORY = 0x00000002, CAST_FLAG_UNKNOWN_3 = 0x00000004, CAST_FLAG_UNKNOWN_4 = 0x00000008, // ignore AOE visual CAST_FLAG_UNKNOWN_5 = 0x00000010, - CAST_FLAG_AMMO = 0x00000020, // Projectiles visual + CAST_FLAG_PROJECTILE = 0x00000020, CAST_FLAG_UNKNOWN_7 = 0x00000040, CAST_FLAG_UNKNOWN_8 = 0x00000080, CAST_FLAG_UNKNOWN_9 = 0x00000100, @@ -68,7 +68,7 @@ enum SpellCastFlags CAST_FLAG_UNKNOWN_28 = 0x08000000, CAST_FLAG_UNKNOWN_29 = 0x10000000, CAST_FLAG_UNKNOWN_30 = 0x20000000, - CAST_FLAG_UNKNOWN_31 = 0x40000000, + CAST_FLAG_HEAL_PREDICTION = 0x40000000, CAST_FLAG_UNKNOWN_32 = 0x80000000, }; @@ -407,7 +407,6 @@ class Spell void DoCreateItem(uint32 i, uint32 itemtype); void WriteSpellGoTargets(WorldPacket* data); - void WriteAmmoToPacket(WorldPacket* data); bool CheckEffectTarget(Unit const* target, uint32 eff) const; bool CanAutoCast(Unit* target); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index d30f6e593dd..8b620e1e9ea 100755..100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -118,7 +118,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectUnused, // 49 SPELL_EFFECT_DETECT one spell: Detect &Spell::EffectTransmitted, // 50 SPELL_EFFECT_TRANS_DOOR &Spell::EffectUnused, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT unused - &Spell::EffectUnused, // 52 SPELL_EFFECT_GUARANTEE_HIT one spell: zzOLDCritical Shot + &Spell::EffectUnused, // 52 SPELL_EFFECT_GUARANTEE_HIT unused &Spell::EffectEnchantItemPerm, // 53 SPELL_EFFECT_ENCHANT_ITEM &Spell::EffectEnchantItemTmp, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY &Spell::EffectTameCreature, // 55 SPELL_EFFECT_TAMECREATURE @@ -229,8 +229,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectNULL, //160 SPELL_EFFECT_160 1 spell - 45534 &Spell::EffectSpecCount, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert) &Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec - &Spell::EffectNULL, //163 unused + &Spell::EffectUnused, //163 SPELL_EFFECT_163 unused &Spell::EffectRemoveAura, //164 SPELL_EFFECT_REMOVE_AURA + &Spell::EffectNULL, //165 SPELL_EFFECT_165 + &Spell::EffectNULL, //166 SPELL_EFFECT_166 + &Spell::EffectNULL, //167 SPELL_EFFECT_167 + &Spell::EffectNULL, //168 SPELL_EFFECT_168 + &Spell::EffectNULL, //169 SPELL_EFFECT_169 + &Spell::EffectNULL, //170 SPELL_EFFECT_170 + &Spell::EffectNULL, //171 SPELL_EFFECT_171 + &Spell::EffectNULL, //172 SPELL_EFFECT_172 + &Spell::EffectNULL, //173 SPELL_EFFECT_173 + &Spell::EffectNULL, //174 SPELL_EFFECT_174 + &Spell::EffectUnused, //175 SPELL_EFFECT_175 unused + &Spell::EffectNULL, //176 SPELL_EFFECT_176 + &Spell::EffectNULL, //177 SPELL_EFFECT_177 }; void Spell::EffectNULL(SpellEffIndex /*effIndex*/) @@ -605,13 +618,13 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (Item* item = caster->GetWeaponForAttack(RANGED_ATTACK)) { ItemTemplate const* weaponTemplate = item->GetTemplate(); - float dmg_min = weaponTemplate->Damage[0].DamageMin; - float dmg_max = weaponTemplate->Damage[0].DamageMax; + float dmg_min = weaponTemplate->DamageMin; + float dmg_max = weaponTemplate->DamageMax; if (dmg_max == 0.0f && dmg_min > dmg_max) damage += int32(dmg_min); else damage += irand(int32(dmg_min), int32(dmg_max)); - damage += int32(caster->GetAmmoDPS() * weaponTemplate->Delay * 0.001f); + damage += int32(weaponTemplate->Delay * 0.001f); } } } @@ -2878,58 +2891,6 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) Player* p_caster = (Player*)m_caster; - // Rockbiter Weapon apply to both weapon - if (!itemTarget) - return; - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x400000) - { - uint32 spell_id = 0; - - // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value - // Note: damage calculated (correctly) with rounding int32(float(v)) but - // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime - switch (damage) - { - // Rank 1 - case 2: spell_id = 36744; break; // 0% [ 7% == 2, 14% == 2, 20% == 2] - // Rank 2 - case 4: spell_id = 36753; break; // 0% [ 7% == 4, 14% == 4] - case 5: spell_id = 36751; break; // 20% - // Rank 3 - case 6: spell_id = 36754; break; // 0% [ 7% == 6, 14% == 6] - case 7: spell_id = 36755; break; // 20% - // Rank 4 - case 9: spell_id = 36761; break; // 0% [ 7% == 6] - case 10: spell_id = 36758; break; // 14% - case 11: spell_id = 36760; break; // 20% - default: - sLog->outError(LOG_FILTER_SPELLS_AURAS, "Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW", damage); - return; - } - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id); - if (!spellInfo) - { - sLog->outError(LOG_FILTER_SPELLS_AURAS, "Spell::EffectEnchantItemTmp: unknown spell id %i", spell_id); - return; - - } - - for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j) - { - if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j))) - { - if (item->IsFitToSpellRequirements(m_spellInfo)) - { - Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK); - SpellCastTargets targets; - targets.SetItemTarget(item); - spell->prepare(&targets); - } - } - } - return; - } if (!itemTarget) return; @@ -3180,9 +3141,6 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) return; } - if (m_spellInfo->Id == 62124) - m_caster->CastSpell(unitTarget, 67485, true); - // Also use this effect to set the taunter's threat to the taunted creature's highest value if (unitTarget->getThreatManager().getCurrentVictim()) { @@ -4659,12 +4617,16 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex) switch (m_glyphIndex) { case 0: - case 1: minLevel = 15; break; - case 2: minLevel = 50; break; - case 3: minLevel = 30; break; - case 4: minLevel = 70; break; - case 5: minLevel = 80; break; + case 1: + case 6: minLevel = 25; break; + case 2: + case 3: + case 7: minLevel = 50; break; + case 4: + case 5: + case 8: minLevel = 75; break; } + if (minLevel && m_caster->getLevel() < minLevel) { SendCastResult(SPELL_FAILED_GLYPH_SOCKET_LOCKED); @@ -4686,7 +4648,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex) } // remove old glyph - if (uint32 oldglyph = player->GetGlyph(m_glyphIndex)) + if (uint32 oldglyph = player->GetGlyph(player->GetActiveSpec(), m_glyphIndex)) { if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) { @@ -5109,6 +5071,7 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex) player->SetPower(POWER_MANA, mana); player->SetPower(POWER_RAGE, 0); player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY)); + player->SetPower(POWER_FOCUS, 0); player->SpawnCorpseBones(); } @@ -6257,7 +6220,7 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex) if (!(spellInfo->AttributesEx7 & SPELL_ATTR7_SUMMON_PLAYER_TOTEM)) continue; - uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask()); + int32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask()); if (m_caster->GetPower(POWER_MANA) < cost) continue; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 7b3f9a1bef9..e2c17dfe28a 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -319,28 +319,30 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_ SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex) { + SpellEffectEntry const* _effect = spellEntry->GetSpellEffect(effIndex); + _spellInfo = spellInfo; _effIndex = effIndex; - Effect = spellEntry->Effect[effIndex]; - ApplyAuraName = spellEntry->EffectApplyAuraName[effIndex]; - Amplitude = spellEntry->EffectAmplitude[effIndex]; - DieSides = spellEntry->EffectDieSides[effIndex]; - RealPointsPerLevel = spellEntry->EffectRealPointsPerLevel[effIndex]; - BasePoints = spellEntry->EffectBasePoints[effIndex]; - PointsPerComboPoint = spellEntry->EffectPointsPerComboPoint[effIndex]; - ValueMultiplier = spellEntry->EffectValueMultiplier[effIndex]; - DamageMultiplier = spellEntry->EffectDamageMultiplier[effIndex]; - BonusMultiplier = spellEntry->EffectBonusMultiplier[effIndex]; - MiscValue = spellEntry->EffectMiscValue[effIndex]; - MiscValueB = spellEntry->EffectMiscValueB[effIndex]; - Mechanic = Mechanics(spellEntry->EffectMechanic[effIndex]); - TargetA = SpellImplicitTargetInfo(spellEntry->EffectImplicitTargetA[effIndex]); - TargetB = SpellImplicitTargetInfo(spellEntry->EffectImplicitTargetB[effIndex]); - RadiusEntry = spellEntry->EffectRadiusIndex[effIndex] ? sSpellRadiusStore.LookupEntry(spellEntry->EffectRadiusIndex[effIndex]) : NULL; - ChainTarget = spellEntry->EffectChainTarget[effIndex]; - ItemType = spellEntry->EffectItemType[effIndex]; - TriggerSpell = spellEntry->EffectTriggerSpell[effIndex]; - SpellClassMask = spellEntry->EffectSpellClassMask[effIndex]; + Effect = _effect ? _effect->Effect : 0; + ApplyAuraName = _effect ? _effect->EffectApplyAuraName : 0; + Amplitude = _effect ? _effect->EffectAmplitude : 0; + DieSides = _effect ? _effect->EffectDieSides : 0; + RealPointsPerLevel = _effect ? _effect->EffectRealPointsPerLevel : 0.0f; + BasePoints = _effect ? _effect->EffectBasePoints : 0; + PointsPerComboPoint = _effect ? _effect->EffectPointsPerComboPoint : 0.0f; + ValueMultiplier = _effect ? _effect->EffectValueMultiplier : 0.0f; + DamageMultiplier = _effect ? _effect->EffectDamageMultiplier : 0.0f; + BonusMultiplier = _effect ? _effect->EffectBonusMultiplier : 0.0f; + MiscValue = _effect ? _effect->EffectMiscValue : 0; + MiscValueB = _effect ? _effect->EffectMiscValueB : 0; + Mechanic = Mechanics(_effect ? _effect->EffectMechanic : 0); + TargetA = SpellImplicitTargetInfo(_effect ? _effect->EffectImplicitTargetA : 0); + TargetB = SpellImplicitTargetInfo(_effect ? _effect->EffectImplicitTargetB : 0); + RadiusEntry = _effect && _effect->EffectRadiusIndex ? sSpellRadiusStore.LookupEntry(_effect->EffectRadiusIndex) : NULL; + ChainTarget = _effect ? _effect->EffectChainTarget : 0; + ItemType = _effect ? _effect->EffectItemType : 0; + TriggerSpell = _effect ? _effect->EffectTriggerSpell : 0; + SpellClassMask = _effect ? _effect->EffectSpellClassMask : flag96(0); ImplicitTargetConditions = NULL; } @@ -496,8 +498,8 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const { if (!HasRadius()) return 0.0f; - - float radius = RadiusEntry->radiusMax; + //TODO: FIX radius value + float radius = RadiusEntry->ID; if (Player* modOwner = (caster ? caster->GetSpellModOwner() : NULL)) modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_RADIUS, radius, spell); @@ -716,9 +718,6 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = SpellInfo::SpellInfo(SpellEntry const* spellEntry) { Id = spellEntry->Id; - Category = spellEntry->Category; - Dispel = spellEntry->Dispel; - Mechanic = spellEntry->Mechanic; Attributes = spellEntry->Attributes; AttributesEx = spellEntry->AttributesEx; AttributesEx2 = spellEntry->AttributesEx2; @@ -727,75 +726,151 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) AttributesEx5 = spellEntry->AttributesEx5; AttributesEx6 = spellEntry->AttributesEx6; AttributesEx7 = spellEntry->AttributesEx7; + AttributesEx8 = spellEntry->AttributesEx8; AttributesCu = 0; - Stances = spellEntry->Stances; - StancesNot = spellEntry->StancesNot; - Targets = spellEntry->Targets; - TargetCreatureType = spellEntry->TargetCreatureType; - RequiresSpellFocus = spellEntry->RequiresSpellFocus; - FacingCasterFlags = spellEntry->FacingCasterFlags; - CasterAuraState = spellEntry->CasterAuraState; - TargetAuraState = spellEntry->TargetAuraState; - CasterAuraStateNot = spellEntry->CasterAuraStateNot; - TargetAuraStateNot = spellEntry->TargetAuraStateNot; - CasterAuraSpell = spellEntry->casterAuraSpell; - TargetAuraSpell = spellEntry->targetAuraSpell; - ExcludeCasterAuraSpell = spellEntry->excludeCasterAuraSpell; - ExcludeTargetAuraSpell = spellEntry->excludeTargetAuraSpell; CastTimeEntry = spellEntry->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(spellEntry->CastingTimeIndex) : NULL; - RecoveryTime = spellEntry->RecoveryTime; - CategoryRecoveryTime = spellEntry->CategoryRecoveryTime; - StartRecoveryCategory = spellEntry->StartRecoveryCategory; - StartRecoveryTime = spellEntry->StartRecoveryTime; - InterruptFlags = spellEntry->InterruptFlags; - AuraInterruptFlags = spellEntry->AuraInterruptFlags; - ChannelInterruptFlags = spellEntry->ChannelInterruptFlags; - ProcFlags = spellEntry->procFlags; - ProcChance = spellEntry->procChance; - ProcCharges = spellEntry->procCharges; - MaxLevel = spellEntry->maxLevel; - BaseLevel = spellEntry->baseLevel; - SpellLevel = spellEntry->spellLevel; DurationEntry = spellEntry->DurationIndex ? sSpellDurationStore.LookupEntry(spellEntry->DurationIndex) : NULL; PowerType = spellEntry->powerType; - ManaCost = spellEntry->manaCost; - ManaCostPerlevel = spellEntry->manaCostPerlevel; - ManaPerSecond = spellEntry->manaPerSecond; - ManaPerSecondPerLevel = spellEntry->manaPerSecondPerLevel; - ManaCostPercentage = spellEntry->ManaCostPercentage; - RuneCostID = spellEntry->runeCostID; RangeEntry = spellEntry->rangeIndex ? sSpellRangeStore.LookupEntry(spellEntry->rangeIndex) : NULL; Speed = spellEntry->speed; - StackAmount = spellEntry->StackAmount; - for (uint8 i = 0; i < 2; ++i) - Totem[i] = spellEntry->Totem[i]; - for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) - Reagent[i] = spellEntry->Reagent[i]; - for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) - ReagentCount[i] = spellEntry->ReagentCount[i]; - EquippedItemClass = spellEntry->EquippedItemClass; - EquippedItemSubClassMask = spellEntry->EquippedItemSubClassMask; - EquippedItemInventoryTypeMask = spellEntry->EquippedItemInventoryTypeMask; - for (uint8 i = 0; i < 2; ++i) - TotemCategory[i] = spellEntry->TotemCategory[i]; for (uint8 i = 0; i < 2; ++i) SpellVisual[i] = spellEntry->SpellVisual[i]; SpellIconID = spellEntry->SpellIconID; ActiveIconID = spellEntry->activeIconID; - for (uint8 i = 0; i < 16; ++i) - SpellName[i] = spellEntry->SpellName[i]; - for (uint8 i = 0; i < 16; ++i) - Rank[i] = spellEntry->Rank[i]; - MaxTargetLevel = spellEntry->MaxTargetLevel; - MaxAffectedTargets = spellEntry->MaxAffectedTargets; - SpellFamilyName = spellEntry->SpellFamilyName; - SpellFamilyFlags = spellEntry->SpellFamilyFlags; - DmgClass = spellEntry->DmgClass; - PreventionType = spellEntry->PreventionType; - AreaGroupId = spellEntry->AreaGroupId; + SpellName = spellEntry->SpellName; + Rank = spellEntry->Rank; SchoolMask = spellEntry->SchoolMask; + RuneCostID = spellEntry->runeCostID; + SpellDifficultyId = spellEntry->SpellDifficultyId; + SpellScalingId = spellEntry->SpellScalingId; + SpellAuraOptionsId = spellEntry->SpellAuraOptionsId; + SpellAuraRestrictionsId = spellEntry->SpellAuraRestrictionsId; + SpellCastingRequirementsId = spellEntry->SpellCastingRequirementsId; + SpellCategoriesId = spellEntry->SpellCategoriesId; + SpellClassOptionsId = spellEntry->SpellClassOptionsId; + SpellCooldownsId = spellEntry->SpellCooldownsId; + SpellEquippedItemsId = spellEntry->SpellEquippedItemsId; + SpellInterruptsId = spellEntry->SpellInterruptsId; + SpellLevelsId = spellEntry->SpellLevelsId; + SpellPowerId = spellEntry->SpellPowerId; + SpellReagentsId = spellEntry->SpellReagentsId; + SpellShapeshiftId = spellEntry->SpellShapeshiftId; + SpellTargetRestrictionsId = spellEntry->SpellTargetRestrictionsId; + SpellTotemsId = spellEntry->SpellTotemsId; + + // SpellDifficultyEntry for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) Effects[i] = SpellEffectInfo(spellEntry, this, i); + + // SpellScalingEntry + SpellScalingEntry const* _scaling = GetSpellScaling(); + castTimeMin = _scaling ? _scaling->castTimeMin : 0; + castTimeMax = _scaling ?_scaling->castTimeMax : 0; + castScalingMaxLevel = _scaling ? _scaling->castScalingMaxLevel : 0; + playerClass = _scaling ? _scaling->playerClass : 0; + for (uint8 i = 0; i < 3; ++i) + { + Multiplier[i] = _scaling ? _scaling->Multiplier[i] : 0; + RandomMultiplier[i] = _scaling ? _scaling->RandomMultiplier[i] : 0; + OtherMultiplier[i] = _scaling ? _scaling->OtherMultiplier[i] : 0; + } + CoefBase = _scaling ? _scaling->CoefBase : 0; + CoefLevelBase = _scaling ? _scaling->CoefLevelBase : 0; + + // SpellAuraOptionsEntry + SpellAuraOptionsEntry const* _options = GetSpellAuraOptions(); + ProcFlags = _options ? _options->procFlags : 0; + ProcChance = _options ? _options->procChance : 0; + ProcCharges = _options ? _options->procCharges : 0; + StackAmount = _options ? _options->StackAmount : 0; + + // SpellAuraRestrictionsEntry + SpellAuraRestrictionsEntry const* _aura = GetSpellAuraRestrictions(); + CasterAuraState = _aura ? _aura->CasterAuraState : 0; + TargetAuraState = _aura ? _aura->TargetAuraState : 0; + CasterAuraStateNot = _aura ? _aura->CasterAuraStateNot : 0; + TargetAuraStateNot = _aura ? _aura->TargetAuraStateNot : 0; + CasterAuraSpell = _aura ? _aura->casterAuraSpell : 0; + TargetAuraSpell = _aura ? _aura->targetAuraSpell : 0; + ExcludeCasterAuraSpell = _aura ? _aura->excludeCasterAuraSpell : 0; + ExcludeTargetAuraSpell = _aura ? _aura->excludeTargetAuraSpell : 0; + + // SpellCastingRequirementsEntry + SpellCastingRequirementsEntry const* _castreq = GetSpellCastingRequirements(); + RequiresSpellFocus = _castreq ? _castreq->RequiresSpellFocus : 0; + FacingCasterFlags = _castreq ? _castreq->FacingCasterFlags : 0; + AreaGroupId = _castreq ? _castreq->AreaGroupId : -1; + + // SpellCategoriesEntry + SpellCategoriesEntry const* _categorie = GetSpellCategories(); + Category = _categorie ? _categorie->Category : 0; + Dispel = _categorie ? _categorie->Dispel : 0; + Mechanic = _categorie ? _categorie->Mechanic : 0; + StartRecoveryCategory = _categorie ? _categorie->StartRecoveryCategory : 0; + DmgClass = _categorie ? _categorie->DmgClass : 0; + PreventionType = _categorie ? _categorie->PreventionType : 0; + + // SpellClassOptionsEntry + SpellClassOptionsEntry const* _class = GetSpellClassOptions(); + SpellFamilyName = _class ? _class->SpellFamilyName : 0; + SpellFamilyFlags = _class ? _class->SpellFamilyFlags : flag96(0); + + // SpellCooldownsEntry + SpellCooldownsEntry const* _cooldowns = GetSpellCooldowns(); + RecoveryTime = _cooldowns ? _cooldowns->RecoveryTime : 0; + CategoryRecoveryTime = _cooldowns ? _cooldowns->CategoryRecoveryTime : 0; + StartRecoveryTime = _cooldowns ? _cooldowns->StartRecoveryTime : 0; + + // SpellEquippedItemsEntry + SpellEquippedItemsEntry const* _equipped = GetSpellEquippedItems(); + EquippedItemClass = _equipped ? _equipped->EquippedItemClass : -1; + EquippedItemSubClassMask = _equipped ?_equipped->EquippedItemSubClassMask : -1; + EquippedItemInventoryTypeMask = _equipped ? _equipped->EquippedItemInventoryTypeMask : -1; + + // SpellInterruptsEntry + SpellInterruptsEntry const* _interrupt = GetSpellInterrupts(); + InterruptFlags = _interrupt ? _interrupt->InterruptFlags : 0; + AuraInterruptFlags = _interrupt ? _interrupt->AuraInterruptFlags : 0; + ChannelInterruptFlags = _interrupt ? _interrupt->ChannelInterruptFlags : 0; + + // SpellLevelsEntry + SpellLevelsEntry const* _levels = GetSpellLevels(); + MaxLevel = _levels ? _levels->maxLevel : 0; + BaseLevel = _levels ? _levels->baseLevel : 0; + SpellLevel = _levels ? _levels->spellLevel : 0; + + // SpellPowerEntry + SpellPowerEntry const* _power = GetSpellPower(); + ManaCost = _power ? _power->manaCost : 0; + ManaCostPerlevel = _power ? _power->manaCostPerlevel : 0; + ManaCostPercentage = _power ? _power->ManaCostPercentage : 0; + ManaPerSecond = _power ? _power->manaPerSecond : 0; + + // SpellReagentsEntry + SpellReagentsEntry const* _reagents = GetSpellReagents(); + for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) + Reagent[i] = _reagents ? _reagents->Reagent[i] : 0; + for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i) + ReagentCount[i] = _reagents ? _reagents->ReagentCount[i] : 0; + + // SpellShapeshiftEntry + SpellShapeshiftEntry const* _shapeshift = GetSpellShapeshift(); + Stances = _shapeshift ? _shapeshift->Stances : 0; + StancesNot = _shapeshift ? _shapeshift->StancesNot : 0; + + // SpellTargetRestrictionsEntry + SpellTargetRestrictionsEntry const* _target = GetSpellTargetRestrictions(); + Targets = _target ? _target->Targets : 0; + TargetCreatureType = _target ? _target->TargetCreatureType : 0; + MaxAffectedTargets = _target ? _target->MaxAffectedTargets : 0; + + // SpellTotemsEntry + SpellTotemsEntry const* _totem = GetSpellTotems(); + for (uint8 i = 0; i < 2; ++i) + TotemCategory[i] = _totem ? _totem->TotemCategory[i] : 0; + for (uint8 i = 0; i < 2; ++i) + Totem[i] = _totem ? _totem->Totem[i] : 0; + ExplicitTargetMask = _GetExplicitTargetMask(); ChainEntry = NULL; } @@ -1256,10 +1331,10 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const return SPELL_CAST_OK; bool actAsShifted = false; - SpellShapeshiftEntry const* shapeInfo = NULL; + SpellShapeshiftFormEntry const* shapeInfo = NULL; if (form > 0) { - shapeInfo = sSpellShapeshiftStore.LookupEntry(form); + shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form); if (!shapeInfo) { sLog->outError(LOG_FILTER_SPELLS_AURAS, "GetErrorAtShapeshiftedCast: unknown shapeshift %u", form); @@ -2038,7 +2113,6 @@ uint32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) case POWER_RAGE: case POWER_FOCUS: case POWER_ENERGY: - case POWER_HAPPINESS: powerCost += int32(CalculatePctU(caster->GetMaxPower(Powers(PowerType)), ManaCostPercentage)); break; case POWER_RUNE: @@ -2482,6 +2556,86 @@ bool SpellInfo::_IsPositiveTarget(uint32 targetA, uint32 targetB) return true; } +SpellTargetRestrictionsEntry const* SpellInfo::GetSpellTargetRestrictions() const +{ + return SpellTargetRestrictionsId ? sSpellTargetRestrictionsStore.LookupEntry(SpellTargetRestrictionsId) : NULL; +} + +SpellEquippedItemsEntry const* SpellInfo::GetSpellEquippedItems() const +{ + return SpellEquippedItemsId ? sSpellEquippedItemsStore.LookupEntry(SpellEquippedItemsId) : NULL; +} + +SpellInterruptsEntry const* SpellInfo::GetSpellInterrupts() const +{ + return SpellInterruptsId ? sSpellInterruptsStore.LookupEntry(SpellInterruptsId) : NULL; +} + +SpellLevelsEntry const* SpellInfo::GetSpellLevels() const +{ + return SpellLevelsId ? sSpellLevelsStore.LookupEntry(SpellLevelsId) : NULL; +} + +SpellPowerEntry const* SpellInfo::GetSpellPower() const +{ + return SpellPowerId ? sSpellPowerStore.LookupEntry(SpellPowerId) : NULL; +} + +SpellReagentsEntry const* SpellInfo::GetSpellReagents() const +{ + return SpellReagentsId ? sSpellReagentsStore.LookupEntry(SpellReagentsId) : NULL; +} + +SpellScalingEntry const* SpellInfo::GetSpellScaling() const +{ + return SpellScalingId ? sSpellScalingStore.LookupEntry(SpellScalingId) : NULL; +} + +SpellShapeshiftEntry const* SpellInfo::GetSpellShapeshift() const +{ + return SpellShapeshiftId ? sSpellShapeshiftStore.LookupEntry(SpellShapeshiftId) : NULL; +} + +SpellTotemsEntry const* SpellInfo::GetSpellTotems() const +{ + return SpellTotemsId ? sSpellTotemsStore.LookupEntry(SpellTotemsId) : NULL; +} + +SpellAuraOptionsEntry const* SpellInfo::GetSpellAuraOptions() const +{ + return SpellAuraOptionsId ? sSpellAuraOptionsStore.LookupEntry(SpellAuraOptionsId) : NULL; +} + +SpellAuraRestrictionsEntry const* SpellInfo::GetSpellAuraRestrictions() const +{ + return SpellAuraRestrictionsId ? sSpellAuraRestrictionsStore.LookupEntry(SpellAuraRestrictionsId) : NULL; +} + +SpellCastingRequirementsEntry const* SpellInfo::GetSpellCastingRequirements() const +{ + return SpellCastingRequirementsId ? sSpellCastingRequirementsStore.LookupEntry(SpellCastingRequirementsId) : NULL; +} + +SpellCategoriesEntry const* SpellInfo::GetSpellCategories() const +{ + return SpellCategoriesId ? sSpellCategoriesStore.LookupEntry(SpellCategoriesId) : NULL; +} + +SpellClassOptionsEntry const* SpellInfo::GetSpellClassOptions() const +{ + return SpellClassOptionsId ? sSpellClassOptionsStore.LookupEntry(SpellClassOptionsId) : NULL; +} + +SpellCooldownsEntry const* SpellInfo::GetSpellCooldowns() const +{ + return SpellCooldownsId ? sSpellCooldownsStore.LookupEntry(SpellCooldownsId) : NULL; +} + +SpellEffectEntry const* SpellEntry::GetSpellEffect(uint32 eff) const +{ + return GetSpellEffectEntry(Id, eff); +} + void SpellInfo::_UnloadImplicitTargetConditionLists() { // find the same instances of ConditionList and delete them. diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 54430cd7116..a338b8d627f 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -60,7 +60,7 @@ enum SpellCastTargetFlags TARGET_FLAG_UNIT_MINIPET = 0x00010000, // pguid, used to validate target (if non combat pet) TARGET_FLAG_GLYPH_SLOT = 0x00020000, // used in glyph spells TARGET_FLAG_DEST_TARGET = 0x00040000, // sometimes appears with DEST_TARGET spells (may appear or not for a given spell) - TARGET_FLAG_UNUSED20 = 0x00080000, // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far + TARGET_FLAG_EXTRA_TARGETS = 0x00080000, // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far TARGET_FLAG_UNIT_PASSENGER = 0x00100000, // guessed, used to validate target (if vehicle passenger) TARGET_FLAG_UNIT_MASK = TARGET_FLAG_UNIT | TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY @@ -301,6 +301,7 @@ public: uint32 AttributesEx5; uint32 AttributesEx6; uint32 AttributesEx7; + uint32 AttributesEx8; uint32 AttributesCu; uint32 Stances; uint32 StancesNot; @@ -335,7 +336,6 @@ public: uint32 ManaCost; uint32 ManaCostPerlevel; uint32 ManaPerSecond; - uint32 ManaPerSecondPerLevel; uint32 ManaCostPercentage; uint32 RuneCostID; SpellRangeEntry const* RangeEntry; @@ -351,8 +351,8 @@ public: uint32 SpellVisual[2]; uint32 SpellIconID; uint32 ActiveIconID; - char* SpellName[16]; - char* Rank[16]; + char* SpellName; + char* Rank; uint32 MaxTargetLevel; uint32 MaxAffectedTargets; uint32 SpellFamilyName; @@ -361,10 +361,53 @@ public: uint32 PreventionType; int32 AreaGroupId; uint32 SchoolMask; + uint32 SpellDifficultyId; + uint32 SpellScalingId; + uint32 SpellAuraOptionsId; + uint32 SpellAuraRestrictionsId; + uint32 SpellCastingRequirementsId; + uint32 SpellCategoriesId; + uint32 SpellClassOptionsId; + uint32 SpellCooldownsId; + uint32 SpellEquippedItemsId; + uint32 SpellInterruptsId; + uint32 SpellLevelsId; + uint32 SpellPowerId; + uint32 SpellReagentsId; + uint32 SpellShapeshiftId; + uint32 SpellTargetRestrictionsId; + uint32 SpellTotemsId; + // SpellScalingEntry + int32 castTimeMin; + int32 castTimeMax; + uint32 castScalingMaxLevel; + uint32 playerClass; + float Multiplier[3]; + float RandomMultiplier[3]; + float OtherMultiplier[3]; + float CoefBase; + uint32 CoefLevelBase; SpellEffectInfo Effects[MAX_SPELL_EFFECTS]; uint32 ExplicitTargetMask; SpellChainNode const* ChainEntry; + // struct access functions + SpellTargetRestrictionsEntry const* GetSpellTargetRestrictions() const; + SpellAuraOptionsEntry const* GetSpellAuraOptions() const; + SpellAuraRestrictionsEntry const* GetSpellAuraRestrictions() const; + SpellCastingRequirementsEntry const* GetSpellCastingRequirements() const; + SpellCategoriesEntry const* GetSpellCategories() const; + SpellClassOptionsEntry const* GetSpellClassOptions() const; + SpellCooldownsEntry const* GetSpellCooldowns() const; + SpellEquippedItemsEntry const* GetSpellEquippedItems() const; + SpellInterruptsEntry const* GetSpellInterrupts() const; + SpellLevelsEntry const* GetSpellLevels() const; + SpellPowerEntry const* GetSpellPower() const; + SpellReagentsEntry const* GetSpellReagents() const; + SpellScalingEntry const* GetSpellScaling() const; + SpellShapeshiftEntry const* GetSpellShapeshift() const; + SpellTotemsEntry const* GetSpellTotems() const; + SpellInfo(SpellEntry const* spellEntry); ~SpellInfo(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index e2b7df2889d..e887f8caa22 100755..100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2933,7 +2933,7 @@ void SpellMgr::LoadDbcDataCorrections() { uint32 oldMSTime = getMSTime(); - SpellEntry* spellInfo = NULL; + /*SpellEntry* spellInfo = NULL; for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i) { spellInfo = (SpellEntry*)sSpellStore.LookupEntry(i); @@ -3564,7 +3564,6 @@ void SpellMgr::LoadDbcDataCorrections() properties->Type = SUMMON_TYPE_TOTEM; properties = const_cast<SummonPropertiesEntry*>(sSummonPropertiesStore.LookupEntry(647)); // 52893 properties->Type = SUMMON_TYPE_TOTEM; - + */ sLog->outInfo(LOG_FILTER_SPELLS_AURAS, ">> Loading spell dbc data corrections in %u ms", GetMSTimeDiffToNow(oldMSTime)); - } diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index d03ffbbb1f6..fc64a4b8b52 100755 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -31,34 +31,34 @@ inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; } // GM ticket GmTicket::GmTicket() { } -GmTicket::GmTicket(Player* player, WorldPacket& recv_data) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED) +GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED) { _id = sTicketMgr->GenerateTicketId(); _playerName = player->GetName(); _playerGuid = player->GetGUID(); uint32 mapId; - recv_data >> mapId; // Map is sent as UInt32! + recvData >> mapId; // Map is sent as UInt32! _mapId = mapId; - recv_data >> _posX; - recv_data >> _posY; - recv_data >> _posZ; - recv_data >> _message; + recvData >> _posX; + recvData >> _posY; + recvData >> _posZ; + recvData >> _message; uint32 needResponse; - recv_data >> needResponse; + recvData >> needResponse; _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default) uint8 unk1; - recv_data >> unk1; // Requests further GM interaction on a ticket to which a GM has already responded + recvData >> unk1; // Requests further GM interaction on a ticket to which a GM has already responded - recv_data.rfinish(); + recvData.rfinish(); /* - recv_data >> uint32(count); // text lines + recvData >> uint32(count); // text lines for (int i = 0; i < count; i++) - recv_data >> uint32(); + recvData >> uint32(); if (something) - recv_data >> uint32(); + recvData >> uint32(); else compressed uint32 + string; */ @@ -373,12 +373,12 @@ void TicketMgr::SendTicket(WorldSession* session, GmTicket* ticket) const status = GMTICKET_STATUS_HASTEXT; } - WorldPacket data(SMSG_GMTICKET_GETTICKET, (4 + 4 + (ticket ? message.length() + 1 + 4 + 4 + 4 + 1 + 1 : 0))); + WorldPacket data(SMSG_GMTICKET_GETTICKET, (4 + (ticket ? 4 + message.length() + 1 + 4 + 4 + 4 + 1 + 1 : 0))); data << uint32(status); // standard 0x0A, 0x06 if text present - data << uint32(ticket ? ticket->GetId() : 0); // ticketID if (ticket) { + data << uint32(ticket->GetId()); // ticketID data << message.c_str(); // ticket text data << uint8(0x7); // ticket category; why is this hardcoded? does it make a diff re: client? @@ -386,5 +386,6 @@ void TicketMgr::SendTicket(WorldSession* session, GmTicket* ticket) const // Now we need to go through the client logic for displaying various levels of ticket load ticket->WritePacket(data); } + session->SendPacket(&data); } diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index be8b4063d84..0e78ac72692 100755 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -82,7 +82,7 @@ class GmTicket { public: GmTicket(); - explicit GmTicket(Player* player, WorldPacket& recv_data); + explicit GmTicket(Player* player, WorldPacket& recvData); ~GmTicket(); bool IsClosed() const { return _closedBy; } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index ab3b7150089..f8a08200c42 100755..100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -45,6 +45,7 @@ #include "GroupMgr.h" #include "Chat.h" #include "DBCStores.h" +#include "DB2Stores.h" #include "LootMgr.h" #include "ItemEnchantmentMgr.h" #include "MapManager.h" @@ -271,7 +272,7 @@ void World::AddSession_(WorldSession* s) return; } - s->SendAuthResponse(AUTH_OK, true); + s->SendAuthResponse(AUTH_OK, false); s->SendAddonsInfo(); s->SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION)); s->SendTutorialsData(); @@ -327,7 +328,7 @@ void World::AddQueuedPlayer(WorldSession* sess) m_QueuedPlayer.push_back(sess); // The 1st SMSG_AUTH_RESPONSE needs to contain other info too. - sess->SendAuthResponse(AUTH_WAIT_QUEUE, false, GetQueuePos(sess)); + sess->SendAuthResponse(AUTH_WAIT_QUEUE, true, GetQueuePos(sess)); } bool World::RemoveQueuedPlayer(WorldSession* sess) @@ -772,11 +773,11 @@ void World::LoadConfigSettings(bool reload) sLog->outError(LOG_FILTER_GENERAL, "StartPlayerMoney (%i) must be in range 0..%u. Set to %u.", m_int_configs[CONFIG_START_PLAYER_MONEY], MAX_MONEY_AMOUNT, 0); m_int_configs[CONFIG_START_PLAYER_MONEY] = 0; } - else if (m_int_configs[CONFIG_START_PLAYER_MONEY] > MAX_MONEY_AMOUNT) + else if (m_int_configs[CONFIG_START_PLAYER_MONEY] > 0x7FFFFFFF-1) // TODO: (See MAX_MONEY_AMOUNT) { sLog->outError(LOG_FILTER_GENERAL, "StartPlayerMoney (%i) must be in range 0..%u. Set to %u.", - m_int_configs[CONFIG_START_PLAYER_MONEY], MAX_MONEY_AMOUNT, MAX_MONEY_AMOUNT); - m_int_configs[CONFIG_START_PLAYER_MONEY] = MAX_MONEY_AMOUNT; + m_int_configs[CONFIG_START_PLAYER_MONEY], 0x7FFFFFFF-1, 0x7FFFFFFF-1); + m_int_configs[CONFIG_START_PLAYER_MONEY] = 0x7FFFFFFF-1; } m_int_configs[CONFIG_MAX_HONOR_POINTS] = ConfigMgr::GetIntDefault("MaxHonorPoints", 75000); @@ -1256,12 +1257,7 @@ void World::SetInitialWorldSettings() //No SQL injection as values are treated as integers // not send custom type REALM_FFA_PVP to realm list - uint32 server_type; - if (IsFFAPvPRealm()) - server_type = REALM_TYPE_PVP; - else - server_type = getIntConfig(CONFIG_GAME_TYPE); - + uint32 server_type = IsFFAPvPRealm() ? REALM_TYPE_PVP : getIntConfig(CONFIG_GAME_TYPE); uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE); LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query @@ -1274,6 +1270,7 @@ void World::SetInitialWorldSettings() ///- Load the DBC files sLog->outInfo(LOG_FILTER_GENERAL, "Initialize data stores..."); LoadDBCStores(m_dataPath); + LoadDB2Stores(m_dataPath); DetectDBCLang(); sLog->outInfo(LOG_FILTER_GENERAL, "Loading spell dbc data corrections..."); @@ -1306,7 +1303,6 @@ void World::SetInitialWorldSettings() sObjectMgr->LoadCreatureLocales(); sObjectMgr->LoadGameObjectLocales(); sObjectMgr->LoadItemLocales(); - sObjectMgr->LoadItemSetNameLocales(); sObjectMgr->LoadQuestLocales(); sObjectMgr->LoadNpcTextLocales(); sObjectMgr->LoadPageTextLocales(); @@ -1362,14 +1358,17 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_GENERAL, "Loading Item Random Enchantments Table..."); LoadRandomEnchantmentsTable(); - sLog->outInfo(LOG_FILTER_GENERAL, "Loading Disables"); - DisableMgr::LoadDisables(); // must be before loading quests and items + sLog->outInfo(LOG_FILTER_GENERAL, "Loading Disables..."); + DisableMgr::LoadDisables(); // must be before loading quests and items - sLog->outInfo(LOG_FILTER_GENERAL, "Loading Items..."); // must be after LoadRandomEnchantmentsTable and LoadPageTexts + sLog->outInfo(LOG_FILTER_GENERAL, "Loading Items..."); // must be after LoadRandomEnchantmentsTable and LoadPageTexts sObjectMgr->LoadItemTemplates(); - sLog->outInfo(LOG_FILTER_GENERAL, "Loading Item set names..."); // must be after LoadItemPrototypes - sObjectMgr->LoadItemSetNames(); + sLog->outInfo(LOG_FILTER_GENERAL, "Loading Item Extra Data..."); // must be after LoadItemPrototypes + sObjectMgr->LoadItemTemplateAddon(); + + sLog->outInfo(LOG_FILTER_GENERAL, "Loading Item Scripts..."); // must be after LoadItemPrototypes + sObjectMgr->LoadItemScriptNames(); sLog->outInfo(LOG_FILTER_GENERAL, "Loading Creature Model Based Info Data..."); sObjectMgr->LoadCreatureModelInfo(); @@ -1748,6 +1747,12 @@ void World::SetInitialWorldSettings() LoadCharacterNameData(); + sLog->outInfo(LOG_FILTER_GENERAL, "Initializing Opcodes..."); + InitOpcodes(); + + sLog->outInfo(LOG_FILTER_GENERAL, "Loading hotfix info..."); + sObjectMgr->LoadHotfixData(); + uint32 startupDuration = GetMSTimeDiffToNow(startupBegin); sLog->outInfo(LOG_FILTER_GENERAL, "WORLD: World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); @@ -1756,15 +1761,15 @@ void World::SetInitialWorldSettings() void World::DetectDBCLang() { - uint8 m_lang_confid = ConfigMgr::GetIntDefault("DBC.Locale", 255); + uint8 m_lang_confid = ConfigMgr::GetIntDefault("DBC.Locale", 0); - if (m_lang_confid != 255 && m_lang_confid >= TOTAL_LOCALES) + if (m_lang_confid >= TOTAL_LOCALES) { sLog->outError(LOG_FILTER_GENERAL, "Incorrect DBC.Locale! Must be >= 0 and < %d (set to 0)", TOTAL_LOCALES); m_lang_confid = LOCALE_enUS; } - ChrRacesEntry const* race = sChrRacesStore.LookupEntry(1); + /*ChrRacesEntry const* race = sChrRacesStore.LookupEntry(1); std::string availableLocalsStr; @@ -1790,12 +1795,11 @@ void World::DetectDBCLang() { sLog->outError(LOG_FILTER_GENERAL, "Unable to determine your DBC Locale! (corrupt DBC?)"); exit(1); - } - - m_defaultDbcLocale = LocaleConstant(default_locale); + }*/ - sLog->outInfo(LOG_FILTER_GENERAL, "Using %s DBC Locale as default. All available DBC locales: %s", localeNames[m_defaultDbcLocale], availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str()); + m_defaultDbcLocale = LocaleConstant(m_lang_confid); + sLog->outInfo(LOG_FILTER_GENERAL, "Using %s DBC Locale", localeNames[m_defaultDbcLocale]); } void World::RecordTimeDiff(const char *text, ...) @@ -2594,8 +2598,10 @@ void World::SendAutoBroadcast() else if (abcenter == 1) { - WorldPacket data(SMSG_NOTIFICATION, (msg.size()+1)); - data << msg; + WorldPacket data(SMSG_NOTIFICATION, 2 + msg.length()); + data.WriteBits(msg.length(), 13); + data.FlushBits(); + data.append(msg.c_str(), msg.length()); sWorld->SendGlobalMessage(&data); } @@ -2603,8 +2609,10 @@ void World::SendAutoBroadcast() { sWorld->SendWorldText(LANG_AUTO_BROADCAST, msg.c_str()); - WorldPacket data(SMSG_NOTIFICATION, (msg.size()+1)); - data << msg; + WorldPacket data(SMSG_NOTIFICATION, 2 + msg.length()); + data.WriteBits(msg.length(), 13); + data.FlushBits(); + data.append(msg.c_str(), msg.length()); sWorld->SendGlobalMessage(&data); } @@ -2796,8 +2804,8 @@ void World::LoadDBVersion() if (result) { Field* fields = result->Fetch(); - m_DBVersion = fields[0].GetString(); + m_DBVersion = fields[0].GetString(); // will be overwrite by config values if different and non-0 m_int_configs[CONFIG_CLIENTCACHE_VERSION] = fields[1].GetUInt32(); } diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index f0dbc3c84ad..65377eacf4b 100755 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -45,11 +45,19 @@ class SystemMgr; // ServerMessages.dbc enum ServerMessageType { - SERVER_MSG_SHUTDOWN_TIME = 1, - SERVER_MSG_RESTART_TIME = 2, - SERVER_MSG_STRING = 3, - SERVER_MSG_SHUTDOWN_CANCELLED = 4, - SERVER_MSG_RESTART_CANCELLED = 5 + SERVER_MSG_SHUTDOWN_TIME = 1, + SERVER_MSG_RESTART_TIME = 2, + SERVER_MSG_STRING = 3, + SERVER_MSG_SHUTDOWN_CANCELLED = 4, + SERVER_MSG_RESTART_CANCELLED = 5, + SERVER_MSG_BG_SHUTDOWN_TIME = 6, + SERVER_MSG_BG_RESTART_TIME = 7, + SERVER_MSG_INSTANCE_SHUTDOWN_TIME = 8, + SERVER_MSG_INSTANCE_RESTART_TIME = 9, + SERVER_MSG_CONTENT_READY = 10, + SERVER_MSG_TICKET_SERVICED_SOON = 11, + SERVER_MSG_WAIT_TIME_UNAVAILABLE = 12, + SERVER_MSG_TICKET_WAIT_TIME = 13, }; enum ShutdownMask @@ -217,8 +225,10 @@ enum WorldIntConfigs CONFIG_START_PLAYER_MONEY, CONFIG_MAX_HONOR_POINTS, CONFIG_START_HONOR_POINTS, - CONFIG_MAX_ARENA_POINTS, - CONFIG_START_ARENA_POINTS, + CONFIG_MAX_JUSTICE_POINTS, + CONFIG_START_JUSTICE_POINTS, + CONFIG_MAX_ARENA_POINTS,//todo: remove + CONFIG_START_ARENA_POINTS,//todo: remove CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL_DIFFERENCE, CONFIG_INSTANCE_RESET_TIME_HOUR, @@ -628,7 +638,7 @@ class World /// Get the maximum skill level a player can reach uint16 GetConfigMaxSkillValue() const { - uint8 lvl = getIntConfig(CONFIG_MAX_PLAYER_LEVEL); + uint8 lvl = uint8(getIntConfig(CONFIG_MAX_PLAYER_LEVEL)); return lvl > 60 ? 300 + ((lvl - 60) * 75) / 10 : lvl*5; } diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index f5fbfa33cae..87948391500 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -275,7 +275,7 @@ public: if (titleInfo && target->HasTitle(titleInfo)) { - std::string name = titleInfo->name[loc]; + std::string name = titleInfo->name; if (name.empty()) continue; @@ -471,7 +471,7 @@ public: { FactionState const& faction = itr->second; FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID); - char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#"; + char const* factionName = factionEntry ? factionEntry->name : "#Not found#"; ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry); std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]); std::ostringstream ss; diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 7f25a11bcdd..c7b766cacd0 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -310,7 +310,7 @@ public: uint32 opcode; parsedStream >> opcode; - WorldPacket data(opcode, 0); + WorldPacket data(Opcodes(opcode), 0); while (!parsedStream.eof()) { @@ -416,7 +416,7 @@ public: } sLog->outDebug(LOG_FILTER_NETWORKIO, "Sending opcode %u", data.GetOpcode()); data.hexlike(); - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(&data, true); handler->PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName()); return true; } @@ -1325,7 +1325,7 @@ public: { Player* player = handler->GetSession()->GetPlayer(); - sLog->outInfo(LOG_FILTER_SQL_DEV, "(@PATH, XX, %.3f, %.3f, %.5f, 0,0, 0,100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + sLog->outInfo(LOG_FILTER_SQL_DEV, "(@PATH, XX, %.3f, %.3f, %.5f, 0, 0, 0, 100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); handler->PSendSysMessage("Waypoint SQL written to SQL Developer log"); return true; diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 3dfc6f9c7e8..0230ebcd1e7 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -96,19 +96,16 @@ public: if (!target) target = handler->GetSession()->GetPlayer(); - WorldPacket data(12); + WorldPacket data; if (strncmp(args, "on", 3) == 0) - data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + target->SendMovementSetCanFly(true); else if (strncmp(args, "off", 4) == 0) - data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + target->SendMovementSetCanFly(false); else { handler->SendSysMessage(LANG_USE_BOL); return false; } - data.append(target->GetPackGUID()); - data << uint32(0); // unknown - target->SendMessageToSet(&data, true); handler->PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, handler->GetNameLink(target).c_str(), args); return true; } diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index 5c16a0963d3..5a0fd28e81a 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -435,7 +435,7 @@ public: AuraApplication const* aurApp = itr->second; Aura const* aura = aurApp->GetBase(); - char const* name = aura->GetSpellInfo()->SpellName[handler->GetSessionDbcLocale()]; + char const* name = aura->GetSpellInfo()->SpellName; std::ostringstream ss_name; ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r"; diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index 951ebc7714b..3a2ef366ace 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -94,48 +94,30 @@ public: AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(areaflag); if (areaEntry) { - int locale = handler->GetSessionDbcLocale(); - std::string name = areaEntry->area_name[locale]; + std::string name = areaEntry->area_name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = areaEntry->area_name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send area in "id - [name]" format - std::ostringstream ss; - if (handler->GetSession()) - ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << ' ' << localeNames[locale]<< "]|h|r"; - else - ss << areaEntry->ID << " - " << name << ' ' << localeNames[locale]; + // send area in "id - [name]" format + std::ostringstream ss; + if (handler->GetSession()) + ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name<< "]|h|r"; + else + ss << areaEntry->ID << " - " << name; - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; - } + if (!found) + found = true; } } @@ -301,77 +283,58 @@ public: for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id) { - FactionEntry const* factionEntry = sFactionStore.LookupEntry(id); - if (factionEntry) + if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(id)) { FactionState const* factionState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL; - int locale = handler->GetSessionDbcLocale(); - std::string name = factionEntry->name[locale]; + std::string name = factionEntry->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = factionEntry->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format - // or "id - [faction] [no reputation]" format - std::ostringstream ss; - if (handler->GetSession()) - ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << ' ' << localeNames[locale] << "]|h|r"; - else - ss << id << " - " << name << ' ' << localeNames[locale]; + // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format + // or "id - [faction] [no reputation]" format + std::ostringstream ss; + if (handler->GetSession()) + ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << "]|h|r"; + else + ss << id << " - " << name; - if (factionState) // and then target != NULL also - { - uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry); - std::string rankName = handler->GetTrinityString(index); - - ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; - - if (factionState->Flags & FACTION_FLAG_VISIBLE) - ss << handler->GetTrinityString(LANG_FACTION_VISIBLE); - if (factionState->Flags & FACTION_FLAG_AT_WAR) - ss << handler->GetTrinityString(LANG_FACTION_ATWAR); - if (factionState->Flags & FACTION_FLAG_PEACE_FORCED) - ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED); - if (factionState->Flags & FACTION_FLAG_HIDDEN) - ss << handler->GetTrinityString(LANG_FACTION_HIDDEN); - if (factionState->Flags & FACTION_FLAG_INVISIBLE_FORCED) - ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); - if (factionState->Flags & FACTION_FLAG_INACTIVE) - ss << handler->GetTrinityString(LANG_FACTION_INACTIVE); - } - else - ss << handler->GetTrinityString(LANG_FACTION_NOREPUTATION); + if (factionState) // and then target != NULL also + { + uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry); + std::string rankName = handler->GetTrinityString(index); + + ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')'; + + if (factionState->Flags & FACTION_FLAG_VISIBLE) + ss << handler->GetTrinityString(LANG_FACTION_VISIBLE); + if (factionState->Flags & FACTION_FLAG_AT_WAR) + ss << handler->GetTrinityString(LANG_FACTION_ATWAR); + if (factionState->Flags & FACTION_FLAG_PEACE_FORCED) + ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED); + if (factionState->Flags & FACTION_FLAG_HIDDEN) + ss << handler->GetTrinityString(LANG_FACTION_HIDDEN); + if (factionState->Flags & FACTION_FLAG_INVISIBLE_FORCED) + ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED); + if (factionState->Flags & FACTION_FLAG_INACTIVE) + ss << handler->GetTrinityString(LANG_FACTION_INACTIVE); + } + else + ss << handler->GetTrinityString(LANG_FACTION_NOREPUTATION); - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; - } + if (!found) + found = true; } } @@ -486,45 +449,27 @@ public: ItemSetEntry const* set = sItemSetStore.LookupEntry(id); if (set) { - int locale = handler->GetSessionDbcLocale(); - std::string name = set->name[locale]; + std::string name = set->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = set->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send item set in "id - [namedlink locale]" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), localeNames[locale]); - else - handler->PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), localeNames[locale]); + // send item set in "id - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), ""); + else + handler->PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), ""); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -767,59 +712,41 @@ public: SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(id); if (skillInfo) { - int locale = handler->GetSessionDbcLocale(); - std::string name = skillInfo->name[locale]; + std::string name = skillInfo->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = skillInfo->name[locale]; - if (name.empty()) - continue; + continue; - if (Utf8FitTo(name, wNamePart)) - break; - } + if (maxResults && count++ == maxResults) + { + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; } - if (locale < TOTAL_LOCALES) + char valStr[50] = ""; + char const* knownStr = ""; + if (target && target->HasSkill(id)) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } - - char valStr[50] = ""; - char const* knownStr = ""; - if (target && target->HasSkill(id)) - { - knownStr = handler->GetTrinityString(LANG_KNOWN); - uint32 curValue = target->GetPureSkillValue(id); - uint32 maxValue = target->GetPureMaxSkillValue(id); - uint32 permValue = target->GetSkillPermBonusValue(id); - uint32 tempValue = target->GetSkillTempBonusValue(id); - - char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES); - snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue); - } + knownStr = handler->GetTrinityString(LANG_KNOWN); + uint32 curValue = target->GetPureSkillValue(id); + uint32 maxValue = target->GetPureMaxSkillValue(id); + uint32 permValue = target->GetSkillPermBonusValue(id); + uint32 tempValue = target->GetSkillTempBonusValue(id); + + char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES); + snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue); + } - // send skill in "id - [namedlink locale]" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), localeNames[locale], knownStr, valStr); - else - handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), localeNames[locale], knownStr, valStr); + // send skill in "id - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), "", knownStr, valStr); + else + handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), "", knownStr, valStr); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -855,83 +782,63 @@ public: SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id); if (spellInfo) { - int locale = handler->GetSessionDbcLocale(); - std::string name = spellInfo->SpellName[locale]; + std::string name = spellInfo->SpellName; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = spellInfo->SpellName[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - bool known = target && target->HasSpell(id); - bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL); + bool known = target && target->HasSpell(id); + bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL); - SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell); + SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell); - uint32 talentCost = GetTalentSpellCost(id); + uint32 talentCost = GetTalentSpellCost(id); - bool talent = (talentCost > 0); - bool passive = spellInfo->IsPassive(); - bool active = target && target->HasAura(id); + bool talent = (talentCost > 0); + bool passive = spellInfo->IsPassive(); + bool active = target && target->HasAura(id); - // unit32 used to prevent interpreting uint8 as char at output - // find rank of learned spell for learning spell, or talent rank - uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank(); + // unit32 used to prevent interpreting uint8 as char at output + // find rank of learned spell for learning spell, or talent rank + uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank(); - // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format - std::ostringstream ss; - if (handler->GetSession()) - ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; - else - ss << id << " - " << name; + // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format + std::ostringstream ss; + if (handler->GetSession()) + ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name; + else + ss << id << " - " << name; - // include rank in link name - if (rank) - ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank; + // include rank in link name + if (rank) + ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank; - if (handler->GetSession()) - ss << ' ' << localeNames[locale] << "]|h|r"; - else - ss << ' ' << localeNames[locale]; + if (handler->GetSession()) + ss << "]|h|r"; - if (talent) - ss << handler->GetTrinityString(LANG_TALENT); - if (passive) - ss << handler->GetTrinityString(LANG_PASSIVE); - if (learn) - ss << handler->GetTrinityString(LANG_LEARN); - if (known) - ss << handler->GetTrinityString(LANG_KNOWN); - if (active) - ss << handler->GetTrinityString(LANG_ACTIVE); + if (talent) + ss << handler->GetTrinityString(LANG_TALENT); + if (passive) + ss << handler->GetTrinityString(LANG_PASSIVE); + if (learn) + ss << handler->GetTrinityString(LANG_LEARN); + if (known) + ss << handler->GetTrinityString(LANG_KNOWN); + if (active) + ss << handler->GetTrinityString(LANG_ACTIVE); - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -964,47 +871,29 @@ public: TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(id); if (nodeEntry) { - int locale = handler->GetSessionDbcLocale(); - std::string name = nodeEntry->name[locale]; + std::string name = nodeEntry->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = nodeEntry->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && count++ == maxResults) { - if (maxResults && count++ == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), localeNames[locale], - nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); - else - handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[locale], - nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); + // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), "", + nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); + else + handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), "", + nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z); - if (!found) - found = true; - } + if (!found) + found = true; } } if (!found) @@ -1101,53 +990,35 @@ public: CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id); if (titleInfo) { - int locale = handler->GetSessionDbcLocale(); - std::string name = titleInfo->name[locale]; + std::string name = titleInfo->name; if (name.empty()) continue; if (!Utf8FitTo(name, wNamePart)) - { - locale = 0; - for (; locale < TOTAL_LOCALES; ++locale) - { - if (locale == handler->GetSessionDbcLocale()) - continue; - - name = titleInfo->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; - } - } + continue; - if (locale < TOTAL_LOCALES) + if (maxResults && counter == maxResults) { - if (maxResults && counter == maxResults) - { - handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); - return true; - } + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; + } - char const* knownStr = target && target->HasTitle(titleInfo) ? handler->GetTrinityString(LANG_KNOWN) : ""; + char const* knownStr = target && target->HasTitle(titleInfo) ? handler->GetTrinityString(LANG_KNOWN) : ""; - char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index - ? handler->GetTrinityString(LANG_ACTIVE) - : ""; + char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index + ? handler->GetTrinityString(LANG_ACTIVE) + : ""; - char titleNameStr[80]; - snprintf(titleNameStr, 80, name.c_str(), targetName); + char titleNameStr[80]; + snprintf(titleNameStr, 80, name.c_str(), targetName); - // send title in "id (idx:idx) - [namedlink locale]" format - if (handler->GetSession()) - handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[locale], knownStr, activeStr); - else - handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, localeNames[locale], knownStr, activeStr); + // send title in "id (idx:idx) - [namedlink locale]" format + if (handler->GetSession()) + handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, "", knownStr, activeStr); + else + handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, "", knownStr, activeStr); - ++counter; - } + ++counter; } } if (counter == 0) // if counter == 0 then we found nth diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 80847d7dec4..d8026ccd10a 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -220,9 +220,9 @@ public: handler->PSendSysMessage("no VMAP available for area info");
handler->PSendSysMessage(LANG_MAP_POSITION,
- object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
- zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
- areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ object->GetMapId(), (mapEntry ? mapEntry->name : "<unknown>"),
+ zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"),
+ areaId, (areaEntry ? areaEntry->area_name : "<unknown>"),
object->GetPhaseMask(),
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
@@ -2212,9 +2212,9 @@ public: return false;
if (strncmp(args, "on", 3) == 0)
- player->SetMovement(MOVE_WATER_WALK); // ON
+ player->SendMovementSetWaterWalking(true);
else if (strncmp(args, "off", 4) == 0)
- player->SetMovement(MOVE_LAND_WALK); // OFF
+ player->SendMovementSetWaterWalking(false);
else
{
handler->SendSysMessage(LANG_USE_BOL);
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index a88c765c596..dee8a52debd 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -25,6 +25,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ObjectMgr.h" #include "Chat.h" +#include <stdlib.h> class modify_commandscript : public CommandScript { @@ -968,14 +969,14 @@ public: target->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); target->Mount(mId); - WorldPacket data(SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+1+4)); + WorldPacket data(SMSG_MOVE_SET_RUN_SPEED, (8+4+1+4)); data.append(target->GetPackGUID()); data << (uint32)0; data << (uint8)0; //new 2.1.0 data << float(speed); target->SendMessageToSet(&data, true); - data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4)); + data.Initialize(SMSG_MOVE_SET_SWIM_SPEED, (8+4+4)); data.append(target->GetPackGUID()); data << (uint32)0; data << float(speed); @@ -1004,11 +1005,11 @@ public: int32 addmoney = atoi((char*)args); - uint32 moneyuser = target->GetMoney(); + uint64 moneyuser = target->GetMoney(); if (addmoney < 0) { - int32 newmoney = int32(moneyuser) + addmoney; + int64 newmoney = int32(moneyuser) + addmoney; sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_CURRENT_MONEY), moneyuser, addmoney, newmoney); if (newmoney <= 0) @@ -1032,18 +1033,17 @@ public: } else { - handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, addmoney, handler->GetNameLink(target).c_str()); + handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, uint32(addmoney), handler->GetNameLink(target).c_str()); if (handler->needReportToTarget(target)) - (ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), addmoney); + (ChatHandler(target)).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), uint32(addmoney)); if (addmoney >=MAX_MONEY_AMOUNT) target->SetMoney(MAX_MONEY_AMOUNT); else - target->ModifyMoney(addmoney); + target->ModifyMoney(int64(addmoney)); } - sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_NEW_MONEY), moneyuser, addmoney, target->GetMoney()); - + sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_NEW_MONEY), moneyuser, uint32(addmoney), target->GetMoney()); return true; } @@ -1102,7 +1102,7 @@ public: return true; } - static bool HandleModifyHonorCommand (ChatHandler* handler, const char* args) + static bool HandleModifyHonorCommand(ChatHandler* handler, const char* args) { if (!*args) return false; @@ -1121,9 +1121,9 @@ public: int32 amount = (uint32)atoi(args); - target->ModifyHonorPoints(amount); + target->ModifyCurrency(CURRENCY_TYPE_HONOR_POINTS, amount); - handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetHonorPoints()); + handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetCurrency(CURRENCY_TYPE_HONOR_POINTS)); return true; } @@ -1237,7 +1237,7 @@ public: } target->GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false); - handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[handler->GetSessionDbcLocale()], factionId, + handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name, factionId, handler->GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); return true; } @@ -1311,9 +1311,9 @@ public: int32 amount = (uint32)atoi(args); - target->ModifyArenaPoints(amount); + target->ModifyCurrency(CURRENCY_TYPE_CONQUEST_POINTS, amount); - handler->PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, handler->GetNameLink(target).c_str(), target->GetArenaPoints()); + handler->PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, handler->GetNameLink(target).c_str(), target->GetCurrency(CURRENCY_TYPE_CONQUEST_POINTS)); return true; } diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 3bb29f8abfe..93b450bab0f 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -102,7 +102,6 @@ public: { "gossip_menu_option", SEC_ADMINISTRATOR, true, &HandleReloadGossipMenuOptionCommand, "", NULL }, { "item_enchantment_template", SEC_ADMINISTRATOR, true, &HandleReloadItemEnchantementsCommand, "", NULL }, { "item_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesItemCommand, "", NULL }, - { "item_set_names", SEC_ADMINISTRATOR, true, &HandleReloadItemSetNamesCommand, "", NULL }, { "lfg_dungeon_rewards", SEC_ADMINISTRATOR, true, &HandleReloadLfgRewardsCommand, "", NULL }, { "locales_achievement_reward", SEC_ADMINISTRATOR, true, &HandleReloadLocalesAchievementRewardCommand, "", NULL }, { "locales_creature", SEC_ADMINISTRATOR, true, &HandleReloadLocalesCreatureCommand, "", NULL }, @@ -110,7 +109,6 @@ public: { "locales_gameobject", SEC_ADMINISTRATOR, true, &HandleReloadLocalesGameobjectCommand, "", NULL }, { "locales_gossip_menu_option", SEC_ADMINISTRATOR, true, &HandleReloadLocalesGossipMenuOptionCommand, "", NULL }, { "locales_item", SEC_ADMINISTRATOR, true, &HandleReloadLocalesItemCommand, "", NULL }, - { "locales_item_set_name", SEC_ADMINISTRATOR, true, &HandleReloadLocalesItemSetNameCommand, "", NULL }, { "locales_npc_text", SEC_ADMINISTRATOR, true, &HandleReloadLocalesNpcTextCommand, "", NULL }, { "locales_page_text", SEC_ADMINISTRATOR, true, &HandleReloadLocalesPageTextCommand, "", NULL }, { "locales_points_of_interest", SEC_ADMINISTRATOR, true, &HandleReloadLocalesPointsOfInterestCommand, "", NULL }, @@ -946,14 +944,6 @@ public: return true; } - static bool HandleReloadItemSetNamesCommand(ChatHandler* handler, const char* /*args*/) - { - sLog->outInfo(LOG_FILTER_GENERAL, "Re-Loading Item set names..."); - sObjectMgr->LoadItemSetNames(); - handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded."); - return true; - } - static bool HandleReloadGameObjectScriptsCommand(ChatHandler* handler, const char* args) { if (sScriptMgr->IsScriptScheduled()) @@ -1208,14 +1198,6 @@ public: return true; } - static bool HandleReloadLocalesItemSetNameCommand(ChatHandler* handler, const char* /*args*/) - { - sLog->outInfo(LOG_FILTER_GENERAL, "Re-Loading Locales Item set name... "); - sObjectMgr->LoadItemSetNameLocales(); - handler->SendGlobalGMSysMessage("DB table `locales_item_set_name` reloaded."); - return true; - } - static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler, const char* /*args*/) { sLog->outInfo(LOG_FILTER_GENERAL, "Re-Loading Locales NPC Text ... "); diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index 82fb409faa7..b0bf3e03f58 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -62,7 +62,7 @@ public: if (target) target->GetAchievementMgr().Reset(); else - AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid)); + AchievementMgr<Player>::DeleteFromDB(GUID_LOPART(targetGuid)); return true; } @@ -73,11 +73,8 @@ public: if (!handler->extractPlayerTarget((char*)args, &target)) return false; - target->SetHonorPoints(0); target->SetUInt32Value(PLAYER_FIELD_KILLS, 0); target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); - target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); - target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL); return true; @@ -234,7 +231,7 @@ public: if (target) { - target->resetTalents(true); + target->ResetTalents(true); target->SendTalentsInfoData(false); ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS); if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp index f35f6baca98..0a3b430ab2c 100644 --- a/src/server/scripts/Commands/cs_titles.cpp +++ b/src/server/scripts/Commands/cs_titles.cpp @@ -138,7 +138,7 @@ public: char const* targetName = target->GetName(); char titleNameStr[80]; - snprintf(titleNameStr, 80, titleInfo->name[handler->GetSessionDbcLocale()], targetName); + snprintf(titleNameStr, 80, titleInfo->name, targetName); target->SetTitle(titleInfo); handler->PSendSysMessage(LANG_TITLE_ADD_RES, id, titleNameStr, tNameLink.c_str()); @@ -187,7 +187,7 @@ public: char const* targetName = target->GetName(); char titleNameStr[80]; - snprintf(titleNameStr, 80, titleInfo->name[handler->GetSessionDbcLocale()], targetName); + snprintf(titleNameStr, 80, titleInfo->name, targetName); handler->PSendSysMessage(LANG_TITLE_REMOVE_RES, id, titleNameStr, tNameLink.c_str()); diff --git a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp index 8e0fb9ff411..c2dab8d6c9e 100644 --- a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp +++ b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp @@ -237,7 +237,7 @@ class instance_deadmines : public InstanceMapScript void DoPlaySound(GameObject* unit, uint32 sound) { - WorldPacket data(4); + WorldPacket data; data.SetOpcode(SMSG_PLAY_SOUND); data << uint32(sound); unit->SendMessageToSet(&data, false); @@ -245,7 +245,7 @@ class instance_deadmines : public InstanceMapScript void DoPlaySoundCreature(Unit* unit, uint32 sound) { - WorldPacket data(4); + WorldPacket data; data.SetOpcode(SMSG_PLAY_SOUND); data << uint32(sound); unit->SendMessageToSet(&data, false); diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index bd79cbba628..d1b0e076d9c 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -246,8 +246,7 @@ public: // Also needs an exception in spell system. unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_FLY, true, 0, 0, me->GetGUID()); // Use packet hack - WorldPacket data(12); - data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + WorldPacket data(SMSG_MOVE_SET_CAN_FLY, 12); data.append(unit->GetPackGUID()); data << uint32(0); unit->SendMessageToSet(&data, true); @@ -266,8 +265,7 @@ public: unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY); unit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT); - WorldPacket data(12); - data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + WorldPacket data(SMSG_MOVE_UNSET_CAN_FLY, 12); data.append(unit->GetPackGUID()); data << uint32(0); unit->SendMessageToSet(&data, true); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index 028cf640d21..61df92c18e2 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -434,7 +434,7 @@ public: { me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_DISABLE_GRAVITY); + me->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); me->SetSpeed(MOVE_WALK, 5.0f, true); wp_reached = false; count = 0; @@ -467,7 +467,7 @@ public: instance->SetData(GAMEOBJECT_PUMPKIN_SHRINE, 0); //hide gameobject break; case 19: - me->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_DISABLE_GRAVITY); + me->RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); break; case 20: { diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 167f040bbc4..5ca685393ae 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -265,7 +265,7 @@ public: { OrbsEmpowered = 0; EmpowerCount = 0; - me->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_DISABLE_GRAVITY); + me->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->setActive(true); @@ -453,7 +453,7 @@ public: summoned->CastSpell(summoned, SPELL_SHADOW_CHANNELING, false); break; case CREATURE_ANVEENA: - summoned->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT | MOVEMENTFLAG_DISABLE_GRAVITY); + summoned->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); summoned->CastSpell(summoned, SPELL_ANVEENA_PRISON, true); summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); break; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp index f3b6078d536..0e781c6ddc0 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp @@ -131,9 +131,9 @@ bool GrandChampionsOutVehicle(Creature* me) if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3) { - if (!pGrandChampion1->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && - !pGrandChampion2->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && - !pGrandChampion3->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!pGrandChampion1->m_movementInfo.t_guid && + !pGrandChampion2->m_movementInfo.t_guid && + !pGrandChampion3->m_movementInfo.t_guid) return true; } @@ -385,7 +385,7 @@ public: } }else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.t_guid) return; if (uiInterceptTimer <= uiDiff) @@ -529,7 +529,7 @@ public: uiFireBallTimer = 5000; } else uiFireBallTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.t_guid) return; if (uiFireBallTimer <= uiDiff) @@ -667,7 +667,7 @@ public: } }else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.t_guid) return; if (uiChainLightningTimer <= uiDiff) @@ -813,7 +813,7 @@ public: } }else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.t_guid) return; if (uiLightningArrowsTimer <= uiDiff) @@ -961,7 +961,7 @@ public: } } else uiPhaseTimer -= uiDiff; - if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) + if (!UpdateVictim() || me->m_movementInfo.t_guid) return; if (uiEviscerateTimer <= uiDiff) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 5d3a6814eb2..9017509781f 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -1244,6 +1244,7 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); } WorldObject* target; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index e2f9faf6a97..0515ba83480 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -357,7 +357,7 @@ class boss_lady_deathwhisper : public CreatureScript void DamageTaken(Unit* /*damageDealer*/, uint32& damage) { // phase transition - if (events.GetPhaseMask() & PHASE_ONE_MASK && damage > me->GetPower(POWER_MANA)) + if (events.GetPhaseMask() & PHASE_ONE_MASK && damage > (uint32)me->GetPower(POWER_MANA)) { Talk(SAY_PHASE_2); Talk(EMOTE_PHASE_2); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp index 7ada42144a8..79e4684f3a6 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp @@ -965,6 +965,7 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage); + OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage); } }; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp index f2f03ff602b..3a90b6901e3 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp @@ -339,6 +339,8 @@ public: me->GetMotionMaster()->MoveLand(0, pos); me->SetDisableGravity(false, true); me->SetHover(true); + me->SetDisableGravity(false, true); + me->SetHover(true); ++introPhase; introTimer = 3000; break; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index f60cc1d188c..cb9f9cbc15c 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -926,8 +926,7 @@ class boss_kaelthas : public CreatureScript unit->CastSpell(unit, SPELL_GRAVITY_LAPSE_AURA, true, 0, 0, me->GetGUID()); //Using packet workaround - WorldPacket data(12); - data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + WorldPacket data(SMSG_MOVE_SET_CAN_FLY, 12); data.append(unit->GetPackGUID()); data << uint32(0); unit->SendMessageToSet(&data, true); @@ -953,8 +952,7 @@ class boss_kaelthas : public CreatureScript if (Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid())) { //Using packet workaround - WorldPacket data(12); - data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + WorldPacket data(SMSG_MOVE_UNSET_CAN_FLY, 12); data.append(unit->GetPackGUID()); data << uint32(0); unit->SendMessageToSet(&data, true); diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index b213f3df624..0bd7397f1d4 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -317,7 +317,7 @@ class spell_dru_swift_flight_passive : public SpellScriptLoader void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) { if (Player* caster = GetCaster()->ToPlayer()) - if (caster->Has310Flyer(false)) + if (caster->GetSkillValue(SKILL_RIDING) >= 375) amount = 310; } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 9cbf81b39af..a35d243593e 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3027,12 +3027,13 @@ class spell_gen_mount : public SpellScriptLoader break; case 300: if (canFly) - { - if (_mount310 && target->Has310Flyer(false)) - mount = _mount310; - else - mount = _mount280; - } + mount = _mount280; + else + mount = _mount100; + break; + case 375: + if (canFly) + mount = _mount310; else mount = _mount100; break; diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp index 7830d46260c..4928ec40abd 100644 --- a/src/server/scripts/Spells/spell_pet.cpp +++ b/src/server/scripts/Spells/spell_pet.cpp @@ -1347,24 +1347,6 @@ public: return; if (GetCaster()->GetOwner()->ToPlayer()) { - // Pet's base damage changes depending on happiness - if (GetCaster()->isPet() && GetCaster()->ToPet()->isHunterPet()) - { - switch (GetCaster()->ToPet()->GetHappinessState()) - { - case HAPPY: - // 125% of normal damage - amount += 25.0f; - break; - case CONTENT: - // 100% of normal damage, nothing to modify - break; - case UNHAPPY: - // 75% of normal damage - amount += -25.0f; - break; - } - } // Cobra Reflexes if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0)) amount -= cobraReflexes->GetAmount(); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index bb0fd1e73ab..038f3239dbb 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -338,6 +338,9 @@ class spell_rog_deadly_poison : public SpellScriptLoader // item combat enchantments for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot) { + if (slot > PRISMATIC_ENCHANTMENT_SLOT || slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id + continue; + SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot))); if (!enchant) continue; diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp index 175cfb190d7..74f615a87d1 100644 --- a/src/server/scripts/World/npc_professions.cpp +++ b/src/server/scripts/World/npc_professions.cpp @@ -211,7 +211,7 @@ int32 DoLowUnlearnCost(Player* player) //blacksmith void ProcessCastaction(Player* player, Creature* creature, uint32 spellId, uint32 triggeredSpellId, int32 cost) { - if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney(cost)) + if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney((int64)cost)) { player->CastSpell(player, triggeredSpellId, true); player->ModifyMoney(-cost); @@ -349,11 +349,11 @@ void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, ui { if (EquippedOk(player, spellId)) { - if (player->HasEnoughMoney(cost)) + if (player->HasEnoughMoney(int64(cost))) { player->CastSpell(player, spellId, true); ProfessionUnlearnSpells(player, spellId); - player->ModifyMoney(-cost); + player->ModifyMoney(-int64(cost)); if (alternativeSpellId) creature->CastSpell(player, alternativeSpellId, true); } diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 5640a84317c..2d0198bfb0e 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1297,7 +1297,7 @@ public: case GOSSIP_OPTION_LEARNDUALSPEC: if (player->GetSpecsCount() == 1 && !(player->getLevel() < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL))) { - if (!player->HasEnoughMoney(10000000)) + if (!player->HasEnoughMoney(UI64LIT(10000000))) { player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); player->PlayerTalkClass->SendCloseGossip(); @@ -1305,7 +1305,7 @@ public: } else { - player->ModifyMoney(-10000000); + player->ModifyMoney(SI64LIT(-10000000)); // Cast spells that teach dual spec // Both are also ImplicitTarget self and must be cast by player @@ -2610,11 +2610,11 @@ public: } if (doSwitch) { - if (!player->HasEnoughMoney(EXP_COST)) + if (!player->HasEnoughMoney(uint64(EXP_COST))) player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); else if (noXPGain) { - player->ModifyMoney(-EXP_COST); + player->ModifyMoney(-int64(EXP_COST)); player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN); } else if (!noXPGain) diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index 259c60ade20..7a16f2a0eb3 100755 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -116,7 +116,7 @@ #define I32FMT "%08I32X" #define I64FMT "%016I64X" #define snprintf _snprintf -#define atoll __atoi64 +#define atoll _atoi64 #define vsnprintf _vsnprintf #define finite(X) _finite(X) #define llabs _abs64 diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp new file mode 100644 index 00000000000..14170845211 --- /dev/null +++ b/src/server/shared/DataStores/DB2FileLoader.cpp @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Common.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "DB2FileLoader.h" + +DB2FileLoader::DB2FileLoader() +{ + data = NULL; + fieldsOffset = NULL; +} + +bool DB2FileLoader::Load(const char *filename, const char *fmt) +{ + uint32 header = 48; + if (data) + { + delete [] data; + data=NULL; + } + + FILE * f = fopen(filename, "rb"); + if (!f) + return false; + + if (fread(&header, 4, 1, f) != 1) // Signature + { + fclose(f); + return false; + } + + EndianConvert(header); + + if (header != 0x32424457) + { + fclose(f); + return false; //'WDB2' + } + + if (fread(&recordCount, 4, 1, f) != 1) // Number of records + { + fclose(f); + return false; + } + + EndianConvert(recordCount); + + if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields + { + fclose(f); + return false; + } + + EndianConvert(fieldCount); + + if (fread(&recordSize, 4, 1, f) != 1) // Size of a record + { + fclose(f); + return false; + } + + EndianConvert(recordSize); + + if (fread(&stringSize, 4, 1, f) != 1) // String size + { + fclose(f); + return false; + } + + EndianConvert(stringSize); + + /* NEW WDB2 FIELDS*/ + if (fread(&tableHash, 4, 1, f) != 1) // Table hash + { + fclose(f); + return false; + } + + EndianConvert(tableHash); + + if (fread(&build, 4, 1, f) != 1) // Build + { + fclose(f); + return false; + } + + EndianConvert(build); + + if (fread(&unk1, 4, 1, f) != 1) // Unknown WDB2 + { + fclose(f); + return false; + } + + EndianConvert(unk1); + + if (build > 12880) + { + if (fread(&unk2, 4, 1, f) != 1) // Unknown WDB2 + { + fclose(f); + return false; + } + EndianConvert(unk2); + + if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2 + { + fclose(f); + return false; + } + EndianConvert(maxIndex); + + if (fread(&locale, 4, 1, f) != 1) // Locales + { + fclose(f); + return false; + } + EndianConvert(locale); + + if (fread(&unk5, 4, 1, f) != 1) // Unknown WDB2 + { + fclose(f); + return false; + } + EndianConvert(unk5); + } + + if (maxIndex != 0) + { + int32 diff = maxIndex - unk2 + 1; + fseek(f, diff * 4 + diff * 2, SEEK_CUR); // diff * 4: an index for rows, diff * 2: a memory allocation bank + } + + fieldsOffset = new uint32[fieldCount]; + fieldsOffset[0] = 0; + for (uint32 i = 1; i < fieldCount; i++) + { + fieldsOffset[i] = fieldsOffset[i - 1]; + if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') + fieldsOffset[i] += 1; + else + fieldsOffset[i] += 4; + } + + data = new unsigned char[recordSize*recordCount+stringSize]; + stringTable = data + recordSize*recordCount; + + if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1) + { + fclose(f); + return false; + } + + fclose(f); + return true; +} + +DB2FileLoader::~DB2FileLoader() +{ + if (data) + delete [] data; + if (fieldsOffset) + delete [] fieldsOffset; +} + +DB2FileLoader::Record DB2FileLoader::getRecord(size_t id) +{ + assert(data); + return Record(*this, data + id*recordSize); +} + +uint32 DB2FileLoader::GetFormatRecordSize(const char * format, int32* index_pos) +{ + uint32 recordsize = 0; + int32 i = -1; + for (uint32 x=0; format[x]; ++x) + { + switch(format[x]) + { + case FT_FLOAT: + case FT_INT: + recordsize += 4; + break; + case FT_STRING: + recordsize += sizeof(char*); + break; + case FT_SORT: + i = x; + break; + case FT_IND: + i = x; + recordsize += 4; + break; + case FT_BYTE: + recordsize += 1; + break; + } + } + + if (index_pos) + *index_pos = i; + + return recordsize; +} + +uint32 DB2FileLoader::GetFormatStringsFields(const char * format) +{ + uint32 stringfields = 0; + for (uint32 x=0; format[x]; ++x) + if (format[x] == FT_STRING) + ++stringfields; + + return stringfields; +} + +char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable) +{ + + typedef char * ptr; + if (strlen(format) != fieldCount) + return NULL; + + //get struct size and index pos + int32 i; + uint32 recordsize=GetFormatRecordSize(format, &i); + + if (i >= 0) + { + uint32 maxi = 0; + //find max index + for (uint32 y = 0; y < recordCount; y++) + { + uint32 ind=getRecord(y).getUInt(i); + if (ind>maxi) + maxi = ind; + } + + ++maxi; + records = maxi; + indexTable = new ptr[maxi]; + memset(indexTable, 0, maxi * sizeof(ptr)); + } + else + { + records = recordCount; + indexTable = new ptr[recordCount]; + } + + char* dataTable = new char[recordCount * recordsize]; + + uint32 offset=0; + + for (uint32 y =0; y < recordCount; y++) + { + if (i>=0) + { + indexTable[getRecord(y).getUInt(i)] = &dataTable[offset]; + } + else + indexTable[y] = &dataTable[offset]; + + for (uint32 x = 0; x < fieldCount; x++) + { + switch(format[x]) + { + case FT_FLOAT: + *((float*)(&dataTable[offset])) = getRecord(y).getFloat(x); + offset += 4; + break; + case FT_IND: + case FT_INT: + *((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x); + offset += 4; + break; + case FT_BYTE: + *((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x); + offset += 1; + break; + case FT_STRING: + *((char**)(&dataTable[offset])) = NULL; // will be replaces non-empty or "" strings in AutoProduceStrings + offset += sizeof(char*); + break; + } + } + } + + return dataTable; +} + +static char const* const nullStr = ""; + +char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable) +{ + if (strlen(format) != fieldCount) + return NULL; + + // we store flat holders pool as single memory block + size_t stringFields = GetFormatStringsFields(format); + // each string field at load have array of string for each locale + size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES; + size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize; + size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * recordCount; + + char* stringHoldersPool = new char[stringHoldersPoolSize]; + + // DB2 strings expected to have at least empty string + for (size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i) + ((char const**)stringHoldersPool)[i] = nullStr; + + uint32 offset=0; + + // assign string holders to string field slots + for (uint32 y = 0; y < recordCount; y++) + { + uint32 stringFieldNum = 0; + + for(uint32 x = 0; x < fieldCount; x++) + switch(format[x]) + { + case FT_FLOAT: + case FT_IND: + case FT_INT: + offset += 4; + break; + case FT_BYTE: + offset += 1; + break; + case FT_STRING: + { + // init db2 string field slots by pointers to string holders + char const*** slot = (char const***)(&dataTable[offset]); + *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * y + stringHolderSize*stringFieldNum]); + ++stringFieldNum; + offset += sizeof(char*); + break; + } + case FT_NA: + case FT_NA_BYTE: + case FT_SORT: + break; + default: + assert(false && "unknown format character"); + } + } + + //send as char* for store in char* pool list for free at unload + return stringHoldersPool; +} + +char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable) +{ + if (strlen(format) != fieldCount) + return NULL; + + char* stringPool= new char[stringSize]; + memcpy(stringPool, stringTable, stringSize); + + uint32 offset = 0; + + for (uint32 y =0; y < recordCount; y++) + { + for (uint32 x = 0; x < fieldCount; x++) + switch(format[x]) + { + case FT_FLOAT: + case FT_IND: + case FT_INT: + offset += 4; + break; + case FT_BYTE: + offset += 1; + break; + case FT_STRING: + { + // fill only not filled entries + char** slot = (char**)(&dataTable[offset]); + if (**((char***)slot) == nullStr) + { + const char * st = getRecord(y).getString(x); + *slot=stringPool + (st-(const char*)stringTable); + } + + offset+=sizeof(char*); + break; + } + } + } + + return stringPool; +} diff --git a/src/server/shared/DataStores/DB2FileLoader.h b/src/server/shared/DataStores/DB2FileLoader.h new file mode 100644 index 00000000000..c30e33c29f6 --- /dev/null +++ b/src/server/shared/DataStores/DB2FileLoader.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DB2_FILE_LOADER_H +#define DB2_FILE_LOADER_H + +#include "Define.h" +#include "Utilities/ByteConverter.h" +#include <cassert> + +class DB2FileLoader +{ + public: + DB2FileLoader(); + ~DB2FileLoader(); + + bool Load(const char *filename, const char *fmt); + + class Record + { + public: + float getFloat(size_t field) const + { + assert(field < file.fieldCount); + float val = *reinterpret_cast<float*>(offset+file.GetOffset(field)); + EndianConvert(val); + return val; + } + uint32 getUInt(size_t field) const + { + assert(field < file.fieldCount); + uint32 val = *reinterpret_cast<uint32*>(offset+file.GetOffset(field)); + EndianConvert(val); + return val; + } + uint8 getUInt8(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast<uint8*>(offset+file.GetOffset(field)); + } + + const char *getString(size_t field) const + { + assert(field < file.fieldCount); + size_t stringOffset = getUInt(field); + assert(stringOffset < file.stringSize); + return reinterpret_cast<char*>(file.stringTable + stringOffset); + } + + private: + Record(DB2FileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) {} + unsigned char *offset; + DB2FileLoader &file; + + friend class DB2FileLoader; + }; + + // Get record by id + Record getRecord(size_t id); + /// Get begin iterator over records + + uint32 GetNumRows() const { return recordCount;} + uint32 GetCols() const { return fieldCount; } + uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; } + bool IsLoaded() const { return (data != NULL); } + char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable); + char* AutoProduceStringsArrayHolders(const char* fmt, char* dataTable); + char* AutoProduceStrings(const char* fmt, char* dataTable); + static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL); + static uint32 GetFormatStringsFields(const char * format); +private: + + uint32 recordSize; + uint32 recordCount; + uint32 fieldCount; + uint32 stringSize; + uint32 *fieldsOffset; + unsigned char *data; + unsigned char *stringTable; + + // WDB2 / WCH2 fields + uint32 tableHash; // WDB2 + uint32 build; // WDB2 + + int unk1; // WDB2 (Unix time in WCH2) + int unk2; // WDB2 + int maxIndex; // WDB2 (index table) + int locale; // WDB2 + int unk5; // WDB2 +}; + +#endif
\ No newline at end of file diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h new file mode 100644 index 00000000000..6ebca714fe6 --- /dev/null +++ b/src/server/shared/DataStores/DB2Store.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2011 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DB2STORE_H +#define DB2STORE_H + +#include "DB2FileLoader.h" +#include "DB2fmt.h" +#include "Log.h" +#include "Field.h" +#include "DatabaseWorkerPool.h" +#include "Implementation/WorldDatabase.h" +#include "DatabaseEnv.h" + +#include <vector> + +template<class T> +class DB2Storage +{ + typedef std::list<char*> StringPoolList; + typedef std::vector<T*> DataTableEx; +public: + explicit DB2Storage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { } + ~DB2Storage() { Clear(); } + + T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; } + uint32 GetNumRows() const { return nCount; } + char const* GetFormat() const { return fmt; } + uint32 GetFieldCount() const { return fieldCount; } + + /// Copies the provided entry and stores it. + void AddEntry(uint32 id, const T* entry) + { + if (LookupEntry(id)) + return; + + if (id >= nCount) + { + // reallocate index table + char** tmpIdxTable = new char*[id+1]; + memset(tmpIdxTable, 0, (id+1) * sizeof(char*)); + memcpy(tmpIdxTable, (char*)indexTable, nCount * sizeof(char*)); + delete[] ((char*)indexTable); + nCount = id + 1; + indexTable = (T**)tmpIdxTable; + } + + T* entryDst = new T; + memcpy((char*)entryDst, (char*)entry, sizeof(T)); + m_dataTableEx.push_back(entryDst); + indexTable[id] = entryDst; + } + + bool Load(char const* fn) + { + DB2FileLoader db2; + // Check if load was sucessful, only then continue + if (!db2.Load(fn, fmt)) + return false; + + fieldCount = db2.GetCols(); + + // load raw non-string data + m_dataTable = (T*)db2.AutoProduceData(fmt, nCount, (char**&)indexTable); + + // create string holders for loaded string fields + m_stringPoolList.push_back(db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable)); + + // load strings from dbc data + m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable)); + + // error in dbc file at loading if NULL + return indexTable!=NULL; + } + + bool LoadStringsFrom(char const* fn) + { + // DBC must be already loaded using Load + if (!indexTable) + return false; + + DB2FileLoader db2; + // Check if load was successful, only then continue + if (!db2.Load(fn, fmt)) + return false; + + // load strings from another locale dbc data + m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable)); + + return true; + } + + void Clear() + { + if (!indexTable) + return; + + delete[] ((char*)indexTable); + indexTable = NULL; + delete[] ((char*)m_dataTable); + m_dataTable = NULL; + for (typename DataTableEx::const_iterator itr = m_dataTableEx.begin(); itr != m_dataTableEx.end(); ++itr) + delete *itr; + m_dataTableEx.clear(); + + while (!m_stringPoolList.empty()) + { + delete[] m_stringPoolList.front(); + m_stringPoolList.pop_front(); + } + nCount = 0; + } + + void EraseEntry(uint32 id) { indexTable[id] = NULL; } + +private: + uint32 nCount; + uint32 fieldCount; + uint32 recordSize; + char const* fmt; + T** indexTable; + T* m_dataTable; + DataTableEx m_dataTableEx; + StringPoolList m_stringPoolList; +}; + +#endif
\ No newline at end of file diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h index a43807a3b59..3d5c23dcb85 100755 --- a/src/server/shared/DataStores/DBCFileLoader.h +++ b/src/server/shared/DataStores/DBCFileLoader.h @@ -22,21 +22,6 @@ #include "Utilities/ByteConverter.h" #include <cassert> -enum -{ - FT_NA='x', //not used or unknown, 4 byte size - FT_NA_BYTE='X', //not used or unknown, byte - FT_STRING='s', //char* - FT_FLOAT='f', //float - FT_INT='i', //uint32 - FT_BYTE='b', //uint8 - FT_SORT='d', //sorted by this field, field is not included - FT_IND='n', //the same, but parsed to data - FT_LOGIC='l', //Logical (boolean) - FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc - FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc -}; - class DBCFileLoader { public: diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h index 9965a5c1d71..0c502d3fd77 100755 --- a/src/server/shared/DataStores/DBCStore.h +++ b/src/server/shared/DataStores/DBCStore.h @@ -20,7 +20,7 @@ #define DBCSTORE_H #include "DBCFileLoader.h" -#include "Logging/Log.h" +#include "Log.h" #include "Field.h" #include "DatabaseWorkerPool.h" #include "Implementation/WorldDatabase.h" @@ -41,7 +41,7 @@ struct SqlDbc for (uint32 i = 0; i< sqlTableName.size(); ++i) { if (isalpha(sqlTableName[i])) - sqlTableName[i] = tolower(sqlTableName[i]); + sqlTableName[i] = char(tolower(sqlTableName[i])); else if (sqlTableName[i] == '.') sqlTableName[i] = '_'; } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index c7a283c94d7..222e212a08f 100644..100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -64,9 +64,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() // Start LoginQueryHolder content PREPARE_STATEMENT(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " - "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " - "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = ?", CONNECTION_ASYNC) + "resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " + "conquestPoints, totalHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " + "health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AURAS, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, " @@ -161,7 +161,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() // 0: uint32, 1: uint8, 3: string, 4: uint32 PREPARE_STATEMENT(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint32 - PREPARE_STATEMENT(CHAR_DEL_GUILD_LOWEST_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid >= ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 + PREPARE_STATEMENT(CHAR_DEL_GUILD_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_INS_GUILD_BANK_TAB, "INSERT INTO guild_bank_tab (guildid, TabId) VALUES (?, ?)", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_TAB, "DELETE FROM guild_bank_tab WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_TABS, "DELETE FROM guild_bank_tab WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint32 @@ -225,6 +225,14 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME4, "UPDATE guild_member SET BankResetTimeTab4 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME5, "UPDATE guild_member SET BankResetTimeTab5 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ? AND criteria = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, "INSERT INTO guild_achievement_progress (guildId, criteria, counter, date, completedGuid) VALUES (?, ?, ?, ?, ?)", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, "DELETE FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT, "SELECT achievement, date, guids FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH) // Chat channel handling PREPARE_STATEMENT(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH) @@ -307,8 +315,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC) // Corpse - PREPARE_STATEMENT(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH) - PREPARE_STATEMENT(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC) @@ -348,18 +356,18 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " "map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, " "taximask, cinematic, " - "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " + "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, talentTree, " "extra_flags, stable_slots, at_login, zone, " - "death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, " - "todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, " - "power4, power5, power6, power7, latency, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + "death_expire_time, taxi_path, conquestPoints, totalHonorPoints, totalKills, " + "todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, " + "power4, power5, latency, speccount, activespec, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES " + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?," "map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," - "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," - "arenaPoints=?,totalHonorPoints=?,todayHonorPoints=?,yesterdayHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,knownCurrencies=?," - "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,speccount=?,activespec=?,exploredZones=?," - "equipmentCache=?,ammoId=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC); + "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," + "conquestPoints=?,totalHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," + "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,latency=?,speccount=?,activespec=?,exploredZones=?," + "equipmentCache=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); @@ -445,14 +453,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_MAIL_ITEMS_BY_ENTRY, "SELECT mi.item_guid, m.sender, m.receiver, cs.account, cs.name, cr.account, cr.name FROM mail m INNER JOIN mail_items mi ON mi.mail_id = m.id INNER JOIN item_instance ii ON ii.guid = mi.item_guid INNER JOIN characters cs ON cs.guid = m.sender INNER JOIN characters cr ON cr.guid = m.receiver WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, "SELECT ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah INNER JOIN characters c ON c.guid = ah.itemowner INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, "SELECT gi.item_guid, gi.guildid, g.name FROM guild_bank_item gi INNER JOIN guild g ON g.guildid = gi.guildid INNER JOIN item_instance ii ON ii.guid = gi.item_guid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT, "DELETE FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, "DELETE FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC); @@ -522,7 +529,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UDP_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_UDP_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UDP_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC); @@ -539,14 +545,18 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); + + PREPARE_STATEMENT(CHAR_SEL_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor FROM void_storage WHERE playerGuid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_VOID_STORAGE_ITEM, "REPLACE INTO void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_VOID_STORAGE_ITEM_BY_SLOT, "DELETE FROM void_storage WHERE slot = ? AND playerGuid = ?", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index e1530f36e44..01db91320f5 100644..100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -166,7 +166,7 @@ enum CharacterDatabaseStatements CHAR_DEL_GUILD_MEMBERS, CHAR_INS_GUILD_RANK, CHAR_DEL_GUILD_RANKS, - CHAR_DEL_GUILD_LOWEST_RANK, + CHAR_DEL_GUILD_RANK, CHAR_INS_GUILD_BANK_TAB, CHAR_DEL_GUILD_BANK_TAB, CHAR_DEL_GUILD_BANK_TABS, @@ -220,6 +220,14 @@ enum CharacterDatabaseStatements CHAR_UPD_GUILD_RANK_BANK_TIME4, CHAR_UPD_GUILD_RANK_BANK_TIME5, CHAR_SEL_CHAR_DATA_FOR_GUILD, + CHAR_DEL_GUILD_ACHIEVEMENT, + CHAR_INS_GUILD_ACHIEVEMENT, + CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, + CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_SEL_GUILD_ACHIEVEMENT, + CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, CHAR_SEL_CHANNEL, CHAR_INS_CHANNEL, @@ -415,7 +423,6 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, CHAR_DEL_CHAR_REPUTATION_BY_FACTION, CHAR_INS_CHAR_REPUTATION_BY_FACTION, - CHAR_UPD_CHAR_ARENA_POINTS, CHAR_DEL_ITEM_REFUND_INSTANCE, CHAR_INS_ITEM_REFUND_INSTANCE, CHAR_DEL_GROUP, @@ -485,7 +492,6 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_TALENT, CHAR_DEL_CHAR_SKILLS, CHAR_UDP_CHAR_HONOR_POINTS, - CHAR_UDP_CHAR_ARENA_POINTS, CHAR_UDP_CHAR_MONEY, CHAR_INS_CHAR_ACTION, CHAR_UPD_CHAR_ACTION, @@ -513,6 +519,10 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, + CHAR_SEL_VOID_STORAGE, + CHAR_REP_VOID_STORAGE_ITEM, + CHAR_DEL_VOID_STORAGE_ITEM_BY_SLOT, + MAX_CHARACTERDATABASE_STATEMENTS, }; diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp index a72532e928b..08b554ff696 100755 --- a/src/server/shared/Database/PreparedStatement.cpp +++ b/src/server/shared/Database/PreparedStatement.cpp @@ -230,11 +230,16 @@ void MySQLPreparedStatement::ClearParameters() } } +static bool ParementerIndexAssertFail(uint32 stmtIndex, uint8 index, uint32 paramCount) +{ + sLog->outError(LOG_FILTER_SQL_DRIVER, "Attempted to bind parameter %u%s on a PreparedStatement %u (statement has only %u parameters)", uint32(index) + 1, (index == 1 ? "st" : (index == 2 ? "nd" : (index == 3 ? "rd" : "nd"))), stmtIndex, paramCount); + return false; +} + //- Bind on mysql level bool MySQLPreparedStatement::CheckValidIndex(uint8 index) { - if (index >= m_paramCount) - return false; + ASSERT(index < m_paramCount || ParementerIndexAssertFail(m_stmt->m_index, index, m_paramCount)); if (m_paramsSet[index]) sLog->outWarn(LOG_FILTER_SQL, "[WARNING] Prepared Statement (id: %u) trying to bind value on already bound index (%u).", m_stmt->m_index, index); diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h index bb3bab75e87..8c1b42af36f 100755 --- a/src/server/shared/Define.h +++ b/src/server/shared/Define.h @@ -79,4 +79,18 @@ typedef ACE_UINT32 uint32; typedef ACE_UINT16 uint16; typedef ACE_UINT8 uint8; +enum DBCFormer +{ + FT_NA='x', //not used or unknown, 4 byte size + FT_NA_BYTE='X', //not used or unknown, byte + FT_STRING='s', //char* + FT_FLOAT='f', //float + FT_INT='i', //uint32 + FT_BYTE='b', //uint8 + FT_SORT='d', //sorted by this field, field is not included + FT_IND='n', //the same, but parsed to data + FT_LOGIC='l', //Logical (boolean) + FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc + FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc +}; #endif //TRINITY_DEFINE_H diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp index be30a54ff02..7950e045201 100644 --- a/src/server/shared/Logging/Appender.cpp +++ b/src/server/shared/Logging/Appender.cpp @@ -209,6 +209,8 @@ char const* Appender::getLogFilterTypeString(LogFilterType type) return "SQL DRIVER"; case LOG_FILTER_SQL_DEV: return "SQL DEV"; + case LOG_FILTER_OPCODES: + return "OPCODES"; default: break; } diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 7d7375a1edb..956776c500b 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -62,7 +62,8 @@ enum LogFilterType LOG_FILTER_CHARACTER, LOG_FILTER_ARENAS, LOG_FILTER_SQL_DRIVER, - LOG_FILTER_SQL_DEV + LOG_FILTER_SQL_DEV, + LOG_FILTER_OPCODES }; const uint8 MaxLogFilter = uint8(LOG_FILTER_SQL_DEV) + 1; diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 1dca5e71006..14234dfb155 100755..100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -460,6 +460,14 @@ void Log::outCommand(uint32 account, const char * str, ...) write(msg); } +void Log::outOpCode(uint32 op, const char* name, bool smsg) +{ + if (!ShouldLog(LOG_FILTER_OPCODES, LOG_LEVEL_DEBUG)) + return; + + outInfo(LOG_FILTER_OPCODES, "%s: %s 0x%.4X (%u)", smsg ? "S->C" : "C->S", name, op, op); +} + void Log::SetRealmID(uint32 id) { realm = id; diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index 7b0e8cd381b..898db43a883 100755..100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -53,6 +53,7 @@ class Log void outWarn(LogFilterType f, char const* str, ...) ATTR_PRINTF(3,4); void outError(LogFilterType f, char const* str, ...) ATTR_PRINTF(3,4); void outFatal(LogFilterType f, char const* str, ...) ATTR_PRINTF(3,4); + void outOpCode(uint32 op, const char* name, bool smsg); void EnableDBAppenders(); void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4); diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 760fcfd48d9..51c253057d2 100755 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -21,9 +21,11 @@ #include "Common.h" #include "Debugging/Errors.h" -#include "Logging/Log.h" +#include "Log.h" #include "Utilities/ByteConverter.h" + + class ByteBufferException { public: @@ -85,19 +87,21 @@ class ByteBuffer const static size_t DEFAULT_SIZE = 0x1000; // constructor - ByteBuffer(): _rpos(0), _wpos(0) + ByteBuffer() : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0) { _storage.reserve(DEFAULT_SIZE); } - // constructor - ByteBuffer(size_t res): _rpos(0), _wpos(0) + ByteBuffer(size_t reserve) : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0) { - _storage.reserve(res); + _storage.reserve(reserve); } // copy constructor - ByteBuffer(const ByteBuffer &buf): _rpos(buf._rpos), _wpos(buf._wpos), _storage(buf._storage) { } + ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos), + _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf._storage) + { + } void clear() { @@ -107,10 +111,78 @@ class ByteBuffer template <typename T> void append(T value) { + FlushBits(); EndianConvert(value); append((uint8 *)&value, sizeof(value)); } + void FlushBits() + { + if (_bitpos == 8) + return; + + append((uint8 *)&_curbitval, sizeof(uint8)); + _curbitval = 0; + _bitpos = 8; + } + + bool WriteBit(uint32 bit) + { + --_bitpos; + if (bit) + _curbitval |= (1 << (_bitpos)); + + if (_bitpos == 0) + { + _bitpos = 8; + append((uint8 *)&_curbitval, sizeof(_curbitval)); + _curbitval = 0; + } + + return (bit != 0); + } + + bool ReadBit() + { + ++_bitpos; + if (_bitpos > 7) + { + _bitpos = 0; + _curbitval = read<uint8>(); + } + + return ((_curbitval >> (7-_bitpos)) & 1) != 0; + } + + template <typename T> void WriteBits(T value, size_t bits) + { + for (int32 i = bits-1; i >= 0; --i) + WriteBit((value >> i) & 1); + } + + uint32 ReadBits(size_t bits) + { + uint32 value = 0; + for (int32 i = bits-1; i >= 0; --i) + if (ReadBit()) + value |= (1 << (i)); + + return value; + } + + // Reads a byte (if needed) in-place + void ReadByteSeq(uint8& b) + { + if (b != 0) + b ^= read<uint8>(); + } + + void WriteByteSeq(uint8 b) + { + if (b != 0) + append<uint8>(b ^ 1); + } + template <typename T> void put(size_t pos, T value) { EndianConvert(value); @@ -275,9 +347,18 @@ class ByteBuffer return *this; } - uint8 operator[](size_t pos) const + uint8& operator[](size_t const pos) + { + if (pos >= size()) + throw ByteBufferPositionException(false, pos, 1, size()); + return _storage[pos]; + } + + uint8 const& operator[](size_t const pos) const { - return read<uint8>(pos); + if (pos >= size()) + throw ByteBufferPositionException(false, pos, 1, size()); + return _storage[pos]; } size_t rpos() const { return _rpos; } @@ -359,6 +440,18 @@ class ByteBuffer } } + std::string ReadString(uint32 length) + { + if (!length) + return std::string(); + char* buffer = new char[length + 1]; + memset(buffer, 0, length + 1); + read((uint8*)buffer, length); + std::string retval = buffer; + delete[] buffer; + return retval; + } + const uint8 *contents() const { return &_storage[0]; } size_t size() const { return _storage.size(); } @@ -513,7 +606,8 @@ class ByteBuffer } protected: - size_t _rpos, _wpos; + size_t _rpos, _wpos, _bitpos; + uint8 _curbitval; std::vector<uint8> _storage; }; @@ -596,7 +690,6 @@ inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m) return b; } -// TODO: Make a ByteBuffer.cpp and move all this inlining to it. template<> inline std::string ByteBuffer::read<std::string>() { std::string tmp; @@ -622,5 +715,6 @@ inline void ByteBuffer::read_skip<std::string>() { read_skip<char*>(); } + #endif diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index be5a452c7b4..477b3065dee 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -576,8 +576,7 @@ StrictPetNames = 0 # # DBC.Locale # Description: DBC language settings. -# Default: 255 - (Auto Detect) -# 0 - (English) +# Default: 0 - (English) # 1 - (Korean) # 2 - (French) # 3 - (German) @@ -587,7 +586,7 @@ StrictPetNames = 0 # 7 - (Spanish Mexico) # 8 - (Russian) -DBC.Locale = 255 +DBC.Locale = 0 # # DeclinedNames @@ -601,11 +600,12 @@ DeclinedNames = 0 # Expansion # Description: Allow server to use content from expansions. Checks for expansion-related # map files, client compatibility and class/race character creation. -# Default: 2 - (Expansion 2) +# Default: 3 - (Expansion 3) +# 2 - (Expansion 2) # 1 - (Expansion 1) # 0 - (Disabled, Ignore and disable expansion content (maps, races, classes) -Expansion = 2 +Expansion = 3 # # MinPlayerName @@ -732,16 +732,16 @@ SkipCinematics = 0 # Description: Maximum level that can be reached by players. # Important: Levels beyond 100 are not recommended at all. # Range: 1-255 -# Default: 80 +# Default: 85 -MaxPlayerLevel = 80 +MaxPlayerLevel = 85 # # MinDualSpecLevel # Description: Level requirement for Dual Talent Specialization -# Default: 40 +# Default: 30 -MinDualSpecLevel = 40 +MinDualSpecLevel = 30 # # StartPlayerLevel @@ -799,9 +799,9 @@ StartArenaPoints = 0 # RecruitAFriend.MaxLevel # Description: Highest level up to which a character can benefit from the Recruit-A-Friend # experience multiplier. -# Default: 60 +# Default: 80 -RecruitAFriend.MaxLevel = 60 +RecruitAFriend.MaxLevel = 80 # # RecruitAFriend.MaxDifference @@ -985,10 +985,10 @@ MaxPrimaryTradeSkill = 2 # # MinPetitionSigns # Description: Number of required signatures on charters to create a guild. -# Range: 0-9 -# Default: 9 +# Range: 0-4 +# Default: 4 -MinPetitionSigns = 9 +MinPetitionSigns = 4 # # MaxGroupXPDistance @@ -2688,6 +2688,7 @@ Appender.Chat=2,2,7,Chat.log # 35 - Arenas # 36 - SQL Driver # 37 - SQL Dev +# 38 - Opcodes Logger.Root=0,5,Console Server Logger.Units=1,3,Console Server @@ -2727,6 +2728,7 @@ Logger.Character=34,3,Char Logger.Arenas=35,3,Arenas Logger.SQLDriver=36,5,SQLDriver Logger.SQLDev=37,3,SQLDev +Logger.Opcodes=38,2,Console Server # LogLevel # 0 - (Disabled) @@ -2753,4 +2755,4 @@ Appenders=Console Server # (Using spaces as separator). # Default: "root" -Loggers=Root +Loggers=Root Opcodes NetWork SQL diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index bde62c24c70..af66b73827e 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -11,34 +11,24 @@ file(GLOB_RECURSE sources *.cpp *.h) -if( UNIX ) - include_directories ( - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/loadlib - ) -elseif( WIN32 ) - include_directories ( - ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_SOURCE_DIR}/dep/libmpq/win - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/loadlib - ) -endif() +include_directories ( + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/dep/StormLib/src + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/loadlib +) add_executable(mapextractor ${sources} ) target_link_libraries(mapextractor - mpq ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} + storm ) -add_dependencies(mapextractor mpq) +add_dependencies(mapextractor storm) if( UNIX ) install(TARGETS mapextractor DESTINATION bin) diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index d64276c6363..681013da18b 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -2,7 +2,7 @@ #include <stdio.h> #include <deque> -#include <set> +#include <list> #include <cstdlib> #ifdef _WIN32 @@ -11,8 +11,8 @@ #include <sys/stat.h> #endif +#include "StormLib.h" #include "dbcfile.h" -#include "mpq_libmpq04.h" #include "adt.h" #include "wdt.h" @@ -29,11 +29,13 @@ #endif #ifdef O_LARGEFILE - #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE) + #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE) #else #define OPEN_FLAGS (O_RDONLY | O_BINARY) #endif -extern ArchiveSet gOpenArchives; + +HANDLE WorldMpq = NULL; +HANDLE LocaleMpq = NULL; typedef struct { @@ -59,6 +61,7 @@ enum Extract // Select data for extract int CONF_extract = EXTRACT_MAP | EXTRACT_DBC; + // This option allow limit minimum height to some value (Allow save some memory) bool CONF_allow_height_limit = true; float CONF_use_minHeight = -500.0f; @@ -70,34 +73,47 @@ float CONF_float_to_int16_limit = 2048.0f; // Max accuracy = val/65536 float CONF_flat_height_delta_limit = 0.005f; // If max - min less this value - surface is flat float CONF_flat_liquid_delta_limit = 0.001f; // If max - min less this value - liquid surface is flat -// List MPQ for extract from -const char *CONF_mpq_list[]={ - "common.MPQ", - "common-2.MPQ", - "lichking.MPQ", - "expansion.MPQ", - "patch.MPQ", - "patch-2.MPQ", - "patch-3.MPQ", - "patch-4.MPQ", - "patch-5.MPQ", +uint32 CONF_TargetBuild = 15595; // 4.3.4.15595 + +// List MPQ for extract maps from +char const* CONF_mpq_list[]= +{ + "world.MPQ", + "art.MPQ", + "world2.MPQ", + "expansion1.MPQ", + "expansion2.MPQ", + "expansion3.MPQ", }; -static const char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; -#define LANG_COUNT 12 +uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0}; +#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder -void CreateDir( const std::string& Path ) +char* const Locales[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU"}; +TCHAR* const LocalesT[] = { - #ifdef _WIN32 - _mkdir( Path.c_str()); - #else - mkdir( Path.c_str(), 0777 ); - #endif + _T("enGB"), _T("enUS"), + _T("deDE"), _T("esES"), + _T("frFR"), _T("koKR"), + _T("zhCN"), _T("zhTW"), + _T("enCN"), _T("enTW"), + _T("esMX"), _T("ruRU"), +}; + +#define LOCALES_COUNT 12 + +void CreateDir(std::string const& path) +{ +#ifdef _WIN32 + _mkdir(path.c_str()); +#else + mkdir(path.c_str(), 777); +#endif } -bool FileExists( const char* FileName ) +bool FileExists(TCHAR const* fileName) { - int fp = _open(FileName, OPEN_FLAGS); + int fp = _open(fileName, OPEN_FLAGS); if(fp != -1) { _close(fp); @@ -116,52 +132,62 @@ void Usage(char* prg) "-o set output path\n"\ "-e extract only MAP(1)/DBC(2) - standard: both(3)\n"\ "-f height stored as int (less map size but lost some accuracy) 1 by default\n"\ - "Example: %s -f 0 -i \"c:\\games\\game\"", prg, prg); + "-b target build (default %u)"\ + "Example: %s -f 0 -i \"c:\\games\\game\"", prg, CONF_TargetBuild, prg); exit(1); } void HandleArgs(int argc, char * arg[]) { - for(int c = 1; c < argc; ++c) + for (int c = 1; c < argc; ++c) { // i - input path // o - output path // e - extract only MAP(1)/DBC(2) - standard both(3) // f - use float to int conversion // h - limit minimum height - if(arg[c][0] != '-') + // b - target client build + if (arg[c][0] != '-') Usage(arg[0]); - switch(arg[c][1]) + switch (arg[c][1]) { case 'i': - if(c + 1 < argc) // all ok - strcpy(input_path, arg[(c++) + 1]); + if (c + 1 < argc) // all ok + strcpy(input_path, arg[c++ + 1]); else Usage(arg[0]); break; case 'o': - if(c + 1 < argc) // all ok - strcpy(output_path, arg[(c++) + 1]); + if (c + 1 < argc) // all ok + strcpy(output_path, arg[c++ + 1]); else Usage(arg[0]); break; case 'f': - if(c + 1 < argc) // all ok - CONF_allow_float_to_int=atoi(arg[(c++) + 1])!=0; + if (c + 1 < argc) // all ok + CONF_allow_float_to_int = atoi(arg[c++ + 1])!=0; else Usage(arg[0]); break; case 'e': - if(c + 1 < argc) // all ok + if (c + 1 < argc) // all ok { - CONF_extract=atoi(arg[(c++) + 1]); - if(!(CONF_extract > 0 && CONF_extract < 4)) + CONF_extract = atoi(arg[c++ + 1]); + if (!(CONF_extract > 0 && CONF_extract < 4)) Usage(arg[0]); } else Usage(arg[0]); break; + case 'b': + if (c + 1 < argc) // all ok + CONF_TargetBuild = atoi(arg[c++ + 1]); + else + Usage(arg[0]); + break; + default: + break; } } } @@ -169,22 +195,31 @@ void HandleArgs(int argc, char * arg[]) uint32 ReadBuild(int locale) { // include build info file also - std::string filename = std::string("component.wow-")+langs[locale]+".txt"; + std::string filename = std::string("component.wow-") + Locales[locale] + ".txt"; //printf("Read %s file... ", filename.c_str()); - MPQFile m(filename.c_str()); - if(m.isEof()) + HANDLE dbcFile; + if (!SFileOpenFileEx(LocaleMpq, filename.c_str(), SFILE_OPEN_PATCHED_FILE, &dbcFile)) + { + printf("Fatal error: Not found %s file!\n", filename.c_str()); + exit(1); + } + + char buff[512]; + DWORD readBytes = 0; + SFileReadFile(dbcFile, buff, 512, &readBytes, NULL); + if (!readBytes) { printf("Fatal error: Not found %s file!\n", filename.c_str()); exit(1); } - std::string text = m.getPointer(); - m.close(); + std::string text = buff; + SFileCloseFile(dbcFile); size_t pos = text.find("version=\""); size_t pos1 = pos + strlen("version=\""); - size_t pos2 = text.find("\"",pos1); + size_t pos2 = text.find("\"", pos1); if (pos == text.npos || pos2 == text.npos || pos1 >= pos2) { printf("Fatal error: Invalid %s file format!\n", filename.c_str()); @@ -206,9 +241,16 @@ uint32 ReadBuild(int locale) uint32 ReadMapDBC() { printf("Read Map.dbc file... "); - DBCFile dbc("DBFilesClient\\Map.dbc"); - if(!dbc.open()) + HANDLE dbcFile; + if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\Map.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) + { + printf("Fatal error: Cannot find Map.dbc in archive!\n"); + exit(1); + } + + DBCFile dbc(dbcFile); + if (!dbc.open()) { printf("Fatal error: Invalid Map.dbc file format!\n"); exit(1); @@ -221,15 +263,23 @@ uint32 ReadMapDBC() map_ids[x].id = dbc.getRecord(x).getUInt(0); strcpy(map_ids[x].name, dbc.getRecord(x).getString(1)); } - printf("Done! (%zu maps loaded)\n", map_count); + + SFileCloseFile(dbcFile); + printf("Done! (%u maps loaded)\n", map_count); return map_count; } void ReadAreaTableDBC() { printf("Read AreaTable.dbc file..."); - DBCFile dbc("DBFilesClient\\AreaTable.dbc"); + HANDLE dbcFile; + if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\AreaTable.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) + { + printf("Fatal error: Cannot find AreaTable.dbc in archive!\n"); + exit(1); + } + DBCFile dbc(dbcFile); if(!dbc.open()) { printf("Fatal error: Invalid AreaTable.dbc file format!\n"); @@ -237,22 +287,27 @@ void ReadAreaTableDBC() } size_t area_count = dbc.getRecordCount(); - size_t maxid = dbc.getMaxId(); - areas = new uint16[maxid + 1]; - memset(areas, 0xff, (maxid + 1) * sizeof(uint16)); + maxAreaId = dbc.getMaxId(); + areas = new uint16[maxAreaId + 1]; - for(uint32 x = 0; x < area_count; ++x) + for (uint32 x = 0; x < area_count; ++x) areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - maxAreaId = dbc.getMaxId(); - - printf("Done! (%zu areas loaded)\n", area_count); + SFileCloseFile(dbcFile); + printf("Done! (%u areas loaded)\n", area_count); } void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); - DBCFile dbc("DBFilesClient\\LiquidType.dbc"); + HANDLE dbcFile; + if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\LiquidType.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile)) + { + printf("Fatal error: Cannot find LiquidType.dbc in archive!\n"); + exit(1); + } + + DBCFile dbc(dbcFile); if(!dbc.open()) { printf("Fatal error: Invalid LiquidType.dbc file format!\n"); @@ -267,7 +322,8 @@ void ReadLiquidTypeTableDBC() for(uint32 x = 0; x < liqTypeCount; ++x) LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3); - printf("Done! (%zu LiqTypes loaded)\n", liqTypeCount); + SFileCloseFile(dbcFile); + printf("Done! (%u LiqTypes loaded)\n", liqTypeCount); } // @@ -368,16 +424,9 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, { ADT_file adt; - if (!adt.loadFile(filename)) + if (!adt.loadFile(WorldMpq, filename)) return false; - adt_MCIN *cells = adt.a_grid->getMCIN(); - if (!cells) - { - printf("Can't find cells in '%s'\n", filename); - return false; - } - memset(liquid_show, 0, sizeof(liquid_show)); memset(liquid_flags, 0, sizeof(liquid_flags)); memset(liquid_entry, 0, sizeof(liquid_entry)); @@ -389,24 +438,27 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, map.buildMagic = build; // Get area flags data - for (int i=0;i<ADT_CELLS_PER_GRID;i++) + for (int i = 0; i < ADT_CELLS_PER_GRID; ++i) { - for(int j=0;j<ADT_CELLS_PER_GRID;j++) + for (int j = 0; j < ADT_CELLS_PER_GRID; ++j) { - adt_MCNK * cell = cells->getMCNK(i,j); + adt_MCNK* cell = adt.cells[i][j]; uint32 areaid = cell->areaid; - if(areaid && areaid <= maxAreaId) + if (areaid && areaid <= maxAreaId) { - if(areas[areaid] != 0xffff) + if (areas[areaid] != 0xFFFF) { area_flags[i][j] = areas[areaid]; continue; } + printf("File: %s\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy); } + area_flags[i][j] = 0xffff; } } + //============================================ // Try pack area data //============================================ @@ -448,7 +500,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, { for(int j=0;j<ADT_CELLS_PER_GRID;j++) { - adt_MCNK * cell = cells->getMCNK(i,j); + adt_MCNK * cell = adt.cells[i][j]; if (!cell) continue; // Height values for triangles stored in order: @@ -619,7 +671,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, { for(int j = 0; j < ADT_CELLS_PER_GRID; j++) { - adt_MCNK *cell = cells->getMCNK(i, j); + adt_MCNK *cell = adt.cells[i][j]; if (!cell) continue; @@ -719,7 +771,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, // Dark water detect if (LiqType[h->liquidType] == LIQUID_TYPE_OCEAN) { - uint8 *lm = h2o->getLiquidLightMap(h); + uint8* lm = h2o->getLiquidLightMap(h); if (!lm) liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER; } @@ -727,34 +779,37 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, if (!count && liquid_flags[i][j]) printf("Wrong liquid detect in MH2O chunk"); - float *height = h2o->getLiquidHeightMap(h); + float* height = h2o->getLiquidHeightMap(h); int pos = 0; - for (int y=0; y<=h->height;y++) + for (int y = 0; y <= h->height; y++) { - int cy = i*ADT_CELL_SIZE + y + h->yOffset; - for (int x=0; x<= h->width; x++) + int cy = i * ADT_CELL_SIZE + y + h->yOffset; + for (int x = 0; x <= h->width; x++) { - int cx = j*ADT_CELL_SIZE + x + h->xOffset; + int cx = j * ADT_CELL_SIZE + x + h->xOffset; + if (height) liquid_height[cy][cx] = height[pos]; else liquid_height[cy][cx] = h->heightLevel1; + pos++; } } } } } + //============================================ // Pack liquid data //============================================ uint8 type = liquid_flags[0][0]; bool fullType = false; - for (int y=0;y<ADT_CELLS_PER_GRID;y++) + for (int y = 0; y < ADT_CELLS_PER_GRID; y++) { - for(int x=0;x<ADT_CELLS_PER_GRID;x++) + for (int x = 0; x < ADT_CELLS_PER_GRID; x++) { - if (liquid_flags[y][x]!=type) + if (liquid_flags[y][x] != type) { fullType = true; y = ADT_CELLS_PER_GRID; @@ -864,15 +919,16 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, if (map.liquidMapOffset) { fwrite(&liquidHeader, sizeof(liquidHeader), 1, output); - if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE)) + if (!(liquidHeader.flags & MAP_LIQUID_NO_TYPE)) { fwrite(liquid_entry, sizeof(liquid_entry), 1, output); fwrite(liquid_flags, sizeof(liquid_flags), 1, output); } - if (!(liquidHeader.flags&MAP_LIQUID_NO_HEIGHT)) + + if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT)) { - for (int y=0; y<liquidHeader.height;y++) - fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); + for (int y = 0; y < liquidHeader.height; y++) + fwrite(&liquid_height[y + liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output); } } fclose(output); @@ -898,135 +954,244 @@ void ExtractMapsFromMpq(uint32 build) CreateDir(path); printf("Convert map files\n"); - for(uint32 z = 0; z < map_count; ++z) + for (uint32 z = 0; z < map_count; ++z) { printf("Extract %s (%d/%d) \n", map_ids[z].name, z+1, map_count); // Loadup map grid data sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name); WDT_file wdt; - if (!wdt.loadFile(mpq_map_name, false)) - { -// printf("Error loading %s map wdt data\n", map_ids[z].name); + if (!wdt.loadFile(WorldMpq, mpq_map_name, false)) continue; - } - for(uint32 y = 0; y < WDT_MAP_SIZE; ++y) + for (uint32 y = 0; y < WDT_MAP_SIZE; ++y) { - for(uint32 x = 0; x < WDT_MAP_SIZE; ++x) + for (uint32 x = 0; x < WDT_MAP_SIZE; ++x) { - if (!wdt.main->adt_list[y][x].exist) + if (!(wdt.main->adt_list[y][x].flag & 0x1)) continue; + sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y); sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x); ConvertADT(mpq_filename, output_filename, y, x, build); } + // draw progress bar printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE); } } + printf("\n"); delete [] areas; delete [] map_ids; } -bool ExtractFile( char const* mpq_name, std::string const& filename ) +bool ExtractFile(HANDLE fileInArchive, char const* filename) { - FILE *output = fopen(filename.c_str(), "wb"); + FILE* output = fopen(filename, "wb"); if(!output) { - printf("Can't create the output file '%s'\n", filename.c_str()); + printf("Can't create the output file '%s'\n", filename); return false; } - MPQFile m(mpq_name); - if(!m.isEof()) - fwrite(m.getPointer(), 1, m.getSize(), output); + + char buffer[0x10000]; + DWORD readBytes = 1; + + while (readBytes > 0) + { + SFileReadFile(fileInArchive, buffer, sizeof(buffer), &readBytes, NULL); + if (readBytes > 0) + fwrite(buffer, 1, readBytes, output); + } fclose(output); return true; } -void ExtractDBCFiles(int locale, bool basicLocale) +void ExtractDBCFiles(int l, bool basicLocale) { printf("Extracting dbc files...\n"); - std::set<std::string> dbcfiles; - - // get DBC file list - for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i) + SFILE_FIND_DATA foundFile; + memset(&foundFile, 0, sizeof(foundFile)); + HANDLE listFile = SFileFindFirstFile(LocaleMpq, "DBFilesClient\\*dbc", &foundFile, NULL); + HANDLE dbcFile = NULL; + uint32 count = 0; + if (listFile) { - vector<string> files; - (*i)->GetFileListTo(files); - for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter) - if (iter->rfind(".dbc") == iter->length() - strlen(".dbc")) - dbcfiles.insert(*iter); - } + std::string outputPath = output_path; + outputPath += "/dbc/"; - std::string path = output_path; - path += "/dbc/"; - CreateDir(path); - if(!basicLocale) - { - path += langs[locale]; - path += "/"; - CreateDir(path); - } + CreateDir(outputPath); + if (!basicLocale) + { + outputPath += Locales[l]; + outputPath += "/"; + CreateDir(outputPath); + } - // extract Build info file - { - string mpq_name = std::string("component.wow-") + langs[locale] + ".txt"; - string filename = path + mpq_name; + std::string filename; - ExtractFile(mpq_name.c_str(), filename); - } + do + { + if (!SFileOpenFileEx(LocaleMpq, foundFile.cFileName, SFILE_OPEN_PATCHED_FILE, &dbcFile)) + { + printf("Unable to open file %s in the archive\n", foundFile.cFileName); + continue; + } - // extract DBCs - int count = 0; - for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter) - { - string filename = path; - filename += (iter->c_str() + strlen("DBFilesClient\\")); + filename = foundFile.cFileName; + filename = outputPath + filename.substr(filename.rfind('\\')); + if (ExtractFile(dbcFile, filename.c_str())) + ++count; + + SFileCloseFile(dbcFile); + } while (SFileFindNextFile(listFile, &foundFile)); - if(ExtractFile(iter->c_str(), filename)) - ++count; + SFileFindClose(listFile); } + printf("Extracted %u DBC files\n\n", count); } -void LoadLocaleMPQFiles(int const locale) +void ExtractDB2Files(int l, bool basicLocale) { - char filename[512]; + printf("Extracting db2 files...\n"); + + SFILE_FIND_DATA foundFile; + memset(&foundFile, 0, sizeof(foundFile)); + HANDLE listFile = SFileFindFirstFile(LocaleMpq, "DBFilesClient\\*db2", &foundFile, NULL); + HANDLE dbcFile = NULL; + uint32 count = 0; + if (listFile) + { + std::string outputPath = output_path; + outputPath += "/dbc/"; + if (!basicLocale) + { + outputPath += Locales[l]; + outputPath += "/"; + } - sprintf(filename,"%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]); - new MPQArchive(filename); + std::string filename; - for(int i = 1; i < 5; ++i) - { - char ext[3] = ""; - if(i > 1) - sprintf(ext, "-%i", i); + do + { + if (!SFileOpenFileEx(LocaleMpq, foundFile.cFileName, SFILE_OPEN_PATCHED_FILE, &dbcFile)) + { + printf("Unable to open file %s in the archive\n", foundFile.cFileName); + continue; + } + + filename = foundFile.cFileName; + filename = outputPath + filename.substr(filename.rfind('\\')); + if (ExtractFile(dbcFile, filename.c_str())) + ++count; - sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext); - if(FileExists(filename)) - new MPQArchive(filename); + SFileCloseFile(dbcFile); + } while (SFileFindNextFile(listFile, &foundFile)); + + SFileFindClose(listFile); } + + printf("Extracted %u DB2 files\n\n", count); } -void LoadCommonMPQFiles() +bool LoadLocaleMPQFile(int locale) { - char filename[512]; - int count = sizeof(CONF_mpq_list)/sizeof(char*); - for(int i = 0; i < count; ++i) + TCHAR buff[512]; + memset(buff, 0, sizeof(buff)); + _stprintf(buff, _T("%s/Data/%s/locale-%s.MPQ"), input_path, LocalesT[locale], LocalesT[locale]); + if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &LocaleMpq)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open archive %s\n"), buff); + return false; + } + + char const* prefix = NULL; + for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) { - sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]); - if(FileExists(filename)) - new MPQArchive(filename); + memset(buff, 0, sizeof(buff)); + if (Builds[i] > LAST_DBC_IN_DATA_BUILD) + { + prefix = ""; + _stprintf(buff, _T("%s/Data/%s/wow-update-%s-%u.MPQ"), input_path, LocalesT[locale], LocalesT[locale], Builds[i]); + } + else + { + prefix = Locales[locale]; + _stprintf(buff, _T("%s/Data/wow-update-%u.MPQ"), input_path, Builds[i]); + } + + if (!SFileOpenPatchArchive(LocaleMpq, buff, prefix, 0)) + { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + _tprintf(_T("Cannot open patch archive %s\n"), buff); + continue; + } } + + return true; } -inline void CloseMPQFiles() +void LoadCommonMPQFiles(uint32 build) { - for(ArchiveSet::iterator j = gOpenArchives.begin(); j != gOpenArchives.end();++j) (*j)->close(); - gOpenArchives.clear(); + TCHAR filename[512]; + _stprintf(filename, _T("%s/Data/world.MPQ"), input_path); + if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open archive %s\n"), filename); + return; + } + + int count = sizeof(CONF_mpq_list) / sizeof(char*); + for (int i = 1; i < count; ++i) + { + if (build < 15211 && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ + continue; + + _stprintf(filename, _T("%s/Data/%s"), input_path, CONF_mpq_list[i]); + if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open archive %s\n"), filename); + else + _tprintf(_T("Not found %s\n"), filename); + } + else + _tprintf(_T("Loaded %s\n"), filename); + + } + + char const* prefix = NULL; + for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) + { + memset(filename, 0, sizeof(filename)); + if (Builds[i] > LAST_DBC_IN_DATA_BUILD) + { + prefix = ""; + _stprintf(filename, _T("%s/Data/wow-update-base-%u.MPQ"), input_path, Builds[i]); + } + else + { + prefix = "base"; + _stprintf(filename, _T("%s/Data/wow-update-%u.MPQ"), input_path, Builds[i]); + } + + if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open patch archive %s\n"), filename); + else + _tprintf(_T("Not found %s\n"), filename); + continue; + } + else + _tprintf(_T("Loaded %s\n"), filename); + } + } int main(int argc, char * arg[]) @@ -1039,42 +1204,54 @@ int main(int argc, char * arg[]) int FirstLocale = -1; uint32 build = 0; - for (int i = 0; i < LANG_COUNT; i++) + for (int i = 0; i < LOCALES_COUNT; ++i) { - char tmp1[512]; - sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]); - if (FileExists(tmp1)) + //Open MPQs + if (!LoadLocaleMPQFile(i)) { - printf("Detected locale: %s\n", langs[i]); - - //Open MPQs - LoadLocaleMPQFiles(i); + if (GetLastError() != ERROR_PATH_NOT_FOUND) + printf("Unable to load %s locale archives!\n", Locales[i]); + continue; + } - if((CONF_extract & EXTRACT_DBC) == 0) + printf("Detected locale: %s\n", Locales[i]); + if ((CONF_extract & EXTRACT_DBC) == 0) + { + FirstLocale = i; + build = ReadBuild(i); + if (build > CONF_TargetBuild) { - FirstLocale = i; - build = ReadBuild(FirstLocale); - printf("Detected client build: %u\n", build); - break; + printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], build, CONF_TargetBuild); + return 0; } - //Extract DBC files - if(FirstLocale < 0) - { - FirstLocale = i; - build = ReadBuild(FirstLocale); - printf("Detected client build: %u\n", build); - ExtractDBCFiles(i, true); - } - else - ExtractDBCFiles(i, false); + printf("Detected client build: %u\n", build); + break; + } - //Close MPQs - CloseMPQFiles(); + //Extract DBC files + uint32 tempBuild = ReadBuild(i); + printf("Detected client build %u for locale %s\n", tempBuild, Locales[i]); + if (tempBuild > CONF_TargetBuild) + { + printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], tempBuild, CONF_TargetBuild); + continue; } + + ExtractDBCFiles(i, FirstLocale < 0); + ExtractDB2Files(i, FirstLocale < 0); + + if (FirstLocale < 0) + { + FirstLocale = i; + build = tempBuild; + } + + //Close MPQs + SFileCloseArchive(LocaleMpq); } - if(FirstLocale < 0) + if (FirstLocale < 0) { printf("No locales detected\n"); return 0; @@ -1082,17 +1259,18 @@ int main(int argc, char * arg[]) if (CONF_extract & EXTRACT_MAP) { - printf("Using locale: %s\n", langs[FirstLocale]); + printf("Using locale: %s\n", Locales[FirstLocale]); // Open MPQs - LoadLocaleMPQFiles(FirstLocale); - LoadCommonMPQFiles(); + LoadLocaleMPQFile(FirstLocale); + LoadCommonMPQFiles(build); // Extract maps ExtractMapsFromMpq(build); // Close MPQs - CloseMPQFiles(); + SFileCloseArchive(WorldMpq); + SFileCloseArchive(LocaleMpq); } return 0; diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index fde70681113..bb1e3bfcc45 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -48,6 +48,27 @@ bool ADT_file::prepareLoadedData() if (!a_grid->prepareLoadedData()) return false; + // funny offsets calculations because there is no mapping for them and they have variable lengths + uint8* ptr = (uint8*)a_grid + a_grid->size + 8; + uint32 mcnk_count = 0; + memset(cells, 0, ADT_CELLS_PER_GRID * ADT_CELLS_PER_GRID * sizeof(adt_MCNK*)); + while (ptr < GetData() + GetDataSize()) + { + uint32 header = *(uint32*)ptr; + uint32 size = *(uint32*)(ptr + 4); + if (header == 'MCNK') + { + cells[mcnk_count / ADT_CELLS_PER_GRID][mcnk_count % ADT_CELLS_PER_GRID] = (adt_MCNK*)ptr; + ++mcnk_count; + } + + // move to next chunk + ptr += size + 8; + } + + if (mcnk_count != ADT_CELLS_PER_GRID * ADT_CELLS_PER_GRID) + return false; + return true; } diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h index 5daf5820c3f..20b5ac93540 100644 --- a/src/tools/map_extractor/adt.h +++ b/src/tools/map_extractor/adt.h @@ -245,15 +245,18 @@ public: // // Adt file header chunk // +class ADT_file; class adt_MHDR { + friend class ADT_file; + union{ uint32 fcc; char fcc_txt[4]; }; uint32 size; - uint32 pad; + uint32 flags; uint32 offsMCIN; // MCIN uint32 offsTex; // MTEX uint32 offsModels; // MMDX @@ -271,9 +274,8 @@ class adt_MHDR uint32 data5; public: bool prepareLoadedData(); - adt_MCIN *getMCIN(){ return (adt_MCIN *)((uint8 *)&pad+offsMCIN);} - adt_MH2O *getMH2O(){ return offsMH2O ? (adt_MH2O *)((uint8 *)&pad+offsMH2O) : 0;} - + adt_MCIN* getMCIN() { return offsMCIN ? (adt_MCIN *)((uint8 *)&flags+offsMCIN) : NULL; } + adt_MH2O* getMH2O() { return offsMH2O ? (adt_MH2O *)((uint8 *)&flags+offsMH2O) : NULL; } }; class ADT_file : public FileLoader{ @@ -283,7 +285,8 @@ public: ~ADT_file(); void free(); - adt_MHDR *a_grid; + adt_MHDR* a_grid; + adt_MCNK* cells[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; }; #endif diff --git a/src/tools/map_extractor/dbcfile.cpp b/src/tools/map_extractor/dbcfile.cpp index 927d3d62b7f..021dc6f6e33 100644 --- a/src/tools/map_extractor/dbcfile.cpp +++ b/src/tools/map_extractor/dbcfile.cpp @@ -1,83 +1,91 @@ #define _CRT_SECURE_NO_DEPRECATE #include "dbcfile.h" -#include "mpq_libmpq04.h" -DBCFile::DBCFile(const std::string &filename): - filename(filename), - data(0) +DBCFile::DBCFile(HANDLE file) : + _file(file), _data(NULL), _stringTable(NULL) { - } + bool DBCFile::open() { - MPQFile f(filename.c_str()); char header[4]; - unsigned int na,nb,es,ss; + unsigned int na, nb, es, ss; - if(f.read(header,4)!=4) // Number of records + DWORD readBytes = 0; + SFileReadFile(_file, header, 4, &readBytes, NULL); + if (readBytes != 4) // Number of records return false; - if(header[0]!='W' || header[1]!='D' || header[2]!='B' || header[3]!='C') + if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C') return false; - if(f.read(&na,4)!=4) // Number of records + SFileReadFile(_file, &na, 4, &readBytes, NULL); + if (readBytes != 4) // Number of records return false; - if(f.read(&nb,4)!=4) // Number of fields + + SFileReadFile(_file, &nb, 4, &readBytes, NULL); + if (readBytes != 4) // Number of fields return false; - if(f.read(&es,4)!=4) // Size of a record + + SFileReadFile(_file, &es, 4, &readBytes, NULL); + if (readBytes != 4) // Size of a record return false; - if(f.read(&ss,4)!=4) // String size + + SFileReadFile(_file, &ss, 4, &readBytes, NULL); + if (readBytes != 4) // String size return false; - recordSize = es; - recordCount = na; - fieldCount = nb; - stringSize = ss; - if(fieldCount*4 != recordSize) + _recordSize = es; + _recordCount = na; + _fieldCount = nb; + _stringSize = ss; + if (_fieldCount * 4 != _recordSize) return false; - data = new unsigned char[recordSize*recordCount+stringSize]; - stringTable = data + recordSize*recordCount; + _data = new unsigned char[_recordSize * _recordCount + _stringSize]; + _stringTable = _data + _recordSize*_recordCount; - size_t data_size = recordSize*recordCount+stringSize; - if(f.read(data,data_size)!=data_size) + size_t data_size = _recordSize * _recordCount + _stringSize; + SFileReadFile(_file, _data, data_size, &readBytes, NULL); + if (readBytes != data_size) return false; - f.close(); + return true; } + DBCFile::~DBCFile() { - delete [] data; + delete [] _data; } DBCFile::Record DBCFile::getRecord(size_t id) { - assert(data); - return Record(*this, data + id*recordSize); + assert(_data); + return Record(*this, _data + id*_recordSize); } size_t DBCFile::getMaxId() { - assert(data); + assert(_data); size_t maxId = 0; for(size_t i = 0; i < getRecordCount(); ++i) - { - if(maxId < getRecord(i).getUInt(0)) + if (maxId < getRecord(i).getUInt(0)) maxId = getRecord(i).getUInt(0); - } + return maxId; } DBCFile::Iterator DBCFile::begin() { - assert(data); - return Iterator(*this, data); + assert(_data); + return Iterator(*this, _data); } + DBCFile::Iterator DBCFile::end() { - assert(data); - return Iterator(*this, stringTable); + assert(_data); + return Iterator(*this, _stringTable); } diff --git a/src/tools/map_extractor/dbcfile.h b/src/tools/map_extractor/dbcfile.h index aef61df7aaa..adb4a34f473 100644 --- a/src/tools/map_extractor/dbcfile.h +++ b/src/tools/map_extractor/dbcfile.h @@ -2,118 +2,124 @@ #define DBCFILE_H #include <cassert> #include <string> +#include "StormLib.h" class DBCFile { -public: - DBCFile(const std::string &filename); - ~DBCFile(); + public: + DBCFile(HANDLE file); + ~DBCFile(); - // Open database. It must be openened before it can be used. - bool open(); + // Open database. It must be openened before it can be used. + bool open(); - // Database exceptions - class Exception - { - public: - Exception(const std::string &message): message(message) - { } - virtual ~Exception() - { } - const std::string &getMessage() {return message;} - private: - std::string message; - }; - class NotFound: public Exception - { - public: - NotFound(): Exception("Key was not found") - { } - }; - // Iteration over database - class Iterator; - class Record - { - public: - float getFloat(size_t field) const - { - assert(field < file.fieldCount); - return *reinterpret_cast<float*>(offset+field*4); - } - unsigned int getUInt(size_t field) const + // Database exceptions + class Exception { - assert(field < file.fieldCount); - return *reinterpret_cast<unsigned int*>(offset+field*4); - } - int getInt(size_t field) const - { - assert(field < file.fieldCount); - return *reinterpret_cast<int*>(offset+field*4); - } - const char *getString(size_t field) const + public: + Exception(const std::string &message) : message(message) { } + virtual ~Exception() { } + const std::string &getMessage() { return message; } + private: + std::string message; + }; + + class NotFound: public Exception { - assert(field < file.fieldCount); - size_t stringOffset = getUInt(field); - assert(stringOffset < file.stringSize); - return reinterpret_cast<char*>(file.stringTable + stringOffset); - } - private: - Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} - unsigned char *offset; - DBCFile &file; - - friend class DBCFile; - friend class DBCFile::Iterator; - }; - /** Iterator that iterates over records - */ - class Iterator - { - public: - Iterator(DBCFile &file, unsigned char *offset): - record(file, offset) {} - /// Advance (prefix only) - Iterator & operator++() { - record.offset += record.file.recordSize; - return *this; - } - /// Return address of current instance - Record const & operator*() const { return record; } - const Record* operator->() const { - return &record; - } - /// Comparison - bool operator==(const Iterator &b) const + public: + NotFound(): Exception("Key was not found") { } + }; + + // Iteration over database + class Iterator; + class Record { - return record.offset == b.record.offset; - } - bool operator!=(const Iterator &b) const + public: + float getFloat(size_t field) const + { + assert(field < file._fieldCount); + return *reinterpret_cast<float*>(offset+field*4); + } + + unsigned int getUInt(size_t field) const + { + assert(field < file._fieldCount); + return *reinterpret_cast<unsigned int*>(offset+field*4); + } + + int getInt(size_t field) const + { + assert(field < file._fieldCount); + return *reinterpret_cast<int*>(offset+field*4); + } + + const char *getString(size_t field) const + { + assert(field < file._fieldCount); + size_t stringOffset = getUInt(field); + assert(stringOffset < file._stringSize); + return reinterpret_cast<char*>(file._stringTable + stringOffset); + } + + private: + Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} + unsigned char *offset; + DBCFile &file; + + friend class DBCFile; + friend class DBCFile::Iterator; + }; + /** Iterator that iterates over records + */ + class Iterator { - return record.offset != b.record.offset; - } + public: + Iterator(DBCFile &file, unsigned char *offset) : record(file, offset) { } + + /// Advance (prefix only) + Iterator & operator++() + { + record.offset += record.file._recordSize; + return *this; + } + + /// Return address of current instance + Record const & operator*() const { return record; } + const Record* operator->() const { return &record; } + + /// Comparison + bool operator==(const Iterator &b) const + { + return record.offset == b.record.offset; + } + + bool operator!=(const Iterator &b) const + { + return record.offset != b.record.offset; + } + private: + Record record; + }; + + // Get record by id + Record getRecord(size_t id); + /// Get begin iterator over records + Iterator begin(); + /// Get begin iterator over records + Iterator end(); + /// Trivial + size_t getRecordCount() const { return _recordCount; } + size_t getFieldCount() const { return _fieldCount; } + size_t getMaxId(); + private: - Record record; - }; - - // Get record by id - Record getRecord(size_t id); - /// Get begin iterator over records - Iterator begin(); - /// Get begin iterator over records - Iterator end(); - /// Trivial - size_t getRecordCount() const { return recordCount;} - size_t getFieldCount() const { return fieldCount; } - size_t getMaxId(); -private: - std::string filename; - size_t recordSize; - size_t recordCount; - size_t fieldCount; - size_t stringSize; - unsigned char *data; - unsigned char *stringTable; + HANDLE _file; + size_t _recordSize; + size_t _recordCount; + size_t _fieldCount; + size_t _stringSize; + unsigned char *_data; + unsigned char* _stringTable; }; #endif - diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 465eb04083f..0e2112b2f26 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -1,11 +1,8 @@ #define _CRT_SECURE_NO_DEPRECATE #include "loadlib.h" -#include "mpq_libmpq04.h" #include <cstdio> -class MPQFile; - FileLoader::FileLoader() { data = 0; @@ -18,29 +15,31 @@ FileLoader::~FileLoader() free(); } -bool FileLoader::loadFile(char *filename, bool log) +bool FileLoader::loadFile(HANDLE mpq, char* filename, bool log) { free(); - MPQFile mf(filename); - if(mf.isEof()) + HANDLE file; + if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file)) { if (log) printf("No such file %s\n", filename); return false; } - data_size = mf.getSize(); - - data = new uint8 [data_size]; + data_size = SFileGetFileSize(file, NULL); + data = new uint8[data_size]; if (data) { - mf.read(data, data_size); - mf.close(); + SFileReadFile(file, data, data_size, NULL/*bytesRead*/, NULL); if (prepareLoadedData()) + { + SFileCloseFile(file); return true; + } } - printf("Error loading %s", filename); - mf.close(); + + printf("Error loading %s\n", filename); + SFileCloseFile(file); free(); return false; } diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index bf6c0706d46..7a158ddfcf1 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -1,6 +1,8 @@ #ifndef LOAD_LIB_H #define LOAD_LIB_H +#include "StormLib.h" + #ifdef _WIN32 typedef __int64 int64; typedef __int32 int32; @@ -42,6 +44,7 @@ struct file_MVER uint32 ver; }; + class FileLoader{ uint8 *data; uint32 data_size; @@ -53,7 +56,7 @@ public: file_MVER *version; FileLoader(); ~FileLoader(); - bool loadFile(char *filename, bool log = true); + bool loadFile(HANDLE mpq, char *filename, bool log = true); virtual void free(); }; #endif diff --git a/src/tools/map_extractor/mpq_libmpq.cpp b/src/tools/map_extractor/mpq_libmpq.cpp deleted file mode 100644 index 81aa8cc2894..00000000000 --- a/src/tools/map_extractor/mpq_libmpq.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "mpq_libmpq04.h" -#include <deque> -#include <cstdio> - -ArchiveSet gOpenArchives; - -MPQArchive::MPQArchive(const char* filename) -{ - int result = libmpq__archive_open(&mpq_a, filename, -1); - printf("Opening %s\n", filename); - if(result) { - switch(result) { - case LIBMPQ_ERROR_OPEN : - printf("Error opening archive '%s': Does file really exist?\n", filename); - break; - case LIBMPQ_ERROR_FORMAT : /* bad file format */ - printf("Error opening archive '%s': Bad file format\n", filename); - break; - case LIBMPQ_ERROR_SEEK : /* seeking in file failed */ - printf("Error opening archive '%s': Seeking in file failed\n", filename); - break; - case LIBMPQ_ERROR_READ : /* Read error in archive */ - printf("Error opening archive '%s': Read error in archive\n", filename); - break; - case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */ - printf("Error opening archive '%s': Maybe not enough memory\n", filename); - break; - default: - printf("Error opening archive '%s': Unknown error\n", filename); - break; - } - return; - } - gOpenArchives.push_front(this); -} - -void MPQArchive::close() -{ - //gOpenArchives.erase(erase(&mpq_a); - libmpq__archive_close(mpq_a); -} - -MPQFile::MPQFile(const char* filename): - eof(false), - buffer(0), - pointer(0), - size(0) -{ - for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) - { - mpq_archive *mpq_a = (*i)->mpq_a; - - uint32_t filenum; - if(libmpq__file_number(mpq_a, filename, &filenum)) continue; - libmpq__off_t transferred; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - // HACK: in patch.mpq some files don't want to open and give 1 for filesize - if (size<=1) { -// printf("warning: file %s has size %d; cannot read.\n", filename, size); - eof = true; - buffer = 0; - return; - } - buffer = new char[size]; - - //libmpq_file_getdata - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/ - return; - - } - eof = true; - buffer = 0; -} - -size_t MPQFile::read(void* dest, size_t bytes) -{ - if (eof) return 0; - - size_t rpos = pointer + bytes; - if (rpos > size) { - bytes = size - pointer; - eof = true; - } - - memcpy(dest, &(buffer[pointer]), bytes); - - pointer = rpos; - - return bytes; -} - -void MPQFile::seek(int offset) -{ - pointer = offset; - eof = (pointer >= size); -} - -void MPQFile::seekRelative(int offset) -{ - pointer += offset; - eof = (pointer >= size); -} - -void MPQFile::close() -{ - if (buffer) delete[] buffer; - buffer = 0; - eof = true; -} diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h deleted file mode 100644 index 89f715e9e87..00000000000 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ /dev/null @@ -1,91 +0,0 @@ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_WARNINGS - -#ifndef MPQ_H -#define MPQ_H - -#include "loadlib/loadlib.h" -#include "libmpq/mpq.h" -#include <string.h> -#include <ctype.h> -#include <vector> -#include <iostream> -#include <deque> - -using namespace std; - -class MPQArchive -{ - -public: - mpq_archive_s *mpq_a; - - MPQArchive(const char* filename); - void close(); - - void GetFileListTo(vector<string>& filelist) { - uint32_t filenum; - if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; - libmpq__off_t size, transferred; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - char *buffer = new char[size]; - - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - - char seps[] = "\n"; - char *token; - - token = strtok( buffer, seps ); - uint32 counter = 0; - while ((token != NULL) && (counter < size)) { - //cout << token << endl; - token[strlen(token) - 1] = 0; - string s = token; - filelist.push_back(s); - counter += strlen(token) + 2; - token = strtok(NULL, seps); - } - - delete[] buffer; - } -}; -typedef std::deque<MPQArchive*> ArchiveSet; - -class MPQFile -{ - //MPQHANDLE handle; - bool eof; - char *buffer; - libmpq__off_t pointer,size; - - // disable copying - MPQFile(const MPQFile& /*f*/) {} - void operator=(const MPQFile& /*f*/) {} - -public: - MPQFile(const char* filename); // filenames are not case sensitive - ~MPQFile() { close(); } - size_t read(void* dest, size_t bytes); - size_t getSize() { return size; } - size_t getPos() { return pointer; } - char* getBuffer() { return buffer; } - char* getPointer() { return buffer + pointer; } - bool isEof() { return eof; } - void seek(int offset); - void seekRelative(int offset); - void close(); -}; - -inline void flipcc(char *fcc) -{ - char t; - t=fcc[0]; - fcc[0]=fcc[3]; - fcc[3]=t; - t=fcc[1]; - fcc[1]=fcc[2]; - fcc[2]=t; -} - -#endif diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp index dedefbb64e5..6c2fa337d4f 100644 --- a/src/tools/map_extractor/wdt.cpp +++ b/src/tools/map_extractor/wdt.cpp @@ -57,6 +57,6 @@ bool WDT_file::prepareLoadedData() return false; wmo = (wdt_MWMO *)((uint8*)main+ main->size+8); if (!wmo->prepareLoadedData()) - return false; + wmo = NULL; // optional as of cataclysm return true; }
\ No newline at end of file diff --git a/src/tools/map_extractor/wdt.h b/src/tools/map_extractor/wdt.h index fcee8ac64f2..be6df3f173d 100644 --- a/src/tools/map_extractor/wdt.h +++ b/src/tools/map_extractor/wdt.h @@ -45,7 +45,7 @@ public: uint32 size; struct adtData{ - uint32 exist; + uint32 flag; uint32 data1; } adt_list[64][64]; diff --git a/src/tools/vmap4_assembler/CMakeLists.txt b/src/tools/vmap4_assembler/CMakeLists.txt index e4f57646c49..f0f2e88c471 100644 --- a/src/tools/vmap4_assembler/CMakeLists.txt +++ b/src/tools/vmap4_assembler/CMakeLists.txt @@ -22,7 +22,7 @@ include_directories( add_definitions(-DNO_CORE_FUNCS) add_executable(vmap4assembler VMapAssembler.cpp) -add_dependencies(vmap4assembler mpq) +add_dependencies(vmap4assembler storm) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") set_target_properties(vmap4assembler PROPERTIES LINK_FLAGS "-framework Carbon") diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt index 5c98d84eb17..5a40e89f1ac 100644 --- a/src/tools/vmap4_extractor/CMakeLists.txt +++ b/src/tools/vmap4_extractor/CMakeLists.txt @@ -15,31 +15,25 @@ file(GLOB_RECURSE sources *.cpp *.h) add_definitions("-DIOMAP_DEBUG") # build setup currently only supports libmpq 0.4.x -add_definitions("-DUSE_LIBMPQ04") -add_definitions("-Wall") -add_definitions("-ggdb") -add_definitions("-O3") - -if( UNIX ) - include_directories( - ${CMAKE_SOURCE_DIR}/dep/libmpq - ) -elseif( WIN32 ) - include_directories( - ${CMAKE_SOURCE_DIR}/dep/libmpq - ${CMAKE_SOURCE_DIR}/dep/libmpq/win - ) +if( NOT WIN32 ) + add_definitions("-Wall") + add_definitions("-ggdb") + add_definitions("-O3") endif() +include_directories( + ${CMAKE_SOURCE_DIR}/dep/StormLib/src +) + add_executable(vmap4extractor ${sources}) target_link_libraries(vmap4extractor - mpq ${BZIP2_LIBRARIES} ${ZLIB_LIBRARIES} + storm ) -add_dependencies(vmap4extractor mpq) +add_dependencies(vmap4extractor storm) if( UNIX ) install(TARGETS vmap4extractor DESTINATION bin) diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index a966172a3be..c53b63ffa5e 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -78,7 +78,9 @@ char * GetExtension(char * FileName) return NULL; } -ADTFile::ADTFile(char* filename): ADT(filename) +extern HANDLE WorldMpq; + +ADTFile::ADTFile(char* filename): ADT(WorldMpq, filename) { Adtfilename.append(filename); } diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h index 08814996f68..795eebc892f 100644 --- a/src/tools/vmap4_extractor/adtfile.h +++ b/src/tools/vmap4_extractor/adtfile.h @@ -19,7 +19,7 @@ #ifndef ADT_H #define ADT_H -#include "mpq_libmpq04.h" +#include "mpqfile.h" #include "wmo.h" #include "model.h" diff --git a/src/tools/vmap4_extractor/dbcfile.cpp b/src/tools/vmap4_extractor/dbcfile.cpp index 2474cea5259..efc8aeabe8c 100644 --- a/src/tools/vmap4_extractor/dbcfile.cpp +++ b/src/tools/vmap4_extractor/dbcfile.cpp @@ -16,80 +16,104 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "dbcfile.h" -#include "mpq_libmpq04.h" -#undef min -#undef max +#define _CRT_SECURE_NO_DEPRECATE -#include <cstdio> +#include "dbcfile.h" -DBCFile::DBCFile(const std::string &filename) : filename(filename) +DBCFile::DBCFile(HANDLE mpq, const char* filename) : + _mpq(mpq), _filename(filename), _file(NULL), _data(NULL), _stringTable(NULL) { - data = NULL; } bool DBCFile::open() { - MPQFile f(filename.c_str()); + if (!SFileOpenFileEx(_mpq, _filename, SFILE_OPEN_PATCHED_FILE, &_file)) + return false; + + char header[4]; + unsigned int na, nb, es, ss; + + DWORD readBytes = 0; + SFileReadFile(_file, header, 4, &readBytes, NULL); + if (readBytes != 4) // Number of records + return false; + + if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C') + return false; + + readBytes = 0; + SFileReadFile(_file, &na, 4, &readBytes, NULL); + if (readBytes != 4) // Number of records + return false; + + readBytes = 0; + SFileReadFile(_file, &nb, 4, &readBytes, NULL); + if (readBytes != 4) // Number of fields + return false; + + readBytes = 0; + SFileReadFile(_file, &es, 4, &readBytes, NULL); + if (readBytes != 4) // Size of a record + return false; - // Need some error checking, otherwise an unhandled exception error occurs - // if people screw with the data path. - if (f.isEof() == true) + readBytes = 0; + SFileReadFile(_file, &ss, 4, &readBytes, NULL); + if (readBytes != 4) // String size return false; - unsigned char header[4]; - unsigned int na,nb,es,ss; + _recordSize = es; + _recordCount = na; + _fieldCount = nb; + _stringSize = ss; + if (_fieldCount * 4 != _recordSize) + return false; - f.read(header,4); // File Header + _data = new unsigned char[_recordSize * _recordCount + _stringSize]; + _stringTable = _data + _recordSize*_recordCount; - if (header[0]!='W' || header[1]!='D' || header[2]!='B' || header[3] != 'C') - { - f.close(); - data = NULL; - printf("Critical Error: An error occured while trying to read the DBCFile %s.", filename.c_str()); + size_t data_size = _recordSize * _recordCount + _stringSize; + readBytes = 0; + SFileReadFile(_file, _data, data_size, &readBytes, NULL); + if (readBytes != data_size) return false; - } - - //assert(header[0]=='W' && header[1]=='D' && header[2]=='B' && header[3] == 'C'); - - f.read(&na,4); // Number of records - f.read(&nb,4); // Number of fields - f.read(&es,4); // Size of a record - f.read(&ss,4); // String size - - recordSize = es; - recordCount = na; - fieldCount = nb; - stringSize = ss; - //assert(fieldCount*4 == recordSize); - assert(fieldCount*4 >= recordSize); - - data = new unsigned char[recordSize*recordCount+stringSize]; - stringTable = data + recordSize*recordCount; - f.read(data,recordSize*recordCount+stringSize); - f.close(); + return true; } DBCFile::~DBCFile() { - delete [] data; + delete [] _data; + if (_file != NULL) + SFileCloseFile(_file); } DBCFile::Record DBCFile::getRecord(size_t id) { - assert(data); - return Record(*this, data + id*recordSize); + assert(_data); + return Record(*this, _data + id*_recordSize); +} + +size_t DBCFile::getMaxId() +{ + assert(_data); + + size_t maxId = 0; + for(size_t i = 0; i < getRecordCount(); ++i) + if (maxId < getRecord(i).getUInt(0)) + maxId = getRecord(i).getUInt(0); + + return maxId; } DBCFile::Iterator DBCFile::begin() { - assert(data); - return Iterator(*this, data); + assert(_data); + return Iterator(*this, _data); } DBCFile::Iterator DBCFile::end() { - assert(data); - return Iterator(*this, stringTable); + assert(_data); + return Iterator(*this, _stringTable); } + diff --git a/src/tools/vmap4_extractor/dbcfile.h b/src/tools/vmap4_extractor/dbcfile.h index 56cce9a521c..007ccb6cdcb 100644 --- a/src/tools/vmap4_extractor/dbcfile.h +++ b/src/tools/vmap4_extractor/dbcfile.h @@ -18,138 +18,128 @@ #ifndef DBCFILE_H #define DBCFILE_H - #include <cassert> #include <string> +#include "StormLib.h" class DBCFile { -public: - DBCFile(const std::string &filename); - ~DBCFile(); - - // Open database. It must be openened before it can be used. - bool open(); - - // TODO: Add a close function? - - // Database exceptions - class Exception - { public: - Exception(const std::string &message): message(message) - { } - virtual ~Exception() - { } - const std::string &getMessage() {return message;} - private: - std::string message; - }; + DBCFile(HANDLE mpq, const char* filename); + ~DBCFile(); - // - class NotFound: public Exception - { - public: - NotFound(): Exception("Key was not found") - { } - }; - - // Iteration over database - class Iterator; - class Record - { - public: - Record& operator= (const Record& r) - { - file = r.file; - offset = r.offset; - return *this; - } - float getFloat(size_t field) const - { - assert(field < file.fieldCount); - return *reinterpret_cast<float*>(offset+field*4); - } - unsigned int getUInt(size_t field) const - { - assert(field < file.fieldCount); - return *reinterpret_cast<unsigned int*>(offset+(field*4)); - } - int getInt(size_t field) const + // Open database. It must be openened before it can be used. + bool open(); + + // Database exceptions + class Exception { - assert(field < file.fieldCount); - return *reinterpret_cast<int*>(offset+field*4); - } - unsigned char getByte(size_t ofs) const + public: + Exception(const std::string &message) : message(message) { } + virtual ~Exception() { } + const std::string &getMessage() { return message; } + private: + std::string message; + }; + + class NotFound: public Exception { - assert(ofs < file.recordSize); - return *reinterpret_cast<unsigned char*>(offset+ofs); - } - const char *getString(size_t field) const + public: + NotFound(): Exception("Key was not found") { } + }; + + // Iteration over database + class Iterator; + class Record { - assert(field < file.fieldCount); - size_t stringOffset = getUInt(field); - assert(stringOffset < file.stringSize); - //char * tmp = (char*)file.stringTable + stringOffset; - //unsigned char * tmp2 = file.stringTable + stringOffset; - return reinterpret_cast<char*>(file.stringTable + stringOffset); - } - private: - Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} - DBCFile &file; - unsigned char *offset; + public: + float getFloat(size_t field) const + { + assert(field < file._fieldCount); + return *reinterpret_cast<float*>(offset+field*4); + } - friend class DBCFile; - friend class Iterator; - }; + unsigned int getUInt(size_t field) const + { + assert(field < file._fieldCount); + return *reinterpret_cast<unsigned int*>(offset+field*4); + } - /* Iterator that iterates over records */ - class Iterator - { - public: - Iterator(DBCFile &file, unsigned char *offset): - record(file, offset) {} - /// Advance (prefix only) - Iterator & operator++() { - record.offset += record.file.recordSize; - return *this; - } - /// Return address of current instance - Record const & operator*() const { return record; } - const Record* operator->() const { - return &record; - } - /// Comparison - bool operator==(const Iterator &b) const - { - return record.offset == b.record.offset; - } - bool operator!=(const Iterator &b) const + int getInt(size_t field) const + { + assert(field < file._fieldCount); + return *reinterpret_cast<int*>(offset+field*4); + } + + const char *getString(size_t field) const + { + assert(field < file._fieldCount); + size_t stringOffset = getUInt(field); + assert(stringOffset < file._stringSize); + return reinterpret_cast<char*>(file._stringTable + stringOffset); + } + + private: + Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} + unsigned char *offset; + DBCFile &file; + + friend class DBCFile; + friend class DBCFile::Iterator; + }; + /** Iterator that iterates over records + */ + class Iterator { - return record.offset != b.record.offset; - } + public: + Iterator(DBCFile &file, unsigned char *offset) : record(file, offset) { } + + /// Advance (prefix only) + Iterator & operator++() + { + record.offset += record.file._recordSize; + return *this; + } + + /// Return address of current instance + Record const & operator*() const { return record; } + const Record* operator->() const { return &record; } + + /// Comparison + bool operator==(const Iterator &b) const + { + return record.offset == b.record.offset; + } + + bool operator!=(const Iterator &b) const + { + return record.offset != b.record.offset; + } + private: + Record record; + }; + + // Get record by id + Record getRecord(size_t id); + /// Get begin iterator over records + Iterator begin(); + /// Get begin iterator over records + Iterator end(); + /// Trivial + size_t getRecordCount() const { return _recordCount; } + size_t getFieldCount() const { return _fieldCount; } + size_t getMaxId(); + private: - Record record; - }; - - // Get record by id - Record getRecord(size_t id); - /// Get begin iterator over records - Iterator begin(); - /// Get begin iterator over records - Iterator end(); - /// Trivial - size_t getRecordCount() const { return recordCount;} - size_t getFieldCount() const { return fieldCount; } - -private: - std::string filename; - size_t recordSize; - size_t recordCount; - size_t fieldCount; - size_t stringSize; - unsigned char *data; - unsigned char *stringTable; + HANDLE _mpq; + const char* _filename; + HANDLE _file; + size_t _recordSize; + size_t _recordCount; + size_t _fieldCount; + size_t _stringSize; + unsigned char *_data; + unsigned char* _stringTable; }; #endif diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp index 8a1f67cd2c2..4c8e423bfc4 100644 --- a/src/tools/vmap4_extractor/gameobject_extract.cpp +++ b/src/tools/vmap4_extractor/gameobject_extract.cpp @@ -35,10 +35,12 @@ bool ExtractSingleModel(std::string& fname) return mdl.ConvertToVMAPModel(output.c_str()); } +extern HANDLE LocaleMpq; + void ExtractGameobjectModels() { printf("Extracting GameObject models..."); - DBCFile dbc("DBFilesClient\\GameObjectDisplayInfo.dbc"); + DBCFile dbc(LocaleMpq, "DBFilesClient\\GameObjectDisplayInfo.dbc"); if(!dbc.open()) { printf("Fatal error: Invalid GameObjectDisplayInfo.dbc file format!\n"); diff --git a/src/tools/vmap4_extractor/loadlib/loadlib.h b/src/tools/vmap4_extractor/loadlib/loadlib.h deleted file mode 100644 index 61865c4b436..00000000000 --- a/src/tools/vmap4_extractor/loadlib/loadlib.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef LOAD_LIB_H -#define LOAD_LIB_H - -#ifdef WIN32 -typedef __int64 int64; -typedef __int32 int32; -typedef __int16 int16; -typedef __int8 int8; -typedef unsigned __int64 uint64; -typedef unsigned __int32 uint32; -typedef unsigned __int16 uint16; -typedef unsigned __int8 uint8; -#else -#include <stdint.h> -#ifndef uint64_t -#ifdef __linux__ -#include <linux/types.h> -#endif -#endif -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; -#endif - -#define FILE_FORMAT_VERSION 18 - -// -// File version chunk -// -struct file_MVER -{ - union{ - uint32 fcc; - char fcc_txt[4]; - }; - uint32 size; - uint32 ver; -}; - -class FileLoader{ - uint8 *data; - uint32 data_size; -public: - virtual bool prepareLoadedData(); - uint8 *GetData() {return data;} - uint32 GetDataSize() {return data_size;} - - file_MVER *version; - FileLoader(); - ~FileLoader(); - bool loadFile(char *filename, bool log = true); - virtual void free(); -}; -#endif diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index e81972f521f..d98dca9001b 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -19,18 +19,20 @@ #include "vmapexport.h" #include "model.h" #include "wmo.h" -#include "mpq_libmpq04.h" +#include "mpqfile.h" #include <cassert> #include <algorithm> #include <cstdio> +extern HANDLE WorldMpq; + Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0) { } bool Model::open() { - MPQFile f(filename.c_str()); + MPQFile f(WorldMpq, filename.c_str()); ok = !f.isEof(); diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h index a6f4e27583c..9000d7e4822 100644 --- a/src/tools/vmap4_extractor/model.h +++ b/src/tools/vmap4_extractor/model.h @@ -19,7 +19,6 @@ #ifndef MODEL_H #define MODEL_H -#include "loadlib/loadlib.h" #include "vec3d.h" //#include "mpq.h" #include "modelheaders.h" diff --git a/src/tools/vmap4_extractor/modelheaders.h b/src/tools/vmap4_extractor/modelheaders.h index d859fd3511e..7fd908d7442 100644 --- a/src/tools/vmap4_extractor/modelheaders.h +++ b/src/tools/vmap4_extractor/modelheaders.h @@ -19,12 +19,7 @@ #ifndef MODELHEADERS_H #define MODELHEADERS_H -/* typedef unsigned char uint8; -typedef char int8; -typedef unsigned short uint16; -typedef short int16; -typedef unsigned int uint32; -typedef int int32; */ +#include "mpqfile.h" // integer typedefs #pragma pack(push,1) diff --git a/src/tools/vmap4_extractor/mpq_libmpq.cpp b/src/tools/vmap4_extractor/mpq_libmpq.cpp deleted file mode 100644 index 528b9679a58..00000000000 --- a/src/tools/vmap4_extractor/mpq_libmpq.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "mpq_libmpq04.h" -#include <deque> -#include <cstdio> - -ArchiveSet gOpenArchives; - -MPQArchive::MPQArchive(const char* filename) -{ - int result = libmpq__archive_open(&mpq_a, filename, -1); - printf("Opening %s\n", filename); - if(result) { - switch(result) { - case LIBMPQ_ERROR_OPEN : - printf("Error opening archive '%s': Does file really exist?\n", filename); - break; - case LIBMPQ_ERROR_FORMAT : /* bad file format */ - printf("Error opening archive '%s': Bad file format\n", filename); - break; - case LIBMPQ_ERROR_SEEK : /* seeking in file failed */ - printf("Error opening archive '%s': Seeking in file failed\n", filename); - break; - case LIBMPQ_ERROR_READ : /* Read error in archive */ - printf("Error opening archive '%s': Read error in archive\n", filename); - break; - case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */ - printf("Error opening archive '%s': Maybe not enough memory\n", filename); - break; - default: - printf("Error opening archive '%s': Unknown error\n", filename); - break; - } - return; - } - gOpenArchives.push_front(this); -} - -void MPQArchive::close() -{ - //gOpenArchives.erase(erase(&mpq_a); - libmpq__archive_close(mpq_a); -} - -MPQFile::MPQFile(const char* filename): - eof(false), - buffer(0), - pointer(0), - size(0) -{ - for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i) - { - mpq_archive *mpq_a = (*i)->mpq_a; - - uint32 filenum; - if(libmpq__file_number(mpq_a, filename, &filenum)) continue; - libmpq__off_t transferred; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - // HACK: in patch.mpq some files don't want to open and give 1 for filesize - if (size<=1) { - // printf("info: file %s has size %d; considered dummy file.\n", filename, size); - eof = true; - buffer = 0; - return; - } - buffer = new char[size]; - - //libmpq_file_getdata - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/ - return; - - } - eof = true; - buffer = 0; -} - -size_t MPQFile::read(void* dest, size_t bytes) -{ - if (eof) return 0; - - size_t rpos = pointer + bytes; - if (rpos > size) { - bytes = size - pointer; - eof = true; - } - - memcpy(dest, &(buffer[pointer]), bytes); - - pointer = rpos; - - return bytes; -} - -void MPQFile::seek(int offset) -{ - pointer = offset; - eof = (pointer >= size); -} - -void MPQFile::seekRelative(int offset) -{ - pointer += offset; - eof = (pointer >= size); -} - -void MPQFile::close() -{ - if (buffer) delete[] buffer; - buffer = 0; - eof = true; -} diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h deleted file mode 100644 index ed51022de78..00000000000 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ /dev/null @@ -1,91 +0,0 @@ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_WARNINGS - -#ifndef MPQ_H -#define MPQ_H - -#include "loadlib/loadlib.h" -#include "libmpq/mpq.h" -#include <string.h> -#include <ctype.h> -#include <vector> -#include <iostream> -#include <deque> - -using namespace std; - -class MPQArchive -{ - -public: - mpq_archive_s *mpq_a; - - MPQArchive(const char* filename); - void close(); - - void GetFileListTo(vector<string>& filelist) { - uint32 filenum; - if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; - libmpq__off_t size, transferred; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - char *buffer = new char[size]; - - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - - char seps[] = "\n"; - char *token; - - token = strtok( buffer, seps ); - uint32 counter = 0; - while ((token != NULL) && (counter < size)) { - //cout << token << endl; - token[strlen(token) - 1] = 0; - string s = token; - filelist.push_back(s); - counter += strlen(token) + 2; - token = strtok(NULL, seps); - } - - delete[] buffer; - } -}; -typedef std::deque<MPQArchive*> ArchiveSet; - -class MPQFile -{ - //MPQHANDLE handle; - bool eof; - char *buffer; - libmpq__off_t pointer,size; - - // disable copying - MPQFile(const MPQFile &f) {} - void operator=(const MPQFile &f) {} - -public: - MPQFile(const char* filename); // filenames are not case sensitive - ~MPQFile() { close(); } - size_t read(void* dest, size_t bytes); - size_t getSize() { return size; } - size_t getPos() { return pointer; } - char* getBuffer() { return buffer; } - char* getPointer() { return buffer + pointer; } - bool isEof() { return eof; } - void seek(int offset); - void seekRelative(int offset); - void close(); -}; - -inline void flipcc(char *fcc) -{ - char t; - t=fcc[0]; - fcc[0]=fcc[3]; - fcc[3]=t; - t=fcc[1]; - fcc[1]=fcc[2]; - fcc[2]=t; -} - -#endif diff --git a/src/tools/vmap4_extractor/mpqfile.cpp b/src/tools/vmap4_extractor/mpqfile.cpp new file mode 100644 index 00000000000..9f019f99f38 --- /dev/null +++ b/src/tools/vmap4_extractor/mpqfile.cpp @@ -0,0 +1,86 @@ +#include "mpqfile.h" +#include <deque> +#include <cstdio> +#include "StormLib.h" + +MPQFile::MPQFile(HANDLE mpq, const char* filename): + eof(false), + buffer(0), + pointer(0), + size(0) +{ + HANDLE file; + if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file)) + { + fprintf(stderr, "Can't open %s, err=%u!\n", filename, GetLastError()); + eof = true; + return; + } + + DWORD hi = 0; + size = SFileGetFileSize(file, &hi); + + if (hi) + { + fprintf(stderr, "Can't open %s, size[hi] = %u!\n", filename, (uint32)hi); + SFileCloseFile(file); + eof = true; + return; + } + + if (size <= 1) + { + fprintf(stderr, "Can't open %s, size = %u!\n", filename, size); + SFileCloseFile(file); + eof = true; + return; + } + + DWORD read = 0; + buffer = new char[size]; + if (!SFileReadFile(file, buffer, size, &read) || size != read) + { + fprintf(stderr, "Can't read %s, size=%u read=%u!\n", filename, size, read); + SFileCloseFile(file); + eof = true; + return; + } + + SFileCloseFile(file); +} + +size_t MPQFile::read(void* dest, size_t bytes) +{ + if (eof) return 0; + + size_t rpos = pointer + bytes; + if (rpos > size) { + bytes = size - pointer; + eof = true; + } + + memcpy(dest, &(buffer[pointer]), bytes); + + pointer = rpos; + + return bytes; +} + +void MPQFile::seek(int offset) +{ + pointer = offset; + eof = (pointer >= size); +} + +void MPQFile::seekRelative(int offset) +{ + pointer += offset; + eof = (pointer >= size); +} + +void MPQFile::close() +{ + if (buffer) delete[] buffer; + buffer = 0; + eof = true; +} diff --git a/src/tools/vmap4_extractor/mpqfile.h b/src/tools/vmap4_extractor/mpqfile.h new file mode 100644 index 00000000000..115d096a215 --- /dev/null +++ b/src/tools/vmap4_extractor/mpqfile.h @@ -0,0 +1,80 @@ +#define _CRT_SECURE_NO_DEPRECATE +#ifndef _CRT_SECURE_NO_WARNINGS // fuck the police^Wwarnings +#define _CRT_SECURE_NO_WARNINGS +#endif + +#ifndef MPQ_H +#define MPQ_H + +#include <string.h> +#include <ctype.h> +#include <vector> +#include <iostream> +#include <deque> + +#ifdef _WIN32 +#include <Windows.h> // mainly only HANDLE definition is required +typedef __int64 int64; +typedef __int32 int32; +typedef __int16 int16; +typedef __int8 int8; +typedef unsigned __int64 uint64; +typedef unsigned __int32 uint32; +typedef unsigned __int16 uint16; +typedef unsigned __int8 uint8; +#else +#include <stdint.h> +#ifndef uint64_t +#ifdef __linux__ +#include <linux/types.h> +#endif +#endif +typedef int64_t int64; +typedef int32_t int32; +typedef int16_t int16; +typedef int8_t int8; +typedef uint64_t uint64; +typedef uint32_t uint32; +typedef uint16_t uint16; +typedef uint8_t uint8; +#endif + +using namespace std; + +class MPQFile +{ + //MPQHANDLE handle; + bool eof; + char *buffer; + size_t pointer,size; + + // disable copying + MPQFile(const MPQFile &f); + void operator=(const MPQFile &f); + +public: + MPQFile(HANDLE mpq, const char* filename); // filenames are not case sensitive + ~MPQFile() { close(); } + size_t read(void* dest, size_t bytes); + size_t getSize() { return size; } + size_t getPos() { return pointer; } + char* getBuffer() { return buffer; } + char* getPointer() { return buffer + pointer; } + bool isEof() { return eof; } + void seek(int offset); + void seekRelative(int offset); + void close(); +}; + +inline void flipcc(char *fcc) +{ + char t; + t=fcc[0]; + fcc[0]=fcc[3]; + fcc[3]=t; + t=fcc[1]; + fcc[1]=fcc[2]; + fcc[2]=t; +} + +#endif diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index e60a773c6de..d7b2f30d349 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -45,7 +45,7 @@ #include "wdtfile.h" #include "dbcfile.h" #include "wmo.h" -#include "mpq_libmpq04.h" +#include "mpqfile.h" #include "vmapexport.h" @@ -56,7 +56,37 @@ //----------------------------------------------------------------------------- -extern ArchiveSet gOpenArchives; +HANDLE WorldMpq = NULL; +HANDLE LocaleMpq = NULL; + +uint32 CONF_TargetBuild = 15595; // 4.3.4.15595 + +// List MPQ for extract maps from +char const* CONF_mpq_list[]= +{ + "world.MPQ", + "art.MPQ", + "expansion1.MPQ", + "expansion2.MPQ", + "expansion3.MPQ", + "world2.MPQ", +}; + +uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0}; +#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder + +char* const Locales[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU"}; +TCHAR* const LocalesT[] = +{ + _T("enGB"), _T("enUS"), + _T("deDE"), _T("esES"), + _T("frFR"), _T("koKR"), + _T("zhCN"), _T("zhTW"), + _T("enCN"), _T("enTW"), + _T("esMX"), _T("ruRU"), +}; + +#define LOCALES_COUNT 12 typedef struct { @@ -69,7 +99,6 @@ uint16 *LiqType = 0; uint32 map_count; char output_path[128]="."; char input_path[1024]="."; -bool hasInputPathParam = false; bool preciseVectorData = false; // Constants @@ -78,6 +107,148 @@ bool preciseVectorData = false; const char* szWorkDirWmo = "./Buildings"; const char* szRawVMAPMagic = "VMAP041"; +bool LoadLocaleMPQFile(int locale) +{ + TCHAR buff[512]; + memset(buff, 0, sizeof(buff)); + _stprintf(buff, _T("%s%s/locale-%s.MPQ"), input_path, LocalesT[locale], LocalesT[locale]); + if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &LocaleMpq)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open archive %s\n"), buff); + return false; + } + + char const* prefix = NULL; + for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) + { + memset(buff, 0, sizeof(buff)); + if (Builds[i] > LAST_DBC_IN_DATA_BUILD) + { + prefix = ""; + _stprintf(buff, _T("%s%s/wow-update-%s-%u.MPQ"), input_path, LocalesT[locale], LocalesT[locale], Builds[i]); + } + else + { + prefix = Locales[locale]; + _stprintf(buff, _T("%swow-update-%u.MPQ"), input_path, Builds[i]); + } + + if (!SFileOpenPatchArchive(LocaleMpq, buff, prefix, 0)) + { + if (GetLastError() != ERROR_FILE_NOT_FOUND) + _tprintf(_T("Cannot open patch archive %s\n"), buff); + continue; + } + } + + return true; +} + +void LoadCommonMPQFiles(uint32 build) +{ + TCHAR filename[512]; + _stprintf(filename, _T("%sworld.MPQ"), input_path); + if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open archive %s\n"), filename); + return; + } + + int count = sizeof(CONF_mpq_list) / sizeof(char*); + for (int i = 1; i < count; ++i) + { + if (build < 15211 && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ + continue; + + _stprintf(filename, _T("%s%s"), input_path, CONF_mpq_list[i]); + if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open archive %s\n"), filename); + else + _tprintf(_T("Not found %s\n"), filename); + } + else + { + _tprintf(_T("Loaded %s\n"), filename); + + bool found = false; + int count = 0; + SFILE_FIND_DATA data; + HANDLE find = SFileFindFirstFile(WorldMpq, "*.*", &data, NULL); + if (find != NULL) + { + do + { + ++count; + if (data.dwFileFlags & MPQ_FILE_PATCH_FILE) + { + found = true; + break; + } + } + while (SFileFindNextFile(find, &data)); + } + SFileFindClose(find); + printf("Scanned %d files, found patch = %d\n", count, found); + } + } + + char const* prefix = NULL; + for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) + { + memset(filename, 0, sizeof(filename)); + if (Builds[i] > LAST_DBC_IN_DATA_BUILD) + { + prefix = ""; + _stprintf(filename, _T("%swow-update-base-%u.MPQ"), input_path, Builds[i]); + } + else + { + prefix = "base"; + _stprintf(filename, _T("%swow-update-%u.MPQ"), input_path, Builds[i]); + } + + if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + _tprintf(_T("Cannot open patch archive %s\n"), filename); + else + _tprintf(_T("Not found %s\n"), filename); + continue; + } + else + { + _tprintf(_T("Loaded %s\n"), filename); + + + bool found = false; + int count = 0; + SFILE_FIND_DATA data; + HANDLE find = SFileFindFirstFile(WorldMpq, "*.*", &data, NULL); + if (find != NULL) + { + do + { + ++count; + if (data.dwFileFlags & MPQ_FILE_PATCH_FILE) + { + found = true; + break; + } + } + while (SFileFindNextFile(find, &data)); + } + SFileFindClose(find); + printf("Scanned %d files, found patch = %d\n", count, found); + } + } + +} + + // Local testing functions bool FileExists(const char* file) @@ -103,7 +274,8 @@ void strToLower(char* str) void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); - DBCFile dbc("DBFilesClient\\LiquidType.dbc"); + + DBCFile dbc(LocaleMpq, "DBFilesClient\\LiquidType.dbc"); if(!dbc.open()) { printf("Fatal error: Invalid LiquidType.dbc file format!\n"); @@ -123,21 +295,23 @@ void ReadLiquidTypeTableDBC() bool ExtractWmo() { - bool success = true; + bool success = false; //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"}; - for (ArchiveSet::const_iterator ar_itr = gOpenArchives.begin(); ar_itr != gOpenArchives.end() && success; ++ar_itr) + SFILE_FIND_DATA data; + HANDLE find = SFileFindFirstFile(WorldMpq, "*.wmo", &data, NULL); + if (find != NULL) { - vector<string> filelist; - - (*ar_itr)->GetFileListTo(filelist); - for (vector<string>::iterator fname = filelist.begin(); fname != filelist.end() && success; ++fname) + do { - if (fname->find(".wmo") != string::npos) - success = ExtractSingleWmo(*fname); + std::string str = data.cFileName; + //printf("Extracting wmo %s\n", str.c_str()); + success |= ExtractSingleWmo(str); } + while (SFileFindNextFile(find, &data)); } + SFileFindClose(find); if (success) printf("\nExtract wmo complete (No (fatal) errors)\n"); @@ -297,91 +471,10 @@ bool scan_patches(char* scanmatch, std::vector<std::string>& pArchiveNames) return(true); } -bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames) -{ - if(!hasInputPathParam) - getGamePath(); - - printf("\nGame path: %s\n", input_path); - - char path[512]; - string in_path(input_path); - std::vector<std::string> locales, searchLocales; - - searchLocales.push_back("enGB"); - searchLocales.push_back("enUS"); - searchLocales.push_back("deDE"); - searchLocales.push_back("esES"); - searchLocales.push_back("frFR"); - searchLocales.push_back("koKR"); - searchLocales.push_back("zhCN"); - searchLocales.push_back("zhTW"); - searchLocales.push_back("enCN"); - searchLocales.push_back("enTW"); - searchLocales.push_back("esMX"); - searchLocales.push_back("ruRU"); - - for (std::vector<std::string>::iterator i = searchLocales.begin(); i != searchLocales.end(); ++i) - { - std::string localePath = in_path + *i; - // check if locale exists: - struct stat status; - if (stat(localePath.c_str(), &status)) - continue; - if ((status.st_mode & S_IFDIR) == 0) - continue; - printf("Found locale '%s'\n", i->c_str()); - locales.push_back(*i); - } - printf("\n"); - - // open locale expansion and common files - printf("Adding data files from locale directories.\n"); - for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i) - { - pArchiveNames.push_back(in_path + *i + "/locale-" + *i + ".MPQ"); - pArchiveNames.push_back(in_path + *i + "/expansion-locale-" + *i + ".MPQ"); - pArchiveNames.push_back(in_path + *i + "/lichking-locale-" + *i + ".MPQ"); - } - - // open expansion and common files - pArchiveNames.push_back(input_path + string("common.MPQ")); - pArchiveNames.push_back(input_path + string("common-2.MPQ")); - pArchiveNames.push_back(input_path + string("expansion.MPQ")); - pArchiveNames.push_back(input_path + string("lichking.MPQ")); - - // now, scan for the patch levels in the core dir - printf("Scanning patch levels from data directory.\n"); - sprintf(path, "%spatch", input_path); - if (!scan_patches(path, pArchiveNames)) - return(false); - - // now, scan for the patch levels in locale dirs - printf("Scanning patch levels from locale directories.\n"); - bool foundOne = false; - for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i) - { - printf("Locale: %s\n", i->c_str()); - sprintf(path, "%s%s/patch-%s", input_path, i->c_str(), i->c_str()); - if(scan_patches(path, pArchiveNames)) - foundOne = true; - } - - printf("\n"); - - if(!foundOne) - { - printf("no locale found\n"); - return false; - } - - return true; -} - bool processArgv(int argc, char ** argv, const char *versionString) { bool result = true; - hasInputPathParam = false; + bool hasInputPathParam = false; bool preciseVectorData = false; for(int i=1; i< argc; ++i) @@ -413,12 +506,18 @@ bool processArgv(int argc, char ** argv, const char *versionString) { preciseVectorData = true; } + else if(strcmp("-b",argv[i]) == 0) + { + if (i + 1 < argc) // all ok + CONF_TargetBuild = atoi(argv[i++ + 1]); + } else { result = false; break; } } + if(!result) { printf("Extract %s.\n",versionString); @@ -426,8 +525,13 @@ bool processArgv(int argc, char ** argv, const char *versionString) printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n"); printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n"); printf(" -d <path>: Path to the vector data source folder.\n"); + printf(" -b : target build (default %u)", CONF_TargetBuild); printf(" -? : This message.\n"); } + + if(!hasInputPathParam) + getGamePath(); + return result; } @@ -476,21 +580,24 @@ int main(int argc, char ** argv) )) success = (errno == EEXIST); - // prepare archive name list - std::vector<std::string> archiveNames; - fillArchiveNameVector(archiveNames); - for (size_t i=0; i < archiveNames.size(); ++i) - { - MPQArchive *archive = new MPQArchive(archiveNames[i].c_str()); - if(!gOpenArchives.size() || gOpenArchives.front() != archive) - delete archive; - } + LoadCommonMPQFiles(CONF_TargetBuild); + + int FirstLocale = -1; - if(gOpenArchives.empty()) + for (int i = 0; i < LOCALES_COUNT; ++i) { - printf("FATAL ERROR: None MPQ archive found by path '%s'. Use -d option with proper path.\n",input_path); - return 1; + //Open MPQs + if (!LoadLocaleMPQFile(i)) + { + if (GetLastError() != ERROR_PATH_NOT_FOUND) + printf("Unable to load %s locale archives!\n", Locales[i]); + continue; + } + + printf("Detected and using locale locale: %s\n", Locales[i]); + break; } + ReadLiquidTypeTableDBC(); // extract data @@ -501,7 +608,7 @@ int main(int argc, char ** argv) //map.dbc if(success) { - DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc"); + DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc"); if(!dbc->open()) { delete dbc; @@ -526,6 +633,9 @@ int main(int argc, char ** argv) ExtractGameobjectModels(); } + SFileCloseArchive(LocaleMpq); + SFileCloseArchive(WorldMpq); + printf("\n"); if(!success) { diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index e3ee545db19..2dd7396ae7d 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -30,7 +30,9 @@ char * wdtGetPlainName(char * FileName) return FileName; } -WDTFile::WDTFile(char* file_name, char* file_name1):WDT(file_name) +extern HANDLE WorldMpq; + +WDTFile::WDTFile(char* file_name, char* file_name1):WDT(WorldMpq, file_name) { filename.append(file_name1,strlen(file_name1)); } @@ -129,6 +131,6 @@ ADTFile* WDTFile::GetMap(int x, int z) char name[512]; - sprintf(name,"World\\Maps\\%s\\%s_%d_%d.adt", filename.c_str(), filename.c_str(), x, z); + sprintf(name,"World\\Maps\\%s\\%s_%d_%d_obj0.adt", filename.c_str(), filename.c_str(), x, z); return new ADTFile(name); } diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index f3d71c41791..ef3ec6db98c 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -1,7 +1,7 @@ #ifndef WDTFILE_H #define WDTFILE_H -#include "mpq_libmpq04.h" +#include "mpqfile.h" #include "wmo.h" #include <string> #include "stdlib.h" diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 6703872111b..8bba5610c88 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -26,7 +26,7 @@ #include <fstream> #undef min #undef max -#include "mpq_libmpq04.h" +#include "mpqfile.h" using namespace std; extern uint16 *LiqType; @@ -35,9 +35,11 @@ WMORoot::WMORoot(std::string &filename) : filename(filename) { } +extern HANDLE WorldMpq; + bool WMORoot::open() { - MPQFile f(filename.c_str()); + MPQFile f(WorldMpq, filename.c_str()); if(f.isEof ()) { printf("No such file.\n"); @@ -143,7 +145,7 @@ WMOGroup::WMOGroup(std::string &filename) : filename(filename), bool WMOGroup::open() { - MPQFile f(filename.c_str()); + MPQFile f(WorldMpq, filename.c_str()); if(f.isEof ()) { printf("No such file.\n"); diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index d1f7b82f0c6..7020bb90f12 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -24,7 +24,7 @@ #include <string> #include <set> #include "vec3d.h" -#include "loadlib/loadlib.h" +#include "mpqfile.h" // MOPY flags #define WMO_MATERIAL_NOCAMCOLLIDE 0x01 |