From ddfa7199207e499dd233854a75ac3a6216938873 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 10 Apr 2009 04:49:39 +0400 Subject: [PATCH] [7644] Fixed pet slot values using in pet save. Problem exist from client version switch when stable slot amount changed. In result this has been source problems with stable use (3-4 slots) and possible pet lost in some cases or "not save state" for summoned pets. Use enums to avoid repeating problem, use more safe value for not-in-slot save (for summoned pets) Fixed data preparing for MSG_LIST_STABLED_PETS. --- sql/characters.sql | 2 +- sql/updates/7644_01_characters_character_pet.sql | 5 + sql/updates/Makefile.am | 2 + src/game/CharacterHandler.cpp | 6 +- src/game/NPCHandler.cpp | 46 +++--- src/game/Pet.cpp | 182 +++++++++++------------ src/game/Pet.h | 13 +- src/game/Player.cpp | 6 +- src/shared/revision_nr.h | 2 +- 9 files changed, 141 insertions(+), 123 deletions(-) create mode 100644 sql/updates/7644_01_characters_character_pet.sql diff --git a/sql/characters.sql b/sql/characters.sql index bfa6ec96..f5986244 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_7546_01_characters_uptime` bit(1) default NULL + `required_7644_01_characters_character_pet` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/updates/7644_01_characters_character_pet.sql b/sql/updates/7644_01_characters_character_pet.sql new file mode 100644 index 00000000..03e38a0d --- /dev/null +++ b/sql/updates/7644_01_characters_character_pet.sql @@ -0,0 +1,5 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7546_01_characters_uptime required_7644_01_characters_character_pet bit; + +/* only hunter pets must be in stable */ +UPDATE `character_pet` + SET slot = 100 WHERE PetType <> 1 AND slot >= 1 AND slot <= 4; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 5b8e64e9..2879cb0a 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -170,6 +170,7 @@ pkgdata_DATA = \ 7633_01_mangos_achievement_criteria_data.sql \ 7643_01_mangos_db_version.sql \ 7643_02_mangos_mangos_string.sql \ + 7644_01_characters_character_pet.sql \ README ## Additional files to include when running 'make dist' @@ -320,4 +321,5 @@ EXTRA_DIST = \ 7633_01_mangos_achievement_criteria_data.sql \ 7643_01_mangos_db_version.sql \ 7643_02_mangos_mangos_string.sql \ + 7644_01_characters_character_pet.sql \ README diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 3edc81f1..37a4c863 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -161,7 +161,7 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) "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 "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid " - "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' " + "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" : @@ -170,11 +170,11 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) "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, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, genitive " - "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' " + "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 " "WHERE characters.account = '%u' ORDER BY characters.guid", - GetAccountId()); + PET_SAVE_AS_CURRENT,GetAccountId()); } void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 65163b92..7f69a769 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -475,7 +475,6 @@ void WorldSession::SendBindPoint(Creature *npc) _player->PlayerTalkClass->CloseGossip(); } -//Need fix void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); @@ -508,7 +507,9 @@ void WorldSession::SendStablePet(uint64 guid ) Pet *pet = _player->GetPet(); + size_t wpos = data.wpos(); data << uint8(0); // place holder for slot show number + data << uint8(GetPlayer()->m_stableSlots); uint8 num = 0; // counter for place holder @@ -520,12 +521,13 @@ void WorldSession::SendStablePet(uint64 guid ) data << uint32(pet->GetEntry()); data << uint32(pet->getLevel()); data << pet->GetName(); // petname - data << uint8(0x01); // flags?, client slot 1 == current pet (0) + data << uint8(1); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show) ++num; } - // 0 1 2 3 4 5 - QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow()); + // 0 1 2 3 4 + QueryResult* result = CharacterDatabase.PQuery("SELECT owner, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot", + _player->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT); if(result) { @@ -533,11 +535,11 @@ void WorldSession::SendStablePet(uint64 guid ) { Field *fields = result->Fetch(); - data << uint32(fields[2].GetUInt32()); // petnumber - data << uint32(fields[3].GetUInt32()); // creature entry - data << uint32(fields[4].GetUInt32()); // level - data << fields[5].GetString(); // name - data << uint8(fields[1].GetUInt32()+1); // slot + data << uint32(fields[1].GetUInt32()); // petnumber + data << uint32(fields[2].GetUInt32()); // creature entry + data << uint32(fields[3].GetUInt32()); // level + data << fields[4].GetString(); // name + data << uint8(2); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show) ++num; }while( result->NextRow() ); @@ -545,7 +547,7 @@ void WorldSession::SendStablePet(uint64 guid ) delete result; } - data.put(8, num); // set real data to placeholder + data.put(wpos, num); // set real data to placeholder SendPacket(&data); } @@ -586,7 +588,8 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) uint32 free_slot = 1; - QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5 ORDER BY slot ",_player->GetGUIDLow()); + QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot ", + _player->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT); if(result) { do @@ -595,8 +598,12 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) uint32 slot = fields[1].GetUInt32(); - if(slot==free_slot) // this slot not free - ++free_slot; + // slots ordered in query, and if not equal then free + if(slot!=free_slot) + break; + + // this slot not free, skip + ++free_slot; }while( result->NextRow() ); } delete result; @@ -638,8 +645,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) Pet* pet = _player->GetPet(); if(pet && pet->isAlive()) { - uint8 i = 0x06; - data << uint8(i); + data << uint8(0x06); SendPacket(&data); return; } @@ -650,7 +656,8 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) Pet *newpet = NULL; - QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow(),petnumber); + QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'", + _player->GetGUIDLow(),petnumber,PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT); if(result) { Field *fields = result->Fetch(); @@ -694,7 +701,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data ) WorldPacket data(SMSG_STABLE_RESULT, 200); - if(GetPlayer()->m_stableSlots < 4) // max slots amount = 4 + if(GetPlayer()->m_stableSlots < MAX_PET_STABLES) { StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1); if(_player->GetMoney() >= SlotPrice->Price) @@ -746,7 +753,8 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data ) return; // find swapped pet slot in stable - QueryResult *result = CharacterDatabase.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'",_player->GetGUIDLow(),pet_number); + QueryResult *result = CharacterDatabase.PQuery("SELECT slot,entry FROM character_pet WHERE owner = '%u' AND id = '%u'", + _player->GetGUIDLow(),pet_number); if(!result) return; @@ -756,7 +764,7 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data ) uint32 petentry = fields[1].GetUInt32(); delete result; - // move alive pet to slot or delele dead pet + // move alive pet to slot or delete dead pet _player->RemovePet(pet,pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED); // summon unstabled pet diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 34426115..8e459138 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -91,19 +91,27 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool QueryResult *result; if(petnumber) - // known petnumber entry 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber); + // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType " + "FROM character_pet WHERE owner = '%u' AND id = '%u'", + ownerid, petnumber); else if(current) - // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid ); + // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType " + "FROM character_pet WHERE owner = '%u' AND slot = '%u'", + ownerid, PET_SAVE_AS_CURRENT ); else if(petentry) // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) - // 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry ); + // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType " + "FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ", + ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT); else // any current or other non-stabled pet (for hunter "call pet") - // 0 1 2(?) 3 4 5 6 7 8(?) 9 10 11 12 13 14 15 16 17 18 19 20 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid); + // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType " + "FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ", + ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT); if(!result) return false; @@ -213,11 +221,16 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool uint32 savedmana = fields[12].GetUInt32(); // set current pet as current + // 0=current + // 1..MAX_PET_STABLES in stable slot + // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) if(fields[8].GetUInt32() != 0) { CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'", ownerid, m_charmInfo->GetPetNumber()); - CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'", ownerid, m_charmInfo->GetPetNumber()); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", + PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber()); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'", + PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber()); CharacterDatabase.CommitTransaction(); } @@ -342,99 +355,86 @@ void Pet::SavePetToDB(PetSaveMode mode) uint32 curhealth = GetHealth(); uint32 curmana = GetPower(POWER_MANA); - switch(mode) + // stable and not in slot saves + if(mode > PET_SAVE_AS_CURRENT) { - case PET_SAVE_IN_STABLE_SLOT_1: - case PET_SAVE_IN_STABLE_SLOT_2: - case PET_SAVE_NOT_IN_SLOT: - { - RemoveAllAuras(); + RemoveAllAuras(); - //only alive hunter pets get auras saved, the others don't - if(!(getPetType() == HUNTER_PET && isAlive())) - m_Auras.clear(); - } - default: - break; + //only alive hunter pets get auras saved, the others don't + if(!(getPetType() == HUNTER_PET && isAlive())) + m_Auras.clear(); } _SaveSpells(); _SaveSpellCooldowns(); _SaveAuras(); - switch(mode) + // current/stable/not_in_slot + if(mode >= PET_SAVE_AS_CURRENT) { - case PET_SAVE_AS_CURRENT: - case PET_SAVE_IN_STABLE_SLOT_1: - case PET_SAVE_IN_STABLE_SLOT_2: - case PET_SAVE_NOT_IN_SLOT: + uint32 owner = GUID_LOPART(GetOwnerGUID()); + std::string name = m_name; + CharacterDatabase.escape_string(name); + CharacterDatabase.BeginTransaction(); + // remove current data + CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber() ); + + // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT) + if(mode <= PET_SAVE_LAST_STABLE_SLOT) + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'", + PET_SAVE_NOT_IN_SLOT, owner, uint32(mode) ); + + // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT + if(getPetType()==HUNTER_PET && (mode==PET_SAVE_AS_CURRENT||mode > PET_SAVE_LAST_STABLE_SLOT)) + CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')", + owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT); + // save pet + std::ostringstream ss; + ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) " + << "VALUES (" + << m_charmInfo->GetPetNumber() << ", " + << GetEntry() << ", " + << owner << ", " + << GetNativeDisplayId() << ", " + << getLevel() << ", " + << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", " + << uint32(m_charmInfo->GetReactState()) << ", " + << uint32(GetFreeTalentPoints()) << ", " + << uint32(mode) << ", '" + << name.c_str() << "', " + << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", " + << (curhealth<1?1:curhealth) << ", " + << curmana << ", " + << GetPower(POWER_HAPPINESS) << ", '"; + + for(uint32 i = 0; i < 10; i++) + ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " "; + ss << "', '"; + + //save spells the pet can teach to it's Master { - uint32 owner = GUID_LOPART(GetOwnerGUID()); - std::string name = m_name; - CharacterDatabase.escape_string(name); - CharacterDatabase.BeginTransaction(); - // remove current data - CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber() ); - - // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT) - if(mode!=PET_SAVE_NOT_IN_SLOT) - CharacterDatabase.PExecute("UPDATE character_pet SET slot = 3 WHERE owner = '%u' AND slot = '%u'", owner, uint32(mode) ); - - // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT - if(getPetType()==HUNTER_PET && (mode==PET_SAVE_AS_CURRENT||mode==PET_SAVE_NOT_IN_SLOT)) - CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner ); - // save pet - std::ostringstream ss; - ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) " - << "VALUES (" - << m_charmInfo->GetPetNumber() << ", " - << GetEntry() << ", " - << owner << ", " - << GetNativeDisplayId() << ", " - << getLevel() << ", " - << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", " - << uint32(m_charmInfo->GetReactState()) << ", " - << uint32(GetFreeTalentPoints()) << ", " - << uint32(mode) << ", '" - << name.c_str() << "', " - << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", " - << (curhealth<1?1:curhealth) << ", " - << curmana << ", " - << GetPower(POWER_HAPPINESS) << ", '"; - - for(uint32 i = 0; i < 10; i++) - ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " "; - ss << "', '"; - - //save spells the pet can teach to it's Master - { - int i = 0; - for(TeachSpellMap::iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr) - ss << itr->first << " " << itr->second << " "; - for(; i < 4; ++i) - ss << uint32(0) << " " << uint32(0) << " "; - } - - ss << "', " - << time(NULL) << ", " - << uint32(m_resetTalentsCost) << ", " - << uint64(m_resetTalentsTime) << ", " - << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", " - << uint32(getPetType()) << ")"; + int i = 0; + for(TeachSpellMap::iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr) + ss << itr->first << " " << itr->second << " "; + for(; i < 4; ++i) + ss << uint32(0) << " " << uint32(0) << " "; + } - CharacterDatabase.Execute( ss.str().c_str() ); + ss << "', " + << time(NULL) << ", " + << uint32(m_resetTalentsCost) << ", " + << uint64(m_resetTalentsTime) << ", " + << GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", " + << uint32(getPetType()) << ")"; - CharacterDatabase.CommitTransaction(); - break; - } - case PET_SAVE_AS_DELETED: - { - RemoveAllAuras(); - DeleteFromDB(m_charmInfo->GetPetNumber()); - break; - } - default: - sLog.outError("Unknown pet save/remove mode: %d",mode); + CharacterDatabase.Execute( ss.str().c_str() ); + CharacterDatabase.CommitTransaction(); + } + // delete + else + { + RemoveAllAuras(); + DeleteFromDB(m_charmInfo->GetPetNumber()); } } diff --git a/src/game/Pet.h b/src/game/Pet.h index 7f43b069..255690e7 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -34,13 +34,16 @@ enum PetType extern char const* petTypeSuffix[MAX_PET_TYPE]; +#define MAX_PET_STABLES 4 + +// stored in character_pet.slot enum PetSaveMode { - PET_SAVE_AS_DELETED =-1, - PET_SAVE_AS_CURRENT = 0, - PET_SAVE_IN_STABLE_SLOT_1 = 1, - PET_SAVE_IN_STABLE_SLOT_2 = 2, - PET_SAVE_NOT_IN_SLOT = 3 + PET_SAVE_AS_DELETED = -1, // not saved in fact + PET_SAVE_AS_CURRENT = 0, // in current slot (with player) + PET_SAVE_FIRST_STABLE_SLOT = 1, + PET_SAVE_LAST_STABLE_SLOT = MAX_PET_STABLES, // last in DB stable slot index (including), all higher have same meaning as PET_SAVE_NOT_IN_SLOT + PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100 }; enum HappinessState diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c6c6cce7..c26f9a5f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14073,10 +14073,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) uint32 extraflags = fields[25].GetUInt32(); m_stableSlots = fields[26].GetUInt32(); - if(m_stableSlots > 4) + if(m_stableSlots > MAX_PET_STABLES) { - sLog.outError("Player can have not more 4 stable slots, but have in DB %u",uint32(m_stableSlots)); - m_stableSlots = 4; + 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(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c661d69c..0792696e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7643" + #define REVISION_NR "7644" #endif // __REVISION_NR_H__ -- 2.11.4.GIT