TrinityCore
Pet.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Pet.h"
19#include "CharmInfo.h"
20#include "Common.h"
21#include "DatabaseEnv.h"
22#include "DB2Stores.h"
23#include "Group.h"
24#include "InstanceScript.h"
25#include "Log.h"
26#include "Map.h"
27#include "ObjectMgr.h"
28#include "PetPackets.h"
29#include "PhasingHandler.h"
30#include "Player.h"
31#include "QueryHolder.h"
32#include "Spell.h"
33#include "SpellAuraEffects.h"
34#include "SpellAuras.h"
35#include "SpellHistory.h"
36#include "SpellMgr.h"
37#include "SpellPackets.h"
38#include "Unit.h"
39#include "Util.h"
40#include "World.h"
41#include "WorldSession.h"
42#include <sstream>
43
44#define PET_XP_FACTOR 0.05f
45
46Pet::Pet(Player* owner, PetType type) :
47 Guardian(nullptr, owner, true), m_removed(false),
48 m_petType(type), m_duration(0), m_loading(false), m_groupUpdateMask(0),
49 m_petSpecialization(0)
50{
52
54 if (type == HUNTER_PET)
56
58 {
61 }
62
63 m_name = "Pet";
65}
66
67Pet::~Pet() = default;
68
70{
72 if (!IsInWorld())
73 {
78 if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : GetInstanceScript())
79 zoneScript->OnCreatureCreate(this);
80 }
81
82 // Prevent stuck pets when zoning. Pets default to "follow" when added to world
83 // so we'll reset flags and let the AI handle things
84 if (GetCharmInfo() && GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
85 {
88 GetCharmInfo()->SetIsAtStay(false);
91 }
92}
93
95{
97 if (IsInWorld())
98 {
102 }
103}
104
105std::pair<PetStable::PetInfo const*, PetSaveMode> Pet::GetLoadPetInfo(PetStable const& stable, uint32 petEntry, uint32 petnumber, Optional<PetSaveMode> slot)
106{
107 if (petnumber)
108 {
109 // Known petnumber entry
110 for (std::size_t activeSlot = 0; activeSlot < stable.ActivePets.size(); ++activeSlot)
111 if (stable.ActivePets[activeSlot] && stable.ActivePets[activeSlot]->PetNumber == petnumber)
112 return { &stable.ActivePets[activeSlot].value(), PetSaveMode(PET_SAVE_FIRST_ACTIVE_SLOT + activeSlot) };
113
114 for (std::size_t stableSlot = 0; stableSlot < stable.StabledPets.size(); ++stableSlot)
115 if (stable.StabledPets[stableSlot] && stable.StabledPets[stableSlot]->PetNumber == petnumber)
116 return { &stable.StabledPets[stableSlot].value(), PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + stableSlot) };
117
118 for (PetStable::PetInfo const& pet : stable.UnslottedPets)
119 if (pet.PetNumber == petnumber)
120 return { &pet, PET_SAVE_NOT_IN_SLOT };
121 }
122 else if (slot)
123 {
124 // Current pet
125 if (slot == PET_SAVE_AS_CURRENT)
126 if (stable.GetCurrentActivePetIndex() && stable.ActivePets[*stable.GetCurrentActivePetIndex()])
127 return { &stable.ActivePets[*stable.GetCurrentActivePetIndex()].value(), PetSaveMode(*stable.GetCurrentActivePetIndex()) };
128
130 if (stable.ActivePets[*slot])
131 return { &stable.ActivePets[*slot].value(), *slot };
132
134 if (stable.StabledPets[*slot])
135 return { &stable.StabledPets[*slot].value(), *slot };
136 }
137 else if (petEntry)
138 {
139 // known petEntry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
140 for (PetStable::PetInfo const& pet : stable.UnslottedPets)
141 if (pet.CreatureId == petEntry)
142 return { &pet, PET_SAVE_NOT_IN_SLOT };
143 }
144 else
145 {
146 // Any current or other non-stabled pet (for hunter "call pet")
147 if (stable.ActivePets[0])
148 return { &stable.ActivePets[0].value(), PET_SAVE_FIRST_ACTIVE_SLOT };
149
150 if (!stable.UnslottedPets.empty())
151 return { &stable.UnslottedPets.front(), PET_SAVE_NOT_IN_SLOT };
152 }
153
154 return { nullptr, PET_SAVE_AS_DELETED };
155}
156
158{
159public:
160 enum
161 {
168
169 MAX
170 };
171
173 {
174 SetSize(MAX);
175
177
178 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_DECLINED_NAME);
179 stmt->setUInt64(0, ownerGuid);
180 stmt->setUInt32(1, petNumber);
182
183 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURA);
184 stmt->setUInt32(0, petNumber);
185 SetPreparedQuery(AURAS, stmt);
186
187 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURA_EFFECT);
188 stmt->setUInt32(0, petNumber);
190
191 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL);
192 stmt->setUInt32(0, petNumber);
194
195 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_COOLDOWN);
196 stmt->setUInt32(0, petNumber);
198
199 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_CHARGES);
200 stmt->setUInt32(0, petNumber);
202 }
203};
204
205bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool current, Optional<PetSaveMode> forcedSlot /*= {}*/)
206{
207 m_loading = true;
208
209 PetStable* petStable = ASSERT_NOTNULL(owner->GetPetStable());
210
211 ObjectGuid::LowType ownerid = owner->GetGUID().GetCounter();
212 std::pair<PetStable::PetInfo const*, PetSaveMode> info = GetLoadPetInfo(*petStable, petEntry, petnumber, forcedSlot);
213 PetStable::PetInfo const* petInfo = info.first;
214 PetSaveMode slot = info.second;
215 if (!petInfo || (slot >= PET_SAVE_FIRST_STABLE_SLOT && slot < PET_SAVE_LAST_STABLE_SLOT))
216 {
217 m_loading = false;
218 return false;
219 }
220
221 // Don't try to reload the current pet
222 if (petStable->GetCurrentPet() && owner->GetPet() && petStable->GetCurrentPet()->PetNumber == petInfo->PetNumber)
223 return false;
224
225 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(petInfo->CreatedBySpellId, owner->GetMap()->GetDifficultyID());
226
227 bool isTemporarySummon = spellInfo && spellInfo->GetDuration() > 0;
228 if (current && isTemporarySummon)
229 return false;
230
231 if (petInfo->Type == HUNTER_PET)
232 {
233 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petInfo->CreatureId);
234 if (!creatureInfo)
235 return false;
236
237 CreatureDifficulty const* creatureDifficulty = creatureInfo->GetDifficulty(DIFFICULTY_NONE);
238 if (!creatureDifficulty || !creatureInfo->IsTameable(owner->CanTameExoticPets(), creatureDifficulty))
239 return false;
240 }
241
242 if (current && owner->IsPetNeedBeTemporaryUnsummoned())
243 {
245 return false;
246 }
247
249
250 Map* map = owner->GetMap();
252
253 if (!Create(guid, map, petInfo->CreatureId, petInfo->PetNumber))
254 return false;
255
257
258 setPetType(petInfo->Type);
259 SetFaction(owner->GetFaction());
261
262 if (IsCritter())
263 {
264 float px, py, pz;
266 Relocate(px, py, pz, owner->GetOrientation());
267
268 if (!IsPositionValid())
269 {
270 TC_LOG_ERROR("entities.pet", "Pet{} not loaded. Suggested coordinates isn't valid (X: {} Y: {})",
272 return false;
273 }
274
275 map->AddToMap(ToCreature());
276 return true;
277 }
278
279 m_charmInfo->SetPetNumber(petInfo->PetNumber, IsPermanentPetFor(owner));
280
281 SetDisplayId(petInfo->DisplayId, true);
282 uint8 petlevel = petInfo->Level;
285 SetName(petInfo->Name);
286
287 switch (getPetType())
288 {
289 case SUMMON_PET:
290 petlevel = owner->GetLevel();
292 ReplaceAllUnitFlags(UNIT_FLAG_PLAYER_CONTROLLED); // this enables popup window (pet dismiss, cancel)
293 break;
294 case HUNTER_PET:
299 ReplaceAllUnitFlags(UNIT_FLAG_PLAYER_CONTROLLED); // this enables popup window (pet abandon, cancel)
300 break;
301 default:
302 if (!IsPetGhoul())
303 TC_LOG_ERROR("entities.pet", "Pet have incorrect type ({}) for pet loading.", getPetType());
304 break;
305 }
306
308 SetCreatorGUID(owner->GetGUID());
309
310 InitStatsForLevel(petlevel);
312
314
315 // Set pet's position after setting level, its size depends on it
316 float px, py, pz;
318 Relocate(px, py, pz, owner->GetOrientation());
319 if (!IsPositionValid())
320 {
321 TC_LOG_ERROR("entities.pet", "Pet {} not loaded. Suggested coordinates isn't valid (X: {} Y: {})",
323 return false;
324 }
325
326 SetReactState(petInfo->ReactState);
327 SetCanModifyStats(true);
328
329 if (getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
331 else
332 {
333 uint32 savedhealth = petInfo->Health;
334 uint32 savedmana = petInfo->Mana;
335 if (!savedhealth && getPetType() == HUNTER_PET)
337 else
338 {
339 SetHealth(savedhealth);
340 SetPower(POWER_MANA, savedmana);
341 }
342 }
343
344 // set current pet as current
345 // 0-4=current
346 // PET_SAVE_NOT_IN_SLOT(-1) = not stable slot (summoning))
347 if (slot == PET_SAVE_NOT_IN_SLOT)
348 {
349 uint32 petInfoNumber = petInfo->PetNumber;
350 if (petStable->CurrentPetIndex)
351 owner->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT);
352
353 auto unslottedPetItr = std::find_if(petStable->UnslottedPets.begin(), petStable->UnslottedPets.end(), [&](PetStable::PetInfo const& unslottedPet)
354 {
355 return unslottedPet.PetNumber == petInfoNumber;
356 });
357 ASSERT(!petStable->CurrentPetIndex);
358 ASSERT(unslottedPetItr != petStable->UnslottedPets.end());
359
360 petStable->SetCurrentUnslottedPetIndex(std::distance(petStable->UnslottedPets.begin(), unslottedPetItr));
361 }
362 else if (PET_SAVE_FIRST_ACTIVE_SLOT <= slot && slot <= PET_SAVE_LAST_ACTIVE_SLOT)
363 {
364 auto activePetItr = std::find_if(petStable->ActivePets.begin(), petStable->ActivePets.end(), [&](Optional<PetStable::PetInfo> const& pet)
365 {
366 return pet && pet->PetNumber == petInfo->PetNumber;
367 });
368 ASSERT(activePetItr != petStable->ActivePets.end());
369
370 uint32 newPetIndex = std::distance(petStable->ActivePets.begin(), activePetItr);
371
372 petStable->SetCurrentActivePetIndex(newPetIndex);
373 }
374
375 owner->SetMinion(this, true);
376
377 if (!isTemporarySummon)
378 m_charmInfo->LoadPetActionBar(petInfo->ActionBar);
379
380 map->AddToMap(ToCreature());
381
382 //set last used pet number (for use in BG's)
384 owner->ToPlayer()->SetLastPetNumber(petInfo->PetNumber);
385
386 owner->GetSession()->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(std::make_shared<PetLoadQueryHolder>(ownerid, petInfo->PetNumber)))
387 .AfterComplete([this, owner, session = owner->GetSession(), isTemporarySummon, current, lastSaveTime = petInfo->LastSaveTime, specializationId = petInfo->SpecializationId](SQLQueryHolderBase const& holder)
388 {
389 if (session->GetPlayer() != owner || owner->GetPet() != this)
390 return;
391
392 // passing previous checks ensure that 'this' is still valid
393 if (m_removed)
394 return;
395
396 uint32 timediff = uint32(GameTime::GetGameTime() - lastSaveTime);
397 _LoadAuras(holder.GetPreparedResult(PetLoadQueryHolder::AURAS), holder.GetPreparedResult(PetLoadQueryHolder::AURA_EFFECTS), timediff);
398
399 // load action bar, if data broken will fill later by default spells.
400 if (!isTemporarySummon)
401 {
402 _LoadSpells(holder.GetPreparedResult(PetLoadQueryHolder::SPELLS));
403 GetSpellHistory()->LoadFromDB<Pet>(holder.GetPreparedResult(PetLoadQueryHolder::COOLDOWNS), holder.GetPreparedResult(PetLoadQueryHolder::CHARGES));
404 LearnPetPassives();
405 InitLevelupSpellsForLevel();
406 if (GetMap()->IsBattleArena())
407 RemoveArenaAuras();
408
409 CastPetAuras(current);
410 }
411
412 TC_LOG_DEBUG("entities.pet", "New Pet has {}", GetGUID().ToString());
413
414 uint16 specId = specializationId;
415 if (ChrSpecializationEntry const* petSpec = sChrSpecializationStore.LookupEntry(specId))
416 specId = sDB2Manager.GetChrSpecializationByIndex(owner->HasAuraType(SPELL_AURA_OVERRIDE_PET_SPECS) ? PET_SPEC_OVERRIDE_CLASS_INDEX : 0, petSpec->OrderIndex)->ID;
417
418 SetSpecialization(specId);
419
420 // The SetSpecialization function will run these functions if the pet's spec is not 0
421 if (!GetSpecialization())
422 {
423 CleanupActionBar(); // remove unknown spells from action bar after load
424
425 owner->PetSpellInitialize();
426 }
427
429
430 if (getPetType() == HUNTER_PET)
431 {
433 {
434 m_declinedname = std::make_unique<DeclinedName>();
435 Field* fields = result->Fetch();
436 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
437 m_declinedname->name[i] = fields[i].GetString();
438 }
439 }
440
441 if (owner->IsMounted())
443
444 // must be after SetMinion (owner guid check)
446 m_loading = false;
447 });
448
449 return true;
450}
451
453{
454 if (!GetEntry())
455 return;
456
457 // save only fully controlled creature
458 if (!isControlled())
459 return;
460
461 // not save not player pets
462 if (!GetOwnerGUID().IsPlayer())
463 return;
464
465 Player* owner = GetOwner();
466
467 // not save pet as current if another pet temporary unsummoned
469 owner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
470 {
471 // pet will lost anyway at restore temporary unsummoned
472 if (getPetType() == HUNTER_PET)
473 return;
474
475 // for warlock case
477 }
478
479 uint32 curhealth = GetHealth();
480 uint32 curmana = GetPower(POWER_MANA);
481
482 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
483 // save auras before possibly removing them
484 _SaveAuras(trans);
485
486 if (mode == PET_SAVE_AS_CURRENT)
487 if (Optional<uint32> activeSlot = owner->GetPetStable()->GetCurrentActivePetIndex())
488 mode = PetSaveMode(*activeSlot);
489
490 // stable and not in slot saves
491 if (mode < PET_SAVE_FIRST_ACTIVE_SLOT || mode >= PET_SAVE_LAST_ACTIVE_SLOT)
493
494 _SaveSpells(trans);
495 GetSpellHistory()->SaveToDB<Pet>(trans);
496 CharacterDatabase.CommitTransaction(trans);
497
498 // current/stable/not_in_slot
499 if (mode != PET_SAVE_AS_DELETED)
500 {
502 trans = CharacterDatabase.BeginTransaction();
503 // remove current data
504
506 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
507 trans->Append(stmt);
508
509 // save pet
510 std::string actionBar = GenerateActionBarData();
511
512 ASSERT(owner->GetPetStable()->GetCurrentPet() && owner->GetPetStable()->GetCurrentPet()->PetNumber == m_charmInfo->GetPetNumber());
514
515 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET);
516 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
517 stmt->setUInt32(1, GetEntry());
518 stmt->setUInt64(2, ownerLowGUID);
519 stmt->setUInt32(3, GetNativeDisplayId());
520 stmt->setUInt8(4, GetLevel());
521 stmt->setUInt32(5, m_unitData->PetExperience);
522 stmt->setUInt8(6, owner->GetTemporaryPetReactState().value_or(GetReactState()));
524 stmt->setString(8, m_name);
526 stmt->setUInt32(10, curhealth);
527 stmt->setUInt32(11, curmana);
528 stmt->setString(12, actionBar);
529 stmt->setUInt32(13, GameTime::GetGameTime());
530 stmt->setUInt32(14, m_unitData->CreatedBySpell);
531 stmt->setUInt8(15, getPetType());
532 stmt->setUInt16(16, GetSpecialization());
533 trans->Append(stmt);
534
535 CharacterDatabase.CommitTransaction(trans);
536 }
537 // delete
538 else
539 {
541 DeleteFromDB(m_charmInfo->GetPetNumber());
542 }
543}
544
545void Pet::FillPetInfo(PetStable::PetInfo* petInfo, Optional<ReactStates> forcedReactState /*= {}*/) const
546{
547 petInfo->PetNumber = m_charmInfo->GetPetNumber();
548 petInfo->CreatureId = GetEntry();
549 petInfo->DisplayId = GetNativeDisplayId();
550 petInfo->Level = GetLevel();
551 petInfo->Experience = m_unitData->PetExperience;
552 petInfo->ReactState = forcedReactState.value_or(GetReactState());
553 petInfo->Name = GetName();
555 petInfo->Health = GetHealth();
556 petInfo->Mana = GetPower(POWER_MANA);
557 petInfo->ActionBar = GenerateActionBarData();
559 petInfo->CreatedBySpellId = m_unitData->CreatedBySpell;
560 petInfo->Type = getPetType();
562}
563
565{
566 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
567
569 stmt->setUInt32(0, petNumber);
570 trans->Append(stmt);
571
572 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
573 stmt->setUInt32(0, petNumber);
574 trans->Append(stmt);
575
576 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURA_EFFECTS);
577 stmt->setUInt32(0, petNumber);
578 trans->Append(stmt);
579
580 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS);
581 stmt->setUInt32(0, petNumber);
582 trans->Append(stmt);
583
584 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELLS);
585 stmt->setUInt32(0, petNumber);
586 trans->Append(stmt);
587
588 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS);
589 stmt->setUInt32(0, petNumber);
590 trans->Append(stmt);
591
592 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_CHARGES);
593 stmt->setUInt32(0, petNumber);
594 trans->Append(stmt);
595
596 CharacterDatabase.CommitTransaction(trans);
597}
598
599void Pet::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
600{
602 if (getDeathState() == CORPSE)
603 {
604 if (getPetType() == HUNTER_PET)
605 {
606 // pet corpse non lootable and non skinnable
609
610 //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
611 }
612 }
613 else if (getDeathState() == ALIVE)
614 {
615 //RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
616 CastPetAuras(true);
617 }
618}
619
621{
622 if (m_removed) // pet already removed, just wait in remove queue, no updates
623 return;
624
625 if (m_loading)
626 return;
627
628 switch (m_deathState)
629 {
630 case CORPSE:
631 {
633 {
634 Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
635 return;
636 }
637 break;
638 }
639 case ALIVE:
640 {
641 // unsummon pet that lost owner
642 Player* owner = GetOwner();
643 if ((!IsWithinDistInMap(owner, GetMap()->GetVisibilityRange()) && !isPossessed()) || (isControlled() && !owner->GetPetGUID()))
644 //if (!owner || (!IsWithinDistInMap(owner, GetMap()->GetVisibilityDistance()) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID()))
645 {
647 return;
648 }
649
650 if (isControlled())
651 {
652 if (owner->GetPetGUID() != GetGUID())
653 {
654 TC_LOG_ERROR("entities.pet", "Pet {} is not pet of owner {}, removed", GetEntry(), GetOwner()->GetName());
655 ASSERT(getPetType() != HUNTER_PET, "Unexpected unlinked pet found for owner %s", owner->GetSession()->GetPlayerInfo().c_str());
657 return;
658 }
659 }
660
661 if (m_duration > 0)
662 {
663 if (uint32(m_duration) > diff)
664 m_duration -= diff;
665 else
666 {
668 return;
669 }
670 }
671
672 //regenerate focus for hunter pets or energy for deathknight's ghoul
674 {
675 if (m_focusRegenTimer > diff)
676 m_focusRegenTimer -= diff;
677 else
678 {
679 switch (GetPowerType())
680 {
681 case POWER_FOCUS:
685
686 // Reset if large diff (lag) causes focus to get 'stuck'
689
690 break;
691
692 // in creature::update
693 //case POWER_ENERGY:
694 // Regenerate(POWER_ENERGY);
695 // m_regenTimer += CREATURE_REGEN_INTERVAL - diff;
696 // if (!m_regenTimer) ++m_regenTimer;
697 // break;
698 default:
700 break;
701 }
702 }
703 }
704 break;
705 }
706 default:
707 break;
708 }
709 Creature::Update(diff);
710}
711
712void Pet::Remove(PetSaveMode mode, bool returnreagent)
713{
714 GetOwner()->RemovePet(this, mode, returnreagent);
715}
716
718{
719 if (getPetType() != HUNTER_PET)
720 return;
721
722 if (xp < 1)
723 return;
724
725 if (!IsAlive())
726 return;
727
728 uint8 maxlevel = std::min((uint8)sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL), GetOwner()->GetLevel());
729 uint8 petlevel = GetLevel();
730
731 // If pet is detected to be at, or above(?) the players level, don't hand out XP
732 if (petlevel >= maxlevel)
733 return;
734
735 uint32 nextLvlXP = m_unitData->PetNextLevelExperience;
736 uint32 curXP = m_unitData->PetExperience;
737 uint32 newXP = curXP + xp;
738
739 // Check how much XP the pet should receive, and hand off have any left from previous levelups
740 while (newXP >= nextLvlXP && petlevel < maxlevel)
741 {
742 // Subtract newXP from amount needed for nextlevel, and give pet the level
743 newXP -= nextLvlXP;
744 ++petlevel;
745
746 GivePetLevel(petlevel);
747
748 nextLvlXP = m_unitData->PetNextLevelExperience;
749 }
750 // Not affected by special conditions - give it new XP
751 SetPetExperience(petlevel < maxlevel ? newXP : 0);
752}
753
755{
756 if (!level || level == GetLevel())
757 return;
758
759 if (getPetType() == HUNTER_PET)
760 {
763 }
764
765 InitStatsForLevel(level);
767}
768
770{
771 ASSERT(creature);
772
773 if (!CreateBaseAtTamed(creature->GetCreatureTemplate(), creature->GetMap()))
774 return false;
775
776 Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
777
778 if (!IsPositionValid())
779 {
780 TC_LOG_ERROR("entities.pet", "Pet {} not created base at creature. Suggested coordinates isn't valid (X: {} Y: {})",
782 return false;
783 }
784
785 CreatureTemplate const* cinfo = GetCreatureTemplate();
786 if (!cinfo)
787 {
788 TC_LOG_ERROR("entities.pet", "CreateBaseAtCreature() failed, creatureInfo is missing!");
789 return false;
790 }
791
792 SetDisplayId(creature->GetDisplayId());
793
794 if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
795 SetName(cFamily->Name[GetOwner()->GetSession()->GetSessionDbcLocale()]);
796 else
797 SetName(creature->GetNameForLocaleIdx(sObjectMgr->GetDBCLocaleIndex()));
798
799 return true;
800}
801
803{
804 if (!CreateBaseAtTamed(cinfo, owner->GetMap()))
805 return false;
806
807 if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
808 SetName(cFamily->Name[GetOwner()->GetSession()->GetSessionDbcLocale()]);
809
810 Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
811
812 return true;
813}
814
816{
817 TC_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed");
818 if (!Create(map->GenerateLowGuid<HighGuid::Pet>(), map, cinfo->Entry, sObjectMgr->GeneratePetNumber()))
819 return false;
820
826
827 if (cinfo->type == CREATURE_TYPE_BEAST)
828 {
834 }
835
836 return true;
837}
838
841{
842 CreatureTemplate const* cinfo = GetCreatureTemplate();
843 ASSERT(cinfo);
844
845 SetLevel(petlevel);
846
847 //Determine pet type
848 PetType petType = MAX_PET_TYPE;
849 if (IsPet() && GetOwner()->GetTypeId() == TYPEID_PLAYER)
850 {
852 || GetOwner()->GetClass() == CLASS_SHAMAN // Fire Elemental
853 || GetOwner()->GetClass() == CLASS_DEATH_KNIGHT) // Risen Ghoul
854 {
855 petType = SUMMON_PET;
856 }
857 else if (GetOwner()->GetClass() == CLASS_HUNTER)
858 {
859 petType = HUNTER_PET;
861 }
862 else
863 {
864 TC_LOG_ERROR("entities.pet", "Unknown type pet {} is summoned by player class {}",
865 GetEntry(), GetOwner()->GetClass());
866 }
867 }
868
869 uint32 creature_ID = (petType == HUNTER_PET) ? 1 : cinfo->Entry;
870
872
873 SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel * 50));
874
878
879 //scale
881
882 // Resistance
883 // Hunters pet should not inherit resistances from creature_template, they have separate auras for that
884 if (!IsHunterPet())
885 for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
887
888 Powers powerType = CalculateDisplayPowerType();
889
890 // Health, Mana or Power, Armor
891 PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(creature_ID, petlevel);
892 if (pInfo) // exist in DB
893 {
894 SetCreateHealth(pInfo->health);
895 SetCreateMana(pInfo->mana);
896
898
899 if (pInfo->armor > 0)
901
902 for (uint8 stat = 0; stat < MAX_STATS; ++stat)
903 SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
904 }
905 else // not exist in DB, use some default fake data
906 {
907 // remove elite bonuses included in DB values
908 CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class);
910
911 CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty();
912 SetCreateHealth(std::max(sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, petlevel, creatureDifficulty->GetHealthScalingExpansion(), m_unitData->ContentTuningID, Classes(cinfo->unit_class), 0) * creatureDifficulty->HealthModifier * GetHealthMod(cinfo->Classification), 1.0f));
913 SetCreateMana(stats->BaseMana);
918 }
919
920 // Power
921 SetPowerType(powerType);
922
923 // Damage
925 switch (petType)
926 {
927 case SUMMON_PET:
928 {
929 // the damage bonus used for pets is either fire or shadow damage, whatever is higher
930 int32 fire = GetOwner()->ToPlayer()->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE];
931 int32 shadow = GetOwner()->ToPlayer()->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_SHADOW];
932 int32 val = (fire > shadow) ? fire : shadow;
933 if (val < 0)
934 val = 0;
935
936 SetBonusDamage(val * 0.15f);
937
938 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
939 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
940
941 //SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower));
942 break;
943 }
944 case HUNTER_PET:
945 {
946 ToPet()->SetPetNextLevelExperience(uint32(sObjectMgr->GetXPForLevel(petlevel)*PET_XP_FACTOR));
947 //these formula may not be correct; however, it is designed to be close to what it should be
948 //this makes dps 0.5 of pets level
949 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
950 //damage range is then petlevel / 2
951 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
952 //damage is increased afterwards as strength and pet scaling modify attack power
953 break;
954 }
955 default:
956 {
957 switch (GetEntry())
958 {
959 case 510: // mage Water Elemental
960 {
962 break;
963 }
964 case 1964: //force of nature
965 {
966 if (!pInfo)
967 SetCreateHealth(30 + 30*petlevel);
969 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2) + bonusDmg));
970 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2) + bonusDmg));
971 break;
972 }
973 case 15352: //earth elemental 36213
974 {
975 if (!pInfo)
976 SetCreateHealth(100 + 120*petlevel);
977 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
978 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
979 break;
980 }
981 case 15438: //fire elemental
982 {
983 if (!pInfo)
984 {
985 SetCreateHealth(40*petlevel);
986 SetCreateMana(28 + 10*petlevel);
987 }
989 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
990 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
991 break;
992 }
993 case 19668: // Shadowfiend
994 {
995 if (!pInfo)
996 {
997 SetCreateMana(28 + 10*petlevel);
998 SetCreateHealth(28 + 30*petlevel);
999 }
1001 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + bonus_dmg));
1002 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + bonus_dmg));
1003
1004 break;
1005 }
1006 case 19833: //Snake Trap - Venomous Snake
1007 {
1008 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel / 2) - 25));
1009 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel / 2) - 18));
1010 break;
1011 }
1012 case 19921: //Snake Trap - Viper
1013 {
1014 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel / 2 - 10));
1015 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel / 2));
1016 break;
1017 }
1018 case 29264: // Feral Spirit
1019 {
1020 if (!pInfo)
1021 SetCreateHealth(30*petlevel);
1022
1023 // wolf attack speed is 1.5s
1025
1026 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel)));
1027 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel)));
1028
1029 SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(GetOwner()->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor)
1030 SetStatFlatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(GetOwner()->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina)
1031 if (!HasAura(58877))//prevent apply twice for the 2 wolves
1032 AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done.
1033 break;
1034 }
1035 case 31216: // Mirror Image
1036 {
1039 if (!pInfo)
1040 {
1041 SetCreateMana(28 + 30*petlevel);
1042 SetCreateHealth(28 + 10*petlevel);
1043 }
1044 break;
1045 }
1046 case 27829: // Ebon Gargoyle
1047 {
1048 if (!pInfo)
1049 {
1050 SetCreateMana(28 + 10*petlevel);
1051 SetCreateHealth(28 + 30*petlevel);
1052 }
1054 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
1055 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
1056 break;
1057 }
1058 case 28017: // Bloodworms
1059 {
1060 SetCreateHealth(4 * petlevel);
1062 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - 30 - (petlevel / 4)));
1063 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel - 30 + (petlevel / 4)));
1064 break;
1065 }
1066 default:
1067 {
1068 /* ToDo: Check what 5f5d2028 broke/fixed and how much of Creature::UpdateLevelDependantStats()
1069 * should be copied here (or moved to another method or if that function should be called here
1070 * or not just for this default case)
1071 */
1072 float basedamage = GetBaseDamageForLevel(petlevel);
1073
1074 float weaponBaseMinDamage = basedamage;
1075 float weaponBaseMaxDamage = basedamage * 1.5f;
1076
1077 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1078 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1079 break;
1080 }
1081 }
1082 break;
1083 }
1084 }
1085
1087
1088 SetFullHealth();
1090 return true;
1091}
1092
1093bool Pet::HaveInDiet(ItemTemplate const* item) const
1094{
1095 if (!item->FoodType)
1096 return false;
1097
1098 CreatureTemplate const* cInfo = GetCreatureTemplate();
1099 if (!cInfo)
1100 return false;
1101
1102 CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cInfo->family);
1103 if (!cFamily)
1104 return false;
1105
1106 uint32 diet = cFamily->PetFoodMask;
1107 uint32 FoodMask = 1 << (item->FoodType-1);
1108 return (diet & FoodMask) != 0;
1109}
1110
1112{
1113 if (result)
1114 {
1115 do
1116 {
1117 Field* fields = result->Fetch();
1118
1119 addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt8()), PETSPELL_UNCHANGED);
1120 }
1121 while (result->NextRow());
1122 }
1123}
1124
1126{
1127 for (PetSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
1128 {
1129 ++next;
1130
1131 // prevent saving family passives to DB
1132 if (itr->second.type == PETSPELL_FAMILY)
1133 continue;
1134
1136
1137 switch (itr->second.state)
1138 {
1139 case PETSPELL_REMOVED:
1140 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_BY_SPELL);
1141 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1142 stmt->setUInt32(1, itr->first);
1143 trans->Append(stmt);
1144
1145 m_spells.erase(itr);
1146 continue;
1147 case PETSPELL_CHANGED:
1148 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_BY_SPELL);
1149 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1150 stmt->setUInt32(1, itr->first);
1151 trans->Append(stmt);
1152
1153 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL);
1154 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1155 stmt->setUInt32(1, itr->first);
1156 stmt->setUInt8(2, itr->second.active);
1157 trans->Append(stmt);
1158
1159 break;
1160 case PETSPELL_NEW:
1161 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL);
1162 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1163 stmt->setUInt32(1, itr->first);
1164 stmt->setUInt8(2, itr->second.active);
1165 trans->Append(stmt);
1166 break;
1167 case PETSPELL_UNCHANGED:
1168 continue;
1169 }
1170 itr->second.state = PETSPELL_UNCHANGED;
1171 }
1172}
1173
1174void Pet::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effectResult, uint32 timediff)
1175{
1176 TC_LOG_DEBUG("entities.pet", "Loading auras for pet {}", GetGUID().ToString());
1177
1178 ObjectGuid casterGuid, itemGuid;
1179 std::map<AuraKey, AuraLoadEffectInfo> effectInfo;
1180
1181 /*
1182 0 1 2 3 4 5
1183 SELECT casterGuid, spell, effectMask, effectIndex, amount, baseAmount FROM pet_aura_effect WHERE guid = ?
1184 */
1185 if (effectResult)
1186 {
1187 do
1188 {
1189 Field* fields = effectResult->Fetch();
1190 uint32 effectIndex = fields[3].GetUInt8();
1191 if (effectIndex < MAX_SPELL_EFFECTS)
1192 {
1193 casterGuid.SetRawValue(fields[0].GetBinary());
1194 if (casterGuid.IsEmpty())
1195 casterGuid = GetGUID();
1196
1197 AuraKey key{ casterGuid, itemGuid, fields[1].GetUInt32(), fields[2].GetUInt32() };
1198 AuraLoadEffectInfo& info = effectInfo[key];
1199 info.Amounts[effectIndex] = fields[4].GetInt32();
1200 info.BaseAmounts[effectIndex] = fields[5].GetInt32();
1201 }
1202 } while (effectResult->NextRow());
1203 }
1204
1205 /*
1206 0 1 2 3 4 5 6 7 8
1207 SELECT casterGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?
1208 */
1209 if (auraResult)
1210 {
1211 do
1212 {
1213 Field* fields = auraResult->Fetch();
1214 // NULL guid stored - pet is the caster of the spell - see Pet::_SaveAuras
1215 casterGuid.SetRawValue(fields[0].GetBinary());
1216 if (casterGuid.IsEmpty())
1217 casterGuid = GetGUID();
1218
1219 AuraKey key{ casterGuid, itemGuid, fields[1].GetUInt32(), fields[2].GetUInt32() };
1220 uint32 recalculateMask = fields[3].GetUInt32();
1221 Difficulty difficulty = Difficulty(fields[4].GetUInt8());
1222 uint8 stackCount = fields[5].GetUInt8();
1223 int32 maxDuration = fields[6].GetInt32();
1224 int32 remainTime = fields[7].GetInt32();
1225 uint8 remainCharges = fields[8].GetUInt8();
1226
1227 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(key.SpellId, difficulty);
1228 if (!spellInfo)
1229 {
1230 TC_LOG_ERROR("entities.pet", "Pet::_LoadAuras: Unknown aura (spellid {}), ignore.", key.SpellId);
1231 continue;
1232 }
1233
1234 if (difficulty != DIFFICULTY_NONE && !sDifficultyStore.LookupEntry(difficulty))
1235 {
1236 TC_LOG_ERROR("entities.pet", "Pet::_LoadAuras: Unknown difficulty {} (spellid {}), ignore.", uint32(difficulty), key.SpellId);
1237 continue;
1238 }
1239
1240 // negative effects should continue counting down after logout
1241 if (remainTime != -1 && (!spellInfo->IsPositive() || spellInfo->HasAttribute(SPELL_ATTR4_AURA_EXPIRES_OFFLINE)))
1242 {
1243 if (remainTime/IN_MILLISECONDS <= int32(timediff))
1244 continue;
1245
1246 remainTime -= timediff*IN_MILLISECONDS;
1247 }
1248
1249 // prevent wrong values of remainCharges
1250 if (spellInfo->ProcCharges)
1251 {
1252 // we have no control over the order of applying auras and modifiers allow auras
1253 // to have more charges than value in SpellInfo
1254 if (remainCharges <= 0/* || remainCharges > spellproto->procCharges*/)
1255 remainCharges = spellInfo->ProcCharges;
1256 }
1257 else
1258 remainCharges = 0;
1259
1260 AuraLoadEffectInfo& info = effectInfo[key];
1261 ObjectGuid castId = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellInfo->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>());
1262 AuraCreateInfo createInfo(castId, spellInfo, difficulty, key.EffectMask, this);
1263 createInfo
1264 .SetCasterGUID(casterGuid)
1265 .SetBaseAmount(info.BaseAmounts.data());
1266
1267 if (Aura* aura = Aura::TryCreate(createInfo))
1268 {
1269 if (!aura->CanBeSaved())
1270 {
1271 aura->Remove();
1272 continue;
1273 }
1274
1275 aura->SetLoadedState(maxDuration, remainTime, remainCharges, stackCount, recalculateMask, info.Amounts.data());
1276 aura->ApplyForTargets();
1277 TC_LOG_DEBUG("entities.pet", "Added aura spellid {}, effectmask {}", spellInfo->Id, key.EffectMask);
1278 }
1279 }
1280 while (auraResult->NextRow());
1281 }
1282}
1283
1285{
1287 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1288 trans->Append(stmt);
1289
1290 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS);
1291 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1292 trans->Append(stmt);
1293
1294 uint8 index;
1295 for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end(); ++itr)
1296 {
1297 // check if the aura has to be saved
1298 if (!itr->second->CanBeSaved() || IsPetAura(itr->second))
1299 continue;
1300
1301 Aura* aura = itr->second;
1302 uint32 recalculateMask = 0;
1303 AuraKey key = aura->GenerateKey(recalculateMask);
1304
1305 // don't save guid of caster in case we are caster of the spell - guid for pet is generated every pet load, so it won't match saved guid anyways
1306 if (key.Caster == GetGUID())
1307 key.Caster.Clear();
1308
1309 index = 0;
1310 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_AURA);
1311 stmt->setUInt32(index++, m_charmInfo->GetPetNumber());
1312 stmt->setBinary(index++, key.Caster.GetRawValue());
1313 stmt->setUInt32(index++, key.SpellId);
1314 stmt->setUInt32(index++, key.EffectMask);
1315 stmt->setUInt32(index++, recalculateMask);
1316 stmt->setUInt8(index++, aura->GetCastDifficulty());
1317 stmt->setUInt8(index++, aura->GetStackAmount());
1318 stmt->setInt32(index++, aura->GetMaxDuration());
1319 stmt->setInt32(index++, aura->GetDuration());
1320 stmt->setUInt8(index++, aura->GetCharges());
1321 trans->Append(stmt);
1322
1323 for (AuraEffect const* effect : aura->GetAuraEffects())
1324 {
1325 if (effect)
1326 {
1327 index = 0;
1328 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_AURA_EFFECT);
1329 stmt->setUInt32(index++, m_charmInfo->GetPetNumber());
1330 stmt->setBinary(index++, key.Caster.GetRawValue());
1331 stmt->setUInt32(index++, key.SpellId);
1332 stmt->setUInt32(index++, key.EffectMask);
1333 stmt->setUInt8(index++, effect->GetEffIndex());
1334 stmt->setInt32(index++, effect->GetAmount());
1335 stmt->setInt32(index++, effect->GetBaseAmount());
1336 trans->Append(stmt);
1337 }
1338 }
1339 }
1340}
1341
1342bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
1343{
1344 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
1345 if (!spellInfo)
1346 {
1347 // do pet spell book cleanup
1348 if (state == PETSPELL_UNCHANGED) // spell load case
1349 {
1350 TC_LOG_ERROR("entities.pet", "Pet::addSpell: Non-existed in SpellStore spell #{} request, deleting for all pets in `pet_spell`.", spellId);
1351
1353
1354 stmt->setUInt32(0, spellId);
1355
1356 CharacterDatabase.Execute(stmt);
1357 }
1358 else
1359 TC_LOG_ERROR("entities.pet", "Pet::addSpell: Non-existed in SpellStore spell #{} request.", spellId);
1360
1361 return false;
1362 }
1363
1364 PetSpellMap::iterator itr = m_spells.find(spellId);
1365 if (itr != m_spells.end())
1366 {
1367 if (itr->second.state == PETSPELL_REMOVED)
1368 state = PETSPELL_CHANGED;
1369 else
1370 {
1371 if (state == PETSPELL_UNCHANGED && itr->second.state != PETSPELL_UNCHANGED)
1372 {
1373 // can be in case spell loading but learned at some previous spell loading
1374 itr->second.state = PETSPELL_UNCHANGED;
1375
1376 if (active == ACT_ENABLED)
1377 ToggleAutocast(spellInfo, true);
1378 else if (active == ACT_DISABLED)
1379 ToggleAutocast(spellInfo, false);
1380 }
1381
1382 return false;
1383 }
1384 }
1385
1386 PetSpell newspell;
1387 newspell.state = state;
1388 newspell.type = type;
1389
1390 if (active == ACT_DECIDE) // active was not used before, so we save it's autocast/passive state here
1391 {
1392 if (spellInfo->IsAutocastable())
1393 newspell.active = ACT_DISABLED;
1394 else
1395 newspell.active = ACT_PASSIVE;
1396 }
1397 else
1398 newspell.active = active;
1399
1400 // talent: unlearn all other talent ranks (high and low)
1401 if (spellInfo->IsRanked())
1402 {
1403 for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
1404 {
1405 if (itr2->second.state == PETSPELL_REMOVED)
1406 continue;
1407
1408 SpellInfo const* oldRankSpellInfo = sSpellMgr->GetSpellInfo(itr2->first, DIFFICULTY_NONE);
1409
1410 if (!oldRankSpellInfo)
1411 continue;
1412
1413 if (spellInfo->IsDifferentRankOf(oldRankSpellInfo))
1414 {
1415 // replace by new high rank
1416 if (spellInfo->IsHighRankOf(oldRankSpellInfo))
1417 {
1418 newspell.active = itr2->second.active;
1419
1420 if (newspell.active == ACT_ENABLED)
1421 ToggleAutocast(oldRankSpellInfo, false);
1422
1423 unlearnSpell(itr2->first, false, false);
1424 break;
1425 }
1426 // ignore new lesser rank
1427 else
1428 return false;
1429 }
1430 }
1431 }
1432
1433 m_spells[spellId] = newspell;
1434
1435 if (spellInfo->IsPassive() && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState))))
1436 CastSpell(this, spellId, true);
1437 else
1438 m_charmInfo->AddSpellToActionBar(spellInfo);
1439
1440 if (newspell.active == ACT_ENABLED)
1441 ToggleAutocast(spellInfo, true);
1442
1443 return true;
1444}
1445
1447{
1448 // prevent duplicated entires in spell book
1449 if (!addSpell(spell_id))
1450 return false;
1451
1452 if (!m_loading)
1453 {
1455 packet.Spells.push_back(spell_id);
1456 GetOwner()->SendDirectMessage(packet.Write());
1458 }
1459 return true;
1460}
1461
1462void Pet::learnSpells(std::vector<uint32> const& spellIds)
1463{
1465
1466 for (uint32 spell : spellIds)
1467 {
1468 if (!addSpell(spell))
1469 continue;
1470
1471 packet.Spells.push_back(spell);
1472 }
1473
1474 if (!m_loading)
1475 GetOwner()->GetSession()->SendPacket(packet.Write());
1476}
1477
1479{
1480 uint8 level = GetLevel();
1481
1482 if (PetLevelupSpellSet const* levelupSpells = GetCreatureTemplate()->family ? sSpellMgr->GetPetLevelupSpellList(GetCreatureTemplate()->family) : nullptr)
1483 {
1484 // PetLevelupSpellSet ordered by levels, process in reversed order
1485 for (PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
1486 {
1487 // will called first if level down
1488 if (itr->first > level)
1489 unlearnSpell(itr->second, true); // will learn prev rank if any
1490 // will called if level up
1491 else
1492 learnSpell(itr->second); // will unlearn prev rank if any
1493 }
1494 }
1495
1496 // default spells (can be not learned if pet level (as owner level decrease result for example) less first possible in normal game)
1497 if (PetDefaultSpellsEntry const* defSpells = sSpellMgr->GetPetDefaultSpellsEntry(int32(GetEntry())))
1498 {
1499 for (uint32 spellId : defSpells->spellid)
1500 {
1501 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
1502 if (!spellInfo)
1503 continue;
1504
1505 // will called first if level down
1506 if (spellInfo->SpellLevel > level)
1507 unlearnSpell(spellInfo->Id, true);
1508 // will called if level up
1509 else
1510 learnSpell(spellInfo->Id);
1511 }
1512 }
1513}
1514
1515bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
1516{
1517 if (removeSpell(spell_id, learn_prev, clear_ab))
1518 {
1519 if (!m_loading)
1520 {
1522 packet.Spells.push_back(spell_id);
1523 GetOwner()->SendDirectMessage(packet.Write());
1524 }
1525 return true;
1526 }
1527 return false;
1528}
1529
1530void Pet::unlearnSpells(std::vector<uint32> const& spellIds, bool learn_prev, bool clear_ab)
1531{
1533
1534 for (uint32 spell : spellIds)
1535 {
1536 if (!removeSpell(spell, learn_prev, clear_ab))
1537 continue;
1538
1539 packet.Spells.push_back(spell);
1540 }
1541
1542 if (!m_loading)
1543 GetOwner()->GetSession()->SendPacket(packet.Write());
1544}
1545
1546bool Pet::removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
1547{
1548 PetSpellMap::iterator itr = m_spells.find(spell_id);
1549 if (itr == m_spells.end())
1550 return false;
1551
1552 if (itr->second.state == PETSPELL_REMOVED)
1553 return false;
1554
1555 if (itr->second.state == PETSPELL_NEW)
1556 m_spells.erase(itr);
1557 else
1558 itr->second.state = PETSPELL_REMOVED;
1559
1560 RemoveAurasDueToSpell(spell_id);
1561
1562 if (learn_prev)
1563 {
1564 if (uint32 prev_id = sSpellMgr->GetPrevSpellInChain (spell_id))
1565 learnSpell(prev_id);
1566 else
1567 learn_prev = false;
1568 }
1569
1570 // if remove last rank or non-ranked then update action bar at server and client if need
1571 if (clear_ab && !learn_prev && m_charmInfo->RemoveSpellFromActionBar(spell_id))
1572 {
1573 if (!m_loading)
1574 GetOwner()->PetSpellInitialize(); // need update action bar for last removed rank
1575 }
1576
1577 return true;
1578}
1579
1581{
1582 for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
1583 if (UnitActionBarEntry const* ab = m_charmInfo->GetActionBarEntry(i))
1584 if (ab->GetAction() && ab->IsActionBarForSpell())
1585 {
1586 if (!HasSpell(ab->GetAction()))
1587 m_charmInfo->SetActionBar(i, 0, ACT_PASSIVE);
1588 else if (ab->GetType() == ACT_ENABLED)
1589 {
1590 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(ab->GetAction(), DIFFICULTY_NONE))
1591 ToggleAutocast(spellInfo, true);
1592 }
1593 }
1594}
1595
1597{
1598 m_charmInfo->InitPetActionBar();
1599 m_spells.clear();
1600
1603
1604 CastPetAuras(false);
1605}
1606
1607void Pet::ToggleAutocast(SpellInfo const* spellInfo, bool apply)
1608{
1609 ASSERT(spellInfo);
1610
1611 if (!spellInfo->IsAutocastable())
1612 return;
1613
1614 PetSpellMap::iterator itr = m_spells.find(spellInfo->Id);
1615 if (itr == m_spells.end())
1616 return;
1617
1618 auto autospellItr = std::find(m_autospells.begin(), m_autospells.end(), spellInfo->Id);
1619
1620 if (apply)
1621 {
1622 if (autospellItr == m_autospells.end())
1623 {
1624 m_autospells.push_back(spellInfo->Id);
1625
1626 if (itr->second.active != ACT_ENABLED)
1627 {
1628 itr->second.active = ACT_ENABLED;
1629 if (itr->second.state != PETSPELL_NEW)
1630 itr->second.state = PETSPELL_CHANGED;
1631 }
1632 }
1633 }
1634 else
1635 {
1636 if (autospellItr != m_autospells.end())
1637 {
1638 m_autospells.erase(autospellItr);
1639
1640 if (itr->second.active != ACT_DISABLED)
1641 {
1642 itr->second.active = ACT_DISABLED;
1643 if (itr->second.state != PETSPELL_NEW)
1644 itr->second.state = PETSPELL_CHANGED;
1645 }
1646 }
1647 }
1648}
1649
1651{
1652 switch (getPetType())
1653 {
1654 case SUMMON_PET:
1655 switch (owner->GetClass())
1656 {
1657 case CLASS_WARLOCK:
1659 case CLASS_DEATH_KNIGHT:
1661 case CLASS_MAGE:
1663 default:
1664 return false;
1665 }
1666 case HUNTER_PET:
1667 return true;
1668 default:
1669 return false;
1670 }
1671}
1672
1673bool Pet::Create(ObjectGuid::LowType guidlow, Map* map, uint32 Entry, uint32 /*petId*/)
1674{
1675 ASSERT(map);
1676 SetMap(map);
1677
1678 // TODO: counter should be constructed as (summon_count << 32) | petNumber
1679 Object::_Create(ObjectGuid::Create<HighGuid::Pet>(map->GetId(), Entry, guidlow));
1680
1681 m_spawnId = guidlow;
1683
1684 if (!InitEntry(Entry))
1685 return false;
1686
1687 // Force regen flag for player pets, just like we do for players themselves
1690
1692
1693 return true;
1694}
1695
1696bool Pet::HasSpell(uint32 spell) const
1697{
1698 PetSpellMap::const_iterator itr = m_spells.find(spell);
1699 return itr != m_spells.end() && itr->second.state != PETSPELL_REMOVED;
1700}
1701
1702// Get all passive spells in our skill line
1704{
1705 CreatureTemplate const* cInfo = GetCreatureTemplate();
1706 if (!cInfo)
1707 return;
1708
1709 CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cInfo->family);
1710 if (!cFamily)
1711 return;
1712
1713 PetFamilySpellsStore::const_iterator petStore = sPetFamilySpellsStore.find(cInfo->family);
1714 if (petStore != sPetFamilySpellsStore.end())
1715 {
1716 // For general hunter pets skill 270
1717 // Passive 01~10, Passive 00 (20782, not used), Ferocious Inspiration (34457)
1718 // Scale 01~03 (34902~34904, bonus from owner, not used)
1719 for (uint32 spellId : petStore->second)
1721 }
1722}
1723
1724void Pet::CastPetAuras(bool current)
1725{
1726 Player* owner = GetOwner();
1727
1728 if (!IsPermanentPetFor(owner))
1729 return;
1730
1731 for (auto itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();)
1732 {
1733 PetAura const* pa = *itr;
1734 ++itr;
1735
1736 if (!current && pa->IsRemovedOnChangePet())
1737 owner->RemovePetAura(pa);
1738 else
1739 CastPetAura(pa);
1740 }
1741}
1742
1743void Pet::CastPetAura(PetAura const* aura)
1744{
1745 uint32 auraId = aura->GetAura(GetEntry());
1746 if (!auraId)
1747 return;
1748
1749 CastSpellExtraArgs args;
1751
1752 if (auraId == 35696) // Demonic Knowledge
1754
1755 CastSpell(this, auraId, args);
1756}
1757
1758bool Pet::IsPetAura(Aura const* aura)
1759{
1760 Player* owner = GetOwner();
1761
1762 // if the owner has that pet aura, return true
1763 for (PetAura const* petAura : owner->m_petAuras)
1764 if (petAura->GetAura(GetEntry()) == aura->GetId())
1765 return true;
1766
1767 return false;
1768}
1769
1771{
1772 learnSpell(spellid);
1773
1774 if (uint32 next = sSpellMgr->GetNextSpellInChain(spellid))
1775 learnSpellHighRank(next);
1776}
1777
1779{
1780 Player* owner = GetOwner();
1781
1782 switch (getPetType())
1783 {
1784 // always same level
1785 case SUMMON_PET:
1786 case HUNTER_PET:
1787 GivePetLevel(owner->GetLevel());
1788 break;
1789 default:
1790 break;
1791 }
1792}
1793
1795{
1796 return Minion::GetOwner()->ToPlayer();
1797}
1798
1800{
1801 CreatureFamilyEntry const* creatureFamily = sCreatureFamilyStore.LookupEntry(GetCreatureTemplate()->family);
1802 if (creatureFamily && creatureFamily->MinScale > 0.0f && getPetType() == HUNTER_PET)
1803 {
1804 float scale;
1805 if (GetLevel() >= creatureFamily->MaxScaleLevel)
1806 scale = creatureFamily->MaxScale;
1807 else if (GetLevel() <= creatureFamily->MinScaleLevel)
1808 scale = creatureFamily->MinScale;
1809 else
1810 scale = creatureFamily->MinScale + float(GetLevel() - creatureFamily->MinScaleLevel) / creatureFamily->MaxScaleLevel * (creatureFamily->MaxScale - creatureFamily->MinScale);
1811
1812 return scale;
1813 }
1814
1816}
1817
1818void Pet::SetDisplayId(uint32 modelId, bool setNative /*= false*/)
1819{
1820 Guardian::SetDisplayId(modelId, setNative);
1821
1822 if (!isControlled())
1823 return;
1824
1826}
1827
1829{
1830 if (GetOwner()->GetGroup())
1831 {
1832 m_groupUpdateMask |= flag;
1834 }
1835}
1836
1838{
1840 if (GetOwner()->GetGroup())
1842}
1843
1845{
1846 std::vector<uint32> learnedSpells;
1847
1848 if (std::vector<SpecializationSpellsEntry const*> const* specSpells = sDB2Manager.GetSpecializationSpells(m_petSpecialization))
1849 {
1850 for (size_t j = 0; j < specSpells->size(); ++j)
1851 {
1852 SpecializationSpellsEntry const* specSpell = specSpells->at(j);
1853 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(specSpell->SpellID, DIFFICULTY_NONE);
1854 if (!spellInfo || spellInfo->SpellLevel > GetLevel())
1855 continue;
1856
1857 learnedSpells.push_back(specSpell->SpellID);
1858 }
1859 }
1860
1861 learnSpells(learnedSpells);
1862}
1863
1864void Pet::RemoveSpecializationSpells(bool clearActionBar)
1865{
1866 std::vector<uint32> unlearnedSpells;
1867
1868 for (uint32 i = 0; i < MAX_SPECIALIZATIONS; ++i)
1869 {
1870 if (ChrSpecializationEntry const* specialization = sDB2Manager.GetChrSpecializationByIndex(0, i))
1871 {
1872 if (std::vector<SpecializationSpellsEntry const*> const* specSpells = sDB2Manager.GetSpecializationSpells(specialization->ID))
1873 {
1874 for (size_t j = 0; j < specSpells->size(); ++j)
1875 {
1876 SpecializationSpellsEntry const* specSpell = specSpells->at(j);
1877 unlearnedSpells.push_back(specSpell->SpellID);
1878 }
1879 }
1880 }
1881
1882 if (ChrSpecializationEntry const* specialization = sDB2Manager.GetChrSpecializationByIndex(PET_SPEC_OVERRIDE_CLASS_INDEX, i))
1883 {
1884 if (std::vector<SpecializationSpellsEntry const*> const* specSpells = sDB2Manager.GetSpecializationSpells(specialization->ID))
1885 {
1886 for (size_t j = 0; j < specSpells->size(); ++j)
1887 {
1888 SpecializationSpellsEntry const* specSpell = specSpells->at(j);
1889 unlearnedSpells.push_back(specSpell->SpellID);
1890 }
1891 }
1892 }
1893 }
1894
1895 unlearnSpells(unlearnedSpells, true, clearActionBar);
1896}
1897
1899{
1900 if (m_petSpecialization == spec)
1901 return;
1902
1903 // remove all the old spec's specalization spells, set the new spec, then add the new spec's spells
1904 // clearActionBars is false because we'll be updating the pet actionbar later so we don't have to do it now
1906 if (!sChrSpecializationStore.LookupEntry(spec))
1907 {
1909 return;
1910 }
1911
1912 m_petSpecialization = spec;
1914
1915 // resend SMSG_PET_SPELLS_MESSAGE to remove old specialization spells from the pet action bar
1918
1919 WorldPackets::Pet::SetPetSpecialization setPetSpecialization;
1920 setPetSpecialization.SpecID = m_petSpecialization;
1921 GetOwner()->GetSession()->SendPacket(setPetSpecialization.Write());
1922}
1923
1925{
1926 std::ostringstream ss;
1927
1929 {
1930 ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << ' '
1931 << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << ' ';
1932 }
1933
1934 return ss.str();
1935}
1936
1937std::string Pet::GetDebugInfo() const
1938{
1939 std::stringstream sstr;
1940 sstr << Guardian::GetDebugInfo() << "\n"
1941 << std::boolalpha
1942 << "PetType: " << std::to_string(getPetType()) << " "
1943 << "PetNumber: " << m_charmInfo->GetPetNumber();
1944 return sstr.str();
1945}
@ CHAR_SEL_PET_AURA
@ CHAR_DEL_PET_SPELL_CHARGES
@ CHAR_INS_PET_AURA_EFFECT
@ CHAR_DEL_INVALID_PET_SPELL
@ CHAR_DEL_PET_SPELLS
@ CHAR_INS_PET
@ CHAR_INS_PET_SPELL
@ CHAR_DEL_CHAR_PET_BY_ID
@ CHAR_DEL_PET_AURAS
@ CHAR_SEL_PET_DECLINED_NAME
@ CHAR_SEL_PET_AURA_EFFECT
@ CHAR_DEL_PET_SPELL_BY_SPELL
@ CHAR_DEL_PET_SPELL_COOLDOWNS
@ CHAR_SEL_PET_SPELL
@ CHAR_SEL_PET_SPELL_COOLDOWN
@ CHAR_SEL_PET_SPELL_CHARGES
@ CHAR_DEL_PET_AURA_EFFECTS
@ CHAR_INS_PET_AURA
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
#define MAX_UNIT_ACTION_BAR_INDEX
Definition: CharmInfo.h:86
@ ACTION_BAR_INDEX_END
Definition: CharmInfo.h:83
@ ACTION_BAR_INDEX_START
Definition: CharmInfo.h:80
@ IN_MILLISECONDS
Definition: Common.h:35
const uint32 PET_FOCUS_REGEN_INTERVAL
Definition: CreatureData.h:413
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< CreatureFamilyEntry > sCreatureFamilyStore("CreatureFamily.db2", &CreatureFamilyLoadInfo::Instance)
DB2Storage< ChrSpecializationEntry > sChrSpecializationStore("ChrSpecialization.db2", &ChrSpecializationLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:538
Difficulty
Definition: DBCEnums.h:873
@ DIFFICULTY_NONE
Definition: DBCEnums.h:874
#define MAX_SPELL_EFFECTS
Definition: DBCEnums.h:1953
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
#define ASSERT_NOTNULL(pointer)
Definition: Errors.h:84
#define ASSERT
Definition: Errors.h:68
@ GROUP_UPDATE_FLAG_PET
Definition: Group.h:138
@ GROUP_UPDATE_PET_FULL
Definition: Group.h:159
@ GROUP_UPDATE_FLAG_PET_MODEL_ID
Definition: Group.h:154
@ GROUP_UPDATE_FLAG_PET_NONE
Definition: Group.h:151
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
#define sObjectMgr
Definition: ObjectMgr.h:1946
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
PetSpellState
Definition: PetDefines.h:68
@ PETSPELL_NEW
Definition: PetDefines.h:71
@ PETSPELL_UNCHANGED
Definition: PetDefines.h:69
@ PETSPELL_CHANGED
Definition: PetDefines.h:70
@ PETSPELL_REMOVED
Definition: PetDefines.h:72
#define PET_FOLLOW_DIST
Definition: PetDefines.h:97
PetType
Definition: PetDefines.h:30
@ SUMMON_PET
Definition: PetDefines.h:31
@ HUNTER_PET
Definition: PetDefines.h:32
@ MAX_PET_TYPE
Definition: PetDefines.h:33
PetSpellType
Definition: PetDefines.h:76
@ PETSPELL_FAMILY
Definition: PetDefines.h:78
PetSaveMode
Definition: PetDefines.h:41
@ PET_SAVE_FIRST_STABLE_SLOT
Definition: PetDefines.h:46
@ PET_SAVE_LAST_STABLE_SLOT
Definition: PetDefines.h:47
@ PET_SAVE_LAST_ACTIVE_SLOT
Definition: PetDefines.h:45
@ PET_SAVE_FIRST_ACTIVE_SLOT
Definition: PetDefines.h:44
@ PET_SAVE_AS_DELETED
Definition: PetDefines.h:42
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:48
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:43
#define PET_XP_FACTOR
Definition: Pet.cpp:44
#define MAX_STATS
Classes
@ CLASS_HUNTER
@ CLASS_SHAMAN
@ CLASS_WARRIOR
@ CLASS_WARLOCK
@ CLASS_MAGE
@ CLASS_DEATH_KNIGHT
@ GENDER_NONE
@ SPELL_SCHOOL_MASK_SHADOW
@ SPELL_SCHOOL_MASK_NATURE
@ SPELL_SCHOOL_MASK_FIRE
@ SPELL_SCHOOL_MASK_FROST
@ CREATURE_TYPE_UNDEAD
@ CREATURE_TYPE_DEMON
@ CREATURE_TYPE_ELEMENTAL
@ CREATURE_TYPE_BEAST
#define MAX_SPECIALIZATIONS
@ UNIT_DYNFLAG_NONE
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
#define PET_SPEC_OVERRIDE_CLASS_INDEX
Powers
@ POWER_MANA
@ POWER_FOCUS
Stats
@ STAT_INTELLECT
@ STAT_AGILITY
@ STAT_STRENGTH
@ STAT_STAMINA
AuraStateType
SpellSchools
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
@ MAX_SPELL_SCHOOL
@ SPELL_ATTR4_AURA_EXPIRES_OFFLINE
@ SPELL_AURA_OVERRIDE_PET_SPECS
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ SPELLVALUE_BASE_POINT0
Definition: SpellDefines.h:196
PetFamilySpellsStore sPetFamilySpellsStore
Definition: SpellMgr.cpp:104
#define sSpellMgr
Definition: SpellMgr.h:849
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition: SpellMgr.h:626
@ SPELL_CAST_SOURCE_NORMAL
Definition: Spell.h:146
@ UNIT_FLAG2_REGENERATE_POWER
Definition: UnitDefines.h:205
@ UNIT_PET_FLAG_CAN_BE_ABANDONED
Definition: UnitDefines.h:110
@ UNIT_PET_FLAG_CAN_BE_RENAMED
Definition: UnitDefines.h:109
@ REACT_PASSIVE
Definition: UnitDefines.h:506
#define BASE_ATTACK_TIME
Definition: UnitDefines.h:35
#define MAX_DECLINED_NAME_CASES
Definition: UnitDefines.h:484
ActiveStates
Definition: UnitDefines.h:495
@ ACT_DECIDE
Definition: UnitDefines.h:501
@ ACT_ENABLED
Definition: UnitDefines.h:498
@ ACT_PASSIVE
Definition: UnitDefines.h:496
@ ACT_DISABLED
Definition: UnitDefines.h:497
@ UNIT_NPC_FLAG_NONE
Definition: UnitDefines.h:296
@ SHEATH_STATE_MELEE
Definition: UnitDefines.h:83
@ UNIT_NPC_FLAG_2_NONE
Definition: UnitDefines.h:336
@ COMMAND_FOLLOW
Definition: UnitDefines.h:527
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition: UnitDefines.h:147
@ UNIT_FLAG_SKINNABLE
Definition: UnitDefines.h:170
@ BASE_VALUE
Definition: Unit.h:152
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition: Unit.h:358
@ UNIT_MASK_HUNTER_PET
Definition: Unit.h:357
@ UNIT_MASK_PET
Definition: Unit.h:354
@ MINDAMAGE
Definition: Unit.h:167
@ MAXDAMAGE
Definition: Unit.h:168
UnitMods
Definition: Unit.h:172
@ UNIT_MOD_ARMOR
Definition: Unit.h:204
@ UNIT_MOD_RESISTANCE_START
Definition: Unit.h:220
@ UNIT_MOD_POWER_START
Definition: Unit.h:222
@ UNIT_MOD_STAT_STAMINA
Definition: Unit.h:175
DeathState
Definition: Unit.h:245
@ CORPSE
Definition: Unit.h:248
@ ALIVE
Definition: Unit.h:246
@ JUST_DIED
Definition: Unit.h:247
@ BASE_PCT
Definition: Unit.h:160
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:491
T CalculatePct(T base, U pct)
Definition: Util.h:72
uint32 const Entry[5]
int32 GetMaxDuration() const
Definition: SpellAuras.h:168
static Aura * TryCreate(AuraCreateInfo &createInfo)
Definition: SpellAuras.cpp:377
AuraEffectVector const & GetAuraEffects() const
Definition: SpellAuras.h:308
uint32 GetId() const
Definition: SpellAuras.h:135
int32 GetDuration() const
Definition: SpellAuras.h:173
uint8 GetStackAmount() const
Definition: SpellAuras.h:189
uint8 GetCharges() const
Definition: SpellAuras.h:180
Difficulty GetCastDifficulty() const
Definition: SpellAuras.h:136
AuraKey GenerateKey(uint32 &recalculateMask) const
Fills a helper structure containing aura primary key for character_aura, character_aura_effect,...
void setDeathState(DeathState s) override
Definition: Creature.cpp:2197
ObjectGuid::LowType m_spawnId
For new or temporary creatures is 0 for saved it is lowguid.
Definition: Creature.h:502
void Update(uint32 time) override
Definition: Creature.cpp:709
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:252
void SetObjectScale(float scale) override
Definition: Creature.cpp:3391
std::string GetNameForLocaleIdx(LocaleConstant locale) const override
Definition: Creature.cpp:3260
bool AIM_Initialize(CreatureAI *ai=nullptr)
Definition: Creature.cpp:1044
void LoadTemplateImmunities(int32 creatureImmunitiesId)
Definition: Creature.cpp:2423
void SetReactState(ReactStates st)
Definition: Creature.h:160
void ApplyLevelScaling()
Definition: Creature.cpp:3031
time_t m_corpseRemoveTime
Definition: Creature.h:488
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:250
float GetBaseDamageForLevel(uint8 level) const
Definition: Creature.cpp:3069
uint32 m_originalEntry
Definition: Creature.h:512
float GetNativeObjectScale() const override
Definition: Creature.cpp:3386
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
ReactStates GetReactState() const
Definition: Creature.h:161
bool InitEntry(uint32 entry, CreatureData const *data=nullptr)
Definition: Creature.cpp:487
void SetMeleeDamageSchool(SpellSchools school)
Definition: Creature.h:217
static float GetHealthMod(CreatureClassifications classification)
Definition: Creature.cpp:1657
void Regenerate(Powers power)
Definition: Creature.cpp:918
Class used to access individual fields of database query result.
Definition: Field.h:90
uint8 GetUInt8() const
Definition: Field.cpp:30
std::string GetString() const
Definition: Field.cpp:118
uint32 GetUInt32() const
Definition: Field.cpp:62
int32 GetInt32() const
Definition: Field.cpp:70
void SetBonusDamage(int32 damage)
bool InitStatsForLevel(uint8 level)
Definition: Pet.cpp:840
std::string GetDebugInfo() const override
bool UpdateAllStats() override
Definition: Map.h:189
MapStoredObjectTypesContainer & GetObjectsStore()
Definition: Map.h:422
bool AddToMap(T *)
Definition: Map.cpp:550
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:519
Difficulty GetDifficultyID() const
Definition: Map.h:324
uint32 GetId() const
Definition: Map.cpp:3228
Unit * GetOwner() const
float GetFollowAngle() const override
bool IsPetGhoul() const
LowType GetCounter() const
Definition: ObjectGuid.h:293
bool IsEmpty() const
Definition: ObjectGuid.h:319
uint64 GetRawValue(std::size_t i) const
Definition: ObjectGuid.h:282
void SetRawValue(std::vector< uint8 > const &guid)
Definition: ObjectGuid.cpp:584
uint64 LowType
Definition: ObjectGuid.h:278
void Clear()
Definition: ObjectGuid.h:286
bool IsPlayer() const
Definition: Object.h:212
ObjectGuid const & GetGUID() const
Definition: Object.h:160
bool IsInWorld() const
Definition: Object.h:154
TypeID GetTypeId() const
Definition: Object.h:173
void ReplaceAllDynamicFlags(uint32 flag)
Definition: Object.h:171
uint32 GetEntry() const
Definition: Object.h:161
Creature * ToCreature()
Definition: Object.h:221
void _Create(ObjectGuid const &guid)
Definition: Object.cpp:101
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
int32 GetDamage() const
Definition: SpellMgr.h:514
uint32 GetAura(uint32 petEntry) const
Definition: SpellMgr.h:493
bool IsRemovedOnChangePet() const
Definition: SpellMgr.h:509
PetLoadQueryHolder(ObjectGuid::LowType ownerGuid, uint32 petNumber)
Definition: Pet.cpp:172
Optional< uint32 > GetCurrentActivePetIndex() const
Definition: PetDefines.h:177
std::array< Optional< PetInfo >, MAX_ACTIVE_PETS > ActivePets
Definition: PetDefines.h:158
void SetCurrentUnslottedPetIndex(uint32 index)
Definition: PetDefines.h:180
std::array< Optional< PetInfo >, MAX_PET_STABLES > StabledPets
Definition: PetDefines.h:159
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:160
PetInfo * GetCurrentPet()
Definition: PetDefines.h:162
Optional< uint32 > CurrentPetIndex
Definition: PetDefines.h:157
void SetCurrentActivePetIndex(uint32 index)
Definition: PetDefines.h:178
Definition: Pet.h:40
uint16 GetSpecialization() const
Definition: Pet.h:132
void LearnPetPassives()
Definition: Pet.cpp:1703
Pet(Player *owner, PetType type=MAX_PET_TYPE)
Definition: Pet.cpp:46
void GivePetLevel(uint8 level)
Definition: Pet.cpp:754
void RemoveFromWorld() override
Definition: Pet.cpp:94
bool m_loading
Definition: Pet.h:152
void SetSpecialization(uint16 spec)
Definition: Pet.cpp:1898
uint16 m_petSpecialization
Definition: Pet.h:158
Player * GetOwner() const
Definition: Pet.cpp:1794
bool IsPetAura(Aura const *aura)
Definition: Pet.cpp:1758
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab=true)
Definition: Pet.cpp:1515
bool Create(ObjectGuid::LowType guidlow, Map *map, uint32 Entry, uint32 pet_number)
Definition: Pet.cpp:1673
uint32 m_focusRegenTimer
Definition: Pet.h:153
static void DeleteFromDB(uint32 petNumber)
Definition: Pet.cpp:564
void FillPetInfo(PetStable::PetInfo *petInfo, Optional< ReactStates > forcedReactState={}) const
Definition: Pet.cpp:545
void ToggleAutocast(SpellInfo const *spellInfo, bool apply)
Definition: Pet.cpp:1607
void learnSpells(std::vector< uint32 > const &spellIds)
Definition: Pet.cpp:1462
void AddToWorld() override
Definition: Pet.cpp:69
static std::pair< PetStable::PetInfo const *, PetSaveMode > GetLoadPetInfo(PetStable const &stable, uint32 petEntry, uint32 petnumber, Optional< PetSaveMode > slot)
Definition: Pet.cpp:105
void SetGroupUpdateFlag(uint32 flag)
Definition: Pet.cpp:1828
void CastPetAuras(bool current)
Definition: Pet.cpp:1724
void setPetType(PetType type)
Definition: Pet.h:52
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:452
float GetNativeObjectScale() const override
Definition: Pet.cpp:1799
void _SaveAuras(CharacterDatabaseTransaction trans)
Definition: Pet.cpp:1284
PetType getPetType() const
Definition: Pet.h:51
void SynchronizeLevelWithOwner()
Definition: Pet.cpp:1778
std::unique_ptr< DeclinedName > m_declinedname
Definition: Pet.h:156
bool LoadPetFromDB(Player *owner, uint32 petEntry, uint32 petnumber, bool current, Optional< PetSaveMode > forcedSlot={})
Definition: Pet.cpp:205
void _SaveSpells(CharacterDatabaseTransaction trans)
Definition: Pet.cpp:1125
void learnSpellHighRank(uint32 spellid)
Definition: Pet.cpp:1770
bool IsPermanentPetFor(Player *owner) const
Definition: Pet.cpp:1650
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1093
void RemoveSpecializationSpells(bool clearActionBar)
Definition: Pet.cpp:1864
bool addSpell(uint32 spellId, ActiveStates active=ACT_DECIDE, PetSpellState state=PETSPELL_NEW, PetSpellType type=PETSPELL_NORMAL)
Definition: Pet.cpp:1342
AutoSpellList m_autospells
Definition: Pet.h:128
void SetPetExperience(uint32 xp)
Definition: Pet.h:84
std::string GetDebugInfo() const override
Definition: Pet.cpp:1937
bool CreateBaseAtTamed(CreatureTemplate const *cinfo, Map *map)
Definition: Pet.cpp:815
bool CreateBaseAtCreatureInfo(CreatureTemplate const *cinfo, Unit *owner)
Definition: Pet.cpp:802
void SetDisplayId(uint32 modelId, bool setNative=false) override
Definition: Pet.cpp:1818
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab=true)
Definition: Pet.cpp:1546
bool CreateBaseAtCreature(Creature *creature)
Definition: Pet.cpp:769
void CleanupActionBar()
Definition: Pet.cpp:1580
bool isTemporarySummoned() const
Definition: Pet.h:54
void CastPetAura(PetAura const *aura)
Definition: Pet.cpp:1743
void unlearnSpells(std::vector< uint32 > const &spellIds, bool learn_prev, bool clear_ab=true)
Definition: Pet.cpp:1530
void _LoadSpells(PreparedQueryResult result)
Definition: Pet.cpp:1111
bool isControlled() const
Definition: Pet.h:53
virtual ~Pet()
void SetPetNextLevelExperience(uint32 xp)
Definition: Pet.h:85
void setDeathState(DeathState s) override
Definition: Pet.cpp:599
void ResetGroupUpdateFlag()
Definition: Pet.cpp:1837
bool m_removed
Definition: Pet.h:143
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition: Pet.cpp:712
void _LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effectResult, uint32 timediff)
Definition: Pet.cpp:1174
void Update(uint32 diff) override
Definition: Pet.cpp:620
void InitPetCreateSpells()
Definition: Pet.cpp:1596
bool HasSpell(uint32 spell) const override
Definition: Pet.cpp:1696
void LearnSpecializationSpells()
Definition: Pet.cpp:1844
uint32 m_groupUpdateMask
Definition: Pet.h:154
PetSpellMap m_spells
Definition: Pet.h:127
void GivePetXP(uint32 xp)
Definition: Pet.cpp:717
std::string GenerateActionBarData() const
Definition: Pet.cpp:1924
bool learnSpell(uint32 spell_id)
Definition: Pet.cpp:1446
int32 m_duration
Definition: Pet.h:151
void InitLevelupSpellsForLevel()
Definition: Pet.cpp:1478
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
void SetGroupUpdateFlag(uint32 flag)
Definition: Player.h:2614
uint32 GetTemporaryUnsummonedPetNumber() const
Definition: Player.h:2543
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6324
bool CanTameExoticPets() const
Definition: Player.h:2305
void SetTemporaryUnsummonedPetNumber(uint32 petnumber)
Definition: Player.h:2544
void DisablePetControlsOnMount(ReactStates reactState, CommandStates commandState)
Definition: Player.cpp:27122
void RemoveGroupUpdateFlag(uint32 flag)
Definition: Player.h:2615
bool IsPetNeedBeTemporaryUnsummoned() const
Definition: Player.cpp:27228
PetStable * GetPetStable()
Definition: Player.h:1222
void PetSpellInitialize()
Definition: Player.cpp:21879
Pet * GetPet() const
Definition: Player.cpp:21513
WorldSession * GetSession() const
Definition: Player.h:2101
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:21537
Optional< ReactStates > GetTemporaryPetReactState() const
Definition: Player.h:2545
std::unordered_set< PetAura const * > m_petAuras
Definition: Player.h:1236
UF::UpdateField< UF::ActivePlayerData, 0, TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition: Player.h:2864
void RemovePetAura(PetAura const *petSpell)
Definition: Player.cpp:21643
void SetLastPetNumber(uint32 petnumber)
Definition: Player.h:2597
void setInt16(const uint8 index, const int16 value)
void setInt32(const uint8 index, const int32 value)
void setUInt8(const uint8 index, const uint8 value)
void setBinary(const uint8 index, const std::vector< uint8 > &value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt16(const uint8 index, const uint16 value)
void setString(const uint8 index, const std::string &value)
void setUInt64(const uint8 index, const uint64 value)
void SetSize(size_t size)
Definition: QueryHolder.cpp:69
PreparedQueryResult GetPreparedResult(size_t index) const
Definition: QueryHolder.cpp:37
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition: QueryHolder.h:69
bool SetPreparedQuery(size_t index, PreparedStatement< T > *stmt)
Definition: QueryHolder.h:47
void SaveToDB(CharacterDatabaseTransaction trans)
uint32 SpellLevel
Definition: SpellInfo.h:384
bool IsAutocastable() const
Definition: SpellInfo.cpp:1597
uint32 const Id
Definition: SpellInfo.h:325
bool IsPassive() const
Definition: SpellInfo.cpp:1592
uint32 ProcCharges
Definition: SpellInfo.h:378
bool IsRanked() const
Definition: SpellInfo.cpp:4260
bool IsHighRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:4353
uint32 CasterAuraState
Definition: SpellInfo.h:353
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
int32 GetDuration() const
Definition: SpellInfo.cpp:3791
bool IsDifferentRankOf(SpellInfo const *spellInfo) const
Definition: SpellInfo.cpp:4346
bool IsPositive() const
Definition: SpellInfo.cpp:1709
bool Remove(KEY_TYPE const &handle)
bool Insert(KEY_TYPE const &handle, SPECIFIC_TYPE *obj)
Definition: Unit.h:627
void SetMinion(Minion *minion, bool apply)
Definition: Unit.cpp:6062
bool HasPetFlag(UnitPetFlag flags) const
Definition: Unit.h:878
bool IsHunterPet() const
Definition: Unit.h:741
void SetCreateStat(Stats stat, float val)
Definition: Unit.h:1392
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
Pet * ToPet()
Definition: Unit.h:1750
void SetGender(Gender gender)
Definition: Unit.h:756
void SetFullHealth()
Definition: Unit.h:790
void ReplaceAllNpcFlags2(NPCFlags2 flags)
Definition: Unit.h:990
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void AddToWorld() override
Definition: Unit.cpp:9603
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1814
uint8 GetClass() const
Definition: Unit.h:752
void SetCreateHealth(uint32 val)
Definition: Unit.h:1393
std::unique_ptr< CharmInfo > m_charmInfo
Definition: Unit.h:1902
void SetFaction(uint32 faction) override
Definition: Unit.h:859
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value)
Definition: Unit.h:1530
ObjectGuid GetOwnerGUID() const override
Definition: Unit.h:1170
void SetStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float val)
Definition: Unit.cpp:9021
void SetPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:9419
void ReplaceAllUnitFlags(UnitFlags flags)
Definition: Unit.h:835
bool IsPet() const
Definition: Unit.h:740
Powers GetPowerType() const
Definition: Unit.h:799
void SetCreatedBySpell(int32 spellId)
Definition: Unit.h:847
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:11618
void SetUnitFlag2(UnitFlags2 flags)
Definition: Unit.h:838
void ReplaceAllPetFlags(UnitPetFlag flags)
Definition: Unit.h:881
void SetPetNameTimestamp(uint32 timestamp)
Definition: Unit.h:1225
bool IsAlive() const
Definition: Unit.h:1164
float GetCombatReach() const override
Definition: Unit.h:694
DeathState m_deathState
Definition: Unit.h:1857
uint32 m_unitTypeMask
Definition: Unit.h:1913
CharmInfo * GetCharmInfo()
Definition: Unit.h:1221
void SetBaseAttackTime(WeaponAttackType att, uint32 val)
Definition: Unit.cpp:10308
void SetSheath(SheathState sheathed)
Definition: Unit.cpp:5630
void SetCreateMana(uint32 val)
Definition: Unit.h:1395
uint32 GetDisplayId() const
Definition: Unit.h:1567
uint32 GetNativeDisplayId() const
Definition: Unit.h:1570
bool isPossessed() const
Definition: Unit.h:1216
uint64 GetHealth() const
Definition: Unit.h:776
uint32 GetFaction() const override
Definition: Unit.h:858
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition: Unit.cpp:5961
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4674
uint32 GetArmor() const
Definition: Unit.h:762
void SetFullPower(Powers power)
Definition: Unit.h:812
bool IsMounted() const
Definition: Unit.h:898
void SetPowerType(Powers power, bool sendUpdate=true)
Definition: Unit.cpp:5534
int32 GetPower(Powers power) const
Definition: Unit.cpp:9401
float GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon=true) const
Definition: Unit.cpp:9285
DeathState getDeathState() const
Definition: Unit.h:1167
bool IsCritter() const
Definition: Unit.h:1010
AuraMap m_ownedAuras
Definition: Unit.h:1875
void SetLevel(uint8 lvl, bool sendUpdate=true)
Definition: Unit.cpp:9329
void SetCanModifyStats(bool modifyStats)
Definition: Unit.h:1506
CharmInfo * InitCharmInfo()
Definition: Unit.cpp:9748
void SetClass(uint8 classId)
Definition: Unit.h:753
void RemoveFromWorld() override
Definition: Unit.cpp:9611
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
Powers CalculateDisplayPowerType() const
Definition: Unit.cpp:5575
float GetStat(Stats stat) const
Definition: Unit.h:760
void RemoveAllAuras()
Definition: Unit.cpp:4242
SpellHistory * GetSpellHistory()
Definition: Unit.h:1457
void SetCreatorGUID(ObjectGuid creator)
Definition: Unit.h:1173
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:984
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition: Unit.cpp:6894
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
Definition: Unit.cpp:9012
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3831
uint8 GetLevel() const
Definition: Unit.h:746
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
ObjectGuid GetPetGUID() const
Definition: Unit.h:1176
constexpr uint32 GetMapId() const
Definition: Position.h:201
Map * GetMap() const
Definition: Object.h:624
std::string m_name
Definition: Object.h:795
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float relAngle=0) const
Definition: Object.cpp:3403
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
ZoneScript * GetZoneScript() const
Definition: Object.h:630
std::string const & GetName() const
Definition: Object.h:555
virtual void SetMap(Map *map)
Definition: Object.cpp:1794
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
void SetName(std::string newname)
Definition: Object.h:556
float GetVisibilityRange() const
Definition: Object.cpp:1447
WorldPacket const * Write() override
Definition: PetPackets.cpp:63
std::vector< uint32 > Spells
Definition: PetPackets.h:139
WorldPacket const * Write() override
Definition: PetPackets.cpp:71
WorldPacket const * Write() override
Definition: PetPackets.cpp:169
std::string GetPlayerInfo() const
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
#define sWorld
Definition: World.h:931
@ CONFIG_MAX_PLAYER_LEVEL
Definition: World.h:259
void apply(T *val)
Definition: ByteConverter.h:41
time_t GetGameTime()
Definition: GameTime.cpp:44
AuraCreateInfo & SetBaseAmount(int32 const *bp)
AuraCreateInfo & SetCasterGUID(ObjectGuid const &guid)
uint32 SpellId
Definition: SpellAuras.h:106
ObjectGuid Caster
Definition: SpellAuras.h:104
uint32 EffectMask
Definition: SpellAuras.h:107
std::array< int32, MAX_SPELL_EFFECTS > BaseAmounts
Definition: SpellAuras.h:115
std::array< int32, MAX_SPELL_EFFECTS > Amounts
Definition: SpellAuras.h:114
TriggerCastFlags TriggerFlags
Definition: SpellDefines.h:478
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
Definition: SpellDefines.h:474
void SetIsCommandFollow(bool val)
Definition: Unit.cpp:12586
void SetIsAtStay(bool val)
Definition: Unit.cpp:12617
void SetIsFollowing(bool val)
Definition: Unit.cpp:12627
void SetIsReturning(bool val)
Definition: Unit.cpp:12637
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:12576
int32 GetHealthScalingExpansion() const
Definition: CreatureData.h:459
CreatureDifficulty const * GetDifficulty(Difficulty difficulty) const
Definition: Creature.cpp:238
CreatureClassifications Classification
Definition: CreatureData.h:497
CreatureFamily family
Definition: CreatureData.h:507
int32 resistance[MAX_SPELL_SCHOOL]
Definition: CreatureData.h:510
bool IsTameable(bool canTameExotic, CreatureDifficulty const *creatureDifficulty) const
Definition: CreatureData.h:541
uint32 FoodType
Definition: ItemTemplate.h:832
uint16 health
Definition: ObjectMgr.h:680
uint16 armor
Definition: ObjectMgr.h:682
uint16 stats[MAX_STATS]
Definition: ObjectMgr.h:679
uint16 mana
Definition: ObjectMgr.h:681
Definition: Pet.h:27
PetSpellState state
Definition: Pet.h:29
PetSpellType type
Definition: Pet.h:30
ActiveStates active
Definition: Pet.h:28
uint32 CreatedBySpellId
Definition: PetDefines.h:149
ReactStates ReactState
Definition: PetDefines.h:152
std::string Name
Definition: PetDefines.h:140
uint16 SpecializationId
Definition: PetDefines.h:150
std::string ActionBar
Definition: PetDefines.h:141
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
std::string ToString() const
Definition: Position.cpp:128
bool IsPositionValid() const
Definition: Position.cpp:42
constexpr void Relocate(float x, float y)
Definition: Position.h:63
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78