Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
BattlePetMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "BattlePetMgr.h"
7#include "BattlePetPackets.h"
8#include "BattlePetSpawnMgr.h"
9#include "ByteBuffer.h"
10#include "Common.h"
11#include "Creature.h"
12#include "DatabaseEnv.h"
13#include "DB2Stores.h"
14#include "DB2Enums.h"
15#include "DBCEnums.h"
16#include "ObjectAccessor.h"
17#include "ObjectMgr.h"
18#include "Opcodes.h"
19#include "Player.h"
20#include "SpellAuraDefines.h"
21#include "Util.h"
22#include "World.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25
26#include <algorithm>
27#include <set>
28#include <vector>
29
30namespace
31{
32 CreatureTemplate const* GetBattlePetCreatureTemplate(BattlePet const* battlePet)
33 {
34 if (!battlePet)
35 return NULL;
36
37 BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(battlePet->GetSpecies());
38 if (!speciesEntry)
39 return NULL;
40
41 return sObjectMgr->GetCreatureTemplate(speciesEntry->NpcId);
42 }
43
44 bool BattlePetNameMatches(std::string const& left, std::string const& right)
45 {
46 return !left.empty() && !right.empty() && !stricmp(left.c_str(), right.c_str());
47 }
48
49 uint8 BattlePetHealthPercent(uint32 health, uint32 maxHealth)
50 {
51 if (!maxHealth)
52 return 0;
53
54 return uint8(std::min<uint32>(100, health * 100 / maxHealth));
55 }
56
57 float BattlePetTrapFailedAttemptBonus(uint32 trapAbility)
58 {
59 switch (trapAbility)
60 {
62 return 20.0f;
64 return 25.0f;
66 return 30.0f;
68 return 100.0f;
69 default:
70 return 0.0f;
71 }
72 }
73
74 float BattlePetTrapCaptureChance(uint32 trapAbility, uint8 failedAttempts)
75 {
76 if (trapAbility == BATTLE_PET_ABILITY_GM_TRAP)
77 return 100.0f;
78
79 float chance = 45.0f;
80 float const bonus = BattlePetTrapFailedAttemptBonus(trapAbility);
81 for (uint8 i = 0; i < failedAttempts; ++i)
82 chance += (100.0f - chance) * bonus / 100.0f;
83
84 return std::min<float>(99.0f, chance);
85 }
86}
87
89{
90 for (BattlePetSet::iterator itr = m_battlePetSet.begin(); itr != m_battlePetSet.end(); ++itr)
91 delete* itr;
92
93 m_battlePetSet.clear();
94}
95
97{
98 if (!result)
99 return;
100
101 do
102 {
103 Field* fields = result->Fetch();
104
105 uint64 id = fields[0].GetUInt64();
106 uint16 speciesId = fields[1].GetUInt16();
107 std::string nickname = fields[2].GetString();
108 uint32 timestamp = fields[3].GetUInt32();
109 uint8 level = fields[4].GetUInt8();
110 uint16 xp = fields[5].GetUInt16();
111 uint16 health = fields[6].GetUInt16();
112 uint16 maxHealth = fields[7].GetUInt16();
113 uint16 power = fields[8].GetUInt16();
114 uint16 speed = fields[9].GetUInt16();
115 uint8 quality = fields[10].GetUInt8();
116 uint8 breedId = fields[11].GetUInt8();
117 uint16 flags = fields[12].GetUInt16();
118
119 if (!sBattlePetSpeciesStore.LookupEntry(speciesId))
120 {
121 SF_LOG_ERROR("sql.sql", "Species %u defined in `account_battle_pet` for Battle Pet %lu does not exist, skipped.", speciesId, (uint64)id);
122 continue;
123 }
124
125 if (sBattlePetBreedSet.find(breedId) == sBattlePetBreedSet.end() && breedId != 0)
126 {
127 SF_LOG_ERROR("sql.sql", "Breed %u defined in `account_battle_pet` for Battle Pet %lu does not exist, skipped.", breedId, (uint64)id);
128 continue;
129 }
130
131 // highest quality client supports, currently players can not obtain legendary pets on retail
132 if (quality > ITEM_QUALITY_LEGENDARY)
133 {
134 SF_LOG_ERROR("sql.sql", "Quality %u defined in `account_battle_pet` for Battle Pet %lu is invalid, skipped.", quality, (uint64)id);
135 continue;
136 }
137
138 // client supports up to level 255 (uint8)
139 if (level > BATTLE_PET_MAX_LEVEL)
140 {
141 SF_LOG_ERROR("sql.sql", "Level %u defined in `account_battle_pet` for Battle Pet %lu is invalid, skipped.", level, (uint64)id);
142 continue;
143 }
144
145 BattlePet* battlePet = new BattlePet(id, speciesId, nickname, timestamp, level, xp,
146 health, maxHealth, power, speed, quality, breedId, flags);
147
148 m_battlePetSet.insert(battlePet);
149 } while (result->NextRow());
150
152}
153
155{
157 SaveSlotsToDb(trans);
158
159 if (m_battlePetSet.empty())
160 return;
161
162 for (BattlePetSet::iterator itr = m_battlePetSet.begin(); itr != m_battlePetSet.end();)
163 {
164 BattlePet* battlePet = *itr;
165
166 if (!battlePet)
167 {
168 itr = m_battlePetSet.erase(itr);
169 continue;
170 }
171
172 switch (battlePet->GetDbState())
173 {
175 ++itr;
176 break;
178 {
180 stmt->setUInt64(0, battlePet->GetId());
181 trans->Append(stmt);
182
183 itr = m_battlePetSet.erase(itr);
184 delete battlePet;
185
186 break;
187 }
189 {
191 stmt->setUInt64(0, battlePet->GetId());
192 trans->Append(stmt);
193
194 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_BATTLE_PET);
195 stmt->setUInt64(0, battlePet->GetId());
196 stmt->setUInt32(1, m_owner->GetSession()->GetAccountId());
197 stmt->setUInt16(2, battlePet->GetSpecies());
198 stmt->setString(3, battlePet->GetNickname());
199 stmt->setUInt32(4, battlePet->GetTimestamp());
200 stmt->setUInt8(5, battlePet->GetLevel());
201 stmt->setUInt16(6, battlePet->GetXp());
202 stmt->setUInt16(7, battlePet->GetCurrentHealth());
203 stmt->setUInt16(8, battlePet->GetMaxHealth());
204 stmt->setUInt16(9, battlePet->GetPower());
205 stmt->setUInt16(10, battlePet->GetSpeed());
206 stmt->setUInt8(11, battlePet->GetQuality());
207 stmt->setUInt8(12, battlePet->GetBreed());
208 stmt->setUInt16(13, battlePet->GetFlags());
209 trans->Append(stmt);
210
212 ++itr;
213 break;
214 }
215 default:
216 ++itr;
217 break;
218 }
219 }
220}
221
223{
224 SQLTransaction trans = CharacterDatabase.BeginTransaction();
225 SaveToDb(trans);
226 CharacterDatabase.CommitTransaction(trans);
227}
228
230{
231 if (!result)
232 {
234 return;
235 }
236
237 Field* fields = result->Fetch();
238
239 uint64 slot1 = fields[0].GetUInt64();
240 uint64 slot2 = fields[1].GetUInt64();
241 uint64 slot3 = fields[2].GetUInt64();
242 m_loadoutFlags = fields[3].GetUInt8();
243
246
247 // update flag and spell state for new alt characters
249 {
251
252 m_owner->learnSpell(SPELL_BATTLE_PET_TRAINING_PASSIVE, false);
253 m_owner->learnSpell(SPELL_TRACK_PETS, false);
254 m_owner->learnSpell(SPELL_REVIVE_BATTLE_PETS, false);
255 }
256
257 std::set<uint8> slotErrors;
258
259 if ((!HasLoadoutSlot(BATTLE_PET_LOADOUT_SLOT_1) || !GetBattlePet(slot1)) && slot1 != 0)
260 slotErrors.insert(BATTLE_PET_LOADOUT_SLOT_1);
261 if ((!HasLoadoutSlot(BATTLE_PET_LOADOUT_SLOT_2) || !GetBattlePet(slot2)) && slot2 != 0)
262 slotErrors.insert(BATTLE_PET_LOADOUT_SLOT_2);
263 if ((!HasLoadoutSlot(BATTLE_PET_LOADOUT_SLOT_3) || !GetBattlePet(slot3)) && slot3 != 0)
264 slotErrors.insert(BATTLE_PET_LOADOUT_SLOT_3);
265
266 for (std::set<uint8>::const_iterator citr = slotErrors.begin(); citr != slotErrors.end(); ++citr)
267 {
268 SF_LOG_ERROR("sql.sql", "Battle Pet slot %u in `account_battle_pet_slots` for account %u is invalid!",
269 *citr, m_owner->GetSession()->GetAccountId());
270 }
271
272 bool hasError = slotErrors.size() > 0;
273 if (hasError)
274 m_loadoutSave = true;
275
276 SetLoadoutSlot(BATTLE_PET_LOADOUT_SLOT_1, hasError ? 0 : slot1);
277 SetLoadoutSlot(BATTLE_PET_LOADOUT_SLOT_2, hasError ? 0 : slot2);
278 SetLoadoutSlot(BATTLE_PET_LOADOUT_SLOT_3, hasError ? 0 : slot3);
280}
281
283{
284 if (!m_loadoutSave)
285 return;
286
288 stmt->setUInt32(0, m_owner->GetSession()->GetAccountId());
289 trans->Append(stmt);
290
291 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_BATTLE_PET_SLOTS);
292 stmt->setUInt32(0, m_owner->GetSession()->GetAccountId());
296 stmt->setUInt8(4, GetLoadoutFlags());
297 trans->Append(stmt);
298
299 m_loadoutSave = false;
300}
301
303{
304 for (BattlePetSet::const_iterator itr = m_battlePetSet.begin(); itr != m_battlePetSet.end(); ++itr)
305 if ((*itr)->GetId() == id)
306 return *itr;
307
308 return NULL;
309}
310
312{
313 uint32 counter = 0;
314
315 for (BattlePetSet::const_iterator citr = m_battlePetSet.begin(); citr != m_battlePetSet.end(); ++citr)
316 {
317 BattlePet* battlePet = *citr;
318 if (!battlePet || !battlePet->GetSpecies() || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
319 continue;
320
321 counter++;
322 }
323
324 return counter;
325}
326
328{
329 uint8 counter = 0;
330
331 for (BattlePetSet::const_iterator citr = m_battlePetSet.begin(); citr != m_battlePetSet.end(); ++citr)
332 {
333 BattlePet* battlePet = *citr;
334 if (!battlePet || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
335 continue;
336
337 if (battlePet->GetSpecies() == speciesId)
338 counter++;
339 }
340
341 return counter;
342}
343
344std::string BattlePetMgr::GetBattlePetSpeciesName(BattlePet const* battlePet) const
345{
346 CreatureTemplate const* creatureTemplate = GetBattlePetCreatureTemplate(battlePet);
347 return creatureTemplate ? creatureTemplate->Name : std::string();
348}
349
350std::vector<BattlePet*> BattlePetMgr::FindBattlePetNameMatches(std::string const& name) const
351{
352 std::vector<BattlePet*> matches;
353 if (name.empty())
354 return matches;
355
356 for (BattlePetSet::const_iterator citr = m_battlePetSet.begin(); citr != m_battlePetSet.end(); ++citr)
357 {
358 BattlePet* battlePet = *citr;
359 if (!battlePet || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
360 continue;
361
362 if (BattlePetNameMatches(battlePet->GetNickname(), name))
363 matches.push_back(battlePet);
364 }
365
366 if (!matches.empty())
367 return matches;
368
369 for (BattlePetSet::const_iterator citr = m_battlePetSet.begin(); citr != m_battlePetSet.end(); ++citr)
370 {
371 BattlePet* battlePet = *citr;
372 if (!battlePet || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
373 continue;
374
375 if (BattlePetNameMatches(GetBattlePetSpeciesName(battlePet), name))
376 matches.push_back(battlePet);
377 }
378
379 return matches;
380}
381
383{
384 if (!m_summon || !m_summonId)
385 return;
386
387 m_summonLastId = temporary ? m_summonId : 0;
388 m_summonId = 0;
389
390 m_summon->UnSummon();
391 m_summon = NULL;
392}
393
395{
396 if (!m_summonLastId)
397 return;
398
400 if (!battlePet)
401 {
402 m_summonLastId = 0;
403 return;
404 }
405
406 uint32 summonSpell = BattlePetGetSummonSpell(battlePet->GetSpecies());
407 if (!summonSpell)
408 {
409 m_summonLastId = 0;
410 return;
411 }
412
414 m_owner->CastSpell(m_owner, summonSpell, true);
415
416 m_summonLastId = 0;
417}
418
420{
421 for (uint8 i = 0; i < BATTLE_PET_MAX_LOADOUT_SLOTS; i++)
422 if (GetLoadoutSlot(i) == id)
423 return i;
424
426}
427
429{
430 if (HasLoadoutSlot(slot))
431 return;
432
434 return;
435
436 switch (slot)
437 {
440 break;
444 break;
447 break;
448 }
449
450 SetLoadoutSlot(slot, 0);
451
452 // alert client of new Battle Pet loadout slot
453 SendBattlePetSlotUpdate(slot, true);
454}
455
457{
458 if (!HasLoadoutSlot(slot))
459 return;
460
461 m_loadout[slot] = id;
462
463 if (save)
464 m_loadoutSave = true;
465}
466
468{
469 if (!HasLoadoutSlot(slot))
470 return 0;
471
472 return m_loadout[slot];
473}
474
476{
478 return false;
479
480 switch (slot)
481 {
488 }
489
490 return false;
491}
492
494{
495 for (uint8 i = 0; i < BATTLE_PET_MAX_LOADOUT_SLOTS; i++)
496 {
497 uint64 petId = GetLoadoutSlot(i);
498 if (petId && GetBattlePet(petId))
499 return true;
500 }
501
502 return false;
503}
504
506{
507 for (uint8 i = 0; i < BATTLE_PET_MAX_LOADOUT_SLOTS; i++)
508 {
509 uint64 petId = GetLoadoutSlot(i);
510 if (!petId)
511 continue;
512
513 BattlePet* battlePet = GetBattlePet(petId);
514 if (battlePet && battlePet->GetCurrentHealth())
515 return battlePet;
516 }
517
518 return NULL;
519}
520
522{
523 if (HasLoadoutFlag(flag))
524 return;
525
526 m_loadoutFlags |= flag;
527 m_loadoutSave = true;
528}
529
531{
533 if (trapAbility == BATTLE_PET_ABILITY_GM_TRAP && (!m_owner || !m_owner->IsGameMaster()))
535
536 return trapAbility;
537}
538
540{
541 uint8 const slot = BattlePetLoadoutSlotForAchievement(achievementId);
543 return false;
544
545 if (HasLoadoutSlot(slot))
546 return false;
547
548 UnlockLoadoutSlot(slot);
549 return true;
550}
551
553{
554 bool updated = false;
555
556 if (m_owner->HasAchieved(BATTLE_PET_ACHIEVEMENT_NEWBIE))
558
561
562 if (updated)
563 SaveToDb();
564}
565
567{
568 if (ApplyAchievementLoadoutReward(achievementId))
569 SaveToDb();
570}
571
573{
575 uint8 const quality = sObjectMgr->BattlePetGetRandomQuality(speciesId);
576 return Create(speciesId, level, quality);
577}
578
579BattlePet* BattlePetMgr::Create(uint16 speciesId, uint8 level, uint8 quality, bool notification)
580{
581 return Create(speciesId, level, quality, sObjectMgr->BattlePetGetRandomBreed(speciesId), notification);
582}
583
584BattlePet* BattlePetMgr::Create(uint16 speciesId, uint8 level, uint8 quality, uint8 breed, bool notification)
585{
586 if (!CanCreateBattlePet(speciesId))
587 return NULL;
588
589 if (!level)
590 level = 1;
591 else if (level > BATTLE_PET_MAX_LEVEL)
592 level = BATTLE_PET_MAX_LEVEL;
593
594 if (quality > ITEM_QUALITY_LEGENDARY)
595 quality = ITEM_QUALITY_NORMAL;
596
597 if (breed && sBattlePetBreedSet.find(breed) == sBattlePetBreedSet.end())
598 breed = sObjectMgr->BattlePetGetRandomBreed(speciesId);
599
600 uint64 id = sObjectMgr->BattlePetGetNewId();
601
602 BattlePet* battlePet = new BattlePet(id, speciesId, level, quality, breed);
603 m_battlePetSet.insert(battlePet);
604
606
607 if (notification)
608 SendBattlePetUpdate(battlePet, true);
609
610 return battlePet;
611}
612
614{
615 BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(speciesId);
616 if (!speciesEntry)
617 return false;
618
619 if (!sObjectMgr->GetCreatureTemplate(speciesEntry->NpcId))
620 return false;
621
623 return false;
624
625 uint8 speciesCount = GetBattlePetCount(speciesId);
626 if (BattlePetSpeciesHasFlag(speciesId, BATTLE_PET_FLAG_UNIQUE) && speciesCount >= 1)
627 return false;
628
629 if (speciesCount >= BATTLE_PET_MAX_JOURNAL_SPECIES)
630 return false;
631
632 return true;
633}
634
636{
637 if (!battlePet)
638 return;
639
641 return;
642
643 // this shouldn't happen since the client doesn't allow releasing of slotted Battle Pets
644 uint8 srcSlot = GetLoadoutSlotForBattlePet(battlePet->GetId());
645 if (srcSlot != BATTLE_PET_LOADOUT_SLOT_NONE)
646 {
647 SetLoadoutSlot(srcSlot, 0, true);
648 SendBattlePetSlotUpdate(srcSlot, false);
649 }
650
653
654 // alert client of deleted pet
655 SendBattlePetDeleted(battlePet->GetId());
656}
657
659{
660 if (!percent)
661 return;
662
663 for (BattlePetSet::const_iterator citr = m_battlePetSet.begin(); citr != m_battlePetSet.end(); ++citr)
664 {
665 BattlePet* battlePet = *citr;
666 if (!battlePet || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
667 continue;
668
669 uint16 const health = BattlePetHealthFromPercent(battlePet->GetMaxHealth(), percent);
670 if (health <= battlePet->GetCurrentHealth())
671 continue;
672
673 battlePet->SetCurrentHealth(health);
674 SendBattlePetUpdate(battlePet, false);
675 }
676}
677
678void BattlePetMgr::StartWildPetBattle(uint64 enemyGuid, uint64 allyPetId, uint32 allyMaxHealth, uint32 allyHealth,
679 uint64 enemyPetId, uint32 enemyMaxHealth, uint32 enemyHealth,
680 uint16 enemySpecies, uint8 enemyLevel, uint8 enemyQuality, uint8 enemyBreed, uint8 allyFrontPet)
681{
682 m_petBattlePvpQueued = false;
683 m_activePetBattle.StartWild(enemyGuid, allyPetId, allyMaxHealth, allyHealth,
684 enemyPetId, enemyMaxHealth, enemyHealth, enemySpecies, enemyLevel, enemyQuality, enemyBreed, allyFrontPet);
685}
686
687void BattlePetMgr::StartPvpPetBattle(uint64 opponentGuid, uint64 allyPetId, uint32 allyMaxHealth, uint32 allyHealth,
688 uint64 enemyPetId, uint32 enemyMaxHealth, uint32 enemyHealth,
689 uint16 enemySpecies, uint8 enemyLevel, uint8 enemyQuality, uint8 allyFrontPet, uint8 enemyFrontPet,
691{
692 m_petBattlePvpQueued = false;
693 m_activePetBattle.StartPvp(opponentGuid, allyPetId, allyMaxHealth, allyHealth,
694 enemyPetId, enemyMaxHealth, enemyHealth, enemySpecies, enemyLevel, enemyQuality,
695 allyFrontPet, enemyFrontPet, source);
696}
697
699{
700 if (!m_owner || !creature || !m_activePetBattle.IsActive())
701 return;
702
705 m_owner->UpdateVisibilityOf(creature);
706}
707
709{
710 if (!m_owner)
711 return;
712
713 if (m_owner->IsMounted())
714 m_owner->RemoveAurasByType(SPELL_AURA_MOUNTED);
715
717 m_owner->SetFacingTo(m_owner->GetAngle(faceX, faceY));
718 m_owner->SetControlled(true, UNIT_STATE_ROOT);
720}
721
731
733{
734 if (!m_owner || !m_owner->IsInWorld() || !m_activePetBattle.IsActive()
735 || !m_activePetBattle.IsFinished() || m_activePetBattle.IsPvP())
736 return;
737
739 return;
740
741 uint64 const worldObjectGuid = m_activePetBattle.EnemyGUID;
742 if (Creature* creature = ObjectAccessor::GetCreature(*m_owner, worldObjectGuid))
743 {
744 if (sBattlePetSpawnMgr->ResolveWildBattle(creature))
745 {
746 if (m_activePetBattleWorldObjectGuid == worldObjectGuid)
747 {
750 }
751 }
752 else if (creature->ToTempSummon())
753 creature->DespawnOrUnsummon();
754 else
755 {
756 if (creature->IsAlive())
757 creature->setDeathState(DeathState::JUST_DIED);
758
759 creature->RemoveCorpse();
760 creature->SaveRespawnTime();
761 }
762
763 if (m_activePetBattleWorldObjectGuid == worldObjectGuid)
764 {
767 }
768 }
769}
770
772{
774 return;
775
776 uint64 const worldObjectGuid = m_activePetBattleWorldObjectGuid;
779
780 if (!m_owner || !m_owner->IsInWorld())
781 return;
782
783 if (Creature* creature = ObjectAccessor::GetCreature(*m_owner, worldObjectGuid))
784 m_owner->UpdateVisibilityOf(creature);
785}
786
800
802{
803 if (m_activePetBattle.IsPvP())
805
806 if (!GetTrapAbility())
808
809 uint16 const enemySpecies = m_activePetBattle.EnemySpecies;
810 bool const canStoreBattlePet = enemySpecies && CanCreateBattlePet(enemySpecies);
811 bool const enemyTameable = enemySpecies
813
814 return m_activePetBattle.GetTrapStatus(canStoreBattlePet, enemyTameable);
815}
816
817bool BattlePetMgr::SetActivePetBattleAllyPet(uint8 petIndex, uint64 petId, uint32 maxHealth, uint32 health)
818{
819 return m_activePetBattle.SetAllyPet(petIndex, petId, maxHealth, health);
820}
821
823{
824 return m_activePetBattle.SelectAllyFrontPet(frontPet);
825}
826
829{
830 ActivePetBattleTurn const turn = m_activePetBattle.ApplyEnemyAbilityRound(m_activePetBattle.RoundID, damage);
831 if (!turn.Accepted || !turn.HasRoundResult)
832 return false;
833
834 round = Skyfire::BattlePetPackets::BuildRoundResultFromTurn(turn, abilityEffectId);
836 return true;
837}
838
839bool BattlePetMgr::ApplyBattlePetAbilityInput(uint32 roundId, uint32 damage, uint32 abilityEffectId,
840 uint8 abilitySlot, uint32 abilityId, uint16 abilityCooldown,
843{
844 ActivePetBattleTurn const turn = m_activePetBattle.ApplyAbilityRound(roundId, damage,
845 abilitySlot, abilityId, abilityCooldown);
846 if (!turn.Accepted || !turn.HasRoundResult)
847 return false;
848
849 round = Skyfire::BattlePetPackets::BuildRoundResultFromTurn(turn, abilityEffectId);
851
852 if (finalRound && turn.HasFinalRound)
853 {
855 BuildActivePetBattleFinalRound(turn.Abandoned, *finalRound);
856 }
857
858 return true;
859}
860
862 uint32 allyDamage, uint32 allyAbilityEffectId,
863 uint8 allyAbilitySlot, uint32 allyAbilityId, uint16 allyAbilityCooldown,
864 uint32 enemyDamage, uint32 enemyAbilityEffectId,
865 uint32 allyIncomingDamageReduction, uint8 allyIncomingDamageReductionRounds,
866 uint32 enemyIncomingDamageReduction, uint8 enemyIncomingDamageReductionRounds,
869{
870 m_activePetBattle.ActivateAllyIncomingDamageReduction(
871 allyIncomingDamageReduction, allyIncomingDamageReductionRounds);
872 m_activePetBattle.ActivateEnemyIncomingDamageReduction(
873 enemyIncomingDamageReduction, enemyIncomingDamageReductionRounds);
874
875 ActivePetBattleTurn allyTurn;
876 ActivePetBattleTurn enemyTurn;
877 if (!m_activePetBattle.ApplyAbilityExchange(roundId, allyDamage, enemyDamage,
878 allyAbilitySlot, allyAbilityId, allyAbilityCooldown, allyTurn, enemyTurn))
879 return false;
880
881 if (!allyTurn.Accepted || !allyTurn.HasRoundResult)
882 return false;
883
884 round.RoundID = roundId;
887 allyTurn.CasterPet, allyTurn.TargetPet, int32(allyTurn.RemainingHealth), allyAbilityEffectId, 1));
888
889 if (enemyTurn.Accepted && enemyTurn.HasRoundResult)
890 {
892 enemyTurn.CasterPet, enemyTurn.TargetPet, int32(enemyTurn.RemainingHealth), enemyAbilityEffectId, 2));
893
894 if (enemyTurn.RequiresFrontPet)
896 }
897
899
900 if (finalRound && (allyTurn.HasFinalRound || enemyTurn.HasFinalRound))
901 {
903 BuildActivePetBattleFinalRound(false, *finalRound);
904 }
905
906 return true;
907}
908
911{
912 ActivePetBattleTurn const turn = m_activePetBattle.ApplySwapRound(roundId, newFrontPet);
913 if (!turn.Accepted || !turn.HasRoundResult)
914 return false;
915
918 return true;
919}
920
923{
924 ActivePetBattleTurn const turn = m_activePetBattle.ApplyForfeit(roundId);
925 if (!turn.Accepted || !turn.HasFinalRound)
926 return false;
927
929 return BuildActivePetBattleFinalRound(turn.Abandoned, finalRound);
930}
931
932bool BattlePetMgr::ApplyBattlePetTrapInput(uint32 roundId, uint32 trapAbilityEffectId,
933 uint32 enemyDamage, uint32 enemyAbilityEffectId,
936{
937 if (!m_activePetBattle.CanAcceptInput(roundId))
938 return false;
939
941 return false;
942
943 uint32 const trapAbility = GetTrapAbility();
944 bool const captured = roll_chance_f(BattlePetTrapCaptureChance(trapAbility, m_activePetBattle.TrapFailedAttempts));
945
946 ActivePetBattleTurn trapTurn;
947 ActivePetBattleTurn enemyTurn;
948 if (!m_activePetBattle.ApplyTrapRoundWithEnemyResponse(roundId, captured, enemyDamage, trapTurn, enemyTurn))
949 return false;
950
951 round.RoundID = trapTurn.RoundID;
954 m_activePetBattle.EnemyFrontPet, trapAbilityEffectId, trapTurn.Captured, 1));
955 if (trapTurn.Captured)
957 else if (enemyTurn.Accepted && enemyTurn.HasRoundResult)
958 {
960 enemyTurn.CasterPet, enemyTurn.TargetPet, int32(enemyTurn.RemainingHealth), enemyAbilityEffectId, 2));
961
962 if (enemyTurn.TargetDied)
963 round.DeadPets.push_back(enemyTurn.TargetPet);
964
965 if (enemyTurn.RequiresFrontPet)
967 }
968
970
971 if (!trapTurn.Captured && !enemyTurn.HasFinalRound)
972 return true;
973
974 if (!trapTurn.HasFinalRound && !enemyTurn.HasFinalRound)
975 return false;
976
977 if (trapTurn.Captured)
978 {
979 uint8 const capturedLevel = BattlePetCapturedLevel(m_activePetBattle.EnemyLevel);
980 BattlePet* capturedPet = Create(m_activePetBattle.EnemySpecies,
981 capturedLevel, m_activePetBattle.EnemyQuality, m_activePetBattle.EnemyBreed);
982 if (!capturedPet)
983 return false;
984
986 }
987
989 return BuildActivePetBattleFinalRound(false, finalRound, trapTurn.Captured);
990}
991
998
1000{
1001 if (!m_activePetBattle.IsActive())
1002 return;
1003
1004 for (BattlePetSet::const_iterator itr = m_battlePetSet.begin(); itr != m_battlePetSet.end(); ++itr)
1005 {
1006 BattlePet* battlePet = *itr;
1007 if (!battlePet || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
1008 continue;
1009
1010 uint32 activeHealth = 0;
1011 if (!m_activePetBattle.GetAllyPetHealth(battlePet->GetId(), activeHealth))
1012 continue;
1013
1014 uint16 const health = activeHealth > battlePet->GetMaxHealth()
1015 ? battlePet->GetMaxHealth()
1016 : uint16(activeHealth);
1017 battlePet->SetCurrentHealth(health);
1018 }
1019}
1020
1022{
1023 if (m_activePetBattle.IsActive())
1024 m_activePetBattle.Finish(winner);
1025}
1026
1028{
1029 if (!awardExperience || !battlePet || !m_activePetBattle.EnemyLevel)
1030 return 0;
1031
1032 if (battlePet->GetLevel() >= BATTLE_PET_MAX_LEVEL)
1033 return 0;
1034
1035 uint16 const reward = BattlePetExperienceReward(battlePet->GetLevel(), m_activePetBattle.EnemyLevel);
1036 return battlePet->AddExperience(reward);
1037}
1038
1040{
1041 std::set<uint16> species;
1042
1043 for (BattlePetSet::const_iterator itr = m_battlePetSet.begin(); itr != m_battlePetSet.end(); ++itr)
1044 {
1045 BattlePet const* battlePet = *itr;
1046 if (!battlePet || battlePet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
1047 continue;
1048
1049 species.insert(battlePet->GetSpecies());
1050 }
1051
1052 return uint32(species.size());
1053}
1054
1056 uint16 speciesId, uint8 quality, bool won, bool captured) const
1057{
1059 context.Species = speciesId;
1060 context.FamilyMask = BattlePetSpeciesFamilyMask(speciesId);
1061 context.Quality = quality;
1062 context.Source = m_activePetBattle.GetAchievementSource();
1063 context.HealthPercent = BattlePetHealthPercent(m_activePetBattle.EnemyHealth, m_activePetBattle.EnemyMaxHealth);
1064 context.Won = won;
1065 context.Captured = captured;
1066 return context;
1067}
1068
1070{
1071 if (!m_owner)
1072 return;
1073
1074 if (!battlePet)
1075 {
1076 for (BattlePetSet::const_iterator itr = m_battlePetSet.begin(); itr != m_battlePetSet.end(); ++itr)
1077 {
1078 BattlePet const* existingPet = *itr;
1079 if (!existingPet || !existingPet->GetSpecies() || existingPet->GetDbState() == BattlePetDbState::BATTLE_PET_DB_STATE_DELETE)
1080 continue;
1081
1082 uint16 const speciesId = existingPet->GetSpecies();
1083 if (uint32 const npcId = BattlePetSpeciesNpcId(speciesId))
1084 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET, npcId);
1085
1086 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET_SPECIES, speciesId);
1087
1088 if (uint32 const summonSpell = BattlePetGetSummonSpell(speciesId))
1089 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, summonSpell);
1090 }
1091
1093 return;
1094 }
1095
1097 {
1098 uint16 const speciesId = battlePet->GetSpecies();
1099 if (uint32 const npcId = BattlePetSpeciesNpcId(speciesId))
1100 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET, npcId);
1101
1102 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET_SPECIES, speciesId);
1103
1104 if (uint32 const summonSpell = BattlePetGetSummonSpell(speciesId))
1105 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, summonSpell);
1106 }
1107
1109}
1110
1112{
1113 if (!m_owner)
1114 return;
1115
1117 battlePet.GetSpecies(), battlePet.GetQuality(), true, true);
1118 if (!context.IsValid())
1119 return;
1120
1121 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET,
1122 context.Species, context.FamilyMask, context.Payload());
1123 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET2,
1124 1, context.FamilyMask, context.Payload());
1125}
1126
1127void BattlePetMgr::UpdateBattlePetLevelAchievement(BattlePet const& battlePet, uint8 initialLevel, uint8 finalLevel)
1128{
1129 if (!m_owner || finalLevel <= initialLevel)
1130 return;
1131
1132 uint32 const familyMask = BattlePetSpeciesFamilyMask(battlePet.GetSpecies());
1133 for (uint8 level = initialLevel + 1; level <= finalLevel; ++level)
1134 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_BATTLE_PET_LEVEL, level, familyMask);
1135}
1136
1138{
1139 if (!m_owner || !m_activePetBattle.IsFinished() || m_activePetBattle.AchievementsApplied)
1140 return;
1141
1142 m_activePetBattle.AchievementsApplied = true;
1143
1145 return;
1146
1148 m_activePetBattle.EnemySpecies, m_activePetBattle.EnemyQuality, true, false);
1149 if (!context.IsValid())
1150 return;
1151
1152 m_owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_PET_BATTLE,
1153 context.Species, context.FamilyMask, context.Payload());
1154}
1155
1157 Skyfire::BattlePetPackets::BattlePetFinalRound& finalRound, bool captured)
1158{
1159 if (!m_activePetBattle.IsActive())
1160 return false;
1161
1162 bool const awardExperience = !m_activePetBattle.IsPvP() && !abandoned && !captured && !m_activePetBattle.Captured
1163 && !m_activePetBattle.RewardsApplied && m_activePetBattle.Winner == PET_BATTLE_WINNER_ALLY;
1164
1165 std::vector<Skyfire::BattlePetPackets::BattlePetFinalRoundPet> pets;
1167 {
1168 if (!m_activePetBattle.HasAllyPet(i))
1169 continue;
1170
1172 BattlePet* battlePet = GetBattlePet(m_activePetBattle.AllyTeam[i].PetID);
1173 uint8 const initialLevel = battlePet ? battlePet->GetLevel() : 0;
1174 bool const petEarnedExperience = awardExperience && i == m_activePetBattle.AllyFrontPet
1175 && m_activePetBattle.AllyTeam[i].Health != 0;
1176 uint16 const awardedXp = RewardActivePetBattlePet(
1177 battlePet, petEarnedExperience);
1178 uint8 const finalLevel = battlePet ? battlePet->GetLevel() : initialLevel;
1179 uint16 const finalXp = battlePet ? battlePet->GetXp() : 0;
1180
1181 if (battlePet)
1182 UpdateBattlePetLevelAchievement(*battlePet, initialLevel, finalLevel);
1183
1184 allyPet.Pboid = i;
1185 allyPet.RemainingHealth = battlePet ? battlePet->GetCurrentHealth() : m_activePetBattle.AllyTeam[i].Health;
1186 allyPet.InitialLevel = initialLevel;
1187 allyPet.NewLevel = finalLevel;
1188 allyPet.Xp = finalXp;
1189 allyPet.MaxHealth = battlePet ? battlePet->GetMaxHealth() : m_activePetBattle.AllyTeam[i].MaxHealth;
1190 allyPet.SeenAction = true;
1191 allyPet.AwardedXP = awardedXp != 0 || finalLevel != initialLevel;
1192 pets.push_back(allyPet);
1193 }
1194
1195 if (awardExperience)
1196 m_activePetBattle.RewardsApplied = true;
1197
1199
1201 enemyPet.Pboid = m_activePetBattle.EnemyFrontPet;
1202 enemyPet.RemainingHealth = m_activePetBattle.EnemyHealth;
1203 enemyPet.MaxHealth = m_activePetBattle.EnemyMaxHealth;
1204 enemyPet.SeenAction = true;
1205 enemyPet.Captured = captured || m_activePetBattle.Captured;
1206 enemyPet.Caged = enemyPet.Captured;
1207 pets.push_back(enemyPet);
1208
1210 m_activePetBattle.Winner == PET_BATTLE_WINNER_ALLY, abandoned, pets);
1211 finalRound.PvPBattle = m_activePetBattle.IsPvP();
1212 finalRound.Winners[0] = m_activePetBattle.Winner == PET_BATTLE_WINNER_ALLY;
1213 finalRound.Winners[1] = m_activePetBattle.Winner == PET_BATTLE_WINNER_ENEMY;
1214
1215 return true;
1216}
1217
1219{
1220 ObjectGuid petEntry = id;
1221
1223 data.WriteGuidMask(petEntry, 0, 4, 7, 6, 1, 5, 2, 3);
1224 data.WriteGuidBytes(petEntry, 6, 1, 7, 0, 4, 3, 5, 2);
1225
1226 m_owner->GetSession()->SendPacket(&data);
1227}
1228
1230{
1232 m_owner->GetSession()->SendPacket(&data);
1233
1234 /*WorldPacket data(SMSG_BATTLE_PET_JOURNAL_LOCK_DENINED, 0);
1235 m_owner->GetSession()->SendPacket(&data);*/
1236}
1237
1239{
1241 m_owner->GetSession()->SendPacket(&data);
1242}
1243
1245{
1246 uint32 petCount = 0;
1247 ByteBuffer journalData, slotData;
1248
1249 // packet size is over estimated
1250 WorldPacket data(SMSG_BATTLE_PET_JOURNAL, 8 + m_battlePetSet.size() * (2 + 1 + 8 + 1 + 4 + 2 + 4 + 2 + 4 + 2 + 4 + 4 + 4 + 16 + 4 + 2)
1251 + BATTLE_PET_MAX_LOADOUT_SLOTS * (1 + 1 + 8 + 1));
1252
1253 size_t writePos = data.bitwpos();
1254 data.WriteBits(petCount, 19); // placeholder
1255
1256 for (BattlePetSet::const_iterator citr = m_battlePetSet.begin(); citr != m_battlePetSet.end(); ++citr)
1257 {
1258 BattlePet const* battlePet = *citr;
1259 if (!battlePet)
1260 continue;
1261
1263 continue;
1264
1265 CreatureTemplate const* creatureTemplate = GetBattlePetCreatureTemplate(battlePet);
1266 if (!creatureTemplate)
1267 continue;
1268
1269 ObjectGuid petEntry = battlePet->GetId();
1270
1271 data.WriteBit(!battlePet->GetFlags());
1272 data.WriteBit(petEntry[3]);
1273 data.WriteBit(petEntry[7]);
1274 data.WriteBits(battlePet->GetNickname().size(), 7);
1275 data.WriteBit(0); // BATTLE_PET_FLAG_NOT_ACCOUNT_BOUND
1276 data.WriteBit(petEntry[0]);
1277 data.WriteBit(petEntry[2]);
1278 data.WriteBit(petEntry[6]);
1279 data.WriteBit(0); // unknown
1280 data.WriteBit(petEntry[1]);
1281 data.WriteBit(petEntry[5]);
1282 data.WriteBit(!battlePet->GetBreed());
1283 data.WriteBit(petEntry[4]);
1284 data.WriteBit(!battlePet->GetQuality());
1285
1286 if (battlePet->GetQuality())
1287 journalData << uint8(battlePet->GetQuality());
1288
1289 journalData << uint32(battlePet->GetPower());
1290 journalData.WriteByteSeq(petEntry[7]);
1291 journalData << uint16(battlePet->GetLevel());
1292 journalData << uint32(battlePet->GetCurrentHealth());
1293
1294 if (battlePet->GetBreed())
1295 journalData << uint16(battlePet->GetBreed());
1296
1297 journalData << uint32(battlePet->GetSpecies());
1298 journalData.WriteByteSeq(petEntry[2]);
1299
1300 if (battlePet->GetFlags())
1301 journalData << uint16(battlePet->GetFlags());
1302
1303 journalData << uint32(creatureTemplate->Entry);
1304 journalData << uint32(creatureTemplate->Modelid1);
1305 journalData << uint32(battlePet->GetSpeed());
1306 journalData.WriteString(battlePet->GetNickname());
1307 journalData.WriteByteSeq(petEntry[6]);
1308 journalData.WriteByteSeq(petEntry[5]);
1309 journalData << uint32(battlePet->GetMaxHealth());
1310 journalData.WriteByteSeq(petEntry[4]);
1311 journalData << uint16(battlePet->GetXp());
1312 journalData.WriteByteSeq(petEntry[0]);
1313 journalData.WriteByteSeq(petEntry[1]);
1314 journalData.WriteByteSeq(petEntry[3]);
1315
1316 petCount++;
1317 }
1318
1319 data.WriteBit(1); // slots enabled
1321
1322 for (uint8 i = 0; i < BATTLE_PET_MAX_LOADOUT_SLOTS; i++)
1323 {
1324 ObjectGuid loadoutEntry = GetLoadoutSlot(i);
1325
1326 data.WriteBit(!HasLoadoutSlot(i));
1327 data.WriteBit(1); // unknown
1328 data.WriteBit(0); // has slot number
1329 data.WriteBit(0); // fake
1330 data.WriteBit(loadoutEntry[0]);
1331 data.WriteBit(loadoutEntry[1]);
1332 data.WriteBit(loadoutEntry[7]);
1333 data.WriteBit(loadoutEntry[6]);
1334 data.WriteBit(loadoutEntry[4]);
1335 data.WriteBit(loadoutEntry[2]);
1336 data.WriteBit(loadoutEntry[5]);
1337 data.WriteBit(loadoutEntry[3]);
1338
1339 slotData.WriteByteSeq(loadoutEntry[5]);
1340 slotData.WriteByteSeq(loadoutEntry[1]);
1341 slotData.WriteByteSeq(loadoutEntry[7]);
1342 slotData.WriteByteSeq(loadoutEntry[2]);
1343 slotData.WriteByteSeq(loadoutEntry[3]);
1344 slotData.WriteByteSeq(loadoutEntry[0]);
1345 slotData.WriteByteSeq(loadoutEntry[4]);
1346 slotData.WriteByteSeq(loadoutEntry[6]);
1347 slotData << uint8(i);
1348 }
1349
1350 data.FlushBits();
1351 data.PutBits(writePos, petCount, 19);
1352
1353 data.append(slotData);
1354 data.append(journalData);
1355 data << uint16(0); // unknown
1356
1357 m_owner->GetSession()->SendPacket(&data);
1358}
1359
1360void BattlePetMgr::SendBattlePetSlotUpdate(uint8 slot, bool notification, uint64 id)
1361{
1362 ObjectGuid petEntry = id;
1363
1365 data.WriteBits(1, 25);
1366 data.WriteBit(0); // unknown
1367
1368 {
1369 data.WriteBit(0); // has slot number
1370 data.WriteBit(1); // unknown
1371 data.WriteBit(0); // unknown
1372 data.WriteBit(0); // fake
1373 data.WriteBit(petEntry[4]);
1374 data.WriteBit(petEntry[5]);
1375 data.WriteBit(petEntry[2]);
1376 data.WriteBit(petEntry[1]);
1377 data.WriteBit(petEntry[0]);
1378 data.WriteBit(petEntry[3]);
1379 data.WriteBit(petEntry[7]);
1380 data.WriteBit(petEntry[6]);
1381 }
1382
1383 data.WriteBit(notification);
1384 data.FlushBits();
1385
1386 {
1387 data.WriteByteSeq(petEntry[0]);
1388 data.WriteByteSeq(petEntry[3]);
1389 data.WriteByteSeq(petEntry[2]);
1390 data.WriteByteSeq(petEntry[1]);
1391 data.WriteByteSeq(petEntry[6]);
1392 data.WriteByteSeq(petEntry[4]);
1393 data.WriteByteSeq(petEntry[5]);
1394 data.WriteByteSeq(petEntry[7]);
1395 data << uint8(slot);
1396 }
1397
1398 m_owner->GetSession()->SendPacket(&data);
1399}
1400
1401void BattlePetMgr::SendBattlePetUpdate(BattlePet* battlePet, bool notification)
1402{
1403 if (!battlePet)
1404 return;
1405
1406 ObjectGuid petEntry = battlePet->GetId();
1407
1408 CreatureTemplate const* creatureTemplate = GetBattlePetCreatureTemplate(battlePet);
1409 if (!creatureTemplate)
1410 return;
1411
1412 WorldPacket data(SMSG_BATTLE_PET_PET_UPDATES, 4 + 1 + 8 + battlePet->GetNickname().size() + 4 + 4 + 4 + 4 + 2 + 4 + 4 + 1 + 2 + 2 + 4 + 2);
1413 data.WriteBits(1, 19);
1414 data.WriteBit(petEntry[4]);
1415 data.WriteBit(petEntry[1]);
1416 data.WriteBit(petEntry[7]);
1417 data.WriteBit(!battlePet->GetQuality());
1418 data.WriteBit(!battlePet->GetBreed());
1419 data.WriteBit(petEntry[5]);
1420 data.WriteBit(0); // unknown
1421 data.WriteBit(petEntry[2]);
1422 data.WriteBit(!battlePet->GetFlags());
1423 data.WriteBit(0); // BATTLE_PET_FLAG_NOT_ACCOUNT_BOUND
1424 data.WriteBit(petEntry[6]);
1425 data.WriteBit(petEntry[3]);
1426 data.WriteBits(battlePet->GetNickname().size(), 7);
1427 data.WriteBit(petEntry[0]);
1428 data.WriteBit(notification);
1429 data.FlushBits();
1430
1431 data.WriteByteSeq(petEntry[1]);
1432 data.WriteString(battlePet->GetNickname());
1433 data << uint32(battlePet->GetCurrentHealth());
1434 data << uint32(battlePet->GetSpecies());
1435 data.WriteByteSeq(petEntry[0]);
1436 data << uint32(battlePet->GetPower());
1437 data << uint32(battlePet->GetSpeed());
1438
1439 if (battlePet->GetBreed())
1440 data << uint16(battlePet->GetBreed());
1441
1442 data.WriteByteSeq(petEntry[4]);
1443 data << uint32(creatureTemplate->Entry);
1444 data << uint32(battlePet->GetMaxHealth());
1445 data.WriteByteSeq(petEntry[6]);
1446
1447 if (battlePet->GetQuality())
1448 data << uint8(battlePet->GetQuality());
1449
1450 data.WriteByteSeq(petEntry[2]);
1451 data.WriteByteSeq(petEntry[3]);
1452 data << uint16(battlePet->GetXp());
1453 data.WriteByteSeq(petEntry[7]);
1454
1455 if (battlePet->GetFlags())
1456 data << uint16(battlePet->GetFlags());
1457
1458 data.WriteByteSeq(petEntry[5]);
1459 data << uint32(creatureTemplate->Modelid1);
1460 data << uint16(battlePet->GetLevel());
1461
1462 m_owner->GetSession()->SendPacket(&data);
1463}
uint16 BattlePetExperienceReward(uint8 petLevel, uint8 enemyLevel, uint8 participatingPetCount)
uint16 BattlePetHealthFromPercent(uint16 maxHealth, uint8 percent)
uint32 BattlePetSpeciesFamilyMask(uint16 speciesId)
uint32 BattlePetSpeciesNpcId(uint16 speciesId)
BattlePetAchievementSource
Definition BattlePet.h:19
#define BATTLE_PET_MAX_LEVEL
Definition BattlePet.h:12
uint8 BattlePetCapturedLevel(uint8 level)
Definition BattlePet.h:40
@ PET_BATTLE_TRAP_STATUS_UNAVAILABLE
@ PET_BATTLE_TRAP_STATUS_ACTIVE
@ PET_BATTLE_WINNER_ALLY
@ PET_BATTLE_WINNER_ENEMY
uint8 BattlePetLoadoutSlotForAchievement(uint32 achievementId)
@ BATTLE_PET_ABILITY_STRONG_TRAP
@ BATTLE_PET_ABILITY_GM_TRAP
@ BATTLE_PET_ABILITY_TRAP
@ BATTLE_PET_ABILITY_PRISTINE_TRAP
@ SPELL_REVIVE_BATTLE_PETS
@ SPELL_BATTLE_PET_TRAINING_PASSIVE
@ SPELL_TRACK_PETS
@ BATTLE_PET_ACHIEVEMENT_JUST_A_PUP
@ BATTLE_PET_ACHIEVEMENT_NEWBIE
#define BATTLE_PET_MAX_LOADOUT_SLOTS
#define BATTLE_PET_MAX_JOURNAL_SPECIES
@ BATTLE_PET_LOADOUT_SLOT_NONE
@ BATTLE_PET_LOADOUT_SLOT_1
@ BATTLE_PET_LOADOUT_SLOT_3
@ BATTLE_PET_LOADOUT_SLOT_2
#define BATTLE_PET_MAX_JOURNAL_PETS
@ BATTLE_PET_LOADOUT_SLOT_FLAG_SLOT_1
@ BATTLE_PET_LOADOUT_SLOT_FLAG_SLOT_2
@ BATTLE_PET_LOADOUT_SLOT_FLAG_SLOT_3
@ BATTLE_PET_LOADOUT_SLOT_FLAG_NONE
@ BATTLE_PET_LOADOUT_TRAP
uint32 BattlePetTrapAbilityForLoadoutFlags(uint8 flags)
#define sBattlePetSpawnMgr
@ CHAR_DEL_ACCOUNT_BATTLE_PET
@ CHAR_INS_ACCOUNT_BATTLE_PET
@ CHAR_DEL_ACCOUNT_BATTLE_PET_SLOTS
@ CHAR_INS_ACCOUNT_BATTLE_PET_SLOTS
@ BATTLE_PET_FLAG_UNIQUE
Definition DB2Enums.h:18
@ BATTLE_PET_FLAG_NOT_TAMEABLE
Definition DB2Enums.h:17
bool BattlePetSpeciesHasFlag(uint16 speciesId, uint16 flag)
DB2Storage< BattlePetSpeciesEntry > sBattlePetSpeciesStore(BattlePetSpeciesfmt)
BattlePetBreedSet sBattlePetBreedSet
Definition DB2Stores.cpp:47
uint32 BattlePetGetSummonSpell(uint16 speciesId)
@ ACHIEVEMENT_CRITERIA_TYPE_REACH_BATTLE_PET_LEVEL
Definition DBCEnums.h:289
@ ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL
Definition DBCEnums.h:199
@ ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET_COUNT
Definition DBCEnums.h:286
@ ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET_SPECIES
Definition DBCEnums.h:285
@ ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET
Definition DBCEnums.h:287
@ ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET2
Definition DBCEnums.h:290
@ ACHIEVEMENT_CRITERIA_TYPE_COLLECT_BATTLE_PET
Definition DBCEnums.h:255
@ ACHIEVEMENT_CRITERIA_TYPE_WIN_PET_BATTLE
Definition DBCEnums.h:288
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
std::uint16_t uint16
Definition Define.h:78
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define sObjectMgr
Definition ObjectMgr.h:1617
@ PLAYER_FLAGS_BATTLE_PET_ENABLED
Definition Player.h:561
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
@ ITEM_QUALITY_NORMAL
@ ITEM_QUALITY_LEGENDARY
@ SPELL_AURA_MOUNTED
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ JUST_DIED
Definition Unit.h:504
@ UNIT_STATE_ROOT
Definition Unit.h:522
@ UNIT_FLAG_IMMUNE_TO_NPC
Definition Unit.h:634
@ UNIT_FLAG_PACIFIED
Definition Unit.h:642
@ UNIT_FIELD_FLAGS
@ PLAYER_FIELD_PLAYER_FLAGS
bool roll_chance_f(float chance)
Definition Util.h:83
uint16 GetXp() const
Definition BattlePet.h:220
uint16 GetSpeed() const
Definition BattlePet.h:224
uint8 GetLevel() const
Definition BattlePet.h:219
void SetCurrentHealth(uint16 health)
uint8 GetQuality() const
Definition BattlePet.h:225
uint64 GetId() const
Definition BattlePet.h:215
uint16 GetCurrentHealth() const
Definition BattlePet.h:221
uint16 GetSpecies() const
Definition BattlePet.h:216
uint16 GetMaxHealth() const
Definition BattlePet.h:222
uint16 GetPower() const
Definition BattlePet.h:223
std::string GetNickname() const
Definition BattlePet.h:217
uint8 GetBreed() const
Definition BattlePet.h:226
void SetDbState(BattlePetDbState state)
Definition BattlePet.h:235
uint16 AddExperience(uint16 xp)
BattlePetDbState GetDbState() const
Definition BattlePet.h:234
uint32 GetTimestamp() const
Definition BattlePet.h:218
uint16 GetFlags() const
Definition BattlePet.h:237
bool SetActivePetBattleAllyPet(uint8 petIndex, uint64 petId, uint32 maxHealth, uint32 health)
void ClearActivePetBattleWorldObjectState()
uint8 GetLoadoutFlags() const
uint16 RewardActivePetBattlePet(BattlePet *battlePet, bool awardExperience)
void OnAchievementEarned(uint32 achievementId)
void StartPvpPetBattle(uint64 opponentGuid, uint64 allyPetId, uint32 allyMaxHealth, uint32 allyHealth, uint64 enemyPetId, uint32 enemyMaxHealth, uint32 enemyHealth, uint16 enemySpecies=0, uint8 enemyLevel=0, uint8 enemyQuality=0, uint8 allyFrontPet=0, uint8 enemyFrontPet=3, BattlePetAchievementSource source=BATTLE_PET_ACHIEVEMENT_SOURCE_PVP_DUEL)
bool ApplyBattlePetAbilityInput(uint32 roundId, uint32 damage, uint32 abilityEffectId, uint8 abilitySlot, uint32 abilityId, uint16 abilityCooldown, Skyfire::BattlePetPackets::BattlePetRoundResult &round, Skyfire::BattlePetPackets::BattlePetFinalRound *finalRound=NULL)
uint8 GetActivePetBattleTrapStatus() const
void ClearActivePetBattlePlayerState()
uint32 GetTrapAbility() const
void HideActivePetBattleWorldObject(Creature *creature)
uint32 GetBattlePetCount() const
void SetLoadoutFlag(uint8 flag)
void SendBattlePetJournal()
void Delete(BattlePet *battlePet)
bool HasLoadoutFlag(uint8 flag) const
void ClearActivePetBattle()
BattlePet * GetFirstAliveLoadoutBattlePet() const
bool m_petBattlePvpQueued
void ResummonLastBattlePet()
void UpdateCapturedBattlePetAchievements(BattlePet const &battlePet)
bool ApplyBattlePetAbilityExchangeInput(uint32 roundId, uint32 allyDamage, uint32 allyAbilityEffectId, uint8 allyAbilitySlot, uint32 allyAbilityId, uint16 allyAbilityCooldown, uint32 enemyDamage, uint32 enemyAbilityEffectId, uint32 allyIncomingDamageReduction, uint8 allyIncomingDamageReductionRounds, uint32 enemyIncomingDamageReduction, uint8 enemyIncomingDamageReductionRounds, Skyfire::BattlePetPackets::BattlePetRoundResult &round, Skyfire::BattlePetPackets::BattlePetFinalRound *finalRound=NULL)
void PersistActivePetBattleHealth()
void SyncAchievementLoadoutRewards()
std::string GetBattlePetSpeciesName(BattlePet const *battlePet) const
uint64 m_activePetBattleWorldObjectGuid
void SendBattlePetSlotUpdate(uint8 slot, bool notification, uint64 id=0)
uint32 GetUniqueBattlePetSpeciesCount() const
bool m_activePetBattleWorldObjectHidden
void UpdateFinishedPetBattleAchievements()
void FinishActivePetBattle(uint8 winner)
uint8 m_loadoutFlags
bool ApplyBattlePetTrapInput(uint32 roundId, uint32 trapAbilityEffectId, uint32 enemyDamage, uint32 enemyAbilityEffectId, Skyfire::BattlePetPackets::BattlePetRoundResult &round, Skyfire::BattlePetPackets::BattlePetFinalRound &finalRound)
BattlePet * Create(uint16 speciesId)
BattlePetSet m_battlePetSet
uint64 m_loadout[BATTLE_PET_MAX_LOADOUT_SLOTS]
bool ApplyEnemyBattlePetDamage(uint32 damage, uint32 abilityEffectId, Skyfire::BattlePetPackets::BattlePetRoundResult &round)
bool ApplyBattlePetSwapInput(uint32 roundId, uint8 newFrontPet, Skyfire::BattlePetPackets::BattlePetRoundResult &round)
void SendBattlePetJournalLock()
ActivePetBattle m_activePetBattle
bool ApplyAchievementLoadoutReward(uint32 achievementId)
void LoadSlotsFromDb(PreparedQueryResult result)
uint64 GetLoadoutSlot(uint8 slot) const
BattlePetAchievementContext BuildActivePetBattleAchievementContext(uint16 speciesId, uint8 quality, bool won, bool captured) const
uint8 GetLoadoutSlotForBattlePet(uint64 id) const
bool HasLoadoutSlot(uint8 slot) const
void ApplyActivePetBattleRoundState(Skyfire::BattlePetPackets::BattlePetRoundResult &round) const
uint64 m_summonLastId
void LoadFromDb(PreparedQueryResult result)
void StartWildPetBattle(uint64 enemyGuid, uint64 allyPetId, uint32 allyMaxHealth, uint32 allyHealth, uint64 enemyPetId, uint32 enemyMaxHealth, uint32 enemyHealth, uint16 enemySpecies=0, uint8 enemyLevel=0, uint8 enemyQuality=0, uint8 enemyBreed=0, uint8 allyFrontPet=0)
void DespawnResolvedWildPetBattleWorldObject()
bool ApplyBattlePetForfeitInput(uint32 roundId, Skyfire::BattlePetPackets::BattlePetFinalRound &finalRound)
void SaveSlotsToDb(SQLTransaction &trans)
BattlePet * GetBattlePet(uint64 id) const
void UpdateBattlePetLevelAchievement(BattlePet const &battlePet, uint8 initialLevel, uint8 finalLevel)
void SetLoadoutSlot(uint8 slot, uint64 id, bool save=false)
void SendBattlePetUpdate(BattlePet *battlePet, bool notification)
bool BuildActivePetBattleFinalRound(bool abandoned, Skyfire::BattlePetPackets::BattlePetFinalRound &finalRound, bool captured=false)
Player * m_owner
bool CanCreateBattlePet(uint16 speciesId) const
TempSummon * m_summon
void SendBattlePetDeleted(uint64 id)
bool m_activePetBattlePlayerStateApplied
void UnSummonCurrentBattlePet(bool temporary)
void ApplyActivePetBattlePlayerState(float faceX, float faceY)
void SendPetBattleRequestFailed(uint8 reason)
std::vector< BattlePet * > FindBattlePetNameMatches(std::string const &name) const
void HealBattlePets(uint8 percent)
bool HasLoadoutBattlePet() const
void UpdateBattlePetCollectionAchievements(BattlePet const *battlePet=NULL)
uint64 m_summonId
bool SelectActivePetBattleFrontPet(uint8 frontPet)
void UnlockLoadoutSlot(uint8 slot)
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
size_t bitwpos() const
Returns position of last written bit.
Definition ByteBuffer.h:492
void WriteString(std::string const &str)
Definition ByteBuffer.h:578
void append(T value)
Definition ByteBuffer.h:147
void PutBits(size_t pos, T value, uint32 bitCount)
Definition ByteBuffer.h:283
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
uint64 GetUInt64() const
Definition Field.h:141
uint16 GetUInt16() const
Definition Field.h:69
uint32 GetUInt32() const
Definition Field.h:105
static Creature * GetCreature(WorldObject const &u, uint64 guid)
uint64 GetGUID() const
Definition Object.h:119
void setString(const uint8 index, const std::string &value)
void setUInt16(const uint8 index, const uint16 value)
void setUInt64(const uint8 index, const uint64 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED
Definition Opcodes.h:557
@ SMSG_BATTLE_PET_SLOT_UPDATE
Definition Opcodes.h:561
@ SMSG_BATTLE_PET_JOURNAL
Definition Opcodes.h:556
@ SMSG_BATTLE_PET_PET_UPDATES
Definition Opcodes.h:559
@ SMSG_BATTLE_PET_DELETED
Definition Opcodes.h:554
#define sWorld
Definition World.h:910
@ CONFIG_BATTLE_PET_INITIAL_LEVEL
Definition World.h:362
WorldPacket BuildRequestFailedPacket(uint8 reason)
BattlePetRoundResult BuildRoundResultFromTurn(ActivePetBattleTurn const &turn, uint32 abilityEffectId)
BattlePetRoundEffect BuildCatchEffect(uint8 casterPet, uint8 targetPet, uint32 abilityEffectId, bool captured, uint16 turnInstanceId)
BattlePetRoundEffect BuildDamageEffect(uint8 casterPet, uint8 targetPet, int32 remainingHealth, uint32 abilityEffectId, uint16 turnInstanceId)
void AppendRoundCooldowns(BattlePetRoundResult &round, ActivePetBattleTurn const &turn)
BattlePetFinalRound BuildFinalRoundState(bool allyWon, bool abandoned, std::vector< BattlePetFinalRoundPet > const &pets)
void MarkRoundResultAsCatchOrKill(BattlePetRoundResult &round)
static constexpr uint8 BATTLE_PET_MAX_ACTIVE_TEAM_PETS
BattlePetAchievementSource Source
Definition BattlePet.h:93
uint32 NpcId
uint32 Modelid1
Definition Creature.h:67
std::string Name
Definition Creature.h:71
std::vector< BattlePetRoundEffect > Effects