Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Pet.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 "Common.h"
7#include "CreatureAI.h"
8#include "DatabaseEnv.h"
9#include "Formulas.h"
10#include "Group.h"
11#include "Log.h"
12#include "ObjectMgr.h"
13#include "Opcodes.h"
14#include "Pet.h"
16#include "PetTransportSupport.h"
17#include "SpellAuraEffects.h"
18#include "SpellAuras.h"
19#include "SpellMgr.h"
20#include "Unit.h"
21#include "Util.h"
22#include "WorldPacket.h"
23#include "WorldSession.h"
24
25#define PET_XP_FACTOR 0.05f
26
46
48{
49 delete m_declinedname;
50}
51
53{
55 if (!IsInWorld())
56 {
58 sObjectAccessor->AddObject(this);
61 }
62
63 // Prevent stuck pets when zoning. Pets default to "follow" when added to world
64 // so we'll reset flags and let the AI handle things
65 if (GetCharmInfo() && GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
66 {
69 GetCharmInfo()->SetIsAtStay(false);
72 }
73}
74
76{
78 if (IsInWorld())
79 {
82 sObjectAccessor->RemoveObject(this);
83 }
84}
85
90
91bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool current)
92{
93 m_loading = true;
94
95 uint32 ownerid = owner->GetGUIDLow();
96
99
100 if (petnumber)
101 {
102 // Known petnumber entry
103 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_ENTRY);
104 stmt->setUInt32(0, ownerid);
105 stmt->setUInt32(1, petnumber);
106 }
107 else if (current)
108 {
109 // Current pet
110 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_ACTIVE_PET);
111 stmt->setUInt32(0, ownerid);
112 }
113 else if (petEntry)
114 {
115 // known petEntry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
116 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2);
117 stmt->setUInt32(0, ownerid);
118 stmt->setUInt32(1, petEntry);
120 }
121 else
122 {
123 // Any current or other non-stabled pet (for hunter "call pet")
124 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET_BY_SLOT);
125 stmt->setUInt32(0, ownerid);
127 }
128
129 result = CharacterDatabase.Query(stmt);
130
131 if (!result)
132 {
133 m_loading = false;
134 return false;
135 }
136
137 Field* fields = result->Fetch();
138
139 // update for case of current pet "slot = 0"
140 petEntry = fields[1].GetUInt32();
141 if (!petEntry)
142 return false;
143
144 uint32 summonSpellId = fields[14].GetUInt32();
145 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summonSpellId);
146
147 bool isTemporarySummon = spellInfo && spellInfo->GetDuration() > 0;
148 if (current && isTemporarySummon)
149 return false;
150
151 PetType petType = PetType(fields[15].GetUInt8());
152 if (petType == PetType::HUNTER_PET)
153 {
154 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
155 if (!creatureInfo || !creatureInfo->IsTameable(owner->CanTameExoticPets()))
156 return false;
157 }
158
159 uint32 petId = fields[0].GetUInt32();
160
161 if (current && owner->IsPetNeedBeTemporaryUnsummoned())
162 {
164 return false;
165 }
166
167 Map* map = owner->GetMap();
168 uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_PET);
169 if (!Create(guid, map, /*owner->GetPhaseMask(),*/ petEntry, petId))
170 return false;
171
172 float px, py, pz;
174 Relocate(px, py, pz, owner->GetOrientation());
175
176 if (!IsPositionValid())
177 {
178 SF_LOG_ERROR("entities.pet", "Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",
180 return false;
181 }
182 for (auto itr : owner->GetPhases())
183 SetPhased(itr, false, true);
184 setPetType(petType);
185 setFaction(owner->getFaction());
187
188 CreatureTemplate const* cinfo = GetCreatureTemplate();
189 if (cinfo->type == CREATURE_TYPE_CRITTER)
190 {
191 map->AddToMap(this->ToCreature());
192 return true;
193 }
194
195 m_charmInfo->SetPetNumber(petId, IsPermanentPetFor(owner));
196
197 SetDisplayId(fields[3].GetUInt32());
198 SetNativeDisplayId(fields[3].GetUInt32());
199 uint32 petlevel = fields[4].GetUInt16();
201 SetName(fields[8].GetString());
202
203 switch (getPetType())
204 {
206 petlevel = owner->getLevel();
209 // this enables popup window (pet dismiss, cancel)
210 break;
218 // this enables popup window (pet abandon, cancel)
220 break;
221 default:
222 if (!IsPetGhoul())
223 SF_LOG_ERROR("entities.pet", "Pet have incorrect type (%u) for pet loading.", uint8(getPetType()));
224 break;
225 }
226
227 SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped here
228 SetCreatorGUID(owner->GetGUID());
229
230 InitStatsForLevel(petlevel);
231 SetUInt32Value(UNIT_FIELD_PET_EXPERIENCE, fields[5].GetUInt32());
232
234
235 SetReactState(ReactStates(fields[6].GetUInt8()));
236 SetCanModifyStats(true);
237
238 if (getPetType() == PetType::SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current
240 else
241 {
242 uint32 savedhealth = fields[10].GetUInt32();
243 uint32 savedmana = fields[11].GetUInt32();
244 if (!savedhealth && getPetType() == PetType::HUNTER_PET)
246 else
247 {
248 SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth);
250 }
251 }
252
253 bool const isActivePet = fields[17].GetBool();
254
255 // set loaded pet as current
256 if (!isActivePet || fields[7].GetUInt8())
257 {
258 SQLTransaction trans = CharacterDatabase.BeginTransaction();
259
262 stmt->setUInt32(1, ownerid);
264 stmt->setUInt32(3, m_charmInfo->GetPetNumber());
265 trans->Append(stmt);
266
267 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID);
269 stmt->setUInt32(1, ownerid);
270 stmt->setUInt32(2, m_charmInfo->GetPetNumber());
271 trans->Append(stmt);
272
273 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_ACTIVE_BY_OWNER);
274 stmt->setUInt32(0, ownerid);
275 trans->Append(stmt);
276
277 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_ACTIVE_BY_ID);
278 stmt->setUInt32(0, ownerid);
279 stmt->setUInt32(1, m_charmInfo->GetPetNumber());
280 trans->Append(stmt);
281
282 CharacterDatabase.CommitTransaction(trans);
283 }
284
285 // Send fake summon spell cast - this is needed for correct cooldown application for spells
286 // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside
288 // TODO FIX THIS GOD DAMN HACK
289 /*if (summonSpellId)
290 {
291 WorldPacket data(SMSG_SPELL_GO, (8+8+4+4+2));
292 data.append(owner->GetPackGUID());
293 data.append(owner->GetPackGUID());
294 data << uint8(0);
295 data << uint32(summonSpellId);
296 data << uint32(256); // CAST_FLAG_UNKNOWN3
297 data << uint32(0);
298 owner->SendMessageToSet(&data, true);
299 }
300 */
301
302 owner->SetMinion(this, true);
304 map->AddToMap(this->ToCreature());
306
307 uint16 specId = fields[16].GetUInt16();
308 SetSpec(specId);
309
310 InitTalentForLevel(); // set original talents points before spell loading
311
312 uint32 timediff = uint32(time(NULL) - fields[13].GetUInt32());
313 _LoadAuras(timediff);
314
315 // load action bar, if data broken will fill later by default spells.
316 if (!isTemporarySummon)
317 {
318 m_charmInfo->LoadPetActionBar(fields[12].GetString());
319
320 _LoadSpells();
321 InitTalentForLevel(); // re-init to check talent count
325 CastPetAuras(current);
326 }
327
328 CleanupActionBar(); // remove unknown spells from action bar after load
329
330 SF_LOG_DEBUG("entities.pet", "New Pet has guid %u", GetGUIDLow());
331
332 owner->PetSpellInitialize();
333
334 if (owner->GetGroup())
336
338 {
340 stmt->setUInt32(0, owner->GetGUIDLow());
341 stmt->setUInt32(1, GetCharmInfo()->GetPetNumber());
342 PreparedQueryResult result = CharacterDatabase.Query(stmt);
343
344 if (result)
345 {
346 delete m_declinedname;
348 Field* fields2 = result->Fetch();
349 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
350 {
351 m_declinedname->name[i] = fields2[i].GetString();
352 }
353 }
354 }
355
356 //set last used pet number (for use in BG's)
358 owner->ToPlayer()->SetLastPetNumber(petId);
359
360 m_loading = false;
361
362 return true;
363}
364
366{
367 if (!GetEntry())
368 return;
369
370 // save only fully controlled creature
371 if (!isControlled())
372 return;
373
374 // not save not player pets
376 return;
377
378 Player* owner = GetOwner();
379 if (!owner)
380 return;
381
382 // not save pet as current if another pet temporary unsummoned
384 owner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
385 {
386 // pet will lost anyway at restore temporary unsummoned
388 return;
389
390 // for warlock case
392 }
393
394 bool const saveAsActive = mode == PET_SAVE_AS_CURRENT ||
396 PetSaveMode const dbMode = saveAsActive ? PET_SAVE_AS_CURRENT : mode;
397
398 uint32 curhealth = GetHealth();
399 uint32 curmana = GetPower(POWER_MANA);
400
401 SQLTransaction trans = CharacterDatabase.BeginTransaction();
402 // save auras before possibly removing them
403 _SaveAuras(trans);
404
405 // stable and not in slot saves
406 if (mode > PET_SAVE_AS_CURRENT)
408
409 _SaveSpells(trans);
410 _SaveSpellCooldowns(trans);
411 CharacterDatabase.CommitTransaction(trans);
412
413 // current/stable/not_in_slot
414 if (mode >= PET_SAVE_AS_CURRENT)
415 {
416 uint32 ownerLowGUID = GUID_LOPART(GetOwnerGUID());
417 std::string name = m_name;
418 CharacterDatabase.EscapeString(name);
419 trans = CharacterDatabase.BeginTransaction();
420 // remove current data
421
422 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_ID);
423 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
424 trans->Append(stmt);
425
426 // prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT)
427 if (mode <= PET_SAVE_LAST_STABLE_SLOT)
428 {
429 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT);
431 stmt->setUInt32(1, ownerLowGUID);
432 stmt->setUInt8(2, uint8(mode));
433 trans->Append(stmt);
434 }
435
436 if (saveAsActive)
437 {
438 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_ACTIVE_BY_OWNER);
439 stmt->setUInt32(0, ownerLowGUID);
440 trans->Append(stmt);
441 }
442
443 // prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT
445 {
446 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_SLOT);
447 stmt->setUInt32(0, ownerLowGUID);
450 trans->Append(stmt);
451 }
452
453 // save pet
454 std::ostringstream ss;
455 ss << "INSERT INTO character_pet (id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, active, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType, PetSpecId) "
456 << "VALUES ("
457 << m_charmInfo->GetPetNumber() << ','
458 << GetEntry() << ','
459 << ownerLowGUID << ','
460 << GetNativeDisplayId() << ','
461 << uint32(getLevel()) << ','
463 << uint32(GetReactState()) << ','
464 << uint32(dbMode) << ", '"
465 << name.c_str() << "', "
467 << uint32(saveAsActive ? 1 : 0) << ','
468 << curhealth << ','
469 << curmana << ", '";
470
472 {
473 ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << ' '
474 << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << ' ';
475 };
476
477 ss << "', "
478 << time(NULL) << ','
480 << uint32(getPetType()) << ','
481 << uint16(m_petSpec) << ')';
482
483 trans->Append(ss.str().c_str());
484 CharacterDatabase.CommitTransaction(trans);
485 }
486 // delete
487 else
488 {
490 DeleteFromDB(m_charmInfo->GetPetNumber());
491 }
492}
493
495{
496 SQLTransaction trans = CharacterDatabase.BeginTransaction();
497
498 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_BY_ID);
499 stmt->setUInt32(0, guidlow);
500 trans->Append(stmt);
501
502 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
503 stmt->setUInt32(0, guidlow);
504 trans->Append(stmt);
505
506 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS);
507 stmt->setUInt32(0, guidlow);
508 trans->Append(stmt);
509
510 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELLS);
511 stmt->setUInt32(0, guidlow);
512 trans->Append(stmt);
513
514 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_COOLDOWNS);
515 stmt->setUInt32(0, guidlow);
516 trans->Append(stmt);
517
518 CharacterDatabase.CommitTransaction(trans);
519}
520
521void Pet::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
522{
525 {
527 {
528 // pet corpse non lootable and non skinnable
531 //SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
532 }
533 }
534 else if (getDeathState() == DeathState::ALIVE)
535 {
536 //RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
537 CastPetAuras(true);
538 }
539}
540
542{
543 if (m_removed) // pet already removed, just wait in remove queue, no updates
544 return;
545
546 if (m_loading)
547 return;
548
550 {
551 if (m_transportExitGraceTimer <= diff)
553 else
555 }
556
557 switch (m_deathState)
558 {
560 {
561 if (getPetType() != PetType::HUNTER_PET || m_corpseRemoveTime <= time(NULL))
562 {
563 Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
564 return;
565 }
566 break;
567 }
569 {
570 // unsummon pet that lost owner
571 Player* owner = GetOwner();
572 bool petOnOwnerTransport = false;
573 bool petInVisibilityRange = false;
574 if (owner)
575 {
576 Transport* ownerTransport = owner->GetTransport();
577 petOnOwnerTransport = ownerTransport && GetTransport() == ownerTransport;
580 petOnOwnerTransport))
581 {
583 petOnOwnerTransport = ownerTransport && GetTransport() == ownerTransport;
584 }
585
586 petInVisibilityRange = IsWithinDistInMap(owner, GetMap()->GetVisibilityRange());
587 }
588
589 if (!owner || Skyfire::PetTransport::ShouldRemovePetForOwnerRange(true, isPossessed(), petOnOwnerTransport,
590 petInVisibilityRange, HasTransportExitGrace()) || (isControlled() && !owner->GetPetGUID()))
591 //if (!owner || (!IsWithinDistInMap(owner, GetMap()->GetVisibilityDistance()) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID()))
592 {
594 return;
595 }
596
597 if (isControlled())
598 {
599 if (owner->GetPetGUID() != GetGUID())
600 {
601 SF_LOG_ERROR("entities.pet", "Pet %u is not pet of owner %s, removed", GetEntry(), GetOwner()->GetName().c_str());
603 return;
604 }
605 }
606
607 if (m_duration > 0)
608 {
609 if (uint32(m_duration) > diff)
610 m_duration -= diff;
611 else
612 {
614 return;
615 }
616 }
617
618 //regenerate focus for hunter pets or energy for deathknight's ghoul
619 if (m_regenTimer)
620 {
621 if (m_regenTimer > diff)
622 m_regenTimer -= diff;
623 else
624 {
625 switch (getPowerType())
626 {
627 case POWER_FOCUS:
631
632 // Reset if large diff (lag) causes focus to get 'stuck'
635
636 break;
637
638 // in creature::update
639 //case POWER_ENERGY:
640 // Regenerate(POWER_ENERGY);
641 // m_regenTimer += CREATURE_REGEN_INTERVAL - diff;
642 // if (!m_regenTimer) ++m_regenTimer;
643 // break;
644 default:
645 m_regenTimer = 0;
646 break;
647 }
648 }
649 }
650 break;
651 }
652 default:
653 break;
654 }
655 Creature::Update(diff);
656}
657
659{
660 uint32 curValue = GetPower(power);
661 uint32 maxValue = GetMaxPower(power);
662
663 if (curValue >= maxValue)
664 return;
665
666 float addvalue = 0.0f;
667
668 switch (power)
669 {
670 case POWER_FOCUS:
671 {
672 // For hunter pets.
673 addvalue = 24 * sWorld->getRate(Rates::RATE_POWER_FOCUS);
674 break;
675 }
676 case POWER_ENERGY:
677 {
678 // For deathknight's ghoul.
679 addvalue = 20;
680 break;
681 }
682 default:
683 return;
684 }
685
686 // Apply modifiers (if any).
688 for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
689 if (Powers((*i)->GetMiscValue()) == power)
690 AddPct(addvalue, (*i)->GetAmount());
691
693
694 ModifyPower(power, int32(addvalue));
695}
696
697void Pet::Remove(PetSaveMode mode, bool returnreagent)
698{
699 GetOwner()->RemovePet(this, mode, returnreagent);
700}
701
703{
705 return;
706
707 if (xp < 1)
708 return;
709
710 if (!IsAlive())
711 return;
712
713 uint8 maxlevel = std::min((uint8)sWorld->getIntConfig(WorldIntConfigs::CONFIG_MAX_PLAYER_LEVEL), GetOwner()->getLevel());
714 uint8 petlevel = getLevel();
715
716 // If pet is detected to be at, or above(?) the players level, don't hand out XP
717 if (petlevel >= maxlevel)
718 return;
719
722 uint32 newXP = curXP + xp;
723
724 // Check how much XP the pet should receive, and hand off have any left from previous levelups
725 while (newXP >= nextLvlXP && petlevel < maxlevel)
726 {
727 // Subtract newXP from amount needed for nextlevel, and give pet the level
728 newXP -= nextLvlXP;
729 ++petlevel;
730
731 GivePetLevel(petlevel);
732
734 }
735 // Not affected by special conditions - give it new XP
736 SetUInt32Value(UNIT_FIELD_PET_EXPERIENCE, petlevel < maxlevel ? newXP : 0);
737}
738
740{
741 if (!level || level == getLevel())
742 return;
743
745 {
748 }
749
750 InitStatsForLevel(level);
753}
754
756{
757 ASSERT(creature);
758
759 if (!CreateBaseAtTamed(creature->GetCreatureTemplate(), creature->GetMap()/*, creature->GetPhaseMask()*/))
760 return false;
761
762 Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
763
764 if (!IsPositionValid())
765 {
766 SF_LOG_ERROR("entities.pet", "Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)",
768 return false;
769 }
770
771 CreatureTemplate const* cinfo = GetCreatureTemplate();
772 if (!cinfo)
773 {
774 SF_LOG_ERROR("entities.pet", "CreateBaseAtCreature() failed, creatureInfo is missing!");
775 return false;
776 }
777
778 SetDisplayId(creature->GetDisplayId());
779
780 if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
781 SetName(cFamily->Name);
782 else
783 SetName(creature->GetNameForLocaleIdx(sObjectMgr->GetDBCLocaleIndex()));
784
785 return true;
786}
787
789{
790 if (!CreateBaseAtTamed(cinfo, owner->GetMap()/*, owner->GetPhaseMask()*/))
791 return false;
792
793 if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
794 SetName(cFamily->Name);
795
796 Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
797
798 return true;
799}
800
801bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map/*, uint32 phaseMask*/)
802{
803 SF_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed");
804 uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_PET);
805 uint32 petId = sObjectMgr->GeneratePetNumber();
806 if (!Create(guid, map, /*phaseMask,*/ cinfo->Entry, petId))
807 return false;
808
814
815 if (cinfo->type == CREATURE_TYPE_BEAST)
816 {
822 }
823
824 return true;
825}
826
829{
830 CreatureTemplate const* cinfo = GetCreatureTemplate();
831 ASSERT(cinfo);
832
833 SetLevel(petlevel);
834
835 //Determine pet type
838 {
839 switch (GetOwner()->getClass())
840 {
841 case CLASS_WARLOCK:
842 case CLASS_SHAMAN: // Fire Elemental
843 case CLASS_DEATH_KNIGHT: // Risen Ghoul
844 case CLASS_MAGE:
845 petType = PetType::SUMMON_PET;
846 break;
847 case CLASS_HUNTER:
848 petType = PetType::HUNTER_PET;
850 break;
851 default:
852 SF_LOG_ERROR("entities.pet", "Unknown type pet %u is summoned by player class %u", GetEntry(), GetOwner()->getClass());
853 break;
854 }
855 }
856
857 uint32 creature_ID = (petType == PetType::HUNTER_PET) ? 1 : cinfo->Entry;
858
860
861 SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel * 50));
862
866
869
870 //scale
871 CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family);
872 if (cFamily && cFamily->minScale > 0.0f && petType == PetType::HUNTER_PET)
873 {
874 float scale;
875 if (getLevel() >= cFamily->maxScaleLevel)
876 scale = cFamily->maxScale;
877 else if (getLevel() <= cFamily->minScaleLevel)
878 scale = cFamily->minScale;
879 else
880 scale = cFamily->minScale + float(getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale);
881
882 SetObjectScale(scale);
883 }
884
885 // Resistance
886 for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
888
889 //health, mana, armor and resistance
890 PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(creature_ID, petlevel);
891 if (pInfo) // exist in DB
892 {
893 SetCreateHealth(pInfo->health);
894 if (petType != PetType::HUNTER_PET) //hunter pet use focus
895 SetCreateMana(pInfo->mana);
896
897 if (pInfo->armor > 0)
899
900 for (uint8 stat = 0; stat < MAX_STATS; ++stat)
901 SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
902 }
903 else // not exist in DB, use some default fake data
904 {
905 // remove elite bonuses included in DB values
906 CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(petlevel, cinfo->unit_class);
907 SetCreateHealth(stats->BaseHealth[(CURRENT_CONTENT_EXP == cinfo->expansion) ? 1 : 0]);
908 SetCreateMana(stats->BaseMana);
909
915 }
916
918 switch (petType)
919 {
921 {
922 // the damage bonus used for pets is either fire or shadow damage, whatever is higher
925 int32 val = (fire > shadow) ? fire : shadow;
926 if (val < 0)
927 val = 0;
928
929 SetBonusDamage(val * 0.15f);
930
933
934 //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, float(cinfo->attackpower));
935 break;
936 }
938 {
940 //these formula may not be correct; however, it is designed to be close to what it should be
941 //this makes dps 0.5 of pets level
943 //damage range is then petlevel / 2
945 //damage is increased afterwards as strength and pet scaling modify attack power
946 break;
947 }
948 default:
949 {
950 switch (GetEntry())
951 {
952 case 510: // mage Water Elemental
953 {
955 break;
956 }
957 case 1964: //force of nature
958 {
959 if (!pInfo)
960 SetCreateHealth(30 + 30 * petlevel);
962 SetBaseWeaponDamage(WeaponAttackType::BASE_ATTACK, WeaponDamageRange::MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2) + bonusDmg));
963 SetBaseWeaponDamage(WeaponAttackType::BASE_ATTACK, WeaponDamageRange::MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2) + bonusDmg));
964 break;
965 }
966 case 15352: //earth elemental 36213
967 {
968 if (!pInfo)
969 SetCreateHealth(100 + 120 * petlevel);
972 break;
973 }
974 case 15438: //fire elemental
975 {
976 if (!pInfo)
977 {
978 SetCreateHealth(40 * petlevel);
979 SetCreateMana(28 + 10 * petlevel);
980 }
984 break;
985 }
986 case 19668: // Shadowfiend
987 {
988 if (!pInfo)
989 {
990 SetCreateMana(28 + 10 * petlevel);
991 SetCreateHealth(28 + 30 * petlevel);
992 }
994 SetBaseWeaponDamage(WeaponAttackType::BASE_ATTACK, WeaponDamageRange::MINDAMAGE, float((petlevel * 4 - petlevel) + bonus_dmg));
995 SetBaseWeaponDamage(WeaponAttackType::BASE_ATTACK, WeaponDamageRange::MAXDAMAGE, float((petlevel * 4 + petlevel) + bonus_dmg));
996
997 break;
998 }
999 case 19833: //Snake Trap - Venomous Snake
1000 {
1003 break;
1004 }
1005 case 19921: //Snake Trap - Viper
1006 {
1009 break;
1010 }
1011 case 29264: // Feral Spirit
1012 {
1013 if (!pInfo)
1014 SetCreateHealth(30 * petlevel);
1015
1016 // wolf attack speed is 1.5s
1018
1021
1022 SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetOwner()->GetArmor()) * 0.35f); // Bonus Armor (35% of player armor)
1023 SetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(GetOwner()->GetStat(STAT_STAMINA)) * 0.3f); // Bonus Stamina (30% of player stamina)
1024 if (!HasAura(58877))//prevent apply twice for the 2 wolves
1025 AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done.
1026 break;
1027 }
1028 case 31216: // Mirror Image
1029 {
1032 if (!pInfo)
1033 {
1034 SetCreateMana(28 + 30 * petlevel);
1035 SetCreateHealth(28 + 10 * petlevel);
1036 }
1037 break;
1038 }
1039 case 27829: // Ebon Gargoyle
1040 {
1041 if (!pInfo)
1042 {
1043 SetCreateMana(28 + 10 * petlevel);
1044 SetCreateHealth(28 + 30 * petlevel);
1045 }
1049 break;
1050 }
1051 case 28017: // Bloodworms
1052 {
1053 SetCreateHealth(4 * petlevel);
1057 break;
1058 }
1059 case 63508: // Invoke Xuen
1060 {
1061 if (!pInfo)
1062 SetCreateHealth(30 * petlevel);
1063
1068 break;
1069 }
1070 default:
1071 break;
1072 }
1073 break;
1074 }
1075 }
1076
1078
1079 SetFullHealth();
1081 return true;
1082}
1083
1084bool Pet::HaveInDiet(ItemTemplate const* item) const
1085{
1086 if (!item->FoodType)
1087 return false;
1088
1089 CreatureTemplate const* cInfo = GetCreatureTemplate();
1090 if (!cInfo)
1091 return false;
1092
1093 CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cInfo->family);
1094 if (!cFamily)
1095 return false;
1096
1097 uint32 diet = cFamily->petFoodMask;
1098 uint32 FoodMask = 1 << (item->FoodType - 1);
1099 return diet & FoodMask;
1100}
1101
1103{
1104 // -5 or greater food level
1105 if (getLevel() <= itemlevel + 5) //possible to feed level 60 pet with level 55 level food for full effect
1106 return 35000;
1107 // -10..-6
1108 else if (getLevel() <= itemlevel + 10) //pure guess, but sounds good
1109 return 17000;
1110 // -14..-11
1111 else if (getLevel() <= itemlevel + 14) //level 55 food gets green on 70, makes sense to me
1112 return 8000;
1113 // -15 or less
1114 else
1115 return 0; //food too low level
1116}
1117
1119{
1122
1124 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1125 PreparedQueryResult result = CharacterDatabase.Query(stmt);
1126
1127 if (result)
1128 {
1129 time_t curTime = time(NULL);
1130 ObjectGuid guid = GetGUID();
1131 uint32 count = 0;
1132
1133 WorldPacket data(SMSG_SPELL_COOLDOWN, 9 + 3 + result->GetRowCount() * 8);
1134 data.WriteBit(guid[0]);
1135 data.WriteBit(guid[6]);
1136 data.WriteBit(1); // Missing flags
1137 data.WriteBit(guid[7]);
1138 data.WriteBit(guid[3]);
1139 data.WriteBit(guid[1]);
1140 data.WriteBit(guid[5]);
1141 size_t bitpos = data.bitwpos();
1142 data.WriteBits(0, 21);
1143 data.WriteBit(guid[2]);
1144 data.WriteBit(guid[4]);
1145 data.FlushBits();
1146
1147 do
1148 {
1149 Field* fields = result->Fetch();
1150
1151 uint32 spell_id = fields[0].GetUInt32();
1152 time_t db_time = time_t(fields[1].GetUInt32());
1153
1154 if (!sSpellMgr->GetSpellInfo(spell_id))
1155 {
1156 SF_LOG_ERROR("entities.pet", "Pet %u have unknown spell %u in `pet_spell_cooldown`, skipping.", m_charmInfo->GetPetNumber(), spell_id);
1157 continue;
1158 }
1159
1160 // skip outdated cooldown
1161 if (db_time <= curTime)
1162 continue;
1163
1164 data << uint32(spell_id);
1165 data << uint32(uint32(db_time - curTime) * IN_MILLISECONDS);
1166
1167 _AddCreatureSpellCooldown(spell_id, db_time);
1168 count++;
1169
1170 SF_LOG_DEBUG("entities.pet", "Pet (Number: %u) spell %u cooldown loaded (%u secs).", m_charmInfo->GetPetNumber(), spell_id, uint32(db_time - curTime));
1171 } while (result->NextRow());
1172
1173 data.PutBits(bitpos, count, 21);
1174 data.WriteByteSeq(guid[5]);
1175 data.WriteByteSeq(guid[3]);
1176 data.WriteByteSeq(guid[7]);
1177 data.WriteByteSeq(guid[4]);
1178 data.WriteByteSeq(guid[1]);
1179 data.WriteByteSeq(guid[0]);
1180 data.WriteByteSeq(guid[2]);
1181 data.WriteByteSeq(guid[6]);
1182
1183 if (!m_CreatureSpellCooldowns.empty() && GetOwner())
1184 GetOwner()->GetSession()->SendPacket(&data);
1185 }
1186}
1187
1189{
1191 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1192 trans->Append(stmt);
1193
1194 time_t curTime = time(NULL);
1195
1196 // remove oudated and save active
1197 for (CreatureSpellCooldowns::iterator itr = m_CreatureSpellCooldowns.begin(); itr != m_CreatureSpellCooldowns.end();)
1198 {
1199 if (itr->second <= curTime)
1200 m_CreatureSpellCooldowns.erase(itr++);
1201 else
1202 {
1203 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL_COOLDOWN);
1204 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1205 stmt->setUInt32(1, itr->first);
1206 stmt->setUInt32(2, uint32(itr->second));
1207 trans->Append(stmt);
1208
1209 ++itr;
1210 }
1211 }
1212}
1213
1215{
1216 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL);
1217 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1218 PreparedQueryResult result = CharacterDatabase.Query(stmt);
1219
1220 if (result)
1221 {
1222 do
1223 {
1224 Field* fields = result->Fetch();
1225
1226 addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt8()), PETSPELL_UNCHANGED);
1227 } while (result->NextRow());
1228 }
1229}
1230
1232{
1233 for (PetSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
1234 {
1235 ++next;
1236
1237 // prevent saving family passives to DB
1238 if (itr->second.type == PETSPELL_FAMILY)
1239 continue;
1240
1241 PreparedStatement* stmt;
1242
1243 switch (itr->second.state)
1244 {
1245 case PETSPELL_REMOVED:
1246 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_BY_SPELL);
1247 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1248 stmt->setUInt32(1, itr->first);
1249 trans->Append(stmt);
1250
1251 m_spells.erase(itr);
1252 continue;
1253 case PETSPELL_CHANGED:
1254 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_SPELL_BY_SPELL);
1255 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1256 stmt->setUInt32(1, itr->first);
1257 trans->Append(stmt);
1258
1259 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL);
1260 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1261 stmt->setUInt32(1, itr->first);
1262 stmt->setUInt8(2, itr->second.active);
1263 trans->Append(stmt);
1264
1265 break;
1266 case PETSPELL_NEW:
1267 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_SPELL);
1268 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1269 stmt->setUInt32(1, itr->first);
1270 stmt->setUInt8(2, itr->second.active);
1271 trans->Append(stmt);
1272 break;
1273 case PETSPELL_UNCHANGED:
1274 continue;
1275 }
1276 itr->second.state = PETSPELL_UNCHANGED;
1277 }
1278}
1279
1281{
1282 SF_LOG_DEBUG("entities.pet", "Loading auras for pet %u", GetGUIDLow());
1283
1284 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURA);
1285 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1286 PreparedQueryResult result = CharacterDatabase.Query(stmt);
1287
1288 if (result)
1289 {
1290 do
1291 {
1292 int32 damage[3];
1293 int32 baseDamage[3];
1294 Field* fields = result->Fetch();
1295 uint64 caster_guid = fields[0].GetUInt64();
1296 // NULL guid stored - pet is the caster of the spell - see Pet::_SaveAuras
1297 if (!caster_guid)
1298 caster_guid = GetGUID();
1299 uint32 spellid = fields[1].GetUInt32();
1300 uint32 effMask = fields[2].GetUInt32();
1301 uint32 recalculatemask = fields[3].GetUInt32();
1302 uint8 stackcount = fields[4].GetUInt8();
1303 damage[0] = fields[5].GetInt32();
1304 damage[1] = fields[6].GetInt32();
1305 damage[2] = fields[7].GetInt32();
1306 baseDamage[0] = fields[8].GetInt32();
1307 baseDamage[1] = fields[9].GetInt32();
1308 baseDamage[2] = fields[10].GetInt32();
1309 int32 maxduration = fields[11].GetInt32();
1310 int32 remaintime = fields[12].GetInt32();
1311 uint8 remaincharges = fields[13].GetUInt8();
1312
1313 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
1314 if (!spellInfo)
1315 {
1316 SF_LOG_ERROR("entities.pet", "Unknown aura (spellid %u), ignore.", spellid);
1317 continue;
1318 }
1319
1320 // negative effects should continue counting down after logout
1321 if (remaintime != -1 && !spellInfo->IsPositive())
1322 {
1323 if (remaintime / IN_MILLISECONDS <= int32(timediff))
1324 continue;
1325
1326 remaintime -= timediff * IN_MILLISECONDS;
1327 }
1328
1329 // prevent wrong values of remaincharges
1330 if (spellInfo->ProcCharges)
1331 {
1332 if (remaincharges <= 0 || remaincharges > spellInfo->ProcCharges)
1333 remaincharges = spellInfo->ProcCharges;
1334 }
1335 else
1336 remaincharges = 0;
1337
1338 if (Aura* aura = Aura::TryCreate(spellInfo, effMask, this, NULL, &baseDamage[0], NULL, caster_guid))
1339 {
1340 if (!aura->CanBeSaved())
1341 {
1342 aura->Remove();
1343 continue;
1344 }
1345 aura->SetLoadedState(maxduration, remaintime, remaincharges, stackcount, recalculatemask, &damage[0]);
1346 aura->ApplyForTargets();
1347 SF_LOG_INFO("entities.pet", "Added aura spellid %u, effectmask %u", spellInfo->Id, effMask);
1348 }
1349 } while (result->NextRow());
1350 }
1351}
1352
1354{
1355 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS);
1356 stmt->setUInt32(0, m_charmInfo->GetPetNumber());
1357 trans->Append(stmt);
1358
1359 for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end(); ++itr)
1360 {
1361 // check if the aura has to be saved
1362 if (!itr->second->CanBeSaved() || IsPetAura(itr->second))
1363 continue;
1364
1365 Aura* aura = itr->second;
1366
1367 int32 damage[MAX_SPELL_EFFECTS];
1368 int32 baseDamage[MAX_SPELL_EFFECTS];
1369 uint32 effMask = 0;
1370 uint8 recalculateMask = 0;
1371 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1372 {
1373 if (aura->GetEffect(i))
1374 {
1375 baseDamage[i] = aura->GetEffect(i)->GetBaseAmount();
1376 damage[i] = aura->GetEffect(i)->GetAmount();
1377 effMask |= (1 << i);
1378 if (aura->GetEffect(i)->CanBeRecalculated())
1379 recalculateMask |= (1 << i);
1380 }
1381 else
1382 {
1383 baseDamage[i] = 0;
1384 damage[i] = 0;
1385 }
1386 }
1387
1388 // 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
1389 uint64 casterGUID = (itr->second->GetCasterGUID() == GetGUID()) ? 0 : itr->second->GetCasterGUID();
1390
1391 uint8 index = 0;
1392
1393 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PET_AURA);
1394 stmt->setUInt32(index++, m_charmInfo->GetPetNumber());
1395 stmt->setUInt64(index++, casterGUID);
1396 stmt->setUInt32(index++, itr->second->GetId());
1397 stmt->setUInt8(index++, effMask);
1398 stmt->setUInt8(index++, recalculateMask);
1399 stmt->setUInt8(index++, itr->second->GetStackAmount());
1400 stmt->setInt32(index++, damage[0]);
1401 stmt->setInt32(index++, damage[1]);
1402 stmt->setInt32(index++, damage[2]);
1403 stmt->setInt32(index++, baseDamage[0]);
1404 stmt->setInt32(index++, baseDamage[1]);
1405 stmt->setInt32(index++, baseDamage[2]);
1406 stmt->setInt32(index++, itr->second->GetMaxDuration());
1407 stmt->setInt32(index++, itr->second->GetDuration());
1408 stmt->setUInt8(index++, itr->second->GetCharges());
1409
1410 trans->Append(stmt);
1411 }
1412}
1413
1414bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
1415{
1416 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1417 if (!spellInfo)
1418 {
1419 // do pet spell book cleanup
1420 if (state == PETSPELL_UNCHANGED) // spell load case
1421 {
1422 SF_LOG_ERROR("entities.pet", "Pet::addSpell: Non-existed in SpellStore spell #%u request, deleting for all pets in `pet_spell`.", spellId);
1423
1425
1426 stmt->setUInt32(0, spellId);
1427
1428 CharacterDatabase.Execute(stmt);
1429 }
1430 else
1431 SF_LOG_ERROR("entities.pet", "Pet::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
1432
1433 return false;
1434 }
1435
1436 PetSpellMap::iterator itr = m_spells.find(spellId);
1437 if (itr != m_spells.end())
1438 {
1439 if (itr->second.state == PETSPELL_REMOVED)
1440 {
1441 m_spells.erase(itr);
1442 state = PETSPELL_CHANGED;
1443 }
1444 else if (state == PETSPELL_UNCHANGED && itr->second.state != PETSPELL_UNCHANGED)
1445 {
1446 // can be in case spell loading but learned at some previous spell loading
1447 itr->second.state = PETSPELL_UNCHANGED;
1448
1449 if (active == ACT_ENABLED)
1450 ToggleAutocast(spellInfo, true);
1451 else if (active == ACT_DISABLED)
1452 ToggleAutocast(spellInfo, false);
1453
1454 return false;
1455 }
1456 else
1457 return false;
1458 }
1459
1460 PetSpell newspell;
1461 newspell.state = state;
1462 newspell.type = type;
1463
1464 if (active == ACT_DECIDE) // active was not used before, so we save it's autocast/passive state here
1465 {
1466 if (spellInfo->IsAutocastable())
1467 newspell.active = ACT_DISABLED;
1468 else
1469 newspell.active = ACT_PASSIVE;
1470 }
1471 else
1472 newspell.active = active;
1473
1474 if (spellInfo->IsRanked())
1475 {
1476 for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
1477 {
1478 if (itr2->second.state == PETSPELL_REMOVED)
1479 continue;
1480
1481 SpellInfo const* oldRankSpellInfo = sSpellMgr->GetSpellInfo(itr2->first);
1482
1483 if (!oldRankSpellInfo)
1484 continue;
1485
1486 if (spellInfo->IsDifferentRankOf(oldRankSpellInfo))
1487 {
1488 // replace by new high rank
1489 if (spellInfo->IsHighRankOf(oldRankSpellInfo))
1490 {
1491 newspell.active = itr2->second.active;
1492
1493 if (newspell.active == ACT_ENABLED)
1494 ToggleAutocast(oldRankSpellInfo, false);
1495
1496 unlearnSpell(itr2->first, false, false);
1497 break;
1498 }
1499 // ignore new lesser rank
1500 else
1501 return false;
1502 }
1503 }
1504 }
1505
1506 m_spells[spellId] = newspell;
1507
1508 if (spellInfo->IsPassive() && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState))))
1509 CastSpell(this, spellId, true);
1510 else
1511 m_charmInfo->AddSpellToActionBar(spellInfo);
1512
1513 if (newspell.active == ACT_ENABLED)
1514 ToggleAutocast(spellInfo, true);
1515
1516 uint32 talentCost = GetTalentSpellCost(spellId);
1517 if (talentCost)
1518 {
1519 int32 free_points = GetMaxTalentPointsForLevel(getLevel());
1520 m_usedTalentCount += talentCost;
1521 // update free talent points
1522 free_points -= m_usedTalentCount;
1523 SetFreeTalentPoints(free_points > 0 ? free_points : 0);
1524 }
1525 return true;
1526}
1527
1529{
1530 // prevent duplicated entires in spell book
1531 if (!addSpell(spell_id))
1532 return false;
1533
1534 if (!m_loading)
1535 {
1537 data << uint32(spell_id);
1538 GetOwner()->GetSession()->SendPacket(&data);
1540 }
1541 return true;
1542}
1543
1545{
1546 uint8 level = getLevel();
1547
1548 if (PetLevelupSpellSet const* levelupSpells = GetCreatureTemplate()->family ? sSpellMgr->GetPetLevelupSpellList(GetCreatureTemplate()->family) : NULL)
1549 {
1550 // PetLevelupSpellSet ordered by levels, process in reversed order
1551 for (PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
1552 {
1553 // will called first if level down
1554 if (itr->first > level)
1555 unlearnSpell(itr->second, true); // will learn prev rank if any
1556 // will called if level up
1557 else
1558 learnSpell(itr->second); // will unlearn prev rank if any
1559 }
1560 }
1561
1563
1564 // default spells (can be not learned if pet level (as owner level decrease result for example) less first possible in normal game)
1565 if (PetDefaultSpellsEntry const* defSpells = sSpellMgr->GetPetDefaultSpellsEntry(petSpellsId))
1566 {
1567 for (uint8 i = 0; i < MAX_CREATURE_SPELL_DATA_SLOT; ++i)
1568 {
1569 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(defSpells->spellid[i]);
1570 if (!spellInfo)
1571 continue;
1572
1573 // will called first if level down
1574 if (spellInfo->SpellLevel > level)
1575 unlearnSpell(spellInfo->Id, true);
1576 // will called if level up
1577 else
1578 learnSpell(spellInfo->Id);
1579 }
1580 }
1581
1584}
1585
1586bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
1587{
1588 if (removeSpell(spell_id, learn_prev, clear_ab))
1589 {
1590 if (!m_loading)
1591 {
1593 data << uint32(spell_id);
1594 GetOwner()->GetSession()->SendPacket(&data);
1595 }
1596 return true;
1597 }
1598 return false;
1599}
1600
1601bool Pet::removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
1602{
1603 PetSpellMap::iterator itr = m_spells.find(spell_id);
1604 if (itr == m_spells.end())
1605 return false;
1606
1607 if (itr->second.state == PETSPELL_REMOVED)
1608 return false;
1609
1610 if (itr->second.state == PETSPELL_NEW)
1611 m_spells.erase(itr);
1612 else
1613 itr->second.state = PETSPELL_REMOVED;
1614
1615 RemoveAurasDueToSpell(spell_id);
1616
1617 uint32 talentCost = GetTalentSpellCost(spell_id);
1618 if (talentCost > 0)
1619 {
1620 if (m_usedTalentCount > talentCost)
1621 m_usedTalentCount -= talentCost;
1622 else
1624 // update free talent points
1626 SetFreeTalentPoints(free_points > 0 ? free_points : 0);
1627 }
1628
1629 if (learn_prev)
1630 {
1631 if (uint32 prev_id = sSpellMgr->GetPrevSpellInChain(spell_id))
1632 learnSpell(prev_id);
1633 else
1634 learn_prev = false;
1635 }
1636
1637 // if remove last rank or non-ranked then update action bar at server and client if need
1638 if (clear_ab && !learn_prev && m_charmInfo->RemoveSpellFromActionBar(spell_id))
1639 {
1640 if (!m_loading)
1641 {
1642 // need update action bar for last removed rank
1643 if (Unit* owner = GetOwner())
1644 if (owner->GetTypeId() == TypeID::TYPEID_PLAYER)
1645 owner->ToPlayer()->PetSpellInitialize();
1646 }
1647 }
1648
1649 return true;
1650}
1651
1653{
1654 for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
1655 if (UnitActionBarEntry const* ab = m_charmInfo->GetActionBarEntry(i))
1656 if (ab->GetAction() && ab->IsActionBarForSpell())
1657 {
1658 if (!HasSpell(ab->GetAction()))
1659 m_charmInfo->SetActionBar(i, 0, ACT_PASSIVE);
1660 else if (ab->GetType() == ACT_ENABLED)
1661 {
1662 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(ab->GetAction()))
1663 ToggleAutocast(spellInfo, true);
1664 }
1665 }
1666}
1667
1669{
1670 m_charmInfo->InitPetActionBar();
1671 m_spells.clear();
1672
1675
1676 CastPetAuras(false);
1677}
1678
1680{/*
1681 Unit* owner = GetOwner();
1682 if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
1683 return false;
1684
1685 // not need after this call
1686 if (owner->ToPlayer()->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
1687 owner->ToPlayer()->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true);
1688
1689 CreatureTemplate const* ci = GetCreatureTemplate();
1690 if (!ci)
1691 return false;
1692 // Check pet talent type
1693 CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
1694 if (!pet_family || pet_family->petTalentType < 0)
1695 return false;
1696
1697 Player* player = owner->ToPlayer();
1698
1699 uint8 level = getLevel();
1700 uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
1701
1702 if (m_usedTalentCount == 0)
1703 {
1704 SetFreeTalentPoints(talentPointsForLevel);
1705 return false;
1706 }
1707
1708 for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
1709 {
1710 TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
1711
1712 if (!talentInfo)
1713 continue;
1714
1715
1716 // unlearn only talents for pets family talent type
1717 if (!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
1718 continue;
1719
1720 for (uint8 j = 0; j < MAX_TALENT_RANK; ++j)
1721 {
1722 for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end();)
1723 {
1724 if (itr->second.state == PETSPELL_REMOVED)
1725 {
1726 ++itr;
1727 continue;
1728 }
1729 // remove learned spells (all ranks)
1730 uint32 itrFirstId = sSpellMgr->GetFirstSpellInChain(itr->first);
1731
1732 // unlearn if first rank is talent or learned by talent
1733 if (itrFirstId == talentInfo->RankID[j] || sSpellMgr->IsSpellLearnToSpell(talentInfo->RankID[j], itrFirstId))
1734 {
1735 unlearnSpell(itr->first, false);
1736 itr = m_spells.begin();
1737 continue;
1738 }
1739 else
1740 ++itr;
1741 }
1742 }
1743 }
1744
1745 SetFreeTalentPoints(talentPointsForLevel);
1746
1747 if (!m_loading)
1748 player->PetSpellInitialize();*/
1749 return true;
1750}
1751
1752void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/)
1753{
1754 // not need after this call
1757
1758 // reset for online
1759 if (onlinePet)
1760 onlinePet->resetTalents();
1761
1762 // now need only reset for offline pets (all pets except online case)
1763 uint32 exceptPetNumber = onlinePet ? onlinePet->GetCharmInfo()->GetPetNumber() : 0;
1764
1765 PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET);
1766 stmt->setUInt32(0, owner->GetGUIDLow());
1767 stmt->setUInt32(1, exceptPetNumber);
1768 PreparedQueryResult resultPets = CharacterDatabase.Query(stmt);
1769
1770 // no offline pets
1771 if (!resultPets)
1772 return;
1773
1774 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_LIST);
1775 stmt->setUInt32(0, owner->GetGUIDLow());
1776 stmt->setUInt32(1, exceptPetNumber);
1777 PreparedQueryResult result = CharacterDatabase.Query(stmt);
1778
1779 if (!result)
1780 return;
1781
1782 bool need_comma = false;
1783 std::ostringstream ss;
1784 ss << "DELETE FROM pet_spell WHERE guid IN (";
1785
1786 do
1787 {
1788 Field* fields = resultPets->Fetch();
1789
1790 uint32 id = fields[0].GetUInt32();
1791
1792 if (need_comma)
1793 ss << ',';
1794
1795 ss << id;
1796
1797 need_comma = true;
1798 } while (resultPets->NextRow());
1799
1800 ss << ") AND spell IN (";
1801
1802 bool need_execute = false;
1803 do
1804 {
1805 Field* fields = result->Fetch();
1806
1807 uint32 spell = fields[0].GetUInt32();
1808
1809 if (!GetTalentSpellCost(spell))
1810 continue;
1811
1812 if (need_execute)
1813 ss << ',';
1814
1815 ss << spell;
1816
1817 need_execute = true;
1818 } while (result->NextRow());
1819
1820 if (!need_execute)
1821 return;
1822
1823 ss << ')';
1824
1825 CharacterDatabase.Execute(ss.str().c_str());
1826}
1827
1829{
1830 uint8 level = getLevel();
1831 uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
1832 // Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent)
1833 if (talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel)
1834 resetTalents(); // Remove all talent points
1835
1836 SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
1837
1838 Unit* owner = GetOwner();
1839 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
1840 return;
1841}
1842
1844{
1845 uint8 points = (level >= 20) ? ((level - 16) / 4) : 0;
1846 // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS
1847 if (Unit* owner = GetOwner())
1848 points += owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS);
1849 return points;
1850}
1851
1852void Pet::ToggleAutocast(SpellInfo const* spellInfo, bool apply)
1853{
1854 if (!spellInfo->IsAutocastable())
1855 return;
1856
1857 uint32 spellid = spellInfo->Id;
1858
1859 PetSpellMap::iterator itr = m_spells.find(spellid);
1860 if (itr == m_spells.end())
1861 return;
1862
1863 uint32 i;
1864
1865 if (apply)
1866 {
1867 for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; ++i); // just search
1868
1869 if (i == m_autospells.size())
1870 {
1871 m_autospells.push_back(spellid);
1872
1873 if (itr->second.active != ACT_ENABLED)
1874 {
1875 itr->second.active = ACT_ENABLED;
1876 if (itr->second.state != PETSPELL_NEW)
1877 itr->second.state = PETSPELL_CHANGED;
1878 }
1879 }
1880 }
1881 else
1882 {
1883 AutoSpellList::iterator itr2 = m_autospells.begin();
1884 for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; ++i, ++itr2); // just search
1885
1886 if (i < m_autospells.size())
1887 {
1888 m_autospells.erase(itr2);
1889 if (itr->second.active != ACT_DISABLED)
1890 {
1891 itr->second.active = ACT_DISABLED;
1892 if (itr->second.state != PETSPELL_NEW)
1893 itr->second.state = PETSPELL_CHANGED;
1894 }
1895 }
1896 }
1897}
1898
1900{
1901 switch (getPetType())
1902 {
1904 switch (owner->getClass())
1905 {
1906 case CLASS_WARLOCK:
1908 case CLASS_DEATH_KNIGHT:
1910 case CLASS_MAGE:
1912 default:
1913 return false;
1914 }
1916 return true;
1917 default:
1918 return false;
1919 }
1920}
1921
1922bool Pet::Create(uint32 guidlow, Map* map, /*uint32 phaseMask,*/ uint32 Entry, uint32 petId)
1923{
1924 ASSERT(map);
1925 SetMap(map);
1926
1927 //SetPhaseMask(phaseMask, false);
1928 Object::_Create(guidlow, petId, HIGHGUID_PET);
1929
1930 m_DBTableGuid = guidlow;
1932
1933 if (!InitEntry(Entry))
1934 return false;
1935
1938
1939 return true;
1940}
1941
1942bool Pet::HasSpell(uint32 spell) const
1943{
1944 PetSpellMap::const_iterator itr = m_spells.find(spell);
1945 return itr != m_spells.end() && itr->second.state != PETSPELL_REMOVED;
1946}
1947
1948// Get all passive spells in our skill line
1950{
1951 CreatureTemplate const* cInfo = GetCreatureTemplate();
1952 if (!cInfo)
1953 return;
1954
1955 CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cInfo->family);
1956 if (!cFamily)
1957 return;
1958
1959 PetFamilySpellsStore::const_iterator petStore = sPetFamilySpellsStore.find(cFamily->ID);
1960 if (petStore != sPetFamilySpellsStore.end())
1961 {
1962 // For general hunter pets skill 270
1963 // Passive 01~10, Passive 00 (20782, not used), Ferocious Inspiration (34457)
1964 // Scale 01~03 (34902~34904, bonus from owner, not used)
1965 for (PetFamilySpellsSet::const_iterator petSet = petStore->second.begin(); petSet != petStore->second.end(); ++petSet)
1967 }
1968}
1969
1970void Pet::CastPetAuras(bool current)
1971{
1972 Unit* owner = GetOwner();
1973 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
1974 return;
1975
1976 if (!IsPermanentPetFor(owner->ToPlayer()))
1977 return;
1978
1979 for (PetAuraSet::const_iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end();)
1980 {
1981 PetAura const* pa = *itr;
1982 ++itr;
1983
1984 if (!current && pa->IsRemovedOnChangePet())
1985 owner->RemovePetAura(pa);
1986 else
1987 CastPetAura(pa);
1988 }
1989}
1990
1991void Pet::CastPetAura(PetAura const* aura)
1992{
1993 uint32 auraId = aura->GetAura(GetEntry());
1994 if (!auraId)
1995 return;
1996
1997 if (auraId == 35696) // Demonic Knowledge
1998 {
2000 CastCustomSpell(this, auraId, &basePoints, NULL, NULL, true);
2001 }
2002 else
2003 CastSpell(this, auraId, true);
2004}
2005
2006bool Pet::IsPetAura(Aura const* aura)
2007{
2008 Unit* owner = GetOwner();
2009
2010 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
2011 return false;
2012
2013 // if the owner has that pet aura, return true
2014 for (PetAuraSet::const_iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end(); ++itr)
2015 {
2016 if ((*itr)->GetAura(GetEntry()) == aura->GetId())
2017 return true;
2018 }
2019 return false;
2020}
2021
2023{
2024 learnSpell(spellid);
2025
2026 if (uint32 next = sSpellMgr->GetNextSpellInChain(spellid))
2027 learnSpellHighRank(next);
2028}
2029
2031{
2032 Unit* owner = GetOwner();
2033 if (!owner || owner->GetTypeId() != TypeID::TYPEID_PLAYER)
2034 return;
2035
2036 switch (getPetType())
2037 {
2038 // always same level
2040 GivePetLevel(owner->getLevel());
2041 break;
2042 // can't be greater owner level
2044 if (getLevel() > owner->getLevel())
2045 GivePetLevel(owner->getLevel());
2046 else if (getLevel() + 5 < owner->getLevel())
2047 GivePetLevel(owner->getLevel() - 5);
2048 break;
2049 default:
2050 break;
2051 }
2052}
2053
2055{
2056 time_t curTime = time(NULL);
2057 ObjectGuid guid = GetGUID();
2058 uint32 count = 0;
2059
2060 WorldPacket data(SMSG_SPELL_COOLDOWN, 9 + 3 + m_spells.size() * 8);
2061 data.WriteBit(guid[0]);
2062 data.WriteBit(guid[6]);
2063 data.WriteBit(1); // Missing flags
2064 data.WriteBit(guid[7]);
2065 data.WriteBit(guid[3]);
2066 data.WriteBit(guid[1]);
2067 data.WriteBit(guid[5]);
2068 size_t bitpos = data.bitwpos();
2069 data.WriteBits(0, 21);
2070 data.WriteBit(guid[2]);
2071 data.WriteBit(guid[4]);
2072 data.FlushBits();
2073
2074 for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
2075 {
2076 if (itr->second.state == PETSPELL_REMOVED)
2077 continue;
2078
2079 uint32 unSpellId = itr->first;
2080 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
2081 if (!spellInfo)
2082 {
2083 ASSERT(spellInfo);
2084 continue;
2085 }
2086
2087 // Not send cooldown for this spells
2088 if (spellInfo->IsCooldownStartedOnEvent())
2089 continue;
2090
2092 continue;
2093
2094 if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
2095 {
2096 data << uint32(unSpellId);
2097 data << uint32(unTimeMs); // in m.secs
2098 count++;
2099 _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs / IN_MILLISECONDS);
2100 }
2101 }
2102
2103 data.PutBits(bitpos, count, 21);
2104 data.WriteByteSeq(guid[5]);
2105 data.WriteByteSeq(guid[3]);
2106 data.WriteByteSeq(guid[7]);
2107 data.WriteByteSeq(guid[4]);
2108 data.WriteByteSeq(guid[1]);
2109 data.WriteByteSeq(guid[0]);
2110 data.WriteByteSeq(guid[2]);
2111 data.WriteByteSeq(guid[6]);
2112
2113 if (Player* owner = GetOwner())
2114 owner->GetSession()->SendPacket(&data);
2115}
2116
2118{
2119 return Minion::GetOwner()->ToPlayer();
2120}
2121
2123{
2124 Guardian::SetDisplayId(modelId);
2125
2126 if (!isControlled())
2127 return;
2128
2129 if (Unit* owner = GetOwner())
2130 if (Player* player = owner->ToPlayer())
2131 if (player->GetGroup())
2132 player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
2133}
2134
2136{
2138 return true;
2139
2140 return false;
2141}
2142
2144{
2145 uint16 specId = 0;
2146 for (uint32 j = 0; j < sChrSpecializationStore.GetNumRows(); j++)
2147 {
2148 ChrSpecializationEntry const* specializationInfo = sChrSpecializationStore.LookupEntry(j);
2149 if (!specializationInfo || specializationInfo->classId != 0)
2150 continue;
2151
2152 if (specializationInfo->PetTabPage != talenttab)
2153 continue;
2154
2155 if (specializationInfo->Id == m_petSpec)
2156 continue;
2157
2158 specId = specializationInfo->Id;
2159 }
2160 return specId;
2161}
2162
2164{
2165 if (std::vector<uint32> const* spells = GetSpecializationSpells(m_petSpec))
2166 {
2167 for (std::vector<uint32>::const_iterator iter = spells->begin(); iter != spells->end(); ++iter)
2168 {
2169 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(*iter);
2170 if (!spellInfo)
2171 continue;
2172
2173 if (HasSpell(*iter))
2174 removeSpell(*iter, false, true);
2175 }
2176 }
2177}
2179{
2180 if (std::vector<uint32> const* spells = GetSpecializationSpells(m_petSpec))
2181 {
2182 for (std::vector<uint32>::const_iterator iter = spells->begin(); iter != spells->end(); ++iter)
2183 {
2184 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(*iter);
2185 if (!spellInfo || spellInfo->SpellLevel > getLevel())
2186 continue;
2187
2188 if (!HasSpell(*iter))
2189 learnSpell(*iter);
2190 }
2191 }
2192}
2193
2195{
2196 if (m_petSpec == spec)
2197 return;
2198
2199 // remove all the old spec's specalization spells, set the new spec, then add the new spec's spells
2200 // clearActionBars is false because we'll be updating the pet actionbar later so we don't have to do it now.
2201
2202 // remove spec spells
2204
2205
2206 if (!sChrSpecializationStore.LookupEntry(spec))
2207 {
2208 m_petSpec = 0;
2209 return;
2210 }
2211
2212 m_petSpec = spec;
2213
2214
2215 // learn spec spells
2217
2218 // resend SMSG_PET_SPELLS_MESSAGE to remove old specialization spells from the pet action bar
2221
2222 if (Player* owner = GetOwner())
2223 {
2225 data << uint16(m_petSpec);
2226 owner->GetSession()->SendPacket(&data);
2227 }
2228}
@ CHAR_SEL_PET_AURA
@ CHAR_UPD_CHAR_PET_ACTIVE_BY_ID
@ CHAR_SEL_CHAR_ACTIVE_PET
@ CHAR_DEL_CHAR_PET_BY_SLOT
@ CHAR_UDP_CHAR_PET_SLOT_BY_SLOT
@ CHAR_DEL_INVALID_PET_SPELL
@ CHAR_SEL_CHAR_PET_BY_SLOT
@ CHAR_INS_PET_SPELL_COOLDOWN
@ CHAR_UPD_CHAR_PET_SLOT_BY_ID
@ CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID
@ CHAR_SEL_CHAR_PET_BY_ENTRY
@ CHAR_DEL_PET_SPELLS
@ CHAR_INS_PET_SPELL
@ CHAR_DEL_CHAR_PET_BY_ID
@ CHAR_UPD_CHAR_PET_ACTIVE_BY_OWNER
@ CHAR_DEL_PET_AURAS
@ CHAR_SEL_PET_DECLINED_NAME
@ CHAR_SEL_CHAR_PET
@ CHAR_DEL_PET_SPELL_BY_SPELL
@ CHAR_DEL_PET_SPELL_COOLDOWNS
@ CHAR_SEL_PET_SPELL
@ CHAR_SEL_PET_SPELL_COOLDOWN
@ CHAR_SEL_PET_SPELL_LIST
@ CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2
@ CHAR_INS_PET_AURA
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
@ IN_MILLISECONDS
Definition Common.h:125
#define CREATURE_REGEN_INTERVAL
Definition Creature.h:55
uint32 GetTalentSpellCost(uint32 spellId)
std::vector< uint32 > const * GetSpecializationSpells(uint32 specializationId)
DBCStorage< CreatureFamilyEntry > sCreatureFamilyStore(CreatureFamilyfmt)
DBCStorage< ChrSpecializationEntry > sChrSpecializationStore(ChrSpecializationfmt)
PetFamilySpellsStore sPetFamilySpellsStore
#define MAX_CREATURE_SPELL_DATA_SLOT
#define MAX_SPELL_EFFECTS
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 ASSERT
Definition Errors.h:29
@ GROUP_UPDATE_FLAG_PET_MODEL_ID
Definition Group.h:90
@ GROUP_UPDATE_PET
Definition Group.h:101
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
@ TYPEID_PLAYER
Definition Object.h:55
#define sObjectAccessor
uint32 GUID_LOPART(uint64 x)
@ HIGHGUID_PET
bool IS_PLAYER_GUID(uint64 guid)
#define sObjectMgr
Definition ObjectMgr.h:1617
#define PET_XP_FACTOR
Definition Pet.cpp:25
#define PET_FOCUS_REGEN_INTERVAL
Definition Pet.h:12
PetSaveMode
Definition PetDefines.h:20
@ PET_SAVE_LAST_STABLE_SLOT
Definition PetDefines.h:24
@ PET_SAVE_AS_DELETED
Definition PetDefines.h:21
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:25
@ PET_SAVE_AS_CURRENT
Definition PetDefines.h:22
PetSpellState
Definition PetDefines.h:29
@ PETSPELL_NEW
Definition PetDefines.h:32
@ PETSPELL_UNCHANGED
Definition PetDefines.h:30
@ PETSPELL_CHANGED
Definition PetDefines.h:31
@ PETSPELL_REMOVED
Definition PetDefines.h:33
#define PET_FOLLOW_DIST
Definition PetDefines.h:57
PetType
Definition PetDefines.h:10
@ SUMMON_PET
Definition PetDefines.h:11
@ MAX_PET_TYPE
Definition PetDefines.h:13
@ HUNTER_PET
Definition PetDefines.h:12
PetSpellType
Definition PetDefines.h:37
@ PETSPELL_FAMILY
Definition PetDefines.h:39
@ AT_LOGIN_RESET_PET_TALENTS
Definition Player.h:621
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
#define MAX_STATS
Powers
@ POWER_ENERGY
@ POWER_MANA
@ POWER_FOCUS
SpellSchools
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
@ SPELL_PREVENTION_TYPE_SILENCE
@ GENDER_NONE
@ CREATURE_TYPE_CRITTER
@ CREATURE_TYPE_UNDEAD
@ CREATURE_TYPE_DEMON
@ CREATURE_TYPE_ELEMENTAL
@ CREATURE_TYPE_BEAST
@ UNIT_DYNFLAG_NONE
@ CLASS_HUNTER
@ CLASS_SHAMAN
@ CLASS_WARRIOR
@ CLASS_WARLOCK
@ CLASS_MAGE
@ CLASS_DEATH_KNIGHT
AuraStateType
#define CURRENT_CONTENT_EXP
Stats
@ STAT_SPIRIT
@ STAT_INTELLECT
@ STAT_AGILITY
@ STAT_STRENGTH
@ STAT_STAMINA
#define MAX_SPELL_SCHOOL
SpellSchoolMask
@ SPELL_SCHOOL_MASK_SHADOW
@ SPELL_SCHOOL_MASK_NATURE
@ SPELL_SCHOOL_MASK_FIRE
@ SPELL_SCHOOL_MASK_FROST
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_MOD_PET_TALENT_POINTS
@ SPELL_AURA_MOD_POWER_REGEN_PERCENT
#define sSpellMgr
Definition SpellMgr.h:744
std::multimap< uint32, uint32 > PetLevelupSpellSet
Definition SpellMgr.h:546
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
@ UNIT_NPC_FLAG_NONE
Definition Unit.h:686
@ UNIT_CAN_BE_RENAMED
Definition Unit.h:268
@ UNIT_CAN_BE_ABANDONED
Definition Unit.h:269
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition Unit.h:813
@ UNIT_MASK_HUNTER_PET
Definition Unit.h:812
@ UNIT_MASK_PET
Definition Unit.h:809
#define MAX_UNIT_ACTION_BAR_INDEX
Definition Unit.h:1233
UnitMods
Definition Unit.h:439
@ UNIT_MOD_ARMOR
Definition Unit.h:463
@ UNIT_MOD_RESISTANCE_START
Definition Unit.h:479
@ UNIT_MOD_STAT_STAMINA
Definition Unit.h:442
@ ACTION_BAR_INDEX_END
Definition Unit.h:1230
@ ACTION_BAR_INDEX_START
Definition Unit.h:1227
DeathState
Definition Unit.h:502
@ ALIVE
Definition Unit.h:503
@ JUST_DIED
Definition Unit.h:504
@ CORPSE
Definition Unit.h:505
#define BASE_ATTACK_TIME
Definition Unit.h:157
@ COMMAND_FOLLOW
Definition Unit.h:1165
#define MAX_DECLINED_NAME_CASES
Definition Unit.h:1098
@ BASE_VALUE
Definition Unit.h:384
@ SHEATH_STATE_MELEE
Definition Unit.h:246
ActiveStates
Definition Unit.h:1144
@ ACT_DECIDE
Definition Unit.h:1151
@ ACT_ENABLED
Definition Unit.h:1148
@ ACT_PASSIVE
Definition Unit.h:1145
@ ACT_DISABLED
Definition Unit.h:1147
ReactStates
Definition Unit.h:1155
@ UNIT_FLAG_PVP_ATTACKABLE
Definition Unit.h:628
@ UNIT_FLAG_SKINNABLE
Definition Unit.h:651
@ UNIT_FLAG2_REGENERATE_POWER
Definition Unit.h:673
@ UNIT_FIELD_MOD_CASTING_SPEED
@ UNIT_FIELD_FLAGS2
@ UNIT_FIELD_PET_EXPERIENCE
@ UNIT_FIELD_SHAPESHIFT_FORM
@ UNIT_FIELD_MOD_SPELL_HASTE
@ UNIT_FIELD_PET_NAME_TIMESTAMP
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_PET_NEXT_LEVEL_EXPERIENCE
@ UNIT_FIELD_CREATED_BY_SPELL
@ OBJECT_FIELD_DYNAMIC_FLAGS
EPlayerFields
@ PLAYER_FIELD_MOD_DAMAGE_DONE_POS
T AddPct(T &base, U pct)
Definition Util.h:109
T CalculatePct(T base, U pct)
Definition Util.h:103
bool CanBeRecalculated() const
int32 GetBaseAmount() const
int32 GetAmount() const
static Aura * TryCreate(SpellInfo const *spellproto, uint32 effMask, WorldObject *owner, Unit *caster, int32 *baseAmount=NULL, Item *castItem=NULL, uint64 casterGUID=0)
uint32 GetId() const
Definition SpellAuras.h:88
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:168
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
size_t bitwpos() const
Returns position of last written bit.
Definition ByteBuffer.h:492
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
uint32 m_DBTableGuid
For new or temporary creatures is 0 for saved it is lowguid.
Definition Creature.h:695
void SetDisplayId(uint32 modelId) OVERRIDE
void SetReactState(ReactStates st)
Definition Creature.h:460
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition Creature.h:566
void Update(uint32 time) OVERRIDE
Definition Creature.cpp:446
CreatureSpellCooldowns m_CreatureCategoryCooldowns
Definition Creature.h:567
time_t m_corpseRemoveTime
Timers.
Definition Creature.h:684
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:524
void SetObjectScale(float scale) OVERRIDE
uint32 m_originalEntry
Definition Creature.h:705
bool AIM_Initialize(CreatureAI *ai=NULL)
Definition Creature.cpp:702
ReactStates GetReactState() const
Definition Creature.h:461
void SetMeleeDamageSchool(SpellSchools school)
Definition Creature.h:486
void setDeathState(DeathState s) OVERRIDE
void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time)
void Regenerate(Powers power)
Definition Pet.cpp:658
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const OVERRIDE
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData *data=NULL)
Definition Creature.cpp:257
uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const
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
bool GetBool() const
Definition Field.h:21
uint32 GetUInt32() const
Definition Field.h:105
int32 GetInt32() const
Definition Field.h:123
bool UpdateAllStats() OVERRIDE
Guardian(SummonPropertiesEntry const *properties, Unit *owner, bool isWorldObject)
void SetBonusDamage(int32 damage)
bool InitStatsForLevel(uint8 level)
Definition Pet.cpp:828
Definition Map.h:238
bool AddToMap(T *)
Definition Map.cpp:504
Unit * GetOwner() const
Unit *const m_owner
float GetFollowAngle() const OVERRIDE
bool IsPetGhoul() const
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
Definition Object.cpp:129
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
void SetFloatValue(uint16 index, float value)
Definition Object.cpp:1141
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition Object.cpp:1376
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1322
int32 GetDamage() const
Definition SpellMgr.h:464
uint32 GetAura(uint32 petEntry) const
Definition SpellMgr.h:443
bool IsRemovedOnChangePet() const
Definition SpellMgr.h:459
void _SaveAuras(SQLTransaction &trans)
Definition Pet.cpp:1353
void LearnPetPassives()
Definition Pet.cpp:1949
PetType m_petType
Definition Pet.h:149
void RemoveFromWorld()
Definition Pet.cpp:75
void _LoadSpells()
Definition Pet.cpp:1214
void GivePetLevel(uint8 level)
Definition Pet.cpp:739
bool m_loading
Definition Pet.h:152
void _SaveSpellCooldowns(SQLTransaction &trans)
Definition Pet.cpp:1188
Player * GetOwner() const
Definition Pet.cpp:2117
uint32 m_transportExitGraceTimer
Definition Pet.h:154
bool IsPetAura(Aura const *aura)
Definition Pet.cpp:2006
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab=true)
Definition Pet.cpp:1586
void UnlearnSpecializationSpells()
Definition Pet.cpp:2163
void AddToWorld()
Definition Pet.cpp:52
DeclinedName * m_declinedname
Definition Pet.h:156
void _LoadAuras(uint32 timediff)
Definition Pet.cpp:1280
uint32 m_usedTalentCount
Definition Pet.h:136
void Update(uint32 diff)
Definition Pet.cpp:541
void ToggleAutocast(SpellInfo const *spellInfo, bool apply)
Definition Pet.cpp:1852
virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
Definition Pet.cpp:2054
void setDeathState(DeathState s)
Definition Pet.cpp:521
void _LoadSpellCooldowns()
Definition Pet.cpp:1118
void StartTransportExitGrace(uint32 duration)
Definition Pet.cpp:86
void InitTalentForLevel()
Definition Pet.cpp:1828
void CastPetAuras(bool current)
Definition Pet.cpp:1970
void setPetType(PetType type)
Definition Pet.h:39
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:365
void SetDisplayId(uint32 modelId)
Definition Pet.cpp:2122
PetType getPetType() const
Definition Pet.h:38
void SynchronizeLevelWithOwner()
Definition Pet.cpp:2030
uint32 m_regenTimer
Definition Pet.h:153
void learnSpellHighRank(uint32 spellid)
Definition Pet.cpp:2022
bool IsPermanentPetFor(Player *owner) const
Definition Pet.cpp:1899
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1084
bool addSpell(uint32 spellId, ActiveStates active=ACT_DECIDE, PetSpellState state=PETSPELL_NEW, PetSpellType type=PETSPELL_NORMAL)
Definition Pet.cpp:1414
AutoSpellList m_autospells
Definition Pet.h:124
uint16 GetPetSpecByTalentTab(uint16 talenttab)
Definition Pet.cpp:2143
bool CreateBaseAtTamed(CreatureTemplate const *cinfo, Map *map)
Definition Pet.cpp:801
bool Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)
Definition Pet.cpp:1922
bool CreateBaseAtCreatureInfo(CreatureTemplate const *cinfo, Unit *owner)
Definition Pet.cpp:788
bool LoadPetFromDB(Player *owner, uint32 petentry=0, uint32 petnumber=0, bool current=false)
Definition Pet.cpp:91
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab=true)
Definition Pet.cpp:1601
void SetSpec(uint16 spec)
Definition Pet.cpp:2194
bool CreateBaseAtCreature(Creature *creature)
Definition Pet.cpp:755
void CleanupActionBar()
Definition Pet.cpp:1652
bool isTemporarySummoned() const
Definition Pet.h:41
void CastPetAura(PetAura const *aura)
Definition Pet.cpp:1991
bool isControlled() const
Definition Pet.cpp:2135
virtual ~Pet()
Definition Pet.cpp:47
bool HasTransportExitGrace() const
Definition Pet.h:59
void _SaveSpells(SQLTransaction &trans)
Definition Pet.cpp:1231
bool m_removed
Definition Pet.h:144
bool HasSpell(uint32 spell) const
Definition Pet.cpp:1942
void SetFreeTalentPoints(uint8 points)
Definition Pet.h:134
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:697
uint8 GetMaxTalentPointsForLevel(uint8 level)
Definition Pet.cpp:1843
void InitPetCreateSpells()
Definition Pet.cpp:1668
void LearnSpecializationSpells()
Definition Pet.cpp:2178
uint64 m_auraRaidUpdateMask
Definition Pet.h:151
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1102
static void resetTalentsForAllPetsOf(Player *owner, Pet *online_pet=NULL)
Definition Pet.cpp:1752
bool resetTalents()
Definition Pet.cpp:1679
PetSpellMap m_spells
Definition Pet.h:123
uint16 m_petSpec
Definition Pet.h:106
Pet(Player *owner, PetType type=PetType::MAX_PET_TYPE)
Definition Pet.cpp:27
void GivePetXP(uint32 xp)
Definition Pet.cpp:702
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1528
int32 m_duration
Definition Pet.h:150
void InitLevelupSpellsForLevel()
Definition Pet.cpp:1544
void DeleteFromDB()
Definition Pet.h:163
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist=false)
Definition Player.cpp:21581
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2993
uint32 GetTemporaryUnsummonedPetNumber() const
Definition Player.h:2893
bool CanTameExoticPets() const
Definition Player.h:2624
void SetTemporaryUnsummonedPetNumber(uint32 petnumber)
Definition Player.h:2897
bool IsPetNeedBeTemporaryUnsummoned() const
Definition Player.cpp:21147
void PetSpellInitialize()
Definition Player.cpp:15884
WorldSession * GetSession() const
Definition Player.h:2417
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:15663
Group * GetGroup()
Definition Player.h:2972
bool HasAtLoginFlag(AtLoginFlags f) const
Definition Player.h:2876
void SetLastPetNumber(uint32 petnumber)
Definition Player.h:2955
void setUInt64(const uint8 index, const uint64 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void setInt32(const uint8 index, const int32 value)
uint32 SpellLevel
Definition SpellInfo.h:206
uint32 PreventionType
Definition SpellInfo.h:229
bool IsAutocastable() const
bool IsCooldownStartedOnEvent() const
bool IsPassive() const
uint32 Id
Definition SpellInfo.h:160
uint32 ProcCharges
Definition SpellInfo.h:203
bool IsRanked() const
bool IsHighRankOf(SpellInfo const *spellInfo) const
uint32 CasterAuraState
Definition SpellInfo.h:185
SpellSchoolMask GetSchoolMask() const
int32 GetDuration() const
bool IsDifferentRankOf(SpellInfo const *spellInfo) const
bool IsPositive() const
Definition Unit.h:1367
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:2432
bool IsHunterPet() const
Definition Unit.h:1515
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:2243
void SetCreateStat(Stats stat, float val)
Definition Unit.h:2313
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=NULL, Unit const *Caster=NULL) const
void setFaction(uint32 faction)
Definition Unit.h:1699
void RemovePetAura(PetAura const *petSpell)
Definition Unit.cpp:6245
uint32 getFaction() const
Definition Unit.h:1695
void SetFullHealth()
Definition Unit.h:1644
void AddToWorld() override
Definition Unit.cpp:5400
bool SetPhased(uint32 id, bool update, bool apply) OVERRIDE
Definition Unit.cpp:7516
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void SetCreateHealth(uint32 val)
Definition Unit.h:2317
void SetPower(Powers power, int32 val)
Definition Unit.cpp:5255
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value)
Definition Unit.h:2428
void SetCreatorGUID(uint64 creator)
Definition Unit.h:2059
CharmInfo * m_charmInfo
Definition Unit.h:2918
uint64 GetPetGUID() const
Definition Unit.h:2087
bool IsPet() const
Definition Unit.h:1511
uint32 GetMaxHealth() const
Definition Unit.h:1604
Aura * AddAura(uint32 spellId, Unit *target)
uint8 getClass() const
Definition Unit.h:1543
bool IsAlive() const
Definition Unit.h:2032
DeathState m_deathState
Definition Unit.h:2883
void SetClass(uint8 newClass)
Definition Unit.h:1564
int32 GetMaxPower(Powers power) const
Definition Unit.cpp:5246
uint32 m_unitTypeMask
Definition Unit.h:2935
void SetHealth(uint32 val)
Definition Unit.cpp:5162
CharmInfo * GetCharmInfo()
Definition Unit.h:2148
int32 ModifyPower(Powers power, int32 val)
Definition Unit.cpp:4081
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
void SetCreateMana(uint32 val)
Definition Unit.h:2325
virtual void SetSheath(SheathState sheathed)
Definition Unit.h:1689
uint32 GetDisplayId() const
Definition Unit.h:2490
uint32 GetNativeDisplayId() const
Definition Unit.h:2495
bool isPossessed() const
Definition Unit.h:2140
uint32 GetHealth() const
Definition Unit.h:1600
void SetGender(uint8 gender)
Definition Unit.h:1568
void SetNativeDisplayId(uint32 modelId)
Definition Unit.h:2500
uint32 GetArmor() const
Definition Unit.h:1581
int32 GetPower(Powers power) const
Definition Unit.cpp:5237
DeathState getDeathState() const
Definition Unit.h:2044
void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value)
Definition Unit.h:2400
void CastCustomSpell(Unit *victim, uint32 spellId, int32 const *bp0, int32 const *bp1, int32 const *bp2, bool triggered, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
AuraMap m_ownedAuras
Definition Unit.h:2899
void SetCanModifyStats(bool modifyStats)
Definition Unit.h:2414
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
CharmInfo * InitCharmInfo()
Definition Unit.cpp:5518
void RemoveFromWorld() override
Definition Unit.cpp:5409
float GetStat(Stats stat) const
Definition Unit.h:1573
uint64 GetOwnerGUID() const
Definition Unit.h:2050
void RemoveAllAuras()
PetAuraSet m_petAuras
Definition Unit.h:2708
Powers getPowerType() const
Definition Unit.h:1651
uint8 getLevel() const
Definition Unit.h:1528
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
void SetAttackTime(WeaponAttackType att, uint32 val)
Definition Unit.h:1678
void SetLevel(uint8 lvl)
Definition Unit.cpp:5150
void setPowerType(Powers power)
Definition Unit.cpp:2079
void SetFieldPowerType(uint32 powerType)
Definition Unit.h:1655
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:3055
float GetTotalAttackPowerValue(WeaponAttackType attType) const
Definition Unit.cpp:5118
Map * GetMap() const
Definition Object.h:740
std::string m_name
Definition Object.h:815
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1735
std::set< uint32 > const & GetPhases() const
Definition Object.h:647
void SetName(std::string const &newname)
Definition Object.h:665
std::string const & GetName() const
Definition Object.h:664
virtual void SetMap(Map *map)
Definition Object.cpp:2514
Transport * GetTransport() const
Definition Object.h:797
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0) const
Definition Object.cpp:3070
float GetVisibilityRange() const
Definition Object.cpp:2070
float GetObjectSize() const
Definition Object.cpp:3100
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition Main.cpp:41
@ SMSG_PET_REMOVED_SPELL
Definition Opcodes.h:871
@ SMSG_SPELL_COOLDOWN
Definition Opcodes.h:979
@ SMSG_SET_PET_SPEC
Definition Opcodes.h:959
@ SMSG_PET_LEARNED_SPELL
Definition Opcodes.h:868
#define sWorld
Definition World.h:910
@ CONFIG_MAX_PLAYER_LEVEL
Definition World.h:224
@ RATE_POWER_FOCUS
Definition World.h:383
bool BoardOwnerHunterPet(Player *owner, Transport *transport)
bool AttachHunterPetToOwnerTransport(Player *owner, Pet *pet, Transport *transport)
bool ShouldRemovePetForOwnerRange(bool petExists, bool petPossessed, bool petOnOwnerTransport, bool isWithinVisibilityRange, bool transportExitGraceActive)
bool ShouldReattachPetDuringOwnerTransportUpdate(bool ownerHasTransport, bool petIsHunterPet, bool petIsControlled, bool petIsAlive, bool ownerMatches, bool petOnOwnerTransport)
void SetIsCommandFollow(bool val)
Definition Unit.cpp:9072
uint32 GetPetNumber() const
Definition Unit.h:1241
void SetIsAtStay(bool val)
Definition Unit.cpp:9093
void SetIsFollowing(bool val)
Definition Unit.cpp:9098
void SetIsReturning(bool val)
Definition Unit.cpp:9103
void SetIsCommandAttack(bool val)
Definition Unit.cpp:9067
uint32 Id
uint32 classId
uint32 PetTabPage
uint32 BaseHealth[MAX_CREATURE_BASE_HP]
Definition Creature.h:199
float maxScale
float minScale
uint32 minScaleLevel
uint32 petFoodMask
uint32 ID
uint32 maxScaleLevel
int32 resistance[MAX_SPELL_SCHOOL]
Definition Creature.h:110
uint32 dmgschool
Definition Creature.h:88
uint32 expansion
Definition Creature.h:77
uint32 unit_class
Definition Creature.h:93
uint32 baseattacktime
Definition Creature.h:91
bool IsTameable(bool canTameExotic) const
Definition Creature.h:153
uint32 PetSpellDataId
Definition Creature.h:112
Definition SpellMgr.h:552
uint16 health
Definition ObjectMgr.h:465
uint16 armor
Definition ObjectMgr.h:467
uint16 stats[MAX_STATS]
Definition ObjectMgr.h:464
uint16 mana
Definition ObjectMgr.h:466
Definition Pet.h:16
PetSpellState state
Definition Pet.h:18
PetSpellType type
Definition Pet.h:19
ActiveStates active
Definition Pet.h:17
float GetPositionZ() const
Definition Object.h:330
float GetOrientation() const
Definition Object.h:331
bool IsPositionValid() const
Definition Object.cpp:2049
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void Relocate(float x, float y)
Definition Object.h:302
Definition Unit.h:1176