aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMeji <alvaromegias_46@hotmail.com>2021-09-29 22:26:25 +0200
committerGitHub <noreply@github.com>2021-09-29 22:26:25 +0200
commitde4eaa0de9565da604fa3b6e2b4b59efe117fd7a (patch)
tree1ad955f009dc8796f8d15bc5e2154082c8e8fc85 /src
parentf507737ecff5d564da999c56d672274387d70ec2 (diff)
Core/BattlePets: Misc fixes (#26964)
* Define BattlePetSpeciesFlags enum class. * Define BattlePetDbFlags enum class. * Added check to prevent the pet from being caged if its species has flag BattlePetSpeciesFlags::NotTradable. * Added check to prevent the pet from being caged if it's in battle pet slots. * Added check to prevent the pet from being caged if its health is below maximum health. * Only add pet if the species has flag BattlePetSpeciesFlags::WellKnown. * Added function to check flag BattlePetSpeciesFlags::LegacyAccountUnique to avoid learning copies of unique pets. * Implemented CMSG_BATTLE_PET_CLEAR_FANFARE.
Diffstat (limited to 'src')
-rw-r--r--src/server/game/BattlePets/BattlePetMgr.cpp46
-rw-r--r--src/server/game/BattlePets/BattlePetMgr.h29
-rw-r--r--src/server/game/DataStores/DB2Structure.h2
-rw-r--r--src/server/game/DataStores/DBCEnums.h22
-rw-r--r--src/server/game/Handlers/BattlePetHandler.cpp5
-rw-r--r--src/server/game/Server/Packets/BattlePetPackets.cpp5
-rw-r--r--src/server/game/Server/Packets/BattlePetPackets.h10
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
10 files changed, 116 insertions, 9 deletions
diff --git a/src/server/game/BattlePets/BattlePetMgr.cpp b/src/server/game/BattlePets/BattlePetMgr.cpp
index 55531bf20fa..5938595fb50 100644
--- a/src/server/game/BattlePets/BattlePetMgr.cpp
+++ b/src/server/game/BattlePets/BattlePetMgr.cpp
@@ -196,9 +196,9 @@ void BattlePetMgr::LoadFromDB(PreparedQueryResult pets, PreparedQueryResult slot
if (BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(species))
{
- if (GetPetCount(species) >= MAX_BATTLE_PETS_PER_SPECIES)
+ if (HasMaxPetCount(speciesEntry))
{
- TC_LOG_ERROR("misc", "Battlenet account with id %u has more than 3 battle pets of species %u", _owner->GetBattlenetAccountId(), species);
+ TC_LOG_ERROR("misc", "Battlenet account with id %u has more than maximum battle pets of species %u", _owner->GetBattlenetAccountId(), species);
continue;
}
@@ -314,6 +314,9 @@ void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8
if (!battlePetSpecies) // should never happen
return;
+ if (!battlePetSpecies->GetFlags().HasFlag(BattlePetSpeciesFlags::WellKnown)) // Not learnable
+ return;
+
BattlePet pet;
pet.PacketInfo.Guid = ObjectGuid::Create<HighGuid::BattlePet>(sObjectMgr->GetGenerator<HighGuid::BattlePet>().Generate());
pet.PacketInfo.Species = species;
@@ -351,6 +354,27 @@ void BattlePetMgr::RemovePet(ObjectGuid guid)
_owner->GetPlayer()->RemoveSpell(speciesEntry->SummonSpellID);*/
}
+void BattlePetMgr::ClearFanfare(ObjectGuid guid)
+{
+ BattlePet* pet = GetPet(guid);
+ if (!pet)
+ return;
+
+ pet->PacketInfo.Flags &= ~uint16(BattlePetDbFlags::FanfareNeeded);
+
+ if (pet->SaveInfo != BATTLE_PET_NEW)
+ pet->SaveInfo = BATTLE_PET_CHANGED;
+}
+
+bool BattlePetMgr::IsPetInSlot(ObjectGuid guid)
+{
+ for (WorldPackets::BattlePet::BattlePetSlot const& slot : _slots)
+ if (slot.Pet.Guid == guid)
+ return true;
+
+ return false;
+}
+
uint8 BattlePetMgr::GetPetCount(uint32 species) const
{
return uint8(std::count_if(_pets.begin(), _pets.end(), [species](std::pair<uint64 const, BattlePet> const& pet)
@@ -359,6 +383,13 @@ uint8 BattlePetMgr::GetPetCount(uint32 species) const
}));
}
+bool BattlePetMgr::HasMaxPetCount(BattlePetSpeciesEntry const* speciesEntry) const
+{
+ uint8 maxPetsPerSpecies = speciesEntry->GetFlags().HasFlag(BattlePetSpeciesFlags::LegacyAccountUnique) ? 1 : DEFAULT_MAX_BATTLE_PETS_PER_SPECIES;
+
+ return GetPetCount(speciesEntry->ID) >= maxPetsPerSpecies;
+}
+
uint32 BattlePetMgr::GetPetUniqueSpeciesCount() const
{
std::set<uint32> speciesIds;
@@ -399,6 +430,16 @@ void BattlePetMgr::CageBattlePet(ObjectGuid guid)
if (!pet)
return;
+ if (BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(pet->PacketInfo.Species))
+ if (battlePetSpecies->GetFlags().HasFlag(BattlePetSpeciesFlags::NotTradable))
+ return;
+
+ if (IsPetInSlot(guid))
+ return;
+
+ if (pet->PacketInfo.Health < pet->PacketInfo.MaxHealth)
+ return;
+
ItemPosCountVec dest;
if (_owner->GetPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, BATTLE_PET_CAGE_ITEM_ID, 1) != EQUIP_ERR_OK)
@@ -413,7 +454,6 @@ void BattlePetMgr::CageBattlePet(ObjectGuid guid)
item->SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, pet->PacketInfo.Level);
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, false);
RemovePet(guid);
diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h
index 49ed9edc23f..721c1aafa3d 100644
--- a/src/server/game/BattlePets/BattlePetMgr.h
+++ b/src/server/game/BattlePets/BattlePetMgr.h
@@ -22,14 +22,32 @@
#include "DatabaseEnvFwd.h"
#include <unordered_map>
+struct BattlePetSpeciesEntry;
+
enum BattlePetMisc
{
- MAX_PET_BATTLE_SLOTS = 3,
- MAX_BATTLE_PETS_PER_SPECIES = 3,
- BATTLE_PET_CAGE_ITEM_ID = 82800,
- DEFAULT_SUMMON_BATTLE_PET_SPELL = 118301
+ MAX_PET_BATTLE_SLOTS = 3,
+ DEFAULT_MAX_BATTLE_PETS_PER_SPECIES = 3,
+ BATTLE_PET_CAGE_ITEM_ID = 82800,
+ DEFAULT_SUMMON_BATTLE_PET_SPELL = 118301
};
+enum class BattlePetDbFlags : uint16
+{
+ None = 0x000,
+ Favorite = 0x001,
+ Converted = 0x002,
+ Revoked = 0x004,
+ LockedForConvert = 0x008,
+ Ability0Selection = 0x010,
+ Ability1Selection = 0x020,
+ Ability2Selection = 0x040,
+ FanfareNeeded = 0x080,
+ DisplayOverridden = 0x100
+};
+
+DEFINE_ENUM_FLAG(BattlePetDbFlags);
+
// 6.2.4
enum FlagsControlType
{
@@ -112,8 +130,11 @@ public:
BattlePet* GetPet(ObjectGuid guid);
void AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 quality, uint16 level = 1);
void RemovePet(ObjectGuid guid);
+ void ClearFanfare(ObjectGuid guid);
+ bool IsPetInSlot(ObjectGuid guid);
uint8 GetPetCount(uint32 species) const;
+ bool HasMaxPetCount(BattlePetSpeciesEntry const* speciesEntry) const;
uint32 GetPetUniqueSpeciesCount() const;
WorldPackets::BattlePet::BattlePetSlot* GetSlot(uint8 slot) { return slot < _slots.size() ? &_slots[slot] : nullptr; }
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 941ecc72605..351f6e3d94e 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -479,6 +479,8 @@ struct BattlePetSpeciesEntry
int32 CardUIModelSceneID;
int32 LoadoutUIModelSceneID;
int32 CovenantID;
+
+ EnumFlag<BattlePetSpeciesFlags> GetFlags() const { return static_cast<BattlePetSpeciesFlags>(Flags); }
};
struct BattlePetSpeciesStateEntry
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index babc2fde7a2..26dbebefc37 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -193,6 +193,28 @@ enum AzeriteTierUnlockSetFlags
#define BATTLE_PET_SPECIES_MAX_ID 3159
+enum class BattlePetSpeciesFlags : uint16
+{
+ NoRename = 0x0001,
+ WellKnown = 0x0002,
+ NotAccountWide = 0x0004,
+ Capturable = 0x0008,
+ NotTradable = 0x0010,
+ HideFromJournal = 0x0020,
+ LegacyAccountUnique = 0x0040,
+ CantBattle = 0x0080,
+ HordeOnly = 0x0100,
+ AllianceOnly = 0x0200,
+ Boss = 0x0400,
+ RandomDisplay = 0x0800,
+ NoLicenseRequired = 0x1000,
+ AddsAllowedWithBoss = 0x2000,
+ HideUntilLearned = 0x4000,
+ MatchPlayerHighPetLevel = 0x8000
+};
+
+DEFINE_ENUM_FLAG(BattlePetSpeciesFlags);
+
enum class BattlemasterListFlags : uint32
{
InternalOnly = 0x01,
diff --git a/src/server/game/Handlers/BattlePetHandler.cpp b/src/server/game/Handlers/BattlePetHandler.cpp
index 907c10ac24b..af088ba000f 100644
--- a/src/server/game/Handlers/BattlePetHandler.cpp
+++ b/src/server/game/Handlers/BattlePetHandler.cpp
@@ -62,6 +62,11 @@ void WorldSession::HandleBattlePetSetFlags(WorldPackets::BattlePet::BattlePetSet
}
}
+void WorldSession::HandleBattlePetClearFanfare(WorldPackets::BattlePet::BattlePetClearFanfare& battlePetClearFanfare)
+{
+ GetBattlePetMgr()->ClearFanfare(battlePetClearFanfare.PetGuid);
+}
+
void WorldSession::HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& cageBattlePet)
{
GetBattlePetMgr()->CageBattlePet(cageBattlePet.PetGuid);
diff --git a/src/server/game/Server/Packets/BattlePetPackets.cpp b/src/server/game/Server/Packets/BattlePetPackets.cpp
index f664e92ea0f..e241e985367 100644
--- a/src/server/game/Server/Packets/BattlePetPackets.cpp
+++ b/src/server/game/Server/Packets/BattlePetPackets.cpp
@@ -140,6 +140,11 @@ void WorldPackets::BattlePet::BattlePetSetFlags::Read()
ControlType = _worldPacket.ReadBits(2);
}
+void WorldPackets::BattlePet::BattlePetClearFanfare::Read()
+{
+ _worldPacket >> PetGuid;
+}
+
void WorldPackets::BattlePet::CageBattlePet::Read()
{
_worldPacket >> PetGuid;
diff --git a/src/server/game/Server/Packets/BattlePetPackets.h b/src/server/game/Server/Packets/BattlePetPackets.h
index 2cc13908abc..9ad402a16fa 100644
--- a/src/server/game/Server/Packets/BattlePetPackets.h
+++ b/src/server/game/Server/Packets/BattlePetPackets.h
@@ -158,6 +158,16 @@ namespace WorldPackets
uint8 ControlType = 0;
};
+ class BattlePetClearFanfare final : public ClientPacket
+ {
+ public:
+ BattlePetClearFanfare(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_CLEAR_FANFARE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid PetGuid;
+ };
+
class CageBattlePet final : public ClientPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 21a7f023913..cad41a689a6 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -206,7 +206,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_BATTLE_PAY_REQUEST_PRICE_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BATTLE_PAY_START_PURCHASE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BATTLE_PAY_START_VAS_PURCHASE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_BATTLE_PET_CLEAR_FANFARE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_BATTLE_PET_CLEAR_FANFARE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlePetClearFanfare);
DEFINE_HANDLER(CMSG_BATTLE_PET_DELETE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlePetDeletePet);
DEFINE_HANDLER(CMSG_BATTLE_PET_DELETE_PET_CHEAT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BATTLE_PET_MODIFY_NAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlePetModifyName);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index df4ebae873b..93c6ee84f66 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -194,6 +194,7 @@ namespace WorldPackets
class BattlePetModifyName;
class BattlePetDeletePet;
class BattlePetSetFlags;
+ class BattlePetClearFanfare;
class BattlePetSummon;
class CageBattlePet;
}
@@ -1756,6 +1757,7 @@ class TC_GAME_API WorldSession
void HandleBattlePetModifyName(WorldPackets::BattlePet::BattlePetModifyName& battlePetModifyName);
void HandleBattlePetDeletePet(WorldPackets::BattlePet::BattlePetDeletePet& battlePetDeletePet);
void HandleBattlePetSetFlags(WorldPackets::BattlePet::BattlePetSetFlags& battlePetSetFlags);
+ void HandleBattlePetClearFanfare(WorldPackets::BattlePet::BattlePetClearFanfare& battlePetClearFanfare);
void HandleBattlePetSummon(WorldPackets::BattlePet::BattlePetSummon& battlePetSummon);
void HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& cageBattlePet);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 5a48f16948b..cb330f5ca44 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -5607,7 +5607,7 @@ void Spell::EffectUncageBattlePet()
return;
}
- if (battlePetMgr->GetPetCount(speciesId) >= MAX_BATTLE_PETS_PER_SPECIES)
+ if (battlePetMgr->HasMaxPetCount(speciesEntry))
{
battlePetMgr->SendError(BATTLEPETRESULT_CANT_HAVE_MORE_PETS_OF_THAT_TYPE, creatureId); // or speciesEntry.CreatureID
SendCastResult(SPELL_FAILED_CANT_ADD_BATTLE_PET);