diff options
-rw-r--r-- | sql/characters.sql | 7 | ||||
-rw-r--r-- | sql/updates/7834_characters_characters.sql | 22 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 8 | ||||
-rw-r--r-- | src/game/Level3.cpp | 6 | ||||
-rw-r--r-- | src/game/Player.cpp | 297 | ||||
-rw-r--r-- | src/game/Player.h | 16 |
6 files changed, 164 insertions, 192 deletions
diff --git a/sql/characters.sql b/sql/characters.sql index bec2793647c..a36764752e6 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -327,7 +327,6 @@ DROP TABLE IF EXISTS `characters`; CREATE TABLE `characters` ( `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', `account` int(11) unsigned NOT NULL default '0' COMMENT 'Account Identifier', - `data` longtext, `name` varchar(12) NOT NULL default '', `race` tinyint(3) unsigned NOT NULL default '0', `class` tinyint(3) unsigned NOT NULL default '0', @@ -385,9 +384,13 @@ CREATE TABLE `characters` ( `power5` int(10) unsigned NOT NULL default'0', `power6` int(10) unsigned NOT NULL default'0', `power7` int(10) unsigned NOT NULL default'0', + `latency` int(11) unsigned NOT NULL default '0', `speccount` tinyint(3) unsigned NOT NULL default 1, `activespec` tinyint(3) unsigned NOT NULL default 0, - `latency` int(11) unsigned NOT NULL default '0', + `exploredZones` longtext, + `equipmentCache` longtext, + `ammoId` int(10) UNSIGNED NOT NULL default '0', + `knownTitles` longtext, PRIMARY KEY (`guid`), KEY `idx_account` (`account`), KEY `idx_online` (`online`), diff --git a/sql/updates/7834_characters_characters.sql b/sql/updates/7834_characters_characters.sql new file mode 100644 index 00000000000..694010bcb42 --- /dev/null +++ b/sql/updates/7834_characters_characters.sql @@ -0,0 +1,22 @@ +ALTER TABLE characters + ADD COLUMN `exploredZones` longtext AFTER activeSpec, + ADD COLUMN `equipmentCache` longtext AFTER exploredZones, + ADD COLUMN `ammoId` int(10) UNSIGNED NOT NULL default '0' AFTER equipmentCache, + ADD COLUMN `knownTitles` longtext AFTER ammoId; + +UPDATE characters SET +exploredZones = SUBSTRING(data, +length(SUBSTRING_INDEX(data, ' ', 1041))+2, +length(SUBSTRING_INDEX(data, ' ', 1168+1))- length(SUBSTRING_INDEX(data, ' ', 1041)) - 1), +equipmentCache = SUBSTRING(data, +length(SUBSTRING_INDEX(data, ' ', 283))+2, +length(SUBSTRING_INDEX(data, ' ', 320+1))- length(SUBSTRING_INDEX(data, ' ', 283)) - 1), +ammoId = SUBSTRING(data, +length(SUBSTRING_INDEX(data, ' ', 1198))+2, +length(SUBSTRING_INDEX(data, ' ', 1198+1))- length(SUBSTRING_INDEX(data, ' ', 1198)) - 1), +knownTitles = SUBSTRING(data, +length(SUBSTRING_INDEX(data, ' ', 626))+2, +length(SUBSTRING_INDEX(data, ' ', 631+1))- length(SUBSTRING_INDEX(data, ' ', 626)) - 1); + +ALTER TABLE characters + DROP COLUMN data; diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 21424a97d5b..af055e7eb0b 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -65,11 +65,11 @@ bool LoginQueryHolder::Initialize() // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. // !!! NOTE: including unused `zone`,`online` - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags," + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "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, dungeon_difficulty," "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk," - "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); + "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); @@ -164,7 +164,7 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/) // 8 9 10 11 12 13 14 "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, " // 15 16 17 18 19 - "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data " + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " "WHERE characters.account = '%u' ORDER BY characters.guid" @@ -175,7 +175,7 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/) // 8 9 10 11 12 13 14 "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, " // 15 16 17 18 19 20 - "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data, character_declinedname.genitive " + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_declinedname.genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 3b14b9d9ac2..ce811cd6fa6 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4719,7 +4719,7 @@ bool ChatHandler::HandleExploreCheatCommand(const char *args) ChatHandler(chr).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING,GetNameLink().c_str()); } - for (uint8 i=0; i<128; ++i) + for (uint8 i=0; i<PLAYER_EXPLORED_ZONES_SIZE; ++i) { if (flag != 0) { @@ -4876,7 +4876,7 @@ bool ChatHandler::HandleShowAreaCommand(const char *args) int offset = area / 32; uint32 val = (uint32)(1 << (area % 32)); - if (area<0 || offset >= 128) + if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); @@ -4907,7 +4907,7 @@ bool ChatHandler::HandleHideAreaCommand(const char *args) int offset = area / 32; uint32 val = (uint32)(1 << (area % 32)); - if (area<0 || offset >= 128) + if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 1a8be965f8f..98e8dec9e69 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -609,7 +609,7 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // default for players in 3.0.3 // -1 is default value - SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); + SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); SetUInt32Value(PLAYER_BYTES_2, (facialHair | (0x00 << 8) | (0x00 << 16) | (0x02 << 24))); @@ -619,10 +619,10 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c SetUInt32Value(PLAYER_GUILDRANK, 0); SetUInt32Value(PLAYER_GUILD_TIMESTAMP, 0); - SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES, 0); // 0=disabled - SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES1, 0); // 0=disabled - SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES2, 0); // 0=disabled + for (int i = 0; i < KNOWN_TITLES_SIZE; ++i) + SetUInt64Value(PLAYER__FIELD_KNOWN_TITLES + i, 0); // 0=disabled SetUInt32Value(PLAYER_CHOSEN_TITLE, 0); + SetUInt32Value(PLAYER_FIELD_KILLS, 0); SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0); SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0); @@ -1575,12 +1575,10 @@ bool Player::BuildEnumData(QueryResult_AutoPtr result, WorldPacket * p_data) *p_data << uint32(petFamily); } - // TODO: do not access data field here Tokens data = StrSplit(fields[19].GetCppString(), " "); - for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot) { - uint32 visualbase = PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2); + uint32 visualbase = slot * 2; uint32 item_id = GetUInt32ValueFromArray(data, visualbase); const ItemPrototype * proto = objmgr.GetItemPrototype(item_id); if (!proto) @@ -6110,9 +6108,9 @@ void Player::CheckExploreSystem() return; int offset = areaFlag / 32; - if (offset >= 128) + if (offset >= PLAYER_EXPLORED_ZONES_SIZE) { - sLog.outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u (%u must be < 128).",areaFlag,GetPositionX(),GetPositionY(),offset,offset); + sLog.outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset, PLAYER_EXPLORED_ZONES_SIZE); return; } @@ -15503,19 +15501,6 @@ bool Player::LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& return true; } -bool Player::LoadValuesArrayFromDB(Tokens& data, uint64 guid) -{ - QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT data FROM characters WHERE guid='%u'",GUID_LOPART(guid)); - if (!result) - return false; - - Field *fields = result->Fetch(); - - data = StrSplit(fields[0].GetCppString(), " "); - - return true; -} - uint32 Player::GetUInt32ValueFromArray(Tokens const& data, uint16 index) { if (index >= data.size()) @@ -15533,36 +15518,36 @@ float Player::GetFloatValueFromArray(Tokens const& data, uint16 index) return result; } -uint32 Player::GetUInt32ValueFromDB(uint16 index, uint64 guid) +void Player::_LoadIntoDataField(const char* data, uint32 startOffset, uint32 count) { - Tokens data; - if (!LoadValuesArrayFromDB(data,guid)) - return 0; - - return GetUInt32ValueFromArray(data,index); -} + if (!data) + return; + + Tokens tokens = StrSplit(data, " "); -float Player::GetFloatValueFromDB(uint16 index, uint64 guid) -{ - float result; - uint32 temp = Player::GetUInt32ValueFromDB(index, guid); - memcpy(&result, &temp, sizeof(result)); + if (tokens.size() != count) + return; - return result; + Tokens::iterator iter; + uint32 index; + for (iter = tokens.begin(), index = 0; index < count; ++iter, ++index) + { + m_uint32Values[startOffset + index] = atol((*iter).c_str()); + } } bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) { - //// 0 1 2 3 4 5 6 7 8 9 10 11 12 - //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags," - // 13 14 15 16 17 18 19 20 21 22 23 24 25 + //// 0 1 2 3 4 5 6 7 8 9 10 11 + //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," - // 26 27 28 29 30 31 32 33 34 35 36 37 38 39 + // 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, dungeon_difficulty," - // 40 41 42 43 44 45 46 47 48 49 50 + // 39 40 41 42 43 44 45 46 47 48 49 //"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk," - // 51 52 53 54 55 56 57 58 59 60 61 - //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec FROM characters WHERE guid = '%u'", guid); + // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 + //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles FROM characters WHERE guid = '%u'", guid); QueryResult_AutoPtr result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM); if (!result) @@ -15585,7 +15570,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) Object::_Create(guid, 0, HIGHGUID_PLAYER); - m_name = fields[3].GetCppString(); + m_name = fields[2].GetCppString(); // check name limitations if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS || @@ -15595,37 +15580,41 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) return false; } - if (!LoadValues(fields[2].GetString())) - { - sLog.outError("Player #%d have broken data in `data` field. Can't be loaded.", GUID_LOPART(guid)); - return false; - } - // overwrite possible wrong/corrupted guid SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); // overwrite some data fields - uint32 bytes0 = GetUInt32Value(UNIT_FIELD_BYTES_0) & 0xFF000000; - bytes0 |= fields[4].GetUInt8(); // race - bytes0 |= fields[5].GetUInt8() << 8; // class - bytes0 |= fields[6].GetUInt8() << 16; // gender + uint32 bytes0 = 0; + bytes0 |= fields[3].GetUInt8(); // race + bytes0 |= fields[4].GetUInt8() << 8; // class + bytes0 |= fields[5].GetUInt8() << 16; // gender SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0); - SetUInt32Value(UNIT_FIELD_LEVEL, fields[7].GetUInt8()); - SetUInt32Value(PLAYER_XP, fields[8].GetUInt32()); + SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8()); + SetUInt32Value(PLAYER_XP, fields[7].GetUInt32()); - uint32 money = fields[9].GetUInt32(); + _LoadIntoDataField(fields[61].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); + _LoadIntoDataField(fields[64].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); + + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); + SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f); + SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); + + uint32 money = fields[8].GetUInt32(); if (money > MAX_MONEY_AMOUNT) money = MAX_MONEY_AMOUNT; SetMoney(money); - SetUInt32Value(PLAYER_BYTES, fields[10].GetUInt32()); - SetUInt32Value(PLAYER_BYTES_2, fields[11].GetUInt32()); - SetUInt32Value(PLAYER_BYTES_3, (fields[50].GetUInt16() & 0xFFFE) | fields[6].GetUInt8()); - SetUInt32Value(PLAYER_FLAGS, fields[12].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[49].GetUInt32()); - SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[48].GetUInt64()); + SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32()); + SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32()); + SetUInt32Value(PLAYER_BYTES_3, (fields[49].GetUInt16() & 0xFFFE) | fields[5].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()); + InitDisplayIds(); // cleanup inventory related item value fields (its will be filled correctly in _LoadInventory) @@ -15655,16 +15644,16 @@ 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[31].GetUInt32(); - Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat()); - uint32 mapId = fields[16].GetUInt32(); - uint32 instanceId = fields[59].GetFloat(); + uint32 transGUID = fields[30].GetUInt32(); + Relocate(fields[12].GetFloat(),fields[13].GetFloat(),fields[14].GetFloat(),fields[16].GetFloat()); + uint32 mapId = fields[15].GetUInt32(); + uint32 instanceId = fields[58].GetFloat(); - uint32 difficulty = fields[39].GetUInt32(); + uint32 difficulty = fields[38].GetUInt32(); if (difficulty >= MAX_DUNGEON_DIFFICULTY) difficulty = DUNGEON_DIFFICULTY_NORMAL; SetDungeonDifficulty(Difficulty(difficulty)); // may be changed in _LoadGroup - std::string taxi_nodes = fields[38].GetCppString(); + std::string taxi_nodes = fields[37].GetCppString(); #define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); } @@ -15672,7 +15661,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) _LoadArenaTeamInfo(holder->GetResult(PLAYER_LOGIN_QUERY_LOADARENAINFO)); - uint32 arena_currency = fields[40].GetUInt32(); + uint32 arena_currency = fields[39].GetUInt32(); if (arena_currency > sWorld.getConfig(CONFIG_MAX_ARENA_POINTS)) arena_currency = sWorld.getConfig(CONFIG_MAX_ARENA_POINTS); @@ -15694,12 +15683,12 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arena_slot * ARENA_TEAM_END) + j, 0); } - SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, fields[41].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[42].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[43].GetUInt32()); - SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[44].GetUInt32()); - SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[45].GetUInt16()); - SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[46].GetUInt16()); + SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, 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()); _LoadBoundInstances(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES)); _LoadBGData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADBGDATA)); @@ -15761,10 +15750,10 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) // There are no transports on instances instanceId = 0; - m_movementInfo.t_x = fields[27].GetFloat(); - m_movementInfo.t_y = fields[28].GetFloat(); - m_movementInfo.t_z = fields[29].GetFloat(); - m_movementInfo.t_o = fields[30].GetFloat(); + m_movementInfo.t_x = fields[26].GetFloat(); + m_movementInfo.t_y = fields[27].GetFloat(); + m_movementInfo.t_z = fields[28].GetFloat(); + m_movementInfo.t_o = fields[29].GetFloat(); if (!Trinity::IsValidMapCoord( GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y, @@ -15919,7 +15908,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) SaveRecallPosition(); time_t now = time(NULL); - time_t logoutTime = time_t(fields[23].GetUInt64()); + time_t logoutTime = time_t(fields[22].GetUInt64()); // since last logout (in seconds) uint32 time_diff = uint32(now - logoutTime); //uint64 is excessive for a time_diff in seconds.. uint32 allows for 136~ year difference. @@ -15934,27 +15923,12 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) uint16 newDrunkenValue = uint16(soberFactor*(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE)); SetDrunkValue(newDrunkenValue); - m_rest_bonus = fields[22].GetFloat(); - //speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour) - float bubble0 = 0.031; - //speed collect rest bonus in offline, in logout, in tavern, city (section/in hour) - float bubble1 = 0.125; + m_cinematic = fields[18].GetUInt32(); + m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32(); + m_Played_time[PLAYED_TIME_LEVEL]= fields[20].GetUInt32(); - if (time_diff > 0) - { - float bubble = fields[24].GetUInt32() > 0 - ? bubble1*sWorld.getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY) - : bubble0*sWorld.getRate(RATE_REST_OFFLINE_IN_WILDERNESS); - - SetRestBonus(GetRestBonus()+ time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble); - } - - m_cinematic = fields[19].GetUInt32(); - m_Played_time[PLAYED_TIME_TOTAL]= fields[20].GetUInt32(); - m_Played_time[PLAYED_TIME_LEVEL]= fields[21].GetUInt32(); - - m_resetTalentsCost = fields[25].GetUInt32(); - m_resetTalentsTime = time_t(fields[26].GetUInt64()); + m_resetTalentsCost = fields[24].GetUInt32(); + m_resetTalentsTime = time_t(fields[25].GetUInt64()); // reserve some flags uint32 old_safe_flags = GetUInt32Value(PLAYER_FLAGS) & (PLAYER_FLAGS_HIDE_CLOAK | PLAYER_FLAGS_HIDE_HELM); @@ -15962,25 +15936,25 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM)) SetUInt32Value(PLAYER_FLAGS, 0 | old_safe_flags); - m_taxi.LoadTaxiMask(fields[18].GetString()); // must be before InitTaxiNodesForLevel + m_taxi.LoadTaxiMask(fields[17].GetString()); // must be before InitTaxiNodesForLevel - uint32 extraflags = fields[32].GetUInt32(); + uint32 extraflags = fields[31].GetUInt32(); - m_stableSlots = fields[33].GetUInt32(); + m_stableSlots = fields[32].GetUInt32(); if (m_stableSlots > MAX_PET_STABLES) { sLog.outError("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[34].GetUInt32(); + m_atLoginFlags = fields[33].GetUInt32(); // Honor system // Update Honor kills data m_lastHonorUpdateTime = logoutTime; UpdateHonorFields(); - m_deathExpireTime = (time_t)fields[37].GetUInt64(); + m_deathExpireTime = (time_t)fields[36].GetUInt64(); if (m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP) m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1; @@ -16015,6 +15989,22 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) InitTaxiNodesForLevel(); InitRunes(); + // rest bonus can only be calculated after InitStatsForLevel() + m_rest_bonus = fields[21].GetFloat(); + + if (time_diff > 0) + { + //speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour) + float bubble0 = 0.031f; + //speed collect rest bonus in offline, in logout, in tavern, city (section/in hour) + float bubble1 = 0.125f; + float bubble = fields[23].GetUInt32() > 0 + ? bubble1*sWorld.getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY) + : bubble0*sWorld.getRate(RATE_REST_OFFLINE_IN_WILDERNESS); + + SetRestBonus(GetRestBonus()+ time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble); + } + // load skills after InitStatsForLevel because it triggering aura apply also _LoadSkills(holder->GetResult(PLAYER_LOGIN_QUERY_LOADSKILLS)); @@ -16023,8 +16013,8 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) //mails are loaded only when needed ;-) - when player in game click on mailbox. //_LoadMail(); - m_specsCount = fields[60].GetUInt8(); - m_activeSpec = fields[61].GetUInt8(); + m_specsCount = fields[59].GetUInt8(); + m_activeSpec = fields[60].GetUInt8(); // sanity check if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC || @@ -16069,7 +16059,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[10].GetUInt32(); + uint32 curTitle = fields[46].GetUInt32(); if (curTitle && !HasTitle(curTitle)) curTitle = 0; @@ -16090,11 +16080,11 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) UpdateAllStats(); // restore remembered power/health values (but not more max values) - uint32 savedHealth = fields[51].GetUInt32(); + uint32 savedHealth = fields[50].GetUInt32(); SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth); for (uint8 i = 0; i < MAX_POWERS; ++i) { - uint32 savedPower = fields[52+i].GetUInt32(); + uint32 savedPower = fields[51+i].GetUInt32(); SetPower(Powers(i),savedPower > GetMaxPower(Powers(i)) ? GetMaxPower(Powers(i)) : savedPower); } @@ -17291,13 +17281,13 @@ void Player::SaveToDB() std::ostringstream ss; ss << "REPLACE INTO characters (guid,account,name,race,class,gender,level,xp,money,playerBytes,playerBytes2,playerFlags," - "map, instance_id, dungeon_difficulty, position_x, position_y, position_z, orientation, data, " + "map, instance_id, dungeon_difficulty, position_x, position_y, position_z, orientation, " "taximask, online, 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, " "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) VALUES (" + "power4, power5, power6, power7, latency, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles) VALUES (" << GetGUIDLow() << ", " << GetSession()->GetAccountId() << ", '" << sql_name << "', " @@ -17319,7 +17309,7 @@ void Player::SaveToDB() << finiteAlways(GetPositionX()) << ", " << finiteAlways(GetPositionY()) << ", " << finiteAlways(GetPositionZ()) << ", " - << finiteAlways(GetOrientation()) << ", '"; + << finiteAlways(GetOrientation()) << ", "; } else { @@ -17329,15 +17319,9 @@ void Player::SaveToDB() << finiteAlways(GetTeleportDest().GetPositionX()) << ", " << finiteAlways(GetTeleportDest().GetPositionY()) << ", " << finiteAlways(GetTeleportDest().GetPositionZ()) << ", " - << finiteAlways(GetTeleportDest().GetOrientation()) << ", '"; + << finiteAlways(GetTeleportDest().GetOrientation()) << ", "; } - uint16 i; - for (i = 0; i < m_valuesCount; ++i) - ss << GetUInt32Value(i) << " "; - - ss << "', "; - ss << m_taxi << ", "; // string with TaxiMaskSize numbers ss << (IsInWorld() ? 1 : 0) << ", "; @@ -17408,8 +17392,26 @@ void Player::SaveToDB() ss << ", "; ss << uint32(m_specsCount); ss << ", "; - ss << uint32(m_activeSpec); - ss << ")"; + ss << uint32(m_activeSpec) << ", '"; + for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) + { + ss << GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + i) << " "; + } + + ss << "', '"; + for (uint32 i = 0; i < EQUIPMENT_SLOT_END * 2; ++i ) + { + ss << GetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + i) << " "; + } + + ss << "',"; + + ss << GetUInt32Value(PLAYER_AMMO_ID) << ", '"; + for (uint32 i = 0; i < KNOWN_TITLES_SIZE*2; ++i) + { + ss << GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES + i) << " "; + } + ss << "')"; CharacterDatabase.BeginTransaction(); @@ -17858,34 +17860,6 @@ void Player::SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint CharacterDatabase.Execute(ss.str().c_str()); } -void Player::SaveDataFieldToDB() -{ - std::ostringstream ss; - ss<<"UPDATE characters SET data='"; - - for (uint16 i = 0; i < m_valuesCount; i++) - { - ss << GetUInt32Value(i) << " "; - } - ss<<"' WHERE guid='"<< GUID_LOPART(GetGUIDLow()) <<"'"; - - CharacterDatabase.Execute(ss.str().c_str()); -} - -bool Player::SaveValuesArrayInDB(Tokens const& tokens, uint64 guid) -{ - std::ostringstream ss2; - ss2<<"UPDATE characters SET data='"; - uint32 i=0; - for (Tokens::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter, ++i) - { - ss2<<tokens[i]<<" "; - } - ss2<<"' WHERE guid='"<< GUID_LOPART(guid) <<"'"; - - return CharacterDatabase.Execute(ss2.str().c_str()); -} - void Player::SetUInt32ValueInArray(Tokens& tokens,uint16 index, uint32 value) { char buf[11]; @@ -17897,29 +17871,6 @@ void Player::SetUInt32ValueInArray(Tokens& tokens,uint16 index, uint32 value) tokens[index] = buf; } -void Player::SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid) -{ - Tokens tokens; - if (!LoadValuesArrayFromDB(tokens,guid)) - return; - - if (index >= tokens.size()) - return; - - char buf[11]; - snprintf(buf,11,"%u",value); - tokens[index] = buf; - - SaveValuesArrayInDB(tokens,guid); -} - -void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid) -{ - uint32 temp; - memcpy(&temp, &value, sizeof(value)); - Player::SetUInt32ValueInDB(index, temp, guid); -} - void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair) { // 0 diff --git a/src/game/Player.h b/src/game/Player.h index 7919b85a198..3a5f88548e9 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -56,8 +56,9 @@ class OutdoorPvP; typedef std::deque<Mail*> PlayerMails; -#define PLAYER_MAX_SKILLS 127 -#define PLAYER_MAX_DAILY_QUESTS 25 +#define PLAYER_MAX_SKILLS 127 +#define PLAYER_MAX_DAILY_QUESTS 25 +#define PLAYER_EXPLORED_ZONES_SIZE 128 // Note: SPELLMOD_* values is aura types in fact enum SpellModType @@ -491,7 +492,8 @@ enum PlayerFlags #define PLAYER_TITLE_HAND_OF_ADAL UI64LIT(0x0000008000000000) // 39 #define PLAYER_TITLE_VENGEFUL_GLADIATOR UI64LIT(0x0000010000000000) // 40 -#define MAX_TITLE_INDEX (3*64) // 3 uint64 fields +#define KNOWN_TITLES_SIZE 3 +#define MAX_TITLE_INDEX (KNOWN_TITLES_SIZE*64) // 3 uint64 fields // used in PLAYER_FIELD_BYTES values enum PlayerFieldByteFlags @@ -1406,11 +1408,8 @@ class Player : public Unit, public GridObject<Player> bool isBeingLoaded() const { return GetSession()->PlayerLoading();} bool MinimalLoadFromDB(QueryResult_AutoPtr result, uint32 guid); - static bool LoadValuesArrayFromDB(Tokens& data,uint64 guid); static uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index); static float GetFloatValueFromArray(Tokens const& data, uint16 index); - static uint32 GetUInt32ValueFromDB(uint16 index, uint64 guid); - static float GetFloatValueFromDB(uint16 index, uint64 guid); static uint32 GetZoneIdFromDB(uint64 guid); static uint32 GetLevelFromDB(uint64 guid); static bool LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid); @@ -1422,12 +1421,8 @@ class Player : public Unit, public GridObject<Player> void SaveToDB(); void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing void SaveGoldToDB(); - void SaveDataFieldToDB(); - static bool SaveValuesArrayInDB(Tokens const& data,uint64 guid); static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value); 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); @@ -2384,6 +2379,7 @@ class Player : public Unit, public GridObject<Player> void _LoadBGData(QueryResult_AutoPtr result); void _LoadGlyphs(QueryResult_AutoPtr result); void _LoadTalents(QueryResult_AutoPtr result); + void _LoadIntoDataField(const char* data, uint32 startOffset, uint32 count); /*********************************************************/ /*** SAVE SYSTEM ***/ |