aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/characters.sql7
-rw-r--r--sql/updates/7834_characters_characters.sql22
-rw-r--r--src/game/CharacterHandler.cpp8
-rw-r--r--src/game/Level3.cpp6
-rw-r--r--src/game/Player.cpp297
-rw-r--r--src/game/Player.h16
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 ***/