diff options
-rw-r--r-- | sql/base/characters_database.sql | 1 | ||||
-rw-r--r-- | sql/updates/characters/master/2022_01_31_01_characters.sql | 3 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 5 |
6 files changed, 23 insertions, 25 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 7f16a62dc04..044b995bc88 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1826,6 +1826,7 @@ CREATE TABLE `characters` ( `trans_o` float NOT NULL DEFAULT '0', `transguid` bigint unsigned NOT NULL DEFAULT '0', `extra_flags` smallint unsigned NOT NULL DEFAULT '0', + `summonedPetNumber` int unsigned NOT NULL DEFAULT '0', `at_login` smallint unsigned NOT NULL DEFAULT '0', `zone` smallint unsigned NOT NULL DEFAULT '0', `death_expire_time` bigint NOT NULL DEFAULT '0', diff --git a/sql/updates/characters/master/2022_01_31_01_characters.sql b/sql/updates/characters/master/2022_01_31_01_characters.sql new file mode 100644 index 00000000000..9b5efaa5eec --- /dev/null +++ b/sql/updates/characters/master/2022_01_31_01_characters.sql @@ -0,0 +1,3 @@ +ALTER TABLE `characters` ADD `summonedPetNumber` int unsigned NOT NULL DEFAULT '0' AFTER `extra_flags`; + +UPDATE `characters` SET `summonedPetNumber` = COALESCE((SELECT `id` FROM `character_pet` WHERE `owner` = `guid` AND `slot` = 0 AND `curhealth` > 0), 0); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 309108ae55f..ce954379475 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -52,22 +52,22 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_MAIL_LIST_ITEMS, "SELECT itemEntry,count FROM item_instance WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, " "gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, c.slot, c.logout_time, c.activeTalentGroup, c.lastLoginBuild " - "FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid " + "FROM characters AS c LEFT JOIN character_pet AS cp ON c.summonedPetNumber = cp.id LEFT JOIN guild_member AS gm ON c.guid = gm.guid " "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.level, c.zone, c.map, " "c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, " - "cb.guid, c.slot, c.logout_time, c.activeTalentGroup, c.lastLoginBuild, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? " + "cb.guid, c.slot, c.logout_time, c.activeTalentGroup, c.lastLoginBuild, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.summonedPetNumber = cp.id " "LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid " "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_ENUM_CUSTOMIZATIONS, "SELECT cc.guid, cc.chrCustomizationOptionID, cc.chrCustomizationChoiceID FROM character_customizations cc " "LEFT JOIN characters c ON cc.guid = c.guid WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY cc.guid, cc.chrCustomizationOptionID", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_UNDELETE_ENUM, "SELECT c.guid, c.deleteInfos_Name, c.race, c.class, c.gender, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, " "gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, c.slot, c.logout_time, c.activeTalentGroup, c.lastLoginBuild " - "FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid " + "FROM characters AS c LEFT JOIN character_pet AS cp ON c.summonedPetNumber = cp.id LEFT JOIN guild_member AS gm ON c.guid = gm.guid " "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.deleteInfos_Account = ? AND c.deleteInfos_Name IS NOT NULL", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_UNDELETE_ENUM_DECLINED_NAME, "SELECT c.guid, c.deleteInfos_Name, c.race, c.class, c.gender, c.level, c.zone, c.map, " "c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, " - "cb.guid, c.slot, c.logout_time, c.activeTalentGroup, c.lastLoginBuild, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? " + "cb.guid, c.slot, c.logout_time, c.activeTalentGroup, c.lastLoginBuild, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.summonedPetNumber = cp.id " "LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid " "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.deleteInfos_Account = ? AND c.deleteInfos_Name IS NOT NULL", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_UNDELETE_ENUM_CUSTOMIZATIONS, "SELECT cc.guid, cc.chrCustomizationOptionID, cc.chrCustomizationChoiceID FROM character_customizations cc " @@ -84,7 +84,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER, "SELECT c.guid, account, name, race, class, gender, level, xp, money, inventorySlots, bankSlots, restState, playerFlags, playerFlagsEx, " "position_x, position_y, position_z, map, orientation, taximask, createTime, createMode, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - "resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " + "resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, summonedPetNumber, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " "health, power1, power2, power3, power4, power5, power6, power7, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, raidDifficulty, legacyRaidDifficulty, fishingSteps, " "honor, honorLevel, honorRestState, honorRestBonus, numRespecs " @@ -471,14 +471,14 @@ void CharacterDatabaseConnection::DoPrepareStatements() "map, instance_id, dungeonDifficulty, raidDifficulty, legacyRaidDifficulty, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, " "taximask, createTime, createMode, cinematic, " "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, primarySpecialization, " - "extra_flags, at_login, " + "extra_flags, summonedPetNumber, at_login, " "death_expire_time, taxi_path, totalKills, " "todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, " "power4, power5, power6, power7, latency, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, lastLoginBuild) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,inventorySlots=?,bankSlots=?,restState=?,playerFlags=?,playerFlagsEx=?," "map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," - "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,numRespecs=?,primarySpecialization=?,extra_flags=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," + "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,numRespecs=?,primarySpecialization=?,extra_flags=?,summonedPetNumber=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," "totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,activeTalentGroup=?,lootSpecId=?,exploredZones=?," "equipmentCache=?,knownTitles=?,actionBars=?,online=?,honor=?,honorLevel=?,honorRestState=?,honorRestBonus=?,lastLoginBuild=? WHERE guid=?", CONNECTION_ASYNC); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ae5044c3474..f109e03b738 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17819,7 +17819,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) { // "SELECT c.guid, account, name, race, class, gender, level, xp, money, inventorySlots, bankSlots, restState, playerFlags, playerFlagsEx, " // "position_x, position_y, position_z, map, orientation, taximask, createTime, createMode, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - // "resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " + // "resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, summonedPetNumber, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " // "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " // "health, power1, power2, power3, power4, power5, power6, power7, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, raidDifficulty, legacyRaidDifficulty, fishingSteps, " // "honor, honorLevel, honorRestState, honorRestBonus, numRespecs " @@ -17862,6 +17862,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) float trans_o; ObjectGuid::LowType transguid; uint16 extra_flags; + uint32 summonedPetNumber; uint16 at_login; uint16 zone; uint8 online; @@ -17931,6 +17932,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) trans_o = fields[i++].GetFloat(); transguid = fields[i++].GetUInt64(); extra_flags = fields[i++].GetUInt16(); + summonedPetNumber = fields[i++].GetUInt32(); at_login = fields[i++].GetUInt16(); zone = fields[i++].GetUInt16(); online = fields[i++].GetUInt8(); @@ -18412,6 +18414,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder) uint32 extraflags = fields.extra_flags; _LoadPetStable(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS)); + m_temporaryUnsummonedPetNumber = fields.summonedPetNumber; if (HasAtLoginFlag(AT_LOGIN_RENAME)) { @@ -19453,18 +19456,6 @@ void Player::_LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mail UpdateNextMailTimeAndUnreads(); } -void Player::LoadPet() -{ - //fixme: the pet should still be loaded if the player is not in world - // just not added to the map - if (m_petStable && IsInWorld()) - { - Pet* pet = new Pet(this); - if (!pet->LoadPetFromDB(this, 0, 0, true)) - delete pet; - } -} - void Player::_LoadQuestStatus(PreparedQueryResult result) { uint16 slot = 0; @@ -20475,6 +20466,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba stmt->setInt64(index++, GetTalentResetTime()); stmt->setUInt32(index++, GetPrimarySpecialization()); stmt->setUInt16(index++, (uint16)m_ExtraFlags); + stmt->setUInt32(index++, 0); // summonedPetNumber stmt->setUInt16(index++, (uint16)m_atLoginFlags); stmt->setInt64(index++, m_deathExpireTime); @@ -20618,6 +20610,10 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba stmt->setUInt8(index++, GetNumRespecs()); stmt->setUInt32(index++, GetPrimarySpecialization()); stmt->setUInt16(index++, (uint16)m_ExtraFlags); + if (PetStable const* petStable = GetPetStable()) + stmt->setUInt32(index++, petStable->CurrentPet && petStable->CurrentPet->Health > 0 ? petStable->CurrentPet->PetNumber : 0); // summonedPetNumber + else + stmt->setUInt32(index++, 0); // summonedPetNumber stmt->setUInt16(index++, (uint16)m_atLoginFlags); stmt->setUInt16(index++, GetZoneId()); stmt->setInt64(index++, m_deathExpireTime); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 48ed937beba..471720327f7 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1491,7 +1491,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void RemoveItemDurations(Item* item); void SendItemDurations(); void LoadCorpse(PreparedQueryResult result); - void LoadPet(); bool AddItem(uint32 itemId, uint32 count); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index ae75f958c8e..c80cc034336 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -365,8 +365,7 @@ public: bool result = true; CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(statements[isDeletedCharacters ? 1 : 0][withDeclinedNames ? 1 : 0]); - stmt->setUInt8(0, PET_SAVE_AS_CURRENT); - stmt->setUInt32(1, accountId); + stmt->setUInt32(0, accountId); result &= SetPreparedQuery(CHARACTERS, stmt); stmt = CharacterDatabase.GetPreparedStatement(statements[isDeletedCharacters ? 1 : 0][2]); @@ -1297,7 +1296,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) } // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) - pCurrChar->LoadPet(); + pCurrChar->ResummonPetTemporaryUnSummonedIfAny(); // Set FFA PvP for non GM in non-rest mode if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING)) |