diff options
author | Meji <alvaromegias_46@hotmail.com> | 2021-10-03 21:20:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-03 21:20:45 +0200 |
commit | 0cfd14d2a0a52ceb0d8203c31c7c6c487775bcee (patch) | |
tree | c131dfb62ba3bde90a9bb05c93ae5a2813f62190 | |
parent | b1c0d069e1eba2f7b43ada8032b954bff630b68d (diff) |
Core/BattlePets: Misc fixes (#26990)
* Define BattlePetBreedQuality enum class.
* Check the quality of the battle pet species in battle_pet_quality table to avoid invalid values.
* Set CurrentBattlePetBreedQuality and WildBattlePetLevel update fields with the data of the summoned battle pet.
* Added function to calculate the WildBattlePetLevel of wild battle pets according to their spawn zone.
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.cpp | 27 | ||||
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.h | 17 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 32 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 2 |
8 files changed, 82 insertions, 25 deletions
diff --git a/src/server/game/BattlePets/BattlePetMgr.cpp b/src/server/game/BattlePets/BattlePetMgr.cpp index 5938595fb50..9a22df4ee08 100644 --- a/src/server/game/BattlePets/BattlePetMgr.cpp +++ b/src/server/game/BattlePets/BattlePetMgr.cpp @@ -142,13 +142,24 @@ void BattlePetMgr::LoadDefaultPetQualities() uint32 speciesId = fields[0].GetUInt32(); uint8 quality = fields[1].GetUInt8(); - if (!sBattlePetSpeciesStore.LookupEntry(speciesId)) + BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(speciesId); + if (!battlePetSpecies) { TC_LOG_ERROR("sql.sql", "Non-existing BattlePetSpecies.db2 entry %u was referenced in `battle_pet_quality` by row (%u, %u).", speciesId, speciesId, quality); continue; } - // TODO: verify quality (0 - 3 for player pets or 0 - 5 for both player and tamer pets) if needed + if (quality >= AsUnderlyingType(BattlePetBreedQuality::Count)) + { + TC_LOG_ERROR("sql.sql", "BattlePetSpecies.db2 entry %u was referenced in `battle_pet_quality` with non-existing quality %u).", speciesId, quality); + continue; + } + + if (battlePetSpecies->GetFlags().HasFlag(BattlePetSpeciesFlags::WellKnown) && quality > AsUnderlyingType(BattlePetBreedQuality::Rare)) + { + TC_LOG_ERROR("sql.sql", "Learnable BattlePetSpecies.db2 entry %u was referenced in `battle_pet_quality` with invalid quality %u. Maximum allowed quality is BattlePetBreedQuality::Rare.", speciesId, quality); + continue; + } _defaultQualityPerSpecies[speciesId] = quality; } while (result->NextRow()); @@ -165,13 +176,13 @@ uint16 BattlePetMgr::RollPetBreed(uint32 species) return Trinity::Containers::SelectRandomContainerElement(itr->second); } -uint8 BattlePetMgr::GetDefaultPetQuality(uint32 species) +BattlePetBreedQuality BattlePetMgr::GetDefaultPetQuality(uint32 species) { auto itr = _defaultQualityPerSpecies.find(species); if (itr == _defaultQualityPerSpecies.end()) - return 0; // default poor + return BattlePetBreedQuality::Poor; // Default - return itr->second; + return BattlePetBreedQuality(itr->second); } BattlePetMgr::BattlePetMgr(WorldSession* owner) @@ -308,7 +319,7 @@ BattlePetMgr::BattlePet* BattlePetMgr::GetPet(ObjectGuid guid) return Trinity::Containers::MapGetValuePtr(_pets, guid.GetCounter()); } -void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 quality, uint16 level /*= 1*/) +void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, BattlePetBreedQuality quality, uint16 level /*= 1*/) { BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(species); if (!battlePetSpecies) // should never happen @@ -325,7 +336,7 @@ void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 pet.PacketInfo.Exp = 0; pet.PacketInfo.Flags = 0; pet.PacketInfo.Breed = breed; - pet.PacketInfo.Quality = quality; + pet.PacketInfo.Quality = AsUnderlyingType(quality); pet.PacketInfo.Name = ""; pet.CalculateStats(); pet.PacketInfo.Health = pet.PacketInfo.MaxHealth; @@ -495,6 +506,7 @@ void BattlePetMgr::SummonPet(ObjectGuid guid) // TODO: set proper CreatureID for spell DEFAULT_SUMMON_BATTLE_PET_SPELL (default EffectMiscValueA is 40721 - Murkimus the Gladiator) _owner->GetPlayer()->SetSummonedBattlePetGUID(guid); + _owner->GetPlayer()->SetCurrentBattlePetBreedQuality(pet->PacketInfo.Quality); _owner->GetPlayer()->CastSpell(_owner->GetPlayer(), speciesEntry->SummonSpellID ? speciesEntry->SummonSpellID : uint32(DEFAULT_SUMMON_BATTLE_PET_SPELL)); // TODO: set pet level, quality... update fields @@ -508,6 +520,7 @@ void BattlePetMgr::DismissPet() { pet->DespawnOrUnsummon(); ownerPlayer->SetSummonedBattlePetGUID(ObjectGuid::Empty); + ownerPlayer->SetCurrentBattlePetBreedQuality(AsUnderlyingType(BattlePetBreedQuality::Poor)); } } diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h index 721c1aafa3d..d1da973dc00 100644 --- a/src/server/game/BattlePets/BattlePetMgr.h +++ b/src/server/game/BattlePets/BattlePetMgr.h @@ -20,6 +20,7 @@ #include "BattlePetPackets.h" #include "DatabaseEnvFwd.h" +#include "EnumFlag.h" #include <unordered_map> struct BattlePetSpeciesEntry; @@ -32,6 +33,18 @@ enum BattlePetMisc DEFAULT_SUMMON_BATTLE_PET_SPELL = 118301 }; +enum class BattlePetBreedQuality : uint8 +{ + Poor = 0, + Common = 1, + Uncommon = 2, + Rare = 3, + Epic = 4, + Legendary = 5, + + Count +}; + enum class BattlePetDbFlags : uint16 { None = 0x000, @@ -122,13 +135,13 @@ public: static void Initialize(); static uint16 RollPetBreed(uint32 species); - static uint8 GetDefaultPetQuality(uint32 species); + static BattlePetBreedQuality GetDefaultPetQuality(uint32 species); void LoadFromDB(PreparedQueryResult pets, PreparedQueryResult slots); void SaveToDB(LoginDatabaseTransaction& trans); BattlePet* GetPet(ObjectGuid guid); - void AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 quality, uint16 level = 1); + void AddPet(uint32 species, uint32 creatureId, uint16 breed, BattlePetBreedQuality quality, uint16 level = 1); void RemovePet(ObjectGuid guid); void ClearFanfare(ObjectGuid guid); bool IsPetInSlot(ObjectGuid guid); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 162fd6fc1f0..ef6c5385fda 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1620,6 +1620,20 @@ void Creature::UpdateLevelDependantStats() SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, armor); } +void Creature::SelectWildBattlePetLevel() +{ + if (IsWildBattlePet()) + { + uint8 wildBattlePetLevel = WILD_BATTLE_PET_DEFAULT_LEVEL; + + if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(GetZoneId())) + if (areaTable->WildBattlePetLevelMin > 0) + wildBattlePetLevel = urand(areaTable->WildBattlePetLevelMin, areaTable->WildBattlePetLevelMax); + + SetWildBattlePetLevel(wildBattlePetLevel); + } +} + float Creature::_GetHealthMod(int32 Rank) { switch (Rank) // define rates for each elite rank @@ -1804,6 +1818,8 @@ bool Creature::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, SetSpawnHealth(); + SelectWildBattlePetLevel(); + // checked at creature_template loading m_defaultMovementType = MovementGeneratorType(data->movementType); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index cab9b45e783..2aa3fa395c3 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -54,6 +54,8 @@ typedef std::list<VendorItemCount> VendorItemCounts; #define MAX_VENDOR_ITEMS 150 // Limitation in 4.x.x item count in SMSG_LIST_INVENTORY +static constexpr uint8 WILD_BATTLE_PET_DEFAULT_LEVEL = 1; + //used for handling non-repeatable random texts typedef std::vector<uint8> CreatureTextRepeatIds; typedef std::unordered_map<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup; @@ -81,6 +83,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma bool LoadCreaturesAddon(); void SelectLevel(); void UpdateLevelDependantStats(); + void SelectWildBattlePetLevel(); void LoadEquipment(int8 id = 1, bool force = false); void SetSpawnHealth(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 17818b4c33c..99660ed918c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2622,6 +2622,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetArenaFaction(uint8 arenaFaction) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::ArenaFaction), arenaFaction); } void ApplyModFakeInebriation(int32 mod, bool apply) { ApplyModUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::FakeInebriation), mod, apply); } void SetVirtualPlayerRealm(uint32 virtualRealmAddress) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::VirtualPlayerRealm), virtualRealmAddress); } + void SetCurrentBattlePetBreedQuality(uint8 battlePetBreedQuality) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::CurrentBattlePetBreedQuality), battlePetBreedQuality); } void AddHeirloom(int32 itemId, uint32 flags) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e86156cc3bf..86db8294fcb 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -22,6 +22,7 @@ #include "Battleground.h" #include "BattlegroundPackets.h" #include "BattlegroundScore.h" +#include "BattlePetMgr.h" #include "CellImpl.h" #include "CharacterCache.h" #include "ChatPackets.h" @@ -5823,7 +5824,13 @@ void Unit::SetMinion(Minion *minion, bool apply) { SetCritterGUID(minion->GetGUID()); if (Player const* thisPlayer = ToPlayer()) - minion->SetBattlePetCompanionGUID(thisPlayer->m_activePlayerData->SummonedBattlePetGUID); + { + if (BattlePetMgr::BattlePet const* pet = thisPlayer->GetSession()->GetBattlePetMgr()->GetPet(thisPlayer->m_activePlayerData->SummonedBattlePetGUID)) + { + minion->SetBattlePetCompanionGUID(thisPlayer->m_activePlayerData->SummonedBattlePetGUID); + minion->SetWildBattlePetLevel(pet->PacketInfo.Level); + } + } } // PvP, FFAPvP diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 67746b97bc9..810f1de1413 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1065,20 +1065,21 @@ class TC_GAME_API Unit : public WorldObject void AddNpcFlag2(NPCFlags2 flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::NpcFlags, 1), flags); } void RemoveNpcFlag2(NPCFlags2 flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::NpcFlags, 1), flags); } void SetNpcFlags2(NPCFlags2 flags) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::NpcFlags, 1), flags); } - bool IsVendor() const { return HasNpcFlag(UNIT_NPC_FLAG_VENDOR); } - bool IsTrainer() const { return HasNpcFlag(UNIT_NPC_FLAG_TRAINER); } - bool IsQuestGiver() const { return HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); } - bool IsGossip() const { return HasNpcFlag(UNIT_NPC_FLAG_GOSSIP); } - bool IsTaxi() const { return HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER); } - bool IsGuildMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_PETITIONER); } - bool IsBattleMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_BATTLEMASTER); } - bool IsBanker() const { return HasNpcFlag(UNIT_NPC_FLAG_BANKER); } - bool IsInnkeeper() const { return HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER); } - bool IsSpiritHealer() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER); } - bool IsSpiritGuide() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITGUIDE); } - bool IsTabardDesigner()const{ return HasNpcFlag(UNIT_NPC_FLAG_TABARDDESIGNER); } - bool IsAuctioner() const { return HasNpcFlag(UNIT_NPC_FLAG_AUCTIONEER); } - bool IsArmorer() const { return HasNpcFlag(UNIT_NPC_FLAG_REPAIR); } + bool IsVendor() const { return HasNpcFlag(UNIT_NPC_FLAG_VENDOR); } + bool IsTrainer() const { return HasNpcFlag(UNIT_NPC_FLAG_TRAINER); } + bool IsQuestGiver() const { return HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); } + bool IsGossip() const { return HasNpcFlag(UNIT_NPC_FLAG_GOSSIP); } + bool IsTaxi() const { return HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER); } + bool IsGuildMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_PETITIONER); } + bool IsBattleMaster() const { return HasNpcFlag(UNIT_NPC_FLAG_BATTLEMASTER); } + bool IsBanker() const { return HasNpcFlag(UNIT_NPC_FLAG_BANKER); } + bool IsInnkeeper() const { return HasNpcFlag(UNIT_NPC_FLAG_INNKEEPER); } + bool IsSpiritHealer() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITHEALER); } + bool IsSpiritGuide() const { return HasNpcFlag(UNIT_NPC_FLAG_SPIRITGUIDE); } + bool IsTabardDesigner() const { return HasNpcFlag(UNIT_NPC_FLAG_TABARDDESIGNER); } + bool IsAuctioner() const { return HasNpcFlag(UNIT_NPC_FLAG_AUCTIONEER); } + bool IsArmorer() const { return HasNpcFlag(UNIT_NPC_FLAG_REPAIR); } + bool IsWildBattlePet() const { return HasNpcFlag(UNIT_NPC_FLAG_WILD_BATTLE_PET); } bool IsServiceProvider() const; bool IsSpiritService() const { return HasNpcFlag(NPCFlags(UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE)); } bool IsCritter() const { return GetCreatureType() == CREATURE_TYPE_CRITTER; } @@ -1296,6 +1297,9 @@ class TC_GAME_API Unit : public WorldObject Pet* CreateTamedPetFrom(uint32 creatureEntry, uint32 spell_id = 0); bool InitTamedPet(Pet* pet, uint8 level, uint32 spell_id); + void SetWildBattlePetLevel(uint32 wildBattlePetLevel) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::WildBattlePetLevel), wildBattlePetLevel); } + uint32 GetWildBattlePetLevel() const { return m_unitData->WildBattlePetLevel; } + // aura apply/remove helpers - you should better not use these Aura* _TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo); void _AddAura(UnitAura* aura, Unit* caster); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 0c12f8f8243..49936e0ed15 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5670,7 +5670,7 @@ void Spell::EffectUncageBattlePet() return; } - battlePetMgr->AddPet(speciesId, creatureId, breed, quality, level); + battlePetMgr->AddPet(speciesId, creatureId, breed, BattlePetBreedQuality(quality), level); if (!plr->HasSpell(speciesEntry->SummonSpellID)) plr->LearnSpell(speciesEntry->SummonSpellID, false); |