diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-01-02 14:04:09 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-01-02 14:04:09 +0100 |
commit | ea6de0b565944520570f0723dae35d350b7b96ac (patch) | |
tree | 5350be540a71413f09566c9c5bdd4cba24f748bc | |
parent | 9f94941a3e146897617d4b097018dc871eaba374 (diff) |
Core/BattlePets: Misc fixes
* Fixed caged pet item chat message
* BattlePetMgr optimizations: removed copying data all over the place
* Fixed gaining two pets when learned from item for the first time
* Fixed dismiss button
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.cpp | 70 | ||||
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.h | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/BattlePetHandler.cpp | 15 | ||||
-rw-r--r-- | src/server/game/Server/Packets/BattlePetPackets.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/BattlePetPackets.h | 10 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 26 |
10 files changed, 72 insertions, 71 deletions
diff --git a/src/server/game/BattlePets/BattlePetMgr.cpp b/src/server/game/BattlePets/BattlePetMgr.cpp index a1f0685186a..66f792b1b40 100644 --- a/src/server/game/BattlePets/BattlePetMgr.cpp +++ b/src/server/game/BattlePets/BattlePetMgr.cpp @@ -303,11 +303,7 @@ void BattlePetMgr::SaveToDB(SQLTransaction& trans) BattlePetMgr::BattlePet* BattlePetMgr::GetPet(ObjectGuid guid) { - auto itr = _pets.find(guid.GetCounter()); - if (itr != _pets.end()) - return &itr->second; - - return nullptr; + return Trinity::Containers::MapGetValuePtr(_pets, guid.GetCounter()); } void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 quality, uint16 level /*= 1*/) @@ -332,9 +328,9 @@ void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 _pets[pet.PacketInfo.Guid.GetCounter()] = pet; - std::vector<BattlePet> updates; - updates.push_back(pet); - SendUpdates(updates, true); + std::vector<std::reference_wrapper<BattlePet>> updates; + updates.push_back(std::ref(pet)); + SendUpdates(std::move(updates), true); _owner->GetPlayer()->UpdateCriteria(CRITERIA_TYPE_OWN_BATTLE_PET, species); } @@ -355,12 +351,10 @@ void BattlePetMgr::RemovePet(ObjectGuid guid) uint8 BattlePetMgr::GetPetCount(uint32 species) const { - uint8 count = 0; - for (auto& itr : _pets) - if (itr.second.PacketInfo.Species == species && itr.second.SaveInfo != BATTLE_PET_REMOVED) - count++; - - return count; + return uint8(std::count_if(_pets.begin(), _pets.end(), [species](std::pair<uint64 const, BattlePet> const& pet) + { + return pet.second.PacketInfo.Species == species && pet.second.SaveInfo != BATTLE_PET_REMOVED; + })); } void BattlePetMgr::UnlockSlot(uint8 slot) @@ -377,14 +371,14 @@ void BattlePetMgr::UnlockSlot(uint8 slot) _owner->SendPacket(updates.Write()); } -std::vector<BattlePetMgr::BattlePet> BattlePetMgr::GetLearnedPets() const +uint16 BattlePetMgr::GetMaxPetLevel() const { - std::vector<BattlePet> pets; + uint16 level = 0; for (auto& pet : _pets) if (pet.second.SaveInfo != BATTLE_PET_REMOVED) - pets.push_back(pet.second); + level = std::max(level, pet.second.PacketInfo.Level); - return pets; + return level; } void BattlePetMgr::CageBattlePet(ObjectGuid guid) @@ -408,7 +402,7 @@ void BattlePetMgr::CageBattlePet(ObjectGuid guid) item->SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, pet->PacketInfo.CreatureID); // FIXME: "You create: ." - item name missing in chat - _owner->GetPlayer()->SendNewItem(item, 1, true, true); + _owner->GetPlayer()->SendNewItem(item, 1, true, false); RemovePet(guid); @@ -421,7 +415,7 @@ void BattlePetMgr::HealBattlePetsPct(uint8 pct) { // TODO: After each Pet Battle, any injured companion will automatically // regain 50 % of the damage that was taken during combat - std::vector<BattlePet> updates; + std::vector<std::reference_wrapper<BattlePet>> updates; for (auto& pet : _pets) if (pet.second.PacketInfo.Health != pet.second.PacketInfo.MaxHealth) @@ -431,10 +425,10 @@ void BattlePetMgr::HealBattlePetsPct(uint8 pct) pet.second.PacketInfo.Health = std::min(pet.second.PacketInfo.Health, pet.second.PacketInfo.MaxHealth); if (pet.second.SaveInfo != BATTLE_PET_NEW) pet.second.SaveInfo = BATTLE_PET_CHANGED; - updates.push_back(pet.second); + updates.push_back(std::ref(pet.second)); } - SendUpdates(updates, false); + SendUpdates(std::move(updates), false); } void BattlePetMgr::SummonPet(ObjectGuid guid) @@ -448,16 +442,42 @@ void BattlePetMgr::SummonPet(ObjectGuid guid) return; // TODO: set proper CreatureID for spell DEFAULT_SUMMON_BATTLE_PET_SPELL (default EffectMiscValueA is 40721 - Murkimus the Gladiator) + _owner->GetPlayer()->SetGuidValue(PLAYER_FIELD_SUMMONED_BATTLE_PET_ID, guid); _owner->GetPlayer()->CastSpell(_owner->GetPlayer(), speciesEntry->SummonSpellID ? speciesEntry->SummonSpellID : uint32(DEFAULT_SUMMON_BATTLE_PET_SPELL)); // TODO: set pet level, quality... update fields } -void BattlePetMgr::SendUpdates(std::vector<BattlePet> pets, bool petAdded) +void BattlePetMgr::DismissPet() +{ + Player* ownerPlayer = _owner->GetPlayer(); + Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*ownerPlayer, ownerPlayer->GetCritterGUID()); + if (pet && ownerPlayer->GetGuidValue(PLAYER_FIELD_SUMMONED_BATTLE_PET_ID) == pet->GetGuidValue(UNIT_FIELD_BATTLE_PET_COMPANION_GUID)) + { + pet->DespawnOrUnsummon(); + ownerPlayer->SetGuidValue(PLAYER_FIELD_SUMMONED_BATTLE_PET_ID, ObjectGuid::Empty); + } +} + +void BattlePetMgr::SendJournal() +{ + WorldPackets::BattlePet::BattlePetJournal battlePetJournal; + battlePetJournal.Trap = _trapLevel; + + for (auto& pet : _pets) + if (pet.second.SaveInfo != BATTLE_PET_REMOVED) + battlePetJournal.Pets.push_back(std::ref(pet.second.PacketInfo)); + + battlePetJournal.Slots.reserve(_slots.size()); + std::transform(_slots.begin(), _slots.end(), std::back_inserter(battlePetJournal.Slots), [](WorldPackets::BattlePet::BattlePetSlot& slot) { return std::ref(slot); }); + _owner->SendPacket(battlePetJournal.Write()); +} + +void BattlePetMgr::SendUpdates(std::vector<std::reference_wrapper<BattlePet>> pets, bool petAdded) { WorldPackets::BattlePet::BattlePetUpdates updates; - for (auto pet : pets) - updates.Pets.push_back(pet.PacketInfo); + for (BattlePet& pet : pets) + updates.Pets.push_back(std::ref(pet.PacketInfo)); updates.PetAdded = petAdded; _owner->SendPacket(updates.Write()); diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h index 130a2814bdb..f4a6697a4c2 100644 --- a/src/server/game/BattlePets/BattlePetMgr.h +++ b/src/server/game/BattlePets/BattlePetMgr.h @@ -121,15 +121,17 @@ public: WorldSession* GetOwner() const { return _owner; } uint16 GetTrapLevel() const { return _trapLevel; } - std::vector<BattlePet> GetLearnedPets() const; - std::vector<WorldPackets::BattlePet::BattlePetSlot> GetSlots() const { return _slots; } + uint16 GetMaxPetLevel() const; + std::vector<WorldPackets::BattlePet::BattlePetSlot> const& GetSlots() const { return _slots; } void CageBattlePet(ObjectGuid guid); void HealBattlePetsPct(uint8 pct); void SummonPet(ObjectGuid guid); + void DismissPet(); - void SendUpdates(std::vector<BattlePet> pets, bool petAdded); + void SendJournal(); + void SendUpdates(std::vector<std::reference_wrapper<BattlePet>> pets, bool petAdded); void SendError(BattlePetError error, uint32 creatureId); private: diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 02b72993c6b..d8bf94c7cb1 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14060,9 +14060,9 @@ void Player::SendNewItem(Item* item, uint32 quantity, bool pushed, bool created, packet.Quantity = quantity; packet.QuantityInInventory = GetItemCount(item->GetEntry()); //packet.DungeonEncounterID; + packet.BattlePetSpeciesID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID); packet.BattlePetBreedID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) & 0xFFFFFF; packet.BattlePetBreedQuality = (item->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) >> 24) & 0xFF; - packet.BattlePetSpeciesID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID); packet.BattlePetLevel = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL); packet.ItemGUID = item->GetGUID(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 64c9153a65d..e3b4958b330 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5907,7 +5907,11 @@ void Unit::SetMinion(Minion *minion, bool apply) } if (minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET) + { SetCritterGUID(minion->GetGUID()); + if (GetTypeId() == TYPEID_PLAYER) + minion->SetGuidValue(UNIT_FIELD_BATTLE_PET_COMPANION_GUID, GetGuidValue(PLAYER_FIELD_SUMMONED_BATTLE_PET_ID)); + } // PvP, FFAPvP minion->SetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG)); diff --git a/src/server/game/Handlers/BattlePetHandler.cpp b/src/server/game/Handlers/BattlePetHandler.cpp index f3886aa51c4..295b0c52a4d 100644 --- a/src/server/game/Handlers/BattlePetHandler.cpp +++ b/src/server/game/Handlers/BattlePetHandler.cpp @@ -22,15 +22,7 @@ void WorldSession::HandleBattlePetRequestJournal(WorldPackets::BattlePet::BattlePetRequestJournal& /*battlePetRequestJournal*/) { - // TODO: Move this to BattlePetMgr::SendJournal() just to have all packets in one file - WorldPackets::BattlePet::BattlePetJournal battlePetJournal; - battlePetJournal.Trap = GetBattlePetMgr()->GetTrapLevel(); - - for (auto itr : GetBattlePetMgr()->GetLearnedPets()) - battlePetJournal.Pets.push_back(itr.PacketInfo); - - battlePetJournal.Slots = GetBattlePetMgr()->GetSlots(); - SendPacket(battlePetJournal.Write()); + GetBattlePetMgr()->SendJournal(); } void WorldSession::HandleBattlePetSetBattleSlot(WorldPackets::BattlePet::BattlePetSetBattleSlot& battlePetSetBattleSlot) @@ -76,5 +68,8 @@ void WorldSession::HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& c void WorldSession::HandleBattlePetSummon(WorldPackets::BattlePet::BattlePetSummon& battlePetSummon) { - GetBattlePetMgr()->SummonPet(battlePetSummon.PetGuid); + if (_player->GetGuidValue(PLAYER_FIELD_SUMMONED_BATTLE_PET_ID) != battlePetSummon.PetGuid) + GetBattlePetMgr()->SummonPet(battlePetSummon.PetGuid); + else + GetBattlePetMgr()->DismissPet(); } diff --git a/src/server/game/Server/Packets/BattlePetPackets.cpp b/src/server/game/Server/Packets/BattlePetPackets.cpp index 277d3f9f7ff..0c0419b7c4f 100644 --- a/src/server/game/Server/Packets/BattlePetPackets.cpp +++ b/src/server/game/Server/Packets/BattlePetPackets.cpp @@ -69,10 +69,10 @@ WorldPacket const* WorldPackets::BattlePet::BattlePetJournal::Write() _worldPacket.WriteBit(HasJournalLock); _worldPacket.FlushBits(); - for (auto const& slot : Slots) + for (BattlePetSlot const& slot : Slots) _worldPacket << slot; - for (auto const& pet : Pets) + for (BattlePet const& pet : Pets) _worldPacket << pet; return &_worldPacket; diff --git a/src/server/game/Server/Packets/BattlePetPackets.h b/src/server/game/Server/Packets/BattlePetPackets.h index 89d698c9290..2686414b1bc 100644 --- a/src/server/game/Server/Packets/BattlePetPackets.h +++ b/src/server/game/Server/Packets/BattlePetPackets.h @@ -39,7 +39,7 @@ namespace WorldPackets ObjectGuid Guid; uint32 Species = 0; uint32 CreatureID = 0; - uint32 CollarID = 0; // what's this? + uint32 CollarID = 0; uint16 Breed = 0; uint16 Level = 0; uint16 Exp = 0; @@ -56,7 +56,7 @@ namespace WorldPackets struct BattlePetSlot { BattlePet Pet; - uint32 CollarID = 0; // what's this? + uint32 CollarID = 0; uint8 Index = 0; bool Locked = true; }; @@ -70,8 +70,8 @@ namespace WorldPackets uint16 Trap = 0; bool HasJournalLock = true; - std::vector<BattlePetSlot> Slots; - std::vector<BattlePet> Pets; + std::vector<std::reference_wrapper<BattlePetSlot>> Slots; + std::vector<std::reference_wrapper<BattlePet>> Pets; int32 MaxPets = 1000; }; @@ -98,7 +98,7 @@ namespace WorldPackets WorldPacket const* Write() override; - std::vector<BattlePet> Pets; + std::vector<std::reference_wrapper<BattlePet>> Pets; bool PetAdded = false; }; diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index 5c43b1a704e..87599873de5 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -254,8 +254,8 @@ WorldPacket const* WorldPackets::Item::ItemPushResult::Write() _worldPacket << int32(Quantity); _worldPacket << int32(QuantityInInventory); _worldPacket << int32(DungeonEncounterID); - _worldPacket << int32(BattlePetBreedID); _worldPacket << int32(BattlePetSpeciesID); + _worldPacket << int32(BattlePetBreedID); _worldPacket << uint32(BattlePetBreedQuality); _worldPacket << int32(BattlePetLevel); _worldPacket << ItemGUID; diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h index a889a7dd1ed..d1558755fc2 100644 --- a/src/server/game/Server/Packets/ItemPackets.h +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -347,9 +347,9 @@ namespace WorldPackets int32 Quantity = 0; int32 QuantityInInventory = 0; int32 DungeonEncounterID = 0; + int32 BattlePetSpeciesID = 0; int32 BattlePetBreedID = 0; uint32 BattlePetBreedQuality = 0; - int32 BattlePetSpeciesID = 0; int32 BattlePetLevel = 0; ObjectGuid ItemGUID; bool Pushed = false; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index eeb4936ec04..b373d48fa19 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2161,22 +2161,6 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex) uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : effectInfo->TriggerSpell; player->LearnSpell(spellToLearn, false); - if (m_spellInfo->Id == 55884) - { - if (BattlePetMgr* battlePetMgr = player->GetSession()->GetBattlePetMgr()) - { - for (auto entry : sBattlePetSpeciesStore) - { - if (entry->SummonSpellID == spellToLearn) - { - battlePetMgr->AddPet(entry->ID, entry->CreatureID, BattlePetMgr::RollPetBreed(entry->ID), BattlePetMgr::GetDefaultPetQuality(entry->ID)); - player->UpdateCriteria(CRITERIA_TYPE_OWN_BATTLE_PET_COUNT); - break; - } - } - } - } - TC_LOG_DEBUG("spells", "Spell: %s has learned spell %u from %s", player->GetGUID().ToString().c_str(), spellToLearn, m_caster->GetGUID().ToString().c_str()); } @@ -5705,14 +5689,9 @@ void Spell::EffectUncageBattlePet(SpellEffIndex /*effIndex*/) if (!battlePetMgr) return; - uint16 maxLearnedLevel = 0; - - for (auto pet : battlePetMgr->GetLearnedPets()) - maxLearnedLevel = std::max(pet.PacketInfo.Level, maxLearnedLevel); - // TODO: This means if you put your highest lvl pet into cage, you won't be able to uncage it again which is probably wrong. // We will need to store maxLearnedLevel somewhere to avoid this behaviour. - if (maxLearnedLevel < level) + if (battlePetMgr->GetMaxPetLevel() < level) { battlePetMgr->SendError(BATTLEPETRESULT_TOO_HIGH_LEVEL_TO_UNCAGE, creatureId); // or speciesEntry.CreatureID SendCastResult(SPELL_FAILED_CANT_ADD_BATTLE_PET); @@ -5726,10 +5705,11 @@ void Spell::EffectUncageBattlePet(SpellEffIndex /*effIndex*/) return; } + battlePetMgr->AddPet(speciesId, creatureId, breed, quality, level); + if (!plr->HasSpell(speciesEntry->SummonSpellID)) plr->LearnSpell(speciesEntry->SummonSpellID, false); - battlePetMgr->AddPet(speciesId, creatureId, breed, quality, level); plr->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true); m_CastItem = nullptr; } |