mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[8072] First step to get rid of data blob.
Adds new fields gender, level, xp, money, playerBytes, playerBytes2 and playerFlags to characters table. The update will not work if your database contains characters with an old data field (not fitting to the actual client version). It's recommended to backup your character database before applying this patch. Signed-off-by: hunuza <hunuza@gmail.com>
This commit is contained in:
parent
f34ce077c0
commit
8a32a19bad
13 changed files with 229 additions and 171 deletions
|
|
@ -538,9 +538,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
|
|||
for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i)
|
||||
m_items[i] = NULL;
|
||||
|
||||
m_race = race;
|
||||
m_class = class_;
|
||||
|
||||
SetMapId(info->mapId);
|
||||
Relocate(info->positionX,info->positionY,info->positionZ);
|
||||
|
||||
|
|
@ -572,7 +569,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
|
|||
break;
|
||||
}
|
||||
|
||||
setFactionForRace(m_race);
|
||||
setFactionForRace(race);
|
||||
|
||||
uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 );
|
||||
|
||||
|
|
@ -1400,53 +1397,67 @@ void Player::setDeathState(DeathState s)
|
|||
}
|
||||
}
|
||||
|
||||
void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
|
||||
bool Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
|
||||
{
|
||||
// 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, "
|
||||
// 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 "
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
*p_data << uint64(GetGUID());
|
||||
*p_data << m_name;
|
||||
uint32 guid = fields[0].GetUInt32();
|
||||
uint8 pRace = fields[2].GetUInt8();
|
||||
uint8 pClass = fields[3].GetUInt8();
|
||||
|
||||
*p_data << uint8(getRace());
|
||||
uint8 pClass = getClass();
|
||||
*p_data << uint8(pClass);
|
||||
*p_data << uint8(getGender());
|
||||
PlayerInfo const *info = objmgr.GetPlayerInfo(pRace, pClass);
|
||||
if(!info)
|
||||
{
|
||||
sLog.outError("Player %u have incorrect race/class pair. Don't build enum.", guid);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 bytes = GetUInt32Value(PLAYER_BYTES);
|
||||
*p_data << uint8(bytes);
|
||||
*p_data << uint8(bytes >> 8);
|
||||
*p_data << uint8(bytes >> 16);
|
||||
*p_data << uint8(bytes >> 24);
|
||||
*p_data << uint64(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
|
||||
*p_data << fields[1].GetString(); // name
|
||||
*p_data << uint8(pRace); // race
|
||||
*p_data << uint8(pClass); // class
|
||||
*p_data << uint8(fields[4].GetUInt8()); // gender
|
||||
|
||||
bytes = GetUInt32Value(PLAYER_BYTES_2);
|
||||
*p_data << uint8(bytes);
|
||||
uint32 playerBytes = fields[5].GetUInt32();
|
||||
*p_data << uint8(playerBytes); // skin
|
||||
*p_data << uint8(playerBytes >> 8); // face
|
||||
*p_data << uint8(playerBytes >> 16); // hair style
|
||||
*p_data << uint8(playerBytes >> 24); // hair color
|
||||
|
||||
*p_data << uint8(getLevel()); // player level
|
||||
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded
|
||||
uint32 zoneId = fields[10].GetUInt32();
|
||||
sLog.outDebug("Player::BuildEnumData: map:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
|
||||
*p_data << uint32(zoneId);
|
||||
*p_data << uint32(GetMapId());
|
||||
uint32 playerBytes2 = fields[6].GetUInt32();
|
||||
*p_data << uint8(playerBytes2 & 0xFF); // facial hair
|
||||
|
||||
*p_data << GetPositionX();
|
||||
*p_data << GetPositionY();
|
||||
*p_data << GetPositionZ();
|
||||
*p_data << uint8(fields[7].GetUInt8()); // level
|
||||
*p_data << uint32(fields[8].GetUInt32()); // zone
|
||||
*p_data << uint32(fields[9].GetUInt32()); // map
|
||||
|
||||
// guild id
|
||||
*p_data << uint32(fields[14].GetUInt32());
|
||||
*p_data << fields[10].GetFloat(); // x
|
||||
*p_data << fields[11].GetFloat(); // y
|
||||
*p_data << fields[12].GetFloat(); // z
|
||||
|
||||
*p_data << uint32(fields[13].GetUInt32()); // guild id
|
||||
|
||||
uint32 char_flags = 0;
|
||||
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
|
||||
uint32 playerFlags = fields[14].GetUInt32();
|
||||
uint32 atLoginFlags = fields[15].GetUInt32();
|
||||
if(playerFlags & PLAYER_FLAGS_HIDE_HELM)
|
||||
char_flags |= CHARACTER_FLAG_HIDE_HELM;
|
||||
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK))
|
||||
if(playerFlags & PLAYER_FLAGS_HIDE_CLOAK)
|
||||
char_flags |= CHARACTER_FLAG_HIDE_CLOAK;
|
||||
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
|
||||
if(playerFlags & PLAYER_FLAGS_GHOST)
|
||||
char_flags |= CHARACTER_FLAG_GHOST;
|
||||
if(HasAtLoginFlag(AT_LOGIN_RENAME))
|
||||
if(atLoginFlags & AT_LOGIN_RENAME)
|
||||
char_flags |= CHARACTER_FLAG_RENAME;
|
||||
if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED))
|
||||
{
|
||||
if(!fields[15].GetCppString().empty())
|
||||
if(!fields[20].GetCppString().empty())
|
||||
char_flags |= CHARACTER_FLAG_DECLINED;
|
||||
}
|
||||
else
|
||||
|
|
@ -1454,7 +1465,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
|
|||
|
||||
*p_data << uint32(char_flags); // character flags
|
||||
// character customize (flags?)
|
||||
*p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0);
|
||||
*p_data << uint32(atLoginFlags & AT_LOGIN_CUSTOMIZE ? 1 : 0);
|
||||
*p_data << uint8(1); // unknown
|
||||
|
||||
// Pets info
|
||||
|
|
@ -1463,15 +1474,15 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
|
|||
uint32 petLevel = 0;
|
||||
uint32 petFamily = 0;
|
||||
|
||||
// show pet at selection character in character list only for non-ghost character
|
||||
if (result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT))
|
||||
// show pet at selection character in character list only for non-ghost character
|
||||
if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT))
|
||||
{
|
||||
uint32 entry = fields[11].GetUInt32();
|
||||
uint32 entry = fields[16].GetUInt32();
|
||||
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);
|
||||
if(cInfo)
|
||||
{
|
||||
petDisplayId = fields[12].GetUInt32();
|
||||
petLevel = fields[13].GetUInt32();
|
||||
petDisplayId = fields[17].GetUInt32();
|
||||
petLevel = fields[18].GetUInt32();
|
||||
petFamily = cInfo->family;
|
||||
}
|
||||
}
|
||||
|
|
@ -1481,36 +1492,40 @@ void Player::BuildEnumData( QueryResult * 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 item_id = GetUInt32Value(visualbase);
|
||||
uint32 item_id = GetUInt32ValueFromArray(data, visualbase);
|
||||
const ItemPrototype * proto = objmgr.GetItemPrototype(item_id);
|
||||
SpellItemEnchantmentEntry const *enchant = NULL;
|
||||
|
||||
for(uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
|
||||
{
|
||||
uint32 enchantId = GetUInt16Value(visualbase + 1, enchantSlot);
|
||||
if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId))
|
||||
break;
|
||||
}
|
||||
|
||||
if (proto != NULL)
|
||||
{
|
||||
*p_data << uint32(proto->DisplayInfoID);
|
||||
*p_data << uint8(proto->InventoryType);
|
||||
*p_data << uint32(enchant ? enchant->aura_id : 0);
|
||||
}
|
||||
else
|
||||
if(!proto)
|
||||
{
|
||||
*p_data << uint32(0);
|
||||
*p_data << uint8(0);
|
||||
*p_data << uint32(0); // enchant?
|
||||
*p_data << uint32(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
SpellItemEnchantmentEntry const *enchant = NULL;
|
||||
|
||||
uint32 enchants = GetUInt32ValueFromArray(data, visualbase + 1);
|
||||
for(uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
|
||||
{
|
||||
if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchantSlot >> enchantSlot*16))
|
||||
break;
|
||||
}
|
||||
|
||||
*p_data << uint32(proto->DisplayInfoID);
|
||||
*p_data << uint8(proto->InventoryType);
|
||||
*p_data << uint32(enchant ? enchant->aura_id : 0);
|
||||
}
|
||||
*p_data << uint32(0); // first bag display id
|
||||
*p_data << uint8(0); // first bag inventory type
|
||||
*p_data << uint32(0); // enchant?
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::ToggleAFK()
|
||||
|
|
@ -6061,6 +6076,19 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
|
|||
return zone;
|
||||
}
|
||||
|
||||
uint32 Player::GetLevelFromDB(uint64 guid)
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.PQuery( "SELECT level FROM characters WHERE guid='%u'", GUID_LOPART(guid) );
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
uint32 level = fields[0].GetUInt32();
|
||||
delete result;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
void Player::UpdateArea(uint32 newArea)
|
||||
{
|
||||
// FFA_PVP flags are area and not zone id dependent
|
||||
|
|
@ -13667,8 +13695,8 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
|
|||
bool delete_result = true;
|
||||
if (!result)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10
|
||||
result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login, zone FROM characters WHERE guid = '%u'",guid);
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login, zone, level FROM characters WHERE guid = '%u'",guid);
|
||||
if (!result)
|
||||
return false;
|
||||
}
|
||||
|
|
@ -13870,8 +13898,8 @@ float Player::GetFloatValueFromDB(uint16 index, uint64 guid)
|
|||
|
||||
bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
{
|
||||
//// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33 34 35 36 37 38 39 40
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, 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, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", guid);
|
||||
//// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, 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, arena_pending_points,bgid,bgteam,bgmap,bgx,bgy,bgz,bgo FROM characters WHERE guid = '%u'", guid);
|
||||
QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM);
|
||||
|
||||
if(!result)
|
||||
|
|
@ -13915,6 +13943,19 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
// 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();
|
||||
bytes0 |= fields[5].GetUInt8() << 8;
|
||||
bytes0 |= fields[6].GetUInt8() << 16;
|
||||
SetUInt32Value(UNIT_FIELD_LEVEL, fields[7].GetUInt8());
|
||||
SetUInt32Value(PLAYER_XP, fields[8].GetUInt32());
|
||||
SetUInt32Value(PLAYER_FIELD_COINAGE, fields[9].GetUInt32());
|
||||
SetUInt32Value(PLAYER_BYTES, fields[10].GetUInt32());
|
||||
SetUInt32Value(PLAYER_BYTES_2, fields[11].GetUInt32());
|
||||
SetUInt32Value(PLAYER_BYTES_3, (GetUInt32Value(PLAYER_BYTES_3) & ~1) | fields[6].GetUInt8());
|
||||
SetUInt32Value(PLAYER_FLAGS, fields[12].GetUInt32());
|
||||
|
||||
// cleanup inventory related item value fields (its will be filled correctly in _LoadInventory)
|
||||
for(uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
{
|
||||
|
|
@ -13935,14 +13976,11 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
sLog.outDebug("Load Basic value of player %s is: ", m_name.c_str());
|
||||
outDebugValues();
|
||||
|
||||
m_race = fields[4].GetUInt8();
|
||||
//Need to call it to initialize m_team (m_team can be calculated from m_race)
|
||||
//Need to call it to initialize m_team (m_team can be calculated from race)
|
||||
//Other way is to saves m_team into characters table.
|
||||
setFactionForRace(m_race);
|
||||
setFactionForRace(getRace());
|
||||
SetCharm(NULL);
|
||||
|
||||
m_class = fields[5].GetUInt8();
|
||||
|
||||
// load home bind and check in same time class/race pair, it used later for restore broken positions
|
||||
if(!_LoadHomeBind(holder->GetResult(PLAYER_LOGIN_QUERY_LOADHOMEBIND)))
|
||||
{
|
||||
|
|
@ -13953,16 +13991,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[24].GetUInt32();
|
||||
Relocate(fields[6].GetFloat(),fields[7].GetFloat(),fields[8].GetFloat(),fields[10].GetFloat());
|
||||
SetMapId(fields[9].GetUInt32());
|
||||
SetDifficulty(fields[32].GetUInt32()); // may be changed in _LoadGroup
|
||||
uint32 transGUID = fields[31].GetUInt32();
|
||||
Relocate(fields[13].GetFloat(),fields[14].GetFloat(),fields[15].GetFloat(),fields[17].GetFloat());
|
||||
SetMapId(fields[16].GetUInt32());
|
||||
SetDifficulty(fields[39].GetUInt32()); // may be changed in _LoadGroup
|
||||
|
||||
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
|
||||
|
||||
_LoadArenaTeamInfo(holder->GetResult(PLAYER_LOGIN_QUERY_LOADARENAINFO));
|
||||
|
||||
uint32 arena_currency = GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY) + fields[33].GetUInt32();
|
||||
uint32 arena_currency = GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY) + fields[40].GetUInt32();
|
||||
if (arena_currency > sWorld.getConfig(CONFIG_MAX_ARENA_POINTS))
|
||||
arena_currency = sWorld.getConfig(CONFIG_MAX_ARENA_POINTS);
|
||||
|
||||
|
|
@ -13999,12 +14037,12 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
m_movementInfo.t_o = 0.0f;
|
||||
}
|
||||
|
||||
uint32 bgid = fields[34].GetUInt32();
|
||||
uint32 bgteam = fields[35].GetUInt32();
|
||||
uint32 bgid = fields[41].GetUInt32();
|
||||
uint32 bgteam = fields[42].GetUInt32();
|
||||
|
||||
if(bgid) //saved in BattleGround
|
||||
{
|
||||
SetBattleGroundEntryPoint(fields[36].GetUInt32(),fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
|
||||
SetBattleGroundEntryPoint(fields[43].GetUInt32(),fields[44].GetFloat(),fields[45].GetFloat(),fields[46].GetFloat(),fields[47].GetFloat());
|
||||
|
||||
// check entry point and fix to homebind if need
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(m_bgEntryPoint.mapid);
|
||||
|
|
@ -14043,8 +14081,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
if(!mapEntry || mapEntry->IsBattleGroundOrArena())
|
||||
{
|
||||
// return to BG master
|
||||
SetMapId(fields[36].GetUInt32());
|
||||
Relocate(fields[37].GetFloat(),fields[38].GetFloat(),fields[39].GetFloat(),fields[40].GetFloat());
|
||||
SetMapId(fields[43].GetUInt32());
|
||||
Relocate(fields[44].GetFloat(),fields[45].GetFloat(),fields[46].GetFloat(),fields[47].GetFloat());
|
||||
|
||||
// check entry point and fix to homebind if need
|
||||
mapEntry = sMapStore.LookupEntry(GetMapId());
|
||||
|
|
@ -14055,10 +14093,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
|
||||
if (transGUID != 0)
|
||||
{
|
||||
m_movementInfo.t_x = fields[20].GetFloat();
|
||||
m_movementInfo.t_y = fields[21].GetFloat();
|
||||
m_movementInfo.t_z = fields[22].GetFloat();
|
||||
m_movementInfo.t_o = fields[23].GetFloat();
|
||||
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();
|
||||
|
||||
if( !MaNGOS::IsValidMapCoord(
|
||||
GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
|
||||
|
|
@ -14149,7 +14187,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
SaveRecallPosition();
|
||||
|
||||
time_t now = time(NULL);
|
||||
time_t logoutTime = time_t(fields[16].GetUInt64());
|
||||
time_t logoutTime = time_t(fields[23].GetUInt64());
|
||||
|
||||
// since last logout (in seconds)
|
||||
uint64 time_diff = uint64(now - logoutTime);
|
||||
|
|
@ -14164,27 +14202,27 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
|||
uint16 newDrunkenValue = uint16(soberFactor*(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE));
|
||||
SetDrunkValue(newDrunkenValue);
|
||||
|
||||
m_rest_bonus = fields[15].GetFloat();
|
||||
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;
|
||||
|
||||
if((int32)fields[16].GetUInt32() > 0)
|
||||
if((int32)fields[23].GetUInt32() > 0)
|
||||
{
|
||||
float bubble = fields[17].GetUInt32() > 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[12].GetUInt32();
|
||||
m_Played_time[0]= fields[13].GetUInt32();
|
||||
m_Played_time[1]= fields[14].GetUInt32();
|
||||
m_cinematic = fields[19].GetUInt32();
|
||||
m_Played_time[0]= fields[20].GetUInt32();
|
||||
m_Played_time[1]= fields[21].GetUInt32();
|
||||
|
||||
m_resetTalentsCost = fields[18].GetUInt32();
|
||||
m_resetTalentsTime = time_t(fields[19].GetUInt64());
|
||||
m_resetTalentsCost = fields[25].GetUInt32();
|
||||
m_resetTalentsTime = time_t(fields[26].GetUInt64());
|
||||
|
||||
// reserve some flags
|
||||
uint32 old_safe_flags = GetUInt32Value(PLAYER_FLAGS) & ( PLAYER_FLAGS_HIDE_CLOAK | PLAYER_FLAGS_HIDE_HELM );
|
||||
|
|
@ -14192,29 +14230,29 @@ 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[11].GetString() ); // must be before InitTaxiNodesForLevel
|
||||
m_taxi.LoadTaxiMask( fields[18].GetString() ); // must be before InitTaxiNodesForLevel
|
||||
|
||||
uint32 extraflags = fields[25].GetUInt32();
|
||||
|
||||
m_stableSlots = fields[26].GetUInt32();
|
||||
m_stableSlots = fields[33].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[27].GetUInt32();
|
||||
m_atLoginFlags = fields[34].GetUInt32();
|
||||
|
||||
// Honor system
|
||||
// Update Honor kills data
|
||||
m_lastHonorUpdateTime = logoutTime;
|
||||
UpdateHonorFields();
|
||||
|
||||
m_deathExpireTime = (time_t)fields[30].GetUInt64();
|
||||
m_deathExpireTime = (time_t)fields[37].GetUInt64();
|
||||
if(m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP)
|
||||
m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1;
|
||||
|
||||
std::string taxi_nodes = fields[31].GetCppString();
|
||||
std::string taxi_nodes = fields[38].GetCppString();
|
||||
|
||||
delete result;
|
||||
|
||||
|
|
@ -14551,7 +14589,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
delete result;
|
||||
}
|
||||
|
||||
if(m_class == CLASS_WARRIOR)
|
||||
if(getClass() == CLASS_WARRIOR)
|
||||
CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true);
|
||||
}
|
||||
|
||||
|
|
@ -15373,7 +15411,7 @@ void Player::SaveToDB()
|
|||
CharacterDatabase.escape_string(sql_name);
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO characters (guid,account,name,race,class,"
|
||||
ss << "INSERT INTO characters (guid,account,name,race,class,gender,level,xp,money,playerBytes,playerBytes2,playerFlags,"
|
||||
"map, dungeon_difficulty, position_x, position_y, position_z, orientation, data, "
|
||||
"taximask, online, cinematic, "
|
||||
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
|
||||
|
|
@ -15382,8 +15420,15 @@ void Player::SaveToDB()
|
|||
<< GetGUIDLow() << ", "
|
||||
<< GetSession()->GetAccountId() << ", '"
|
||||
<< sql_name << "', "
|
||||
<< m_race << ", "
|
||||
<< m_class << ", ";
|
||||
<< (uint32)getRace() << ", "
|
||||
<< (uint32)getClass() << ", "
|
||||
<< (uint32)getGender() << ", "
|
||||
<< getLevel() << ", "
|
||||
<< GetUInt32Value(PLAYER_XP) << ", "
|
||||
<< GetMoney() << ", "
|
||||
<< GetUInt32Value(PLAYER_BYTES) << ", "
|
||||
<< GetUInt32Value(PLAYER_BYTES_2) << ", "
|
||||
<< GetUInt32Value(PLAYER_FLAGS) << ", ";
|
||||
|
||||
if(!IsBeingTeleported())
|
||||
{
|
||||
|
|
@ -15514,8 +15559,12 @@ void Player::SaveToDB()
|
|||
void Player::SaveInventoryAndGoldToDB()
|
||||
{
|
||||
_SaveInventory();
|
||||
//money is in data field
|
||||
SaveDataFieldToDB();
|
||||
SaveGoldToDB();
|
||||
}
|
||||
|
||||
void Player::SaveGoldToDB()
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow());
|
||||
}
|
||||
|
||||
void Player::_SaveActions()
|
||||
|
|
@ -15939,38 +15988,31 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid)
|
|||
|
||||
void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
|
||||
{
|
||||
Tokens tokens;
|
||||
if(!LoadValuesArrayFromDB(tokens, guid))
|
||||
// 0 1 2 3 4
|
||||
QueryResult* result = CharacterDatabase.PQuery("SELECT data, race, class, playerBytes, playerBytes2 FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
uint32 unit_bytes0 = GetUInt32ValueFromArray(tokens, UNIT_FIELD_BYTES_0);
|
||||
uint8 race = unit_bytes0 & 0xFF;
|
||||
uint8 class_ = (unit_bytes0 >> 8) & 0xFF;
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_);
|
||||
Tokens tokens = StrSplit(fields[0].GetString(), " ");
|
||||
|
||||
PlayerInfo const* info = objmgr.GetPlayerInfo(fields[1].GetUInt8(), fields[2].GetUInt8());
|
||||
if(!info)
|
||||
return;
|
||||
|
||||
unit_bytes0 &= ~(0xFF << 16);
|
||||
unit_bytes0 |= (gender << 16);
|
||||
SetUInt32ValueInArray(tokens, UNIT_FIELD_BYTES_0, unit_bytes0);
|
||||
|
||||
// TODO: do not access data field here
|
||||
SetUInt32ValueInArray(tokens, UNIT_FIELD_DISPLAYID, gender ? info->displayId_f : info->displayId_m);
|
||||
SetUInt32ValueInArray(tokens, UNIT_FIELD_NATIVEDISPLAYID, gender ? info->displayId_f : info->displayId_m);
|
||||
|
||||
SetUInt32ValueInArray(tokens, PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24)));
|
||||
|
||||
uint32 player_bytes2 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_2);
|
||||
uint32 player_bytes2 = fields[4].GetUInt32();
|
||||
player_bytes2 &= ~0xFF;
|
||||
player_bytes2 |= facialHair;
|
||||
SetUInt32ValueInArray(tokens, PLAYER_BYTES_2, player_bytes2);
|
||||
|
||||
uint32 player_bytes3 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_3);
|
||||
player_bytes3 &= ~0xFF;
|
||||
player_bytes3 |= gender;
|
||||
SetUInt32ValueInArray(tokens, PLAYER_BYTES_3, player_bytes3);
|
||||
|
||||
SaveValuesArrayInDB(tokens, guid);
|
||||
CharacterDatabase.PExecute("UPDATE characters SET gender = '%u', playerBytes = '%u', playerBytes2 = '%u' WHERE guid = '%u'", gender, skin | (face << 8) | (hairStyle << 16) | (hairColor << 24), player_bytes2, GUID_LOPART(guid));
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
void Player::SendAttackSwingDeadTarget()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue