diff options
-rw-r--r-- | sql/characters.sql | 9 | ||||
-rw-r--r-- | sql/mangos.sql | 7 | ||||
-rw-r--r-- | sql/updates/4292_8072_01_characters_characters.sql | 10 | ||||
-rw-r--r-- | sql/updates/4292_8072_02_characters_characters.sql | 11 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 38 | ||||
-rw-r--r-- | src/game/Guild.cpp | 19 | ||||
-rw-r--r-- | src/game/GuildHandler.cpp | 4 | ||||
-rw-r--r-- | src/game/Level1.cpp | 1 | ||||
-rw-r--r-- | src/game/Level2.cpp | 15 | ||||
-rw-r--r-- | src/game/Level3.cpp | 10 | ||||
-rw-r--r-- | src/game/LootMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/Mail.cpp | 2 | ||||
-rw-r--r-- | src/game/Player.cpp | 279 | ||||
-rw-r--r-- | src/game/Player.h | 6 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 1 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 2 |
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; } |