aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/characters.sql9
-rw-r--r--sql/mangos.sql7
-rw-r--r--sql/updates/4292_8072_01_characters_characters.sql10
-rw-r--r--sql/updates/4292_8072_02_characters_characters.sql11
-rw-r--r--src/game/CharacterHandler.cpp38
-rw-r--r--src/game/Guild.cpp19
-rw-r--r--src/game/GuildHandler.cpp4
-rw-r--r--src/game/Level1.cpp1
-rw-r--r--src/game/Level2.cpp15
-rw-r--r--src/game/Level3.cpp10
-rw-r--r--src/game/LootMgr.cpp2
-rw-r--r--src/game/Mail.cpp2
-rw-r--r--src/game/Player.cpp279
-rw-r--r--src/game/Player.h6
-rw-r--r--src/game/SpellEffects.cpp1
-rw-r--r--src/game/SpellMgr.h2
16 files changed, 234 insertions, 182 deletions
diff --git a/sql/characters.sql b/sql/characters.sql
index 855099d6849..693ddfed803 100644
--- a/sql/characters.sql
+++ b/sql/characters.sql
@@ -23,7 +23,7 @@
DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` (
- `required_8030_02_characters_character_action` bit(1) default NULL
+ `required_8072_02_characters_characters` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--
@@ -279,6 +279,13 @@ CREATE TABLE `characters` (
`name` varchar(12) NOT NULL default '',
`race` tinyint(3) unsigned NOT NULL default '0',
`class` tinyint(3) unsigned NOT NULL default '0',
+ `gender` TINYINT UNSIGNED NOT NULL default '0',
+ `level` TINYINT UNSIGNED NOT NULL default '0',
+ `xp` INT UNSIGNED NOT NULL default '0',
+ `money` INT UNSIGNED NOT NULL default '0',
+ `playerBytes` INT UNSIGNED NOT NULL default '0',
+ `playerBytes2` INT UNSIGNED NOT NULL default '0',
+ `playerFlags` INT UNSIGNED NOT NULL default '0',
`position_x` float NOT NULL default '0',
`position_y` float NOT NULL default '0',
`position_z` float NOT NULL default '0',
diff --git a/sql/mangos.sql b/sql/mangos.sql
index 8aecd6c0596..f9200e335f8 100644
--- a/sql/mangos.sql
+++ b/sql/mangos.sql
@@ -23,11 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
-<<<<<<< HEAD:sql/mangos.sql
- `required_8053_01_mangos_command` bit(1) default NULL
-=======
- `required_8065_01_mangos_spell_proc_event` bit(1) default NULL
->>>>>>> fda6c4804e4f8718648d82cf43237be33fac3dd3:sql/mangos.sql
+ `required_8071_01_mangos_command` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@@ -417,6 +413,7 @@ INSERT INTO `command` VALUES
('modify standstate',2,'Syntax: .modify standstate #emoteid\r\n\r\nChange the emote of your character while standing to #emoteid.'),
('modify swim',1,'Syntax: .modify swim #rate\r\n\r\nModify the swim speed of the selected player to \"normal swim speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'),
('modify titles',1,'Syntax: .modify titles #mask\r\n\r\nAllows user to use all titles from #mask.\r\n\r\n #mask=0 disables the title-choose-field'),
+('modify tp',1,'Syntax: .modify tp #amount\r\n\r\nSet free talent pointes for selected character or character\'s pet. It will be reset to default expected at next levelup/login/quest reward.'),
('movegens',3,'Syntax: .movegens\r\n Show movement generators stack for selected creature or player.'),
('mute',1,'Syntax: .mute [$playerName] $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName (or currently selected) at $timeInMinutes minutes. Player can be offline.'),
('namego',1,'Syntax: .namego [$charactername]\r\n\r\nTeleport the given character to you. Character can be offline.'),
diff --git a/sql/updates/4292_8072_01_characters_characters.sql b/sql/updates/4292_8072_01_characters_characters.sql
new file mode 100644
index 00000000000..663fc4840a3
--- /dev/null
+++ b/sql/updates/4292_8072_01_characters_characters.sql
@@ -0,0 +1,10 @@
+-- ALTER TABLE character_db_version CHANGE COLUMN required_8030_02_characters_character_action required_8072_01_characters_characters bit;
+
+ALTER TABLE characters
+ADD gender TINYINT UNSIGNED NOT NULL default '0' AFTER class,
+ADD level TINYINT UNSIGNED NOT NULL default '0' AFTER gender,
+ADD xp INT UNSIGNED NOT NULL default '0' AFTER level,
+ADD money INT UNSIGNED NOT NULL default '0' AFTER xp,
+ADD playerBytes INT UNSIGNED NOT NULL default '0' AFTER money,
+ADD playerBytes2 INT UNSIGNED NOT NULL default '0' AFTER playerBytes,
+ADD playerFlags INT UNSIGNED NOT NULL default '0' AFTER playerBytes2;
diff --git a/sql/updates/4292_8072_02_characters_characters.sql b/sql/updates/4292_8072_02_characters_characters.sql
new file mode 100644
index 00000000000..06fa04c6094
--- /dev/null
+++ b/sql/updates/4292_8072_02_characters_characters.sql
@@ -0,0 +1,11 @@
+-- ALTER TABLE character_db_version CHANGE COLUMN required_8072_01_characters_characters required_8072_02_characters_characters bit;
+
+UPDATE characters SET
+gender = (CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 23), ' ', -1) AS UNSIGNED) & 0xFF0000) >> 16,
+level = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 54), ' ', -1) AS UNSIGNED),
+xp = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 609), ' ', -1) AS UNSIGNED),
+money = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 1145), ' ', -1) AS UNSIGNED),
+playerBytes = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 154), ' ', -1) AS UNSIGNED),
+playerBytes2 = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 155), ' ', -1) AS UNSIGNED),
+playerFlags = CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ' ', 151), ' ', -1) AS UNSIGNED)
+WHERE LENGTH(SUBSTRING_INDEX(data, ' ', 1294)) < LENGTH(data) && LENGTH(data) <= LENGTH(SUBSTRING_INDEX(data, ' ', 1295));
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index aca354750f0..6a6371f473d 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -64,7 +64,7 @@ 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, 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,instance_id FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "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,instance_id 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,stackcount,amount0, amount1, amount2 ,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
@@ -133,21 +133,15 @@ void WorldSession::HandleCharEnum(QueryResult * result)
if( result )
{
- Player *plr = new Player(this);
do
{
uint32 guidlow = (*result)[0].GetUInt32();
sLog.outDetail("Loading char guid %u from account %u.",guidlow,GetAccountId());
-
- if(plr->MinimalLoadFromDB( result, guidlow ))
- {
- plr->BuildEnumData( result, &data );
+ if(Player::BuildEnumData(result, &data))
++num;
- }
}
while( result->NextRow() );
- delete plr;
delete result;
}
@@ -162,19 +156,23 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ )
CharacterDatabase.AsyncPQuery(&chrHandler, &CharacterHandler::HandleCharEnumCallback, GetAccountId(),
!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
- // 0 1 2 3 4 5 6 7 8
- "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
- // 9 10 11 12 13 14
- "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid "
+ // 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
+ "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data "
"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"
:
// --------- Query With Declined Names ---------
- // 0 1 2 3 4 5 6 7 8
- "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
- // 9 10 11 12 13 14 15
- "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive "
+ // 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 "
"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 "
@@ -340,7 +338,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT)
{
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT guid,race,class FROM characters WHERE account = '%u' %s",
+ QueryResult *result2 = CharacterDatabase.PQuery("SELECT level,race,class FROM characters WHERE account = '%u' %s",
GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1");
if(result2)
{
@@ -367,8 +365,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if(!have_req_level_for_heroic)
{
- uint32 acc_guid = field[0].GetUInt32();
- uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
+ uint32 acc_level = field[0].GetUInt32();
if(acc_level >= req_level_for_heroic)
have_req_level_for_heroic = true;
}
@@ -422,8 +419,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if(!have_req_level_for_heroic)
{
- uint32 acc_guid = field[0].GetUInt32();
- uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid);
+ uint32 acc_level = field[0].GetUInt32();
if(acc_level >= req_level_for_heroic)
have_req_level_for_heroic = true;
}
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp
index 84271f08d04..c227644b0ed 100644
--- a/src/game/Guild.cpp
+++ b/src/game/Guild.cpp
@@ -369,20 +369,17 @@ bool Guild::FillPlayerData(uint64 guid, MemberSlot* memslot)
}
else
{
- QueryResult *result = CharacterDatabase.PQuery("SELECT name,data,zone,class FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
- if(!result)
- return false; // player doesn't exist
+ QueryResult *result = CharacterDatabase.PQuery("SELECT name,level,zone,class FROM characters WHERE guid = '%u'", GUID_LOPART(guid));
+ if(!result)
+ return false; // player doesn't exist
Field *fields = result->Fetch();
- plName = fields[0].GetCppString();
-
- Tokens data = StrSplit(fields[1].GetCppString(), " ");
- plLevel = Player::GetUInt32ValueFromArray(data,UNIT_FIELD_LEVEL);
-
- plZone = fields[2].GetUInt32();
- plClass = fields[3].GetUInt32();
- delete result;
+ plName = fields[0].GetCppString();
+ plLevel = fields[1].GetUInt32();
+ plZone = fields[2].GetUInt32();
+ plClass = fields[3].GetUInt32();
+ delete result;
if(plLevel<1||plLevel>STRONG_MAX_LEVEL) // can be at broken `data` field
{
diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
index f3f9c6c6758..a8eba52dee0 100644
--- a/src/game/GuildHandler.cpp
+++ b/src/game/GuildHandler.cpp
@@ -976,7 +976,7 @@ void WorldSession::HandleGuildBankDepositMoney( WorldPacket & recv_data )
pGuild->SetBankMoney(pGuild->GetGuildBankMoney()+money);
GetPlayer()->ModifyMoney(-int(money));
- GetPlayer()->SaveDataFieldToDB(); //contains money
+ GetPlayer()->SaveGoldToDB();
CharacterDatabase.CommitTransaction();
@@ -1032,7 +1032,7 @@ void WorldSession::HandleGuildBankWithdrawMoney( WorldPacket & recv_data )
}
GetPlayer()->ModifyMoney(money);
- GetPlayer()->SaveDataFieldToDB(); // contains money
+ GetPlayer()->SaveGoldToDB();
CharacterDatabase.CommitTransaction();
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index 9ec47381f61..7477801dff7 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -1472,7 +1472,6 @@ bool ChatHandler::HandleModifyTalentCommand (const char* args)
return false;
Unit* target = getSelectedUnit();
-
if(!target)
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index e7a684a8111..901c9ba1d1c 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -2268,22 +2268,17 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
if (HasLowerSecurity(NULL, target_guid))
return false;
- // 0
- QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid));
+ // 0 1 2 3
+ QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime, level, money, account FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid));
if (!result)
return false;
Field *fields = result->Fetch();
total_player_time = fields[0].GetUInt32();
+ level = fields[1].GetUInt32();
+ money = fields[2].GetUInt32();
+ accId = fields[3].GetUInt32();
delete result;
-
- Tokens data;
- if (!Player::LoadValuesArrayFromDB(data,target_guid))
- return false;
-
- money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
- level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
- accId = objmgr.GetPlayerAccountIdByGUID(target_guid);
}
std::string username = GetTrinityString(LANG_ERROR);
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 647919379d8..39d04cefaf3 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -4668,11 +4668,7 @@ void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint3
else
{
// update level and XP at level, all other will be updated at loading
- Tokens values;
- Player::LoadValuesArrayFromDB(values,player_guid);
- Player::SetUInt32ValueInArray(values,UNIT_FIELD_LEVEL,newlevel);
- Player::SetUInt32ValueInArray(values,PLAYER_XP,0);
- Player::SaveValuesArrayInDB(values,player_guid);
+ CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
}
}
@@ -4697,7 +4693,7 @@ bool ChatHandler::HandleCharacterLevelCommand(const char* args)
if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
return false;
- int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid);
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
if(newlevel < 1)
@@ -4736,7 +4732,7 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
return false;
- int32 oldlevel = target ? target->getLevel() : Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,target_guid);
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
int32 addlevel = levelStr ? atoi(levelStr) : 1;
int32 newlevel = oldlevel + addlevel;
diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp
index adba36fd301..0490d133bf2 100644
--- a/src/game/LootMgr.cpp
+++ b/src/game/LootMgr.cpp
@@ -1327,7 +1327,7 @@ void LoadLootTemplates_Spell()
// ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example
if (!(spellInfo->Attributes & SPELL_ATTR_NOT_SHAPESHIFT) || (spellInfo->Attributes & SPELL_ATTR_UNK5))
{
- LootTemplates_Spell.ReportNotExistedId(spell_id);
+ LootTemplates_Spell.ReportNotExistedId(spell_id);
}
}
else
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index 0af4999092f..33ff65e7fe0 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -567,7 +567,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data )
// save money and mail to prevent cheating
CharacterDatabase.BeginTransaction();
- pl->SaveDataFieldToDB(); // contains money
+ pl->SaveGoldToDB();
pl->_SaveMail();
CharacterDatabase.CommitTransaction();
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 55946030206..732acbd316e 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -539,9 +539,6 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
for (uint8 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);
@@ -573,7 +570,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 );
@@ -1452,53 +1449,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
@@ -1506,7 +1517,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
@@ -1515,15 +1526,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;
}
}
@@ -1533,36 +1544,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);
+ if(!proto)
+ {
+ *p_data << uint32(0);
+ *p_data << uint8(0);
+ *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)
{
- uint32 enchantId = GetUInt16Value(visualbase + 1, enchantSlot);
- if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId))
+ if(enchant = sSpellItemEnchantmentStore.LookupEntry(enchantSlot >> enchantSlot*16))
break;
}
- if (proto != NULL)
- {
- *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(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()
@@ -6243,6 +6258,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
@@ -14073,8 +14101,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;
}
@@ -14307,8 +14335,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)
@@ -14352,6 +14380,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)
{
@@ -14372,12 +14413,9 @@ 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);
-
- m_class = fields[5].GetUInt8();
+ setFactionForRace(getRace());
// 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)))
@@ -14389,17 +14427,18 @@ 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());
- SetInstanceId(fields[41].GetFloat());
- 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
+
+ SetInstanceId(fields[47].GetFloat());
_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);
@@ -14436,12 +14475,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);
@@ -14480,8 +14519,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());
@@ -14492,10 +14531,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( !Trinity::IsValidMapCoord(
GetPositionX()+m_movementInfo.t_x,GetPositionY()+m_movementInfo.t_y,
@@ -14627,7 +14666,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);
@@ -14642,27 +14681,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 );
@@ -14670,29 +14709,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;
@@ -15017,7 +15056,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);
}
@@ -15932,7 +15971,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, instance_id, 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, "
@@ -15941,8 +15980,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())
{
@@ -16078,8 +16124,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()
@@ -16483,38 +16533,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()
diff --git a/src/game/Player.h b/src/game/Player.h
index 7826ab7495b..216994f7e7c 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -873,7 +873,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void Update( uint32 time );
- void BuildEnumData( QueryResult * result, WorldPacket * p_data );
+ static bool BuildEnumData( QueryResult * result, WorldPacket * p_data );
void SetInWater(bool apply);
@@ -1234,6 +1234,7 @@ class TRINITY_DLL_SPEC Player : public Unit
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);
/*********************************************************/
@@ -1242,6 +1243,7 @@ class TRINITY_DLL_SPEC Player : public Unit
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);
@@ -2179,8 +2181,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void outDebugValues() const;
uint64 m_lootGuid;
- uint32 m_race;
- uint32 m_class;
uint32 m_team;
uint32 m_nextSave;
time_t m_speakTime;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index d5ee8a0b731..f4d11916fbe 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2860,6 +2860,7 @@ void Spell::EffectCreateItem2(uint32 i)
Player* player = (Player*)m_caster;
uint32 item_id = m_spellInfo->EffectItemType[i];
+
DoCreateItem(i, item_id);
// special case: fake item replaced by generate using spell_loot_template
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 3616e52e07c..374b7c68420 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -218,7 +218,7 @@ inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo)
inline bool IsLootCraftingSpell(SpellEntry const *spellInfo)
{
- return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_RANDOM_ITEM ||
+ return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_RANDOM_ITEM ||
// different random cards from Inscription (121==Virtuoso Inking Set category)
spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 && spellInfo->TotemCategory[0] == 121;
}