mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[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.
This commit is contained in:
parent
34d69bbfdd
commit
263bf2ab22
9 changed files with 142 additions and 124 deletions
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `character_db_version`;
|
DROP TABLE IF EXISTS `character_db_version`;
|
||||||
CREATE TABLE `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';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
||||||
5
sql/updates/7644_01_characters_character_pet.sql
Normal file
5
sql/updates/7644_01_characters_character_pet.sql
Normal file
|
|
@ -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;
|
||||||
|
|
@ -170,6 +170,7 @@ pkgdata_DATA = \
|
||||||
7633_01_mangos_achievement_criteria_data.sql \
|
7633_01_mangos_achievement_criteria_data.sql \
|
||||||
7643_01_mangos_db_version.sql \
|
7643_01_mangos_db_version.sql \
|
||||||
7643_02_mangos_mangos_string.sql \
|
7643_02_mangos_mangos_string.sql \
|
||||||
|
7644_01_characters_character_pet.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -320,4 +321,5 @@ EXTRA_DIST = \
|
||||||
7633_01_mangos_achievement_criteria_data.sql \
|
7633_01_mangos_achievement_criteria_data.sql \
|
||||||
7643_01_mangos_db_version.sql \
|
7643_01_mangos_db_version.sql \
|
||||||
7643_02_mangos_mangos_string.sql \
|
7643_02_mangos_mangos_string.sql \
|
||||||
|
7644_01_characters_character_pet.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -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, "
|
"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
|
// 9 10 11 12 13
|
||||||
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid "
|
"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 "
|
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
|
||||||
"WHERE characters.account = '%u' ORDER BY characters.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, "
|
"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
|
// 9 10 11 12 13 14
|
||||||
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, genitive "
|
"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 character_declinedname ON characters.guid = character_declinedname.guid "
|
||||||
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
|
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
|
||||||
"WHERE characters.account = '%u' ORDER BY characters.guid",
|
"WHERE characters.account = '%u' ORDER BY characters.guid",
|
||||||
GetAccountId());
|
PET_SAVE_AS_CURRENT,GetAccountId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
|
void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
|
||||||
|
|
|
||||||
|
|
@ -475,7 +475,6 @@ void WorldSession::SendBindPoint(Creature *npc)
|
||||||
_player->PlayerTalkClass->CloseGossip();
|
_player->PlayerTalkClass->CloseGossip();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Need fix
|
|
||||||
void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data )
|
void WorldSession::HandleListStabledPetsOpcode( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
CHECK_PACKET_SIZE(recv_data,8);
|
CHECK_PACKET_SIZE(recv_data,8);
|
||||||
|
|
@ -508,7 +507,9 @@ void WorldSession::SendStablePet(uint64 guid )
|
||||||
|
|
||||||
Pet *pet = _player->GetPet();
|
Pet *pet = _player->GetPet();
|
||||||
|
|
||||||
|
size_t wpos = data.wpos();
|
||||||
data << uint8(0); // place holder for slot show number
|
data << uint8(0); // place holder for slot show number
|
||||||
|
|
||||||
data << uint8(GetPlayer()->m_stableSlots);
|
data << uint8(GetPlayer()->m_stableSlots);
|
||||||
|
|
||||||
uint8 num = 0; // counter for place holder
|
uint8 num = 0; // counter for place holder
|
||||||
|
|
@ -520,12 +521,13 @@ void WorldSession::SendStablePet(uint64 guid )
|
||||||
data << uint32(pet->GetEntry());
|
data << uint32(pet->GetEntry());
|
||||||
data << uint32(pet->getLevel());
|
data << uint32(pet->getLevel());
|
||||||
data << pet->GetName(); // petname
|
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;
|
++num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 1 2 3 4 5
|
// 0 1 2 3 4
|
||||||
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());
|
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)
|
if(result)
|
||||||
{
|
{
|
||||||
|
|
@ -533,11 +535,11 @@ void WorldSession::SendStablePet(uint64 guid )
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
|
|
||||||
data << uint32(fields[2].GetUInt32()); // petnumber
|
data << uint32(fields[1].GetUInt32()); // petnumber
|
||||||
data << uint32(fields[3].GetUInt32()); // creature entry
|
data << uint32(fields[2].GetUInt32()); // creature entry
|
||||||
data << uint32(fields[4].GetUInt32()); // level
|
data << uint32(fields[3].GetUInt32()); // level
|
||||||
data << fields[5].GetString(); // name
|
data << fields[4].GetString(); // name
|
||||||
data << uint8(fields[1].GetUInt32()+1); // slot
|
data << uint8(2); // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
|
||||||
|
|
||||||
++num;
|
++num;
|
||||||
}while( result->NextRow() );
|
}while( result->NextRow() );
|
||||||
|
|
@ -545,7 +547,7 @@ void WorldSession::SendStablePet(uint64 guid )
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.put<uint8>(8, num); // set real data to placeholder
|
data.put<uint8>(wpos, num); // set real data to placeholder
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -586,7 +588,8 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
|
||||||
|
|
||||||
uint32 free_slot = 1;
|
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)
|
if(result)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
|
@ -595,8 +598,12 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
|
||||||
|
|
||||||
uint32 slot = fields[1].GetUInt32();
|
uint32 slot = fields[1].GetUInt32();
|
||||||
|
|
||||||
if(slot==free_slot) // this slot not free
|
// slots ordered in query, and if not equal then free
|
||||||
++free_slot;
|
if(slot!=free_slot)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// this slot not free, skip
|
||||||
|
++free_slot;
|
||||||
}while( result->NextRow() );
|
}while( result->NextRow() );
|
||||||
}
|
}
|
||||||
delete result;
|
delete result;
|
||||||
|
|
@ -638,8 +645,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
|
||||||
Pet* pet = _player->GetPet();
|
Pet* pet = _player->GetPet();
|
||||||
if(pet && pet->isAlive())
|
if(pet && pet->isAlive())
|
||||||
{
|
{
|
||||||
uint8 i = 0x06;
|
data << uint8(0x06);
|
||||||
data << uint8(i);
|
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -650,7 +656,8 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
|
||||||
|
|
||||||
Pet *newpet = NULL;
|
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)
|
if(result)
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
|
|
@ -694,7 +701,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )
|
||||||
|
|
||||||
WorldPacket data(SMSG_STABLE_RESULT, 200);
|
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);
|
StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
|
||||||
if(_player->GetMoney() >= SlotPrice->Price)
|
if(_player->GetMoney() >= SlotPrice->Price)
|
||||||
|
|
@ -746,7 +753,8 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// find swapped pet slot in stable
|
// 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)
|
if(!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -756,7 +764,7 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
|
||||||
uint32 petentry = fields[1].GetUInt32();
|
uint32 petentry = fields[1].GetUInt32();
|
||||||
delete result;
|
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);
|
_player->RemovePet(pet,pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED);
|
||||||
|
|
||||||
// summon unstabled pet
|
// summon unstabled pet
|
||||||
|
|
|
||||||
184
src/game/Pet.cpp
184
src/game/Pet.cpp
|
|
@ -91,19 +91,27 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
QueryResult *result;
|
QueryResult *result;
|
||||||
|
|
||||||
if(petnumber)
|
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
|
// 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);
|
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)
|
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
|
// 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 );
|
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)
|
else if(petentry)
|
||||||
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
|
// 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
|
// 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 );
|
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
|
else
|
||||||
// any current or other non-stabled pet (for hunter "call pet")
|
// 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
|
// 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);
|
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)
|
if(!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -213,11 +221,16 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
uint32 savedmana = fields[12].GetUInt32();
|
uint32 savedmana = fields[12].GetUInt32();
|
||||||
|
|
||||||
// set current pet as current
|
// 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)
|
if(fields[8].GetUInt32() != 0)
|
||||||
{
|
{
|
||||||
CharacterDatabase.BeginTransaction();
|
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 = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
|
||||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'", ownerid, m_charmInfo->GetPetNumber());
|
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();
|
CharacterDatabase.CommitTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,99 +355,86 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||||
uint32 curhealth = GetHealth();
|
uint32 curhealth = GetHealth();
|
||||||
uint32 curmana = GetPower(POWER_MANA);
|
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:
|
RemoveAllAuras();
|
||||||
case PET_SAVE_IN_STABLE_SLOT_2:
|
|
||||||
case PET_SAVE_NOT_IN_SLOT:
|
|
||||||
{
|
|
||||||
RemoveAllAuras();
|
|
||||||
|
|
||||||
//only alive hunter pets get auras saved, the others don't
|
//only alive hunter pets get auras saved, the others don't
|
||||||
if(!(getPetType() == HUNTER_PET && isAlive()))
|
if(!(getPetType() == HUNTER_PET && isAlive()))
|
||||||
m_Auras.clear();
|
m_Auras.clear();
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_SaveSpells();
|
_SaveSpells();
|
||||||
_SaveSpellCooldowns();
|
_SaveSpellCooldowns();
|
||||||
_SaveAuras();
|
_SaveAuras();
|
||||||
|
|
||||||
switch(mode)
|
// current/stable/not_in_slot
|
||||||
|
if(mode >= PET_SAVE_AS_CURRENT)
|
||||||
{
|
{
|
||||||
case PET_SAVE_AS_CURRENT:
|
uint32 owner = GUID_LOPART(GetOwnerGUID());
|
||||||
case PET_SAVE_IN_STABLE_SLOT_1:
|
std::string name = m_name;
|
||||||
case PET_SAVE_IN_STABLE_SLOT_2:
|
CharacterDatabase.escape_string(name);
|
||||||
case PET_SAVE_NOT_IN_SLOT:
|
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());
|
int i = 0;
|
||||||
std::string name = m_name;
|
for(TeachSpellMap::iterator itr = m_teachspells.begin(); i < 4 && itr != m_teachspells.end(); ++i, ++itr)
|
||||||
CharacterDatabase.escape_string(name);
|
ss << itr->first << " " << itr->second << " ";
|
||||||
CharacterDatabase.BeginTransaction();
|
for(; i < 4; ++i)
|
||||||
// remove current data
|
ss << uint32(0) << " " << uint32(0) << " ";
|
||||||
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()) << ")";
|
|
||||||
|
|
||||||
CharacterDatabase.Execute( ss.str().c_str() );
|
|
||||||
|
|
||||||
CharacterDatabase.CommitTransaction();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case PET_SAVE_AS_DELETED:
|
|
||||||
{
|
ss << "', "
|
||||||
RemoveAllAuras();
|
<< time(NULL) << ", "
|
||||||
DeleteFromDB(m_charmInfo->GetPetNumber());
|
<< uint32(m_resetTalentsCost) << ", "
|
||||||
break;
|
<< uint64(m_resetTalentsTime) << ", "
|
||||||
}
|
<< GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
|
||||||
default:
|
<< uint32(getPetType()) << ")";
|
||||||
sLog.outError("Unknown pet save/remove mode: %d",mode);
|
|
||||||
|
CharacterDatabase.Execute( ss.str().c_str() );
|
||||||
|
CharacterDatabase.CommitTransaction();
|
||||||
|
}
|
||||||
|
// delete
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RemoveAllAuras();
|
||||||
|
DeleteFromDB(m_charmInfo->GetPetNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,16 @@ enum PetType
|
||||||
|
|
||||||
extern char const* petTypeSuffix[MAX_PET_TYPE];
|
extern char const* petTypeSuffix[MAX_PET_TYPE];
|
||||||
|
|
||||||
|
#define MAX_PET_STABLES 4
|
||||||
|
|
||||||
|
// stored in character_pet.slot
|
||||||
enum PetSaveMode
|
enum PetSaveMode
|
||||||
{
|
{
|
||||||
PET_SAVE_AS_DELETED =-1,
|
PET_SAVE_AS_DELETED = -1, // not saved in fact
|
||||||
PET_SAVE_AS_CURRENT = 0,
|
PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
|
||||||
PET_SAVE_IN_STABLE_SLOT_1 = 1,
|
PET_SAVE_FIRST_STABLE_SLOT = 1,
|
||||||
PET_SAVE_IN_STABLE_SLOT_2 = 2,
|
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 = 3
|
PET_SAVE_NOT_IN_SLOT = 100 // for avoid conflict with stable size grow will use 100
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HappinessState
|
enum HappinessState
|
||||||
|
|
|
||||||
|
|
@ -14073,10 +14073,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||||
uint32 extraflags = fields[25].GetUInt32();
|
uint32 extraflags = fields[25].GetUInt32();
|
||||||
|
|
||||||
m_stableSlots = fields[26].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));
|
sLog.outError("Player can have not more %u stable slots, but have in DB %u",MAX_PET_STABLES,uint32(m_stableSlots));
|
||||||
m_stableSlots = 4;
|
m_stableSlots = MAX_PET_STABLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_atLoginFlags = fields[27].GetUInt32();
|
m_atLoginFlags = fields[27].GetUInt32();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7643"
|
#define REVISION_NR "7644"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue