mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[7645] Fixed problems wit temporary unsummoned pets and cleanup code.
* Save temporary unsummoned pet to current slot (instead non_in_slot mode) and prevent save as current pet summoned while temporay unsummon (arena) * Prevent overwrite temporary summoned pet data * At player loading set temporary unsummoned pet data instead pet loading if pet expected to be temporary unsummoned in current player state (loading in taxi flight/etc) * Restore proper pet at arena leave and unsummon in arena summoned.
This commit is contained in:
parent
263bf2ab22
commit
eb198f8239
9 changed files with 105 additions and 108 deletions
|
|
@ -90,17 +90,17 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
|
||||
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
|
||||
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
|
||||
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)
|
||||
// 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 "
|
||||
|
|
@ -120,7 +120,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
|
||||
// update for case of current pet "slot = 0"
|
||||
petentry = fields[1].GetUInt32();
|
||||
if(!petentry)
|
||||
if (!petentry)
|
||||
{
|
||||
delete result;
|
||||
return false;
|
||||
|
|
@ -132,16 +132,24 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
|
||||
|
||||
// check temporary summoned pets like mage water elemental
|
||||
if(current && is_temporary_summoned)
|
||||
if (current && is_temporary_summoned)
|
||||
{
|
||||
delete result;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 pet_number = fields[0].GetUInt32();
|
||||
|
||||
if (current && owner->IsPetNeedBeTemporaryUnsummoned())
|
||||
{
|
||||
owner->SetTemporaryUnsummonedPetNumber(pet_number);
|
||||
delete result;
|
||||
return false;
|
||||
}
|
||||
|
||||
Map *map = owner->GetMap();
|
||||
uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET);
|
||||
uint32 pet_number = fields[0].GetUInt32();
|
||||
if(!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number))
|
||||
if (!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number))
|
||||
{
|
||||
delete result;
|
||||
return false;
|
||||
|
|
@ -152,7 +160,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
|
||||
Relocate(px, py, pz, owner->GetOrientation());
|
||||
|
||||
if(!IsPositionValid())
|
||||
if (!IsPositionValid())
|
||||
{
|
||||
sLog.outError("Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY());
|
||||
|
|
@ -165,7 +173,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
|
||||
|
||||
CreatureInfo const *cinfo = GetCreatureInfo();
|
||||
if(cinfo->type == CREATURE_TYPE_CRITTER)
|
||||
if (cinfo->type == CREATURE_TYPE_CRITTER)
|
||||
{
|
||||
AIM_Initialize();
|
||||
map->Add((Creature*)this);
|
||||
|
|
@ -173,7 +181,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
return true;
|
||||
}
|
||||
|
||||
if(getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
|
||||
if (getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))
|
||||
m_charmInfo->SetPetNumber(pet_number, true);
|
||||
else
|
||||
m_charmInfo->SetPetNumber(pet_number, false);
|
||||
|
|
@ -185,7 +193,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||
SetName(fields[9].GetString());
|
||||
|
||||
switch(getPetType())
|
||||
switch (getPetType())
|
||||
{
|
||||
case SUMMON_PET:
|
||||
petlevel=owner->getLevel();
|
||||
|
|
@ -224,7 +232,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
// 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.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
|
||||
|
|
@ -234,12 +242,12 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
CharacterDatabase.CommitTransaction();
|
||||
}
|
||||
|
||||
if(!is_temporary_summoned)
|
||||
if (!is_temporary_summoned)
|
||||
{
|
||||
// permanent controlled pets store state in DB
|
||||
Tokens tokens = StrSplit(fields[14].GetString(), " ");
|
||||
|
||||
if(tokens.size() != 20)
|
||||
if (tokens.size() != 20)
|
||||
{
|
||||
delete result;
|
||||
return false;
|
||||
|
|
@ -282,7 +290,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
_LoadAuras(timediff);
|
||||
|
||||
//init AB
|
||||
if(is_temporary_summoned)
|
||||
if (is_temporary_summoned)
|
||||
{
|
||||
// Temporary summoned pets always have initial spell list at load
|
||||
InitPetCreateSpells();
|
||||
|
|
@ -293,7 +301,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
CastPetAuras(current);
|
||||
}
|
||||
|
||||
if(getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
|
||||
if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
|
||||
{
|
||||
SetHealth(GetMaxHealth());
|
||||
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
||||
|
|
@ -314,14 +322,14 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
owner->SetPet(this); // in DB stored only full controlled creature
|
||||
sLog.outDebug("New Pet has guid %u", GetGUIDLow());
|
||||
|
||||
if(owner->GetTypeId() == TYPEID_PLAYER)
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)owner)->PetSpellInitialize();
|
||||
if(((Player*)owner)->GetGroup())
|
||||
((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_PET);
|
||||
}
|
||||
|
||||
if(owner->GetTypeId() == TYPEID_PLAYER && getPetType() == HUNTER_PET)
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER && getPetType() == HUNTER_PET)
|
||||
{
|
||||
result = CharacterDatabase.PQuery("SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", owner->GetGUIDLow(), GetCharmInfo()->GetPetNumber());
|
||||
|
||||
|
|
@ -345,13 +353,33 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
|
||||
void Pet::SavePetToDB(PetSaveMode mode)
|
||||
{
|
||||
if(!GetEntry())
|
||||
if (!GetEntry())
|
||||
return;
|
||||
|
||||
// save only fully controlled creature
|
||||
if(!isControlled())
|
||||
if (!isControlled() && !isTemporarySummoned())
|
||||
return;
|
||||
|
||||
// not save not player pets
|
||||
if(!IS_PLAYER_GUID(GetOwnerGUID()))
|
||||
return;
|
||||
|
||||
Player* pOwner = (Player*)GetOwner();
|
||||
if (!pOwner)
|
||||
return;
|
||||
|
||||
// not save pet as current if another pet temporary unsummoned
|
||||
if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() &&
|
||||
pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
|
||||
{
|
||||
// pet will lost anyway at restore temporary unsummoned
|
||||
if(getPetType()==HUNTER_PET)
|
||||
return;
|
||||
|
||||
// for warlock case
|
||||
mode = PET_SAVE_NOT_IN_SLOT;
|
||||
}
|
||||
|
||||
uint32 curhealth = GetHealth();
|
||||
uint32 curmana = GetPower(POWER_MANA);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue