mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[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:
parent
de66f32882
commit
f9bcfa3a89
13 changed files with 138 additions and 125 deletions
|
|
@ -1045,7 +1045,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
||||||
bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
|
bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
|
||||||
|
|
||||||
// unsummon current and summon old pet if there was one and there isn't a current pet
|
// unsummon current and summon old pet if there was one and there isn't a current pet
|
||||||
plr->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT);
|
plr->RemovePet(PET_SAVE_NOT_IN_SLOT);
|
||||||
plr->ResummonPetTemporaryUnSummonedIfAny();
|
plr->ResummonPetTemporaryUnSummonedIfAny();
|
||||||
|
|
||||||
if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
|
if (isRated() && GetStatus() == STATUS_IN_PROGRESS)
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ void WorldSession::HandleRepopRequestOpcode( WorldPacket & recv_data )
|
||||||
}
|
}
|
||||||
|
|
||||||
//this is spirit release confirm?
|
//this is spirit release confirm?
|
||||||
GetPlayer()->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true);
|
GetPlayer()->RemovePet(PET_SAVE_REAGENTS);
|
||||||
GetPlayer()->BuildPlayerRepop();
|
GetPlayer()->BuildPlayerRepop();
|
||||||
GetPlayer()->RepopAtGraveyard();
|
GetPlayer()->RepopAtGraveyard();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -614,7 +614,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )
|
||||||
|
|
||||||
if( free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots)
|
if( free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots)
|
||||||
{
|
{
|
||||||
_player->RemovePet(pet,PetSaveMode(free_slot));
|
pet->Unsummon(PetSaveMode(free_slot), _player);
|
||||||
SendStableResult(STABLE_SUCCESS_STABLE);
|
SendStableResult(STABLE_SUCCESS_STABLE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -678,7 +678,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )
|
||||||
|
|
||||||
// delete dead pet
|
// delete dead pet
|
||||||
if(pet)
|
if(pet)
|
||||||
_player->RemovePet(pet,PET_SAVE_AS_DELETED);
|
pet->Unsummon(PET_SAVE_AS_DELETED, _player);
|
||||||
|
|
||||||
Pet *newpet = new Pet(HUNTER_PET);
|
Pet *newpet = new Pet(HUNTER_PET);
|
||||||
if(!newpet->LoadPetFromDB(_player,creature_id,petnumber))
|
if(!newpet->LoadPetFromDB(_player,creature_id,petnumber))
|
||||||
|
|
@ -790,7 +790,7 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data )
|
||||||
}
|
}
|
||||||
|
|
||||||
// move alive pet to slot or delete dead pet
|
// move alive pet to slot or delete dead pet
|
||||||
_player->RemovePet(pet,pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED);
|
pet->Unsummon(pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED, _player);
|
||||||
|
|
||||||
// summon unstabled pet
|
// summon unstabled pet
|
||||||
Pet *newpet = new Pet;
|
Pet *newpet = new Pet;
|
||||||
|
|
|
||||||
|
|
@ -356,8 +356,11 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||||
// current/stable/not_in_slot
|
// current/stable/not_in_slot
|
||||||
if (mode >= PET_SAVE_AS_CURRENT)
|
if (mode >= PET_SAVE_AS_CURRENT)
|
||||||
{
|
{
|
||||||
|
// reagents must be returned before save call
|
||||||
|
if (mode == PET_SAVE_REAGENTS)
|
||||||
|
mode = PET_SAVE_NOT_IN_SLOT;
|
||||||
// not save pet as current if another pet temporary unsummoned
|
// not save pet as current if another pet temporary unsummoned
|
||||||
if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() &&
|
else if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() &&
|
||||||
pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
|
pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
|
||||||
{
|
{
|
||||||
// pet will lost anyway at restore temporary unsummoned
|
// pet will lost anyway at restore temporary unsummoned
|
||||||
|
|
@ -453,7 +456,7 @@ void Pet::SetDeathState(DeathState s) // overwrite virtual
|
||||||
{
|
{
|
||||||
//remove summoned pet (no corpse)
|
//remove summoned pet (no corpse)
|
||||||
if(getPetType()==SUMMON_PET)
|
if(getPetType()==SUMMON_PET)
|
||||||
Remove(PET_SAVE_NOT_IN_SLOT);
|
Unsummon(PET_SAVE_NOT_IN_SLOT);
|
||||||
// other will despawn at corpse desppawning (Pet::Update code)
|
// other will despawn at corpse desppawning (Pet::Update code)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -488,7 +491,7 @@ void Pet::Update(uint32 diff)
|
||||||
if (m_corpseDecayTimer <= diff)
|
if (m_corpseDecayTimer <= diff)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(getPetType()!=SUMMON_PET && "Must be already removed.");
|
MANGOS_ASSERT(getPetType()!=SUMMON_PET && "Must be already removed.");
|
||||||
Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
|
Unsummon(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -499,7 +502,7 @@ void Pet::Update(uint32 diff)
|
||||||
Unit* owner = GetOwner();
|
Unit* owner = GetOwner();
|
||||||
if (!owner || (!IsWithinDistInMap(owner, GetMap()->GetVisibilityDistance()) && (!owner->GetCharmGuid().IsEmpty() && (owner->GetCharmGuid() != GetObjectGuid()))) || (isControlled() && owner->GetPetGuid().IsEmpty()))
|
if (!owner || (!IsWithinDistInMap(owner, GetMap()->GetVisibilityDistance()) && (!owner->GetCharmGuid().IsEmpty() && (owner->GetCharmGuid() != GetObjectGuid()))) || (isControlled() && owner->GetPetGuid().IsEmpty()))
|
||||||
{
|
{
|
||||||
Remove(PET_SAVE_NOT_IN_SLOT, true);
|
Unsummon(PET_SAVE_REAGENTS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -507,7 +510,7 @@ void Pet::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
if (owner->GetPetGuid() != GetObjectGuid())
|
if (owner->GetPetGuid() != GetObjectGuid())
|
||||||
{
|
{
|
||||||
Remove(getPetType()==HUNTER_PET?PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT);
|
Unsummon(getPetType() == HUNTER_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT, owner);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -518,7 +521,7 @@ void Pet::Update(uint32 diff)
|
||||||
m_duration -= (int32)diff;
|
m_duration -= (int32)diff;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Remove(getPetType() != SUMMON_PET ? PET_SAVE_AS_DELETED:PET_SAVE_NOT_IN_SLOT);
|
Unsummon(getPetType() != SUMMON_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT, owner);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -656,23 +659,81 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::Remove(PetSaveMode mode, bool returnreagent)
|
void Pet::Unsummon(PetSaveMode mode, Unit* owner /*= NULL*/)
|
||||||
{
|
{
|
||||||
Unit* owner = GetOwner();
|
if (!owner)
|
||||||
|
owner = GetOwner();
|
||||||
|
|
||||||
|
CombatStop();
|
||||||
|
|
||||||
if(owner)
|
if(owner)
|
||||||
{
|
{
|
||||||
if(owner->GetTypeId()==TYPEID_PLAYER)
|
if (GetOwnerGuid() != owner->GetObjectGuid())
|
||||||
{
|
|
||||||
((Player*)owner)->RemovePet(this,mode,returnreagent);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Player* p_owner = owner->GetTypeId()==TYPEID_PLAYER ? (Player*)owner : NULL;
|
||||||
|
|
||||||
|
if (p_owner)
|
||||||
|
{
|
||||||
|
|
||||||
|
// not save secondary permanent pet as current
|
||||||
|
if (mode == PET_SAVE_AS_CURRENT && p_owner->GetTemporaryUnsummonedPetNumber() &&
|
||||||
|
p_owner->GetTemporaryUnsummonedPetNumber() != GetCharmInfo()->GetPetNumber())
|
||||||
|
mode = PET_SAVE_NOT_IN_SLOT;
|
||||||
|
|
||||||
|
if (mode == PET_SAVE_REAGENTS)
|
||||||
|
{
|
||||||
|
//returning of reagents only for players, so best done here
|
||||||
|
uint32 spellId = 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 = p_owner->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellInfo->Reagent[i], spellInfo->ReagentCount[i]);
|
||||||
|
if (msg == EQUIP_ERR_OK)
|
||||||
|
{
|
||||||
|
Item* item = p_owner->StoreNewItem(dest, spellInfo->Reagent[i], true);
|
||||||
|
if (p_owner->IsInWorld())
|
||||||
|
p_owner->SendNewItem(item, spellInfo->ReagentCount[i], true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isControlled())
|
||||||
|
{
|
||||||
|
p_owner->RemovePetActionBar();
|
||||||
|
|
||||||
|
if (p_owner->GetGroup())
|
||||||
|
p_owner->SetGroupUpdateFlag(GROUP_UPDATE_PET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only if current pet in slot
|
// only if current pet in slot
|
||||||
if (owner->GetPetGuid() == GetObjectGuid())
|
switch(getPetType())
|
||||||
owner->SetPet(0);
|
{
|
||||||
|
case MINI_PET:
|
||||||
|
if (p_owner)
|
||||||
|
p_owner->_SetMiniPet(NULL);
|
||||||
|
break;
|
||||||
|
case PROTECTOR_PET:
|
||||||
|
case GUARDIAN_PET:
|
||||||
|
owner->RemoveGuardian(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (owner->GetPetGuid() == GetObjectGuid())
|
||||||
|
owner->SetPet(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SavePetToDB(mode);
|
||||||
AddObjectToRemoveList();
|
AddObjectToRemoveList();
|
||||||
m_removed = true;
|
m_removed = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ enum PetSaveMode
|
||||||
PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
|
PET_SAVE_AS_CURRENT = 0, // in current slot (with player)
|
||||||
PET_SAVE_FIRST_STABLE_SLOT = 1,
|
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_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
|
PET_SAVE_NOT_IN_SLOT = 100, // for avoid conflict with stable size grow will use 100
|
||||||
|
PET_SAVE_REAGENTS = 101 // PET_SAVE_NOT_IN_SLOT with reagents return
|
||||||
};
|
};
|
||||||
|
|
||||||
// There might be a lot more
|
// There might be a lot more
|
||||||
|
|
@ -152,7 +153,7 @@ class Pet : public Creature
|
||||||
bool CreateBaseAtCreature(Creature* creature);
|
bool CreateBaseAtCreature(Creature* creature);
|
||||||
bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
|
bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
|
||||||
void SavePetToDB(PetSaveMode mode);
|
void SavePetToDB(PetSaveMode mode);
|
||||||
void Remove(PetSaveMode mode, bool returnreagent = false);
|
void Unsummon(PetSaveMode mode, Unit* owner = NULL);
|
||||||
static void DeleteFromDB(uint32 guidlow);
|
static void DeleteFromDB(uint32 guidlow);
|
||||||
|
|
||||||
void SetDeathState(DeathState s); // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
|
void SetDeathState(DeathState s); // overwrite virtual Creature::SetDeathState and Unit::SetDeathState
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
Pet* p = (Pet*)pet;
|
Pet* p = (Pet*)pet;
|
||||||
if(p->getPetType() == HUNTER_PET)
|
if(p->getPetType() == HUNTER_PET)
|
||||||
_player->RemovePet(p,PET_SAVE_AS_DELETED);
|
p->Unsummon(PET_SAVE_AS_DELETED, _player);
|
||||||
else
|
else
|
||||||
//dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
|
//dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
|
||||||
p->SetDeathState(CORPSE);
|
p->SetDeathState(CORPSE);
|
||||||
|
|
@ -552,7 +552,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
|
||||||
pet->SetPower(POWER_HAPPINESS ,(feelty-50000) > 0 ?(feelty-50000) : 0);
|
pet->SetPower(POWER_HAPPINESS ,(feelty-50000) > 0 ?(feelty-50000) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_player->RemovePet((Pet*)pet,PET_SAVE_AS_DELETED);
|
((Pet*)pet)->Unsummon(PET_SAVE_AS_DELETED, _player);
|
||||||
}
|
}
|
||||||
else if (pet->GetObjectGuid() == _player->GetCharmGuid())
|
else if (pet->GetObjectGuid() == _player->GetCharmGuid())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -577,7 +577,6 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
|
||||||
m_summon_y = 0.0f;
|
m_summon_y = 0.0f;
|
||||||
m_summon_z = 0.0f;
|
m_summon_z = 0.0f;
|
||||||
|
|
||||||
m_miniPet = 0;
|
|
||||||
m_contestedPvPTimer = 0;
|
m_contestedPvPTimer = 0;
|
||||||
|
|
||||||
m_declinedname = NULL;
|
m_declinedname = NULL;
|
||||||
|
|
@ -1463,9 +1462,7 @@ void Player::Update( uint32 p_time )
|
||||||
|
|
||||||
Pet* pet = GetPet();
|
Pet* pet = GetPet();
|
||||||
if (pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityDistance()) && (!GetCharmGuid().IsEmpty() && (pet->GetObjectGuid() != GetCharmGuid())))
|
if (pet && !pet->IsWithinDistInMap(this, GetMap()->GetVisibilityDistance()) && (!GetCharmGuid().IsEmpty() && (pet->GetObjectGuid() != GetCharmGuid())))
|
||||||
{
|
pet->Unsummon(PET_SAVE_REAGENTS, this);
|
||||||
RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsHasDelayedTeleport())
|
if (IsHasDelayedTeleport())
|
||||||
TeleportTo(m_teleport_dest, m_teleport_options);
|
TeleportTo(m_teleport_dest, m_teleport_options);
|
||||||
|
|
@ -1490,7 +1487,7 @@ void Player::SetDeathState(DeathState s)
|
||||||
RemoveAurasDueToSpell(m_ShapeShiftFormSpellId);
|
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)
|
//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
|
// remove uncontrolled pets
|
||||||
RemoveMiniPet();
|
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
|
//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
|
/* when prev line will dropped use next line
|
||||||
if(Pet* pet = GetPet())
|
if(Pet* pet = GetPet())
|
||||||
{
|
{
|
||||||
if(pet->getPetType()==HUNTER_PET && !pet->GetCreatureInfo()->isTameable(CanTameExoticPets()))
|
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;
|
return true;
|
||||||
|
|
@ -17773,90 +17770,24 @@ void Player::UpdateDuelFlag(time_t currTime)
|
||||||
duel->opponent->duel->startTime = currTime;
|
duel->opponent->duel->startTime = currTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
void Player::RemovePet(PetSaveMode mode)
|
||||||
{
|
{
|
||||||
if (!pet)
|
if (Pet* pet = GetPet())
|
||||||
pet = GetPet();
|
pet->Unsummon(mode, this);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::RemoveMiniPet()
|
void Player::RemoveMiniPet()
|
||||||
{
|
{
|
||||||
if (Pet* pet = GetMiniPet())
|
if (Pet* pet = GetMiniPet())
|
||||||
{
|
pet->Unsummon(PET_SAVE_AS_DELETED);
|
||||||
pet->Remove(PET_SAVE_AS_DELETED);
|
|
||||||
m_miniPet = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pet* Player::GetMiniPet() const
|
Pet* Player::GetMiniPet() const
|
||||||
{
|
{
|
||||||
if (!m_miniPet)
|
if (m_miniPetGuid.IsEmpty())
|
||||||
return NULL;
|
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
|
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)
|
inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
|
||||||
{
|
{
|
||||||
if (p->GetPetGuid() == t->GetObjectGuid() && ((Creature*)t)->IsPet())
|
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)
|
void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* target)
|
||||||
|
|
@ -21834,7 +21765,7 @@ void Player::UnsummonPetTemporaryIfAny()
|
||||||
if(!m_temporaryUnsummonedPetNumber && pet->isControlled() && !pet->isTemporarySummoned() )
|
if(!m_temporaryUnsummonedPetNumber && pet->isControlled() && !pet->isTemporarySummoned() )
|
||||||
m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber();
|
m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber();
|
||||||
|
|
||||||
RemovePet(pet, PET_SAVE_AS_CURRENT);
|
pet->Unsummon(PET_SAVE_AS_CURRENT, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::ResummonPetTemporaryUnSummonedIfAny()
|
void Player::ResummonPetTemporaryUnSummonedIfAny()
|
||||||
|
|
|
||||||
|
|
@ -1213,10 +1213,12 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
time_t GetTimeInnEnter() const { return time_inn_enter; }
|
time_t GetTimeInnEnter() const { return time_inn_enter; }
|
||||||
void UpdateInnerTime (time_t time) { time_inn_enter = time; }
|
void UpdateInnerTime (time_t time) { time_inn_enter = time; }
|
||||||
|
|
||||||
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
void RemovePet(PetSaveMode mode);
|
||||||
void RemoveMiniPet();
|
void RemoveMiniPet();
|
||||||
Pet* GetMiniPet() const;
|
Pet* GetMiniPet() const;
|
||||||
void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); }
|
|
||||||
|
// use only in Pet::Unsummon/Spell::DoSummon
|
||||||
|
void _SetMiniPet(Pet* pet) { m_miniPetGuid = pet ? pet->GetObjectGuid() : ObjectGuid(); }
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
void CallForAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet);
|
void CallForAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet);
|
||||||
|
|
@ -2624,7 +2626,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
uint32 m_groupUpdateMask;
|
uint32 m_groupUpdateMask;
|
||||||
uint64 m_auraUpdateMask;
|
uint64 m_auraUpdateMask;
|
||||||
|
|
||||||
uint64 m_miniPet;
|
ObjectGuid m_miniPetGuid;
|
||||||
|
|
||||||
// Player summoning
|
// Player summoning
|
||||||
time_t m_summon_expire;
|
time_t m_summon_expire;
|
||||||
|
|
|
||||||
|
|
@ -2430,7 +2430,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
if (apply)
|
if (apply)
|
||||||
owner->CastSpell(owner, 8985, true);
|
owner->CastSpell(owner, 8985, true);
|
||||||
else
|
else
|
||||||
((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
|
((Player*)owner)->RemovePet(PET_SAVE_REAGENTS);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2446,7 +2446,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
if (apply)
|
if (apply)
|
||||||
owner->CastSpell(owner, 19704, true);
|
owner->CastSpell(owner, 19704, true);
|
||||||
else
|
else
|
||||||
((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
|
((Player*)owner)->RemovePet(PET_SAVE_REAGENTS);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3595,7 +3595,7 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
|
||||||
// out of range pet dismissed
|
// out of range pet dismissed
|
||||||
if (!pet->IsWithinDistInMap(p_caster, pet->GetMap()->GetVisibilityDistance()))
|
if (!pet->IsWithinDistInMap(p_caster, pet->GetMap()->GetVisibilityDistance()))
|
||||||
{
|
{
|
||||||
pet->Remove(PET_SAVE_NOT_IN_SLOT, true);
|
p_caster->RemovePet(PET_SAVE_REAGENTS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -7595,24 +7595,23 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real)
|
||||||
return;
|
return;
|
||||||
Vehicle* vehicle = (Vehicle*)target;
|
Vehicle* vehicle = (Vehicle*)target;
|
||||||
|
|
||||||
Unit *player = GetCaster();
|
Unit *caster = GetCaster();
|
||||||
if(!player || player->GetTypeId() != TYPEID_PLAYER)
|
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
if(Pet *pet = player->GetPet())
|
((Player*)caster)->RemovePet(PET_SAVE_AS_CURRENT);
|
||||||
pet->Remove(PET_SAVE_AS_CURRENT);
|
((Player*)caster)->EnterVehicle(vehicle);
|
||||||
((Player*)player)->EnterVehicle(vehicle);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SpellEntry const *spell = GetSpellProto();
|
SpellEntry const *spell = GetSpellProto();
|
||||||
|
|
||||||
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
|
// some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
|
||||||
player->RemoveAurasDueToSpell(spell->Id);
|
caster->RemoveAurasDueToSpell(spell->Id);
|
||||||
|
|
||||||
((Player*)player)->ExitVehicle(vehicle);
|
((Player*)caster)->ExitVehicle(vehicle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4590,6 +4590,25 @@ void Spell::DoSummonGuardian(SpellEffectIndex eff_idx, uint32 forceFaction)
|
||||||
if (!propEntry)
|
if (!propEntry)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
PetType petType = propEntry->Title == UNITNAME_SUMMON_TITLE_COMPANION ? PROTECTOR_PET : GUARDIAN_PET;
|
||||||
|
|
||||||
|
// protectors allowed only in single amount
|
||||||
|
if (petType == PROTECTOR_PET)
|
||||||
|
{
|
||||||
|
Pet* old_protector = m_caster->GetProtectorPet();
|
||||||
|
|
||||||
|
// for same pet just despawn
|
||||||
|
if (old_protector && old_protector->GetEntry() == pet_entry)
|
||||||
|
{
|
||||||
|
old_protector->Unsummon(PET_SAVE_AS_DELETED, m_caster);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// despawn old pet before summon new
|
||||||
|
if (old_protector)
|
||||||
|
old_protector->Unsummon(PET_SAVE_AS_DELETED, m_caster);
|
||||||
|
}
|
||||||
|
|
||||||
// in another case summon new
|
// in another case summon new
|
||||||
uint32 level = m_caster->getLevel();
|
uint32 level = m_caster->getLevel();
|
||||||
|
|
||||||
|
|
@ -4621,7 +4640,7 @@ void Spell::DoSummonGuardian(SpellEffectIndex eff_idx, uint32 forceFaction)
|
||||||
|
|
||||||
for(int32 count = 0; count < amount; ++count)
|
for(int32 count = 0; count < amount; ++count)
|
||||||
{
|
{
|
||||||
Pet* spawnCreature = new Pet(propEntry->Title == UNITNAME_SUMMON_TITLE_COMPANION ? PROTECTOR_PET : GUARDIAN_PET);
|
Pet* spawnCreature = new Pet(petType);
|
||||||
|
|
||||||
Map *map = m_caster->GetMap();
|
Map *map = m_caster->GetMap();
|
||||||
uint32 pet_number = sObjectMgr.GeneratePetNumber();
|
uint32 pet_number = sObjectMgr.GeneratePetNumber();
|
||||||
|
|
@ -5039,7 +5058,7 @@ void Spell::EffectSummonPet(SpellEffectIndex eff_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
((Player*)m_caster)->RemovePet(OldSummon,(OldSummon->getPetType()==HUNTER_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT),false);
|
OldSummon->Unsummon(OldSummon->getPetType() == HUNTER_PET ? PET_SAVE_AS_DELETED : PET_SAVE_NOT_IN_SLOT, m_caster);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -5051,7 +5070,7 @@ void Spell::EffectSummonPet(SpellEffectIndex eff_idx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// not error in case fail hunter call pet
|
// not error in case fail hunter call pet
|
||||||
if(!petentry)
|
if (!petentry)
|
||||||
{
|
{
|
||||||
delete NewSummon;
|
delete NewSummon;
|
||||||
return;
|
return;
|
||||||
|
|
@ -6194,7 +6213,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
||||||
{
|
{
|
||||||
// Is this all to be done at completion?
|
// Is this all to be done at completion?
|
||||||
if (Pet* pPet = m_caster->FindGuardianWithEntry(pSpell->EffectMiscValue[EFFECT_INDEX_0]))
|
if (Pet* pPet = m_caster->FindGuardianWithEntry(pSpell->EffectMiscValue[EFFECT_INDEX_0]))
|
||||||
((Player*)m_caster)->RemovePet(pPet, PET_SAVE_NOT_IN_SLOT);
|
pPet->Unsummon(PET_SAVE_NOT_IN_SLOT, m_caster);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -7224,7 +7243,7 @@ void Spell::EffectDismissPet(SpellEffectIndex /*eff_idx*/)
|
||||||
if(!pet||!pet->isAlive())
|
if(!pet||!pet->isAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((Player*)m_caster)->RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
|
pet->Unsummon(PET_SAVE_NOT_IN_SLOT, m_caster);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectSummonObject(SpellEffectIndex eff_idx)
|
void Spell::EffectSummonObject(SpellEffectIndex eff_idx)
|
||||||
|
|
@ -7602,7 +7621,7 @@ void Spell::DoSummonCritter(SpellEffectIndex eff_idx, uint32 forceFaction)
|
||||||
if(duration > 0)
|
if(duration > 0)
|
||||||
critter->SetDuration(duration);
|
critter->SetDuration(duration);
|
||||||
|
|
||||||
player->SetMiniPet(critter);
|
player->_SetMiniPet(critter);
|
||||||
|
|
||||||
map->Add((Creature*)critter);
|
map->Add((Creature*)critter);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5901,7 +5901,7 @@ void Unit::RemoveGuardians()
|
||||||
{
|
{
|
||||||
uint64 guid = *m_guardianPets.begin();
|
uint64 guid = *m_guardianPets.begin();
|
||||||
if(Pet* pet = GetMap()->GetPet(guid))
|
if(Pet* pet = GetMap()->GetPet(guid))
|
||||||
pet->Remove(PET_SAVE_AS_DELETED);
|
pet->Unsummon(PET_SAVE_AS_DELETED, this);
|
||||||
|
|
||||||
m_guardianPets.erase(guid);
|
m_guardianPets.erase(guid);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -391,7 +391,7 @@ void WorldSession::LogoutPlayer(bool Save)
|
||||||
}
|
}
|
||||||
|
|
||||||
///- Remove pet
|
///- Remove pet
|
||||||
_player->RemovePet(NULL, PET_SAVE_AS_CURRENT, true);
|
_player->RemovePet(PET_SAVE_AS_CURRENT);
|
||||||
|
|
||||||
///- empty buyback items and save the player in the database
|
///- empty buyback items and save the player in the database
|
||||||
// some save parts only correctly work in case player present in map/player_lists (pets, etc)
|
// some save parts only correctly work in case player present in map/player_lists (pets, etc)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10738"
|
#define REVISION_NR "10739"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue