[10739] Cleanup pet remove code and some fixes.

* Merge Player::RemovePet and Pet::Remove function code to Pet::Unsummon
  This let be sure that in all cases all required steps doen. For example this fix
  creature's guardians propertly remove from guardians list.
* Add new pet save mode PET_SAVE_REAGENTS as replacement PET_SAVE_NOT_IN_SLOT+true-arg stable pair in old function args
  This will avoid use reagent save arg with wrong different save modes.
* Fixed recently added code with absent check for re-summon protector pet call.
This commit is contained in:
VladimirMangos 2010-11-19 02:07:14 +03:00
parent de66f32882
commit f9bcfa3a89
13 changed files with 138 additions and 125 deletions

View file

@ -577,7 +577,6 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
m_summon_y = 0.0f;
m_summon_z = 0.0f;
m_miniPet = 0;
m_contestedPvPTimer = 0;
m_declinedname = NULL;
@ -1463,9 +1462,7 @@ void Player::Update( uint32 p_time )
Pet* pet = GetPet();
if (pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityDistance()) && (!GetCharmGuid().IsEmpty() && (pet->GetObjectGuid() != GetCharmGuid())))
{
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
}
pet->Unsummon(PET_SAVE_REAGENTS, this);
if (IsHasDelayedTeleport())
TeleportTo(m_teleport_dest, m_teleport_options);
@ -1490,7 +1487,7 @@ void Player::SetDeathState(DeathState s)
RemoveAurasDueToSpell(m_ShapeShiftFormSpellId);
//FIXME: is pet dismissed at dying or releasing spirit? if second, add SetDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
RemovePet(PET_SAVE_REAGENTS);
// remove uncontrolled pets
RemoveMiniPet();
@ -3876,12 +3873,12 @@ bool Player::resetTalents(bool no_cost, bool all_specs)
}
//FIXME: remove pet before or after unlearn spells? for now after unlearn to allow removing of talent related, pet affecting auras
RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true);
RemovePet(PET_SAVE_REAGENTS);
/* when prev line will dropped use next line
if(Pet* pet = GetPet())
{
if(pet->getPetType()==HUNTER_PET && !pet->GetCreatureInfo()->isTameable(CanTameExoticPets()))
RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true);
pet->Unsummon(PET_SAVE_REAGENTS, this);
}
*/
return true;
@ -17773,90 +17770,24 @@ void Player::UpdateDuelFlag(time_t currTime)
duel->opponent->duel->startTime = currTime;
}
void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
void Player::RemovePet(PetSaveMode mode)
{
if (!pet)
pet = GetPet();
if (!pet || pet->GetOwnerGuid() != GetObjectGuid())
return;
// not save secondary permanent pet as current
if (pet && m_temporaryUnsummonedPetNumber && m_temporaryUnsummonedPetNumber != pet->GetCharmInfo()->GetPetNumber() && mode == PET_SAVE_AS_CURRENT)
mode = PET_SAVE_NOT_IN_SLOT;
if (returnreagent && pet && mode != PET_SAVE_AS_CURRENT)
{
//returning of reagents only for players, so best done here
uint32 spellId = pet->GetUInt32Value(UNIT_CREATED_BY_SPELL);
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
if(spellInfo)
{
for(uint32 i = 0; i < MAX_SPELL_REAGENTS; ++i)
{
if(spellInfo->Reagent[i] > 0)
{
ItemPosCountVec dest; //for succubus, voidwalker, felhunter and felguard credit soulshard when despawn reason other than death (out of range, logout)
uint8 msg = CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->Reagent[i], spellInfo->ReagentCount[i] );
if( msg == EQUIP_ERR_OK )
{
Item* item = StoreNewItem( dest, spellInfo->Reagent[i], true);
if(IsInWorld())
SendNewItem(item,spellInfo->ReagentCount[i],true,false);
}
}
}
}
}
// only if current pet in slot
switch(pet->getPetType())
{
case MINI_PET:
m_miniPet = 0;
break;
case PROTECTOR_PET:
case GUARDIAN_PET:
RemoveGuardian(pet);
break;
default:
if (GetPetGuid() == pet->GetObjectGuid())
SetPet(NULL);
break;
}
pet->CombatStop();
pet->SavePetToDB(mode);
pet->AddObjectToRemoveList();
pet->m_removed = true;
if (pet->isControlled())
{
RemovePetActionBar();
if(GetGroup())
SetGroupUpdateFlag(GROUP_UPDATE_PET);
}
if (Pet* pet = GetPet())
pet->Unsummon(mode, this);
}
void Player::RemoveMiniPet()
{
if (Pet* pet = GetMiniPet())
{
pet->Remove(PET_SAVE_AS_DELETED);
m_miniPet = 0;
}
pet->Unsummon(PET_SAVE_AS_DELETED);
}
Pet* Player::GetMiniPet() const
{
if (!m_miniPet)
if (m_miniPetGuid.IsEmpty())
return NULL;
return GetMap()->GetPet(m_miniPet);
return GetMap()->GetPet(m_miniPetGuid);
}
void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, const std::string& text, uint32 language) const
@ -19500,7 +19431,7 @@ template<>
inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
{
if (p->GetPetGuid() == t->GetObjectGuid() && ((Creature*)t)->IsPet())
((Pet*)t)->Remove(PET_SAVE_NOT_IN_SLOT, true);
((Pet*)t)->Unsummon(PET_SAVE_REAGENTS);
}
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target)
@ -21834,7 +21765,7 @@ void Player::UnsummonPetTemporaryIfAny()
if(!m_temporaryUnsummonedPetNumber && pet->isControlled() && !pet->isTemporarySummoned() )
m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber();
RemovePet(pet, PET_SAVE_AS_CURRENT);
pet->Unsummon(PET_SAVE_AS_CURRENT, this);
}
void Player::ResummonPetTemporaryUnSummonedIfAny()