diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/BattleGround.cpp | 26 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 5 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 9 | ||||
-rw-r--r-- | src/game/NPCHandler.cpp | 5 | ||||
-rw-r--r-- | src/game/Pet.cpp | 59 | ||||
-rw-r--r-- | src/game/Player.cpp | 67 | ||||
-rw-r--r-- | src/game/Player.h | 5 | ||||
-rw-r--r-- | src/game/Unit.cpp | 21 |
8 files changed, 103 insertions, 94 deletions
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index b3f74457063..fffedb56ad8 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -951,15 +951,9 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) - // summon old pet if there was one and there isn't a current pet - if(!plr->GetGuardianPet() && plr->GetTemporaryUnsummonedPetNumber()) - { - Pet* NewPet = new Pet(plr); - if(!NewPet->LoadPetFromDB(plr, 0, (plr)->GetTemporaryUnsummonedPetNumber(), true)) - delete NewPet; - - (plr)->SetTemporaryUnsummonedPetNumber(0); - } + // 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->ResummonPetTemporaryUnSummonedIfAny(); if (isRated() && GetStatus() == STATUS_IN_PROGRESS) { @@ -1113,19 +1107,7 @@ void BattleGround::AddPlayer(Player *plr) } plr->DestroyConjuredItems(true); - - Pet* pet = plr->GetPet(); - if (pet) - { - if (pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET) - { - (plr)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber()); - (plr)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL)); - } - (plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT); - } - else - (plr)->SetTemporaryUnsummonedPetNumber(0); + plr->UnsummonPetTemporaryIfAny(); if(GetStatus() == STATUS_WAIT_JOIN) // not started yet { diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 5cd9c8f191c..a2e189603f9 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -814,9 +814,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) SendDoFlight( MountId, path, startNode ); } - // Load pet if any and player is alive and not in taxi flight - if(pCurrChar->isAlive() && pCurrChar->m_taxi.GetTaxiSource()==0) - pCurrChar->LoadPet(); + // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) + pCurrChar->LoadPet(); // Set FFA PvP for non GM in non-rest mode if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 560fb4d651e..b88a67d782f 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -157,14 +157,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet - if(GetPlayer()->m_temporaryUnsummonedPetNumber) - { - Pet* NewPet = new Pet(GetPlayer()); - if(!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true)) - delete NewPet; - - GetPlayer()->m_temporaryUnsummonedPetNumber = 0; - } + GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); GetPlayer()->SetDontMove(false); } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 94a8c03ab24..8d1427c86b8 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -611,12 +611,13 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) // 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; } - delete result; if( free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots) { diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index dba79a47a72..e723298565a 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -99,17 +99,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 " @@ -129,7 +129,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; @@ -141,16 +141,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; @@ -159,7 +167,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool float px, py, pz; owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); 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()); @@ -172,14 +181,14 @@ 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) { map->Add((Creature*)this); delete result; 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); @@ -204,7 +213,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(); @@ -260,12 +269,12 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool _LoadSpells(); _LoadSpellCooldowns(); - 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; @@ -345,13 +354,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()) + 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); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4bf93b3ea70..01ca893b6e3 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1683,16 +1683,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //SendMessageToSet(&data, true); if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { - //same map, only remove pet if out of range - if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE)) - { - if(pet->isControlled() && !pet->isTemporarySummoned() ) - m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber(); - else - m_temporaryUnsummonedPetNumber = 0; - - RemovePet(pet, PET_SAVE_NOT_IN_SLOT); - } + //same map, only remove pet if out of range for new position + if(pet && pet->GetDistance(x,y,z) >= OWNER_MAX_DISTANCE) + UnsummonPetTemporaryIfAny(); } if(!(options & TELE_TO_NOT_LEAVE_COMBAT)) @@ -1701,14 +1694,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { // resummon pet - if(pet && m_temporaryUnsummonedPetNumber) - { - Pet* NewPet = new Pet(this); - if(!NewPet->LoadPetFromDB(this, 0, m_temporaryUnsummonedPetNumber, true)) - delete NewPet; - - m_temporaryUnsummonedPetNumber = 0; - } + if (pet) + ResummonPetTemporaryUnSummonedIfAny(); } uint32 newzone, newarea; @@ -1767,15 +1754,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // remove pet on map change if (pet) - { - //leaving map -> delete pet right away (doing this later will cause problems) - if(pet->isControlled() && !pet->isTemporarySummoned()) - m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber(); - else - m_temporaryUnsummonedPetNumber = 0; - - RemovePet(pet, PET_SAVE_NOT_IN_SLOT); - } + UnsummonPetTemporaryIfAny(); // remove all dyn objects RemoveAllDynObjects(); @@ -20485,3 +20464,37 @@ void Player::UpdateFallInformationIfNeed( MovementInfo const& minfo,uint16 opcod if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <=minfo.z || opcode == MSG_MOVE_FALL_LAND) SetFallInformation(minfo.fallTime, minfo.z); } + +void Player::UnsummonPetTemporaryIfAny() +{ + Pet* pet = GetPet(); + if(!pet) + return; + + if(!m_temporaryUnsummonedPetNumber && pet->isControlled() && !pet->isTemporarySummoned() ) + { + m_temporaryUnsummonedPetNumber = pet->GetCharmInfo()->GetPetNumber(); + m_oldpetspell = pet->GetUInt32Value(UNIT_CREATED_BY_SPELL); + } + + RemovePet(pet, PET_SAVE_AS_CURRENT); +} + +void Player::ResummonPetTemporaryUnSummonedIfAny() +{ + if(!m_temporaryUnsummonedPetNumber) + return; + + // not resummon in not appropriate state + if(IsPetNeedBeTemporaryUnsummoned()) + return; + + if(GetPetGUID()) + return; + + Pet* NewPet = new Pet(this); + if(!NewPet->LoadPetFromDB(this, 0, m_temporaryUnsummonedPetNumber, true)) + delete NewPet; + + m_temporaryUnsummonedPetNumber = 0; +} diff --git a/src/game/Player.h b/src/game/Player.h index 4738ce603a0..1c2f7db6505 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1998,8 +1998,9 @@ class TRINITY_DLL_SPEC Player : public Unit // Temporarily removed pet cache uint32 GetTemporaryUnsummonedPetNumber() const { return m_temporaryUnsummonedPetNumber; } void SetTemporaryUnsummonedPetNumber(uint32 petnumber) { m_temporaryUnsummonedPetNumber = petnumber; } - uint32 GetOldPetSpell() const { return m_oldpetspell; } - void SetOldPetSpell(uint32 petspell) { m_oldpetspell = petspell; } + void UnsummonPetTemporaryIfAny(); + void ResummonPetTemporaryUnSummonedIfAny(); + bool IsPetNeedBeTemporaryUnsummoned() const { return !IsInWorld() || !isAlive() || IsMounted() /*+in flight*/; } void SendCinematicStart(uint32 CinematicSequenceId); void SendMovieStart(uint32 MovieId); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 88155b4be51..4932887d2d9 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9537,21 +9537,7 @@ void Unit::Mount(uint32 mount) // unsummon pet if(GetTypeId() == TYPEID_PLAYER) - { - Pet* pet = ((Player*)this)->GetPet(); - if(pet) - { - if(pet->isControlled()) - { - ((Player*)this)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber()); - ((Player*)this)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL)); - } - - ((Player*)this)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT); - } - else - ((Player*)this)->SetTemporaryUnsummonedPetNumber(0); - } + ((Player*)this)->UnsummonPetTemporaryIfAny(); } void Unit::Unmount() @@ -9567,6 +9553,7 @@ void Unit::Unmount() // only resummon old pet if the player is already added to a map // this prevents adding a pet to a not created map which would otherwise cause a crash // (it could probably happen when logging in after a previous crash) +<<<<<<< HEAD:src/game/Unit.cpp if(GetTypeId() == TYPEID_PLAYER && IsInWorld() && ((Player*)this)->GetTemporaryUnsummonedPetNumber() && isAlive()) { Pet* NewPet = new Pet((Player*)this); @@ -9575,6 +9562,10 @@ void Unit::Unmount() ((Player*)this)->SetTemporaryUnsummonedPetNumber(0); } +======= + if(GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->ResummonPetTemporaryUnSummonedIfAny(); +>>>>>>> 661760f287d94dbbe8f5224b19ba4181c7d62910:src/game/Unit.cpp } void Unit::SetInCombatWith(Unit* enemy) |