From 0f7077546fa4eafe4a8b7d94e0ce8d5fbe9c3a03 Mon Sep 17 00:00:00 2001 From: tomrus88 Date: Fri, 12 Dec 2008 01:44:52 +0300 Subject: [PATCH] Implemented character customize future. Not tested, but should work... --- sql/wotlk_updates/10_mangos_string.sql | 3 + src/game/CharacterHandler.cpp | 120 +++++++++++++++++++++---- src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Language.h | 2 + src/game/Level2.cpp | 53 +++++++++++ src/game/Opcodes.cpp | 2 +- src/game/Player.cpp | 109 +++++++++++----------- src/game/Player.h | 4 +- src/game/WorldSession.h | 1 + src/shared/Database/DBCStructure.h | 5 +- 11 files changed, 229 insertions(+), 72 deletions(-) create mode 100644 sql/wotlk_updates/10_mangos_string.sql diff --git a/sql/wotlk_updates/10_mangos_string.sql b/sql/wotlk_updates/10_mangos_string.sql new file mode 100644 index 000000000..7ac51e307 --- /dev/null +++ b/sql/wotlk_updates/10_mangos_string.sql @@ -0,0 +1,3 @@ +INSERT INTO `mangos_string` VALUES +(345,'Forced customize for player %s will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(346,'Forced customize for player %s (GUID #%u) will be requested at next login.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 6056832e4..f43fef017 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -914,7 +914,7 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ ) void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) { - CHECK_PACKET_SIZE(recv_data,8+1); + CHECK_PACKET_SIZE(recv_data, 8+1); uint64 guid; std::string newname; @@ -929,21 +929,20 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if (!result) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_CREATE_ERROR; + data << uint8(CHAR_CREATE_ERROR); SendPacket( &data ); return; } - uint32 at_loginFlags; Field *fields = result->Fetch(); - at_loginFlags = fields[0].GetUInt32(); + uint32 at_loginFlags = fields[0].GetUInt32(); oldname = fields[1].GetCppString(); delete result; if (!(at_loginFlags & AT_LOGIN_RENAME)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_CREATE_ERROR; + data << uint8(CHAR_CREATE_ERROR); SendPacket( &data ); return; } @@ -952,7 +951,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(!normalizePlayerName(newname)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_NAME_NO_NAME; + data << uint8(CHAR_NAME_NO_NAME); SendPacket( &data ); return; } @@ -960,7 +959,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(!ObjectMgr::IsValidName(newname,true)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_NAME_INVALID_CHARACTER; + data << uint8(CHAR_NAME_INVALID_CHARACTER); SendPacket( &data ); return; } @@ -969,7 +968,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_NAME_RESERVED; + data << uint8(CHAR_NAME_RESERVED); SendPacket( &data ); return; } @@ -977,7 +976,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_CREATE_ERROR; + data << uint8(CHAR_CREATE_NAME_IN_USE); SendPacket( &data ); return; } @@ -985,23 +984,21 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data) if(newname == oldname) // checked by client { WorldPacket data(SMSG_CHAR_RENAME, 1); - data << (uint8)CHAR_NAME_FAILURE; + data << uint8(CHAR_NAME_FAILURE); SendPacket( &data ); return; } - // we have to check character at_login_flag & AT_LOGIN_RENAME also (fake packets hehe) - CharacterDatabase.escape_string(newname); - CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME),GUID_LOPART(guid)); + CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), GUID_LOPART(guid)); CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); std::string IP_str = GetRemoteAddress(); - sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",GetAccountId(),IP_str.c_str(),oldname.c_str(),GUID_LOPART(guid),newname.c_str()); + sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), IP_str.c_str(), oldname.c_str(), GUID_LOPART(guid), newname.c_str()); WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1)); - data << (uint8)RESPONSE_SUCCESS; - data << guid; + data << uint8(RESPONSE_SUCCESS); + data << uint64(guid); data << newname; SendPacket(&data); } @@ -1167,3 +1164,94 @@ void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data ) } } } + +void WorldSession::HandleCharCustomize(WorldPacket& recv_data) +{ + CHECK_PACKET_SIZE(recv_data, 8+1); + + uint64 guid; + std::string newname; + + recv_data >> guid; + recv_data >> newname; + + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+1+1+1+1); + + uint8 gender, skin, face, hairStyle, hairColor, facialHair; + recv_data >> gender >> skin >> face >> hairStyle >> hairColor >> facialHair; + + QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); + if (!result) + { + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); + data << uint8(CHAR_CREATE_ERROR); + SendPacket( &data ); + return; + } + + Field *fields = result->Fetch(); + uint32 at_loginFlags = fields[0].GetUInt32(); + delete result; + + if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE)) + { + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); + data << uint8(CHAR_CREATE_ERROR); + SendPacket( &data ); + return; + } + + // prevent character rename to invalid name + if(!normalizePlayerName(newname)) + { + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); + data << uint8(CHAR_NAME_NO_NAME); + SendPacket( &data ); + return; + } + + if(!ObjectMgr::IsValidName(newname,true)) + { + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); + data << uint8(CHAR_NAME_INVALID_CHARACTER); + SendPacket( &data ); + return; + } + + // check name limitations + if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) + { + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); + data << uint8(CHAR_NAME_RESERVED); + SendPacket( &data ); + return; + } + + if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist + { + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); + data << uint8(CHAR_CREATE_NAME_IN_USE); + SendPacket( &data ); + return; + } + + CharacterDatabase.escape_string(newname); + Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); + CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid)); + CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); + + std::string IP_str = GetRemoteAddress(); + sLog.outChar("Account: %d (IP: %s), Character guid: %u Customized to: %s", GetAccountId(), IP_str.c_str(), GUID_LOPART(guid), newname.c_str()); + + WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6); + data << uint8(RESPONSE_SUCCESS); + data << uint64(guid); + data << newname; + data << uint8(gender); + data << uint8(skin); + data << uint8(face); + data << uint8(hairStyle); + data << uint8(hairColor); + data << uint8(facialHair); + SendPacket(&data); +} diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 3dcf8dc96..531e28670 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -555,6 +555,7 @@ ChatCommand * ChatHandler::getCommandTable() { "sendmail", SEC_MODERATOR, true, &ChatHandler::HandleSendMailCommand, "", NULL }, { "sendmoney", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL }, { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleRenameCommand, "", NULL }, + { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCustomizeCommand, "", NULL }, { "loadscripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLoadScriptsCommand, "", NULL }, { "mute", SEC_GAMEMASTER, true, &ChatHandler::HandleMuteCommand, "", NULL }, { "unmute", SEC_GAMEMASTER, true, &ChatHandler::HandleUnmuteCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index c31ae319c..f719d0aa8 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -406,6 +406,7 @@ class ChatHandler bool HandleSendChannelNotifyCommand(const char* args); bool HandleSendChatMsgCommand(const char* args); bool HandleRenameCommand(const char * args); + bool HandleCustomizeCommand(const char * args); bool HandleLoadPDumpCommand(const char *args); bool HandleWritePDumpCommand(const char *args); bool HandleCastCommand(const char *args); diff --git a/src/game/Language.h b/src/game/Language.h index ad5a2b43c..7b30279c9 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -326,6 +326,8 @@ enum MangosStrings LANG_CREATURE_NOT_FOLLOW_YOU_NOW = 342, LANG_CREATURE_NON_TAMEABLE = 343, LANG_YOU_ALREADY_HAVE_PET = 344, + LANG_CUSTOMIZE_PLAYER = 345, + LANG_CUSTOMIZE_PLAYER_GUID = 346, // Room for more level 2 345-399 not used // level 3 chat diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 875533ffc..6d4777800 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -3356,6 +3356,59 @@ bool ChatHandler::HandleRenameCommand(const char* args) return true; } +// customize characters +bool ChatHandler::HandleCustomizeCommand(const char* args) +{ + Player* target = NULL; + uint64 targetGUID = 0; + std::string oldname; + + char* px = strtok((char*)args, " "); + + if(px) + { + oldname = px; + + if(!normalizePlayerName(oldname)) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + target = objmgr.GetPlayer(oldname.c_str()); + + if (!target) + targetGUID = objmgr.GetPlayerGUIDByName(oldname); + } + + if(!target && !targetGUID) + { + target = getSelectedPlayer(); + } + + if(!target && !targetGUID) + { + SendSysMessage(LANG_PLAYER_NOT_FOUND); + SetSentErrorMessage(true); + return false; + } + + if(target) + { + PSendSysMessage(LANG_CUSTOMIZE_PLAYER, target->GetName()); + target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow()); + } + else + { + PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID)); + CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); + } + + return true; +} + //spawn go bool ChatHandler::HandleGameObjectCommand(const char* args) { diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index cde8c4df8..cc8131e7e 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -1165,7 +1165,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize }, /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_NEVER, &WorldSession::Handle_NULL }, diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 8456e39db..f4c402646 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1329,13 +1329,15 @@ void Player::setDeathState(DeathState s) void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) { - *p_data << GetGUID(); + Field *fields = result->Fetch(); + + *p_data << uint64(GetGUID()); *p_data << m_name; - *p_data << getRace(); + *p_data << uint8(getRace()); uint8 pClass = getClass(); - *p_data << pClass; - *p_data << getGender(); + *p_data << uint8(pClass); + *p_data << uint8(getGender()); uint32 bytes = GetUInt32Value(PLAYER_BYTES); *p_data << uint8(bytes); @@ -1350,14 +1352,15 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // do not use GetMap! it will spawn a new instance since the bound instances are not loaded uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY()); sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId); - *p_data << zoneId; - *p_data << GetMapId(); + *p_data << uint32(zoneId); + *p_data << uint32(GetMapId()); *p_data << GetPositionX(); *p_data << GetPositionY(); *p_data << GetPositionZ(); - *p_data << (result ? result->Fetch()[13].GetUInt32() : 0); + // guild id + *p_data << (result ? fields[13].GetUInt32() : 0); uint32 char_flags = 0; if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) @@ -1368,14 +1371,13 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_GHOST; if(HasAtLoginFlag(AT_LOGIN_RENAME)) char_flags |= CHARACTER_FLAG_RENAME; - // always send the flag if declined names aren't used - // to let the client select a default method of declining the name - if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != "")) + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != "")) char_flags |= CHARACTER_FLAG_DECLINED; - *p_data << (uint32)char_flags; // character flags - *p_data << (uint32)0; // new wotlk - *p_data << (uint8)1; // unknown + *p_data << uint32(char_flags); // character flags + // character customize (flags?) + *p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0); + *p_data << uint8(1); // unknown // Pets info { @@ -1386,8 +1388,6 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) // show pet at selection character in character list only for non-ghost character if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER)) { - Field* fields = result->Fetch(); - uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(entry); if(cInfo) @@ -1398,36 +1398,11 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) } } - *p_data << (uint32)petDisplayId; - *p_data << (uint32)petLevel; - *p_data << (uint32)petFamily; + *p_data << uint32(petDisplayId); + *p_data << uint32(petLevel); + *p_data << uint32(petFamily); } - /*ItemPrototype const *items[EQUIPMENT_SLOT_END]; - for (int i = 0; i < EQUIPMENT_SLOT_END; i++) - items[i] = NULL; - - QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow()); - if (result) - { - do - { - Field *fields = result->Fetch(); - uint8 slot = fields[0].GetUInt8() & 255; - uint32 item_id = fields[1].GetUInt32(); - if( slot >= EQUIPMENT_SLOT_END ) - continue; - - items[slot] = objmgr.GetItemPrototype(item_id); - if(!items[slot]) - { - sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id ); - continue; - } - } while (result->NextRow()); - delete result; - }*/ - for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++) { uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); @@ -1444,20 +1419,20 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) if (proto != NULL) { - *p_data << (uint32)proto->DisplayInfoID; - *p_data << (uint8)proto->InventoryType; - *p_data << (uint32)(enchant?enchant->aura_id:0); + *p_data << uint32(proto->DisplayInfoID); + *p_data << uint8(proto->InventoryType); + *p_data << uint32(enchant ? enchant->aura_id : 0); } else { - *p_data << (uint32)0; - *p_data << (uint8)0; - *p_data << (uint32)0; // enchant? + *p_data << uint32(0); + *p_data << uint8(0); + *p_data << uint32(0); // enchant? } } - *p_data << (uint32)0; // first bag display id - *p_data << (uint8)0; // first bag inventory type - *p_data << (uint32)0; // enchant? + *p_data << uint32(0); // first bag display id + *p_data << uint8(0); // first bag inventory type + *p_data << uint32(0); // enchant? } bool Player::ToggleAFK() @@ -15791,6 +15766,36 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid) Player::SetUInt32ValueInDB(index, temp, guid); } +void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair) +{ + Tokens tokens; + if(!LoadValuesArrayFromDB(tokens,guid)) + return; + + uint32 player_bytes = atol(tokens[PLAYER_BYTES].c_str()); + ((uint8*)player_bytes)[0] = skin; + ((uint8*)player_bytes)[1] = face; + ((uint8*)player_bytes)[2] = hairStyle; + ((uint8*)player_bytes)[3] = hairColor; + char buf[11]; + snprintf(buf,11,"%u",player_bytes); + tokens[PLAYER_BYTES] = buf; + + uint32 player_bytes2 = atol(tokens[PLAYER_BYTES_2].c_str()); + ((uint8*)player_bytes2)[0] = facialHair; + char buf2[11]; + snprintf(buf2,11,"%u",player_bytes2); + tokens[PLAYER_BYTES_2] = buf; + + uint32 player_bytes3 = atol(tokens[PLAYER_BYTES_3].c_str()); + ((uint8*)player_bytes3)[0] = gender; + char buf3[11]; + snprintf(buf3,11,"%u",player_bytes3); + tokens[PLAYER_BYTES_3] = buf; + + SaveValuesArrayInDB(tokens,guid); +} + void Player::SendAttackSwingNotStanding() { WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0); diff --git a/src/game/Player.h b/src/game/Player.h index b302d64fc..82c4899c8 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -548,7 +548,8 @@ enum AtLoginFlags AT_LOGIN_NONE = 0, AT_LOGIN_RENAME = 1, AT_LOGIN_RESET_SPELLS = 2, - AT_LOGIN_RESET_TALENTS = 4 + AT_LOGIN_RESET_TALENTS = 4, + AT_LOGIN_CUSTOMIZE = 8 }; typedef std::map QuestStatusMap; @@ -1333,6 +1334,7 @@ class MANGOS_DLL_SPEC Player : public Unit static void SetFloatValueInArray(Tokens& data,uint16 index, float value); static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid); static void SetFloatValueInDB(uint16 index, float value, uint64 guid); + static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair); static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid); bool m_mailsLoaded; diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 383bb8964..c12810a62 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -664,6 +664,7 @@ class MANGOS_DLL_SPEC WorldSession void HandleSpellClick(WorldPacket& recv_data); void HandleAlterAppearance(WorldPacket& recv_data); void HandleRemoveGlyph(WorldPacket& recv_data); + void HandleCharCustomize(WorldPacket& recv_data); void HandleInspectAchievements(WorldPacket& recv_data); private: // private trade methods diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 4f30eb11c..222266c96 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -40,7 +40,8 @@ struct AchievementEntry uint32 ID; // 0 uint32 factionFlag; // 1 -1=all, 0=horde, 1=alliance uint32 mapID; // 2 -1=none - //char *name[16]; // 3-19 + //uint32 unk; // 3 + //char *name[16]; // 4-19 //uint32 name_flags; // 20 //char *description[16]; // 21-36 //uint32 desc_flags; // 37 @@ -48,7 +49,7 @@ struct AchievementEntry uint32 points; // 39 reward points //uint32 OrderInCategory; // 40 uint32 flags; // 41 - //uint32 flags; // 42 not flags, some unknown value... + //uint32 icon; // 42 icon //char *unk1[16]; // 43-58 //uint32 unk_flags; // 59 //uint32 count; // 60