TrinityCore
Creature.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 "Creature.h"
19#include "BattlegroundMgr.h"
20#include "CellImpl.h"
21#include "CharmInfo.h"
22#include "CombatPackets.h"
23#include "Containers.h"
24#include "CreatureAI.h"
25#include "CreatureAISelector.h"
26#include "CreatureGroups.h"
27#include "DatabaseEnv.h"
28#include "DB2Stores.h"
29#include "Formulas.h"
30#include "GameEventMgr.h"
31#include "GameTime.h"
32#include "GridNotifiersImpl.h"
33#include "Group.h"
34#include "ItemTemplate.h"
35#include "Log.h"
36#include "Loot.h"
37#include "LootMgr.h"
38#include "MapManager.h"
39#include "MiscPackets.h"
40#include "MotionMaster.h"
41#include "ObjectAccessor.h"
42#include "ObjectMgr.h"
43#include "PhasingHandler.h"
44#include "Player.h"
45#include "PoolMgr.h"
46#include "QueryPackets.h"
47#include "ScriptedGossip.h"
48#include "Spell.h"
49#include "SpellAuraEffects.h"
50#include "SpellMgr.h"
51#include "TemporarySummon.h"
52#include "Vehicle.h"
53#include "World.h"
54#include "ZoneScript.h"
55#include <G3D/g3dmath.h>
56#include <sstream>
57
59Random(CreatureRandomMovementType::Walk), InteractionPauseTimer(sWorld->getIntConfig(CONFIG_CREATURE_STOP_FOR_PLAYER)) { }
60
62{
63 char const* const ChaseStates[] = { "Run", "CanWalk", "AlwaysWalk" };
64 char const* const RandomStates[] = { "Walk", "CanRun", "AlwaysRun" };
65
66 std::ostringstream str;
67 str << std::boolalpha
68 << ", HoverInitiallyEnabled: " << HoverInitiallyEnabled
69 << ", Chase: " << ChaseStates[AsUnderlyingType(Chase)]
70 << ", Random: " << RandomStates[AsUnderlyingType(Random)];
71 str << ", InteractionPauseTimer: " << InteractionPauseTimer;
72
73 return str.str();
74}
75
77 : itemId(_item), count(_count), lastIncrementTime(GameTime::GetGameTime()) { }
78
80{
81 auto newEnd = std::remove_if(m_items.begin(), m_items.end(), [=](VendorItem const& vendorItem)
82 {
83 return vendorItem.item == item_id && vendorItem.Type == type;
84 });
85
86 bool found = newEnd != m_items.end();
87 m_items.erase(newEnd, m_items.end());
88 return found;
89}
90
91VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const
92{
93 for (VendorItem const& vendorItem : m_items)
94 if (vendorItem.item == item_id && vendorItem.ExtendedCost == extendedCost && vendorItem.Type == type)
95 return &vendorItem;
96 return nullptr;
97}
98
101
103{
104 return idx < Models.size() ? &Models[idx] : nullptr;
105}
106
108{
109 if (!Models.size())
110 return nullptr;
111
112 // If only one element, ignore the Probability (even if 0)
113 if (Models.size() == 1)
114 return &Models[0];
115
117 {
118 return model.Probability;
119 });
120
121 return &(*selectedItr);
122}
123
125{
126 for (CreatureModel const& model : Models)
127 if (model.CreatureDisplayID)
128 return &model;
129
130 return nullptr;
131}
132
134{
135 for (CreatureModel const& model : Models)
136 if (displayId == model.CreatureDisplayID)
137 return &model;
138
139 return nullptr;
140}
141
143{
144 for (CreatureModel const& model : Models)
145 if (CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(model.CreatureDisplayID))
146 if (modelInfo && modelInfo->is_trigger)
147 return &model;
148
150}
151
153{
154 for (CreatureModel const& model : Models)
155 if (CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(model.CreatureDisplayID))
156 if (modelInfo && !modelInfo->is_trigger)
157 return &model;
158
160}
161
163{
164 for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc)
165 QueryData[loc] = BuildQueryData(static_cast<LocaleConstant>(loc), DIFFICULTY_NONE);
166}
167
169{
170 CreatureDifficulty const* creatureDifficulty = GetDifficulty(difficulty);
171
173
174 queryTemp.CreatureID = Entry;
175
176 queryTemp.Allow = true;
177
178 WorldPackets::Query::CreatureStats& stats = queryTemp.Stats;
179
180 stats.Leader = RacialLeader;
181
182 stats.Name[0] = Name;
183 stats.NameAlt[0] = FemaleName;
184
185 stats.Flags[0] = creatureDifficulty->TypeFlags;
186 stats.Flags[1] = creatureDifficulty->TypeFlags2;
187
188 stats.CreatureType = type;
189 stats.CreatureFamily = family;
191
192 for (uint32 i = 0; i < MAX_KILL_CREDIT; ++i)
193 stats.ProxyCreatureID[i] = KillCredit[i];
194
195 std::transform(Models.begin(), Models.end(), std::back_inserter(stats.Display.CreatureDisplay),
197 {
198 stats.Display.TotalProbability += model.Probability;
199 return { model.CreatureDisplayID, model.DisplayScale, model.Probability };
200 });
201
202 stats.HpMulti = creatureDifficulty->HealthModifier;
203 stats.EnergyMulti = creatureDifficulty->ManaModifier;
204
205 stats.CreatureMovementInfoID = movementId;
206 stats.RequiredExpansion = RequiredExpansion;
207 stats.HealthScalingExpansion = creatureDifficulty->HealthScalingExpansion;
208 stats.VignetteID = VignetteID;
209 stats.Class = unit_class;
210 stats.CreatureDifficultyID = creatureDifficulty->CreatureDifficultyID;
211 stats.WidgetSetID = WidgetSetID;
212 stats.WidgetSetUnitConditionID = WidgetSetUnitConditionID;
213
214 stats.Title = SubName;
215 stats.TitleAlt = TitleAlt;
216 stats.CursorName = IconName;
217
218 if (std::vector<uint32> const* items = sObjectMgr->GetCreatureQuestItemList(Entry, difficulty))
219 stats.QuestItems.assign(items->begin(), items->end());
220
221 if (std::vector<int32> const* currencies = sObjectMgr->GetCreatureQuestCurrencyList(Entry))
222 stats.QuestCurrencies.assign(currencies->begin(), currencies->end());
223
224 if (loc != LOCALE_enUS)
225 if (CreatureLocale const* creatureLocale = sObjectMgr->GetCreatureLocale(Entry))
226 {
227 ObjectMgr::GetLocaleString(creatureLocale->Name, loc, stats.Name[0]);
228 ObjectMgr::GetLocaleString(creatureLocale->NameAlt, loc, stats.NameAlt[0]);
229 ObjectMgr::GetLocaleString(creatureLocale->Title, loc, stats.Title);
230 ObjectMgr::GetLocaleString(creatureLocale->TitleAlt, loc, stats.TitleAlt);
231 }
232
233 queryTemp.Write();
234 queryTemp.ShrinkToFit();
235 return queryTemp.Move();
236}
237
239{
240 auto it = difficultyStore.find(difficulty);
241 if (it != difficultyStore.end())
242 return &it->second;
243
244 // If there is no data for the difficulty, try to get data for the fallback difficulty
245 DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(difficulty);
246 if (difficultyEntry)
247 return GetDifficulty(Difficulty(difficultyEntry->FallbackDifficultyID));
248
249 // No data for DIFFICULTY_NONE (0)
250 struct DefaultCreatureDifficulty : public CreatureDifficulty
251 {
252 DefaultCreatureDifficulty()
253 {
254 DeltaLevelMin = 0;
255 DeltaLevelMax = 0;
256 ContentTuningID = 0;
257 HealthScalingExpansion = 0;
258 HealthModifier = 1.f;
259 ManaModifier = 1.f;
260 ArmorModifier = 1.f;
261 DamageModifier = 1.f;
262 CreatureDifficultyID = 0;
263 TypeFlags = 0;
264 TypeFlags2 = 0;
265 LootID = 0;
266 PickPocketLootID = 0;
267 SkinLootID = 0;
268 GoldMin = 0;
269 GoldMax = 0;
270 }
271 };
272 static const DefaultCreatureDifficulty defDifficulty;
273 return &defDifficulty;
274}
275
276bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
277{
279 {
280 while (!m_assistants.empty())
281 {
283 m_assistants.pop_front();
284
285 if (assistant && assistant->CanAssistTo(&m_owner, victim))
286 {
287 assistant->SetNoCallAssistance(true);
288 assistant->EngageWithTarget(victim);
289 }
290 }
291 }
292 return true;
293}
294
296{
297 return sObjectMgr->GetCreatureBaseStats(level, unitClass);
298}
299
301{
302 m_owner.DespawnOrUnsummon(0s, m_respawnTimer); // since we are here, we are not TempSummon as object type cannot change during runtime
303 return true;
304}
305
306Creature::Creature(bool isWorldObject) : Unit(isWorldObject), MapObject(), m_PlayerDamageReq(0), m_dontClearTapListOnEvade(false), _pickpocketLootRestore(0),
307 m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_ignoreCorpseDecayRatio(false), m_wanderDistance(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
308 m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_cannotReachTarget(false), m_cannotReachTimer(0),
309 m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_creatureDifficulty(nullptr), _waypointPathId(0), _currentWaypointNodeInfo(0, 0),
310 m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false), _lastDamagedTime(0),
311 _regenerateHealth(true), _creatureImmunitiesId(0), _gossipMenuId(0), _sparringHealthPct(0)
312{
314
315 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
316 m_spells[i] = 0;
317
318 DisableReputationGain = false;
319
321 m_CombatDistance = 0;//MELEE_RANGE;
322
323 ResetLootMode(); // restore default loot mode
324 m_isTempWorldObject = false;
325}
326
327Creature::~Creature() = default;
328
330{
332 if (!IsInWorld())
333 {
335 if (m_spawnId)
336 GetMap()->GetCreatureBySpawnIdStore().insert(std::make_pair(m_spawnId, this));
337
341 if (IsVehicle())
343
344 if (GetZoneScript())
346 }
347}
348
350{
351 if (IsInWorld())
352 {
353 if (GetZoneScript())
355
356 if (m_formation)
357 sFormationMgr->RemoveCreatureFromGroup(m_formation, this);
358
360
361 if (m_spawnId)
362 Trinity::Containers::MultimapErasePair(GetMap()->GetCreatureBySpawnIdStore(), m_spawnId, this);
364 }
365}
366
368{
369 if (GetMotionMaster()->GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE)
370 return true;
371
372 return false;
373}
374
376{
377 if (IsSummon())
378 return;
379
381 if (!lowguid)
382 return;
383
384 if (FormationInfo const* formationInfo = sFormationMgr->GetFormationInfo(lowguid))
385 sFormationMgr->AddCreatureToGroup(formationInfo->LeaderSpawnId, this);
386}
387
389{
390 if (!m_formation)
391 return false;
392
393 return m_formation->IsLeader(this);
394}
395
397{
398 if (!m_formation)
399 return;
400
401 if (!m_formation->IsLeader(this))
402 return;
403
405}
406
408{
409 if (!m_formation)
410 return false;
411
413}
414
415void Creature::RemoveCorpse(bool setSpawnTime, bool destroyForNearbyPlayers)
416{
417 if (getDeathState() != CORPSE)
418 return;
419
421 {
425 m_loot = nullptr;
426 uint32 respawnDelay = m_respawnDelay;
427 if (CreatureAI* ai = AI())
428 ai->CorpseRemoved(respawnDelay);
429
430 if (destroyForNearbyPlayers)
432
433 // Should get removed later, just keep "compatibility" with scripts
434 if (setSpawnTime)
435 m_respawnTime = std::max<time_t>(GameTime::GetGameTime() + respawnDelay, m_respawnTime);
436
437 // if corpse was removed during falling, the falling will continue and override relocation to respawn position
438 if (IsFalling())
439 StopMoving();
440
441 float x, y, z, o;
442 GetRespawnPosition(x, y, z, &o);
443
444 // We were spawned on transport, calculate real position
446 {
448 pos.m_positionX = x;
449 pos.m_positionY = y;
450 pos.m_positionZ = z;
451 pos.SetOrientation(o);
452
453 if (TransportBase* transport = GetDirectTransport())
454 transport->CalculatePassengerPosition(x, y, z, &o);
455 }
456
457 UpdateAllowedPositionZ(x, y, z);
458 SetHomePosition(x, y, z, o);
459 GetMap()->CreatureRelocation(this, x, y, z, o);
460 }
461 else
462 {
463 if (CreatureAI* ai = AI())
464 ai->CorpseRemoved(m_respawnDelay);
465
466 // In case this is called directly and normal respawn timer not set
467 // Since this timer will be longer than the already present time it
468 // will be ignored if the correct place added a respawn timer
469 if (setSpawnTime)
470 {
471 uint32 respawnDelay = m_respawnDelay;
472 m_respawnTime = std::max<time_t>(GameTime::GetGameTime() + respawnDelay, m_respawnTime);
473
475 }
476
477 if (TempSummon* summon = ToTempSummon())
478 summon->UnSummon();
479 else
481 }
482}
483
487bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
488{
489 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry);
490 if (!creatureInfo)
491 {
492 TC_LOG_ERROR("sql.sql", "Creature::InitEntry creature entry {} does not exist.", entry);
493 return false;
494 }
495
496 m_creatureInfo = creatureInfo;
497 SetEntry(entry);
498 m_creatureDifficulty = creatureInfo->GetDifficulty(!IsPet() ? GetMap()->GetDifficultyID() : DIFFICULTY_NONE);
499
500 // equal to player Race field, but creature does not have race
502
503 // known valid are: CLASS_WARRIOR, CLASS_PALADIN, CLASS_ROGUE, CLASS_MAGE
504 SetClass(uint8(creatureInfo->unit_class));
505
506 // Cancel load if no model defined
507 if (!(creatureInfo->GetFirstValidModel()))
508 {
509 TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has no model defined in table `creature_template`, can't load. ", entry);
510 return false;
511 }
512
513 CreatureModel model = *ObjectMgr::ChooseDisplayId(creatureInfo, data);
514 CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&model, creatureInfo);
515 if (!minfo) // Cancel load if no model defined
516 {
517 TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid model {} defined in table `creature_template`, can't load.", entry, model.CreatureDisplayID);
518 return false;
519 }
520
521 SetDisplayId(model.CreatureDisplayID, true);
522
523 // Load creature equipment
524 if (!data)
525 LoadEquipment(); // use default equipment (if available) for summons
526 else if (data->equipmentId == 0)
527 LoadEquipment(0); // 0 means no equipment for creature table
528 else
529 {
532 }
533
534 SetName(creatureInfo->Name); // at normal entry always
535
536 SetModCastingSpeed(1.0f);
537 SetModSpellHaste(1.0f);
538 SetModHaste(1.0f);
539 SetModRangedHaste(1.0f);
540 SetModHasteRegen(1.0f);
541 SetModTimeRate(1.0f);
542
543 SetSpeedRate(MOVE_WALK, creatureInfo->speed_walk);
544 SetSpeedRate(MOVE_RUN, creatureInfo->speed_run);
545 SetSpeedRate(MOVE_SWIM, 1.0f); // using 1.0 rate
546 SetSpeedRate(MOVE_FLIGHT, 1.0f); // using 1.0 rate
547
548 // Will set UNIT_FIELD_BOUNDINGRADIUS, UNIT_FIELD_COMBATREACH and UNIT_FIELD_DISPLAYSCALE
550
552
553 // checked at loading
557
558 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
560
562
564 || IsPet()
565 || IsTotem()
566 || creatureInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_XP);
567
568 // TODO: migrate these in DB
573
574 return true;
575}
576
577bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, bool updateLevel /* = true */)
578{
579 if (!InitEntry(entry, data))
580 return false;
581
582 CreatureTemplate const* cInfo = GetCreatureTemplate();
583
585
586 // creatures always have melee weapon ready if any unless specified otherwise
587 if (!GetCreatureAddon())
589
590 SetFaction(cInfo->faction);
591
592 uint64 npcFlags;
593 uint32 unitFlags, unitFlags2, unitFlags3;
594 ObjectMgr::ChooseCreatureFlags(cInfo, &npcFlags, &unitFlags, &unitFlags2, &unitFlags3, _staticFlags, data);
595
597 npcFlags |= sGameEventMgr->GetNPCFlag(this);
598
599 ReplaceAllNpcFlags(NPCFlags(npcFlags & 0xFFFFFFFF));
600 ReplaceAllNpcFlags2(NPCFlags2(npcFlags >> 32));
601
602 // if unit is in combat, keep this flag
603 unitFlags &= ~UNIT_FLAG_IN_COMBAT;
604 if (IsInCombat())
605 unitFlags |= UNIT_FLAG_IN_COMBAT;
606
607 ReplaceAllUnitFlags(UnitFlags(unitFlags));
608 ReplaceAllUnitFlags2(UnitFlags2(unitFlags2));
609 ReplaceAllUnitFlags3(UnitFlags3(unitFlags3));
610
612
614
616
620
621 if (updateLevel)
622 SelectLevel();
623 else if (!IsGuardian())
624 {
625 uint32 previousHealth = GetHealth();
626 UpdateLevelDependantStats(); // We still re-initialize level dependant stats on entry update
627 if (previousHealth > 0)
628 SetHealth(previousHealth);
629 }
630
631 // Do not update guardian stats here - they are handled in Guardian::InitStatsForLevel()
632 if (!IsGuardian())
633 {
641
642 SetCanModifyStats(true);
644 }
645
646 // checked and error show at loading templates
647 if (FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction))
648 {
649 SetPvP((factionTemplate->Flags & FACTION_TEMPLATE_FLAG_PVP) != 0);
650 if (IsTaxi())
651 {
652 uint32 taxiNodesId = sObjectMgr->GetNearestTaxiNode(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(),
653 factionTemplate->FactionGroup & FACTION_MASK_ALLIANCE ? ALLIANCE : HORDE);
655 }
656 }
657
658 // updates spell bars for vehicles and set player's faction - should be called here, to overwrite faction that is set from the new template
659 if (IsVehicle())
660 {
661 if (Player* owner = Creature::GetCharmerOrOwnerPlayerOrPlayerItself()) // this check comes in case we don't have a player
662 {
663 SetFaction(owner->GetFaction()); // vehicles should have same as owner faction
664 owner->VehicleSpellInitialize();
665 }
666 }
667
668 // trigger creature is always uninteractible and can not be attacked
669 if (IsTrigger())
670 SetUninteractible(true);
671
674
676
678 {
681 }
682
684
686
690
692
693 //We must update last scriptId or it looks like we reloaded a script, breaking some things such as gossip temporarily
695
696 m_stringIds[0] = cInfo->StringId;
697
698 return true;
699}
700
702{
704
705 // Apply all other side effects of flag changes
707}
708
710{
712 {
715
718 m_triggerJustAppeared = false;
719 AI()->JustAppeared();
720 }
721
723
724 switch (m_deathState)
725 {
726 case JUST_RESPAWNED:
727 // Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting.
728 TC_LOG_ERROR("entities.unit", "Creature {} in wrong state: JUST_RESPAWNED (4)", GetGUID().ToString());
729 break;
730 case JUST_DIED:
731 // Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
732 TC_LOG_ERROR("entities.unit", "Creature {} in wrong state: JUST_DIED (1)", GetGUID().ToString());
733 break;
734 case DEAD:
735 {
737 {
738 TC_LOG_ERROR("entities.unit", "Creature {} in wrong state: DEAD (3)", GetGUID().ToString());
739 break;
740 }
741 time_t now = GameTime::GetGameTime();
742 if (m_respawnTime <= now)
743 {
744 // Delay respawn if spawn group is not active
745 if (m_creatureData && !GetMap()->IsSpawnGroupActive(m_creatureData->spawnGroupData->groupId))
746 {
747 m_respawnTime = now + urand(4,7);
748 break; // Will be rechecked on next Update call after delay expires
749 }
750
751 ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Creature>(GetMapId(), GetEntry(), m_spawnId);
752 time_t linkedRespawnTime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
753 if (!linkedRespawnTime) // Can respawn
754 Respawn();
755 else // the master is dead
756 {
757 ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
758 if (targetGuid == dbtableHighGuid) // if linking self, never respawn
760 else
761 {
762 // else copy time from master and add a little
763 time_t baseRespawnTime = std::max(linkedRespawnTime, now);
764 time_t const offset = urand(5, MINUTE);
765
766 // linked guid can be a boss, uses std::numeric_limits<time_t>::max to never respawn in that instance
767 // we shall inherit it instead of adding and causing an overflow
768 if (baseRespawnTime <= std::numeric_limits<time_t>::max() - offset)
769 m_respawnTime = baseRespawnTime + offset;
770 else
771 m_respawnTime = std::numeric_limits<time_t>::max();
772 }
773 SaveRespawnTime(); // also save to DB immediately
774 }
775 }
776 break;
777 }
778 case CORPSE:
779 {
780 Unit::Update(diff);
781 // deathstate changed on spells update, prevent problems
782 if (m_deathState != CORPSE)
783 break;
784
785 if (IsEngaged())
786 Unit::AIUpdateTick(diff);
787
788 if (m_loot)
789 m_loot->Update();
790
791 for (auto&& [playerOwner, loot] : m_personalLoot)
792 loot->Update();
793
795 {
796 RemoveCorpse(false);
797 TC_LOG_DEBUG("entities.unit", "Removing corpse... {} ", GetEntry());
798 }
799 break;
800 }
801 case ALIVE:
802 {
803 Unit::Update(diff);
804
805 // creature can be dead after Unit::Update call
806 // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
807 if (!IsAlive())
808 break;
809
810 GetThreatManager().Update(diff);
811 if (_spellFocusInfo.Delay)
812 {
813 if (_spellFocusInfo.Delay <= diff)
815 else
816 _spellFocusInfo.Delay -= diff;
817 }
818
819 // periodic check to see if the creature has passed an evade boundary
820 if (IsAIEnabled() && !IsInEvadeMode() && IsEngaged())
821 {
822 if (diff >= m_boundaryCheckTime)
823 {
824 AI()->CheckInRoom();
825 m_boundaryCheckTime = 2500;
826 } else
827 m_boundaryCheckTime -= diff;
828 }
829
830 // if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now
831 if (m_combatPulseDelay > 0 && IsEngaged() && GetMap()->IsDungeon())
832 {
833 if (diff > m_combatPulseTime)
835 else
836 m_combatPulseTime -= diff;
837
838 if (m_combatPulseTime == 0)
839 {
840 Map::PlayerList const& players = GetMap()->GetPlayers();
841 if (!players.isEmpty())
842 for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
843 {
844 if (Player* player = it->GetSource())
845 {
846 if (player->IsGameMaster())
847 continue;
848
849 if (player->IsAlive() && IsHostileTo(player))
850 EngageWithTarget(player);
851 }
852 }
853
855 }
856 }
857
858 Unit::AIUpdateTick(diff);
859
861
862 // creature can be dead after UpdateAI call
863 // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
864 if (!IsAlive())
865 break;
866
867 if (m_regenTimer > 0)
868 {
869 if (diff >= m_regenTimer)
870 m_regenTimer = 0;
871 else
872 m_regenTimer -= diff;
873 }
874
875 if (m_regenTimer == 0)
876 {
877 if (!IsInEvadeMode())
878 {
879 // regenerate health if not in combat or if polymorphed)
880 if (!IsEngaged() || IsPolymorphed())
882 else if (CanNotReachTarget())
883 {
884 // regenerate health if cannot reach the target and the setting is set to do so.
885 // this allows to disable the health regen of raid bosses if pathfinding has issues for whatever reason
886 if (sWorld->getBoolConfig(CONFIG_REGEN_HP_CANNOT_REACH_TARGET_IN_RAID) || !GetMap()->IsRaid())
887 {
889 TC_LOG_DEBUG("entities.unit.chase", "RegenerateHealth() enabled because Creature cannot reach the target. Detail: {}", GetDebugInfo());
890 }
891 else
892 TC_LOG_DEBUG("entities.unit.chase", "RegenerateHealth() disabled even if the Creature cannot reach the target. Detail: {}", GetDebugInfo());
893 }
894 }
895
896 if (GetPowerType() == POWER_ENERGY)
898 else
900
902 }
903
904 if (CanNotReachTarget() && !IsInEvadeMode() && !GetMap()->IsRaid())
905 {
906 m_cannotReachTimer += diff;
908 if (CreatureAI* ai = AI())
909 ai->EnterEvadeMode(EvadeReason::NoPath);
910 }
911 break;
912 }
913 default:
914 break;
915 }
916}
917
919{
920 uint32 curValue = GetPower(power);
921 uint32 maxValue = GetMaxPower(power);
922
924 return;
925
926 if (curValue >= maxValue)
927 return;
928
929 float addvalue = 0.0f;
930
931 switch (power)
932 {
933 case POWER_FOCUS:
934 {
935 // For hunter pets.
936 addvalue = 24 * sWorld->getRate(RATE_POWER_FOCUS);
937 break;
938 }
939 case POWER_ENERGY:
940 {
941 // For deathknight's ghoul.
942 addvalue = 20;
943 break;
944 }
945 case POWER_MANA:
946 {
947 // Combat and any controlled creature
948 if (IsInCombat() || GetCharmerOrOwnerGUID().IsEmpty())
949 {
950 float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
951
952 addvalue = uint32((27.0f / 5.0f + 17.0f) * ManaIncreaseRate);
953 }
954 else
955 addvalue = maxValue / 3;
956
957 break;
958 }
959 default:
960 return;
961 }
962
963 // Apply modifiers (if any).
965
967
968 ModifyPower(power, int32(addvalue));
969}
970
972{
973 if (!CanRegenerateHealth())
974 return;
975
976 uint32 curValue = GetHealth();
977 uint32 maxValue = GetMaxHealth();
978
979 if (curValue >= maxValue)
980 return;
981
982 uint32 addvalue = 0;
983
984 // Not only pet, but any controlled creature (and not polymorphed)
985 if (!GetCharmerOrOwnerGUID().IsEmpty() && !IsPolymorphed())
986 {
987 float HealthIncreaseRate = sWorld->getRate(RATE_HEALTH);
988
989 addvalue = 0.015f * ((float)GetMaxHealth()) * HealthIncreaseRate;
990 }
991 else
992 addvalue = maxValue/3;
993
994 // Apply modifiers (if any).
996
998
999 ModifyHealth(addvalue);
1000}
1001
1003{
1004 if (!GetVictim())
1005 return;
1006
1008 return;
1009
1010 float radius = sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS);
1011 if (radius >0)
1012 {
1013 Creature* creature = nullptr;
1016 Cell::VisitGridObjects(this, searcher, radius);
1017
1019
1020 if (!creature)
1023 else
1024 GetMotionMaster()->MoveSeekAssistance(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ());
1025 }
1026}
1027
1029{
1030 PopAI();
1031 RefreshAI();
1032 return true;
1033}
1034
1035bool Creature::AIM_Create(CreatureAI* ai /*= nullptr*/)
1036{
1038
1039 SetAI(ai ? ai : FactorySelector::SelectAI(this));
1040
1041 return true;
1042}
1043
1045{
1046 if (!AIM_Create(ai))
1047 return false;
1048
1049 AI()->InitializeAI();
1050 if (GetVehicleKit())
1051 GetVehicleKit()->Reset();
1052 return true;
1053}
1054
1056{
1057 if (m_formation)
1058 {
1059 if (m_formation->GetLeader() == this)
1061 else if (m_formation->IsFormed())
1062 {
1063 GetMotionMaster()->MoveIdle(); // wait the order of leader
1064 return;
1065 }
1066 }
1067
1069}
1070
1071bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, Position const& pos, CreatureData const* data /*= nullptr*/, uint32 vehId /*= 0*/, bool dynamic)
1072{
1073 ASSERT(map);
1074 SetMap(map);
1075
1076 if (data)
1077 {
1080 }
1081
1082 // Set if this creature can handle dynamic spawns
1083 if (!dynamic)
1085
1086 CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
1087 if (!cinfo)
1088 {
1089 TC_LOG_ERROR("sql.sql", "Creature::Create(): creature template (guidlow: {}, entry: {}) does not exist.", guidlow, entry);
1090 return false;
1091 }
1092
1093 CreatureDifficulty const* creatureDifficulty = cinfo->GetDifficulty(GetMap()->GetDifficultyID());
1094
1097 Relocate(pos);
1098
1099 // Check if the position is valid before calling CreateFromProto(), otherwise we might add Auras to Creatures at
1100 // invalid position, triggering a crash about Auras not removed in the destructor
1101 if (!IsPositionValid())
1102 {
1103 TC_LOG_ERROR("entities.unit", "Creature::Create(): given coordinates for creature (guidlow {}, entry {}) are not valid (X: {}, Y: {}, Z: {}, O: {})", guidlow, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
1104 return false;
1105 }
1106 {
1107 // area/zone id is needed immediately for ZoneScript::GetCreatureEntry hook before it is known which creature template to load (no model/scale available yet)
1108 PositionFullTerrainStatus terrainStatus;
1110 ProcessPositionDataChanged(terrainStatus);
1111 }
1112
1113 // Allow players to see those units while dead, do it here (mayby altered by addon auras)
1114 if (creatureDifficulty->TypeFlags & CREATURE_TYPE_FLAG_VISIBLE_TO_GHOSTS)
1116
1117 if (!CreateFromProto(guidlow, entry, data, vehId))
1118 return false;
1119
1120 cinfo = GetCreatureTemplate(); // might be different than initially requested
1122 m_respawnDelay = 0; // special value, prevents respawn for dungeon bosses unless overridden
1123
1124 switch (GetCreatureClassification())
1125 {
1128 break;
1131 break;
1134 break;
1137 break;
1140 break;
1143 break;
1144 default:
1146 break;
1147 }
1148
1151
1154
1156
1158 {
1161 }
1162
1165
1167 {
1170 }
1171
1173
1174 return true;
1175}
1176
1177Creature* Creature::CreateCreature(uint32 entry, Map* map, Position const& pos, uint32 vehId /*= 0*/)
1178{
1179 CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry);
1180 if (!cInfo)
1181 return nullptr;
1182
1183 ObjectGuid::LowType lowGuid;
1184 if (vehId || cInfo->VehicleId)
1185 lowGuid = map->GenerateLowGuid<HighGuid::Vehicle>();
1186 else
1187 lowGuid = map->GenerateLowGuid<HighGuid::Creature>();
1188
1189 Creature* creature = new Creature();
1190 if (!creature->Create(lowGuid, map, entry, pos, nullptr, vehId))
1191 {
1192 delete creature;
1193 return nullptr;
1194 }
1195
1196 return creature;
1197}
1198
1199Creature* Creature::CreateCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap /*= true*/, bool allowDuplicate /*= false*/)
1200{
1201 Creature* creature = new Creature();
1202 if (!creature->LoadFromDB(spawnId, map, addToMap, allowDuplicate))
1203 {
1204 delete creature;
1205 return nullptr;
1206 }
1207
1208 return creature;
1209}
1210
1212{
1213 Unit* target = nullptr;
1214
1215 if (CanHaveThreatList())
1217 else if (!HasReactState(REACT_PASSIVE))
1218 {
1219 // We're a player pet, probably
1220 target = getAttackerForHelper();
1221 if (!target && IsSummon())
1222 {
1223 if (Unit* owner = ToTempSummon()->GetOwner())
1224 {
1225 if (owner->IsInCombat())
1226 target = owner->getAttackerForHelper();
1227 if (!target)
1228 {
1229 for (ControlList::const_iterator itr = owner->m_Controlled.begin(); itr != owner->m_Controlled.end(); ++itr)
1230 {
1231 if ((*itr)->IsInCombat())
1232 {
1233 target = (*itr)->getAttackerForHelper();
1234 if (target)
1235 break;
1236 }
1237 }
1238 }
1239 }
1240 }
1241 }
1242 else
1243 return nullptr;
1244
1245 if (target && _IsTargetAcceptable(target) && CanCreatureAttack(target))
1246 {
1247 if (!HasSpellFocus())
1248 SetInFront(target);
1249 return target;
1250 }
1251
1253 if (GetVehicle())
1254 return nullptr;
1255
1257 if (!iAuras.empty())
1258 {
1259 for (Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
1260 {
1261 if ((*itr)->GetBase()->IsPermanent())
1262 {
1264 break;
1265 }
1266 }
1267 return nullptr;
1268 }
1269
1270 // enter in evade mode in other case
1272
1273 return nullptr;
1274}
1275
1277{
1278 if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService())
1280 /*
1281 else if (IsCivilian())
1282 SetReactState(REACT_DEFENSIVE);
1283 */
1284 else
1286}
1287
1289{
1290 if (!IsBattleMaster())
1291 return false;
1292
1293 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(GetEntry());
1294 if (!msg)
1295 return player->GetBGAccessByLevel(bgTypeId);
1296
1297 if (!player->GetBGAccessByLevel(bgTypeId))
1298 {
1299 ClearGossipMenuFor(player);
1300 switch (bgTypeId)
1301 {
1302 case BATTLEGROUND_AV: SendGossipMenuFor(player, 7616, this); break;
1303 case BATTLEGROUND_WS: SendGossipMenuFor(player, 7599, this); break;
1304 case BATTLEGROUND_AB: SendGossipMenuFor(player, 7642, this); break;
1305 case BATTLEGROUND_EY:
1306 case BATTLEGROUND_NA:
1307 case BATTLEGROUND_BE:
1308 case BATTLEGROUND_AA:
1309 case BATTLEGROUND_RL:
1310 case BATTLEGROUND_SA:
1311 case BATTLEGROUND_DS:
1312 case BATTLEGROUND_RV: SendGossipMenuFor(player, 10024, this); break;
1313 default: break;
1314 }
1315 return false;
1316 }
1317 return true;
1318}
1319
1321{
1322 return player->GetLevel() >= 15
1323 && player->GetClass() == GetCreatureTemplate()->trainer_class;
1324}
1325
1327{
1328 if (m_lootId)
1329 return *m_lootId;
1330
1331 return GetCreatureDifficulty()->LootID;
1332}
1333
1335{
1336 m_lootId = lootId;
1337}
1338
1339void Creature::SetTappedBy(Unit const* unit, bool withGroup)
1340{
1341 // set the player whose group should receive the right
1342 // to loot the creature after it dies
1343 // should be set to nullptr after the loot disappears
1344
1345 if (!unit)
1346 {
1347 m_tapList.clear();
1349 return;
1350 }
1351
1353 return;
1354
1355 if (unit->GetTypeId() != TYPEID_PLAYER && !unit->IsVehicle())
1356 return;
1357
1359 if (!player) // normal creature, no player involved
1360 return;
1361
1362 m_tapList.insert(player->GetGUID());
1363 if (withGroup)
1364 if (Group const* group = player->GetGroup())
1365 for (auto const* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1366 if (GetMap()->IsRaid() || group->SameSubGroup(player, itr->GetSource()))
1367 m_tapList.insert(itr->GetSource()->GetGUID());
1368
1371}
1372
1374{
1375 // only temporary summons are allowed to not clear their tap list
1376 if (!m_spawnId)
1377 m_dontClearTapListOnEvade = dontClear;
1378}
1379
1380// return true if this creature is tapped by the player or by a member of his group.
1381bool Creature::isTappedBy(Player const* player) const
1382{
1383 return m_tapList.find(player->GetGUID()) != m_tapList.end();
1384}
1385
1387{
1388 if (m_personalLoot.empty())
1389 return m_loot.get();
1390
1391 if (std::unique_ptr<Loot> const* loot = Trinity::Containers::MapGetValuePtr(m_personalLoot, player->GetGUID()))
1392 return loot->get();
1393
1394 return nullptr;
1395}
1396
1398{
1399 if (m_loot && !m_loot->isLooted())
1400 return false;
1401
1402 for (auto const& [_, loot] : m_personalLoot)
1403 if (!loot->isLooted())
1404 return false;
1405
1406 return true;
1407}
1408
1409bool Creature::IsSkinnedBy(Player const* player) const
1410{
1411 if (Loot* loot = GetLootForPlayer(player))
1412 return loot->loot_type == LOOT_SKINNING;
1413
1414 return false;
1415}
1416
1418{
1419 // this should only be used when the creature has already been loaded
1420 // preferably after adding to map, because mapid may not be valid otherwise
1421 CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
1422 if (!data)
1423 {
1424 TC_LOG_ERROR("entities.unit", "Creature::SaveToDB failed, cannot get creature data!");
1425 return;
1426 }
1427
1428 uint32 mapId = GetMapId();
1429 if (TransportBase* transport = GetTransport())
1430 if (transport->GetMapIdForSpawning() >= 0)
1431 mapId = transport->GetMapIdForSpawning();
1432
1433 SaveToDB(mapId, data->spawnDifficulties);
1434}
1435
1436void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDifficulties)
1437{
1438 // update in loaded data
1439 if (!m_spawnId)
1440 m_spawnId = sObjectMgr->GenerateCreatureSpawnId();
1441
1442 CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId);
1443
1444 uint32 displayId = GetNativeDisplayId();
1445 uint64 spawnNpcFlags = (uint64(m_unitData->NpcFlags[1]) << 32) | m_unitData->NpcFlags[0];
1446 Optional<uint64> npcflag;
1447 Optional<uint32> unitFlags;
1448 Optional<uint32> unitFlags2;
1449 Optional<uint32> unitFlags3;
1450
1451 // check if it's a custom model and if not, use 0 for displayId
1452 CreatureTemplate const* cinfo = GetCreatureTemplate();
1453 if (cinfo)
1454 {
1455 for (CreatureModel const& model : cinfo->Models)
1456 if (displayId && displayId == model.CreatureDisplayID)
1457 displayId = 0;
1458
1459 if (spawnNpcFlags != cinfo->npcflag)
1460 npcflag = spawnNpcFlags;
1461
1462 if (m_unitData->Flags != cinfo->unit_flags)
1463 unitFlags = m_unitData->Flags;
1464
1465 if (m_unitData->Flags2 != cinfo->unit_flags2)
1466 unitFlags2 = m_unitData->Flags2;
1467
1468 if (m_unitData->Flags3 != cinfo->unit_flags3)
1469 unitFlags3 = m_unitData->Flags3;
1470 }
1471
1472 if (!data.spawnId)
1473 data.spawnId = m_spawnId;
1474 ASSERT(data.spawnId == m_spawnId);
1475 data.id = GetEntry();
1476 if (displayId)
1477 data.display.emplace(displayId, DEFAULT_PLAYER_DISPLAY_SCALE, 1.0f);
1478 else
1479 data.display.reset();
1481 if (!GetTransport())
1482 {
1483 data.mapId = GetMapId();
1484 data.spawnPoint.Relocate(this);
1485 }
1486 else
1487 {
1488 data.mapId = mapid;
1490 }
1492 // prevent add data integrity problems
1494 data.currentwaypoint = 0;
1495 data.curhealth = GetHealth();
1496 data.curmana = GetPower(POWER_MANA);
1497 // prevent add data integrity problems
1500 data.spawnDifficulties = spawnDifficulties;
1501 data.npcflag = npcflag;
1502 data.unit_flags = unitFlags;
1503 data.unit_flags2 = unitFlags2;
1504 data.unit_flags3 = unitFlags3;
1505 if (!data.spawnGroupData)
1506 data.spawnGroupData = sObjectMgr->GetDefaultSpawnGroup();
1507
1508 data.phaseId = GetDBPhase() > 0 ? GetDBPhase() : data.phaseId;
1509 data.phaseGroup = GetDBPhase() < 0 ? -GetDBPhase() : data.phaseGroup;
1510
1511 // update in DB
1512 WorldDatabaseTransaction trans = WorldDatabase.BeginTransaction();
1513
1515 stmt->setUInt64(0, m_spawnId);
1516 trans->Append(stmt);
1517
1518 uint8 index = 0;
1519
1520 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE);
1521 stmt->setUInt64(index++, m_spawnId);
1522 stmt->setUInt32(index++, GetEntry());
1523 stmt->setUInt16(index++, uint16(mapid));
1524 stmt->setString(index++, [&data]() -> std::string
1525 {
1526 if (data.spawnDifficulties.empty())
1527 return "";
1528
1529 std::ostringstream os;
1530 auto itr = data.spawnDifficulties.begin();
1531 os << int32(*itr++);
1532
1533 for (; itr != data.spawnDifficulties.end(); ++itr)
1534 os << ',' << int32(*itr);
1535
1536 return os.str();
1537 }());
1538 stmt->setUInt32(index++, data.phaseId);
1539 stmt->setUInt32(index++, data.phaseGroup);
1540 stmt->setUInt32(index++, displayId);
1541 stmt->setUInt8(index++, GetCurrentEquipmentId());
1542 stmt->setFloat(index++, GetPositionX());
1543 stmt->setFloat(index++, GetPositionY());
1544 stmt->setFloat(index++, GetPositionZ());
1545 stmt->setFloat(index++, GetOrientation());
1546 stmt->setUInt32(index++, m_respawnDelay);
1547 stmt->setFloat(index++, m_wanderDistance);
1548 stmt->setUInt32(index++, 0);
1549 stmt->setUInt32(index++, GetHealth());
1550 stmt->setUInt32(index++, GetPower(POWER_MANA));
1551 stmt->setUInt8(index++, uint8(GetDefaultMovementType()));
1552 if (npcflag.has_value())
1553 stmt->setUInt64(index++, *npcflag);
1554 else
1555 stmt->setNull(index++);
1556
1557 if (unitFlags.has_value())
1558 stmt->setUInt32(index++, *unitFlags);
1559 else
1560 stmt->setNull(index++);
1561
1562 if (unitFlags2.has_value())
1563 stmt->setUInt32(index++, *unitFlags2);
1564 else
1565 stmt->setNull(index++);
1566
1567 if (unitFlags3.has_value())
1568 stmt->setUInt32(index++, *unitFlags3);
1569 else
1570 stmt->setNull(index++);
1571 trans->Append(stmt);
1572
1573 WorldDatabase.CommitTransaction(trans);
1574}
1575
1577{
1578 // Level
1580 int32 levelWithDelta = m_unitData->ScalingLevelMax + m_unitData->ScalingLevelDelta;
1581 uint8 level = RoundToInterval<int32>(levelWithDelta, 1, STRONG_MAX_LEVEL);
1582 SetLevel(level);
1583
1585}
1586
1588{
1589 CreatureTemplate const* cInfo = GetCreatureTemplate();
1591 uint8 level = GetLevel();
1592 CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(level, cInfo->unit_class);
1593
1594 // health
1595 float healthmod = GetHealthMod(classification);
1596
1597 uint32 basehp = GetMaxHealthByLevel(level);
1598 uint32 health = uint32(basehp * healthmod);
1599
1600 SetCreateHealth(health);
1601 SetMaxHealth(health);
1602 SetHealth(health);
1604
1606
1607 // mana
1608 Powers powerType = CalculateDisplayPowerType();
1609 SetCreateMana(stats->BaseMana);
1611 SetPowerType(powerType);
1612
1613 if (PowerTypeEntry const* powerTypeEntry = sDB2Manager.GetPowerTypeEntry(powerType))
1614 {
1615 if (powerTypeEntry->GetFlags().HasFlag(PowerTypeFlags::UnitsUseDefaultPowerOnInit))
1616 SetPower(powerType, powerTypeEntry->DefaultPower);
1617 else
1618 SetFullPower(powerType);
1619 }
1620
1621 // damage
1622 float basedamage = GetBaseDamageForLevel(level);
1623
1624 float weaponBaseMinDamage = basedamage;
1625 float weaponBaseMaxDamage = basedamage * 1.5f;
1626
1627 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1628 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1629
1630 SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1631 SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1632
1633 SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1634 SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1635
1638
1639 float armor = GetBaseArmorForLevel(level);
1641}
1642
1644{
1645 if (IsWildBattlePet())
1646 {
1647 uint8 wildBattlePetLevel = WILD_BATTLE_PET_DEFAULT_LEVEL;
1648
1649 if (AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(GetZoneId()))
1650 if (areaTable->WildBattlePetLevelMin > 0)
1651 wildBattlePetLevel = urand(areaTable->WildBattlePetLevelMin, areaTable->WildBattlePetLevelMax);
1652
1653 SetWildBattlePetLevel(wildBattlePetLevel);
1654 }
1655}
1656
1658{
1659 switch (classification)
1660 {
1662 return sWorld->getRate(RATE_CREATURE_HP_NORMAL);
1664 return sWorld->getRate(RATE_CREATURE_HP_ELITE);
1666 return sWorld->getRate(RATE_CREATURE_HP_RAREELITE);
1668 return sWorld->getRate(RATE_CREATURE_HP_OBSOLETE);
1670 return sWorld->getRate(RATE_CREATURE_HP_RARE);
1672 return sWorld->getRate(RATE_CREATURE_HP_TRIVIAL);
1674 return sWorld->getRate(RATE_CREATURE_HP_MINUSMOB);
1675 default:
1676 return sWorld->getRate(RATE_CREATURE_HP_ELITE);
1677 }
1678}
1679
1681{
1683 m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0;
1684}
1685
1687{
1688 switch (classification)
1689 {
1691 return sWorld->getRate(RATE_CREATURE_DAMAGE_NORMAL);
1693 return sWorld->getRate(RATE_CREATURE_DAMAGE_ELITE);
1695 return sWorld->getRate(RATE_CREATURE_DAMAGE_RAREELITE);
1697 return sWorld->getRate(RATE_CREATURE_DAMAGE_OBSOLETE);
1699 return sWorld->getRate(RATE_CREATURE_DAMAGE_RARE);
1701 return sWorld->getRate(RATE_CREATURE_DAMAGE_TRIVIAL);
1703 return sWorld->getRate(RATE_CREATURE_DAMAGE_MINUSMOB);
1704 default:
1705 return sWorld->getRate(RATE_CREATURE_DAMAGE_ELITE);
1706 }
1707}
1708
1710{
1711 switch (classification)
1712 {
1716 return sWorld->getRate(RATE_CREATURE_SPELLDAMAGE_ELITE);
1722 return sWorld->getRate(RATE_CREATURE_SPELLDAMAGE_RARE);
1727 default:
1728 return sWorld->getRate(RATE_CREATURE_SPELLDAMAGE_ELITE);
1729 }
1730}
1731
1732void Creature::OverrideSparringHealthPct(std::vector<float> const& healthPct)
1733{
1735}
1736
1738{
1739 if (GetSparringHealthPct() == 0)
1740 return damage;
1741
1742 if (!attacker)
1743 return damage;
1744
1746 return damage;
1747
1749 return 0;
1750
1751 uint32 sparringHealth = GetMaxHealth() * GetSparringHealthPct() / 100;
1752 if (GetHealth() - damage <= sparringHealth)
1753 return GetHealth() - sparringHealth;
1754
1755 if (damage >= GetHealth())
1756 return GetHealth() - 1;
1757
1758 return damage;
1759}
1760
1762{
1763 if (!GetSparringHealthPct())
1764 return false;
1765
1766 if (!attacker)
1767 return false;
1768
1769 if (!attacker->IsCreature())
1770 return false;
1771
1773 return false;
1774
1776 return false;
1777
1778 return true;
1779}
1780
1781bool Creature::CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data /*= nullptr*/, uint32 vehId /*= 0*/)
1782{
1783 SetZoneScript();
1784 if (GetZoneScript() && data)
1785 {
1786 entry = GetZoneScript()->GetCreatureEntry(guidlow, data);
1787 if (!entry)
1788 return false;
1789 }
1790
1791 CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
1792 if (!cinfo)
1793 {
1794 TC_LOG_ERROR("sql.sql", "Creature::CreateFromProto(): creature template (guidlow: {}, entry: {}) does not exist.", guidlow, entry);
1795 return false;
1796 }
1797
1798 SetOriginalEntry(entry);
1799
1800 if (vehId || cinfo->VehicleId)
1801 Object::_Create(ObjectGuid::Create<HighGuid::Vehicle>(GetMapId(), entry, guidlow));
1802 else
1803 Object::_Create(ObjectGuid::Create<HighGuid::Creature>(GetMapId(), entry, guidlow));
1804
1805 if (!UpdateEntry(entry, data))
1806 return false;
1807
1808 if (!vehId)
1809 {
1810 if (GetCreatureTemplate()->VehicleId)
1811 {
1812 vehId = GetCreatureTemplate()->VehicleId;
1813 entry = GetCreatureTemplate()->Entry;
1814 }
1815 else
1816 vehId = cinfo->VehicleId;
1817 }
1818
1819 if (vehId)
1820 if (CreateVehicleKit(vehId, entry, true))
1822
1823 if (!IsPet())
1824 if (uint32 vignetteId = GetCreatureTemplate()->VignetteID)
1825 SetVignette(vignetteId);
1826
1827 return true;
1828}
1829
1830bool Creature::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate)
1831{
1832 if (!allowDuplicate)
1833 {
1834 // If an alive instance of this spawnId is already found, skip creation
1835 // If only dead instance(s) exist, despawn them and spawn a new (maybe also dead) version
1836 const auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(spawnId);
1837 std::vector <Creature*> despawnList;
1838
1839 if (creatureBounds.first != creatureBounds.second)
1840 {
1841 for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr)
1842 {
1843 if (itr->second->IsAlive())
1844 {
1845 TC_LOG_DEBUG("maps", "Would have spawned {} but {} already exists", spawnId, creatureBounds.first->second->GetGUID().ToString());
1846 return false;
1847 }
1848 else
1849 {
1850 despawnList.push_back(itr->second);
1851 TC_LOG_DEBUG("maps", "Despawned dead instance of spawn {} ({})", spawnId, itr->second->GetGUID().ToString());
1852 }
1853 }
1854
1855 for (Creature* despawnCreature : despawnList)
1856 {
1857 despawnCreature->AddObjectToRemoveList();
1858 }
1859 }
1860 }
1861
1862 CreatureData const* data = sObjectMgr->GetCreatureData(spawnId);
1863 if (!data)
1864 {
1865 TC_LOG_ERROR("sql.sql", "Creature (SpawnID {}) not found in table `creature`, can't load. ", spawnId);
1866 return false;
1867 }
1868
1869 m_spawnId = spawnId;
1870
1872 m_creatureData = data;
1875
1876 if (!Create(map->GenerateLowGuid<HighGuid::Creature>(), map, data->id, data->spawnPoint, data, 0U , !m_respawnCompatibilityMode))
1877 return false;
1878
1879 //We should set first home position, because then AI calls home movement
1880 SetHomePosition(*this);
1881
1883
1885
1887 {
1889 {
1890 // @todo pools need fixing! this is just a temporary thing, but they violate dynspawn principles
1891 if (!data->poolId)
1892 {
1893 TC_LOG_ERROR("entities.unit", "Creature (SpawnID {}) trying to load in inactive spawn group '{}':\n{}", spawnId, data->spawnGroupData->name, GetDebugInfo());
1894 return false;
1895 }
1896 }
1897
1899 }
1900
1901 if (m_respawnTime)
1902 {
1904 {
1905 // @todo same as above
1906 if (!data->poolId)
1907 {
1908 TC_LOG_ERROR("entities.unit", "Creature (SpawnID {}) trying to load despite a respawn timer in progress:\n{}", spawnId, GetDebugInfo());
1909 return false;
1910 }
1911 }
1912 else
1913 {
1914 // compatibility mode creatures will be respawned in ::Update()
1916 }
1917
1918 if (CanFly())
1919 {
1920 float tz = map->GetHeight(GetPhaseShift(), data->spawnPoint, true, MAX_FALL_DISTANCE);
1921 if (data->spawnPoint.GetPositionZ() - tz > 0.1f && Trinity::IsValidMapCoord(tz))
1923 }
1924 }
1925
1927
1929
1930 // checked at creature_template loading
1932
1933 m_stringIds[1] = data->StringId;
1934
1935 if (addToMap && !GetMap()->AddToMap(this))
1936 return false;
1937 return true;
1938}
1939
1941{
1942 Unit::SetCanDualWield(value);
1944}
1945
1946void Creature::LoadEquipment(int8 id, bool force /*= true*/)
1947{
1948 if (id == 0)
1949 {
1950 if (force)
1951 {
1952 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1953 SetVirtualItem(i, 0);
1954 m_equipmentId = 0;
1955 }
1956
1957 return;
1958 }
1959
1960 EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(GetEntry(), id);
1961 if (!einfo)
1962 return;
1963
1964 m_equipmentId = id;
1965 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1966 SetVirtualItem(i, einfo->Items[i].ItemId, einfo->Items[i].AppearanceModId, einfo->Items[i].ItemVisual);
1967}
1968
1970{
1972 return;
1973
1974 uint32 curhealth;
1976 {
1977 curhealth = m_creatureData->curhealth;
1978 if (curhealth)
1979 {
1980 curhealth = uint32(curhealth*GetHealthMod(GetCreatureTemplate()->Classification));
1981 if (curhealth < 1)
1982 curhealth = 1;
1983 }
1985 }
1986 else
1987 {
1988 curhealth = GetMaxHealth();
1990 }
1991
1992 SetHealth((m_deathState == ALIVE || m_deathState == JUST_RESPAWNED) ? curhealth : 0);
1993}
1994
1995bool Creature::hasQuest(uint32 quest_id) const
1996{
1997 return sObjectMgr->GetCreatureQuestRelations(GetEntry()).HasQuest(quest_id);
1998}
1999
2001{
2002 return sObjectMgr->GetCreatureQuestInvolvedRelations(GetEntry()).HasQuest(quest_id);
2003}
2004
2006{
2007 CreatureData const* data = sObjectMgr->GetCreatureData(spawnId);
2008 if (!data)
2009 return false;
2010
2011 CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
2012
2013 sMapMgr->DoForAllMapsWithMapId(data->mapId,
2014 [spawnId, charTrans](Map* map) -> void
2015 {
2016 // despawn all active creatures, and remove their respawns
2017 std::vector<Creature*> toUnload;
2018 for (auto const& pair : Trinity::Containers::MapEqualRange(map->GetCreatureBySpawnIdStore(), spawnId))
2019 toUnload.push_back(pair.second);
2020 for (Creature* creature : toUnload)
2021 map->AddObjectToRemoveList(creature);
2022 map->RemoveRespawnTime(SPAWN_TYPE_CREATURE, spawnId, charTrans);
2023 }
2024 );
2025
2026 // delete data from memory ...
2027 sObjectMgr->DeleteCreatureData(spawnId);
2028
2029 CharacterDatabase.CommitTransaction(charTrans);
2030
2031 WorldDatabaseTransaction trans = WorldDatabase.BeginTransaction();
2032
2033 // ... and the database
2035 stmt->setUInt64(0, spawnId);
2036 trans->Append(stmt);
2037
2038 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_SPAWNGROUP_MEMBER);
2040 stmt->setUInt64(1, spawnId);
2041 trans->Append(stmt);
2042
2043 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON);
2044 stmt->setUInt64(0, spawnId);
2045 trans->Append(stmt);
2046
2047 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_CREATURE);
2048 stmt->setUInt64(0, spawnId);
2049 trans->Append(stmt);
2050
2051 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP);
2052 stmt->setUInt64(0, spawnId);
2053 trans->Append(stmt);
2054
2055 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN);
2056 stmt->setUInt64(0, spawnId);
2058 trans->Append(stmt);
2059
2060 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN);
2061 stmt->setUInt64(0, spawnId);
2063 trans->Append(stmt);
2064
2065 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN_MASTER);
2066 stmt->setUInt64(0, spawnId);
2068 trans->Append(stmt);
2069
2070 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN_MASTER);
2071 stmt->setUInt64(0, spawnId);
2073 trans->Append(stmt);
2074
2075 WorldDatabase.CommitTransaction(trans);
2076
2077 return true;
2078}
2079
2081{
2083 return true;
2084
2086 return false;
2087
2088 return true;
2089}
2090
2092{
2093 if (IsAIEnabled() && AI()->CanSeeAlways(obj))
2094 return true;
2095
2096 return false;
2097}
2098
2099bool Creature::CanStartAttack(Unit const* who, bool force) const
2100{
2101 if (IsCivilian())
2102 return false;
2103
2104 // This set of checks is should be done only for creatures
2107 return false;
2108
2109 // Do not attack non-combat pets
2111 return false;
2112
2114 //|| who->IsControlledByPlayer() && who->IsFlying()))
2115 // we cannot check flying for other creatures, too much map/vmap calculation
2117 return false;
2118
2119 if (!force)
2120 {
2121 if (!_IsTargetAcceptable(who))
2122 return false;
2123
2125 return false;
2126 }
2127
2128 if (!CanCreatureAttack(who, force))
2129 return false;
2130
2131 // No aggro from gray creatures
2133 return false;
2134
2135 return IsWithinLOSInMap(who);
2136}
2137
2138bool Creature::CheckNoGrayAggroConfig(uint32 playerLevel, uint32 creatureLevel) const
2139{
2140 if (Trinity::XP::GetColorCode(playerLevel, creatureLevel) != XP_GRAY)
2141 return false;
2142
2143 uint32 notAbove = sWorld->getIntConfig(CONFIG_NO_GRAY_AGGRO_ABOVE);
2144 uint32 notBelow = sWorld->getIntConfig(CONFIG_NO_GRAY_AGGRO_BELOW);
2145 if (notAbove == 0 && notBelow == 0)
2146 return false;
2147
2148 if (playerLevel <= notBelow || (playerLevel >= notAbove && notAbove > 0))
2149 return true;
2150 return false;
2151}
2152
2153float Creature::GetAttackDistance(Unit const* player) const
2154{
2155 float aggroRate = sWorld->getRate(RATE_CREATURE_AGGRO);
2156 if (aggroRate == 0)
2157 return 0.0f;
2158
2159 // WoW Wiki: the minimum radius seems to be 5 yards, while the maximum range is 45 yards
2160 float maxRadius = 45.0f * aggroRate;
2161 float minRadius = 5.0f * aggroRate;
2162
2163 int32 expansionMaxLevel = int32(GetMaxLevelForExpansion(GetCreatureTemplate()->RequiredExpansion));
2164 int32 playerLevel = player->GetLevelForTarget(this);
2165 int32 creatureLevel = GetLevelForTarget(player);
2166 int32 levelDifference = creatureLevel - playerLevel;
2167
2168 // The aggro radius for creatures with equal level as the player is 20 yards.
2169 // The combatreach should not get taken into account for the distance so we drop it from the range (see Supremus as expample)
2170 float baseAggroDistance = 20.0f - GetCombatReach();
2171
2172 // + - 1 yard for each level difference between player and creature
2173 float aggroRadius = baseAggroDistance + float(levelDifference);
2174
2175 // detect range auras
2176 if (uint32(creatureLevel + 5) <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
2177 {
2180 }
2181
2182 // The aggro range of creatures with higher levels than the total player level for the expansion should get the maxlevel treatment
2183 // This makes sure that creatures such as bosses wont have a bigger aggro range than the rest of the npc's
2184 // The following code is used for blizzlike behaviour such as skippable bosses
2185 if (creatureLevel > expansionMaxLevel)
2186 aggroRadius = baseAggroDistance + float(expansionMaxLevel - playerLevel);
2187
2188 // Make sure that we wont go over the total range limits
2189 if (aggroRadius > maxRadius)
2190 aggroRadius = maxRadius;
2191 else if (aggroRadius < minRadius)
2192 aggroRadius = minRadius;
2193
2194 return (aggroRadius * aggroRate);
2195}
2196
2198{
2200
2201 if (s == JUST_DIED)
2202 {
2204
2205 uint32 respawnDelay = m_respawnDelay;
2206 if (uint32 scalingMode = sWorld->getIntConfig(CONFIG_RESPAWN_DYNAMICMODE))
2207 GetMap()->ApplyDynamicModeRespawnScaling(this, m_spawnId, respawnDelay, scalingMode);
2208
2209 // @todo remove the boss respawn time hack in a dynspawn follow-up once we have creature groups in instances
2211 {
2212 if (IsDungeonBoss() && !m_respawnDelay)
2213 m_respawnTime = std::numeric_limits<time_t>::max(); // never respawn in this instance
2214 else
2216 }
2217 else
2218 {
2219 if (IsDungeonBoss() && !m_respawnDelay)
2220 m_respawnTime = std::numeric_limits<time_t>::max(); // never respawn in this instance
2221 else
2222 m_respawnTime = GameTime::GetGameTime() + respawnDelay;
2223 }
2224
2226
2227 ReleaseSpellFocus(nullptr, false); // remove spellcast focus
2228 DoNotReacquireSpellFocusTarget(); // cancel delayed re-target
2229 SetTarget(ObjectGuid::Empty); // drop target - dead mobs shouldn't ever target things
2230
2233
2234 SetMountDisplayId(0); // if creature is mounted on a virtual mount, remove it at death
2235
2236 setActive(false);
2237
2238 SetNoSearchAssistance(false);
2239
2240 //Dismiss group if is leader
2241 if (m_formation && m_formation->GetLeader() == this)
2243
2244 bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater() && !HasUnitState(UNIT_STATE_ROOT);
2245 SetHover(false, false);
2246 SetDisableGravity(false, false);
2247
2248 if (needsFalling)
2250
2252 }
2253 else if (s == JUST_RESPAWNED)
2254 {
2255 if (IsPet())
2256 SetFullHealth();
2257 else
2259
2260 SetTappedBy(nullptr);
2262
2263 SetCannotReachTarget(false);
2265
2267
2268 if (!IsPet())
2269 {
2271 CreatureTemplate const* cInfo = GetCreatureTemplate();
2272
2273 uint64 npcFlags;
2274 uint32 unitFlags, unitFlags2, unitFlags3;
2275 ObjectMgr::ChooseCreatureFlags(cInfo, &npcFlags, &unitFlags, &unitFlags2, &unitFlags3, _staticFlags, creatureData);
2276
2278 npcFlags |= sGameEventMgr->GetNPCFlag(this);
2279
2280 ReplaceAllNpcFlags(NPCFlags(npcFlags & 0xFFFFFFFF));
2281 ReplaceAllNpcFlags2(NPCFlags2(npcFlags >> 32));
2282
2283 ReplaceAllUnitFlags(UnitFlags(unitFlags));
2284 ReplaceAllUnitFlags2(UnitFlags2(unitFlags2));
2285 ReplaceAllUnitFlags3(UnitFlags3(unitFlags3));
2287
2289
2291
2292 if (uint32 vignetteId = cInfo->VignetteID)
2293 SetVignette(vignetteId);
2294 }
2295
2300 }
2301}
2302
2303void Creature::Respawn(bool force)
2304{
2305 if (force)
2306 {
2307 if (IsAlive())
2309 else if (getDeathState() != CORPSE)
2311 }
2312
2314 {
2316 RemoveCorpse(false, false);
2317
2318 if (getDeathState() == DEAD)
2319 {
2320 TC_LOG_DEBUG("entities.unit", "Respawning creature {} ({})", GetName(), GetGUID().ToString());
2321 m_respawnTime = 0;
2323 m_loot = nullptr;
2324
2325 if (m_originalEntry != GetEntry())
2327
2328 SelectLevel();
2329
2331
2333 if (sObjectMgr->GetCreatureModelRandomGender(&display, GetCreatureTemplate()))
2334 SetDisplayId(display.CreatureDisplayID, true);
2335
2337
2338 // Re-initialize reactstate that could be altered by movementgenerators
2340
2341 if (UnitAI* ai = AI()) // reset the AI to be sure no dirty or uninitialized values will be used till next tick
2342 ai->Reset();
2343
2344 m_triggerJustAppeared = true;
2345
2346 uint32 poolid = GetCreatureData() ? GetCreatureData()->poolId : 0;
2347 if (poolid)
2348 sPoolMgr->UpdatePool<Creature>(GetMap()->GetPoolData(), poolid, GetSpawnId());
2349 }
2351 }
2352 else
2353 {
2354 if (m_spawnId)
2356 }
2357
2358 TC_LOG_DEBUG("entities.unit", "Respawning creature {} ({})",
2359 GetName(), GetGUID().ToString());
2360
2361}
2362
2363void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
2364{
2365 if (timeMSToDespawn)
2366 {
2367 m_Events.AddEvent(new ForcedDespawnDelayEvent(*this, forceRespawnTimer), m_Events.CalculateTime(Milliseconds(timeMSToDespawn)));
2368 return;
2369 }
2370
2372 {
2373 uint32 corpseDelay = GetCorpseDelay();
2374 uint32 respawnDelay = GetRespawnDelay();
2375
2376 // do it before killing creature
2378
2379 bool overrideRespawnTime = false;
2380 if (IsAlive())
2381 {
2382 if (forceRespawnTimer > Seconds::zero())
2383 {
2384 SetCorpseDelay(0);
2385 SetRespawnDelay(forceRespawnTimer.count());
2386 overrideRespawnTime = true;
2387 }
2388
2390 }
2391
2392 // Skip corpse decay time
2393 RemoveCorpse(!overrideRespawnTime, false);
2394
2395 SetCorpseDelay(corpseDelay);
2396 SetRespawnDelay(respawnDelay);
2397 }
2398 else
2399 {
2400 if (forceRespawnTimer > Seconds::zero())
2401 SaveRespawnTime(forceRespawnTimer.count());
2402 else
2403 {
2404 uint32 respawnDelay = m_respawnDelay;
2405 if (uint32 scalingMode = sWorld->getIntConfig(CONFIG_RESPAWN_DYNAMICMODE))
2406 GetMap()->ApplyDynamicModeRespawnScaling(this, m_spawnId, respawnDelay, scalingMode);
2407 m_respawnTime = GameTime::GetGameTime() + respawnDelay;
2409 }
2410
2412 }
2413}
2414
2415void Creature::DespawnOrUnsummon(Milliseconds timeToDespawn /*= 0s*/, Seconds forceRespawnTimer /*= 0s*/)
2416{
2417 if (TempSummon* summon = ToTempSummon())
2418 summon->UnSummon(timeToDespawn.count());
2419 else
2420 ForcedDespawn(timeToDespawn.count(), forceRespawnTimer);
2421}
2422
2423void Creature::LoadTemplateImmunities(int32 creatureImmunitiesId)
2424{
2425 // uint32 max used for "spell id", the immunity system will not perform SpellInfo checks against invalid spells
2426 // used so we know which immunities were loaded from template
2427 static uint32 constexpr placeholderSpellId = std::numeric_limits<uint32>::max();
2428
2429 auto applyCreatureImmunities = [this](CreatureImmunities const* immunities, bool apply)
2430 {
2431 for (std::size_t i = 0; i < immunities->School.size(); ++i)
2432 if (immunities->School[i])
2433 ApplySpellImmune(placeholderSpellId, IMMUNITY_SCHOOL, 1 << i, apply);
2434
2435 for (std::size_t i = 0; i < immunities->DispelType.size(); ++i)
2436 if (immunities->DispelType[i])
2437 ApplySpellImmune(placeholderSpellId, IMMUNITY_DISPEL, i, apply);
2438
2439 for (std::size_t i = 0; i < immunities->Mechanic.size(); ++i)
2440 if (immunities->Mechanic[i])
2441 ApplySpellImmune(placeholderSpellId, IMMUNITY_MECHANIC, i, apply);
2442
2443 for (SpellEffectName effect : immunities->Effect)
2444 ApplySpellImmune(placeholderSpellId, IMMUNITY_EFFECT, effect, apply);
2445
2446 for (AuraType aura : immunities->Aura)
2447 ApplySpellImmune(placeholderSpellId, IMMUNITY_STATE, aura, apply);
2448
2449 if (immunities->Other != SpellOtherImmunity::None)
2450 ApplySpellImmune(placeholderSpellId, IMMUNITY_OTHER, immunities->Other.AsUnderlyingType(), apply);
2451 };
2452
2453 // unapply template immunities (in case we're updating entry)
2455 applyCreatureImmunities(immunities, false);
2456
2457 // apply new immunities
2458 if (CreatureImmunities const* immunities = SpellMgr::GetCreatureImmunities(creatureImmunitiesId))
2459 {
2460 _creatureImmunitiesId = creatureImmunitiesId;
2461 applyCreatureImmunities(immunities, true);
2462 }
2463 else
2465}
2466
2467bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster,
2468 bool requireImmunityPurgesEffectAttribute /*= false*/) const
2469{
2471 return true;
2472
2473 return Unit::IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute);
2474}
2475
2477{
2478 if (IsPet())
2479 return false;
2480
2482}
2483
2485{
2486 if (IsPet())
2487 return false;
2488
2489 return (GetCreatureDifficulty()->TypeFlags & CREATURE_TYPE_FLAG_BOSS_MOB) != 0;
2490}
2491
2492// select nearest hostile unit within the given distance (regardless of threat list).
2493Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const
2494{
2495 if (dist == 0.0f)
2497
2498 Unit* target = nullptr;
2499 Trinity::NearestHostileUnitCheck u_check(this, dist, playerOnly);
2501 Cell::VisitAllObjects(this, searcher, dist);
2502 return target;
2503}
2504
2505// select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list.
2507{
2508 if (dist > MAX_VISIBILITY_DISTANCE)
2509 {
2510 TC_LOG_ERROR("entities.unit", "Creature {} SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUID().ToString());
2511 dist = ATTACK_DISTANCE;
2512 }
2513
2514 Unit* target = nullptr;
2517 Cell::VisitAllObjects(this, searcher, std::max(dist, ATTACK_DISTANCE));
2518 return target;
2519}
2520
2522{
2524
2525 packet.UnitGUID = GetGUID();
2526 packet.Reaction = reactionType;
2527
2528 SendMessageToSet(packet.Write(), true);
2529
2530 TC_LOG_DEBUG("network", "WORLD: Sent SMSG_AI_REACTION, type {}.", reactionType);
2531}
2532
2534{
2535 if (!m_AlreadyCallAssistance && GetVictim() && !IsPet() && !IsCharmed())
2536 {
2537 SetNoCallAssistance(true);
2538
2539 float radius = sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
2540
2541 if (radius > 0)
2542 {
2543 std::list<Creature*> assistList;
2544 Trinity::AnyAssistCreatureInRangeCheck u_check(this, GetVictim(), radius);
2546 Cell::VisitGridObjects(this, searcher, radius);
2547
2548 if (!assistList.empty())
2549 {
2551 while (!assistList.empty())
2552 {
2553 // Pushing guids because in delay can happen some creature gets despawned => invalid pointer
2554 e->AddAssistant((*assistList.begin())->GetGUID());
2555 assistList.pop_front();
2556 }
2558 }
2559 }
2560 }
2561}
2562
2563void Creature::CallForHelp(float radius)
2564{
2565 if (radius <= 0.0f || !IsEngaged() || !IsAlive() || IsPet() || IsCharmed())
2566 return;
2567
2569 if (!target)
2570 target = GetThreatManager().GetAnyTarget();
2571 if (!target)
2572 target = GetCombatManager().GetAnyTarget();
2573
2574 if (!target)
2575 {
2576 TC_LOG_ERROR("entities.unit", "Creature {} ({}) trying to call for help without being in combat.", GetEntry(), GetName());
2577 return;
2578 }
2579
2580 Trinity::CallOfHelpCreatureInRangeDo u_do(this, target, radius);
2582 Cell::VisitGridObjects(this, worker, radius);
2583}
2584
2585bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /*= true*/) const
2586{
2587 // is it true?
2589 return false;
2590
2591 // we don't need help from zombies :)
2592 if (!IsAlive())
2593 return false;
2594
2595 // we cannot assist in evade mode
2596 if (IsInEvadeMode())
2597 return false;
2598
2599 // or if enemy is in evade mode
2600 if (enemy->GetTypeId() == TYPEID_UNIT && enemy->ToCreature()->IsInEvadeMode())
2601 return false;
2602
2603 // we don't need help from non-combatant ;)
2604 if (IsCivilian())
2605 return false;
2606
2608 return false;
2609
2610 // skip fighting creature
2611 if (IsEngaged())
2612 return false;
2613
2614 // only free creature
2615 if (!GetCharmerOrOwnerGUID().IsEmpty())
2616 return false;
2617
2618 // only from same creature faction
2619 if (checkfaction)
2620 {
2621 if (GetFaction() != u->GetFaction())
2622 return false;
2623 }
2624 else
2625 {
2626 if (!IsFriendlyTo(u))
2627 return false;
2628 }
2629
2630 // skip non hostile to caster enemy creatures
2631 if (!IsHostileTo(enemy))
2632 return false;
2633
2634 return true;
2635}
2636
2637// use this function to avoid having hostile creatures attack
2638// friendlies and other mobs they shouldn't attack
2639bool Creature::_IsTargetAcceptable(Unit const* target) const
2640{
2641 ASSERT(target);
2642
2643 // if the target cannot be attacked, the target is not acceptable
2644 if (IsFriendlyTo(target)
2645 || !target->isTargetableForAttack(false)
2646 || (m_vehicle && (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))))
2647 return false;
2648
2649 if (target->HasUnitState(UNIT_STATE_DIED))
2650 {
2651 // some creatures can detect fake death
2653 return true;
2654 else
2655 return false;
2656 }
2657
2658 // if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
2659 if (IsEngagedBy(target) || IsHostileTo(target))
2660 return true;
2661
2662 // if the target's victim is not friendly, or the target is friendly, the target is not acceptable
2663 return false;
2664}
2665
2667{
2669 return;
2670
2672 {
2673 RespawnInfo ri;
2675 ri.spawnId = m_spawnId;
2678 return;
2679 }
2680
2681 time_t thisRespawnTime = forceDelay ? GameTime::GetGameTime() + forceDelay : m_respawnTime;
2683}
2684
2685// this should not be called by petAI or
2686bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
2687{
2688 if (!victim->IsInMap(this))
2689 return false;
2690
2691 if (!IsValidAttackTarget(victim))
2692 return false;
2693
2694 if (!victim->isInAccessiblePlaceFor(this))
2695 return false;
2696
2697 if (CreatureAI* ai = AI())
2698 if (!ai->CanAIAttack(victim))
2699 return false;
2700
2701 // we cannot attack in evade mode
2702 if (IsInEvadeMode())
2703 return false;
2704
2705 // or if enemy is in evade mode
2706 if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
2707 return false;
2708
2710 {
2711 if (GetMap()->IsDungeon())
2712 return true;
2713
2714 // don't check distance to home position if recently damaged, this should include taunt auras
2716 return true;
2717 }
2718
2719 // Map visibility range, but no more than 2*cell size
2720 float dist = std::min<float>(GetMap()->GetVisibilityRange(), SIZE_OF_GRID_CELL * 2);
2721
2722 if (Unit* unit = GetCharmerOrOwner())
2723 return victim->IsWithinDist(unit, dist);
2724 else
2725 {
2726 // include sizes for huge npcs
2727 dist += GetCombatReach() + victim->GetCombatReach();
2728
2729 // to prevent creatures in air ignore attacks because distance is already too high...
2730 if (CanFly())
2731 return victim->IsInDist2d(&m_homePosition, dist);
2732 else
2733 return victim->IsInDist(&m_homePosition, dist);
2734 }
2735}
2736
2738{
2739 if (m_spawnId)
2740 {
2741 if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_spawnId))
2742 return addon;
2743 }
2744
2745 return sObjectMgr->GetCreatureTemplateAddon(GetEntry());
2746}
2747
2748//creature_addon table
2750{
2751 CreatureAddon const* creatureAddon = GetCreatureAddon();
2752 if (!creatureAddon)
2753 return false;
2754
2755 if (uint32 mountDisplayId = _defaultMountDisplayIdOverride.value_or(creatureAddon->mount); mountDisplayId != 0)
2756 Mount(mountDisplayId);
2757
2759 ReplaceAllVisFlags(UnitVisFlags(creatureAddon->visFlags));
2760 SetAnimTier(AnimTier(creatureAddon->animTier), false);
2761
2762 SetSheath(SheathState(creatureAddon->sheathState));
2764
2765 // These fields must only be handled by core internals and must not be modified via scripts/DB dat
2768
2769 if (creatureAddon->emote != 0)
2770 SetEmoteState(Emote(creatureAddon->emote));
2771
2772 SetAIAnimKitId(creatureAddon->aiAnimKit);
2773 SetMovementAnimKitId(creatureAddon->movementAnimKit);
2774 SetMeleeAnimKitId(creatureAddon->meleeAnimKit);
2775
2776 // Check if visibility distance different
2779
2780 // Load Path
2781 if (creatureAddon->PathId != 0)
2782 _waypointPathId = creatureAddon->PathId;
2783
2784 if (!creatureAddon->auras.empty())
2785 {
2786 for (std::vector<uint32>::const_iterator itr = creatureAddon->auras.begin(); itr != creatureAddon->auras.end(); ++itr)
2787 {
2788 SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(*itr, GetMap()->GetDifficultyID());
2789 if (!AdditionalSpellInfo)
2790 {
2791 TC_LOG_ERROR("sql.sql", "Creature {} has wrong spell {} defined in `auras` field.", GetGUID().ToString(), *itr);
2792 continue;
2793 }
2794
2795 // skip already applied aura
2796 if (HasAura(*itr))
2797 continue;
2798
2799 AddAura(*itr, this);
2800 TC_LOG_DEBUG("entities.unit", "Spell: {} added to creature {}", *itr, GetGUID().ToString());
2801 }
2802 }
2803 return true;
2804}
2805
2806void Creature::LoadCreaturesSparringHealth(bool force /*= false*/)
2807{
2808 if (std::vector<float> const* templateValues = sObjectMgr->GetCreatureTemplateSparringValues(GetCreatureTemplate()->Entry))
2809 if (force || std::find(templateValues->begin(), templateValues->end(), _sparringHealthPct) != templateValues->end()) // only re-randomize sparring value if it was loaded from template (not when set to custom value from script)
2811}
2812
2815{
2816 uint32 enemy_team = attacker->GetTeam();
2818 packet.AreaID = GetAreaId();
2819 sWorld->SendGlobalMessage(packet.Write(), nullptr, (enemy_team == ALLIANCE ? HORDE : ALLIANCE));
2820}
2821
2822void Creature::SetCanMelee(bool canMelee, bool fleeFromMelee /*= false*/)
2823{
2824 bool wasFleeingFromMelee = HasFlag(CREATURE_STATIC_FLAG_NO_MELEE_FLEE);
2825
2826 _staticFlags.ApplyFlag(CREATURE_STATIC_FLAG_NO_MELEE_FLEE, !canMelee && fleeFromMelee);
2828
2829 if (wasFleeingFromMelee == HasFlag(CREATURE_STATIC_FLAG_NO_MELEE_FLEE))
2830 return;
2831
2832 Unit* victim = GetVictim();
2833 if (!victim)
2834 return;
2835
2837 if (!currentMovement)
2838 return;
2839
2840 bool canChangeMovement = [&]
2841 {
2842 if (wasFleeingFromMelee)
2844
2845 return currentMovement->GetMovementGeneratorType() == CHASE_MOTION_TYPE;
2846 }();
2847
2848 if (!canChangeMovement)
2849 return;
2850
2851 GetMotionMaster()->Remove(currentMovement);
2853}
2854
2856{
2858 GetMotionMaster()->MoveChase(victim, range, angle);
2859 else
2860 GetMotionMaster()->MoveFleeing(victim);
2861}
2862
2863bool Creature::HasSpell(uint32 spellID) const
2864{
2865 return std::find(std::begin(m_spells), std::end(m_spells), spellID) != std::end(m_spells);
2866}
2867
2869{
2870 time_t now = GameTime::GetGameTime();
2871 if (m_respawnTime > now)
2872 return m_respawnTime;
2873 else
2874 return now;
2875}
2876
2878{
2879 m_respawnTime = respawn ? GameTime::GetGameTime() + respawn : 0;
2880}
2881
2882void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, float* dist) const
2883{
2884 if (m_creatureData)
2885 {
2886 if (ori)
2887 m_creatureData->spawnPoint.GetPosition(x, y, z, *ori);
2888 else
2890
2891 if (dist)
2893 }
2894 else
2895 {
2896 Position const& homePos = GetHomePosition();
2897 if (ori)
2898 homePos.GetPosition(x, y, z, *ori);
2899 else
2900 homePos.GetPosition(x, y, z);
2901 if (dist)
2902 *dist = 0;
2903 }
2904}
2905
2907{
2908 SetHover(GetMovementTemplate().IsHoverInitiallyEnabled());
2911
2912 // If an amphibious creatures was swimming while engaged, disable swimming again
2915
2917}
2918
2920{
2921 // Do not update movement flags if creature is controlled by a player (charm/vehicle)
2922 if (m_playerMovingMe)
2923 return;
2924
2925 // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
2926 float ground = GetFloorZ();
2927 bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + GetHoverOffset() + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling
2928 if (!isInAir)
2930
2931 // Some Amphibious creatures toggle swimming while engaged
2933 if (!IsSwimPrevented() || (GetVictim() && !GetVictim()->IsOnOceanFloor()))
2935
2936 SetSwim(IsInWater() && CanSwim());
2937}
2938
2940{
2941 if (CreatureMovementData const* movementOverride = sObjectMgr->GetCreatureMovementOverride(m_spawnId))
2942 return *movementOverride;
2943
2944 return GetCreatureTemplate()->Movement;
2945}
2946
2948{
2949 if (Unit::CanSwim())
2950 return true;
2951
2952 if (IsPet())
2953 return true;
2954
2955 return false;
2956}
2957
2959{
2960 time_t now = GameTime::GetGameTime();
2961 // Do not reset corpse remove time if corpse is already removed
2962 if (m_corpseRemoveTime <= now)
2963 return;
2964
2965 // Scripts can choose to ignore RATE_CORPSE_DECAY_LOOTED by calling SetCorpseDelay(timer, true)
2966 float decayRate = m_ignoreCorpseDecayRatio ? 1.f : sWorld->getRate(RATE_CORPSE_DECAY_LOOTED);
2967
2968 // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
2969 bool isFullySkinned = [&]() -> bool
2970 {
2971 if (m_loot && m_loot->loot_type == LOOT_SKINNING && m_loot->isLooted())
2972 return true;
2973
2974 bool hasSkinningLoot = false;
2975 for (auto const& [_, loot] : m_personalLoot)
2976 {
2977 if (loot->loot_type == LOOT_SKINNING)
2978 {
2979 if (!loot->isLooted())
2980 return false;
2981
2982 hasSkinningLoot = true;
2983 }
2984 }
2985
2986 return hasSkinningLoot;
2987 }();
2988
2989 if (isFullySkinned)
2990 m_corpseRemoveTime = now;
2991 else
2992 m_corpseRemoveTime = now + uint32(m_corpseDelay * decayRate);
2993
2995}
2996
2998{
3000 Unit::SetInteractionAllowedWhileHostile(interactionAllowed);
3001}
3002
3003void Creature::SetInteractionAllowedInCombat(bool interactionAllowed)
3004{
3006 Unit::SetInteractionAllowedInCombat(interactionAllowed);
3007}
3008
3010{
3012
3013 // If as a result of npcflag updates we stop seeing UNIT_NPC_FLAG_QUESTGIVER then
3014 // we must also send SMSG_QUEST_GIVER_STATUS_MULTIPLE because client will not request it automatically
3015 if (IsQuestGiver())
3016 {
3017 auto sender = [&](Player const* receiver)
3018 {
3019 receiver->PlayerTalkClass->SendQuestGiverStatus(receiver->GetQuestDialogStatus(this), GetGUID());
3020 };
3021 Trinity::MessageDistDeliverer notifier(this, sender, GetVisibilityRange());
3023 }
3024}
3025
3027{
3028 return m_unitData->ContentTuningID != 0;
3029}
3030
3032{
3033 CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty();
3034
3035 if (Optional<ContentTuningLevels> levels = sDB2Manager.GetContentTuningData(creatureDifficulty->ContentTuningID, 0))
3036 {
3039 }
3040
3041 int32 mindelta = std::min(creatureDifficulty->DeltaLevelMax, creatureDifficulty->DeltaLevelMin);
3042 int32 maxdelta = std::max(creatureDifficulty->DeltaLevelMax, creatureDifficulty->DeltaLevelMin);
3043 int32 delta = mindelta == maxdelta ? mindelta : irand(mindelta, maxdelta);
3044
3047}
3048
3050{
3051 CreatureTemplate const* cInfo = GetCreatureTemplate();
3052 CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty();
3053 float baseHealth = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureHealth, level, creatureDifficulty->GetHealthScalingExpansion(), creatureDifficulty->ContentTuningID, Classes(cInfo->unit_class), 0);
3054 return std::max(baseHealth * creatureDifficulty->HealthModifier, 1.0f);
3055}
3056
3058{
3059 if (!HasScalableLevels())
3060 return 1.0f;
3061
3062 uint8 levelForTarget = GetLevelForTarget(target);
3063 if (GetLevel() < levelForTarget)
3064 return 1.0f;
3065
3066 return double(GetMaxHealthByLevel(levelForTarget)) / double(GetCreateHealth());
3067}
3068
3070{
3071 CreatureTemplate const* cInfo = GetCreatureTemplate();
3072 CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty();
3073 return sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureAutoAttackDps, level, creatureDifficulty->GetHealthScalingExpansion(), creatureDifficulty->ContentTuningID, Classes(cInfo->unit_class), 0);
3074}
3075
3077{
3078 if (!HasScalableLevels())
3079 return 1.0f;
3080
3081 uint8 levelForTarget = GetLevelForTarget(target);
3082
3083 return GetBaseDamageForLevel(levelForTarget) / GetBaseDamageForLevel(GetLevel());
3084}
3085
3087{
3088 CreatureTemplate const* cInfo = GetCreatureTemplate();
3089 CreatureDifficulty const* creatureDifficulty = GetCreatureDifficulty();
3090 float baseArmor = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::CreatureArmor, level, creatureDifficulty->GetHealthScalingExpansion(), creatureDifficulty->ContentTuningID, Classes(cInfo->unit_class), 0);
3091 return baseArmor * creatureDifficulty->ArmorModifier;
3092}
3093
3095{
3096 if (!HasScalableLevels())
3097 return 1.0f;
3098
3099 uint8 levelForTarget = GetLevelForTarget(target);
3100
3101 return GetBaseArmorForLevel(levelForTarget) / GetBaseArmorForLevel(GetLevel());
3102}
3103
3105{
3106 if (Unit const* unitTarget = target->ToUnit())
3107 {
3108 if (isWorldBoss())
3109 {
3110 uint8 level = unitTarget->GetLevel() + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF);
3111 return RoundToInterval<uint8>(level, 1u, 255u);
3112 }
3113
3114 // If this creature should scale level, adapt level depending of target level
3115 // between UNIT_FIELD_SCALING_LEVEL_MIN and UNIT_FIELD_SCALING_LEVEL_MAX
3116 if (HasScalableLevels())
3117 {
3118 int32 scalingLevelMin = m_unitData->ScalingLevelMin;
3119 int32 scalingLevelMax = m_unitData->ScalingLevelMax;
3120 int32 scalingLevelDelta = m_unitData->ScalingLevelDelta;
3121 int32 scalingFactionGroup = m_unitData->ScalingFactionGroup;
3122 int32 targetLevel = unitTarget->m_unitData->EffectiveLevel;
3123 if (!targetLevel)
3124 targetLevel = unitTarget->GetLevel();
3125
3126 int32 targetLevelDelta = 0;
3127
3128 if (Player const* playerTarget = target->ToPlayer())
3129 {
3130 if (scalingFactionGroup && sFactionTemplateStore.AssertEntry(sChrRacesStore.AssertEntry(playerTarget->GetRace())->FactionID)->FactionGroup != scalingFactionGroup)
3131 scalingLevelMin = scalingLevelMax;
3132
3133 int32 maxCreatureScalingLevel = playerTarget->m_activePlayerData->MaxCreatureScalingLevel;
3134 targetLevelDelta = std::min(maxCreatureScalingLevel > 0 ? maxCreatureScalingLevel - targetLevel : 0, *playerTarget->m_activePlayerData->ScalingPlayerLevelDelta);
3135 }
3136
3137 int32 levelWithDelta = targetLevel + targetLevelDelta;
3138 int32 level = RoundToInterval(levelWithDelta, scalingLevelMin, scalingLevelMax) + scalingLevelDelta;
3139 return RoundToInterval(level, 1, MAX_LEVEL + 3);
3140 }
3141 }
3142
3143 return Unit::GetLevelForTarget(target);
3144}
3145
3146std::string const& Creature::GetAIName() const
3147{
3148 return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName;
3149}
3150
3151std::string Creature::GetScriptName() const
3152{
3153 return sObjectMgr->GetScriptName(GetScriptId());
3154}
3155
3157{
3159 if (uint32 scriptId = creatureData->scriptId)
3160 return scriptId;
3161
3162 return ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(GetEntry()))->ScriptID;
3163}
3164
3165bool Creature::HasStringId(std::string_view id) const
3166{
3167 return std::find(m_stringIds.begin(), m_stringIds.end(), id) != m_stringIds.end();
3168}
3169
3171{
3172 if (!id.empty())
3173 {
3174 m_scriptStringId.emplace(std::move(id));
3176 }
3177 else
3178 {
3179 m_scriptStringId.reset();
3180 m_stringIds[2] = {};
3181 }
3182}
3183
3185{
3186 return sObjectMgr->GetNpcVendorItemList(GetEntry());
3187}
3188
3190{
3191 if (!vItem->maxcount)
3192 return vItem->maxcount;
3193
3194 VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
3195 for (; itr != m_vendorItemCounts.end(); ++itr)
3196 if (itr->itemId == vItem->item)
3197 break;
3198
3199 if (itr == m_vendorItemCounts.end())
3200 return vItem->maxcount;
3201
3202 VendorItemCount* vCount = &*itr;
3203
3204 time_t ptime = GameTime::GetGameTime();
3205
3206 if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime)
3207 if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item))
3208 {
3209 uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
3210 if ((vCount->count + diff * pProto->GetBuyCount()) >= vItem->maxcount)
3211 {
3212 m_vendorItemCounts.erase(itr);
3213 return vItem->maxcount;
3214 }
3215
3216 vCount->count += diff * pProto->GetBuyCount();
3217 vCount->lastIncrementTime = ptime;
3218 }
3219
3220 return vCount->count;
3221}
3222
3224{
3225 if (!vItem->maxcount)
3226 return 0;
3227
3228 VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
3229 for (; itr != m_vendorItemCounts.end(); ++itr)
3230 if (itr->itemId == vItem->item)
3231 break;
3232
3233 if (itr == m_vendorItemCounts.end())
3234 {
3235 uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount-used_count : 0;
3236 m_vendorItemCounts.push_back(VendorItemCount(vItem->item, new_count));
3237 return new_count;
3238 }
3239
3240 VendorItemCount* vCount = &*itr;
3241
3242 time_t ptime = GameTime::GetGameTime();
3243
3244 if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime)
3245 if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item))
3246 {
3247 uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
3248 if ((vCount->count + diff * pProto->GetBuyCount()) < vItem->maxcount)
3249 vCount->count += diff * pProto->GetBuyCount();
3250 else
3251 vCount->count = vItem->maxcount;
3252 }
3253
3254 vCount->count = vCount->count > used_count ? vCount->count-used_count : 0;
3255 vCount->lastIncrementTime = ptime;
3256 return vCount->count;
3257}
3258
3259// overwrite WorldObject function for proper name localization
3261{
3262 if (locale != DEFAULT_LOCALE)
3263 if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(GetEntry()))
3264 if (cl->Name.size() > locale && !cl->Name[locale].empty())
3265 return cl->Name[locale];
3266
3267 return GetName();
3268}
3269
3271{
3272 return MAX_SPELL_CHARM;
3273}
3274
3276{
3277 if (pos >= MAX_SPELL_CHARM || !m_charmInfo || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED)
3278 return 0;
3279 else
3280 return m_charmInfo->GetCharmSpell(pos)->GetAction();
3281}
3282
3284{
3285 float range = 0.f;
3286
3287 for (uint8 i = 0; i < GetPetAutoSpellSize(); ++i)
3288 {
3289 uint32 spellID = GetPetAutoSpellOnPos(i);
3290 if (!spellID)
3291 continue;
3292
3293 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID, GetMap()->GetDifficultyID()))
3294 {
3295 if (spellInfo->GetRecoveryTime() == 0 && spellInfo->RangeEntry && spellInfo->RangeEntry->ID != 1 /*Self*/ && spellInfo->RangeEntry->ID != 2 /*Combat Range*/ && spellInfo->GetMaxRange() > range)
3296 range = spellInfo->GetMaxRange();
3297 }
3298 }
3299
3300 return range;
3301}
3302
3304{
3305 if (cannotReach == m_cannotReachTarget)
3306 return;
3307 m_cannotReachTarget = cannotReach;
3309
3310 if (cannotReach)
3311 TC_LOG_DEBUG("entities.unit.chase", "Creature::SetCannotReachTarget() called with true. Details: {}", GetDebugInfo());
3312}
3313
3315{
3316 if (mountCreatureDisplayId && !sCreatureDisplayInfoStore.HasRecord(*mountCreatureDisplayId))
3317 mountCreatureDisplayId.reset();
3318
3319 _defaultMountDisplayIdOverride = mountCreatureDisplayId;
3320}
3321
3322float Creature::GetAggroRange(Unit const* target) const
3323{
3324 // Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
3325 // Based on data from wowwiki due to lack of 3.3.5a data
3326
3327 if (target && IsPet())
3328 {
3329 uint32 targetLevel = 0;
3330
3331 if (target->GetTypeId() == TYPEID_PLAYER)
3332 targetLevel = target->GetLevelForTarget(this);
3333 else if (target->GetTypeId() == TYPEID_UNIT)
3334 targetLevel = target->ToCreature()->GetLevelForTarget(this);
3335
3336 uint32 myLevel = GetLevelForTarget(target);
3337 int32 levelDiff = int32(targetLevel) - int32(myLevel);
3338
3339 // The maximum Aggro Radius is capped at 45 yards (25 level difference)
3340 if (levelDiff < -25)
3341 levelDiff = -25;
3342
3343 // The base aggro radius for mob of same level
3344 float aggroRadius = 20;
3345
3346 // Aggro Radius varies with level difference at a rate of roughly 1 yard/level
3347 aggroRadius -= (float)levelDiff;
3348
3349 // detect range auras
3351
3352 // detected range auras
3354
3355 // Just in case, we don't want pets running all over the map
3356 if (aggroRadius > MAX_AGGRO_RADIUS)
3357 aggroRadius = MAX_AGGRO_RADIUS;
3358
3359 // Minimum Aggro Radius for a mob seems to be combat range (5 yards)
3360 // hunter pets seem to ignore minimum aggro radius so we'll default it a little higher
3361 if (aggroRadius < 10)
3362 aggroRadius = 10;
3363
3364 return (aggroRadius);
3365 }
3366
3367 // Default
3368 return 0.0f;
3369}
3370
3371Unit* Creature::SelectNearestHostileUnitInAggroRange(bool useLOS, bool ignoreCivilians) const
3372{
3373 // Selects nearest hostile target within creature's aggro range. Used primarily by
3374 // pets set to aggressive. Will not return neutral or friendly targets.
3375
3376 Unit* target = nullptr;
3377
3378 Trinity::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS, ignoreCivilians);
3380
3382
3383 return target;
3384}
3385
3387{
3388 return GetCreatureTemplate()->scale;
3389}
3390
3392{
3393 Unit::SetObjectScale(scale);
3394
3395 if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(GetDisplayId()))
3396 {
3397 SetBoundingRadius((IsPet() ? 1.0f : minfo->bounding_radius) * scale * GetDisplayScale());
3398 SetCombatReach((IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * scale * GetDisplayScale());
3399 }
3400}
3401
3402void Creature::SetDisplayId(uint32 displayId, bool setNative /*= false*/)
3403{
3404 Unit::SetDisplayId(displayId, setNative);
3405
3406 if (CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(displayId))
3407 {
3408 SetBoundingRadius((IsPet() ? 1.0f : modelInfo->bounding_radius) * GetObjectScale() * GetDisplayScale());
3409 SetCombatReach((IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : modelInfo->combat_reach) * GetObjectScale() * GetDisplayScale());
3410 }
3411}
3412
3414{
3415 if (CreatureModel const* model = GetCreatureTemplate()->GetModelByIdx(modelIdx))
3416 SetDisplayId(model->CreatureDisplayID);
3417}
3418
3420{
3421 if (HasSpellFocus())
3422 _spellFocusInfo.Target = guid;
3423 else
3425}
3426
3427void Creature::SetSpellFocus(Spell const* focusSpell, WorldObject const* target)
3428{
3429 // Pointer validation and checking for a already existing focus
3430 if (_spellFocusInfo.Spell || !focusSpell)
3431 return;
3432
3433 // Prevent dead / feign death creatures from setting a focus target
3435 return;
3436
3437 // Don't allow stunned creatures to set a focus target
3439 return;
3440
3441 // some spells shouldn't track targets
3442 if (focusSpell->IsFocusDisabled())
3443 return;
3444
3445 SpellInfo const* spellInfo = focusSpell->GetSpellInfo();
3446
3447 // don't use spell focus for vehicle spells
3448 if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
3449 return;
3450
3451 // instant non-channeled casts and non-target spells don't need facing updates
3452 if (!target && (!focusSpell->GetCastTime() && !spellInfo->IsChanneled()))
3453 return;
3454
3455 // store pre-cast values for target and orientation (used to later restore)
3456 if (!_spellFocusInfo.Delay)
3457 { // only overwrite these fields if we aren't transitioning from one spell focus to another
3458 _spellFocusInfo.Target = GetTarget();
3459 _spellFocusInfo.Orientation = GetOrientation();
3460 }
3461 else // don't automatically reacquire target for the previous spellcast
3462 _spellFocusInfo.Delay = 0;
3463
3464 _spellFocusInfo.Spell = focusSpell;
3465
3466 bool const noTurnDuringCast = spellInfo->HasAttribute(SPELL_ATTR5_AI_DOESNT_FACE_TARGET);
3467 bool const turnDisabled = CannotTurn();
3468 // set target, then force send update packet to players if it changed to provide appropriate facing
3469 ObjectGuid newTarget = (target && !noTurnDuringCast && !turnDisabled) ? target->GetGUID() : ObjectGuid::Empty;
3470 if (GetTarget() != newTarget)
3472
3473 // If we are not allowed to turn during cast but have a focus target, face the target
3474 if (!turnDisabled && noTurnDuringCast && target)
3475 SetFacingToObject(target, false);
3476
3477 if (noTurnDuringCast)
3479}
3480
3481bool Creature::HasSpellFocus(Spell const* focusSpell) const
3482{
3483 if (isDead()) // dead creatures cannot focus
3484 {
3485 if (_spellFocusInfo.Spell || _spellFocusInfo.Delay)
3486 {
3487 TC_LOG_WARN("entities.unit", "Creature '{}' (entry {}) has spell focus (spell id {}, delay {}ms) despite being dead.",
3488 GetName(), GetEntry(), _spellFocusInfo.Spell ? _spellFocusInfo.Spell->GetSpellInfo()->Id : 0, _spellFocusInfo.Delay);
3489 }
3490 return false;
3491 }
3492
3493 if (focusSpell)
3494 return (focusSpell == _spellFocusInfo.Spell);
3495 else
3496 return (_spellFocusInfo.Spell || _spellFocusInfo.Delay);
3497}
3498
3499void Creature::ReleaseSpellFocus(Spell const* focusSpell, bool withDelay)
3500{
3501 if (!_spellFocusInfo.Spell)
3502 return;
3503
3504 // focused to something else
3505 if (focusSpell && focusSpell != _spellFocusInfo.Spell)
3506 return;
3507
3508 if (_spellFocusInfo.Spell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_AI_DOESNT_FACE_TARGET))
3510
3511 if (IsPet()) // player pets do not use delay system
3512 {
3513 if (!CannotTurn())
3515 }
3516 else // don't allow re-target right away to prevent visual bugs
3517 _spellFocusInfo.Delay = withDelay ? 1000 : 1;
3518
3519 _spellFocusInfo.Spell = nullptr;
3520}
3521
3523{
3524 if (!HasSpellFocus())
3525 {
3526 TC_LOG_ERROR("entities.unit", "Creature::ReacquireSpellFocusTarget() being called with HasSpellFocus() returning false. {}", GetDebugInfo());
3527 return;
3528 }
3529
3531
3532 if (!CannotTurn())
3533 {
3534 if (!_spellFocusInfo.Target.IsEmpty())
3535 {
3536 if (WorldObject const* objTarget = ObjectAccessor::GetWorldObject(*this, _spellFocusInfo.Target))
3537 SetFacingToObject(objTarget, false);
3538 }
3539 else
3540 SetFacingTo(_spellFocusInfo.Orientation, false);
3541 }
3542 _spellFocusInfo.Delay = 0;
3543}
3544
3546{
3547 _spellFocusInfo.Delay = 0;
3548 _spellFocusInfo.Spell = nullptr;
3549}
3550
3552{
3554 return false;
3555
3556 return true;
3557}
3558
3560{
3562}
3563
3565{
3567}
3568
3570{
3571 CreatureTextRepeatIds& repeats = m_textRepeat[textGroup];
3572 if (std::find(repeats.begin(), repeats.end(), id) == repeats.end())
3573 repeats.push_back(id);
3574 else
3575 TC_LOG_ERROR("sql.sql", "CreatureTextMgr: TextGroup {} for Creature({}) {}, id {} already added", uint32(textGroup), GetName(), GetGUID().ToString(), uint32(id));
3576}
3577
3579{
3581
3582 CreatureTextRepeatGroup::const_iterator groupItr = m_textRepeat.find(textGroup);
3583 if (groupItr != m_textRepeat.end())
3584 ids = groupItr->second;
3585
3586 return ids;
3587}
3588
3590{
3591 CreatureTextRepeatGroup::iterator groupItr = m_textRepeat.find(textGroup);
3592 if (groupItr != m_textRepeat.end())
3593 groupItr->second.clear();
3594}
3595
3597{
3599}
3600
3602{
3603 if (CreatureAI const* ai = AI())
3604 return ai->IsEngaged();
3605 return false;
3606}
3607
3609{
3610 Unit::AtEngage(target);
3611
3613 Dismount();
3614
3615 if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
3616 {
3620 }
3621
3623 if (movetype == WAYPOINT_MOTION_TYPE || movetype == POINT_MOTION_TYPE || (IsAIEnabled() && AI()->IsEscorted()))
3624 {
3626
3627 // if its a vehicle, set the home positon of every creature passenger at engage
3628 // so that they are in combat range if hostile
3629 if (Vehicle* vehicle = GetVehicleKit())
3630 {
3631 for (auto seat = vehicle->Seats.begin(); seat != vehicle->Seats.end(); ++seat)
3632 if (Unit* passenger = ObjectAccessor::GetUnit(*this, seat->second.Passenger.Guid))
3633 if (Creature* creature = passenger->ToCreature())
3634 creature->SetHomePosition(GetPosition());
3635 }
3636 }
3637
3638 if (CreatureAI* ai = AI())
3639 ai->JustEngagedWith(target);
3640 if (CreatureGroup* formation = GetFormation())
3641 formation->MemberEngagingTarget(this, target);
3642}
3643
3645{
3647
3651
3652 if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
3653 {
3657 }
3658}
3659
3661{
3662 if (CreatureAI const* ai = AI())
3663 return ai->IsEscorted();
3664 return false;
3665}
3666
3667std::string Creature::GetDebugInfo() const
3668{
3669 std::stringstream sstr;
3670 sstr << Unit::GetDebugInfo() << "\n"
3671 << "AIName: " << GetAIName() << " ScriptName: " << GetScriptName()
3672 << " WaypointPath: " << GetWaypointPathId() << " SpawnId: " << GetSpawnId();
3673 return sstr.str();
3674}
3675
3676void Creature::ExitVehicle(Position const* /*exitPosition*/)
3677{
3679
3680 // if the creature exits a vehicle, set it's home position to the
3681 // exited position so it won't run away (home) and evade if it's hostile
3683}
3684
3686{
3687 return _gossipMenuId;
3688}
3689
3691{
3692 _gossipMenuId = gossipMenuId;
3693}
3694
3696{
3697 if (_trainerId)
3698 return *_trainerId;
3699
3700 return sObjectMgr->GetCreatureDefaultTrainer(GetEntry());
3701}
3702
3704{
3705 _trainerId = trainerId;
3706}
3707
3709{
3713
3715{
3716 if (!IsAreaSpiritHealer())
3717 return;
3718
3720
3721 // maybe NPC is summoned with these spells:
3722 // ID - 24237 Summon Alliance Graveyard Teleporter (SERVERSIDE)
3723 // ID - 46894 Summon Horde Graveyard Teleporter (SERVERSIDE)
3724 SummonCreature(npcEntry, GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 1s, 0, 0);
3725}
3726
3728{
3729 auto clickBounds = sObjectMgr->GetSpellClickInfoMapBounds(GetEntry());
3730 auto itr = clickBounds.begin();
3731 // Set InteractSpellID if there is only one row in npc_spellclick_spells in db for this creature
3732 if (itr != clickBounds.end() && ++itr == clickBounds.end())
3733 SetInteractSpellId(clickBounds.begin()->second.spellId);
3734 else
3736}
#define sBattlegroundMgr
@ SPELL_SPIRIT_HEAL_CHANNEL_AOE
Definition: Battleground.h:101
constexpr uint8 MAX_SPELL_CHARM
Definition: CharmInfo.h:28
LocaleConstant
Definition: Common.h:48
@ TOTAL_LOCALES
Definition: Common.h:62
@ LOCALE_enUS
Definition: Common.h:49
#define DEFAULT_LOCALE
Definition: Common.h:66
@ IN_MILLISECONDS
Definition: Common.h:35
@ MINUTE
Definition: Common.h:29
@ WEEK
Definition: Common.h:32
const uint32 CREATURE_REGEN_INTERVAL
Definition: CreatureData.h:412
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
Definition: CreatureData.h:362
@ CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING
Definition: CreatureData.h:363
@ CREATURE_FLAG_EXTRA_CANNOT_ENTER_COMBAT
Definition: CreatureData.h:347
@ CREATURE_FLAG_EXTRA_NO_XP
Definition: CreatureData.h:340
@ CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK
Definition: CreatureData.h:364
@ CREATURE_FLAG_EXTRA_IGNORE_FEIGN_DEATH
Definition: CreatureData.h:350
@ CREATURE_FLAG_EXTRA_NO_TAUNT
Definition: CreatureData.h:342
@ CREATURE_FLAG_EXTRA_GHOST_VISIBILITY
Definition: CreatureData.h:344
@ CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK
Definition: CreatureData.h:345
@ CREATURE_FLAG_EXTRA_WORLDEVENT
Definition: CreatureData.h:348
@ CREATURE_STATIC_FLAG_CAN_SWIM
Definition: CreatureData.h:66
@ CREATURE_STATIC_FLAG_NO_XP
Definition: CreatureData.h:39
@ CREATURE_STATIC_FLAG_NO_MELEE_FLEE
Definition: CreatureData.h:58
CreatureChaseMovementType
Definition: CreatureData.h:376
const uint8 MAX_KILL_CREDIT
Definition: CreatureData.h:416
@ CREATURE_STATIC_FLAG_4_NO_BIRTH_ANIM
Definition: CreatureData.h:152
@ CREATURE_STATIC_FLAG_4_NO_MELEE_APPROACH
Definition: CreatureData.h:161
@ CREATURE_STATIC_FLAG_5_NO_HEALTH_REGEN
Definition: CreatureData.h:217
@ CREATURE_STATIC_FLAG_5_INTERACT_WHILE_HOSTILE
Definition: CreatureData.h:198
CreatureRandomMovementType
Definition: CreatureData.h:385
const uint32 CREATURE_NOPATH_EVADE_TIME
Definition: CreatureData.h:414
@ CREATURE_STATIC_FLAG_3_ALLOW_INTERACTION_WHILE_IN_COMBAT
Definition: CreatureData.h:132
@ CREATURE_STATIC_FLAG_2_ALLOW_MOUNTED_COMBAT
Definition: CreatureData.h:94
const uint32 MAX_CREATURE_SPELLS
Definition: CreatureData.h:419
const uint32 PET_FOCUS_REGEN_INTERVAL
Definition: CreatureData.h:413
#define sFormationMgr
AreaSpiritHealerData
Definition: Creature.cpp:3709
@ NPC_ALLIANCE_GRAVEYARD_TELEPORT
Definition: Creature.cpp:3710
@ NPC_HORDE_GRAVEYARD_TELEPORT
Definition: Creature.cpp:3711
std::vector< uint8 > CreatureTextRepeatIds
Definition: Creature.h:66
#define CREATURE_Z_ATTACK_RANGE
Definition: Creature.h:52
static constexpr uint8 WILD_BATTLE_PET_DEFAULT_LEVEL
Definition: Creature.h:62
static constexpr size_t CREATURE_TAPPERS_SOFT_CAP
Definition: Creature.h:63
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< ChrRacesEntry > sChrRacesStore("ChrRaces.db2", &ChrRacesLoadInfo::Instance)
DB2Storage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore("CreatureDisplayInfo.db2", &CreatureDisplayInfoLoadInfo::Instance)
DB2Storage< FactionTemplateEntry > sFactionTemplateStore("FactionTemplate.db2", &FactionTemplateLoadInfo::Instance)
DB2Storage< AreaTableEntry > sAreaTableStore("AreaTable.db2", &AreaTableLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:538
@ MAX_LEVEL
Definition: DBCEnums.h:51
@ STRONG_MAX_LEVEL
Definition: DBCEnums.h:55
Difficulty
Definition: DBCEnums.h:873
@ DIFFICULTY_NONE
Definition: DBCEnums.h:874
@ FACTION_MASK_ALLIANCE
Definition: DBCEnums.h:950
@ UnitsUseDefaultPowerOnInit
@ FACTION_TEMPLATE_FLAG_PVP
Definition: DBCEnums.h:942
SQLTransaction< WorldDatabaseConnection > WorldDatabaseTransaction
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
#define UI64LIT(N)
Definition: Define.h:127
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
#define ASSERT_NOTNULL(pointer)
Definition: Errors.h:84
#define ASSERT
Definition: Errors.h:68
#define sGameEventMgr
Definition: GameEventMgr.h:177
#define MAX_FALL_DISTANCE
Definition: GridDefines.h:62
#define SIZE_OF_GRID_CELL
Definition: GridDefines.h:48
#define TC_LOG_WARN(filterType__,...)
Definition: Log.h:162
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
@ LOOT_SKINNING
Definition: Loot.h:106
#define sMapMgr
Definition: MapManager.h:184
MovementGeneratorType
@ IDLE_MOTION_TYPE
@ CHASE_MOTION_TYPE
@ WAYPOINT_MOTION_TYPE
@ FLEEING_MOTION_TYPE
@ HOME_MOTION_TYPE
@ POINT_MOTION_TYPE
@ RANDOM_MOTION_TYPE
#define ATTACK_DISTANCE
Definition: ObjectDefines.h:25
#define MAX_VISIBILITY_DISTANCE
Definition: ObjectDefines.h:28
#define DEFAULT_PLAYER_COMBAT_REACH
Definition: ObjectDefines.h:40
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
#define DEFAULT_PLAYER_DISPLAY_SCALE
Definition: ObjectDefines.h:41
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ 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
#define sPoolMgr
Definition: PoolMgr.h:179
@ RACE_NONE
Definition: RaceMask.h:27
int32 irand(int32 min, int32 max)
Definition: Random.cpp:35
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void ClearGossipMenuFor(Player *player)
@ SERVERSIDE_VISIBILITY_GHOST
Classes
constexpr uint32 GetMaxLevelForExpansion(uint32 expansion)
@ SPELL_ATTR5_AI_DOESNT_FACE_TARGET
@ XP_GRAY
Emote
@ SPELL_SCHOOL_MASK_NORMAL
@ CREATURE_TYPE_CRITTER
@ CREATURE_TYPE_NON_COMBAT_PET
@ CREATURE_TYPE_MECHANICAL
@ UNIT_DYNFLAG_TAPPED
@ UNIT_DYNFLAG_LOOTABLE
@ UNIT_DYNFLAG_NONE
AiReaction
SpellEffectName
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_ATTACK_ME
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
float const GROUND_HEIGHT_TOLERANCE
Definition: SharedDefines.h:25
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ IMMUNITY_OTHER
@ IMMUNITY_DISPEL
@ ALLIANCE
@ HORDE
Powers
@ POWER_ENERGY
@ POWER_MANA
@ POWER_FOCUS
BattlegroundTypeId
@ BATTLEGROUND_AA
@ BATTLEGROUND_WS
@ BATTLEGROUND_EY
@ BATTLEGROUND_AV
@ BATTLEGROUND_BE
@ BATTLEGROUND_RV
@ BATTLEGROUND_NA
@ BATTLEGROUND_DS
@ BATTLEGROUND_SA
@ BATTLEGROUND_AB
@ BATTLEGROUND_RL
@ GHOST_VISIBILITY_ALIVE
@ GHOST_VISIBILITY_GHOST
CreatureClassifications
@ FACTION_ALLIANCE_GENERIC
SpellSchools
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_NATURE
@ SPELL_SCHOOL_FROST
@ SPELL_SCHOOL_ARCANE
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
@ CREATURE_TYPE_FLAG_VISIBLE_TO_GHOSTS
@ CREATURE_TYPE_FLAG_BOSS_MOB
@ CREATURE_TYPE_FLAG_ALLOW_INTERACTION_WHILE_IN_COMBAT
@ CREATURE_TYPE_FLAG_TREAT_AS_RAID_UNIT
Creature can be targeted by spells that require target to be in caster's party/raid.
@ CREATURE_TYPE_FLAG_ALLOW_MOUNTED_COMBAT
@ SPAWNGROUP_FLAG_COMPATIBILITY_MODE
Definition: SpawnData.h:55
@ LINKED_RESPAWN_CREATURE_TO_GO
Definition: SpawnData.h:123
@ LINKED_RESPAWN_CREATURE_TO_CREATURE
Definition: SpawnData.h:122
@ LINKED_RESPAWN_GO_TO_CREATURE
Definition: SpawnData.h:125
@ SPAWN_TYPE_CREATURE
Definition: SpawnData.h:34
AuraType
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_PREVENTS_FLEEING
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_MOD_INVISIBILITY
@ SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
@ SPELL_AURA_MOD_DETECTED_RANGE
@ SPELL_AURA_MOD_TAUNT
@ SPELL_AURA_FEIGN_DEATH
@ SPELL_AURA_MOD_POWER_REGEN_PERCENT
@ SPELL_AURA_MOD_DETECT_RANGE
@ SPELL_AURA_MOD_REGEN
@ FORM_NONE
#define sSpellMgr
Definition: SpellMgr.h:849
@ MOVE_FLIGHT
Definition: UnitDefines.h:123
@ MOVE_SWIM
Definition: UnitDefines.h:120
@ MOVE_RUN
Definition: UnitDefines.h:118
@ MOVE_WALK
Definition: UnitDefines.h:117
UnitFlags2
Definition: UnitDefines.h:193
@ UNIT_FLAG2_FEIGN_DEATH
Definition: UnitDefines.h:194
@ UNIT_FLAG2_REGENERATE_POWER
Definition: UnitDefines.h:205
@ UNIT_PET_FLAG_NONE
Definition: UnitDefines.h:108
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
UnitStandStateType
Definition: UnitDefines.h:41
@ MOVEMENTFLAG_FALLING
Definition: UnitDefines.h:369
@ ACT_ENABLED
Definition: UnitDefines.h:498
NPCFlags
Non Player Character flags.
Definition: UnitDefines.h:295
@ UNIT_NPC_FLAG_NONE
Definition: UnitDefines.h:296
@ UNIT_NPC_FLAG_SPELLCLICK
Definition: UnitDefines.h:321
UnitFlags3
Definition: UnitDefines.h:245
SheathState
Definition: UnitDefines.h:81
@ SHEATH_STATE_MELEE
Definition: UnitDefines.h:83
#define MAX_EQUIPMENT_ITEMS
Definition: UnitDefines.h:37
NPCFlags2
Definition: UnitDefines.h:335
@ UNIT_NPC_FLAG_2_NONE
Definition: UnitDefines.h:336
UnitPVPStateFlags
Definition: UnitDefines.h:91
AnimTier
Definition: UnitDefines.h:69
UnitVisFlags
Definition: UnitDefines.h:58
UnitFlags
Definition: UnitDefines.h:143
@ UNIT_FLAG_STUNNED
Definition: UnitDefines.h:162
@ UNIT_FLAG_NON_ATTACKABLE
Definition: UnitDefines.h:145
@ UNIT_FLAG_IN_COMBAT
Definition: UnitDefines.h:163
@ UNIT_FLAG_CAN_SWIM
Definition: UnitDefines.h:159
@ UNIT_FLAG_FLEEING
Definition: UnitDefines.h:167
@ UNIT_FLAG_CANT_SWIM
Definition: UnitDefines.h:158
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition: UnitDefines.h:147
@ BASE_VALUE
Definition: Unit.h:152
@ 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_SHADOW
Definition: Unit.h:209
@ UNIT_MOD_RESISTANCE_FROST
Definition: Unit.h:208
@ UNIT_MOD_ATTACK_POWER
Definition: Unit.h:211
@ UNIT_MOD_RESISTANCE_HOLY
Definition: Unit.h:205
@ UNIT_MOD_RESISTANCE_ARCANE
Definition: Unit.h:210
@ UNIT_MOD_HEALTH
Definition: Unit.h:177
@ UNIT_MOD_POWER_START
Definition: Unit.h:222
@ UNIT_MOD_RESISTANCE_FIRE
Definition: Unit.h:206
@ UNIT_MOD_RESISTANCE_NATURE
Definition: Unit.h:207
@ UNIT_MOD_ATTACK_POWER_RANGED
Definition: Unit.h:212
#define MAX_AGGRO_RADIUS
Definition: Unit.h:44
DeathState
Definition: Unit.h:245
@ CORPSE
Definition: Unit.h:248
@ DEAD
Definition: Unit.h:249
@ ALIVE
Definition: Unit.h:246
@ JUST_RESPAWNED
Definition: Unit.h:250
@ JUST_DIED
Definition: Unit.h:247
@ UNIT_STATE_DIED
Definition: Unit.h:255
@ UNIT_STATE_ATTACK_PLAYER
Definition: Unit.h:269
@ UNIT_STATE_ROOT
Definition: Unit.h:265
@ UNIT_STATE_IGNORE_PATHFINDING
Definition: Unit.h:283
@ UNIT_STATE_FLEEING
Definition: Unit.h:262
@ UNIT_STATE_FOCUSING
Definition: Unit.h:261
@ UNIT_STATE_ALL_ERASABLE
Definition: Unit.h:302
@ BASE_PCT
Definition: Unit.h:160
T RoundToInterval(T &num, T floor, T ceil)
Definition: Util.h:97
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:491
@ WORLD_DEL_SPAWNGROUP_MEMBER
Definition: WorldDatabase.h:84
@ WORLD_DEL_GAME_EVENT_MODEL_EQUIP
Definition: WorldDatabase.h:77
@ WORLD_DEL_CREATURE_ADDON
Definition: WorldDatabase.h:66
@ WORLD_DEL_LINKED_RESPAWN
Definition: WorldDatabase.h:31
@ WORLD_DEL_GAME_EVENT_CREATURE
Definition: WorldDatabase.h:76
@ WORLD_DEL_CREATURE
Definition: WorldDatabase.h:68
@ WORLD_DEL_LINKED_RESPAWN_MASTER
Definition: WorldDatabase.h:32
@ WORLD_INS_CREATURE
Definition: WorldDatabase.h:75
uint32 const Entry[5]
Unit & m_owner
Definition: Creature.h:583
ObjectGuid m_victim
Definition: Creature.h:581
bool Execute(uint64 e_time, uint32 p_time) override
Definition: Creature.cpp:276
void AddAssistant(ObjectGuid guid)
Definition: Creature.h:577
GuidList m_assistants
Definition: Creature.h:582
Unit * GetAnyTarget() const
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
virtual void JustAppeared()
Definition: CreatureAI.cpp:194
virtual bool CheckInRoom()
Definition: CreatureAI.cpp:453
Creature * GetLeader() const
void FormationReset(bool dismiss)
bool IsFormed() const
void LeaderStartedMoving()
bool IsLeader(Creature const *creature) const
bool CanLeaderStartMoving() const
bool HasFlag(CreatureStaticFlags flag) const
Definition: CreatureData.h:302
void ApplyFlag(CreatureStaticFlags flag, bool apply)
Definition: CreatureData.h:311
bool IsSwimPrevented() const
Definition: Creature.h:143
bool HasClassification(CreatureClassifications classification) const
Definition: Creature.h:153
bool LoadCreaturesAddon()
Definition: Creature.cpp:2749
time_t _pickpocketLootRestore
Timers.
Definition: Creature.h:487
bool HasSpell(uint32 spellID) const override
Definition: Creature.cpp:2863
uint32 CalculateDamageForSparring(Unit *attacker, uint32 damage)
Definition: Creature.cpp:1737
bool AIM_Destroy()
Definition: Creature.cpp:1028
VendorItemCounts m_vendorItemCounts
Definition: Creature.h:479
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:371
float m_wanderDistance
Definition: Creature.h:493
void SetNoSearchAssistance(bool val)
Definition: Creature.h:318
void ReleaseSpellFocus(Spell const *focusSpell=nullptr, bool withDelay=true)
Definition: Creature.cpp:3499
CreatureDifficulty const * m_creatureDifficulty
Definition: Creature.h:521
void SetCanMelee(bool canMelee, bool fleeFromMelee=false)
Definition: Creature.cpp:2822
bool IsTrigger() const
Definition: Creature.h:113
void Respawn(bool force=false)
Definition: Creature.cpp:2303
void SetInteractionAllowedInCombat(bool interactionAllowed) override
Definition: Creature.cpp:3003
void ResetLootMode()
Definition: Creature.h:300
struct Creature::@208 _spellFocusInfo
bool CanSwim() const override
Definition: Creature.cpp:2947
void RegenerateHealth()
Definition: Creature.cpp:971
CreatureTextRepeatGroup m_textRepeat
Definition: Creature.h:557
void GetRespawnPosition(float &x, float &y, float &z, float *ori=nullptr, float *dist=nullptr) const
Definition: Creature.cpp:2882
VendorItemData const * GetVendorItems() const
Definition: Creature.cpp:3184
void StartDefaultCombatMovement(Unit *victim, Optional< float > range={}, Optional< float > angle={})
Definition: Creature.cpp:2855
float _sparringHealthPct
Definition: Creature.h:568
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const *data=nullptr, uint32 vehId=0)
Definition: Creature.cpp:1781
bool _regenerateHealth
Definition: Creature.h:562
CreatureStaticFlagsHolder _staticFlags
Definition: Creature.h:528
bool IsDungeonBoss() const
Definition: Creature.h:155
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool allowDuplicate)
Definition: Creature.cpp:1830
float GetHealthMultiplierForTarget(WorldObject const *target) const override
Definition: Creature.cpp:3057
bool isWorldBoss() const
Definition: Creature.cpp:2484
bool IsReturningHome() const
Definition: Creature.cpp:367
Optional< uint32 > m_lootId
Definition: Creature.h:525
void UpdateLevelDependantStats()
Definition: Creature.cpp:1587
int8 m_originalEquipmentId
Definition: Creature.h:504
void setDeathState(DeathState s) override
Definition: Creature.cpp:2197
static Creature * CreateCreatureFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap=true, bool allowDuplicate=false)
Definition: Creature.cpp:1199
bool UpdateAllStats() override
Definition: StatSystem.cpp:902
void CallForHelp(float fRadius)
Definition: Creature.cpp:2563
float GetAttackDistance(Unit const *player) const
Definition: Creature.cpp:2153
ObjectGuid::LowType m_spawnId
For new or temporary creatures is 0 for saved it is lowguid.
Definition: Creature.h:502
std::unique_ptr< Loot > m_loot
Definition: Creature.h:277
void Update(uint32 time) override
Definition: Creature.cpp:709
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:252
bool _IsTargetAcceptable(Unit const *target) const
Definition: Creature.cpp:2639
CreatureClassifications GetCreatureClassification() const
Definition: Creature.h:152
Optional< uint32 > _defaultMountDisplayIdOverride
Definition: Creature.h:564
bool IsSessile() const
Definition: Creature.h:132
bool IsIgnoringFeignDeath() const
Definition: Creature.h:322
bool IsCivilian() const
Definition: Creature.h:112
float GetSparringHealthPct() const
Definition: Creature.h:446
void SetRespawnTime(uint32 respawn)
Definition: Creature.cpp:2877
void SetObjectScale(float scale) override
Definition: Creature.cpp:3391
Optional< std::string > m_scriptStringId
Definition: Creature.h:523
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition: Creature.h:302
void ApplyAllStaticFlags(CreatureStaticFlagsHolder const &flags)
Definition: Creature.cpp:701
static float GetDamageMod(CreatureClassifications classification)
Definition: Creature.cpp:1686
bool m_cannotReachTarget
Definition: Creature.h:508
bool m_respawnCompatibilityMode
Definition: Creature.h:544
void SelectWildBattlePetLevel()
Definition: Creature.cpp:1643
std::string GetNameForLocaleIdx(LocaleConstant locale) const override
Definition: Creature.cpp:3260
bool IsFloating() const
Definition: Creature.h:128
std::unordered_map< ObjectGuid, std::unique_ptr< Loot > > m_personalLoot
Definition: Creature.h:278
CreatureTemplate const * m_creatureInfo
Definition: Creature.h:519
bool IsSpawnedOnTransport() const
Definition: Creature.h:102
void UpdateNearbyPlayersInteractions() override
Definition: Creature.cpp:3009
bool CanFly() const override
Definition: Creature.h:147
Position const & GetHomePosition() const
Definition: Creature.h:374
bool CanGiveExperience() const
Definition: Creature.cpp:3596
CreatureTextRepeatIds GetTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:3578
void LoadEquipment(int8 id=1, bool force=false)
Definition: Creature.cpp:1946
uint8 GetLevelForTarget(WorldObject const *target) const override
Definition: Creature.cpp:3104
void SetTrainerId(Optional< uint32 > trainerId)
Definition: Creature.cpp:3703
bool HasReactState(ReactStates state) const
Definition: Creature.h:162
bool AIM_Initialize(CreatureAI *ai=nullptr)
Definition: Creature.cpp:1044
void DoNotReacquireSpellFocusTarget()
Definition: Creature.cpp:3545
void RemoveCorpse(bool setSpawnTime=true, bool destroyForNearbyPlayers=true)
Definition: Creature.cpp:415
void SendZoneUnderAttackMessage(Player *attacker)
Send a message to LocalDefense channel for players opposition team in the zone.
Definition: Creature.cpp:2814
bool m_triggerJustAppeared
Definition: Creature.h:543
void StartPickPocketRefillTimer()
Definition: Creature.cpp:3559
void AllLootRemovedFromCorpse()
Definition: Creature.cpp:2958
static Creature * CreateCreature(uint32 entry, Map *map, Position const &pos, uint32 vehId=0)
Definition: Creature.cpp:1177
float GetAggroRange(Unit const *target) const
Definition: Creature.cpp:3322
void LoadTemplateImmunities(int32 creatureImmunitiesId)
Definition: Creature.cpp:2423
void SignalFormationMovement()
Definition: Creature.cpp:396
void SetDisplayFromModel(uint32 modelIdx)
Definition: Creature.cpp:3413
bool IsEngaged() const override
Definition: Creature.cpp:3601
MovementGeneratorType m_defaultMovementType
Definition: Creature.h:501
Unit * SelectNearestHostileUnitInAggroRange(bool useLOS=false, bool ignoreCivilians=false) const
Definition: Creature.cpp:3371
bool Create(ObjectGuid::LowType guidlow, Map *map, uint32 entry, Position const &pos, CreatureData const *data, uint32 vehId, bool dynamic=false)
Definition: Creature.cpp:1071
void SetReactState(ReactStates st)
Definition: Creature.h:160
uint32 GetTrainerId() const
Definition: Creature.cpp:3695
void RemoveFromWorld() override
Definition: Creature.cpp:349
void SetTextRepeatId(uint8 textGroup, uint8 id)
Definition: Creature.cpp:3569
uint32 _waypointPathId
Definition: Creature.h:538
void ResetPlayerDamageReq()
Definition: Creature.h:400
float m_SightDistance
Definition: Creature.h:412
int32 _creatureImmunitiesId
Definition: Creature.h:565
void SetRespawnCompatibilityMode(bool mode=true)
Definition: Creature.h:407
void SetCannotReachTarget(bool cannotReach)
Definition: Creature.cpp:3303
bool ShouldFakeDamageFrom(Unit *attacker)
Definition: Creature.cpp:1761
void ApplyLevelScaling()
Definition: Creature.cpp:3031
void ClearTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:3589
void SetRespawnDelay(uint32 delay)
Definition: Creature.h:338
void AddToWorld() override
Definition: Creature.cpp:329
uint32 m_cannotReachTimer
Definition: Creature.h:509
uint32 m_respawnDelay
Definition: Creature.h:490
void SetScriptStringId(std::string id)
Definition: Creature.cpp:3170
void SetTappedBy(Unit const *unit, bool withGroup=true)
Definition: Creature.cpp:1339
void InitializeMovementCapabilities()
Definition: Creature.cpp:2906
void InitializeInteractSpellId()
Definition: Creature.cpp:3727
bool IsSkinnedBy(Player const *player) const
Definition: Creature.cpp:1409
time_t m_corpseRemoveTime
Definition: Creature.h:488
void ForcedDespawn(uint32 timeMSToDespawn=0, Seconds forceRespawnTimer=0s)
Definition: Creature.cpp:2363
uint32 m_combatPulseDelay
Definition: Creature.h:496
float GetPetChaseDistance() const
Definition: Creature.cpp:3283
bool IsFormationLeaderMoveAllowed() const
Definition: Creature.cpp:407
void SummonGraveyardTeleporter()
Definition: Creature.cpp:3714
bool IsImmuneToNPC() const
Definition: Unit.h:1033
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition: Creature.cpp:577
float GetArmorMultiplierForTarget(WorldObject const *target) const override
Definition: Creature.cpp:3094
bool HasStringId(std::string_view id) const
Definition: Creature.cpp:3165
float GetSpellDamageMod(CreatureClassifications classification) const
Definition: Creature.cpp:1709
time_t m_respawnTime
Definition: Creature.h:489
void DoFleeToGetAssistance()
Definition: Creature.cpp:1002
float GetDamageMultiplierForTarget(WorldObject const *target) const override
Definition: Creature.cpp:3076
uint32 _gossipMenuId
Definition: Creature.h:566
bool CanResetTalents(Player *player) const
Definition: Creature.cpp:1320
bool IsEscorted() const
Definition: Creature.cpp:3660
void AtEngage(Unit *target) override
Definition: Creature.cpp:3608
uint32 GetScriptId() const
Definition: Creature.cpp:3156
CreatureData const * m_creatureData
Definition: Creature.h:520
float m_CombatDistance
Definition: Creature.h:412
void AtDisengage() override
Definition: Creature.cpp:3644
bool hasInvolvedQuest(uint32 quest_id) const override
Definition: Creature.cpp:2000
uint32 m_boundaryCheckTime
Definition: Creature.h:494
bool isCanInteractWithBattleMaster(Player *player, bool msg) const
Definition: Creature.cpp:1288
Position m_homePosition
Definition: Creature.h:514
uint32 GetWaypointPathId() const
Definition: Creature.h:381
Loot * GetLootForPlayer(Player const *player) const override
Definition: Creature.cpp:1386
CreatureData const * GetCreatureData() const
Definition: Creature.h:251
bool CanGeneratePickPocketLoot() const
Definition: Creature.cpp:3564
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:98
void SetInteractionAllowedWhileHostile(bool interactionAllowed) override
Definition: Creature.cpp:2997
bool CanNotReachTarget() const
Definition: Creature.h:367
bool m_AlreadyCallAssistance
Definition: Creature.h:506
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:250
uint32 GetRespawnDelay() const
Definition: Creature.h:337
void SetDontClearTapListOnEvade(bool dontClear)
Definition: Creature.cpp:1373
bool IsFormationLeader() const
Definition: Creature.cpp:388
bool CanCreatureAttack(Unit const *victim, bool force=true) const
Definition: Creature.cpp:2686
bool CanRegenerateHealth() const
Definition: Creature.h:357
bool DisableReputationGain
Definition: Creature.h:517
void SetTarget(ObjectGuid const &guid) override
Definition: Creature.cpp:3419
float GetBaseDamageForLevel(uint8 level) const
Definition: Creature.cpp:3069
uint32 GetLootId() const
Definition: Creature.cpp:1326
CreatureGroup * m_formation
Definition: Creature.h:542
static bool DeleteFromDB(ObjectGuid::LowType spawnId)
Definition: Creature.cpp:2005
void SetInteractSpellId(int32 interactSpellId)
Definition: Creature.h:472
void InitializeReactState()
Definition: Creature.cpp:1276
bool AIM_Create(CreatureAI *ai=nullptr)
Definition: Creature.cpp:1035
uint32 m_corpseDelay
Definition: Creature.h:491
void Motion_Initialize()
Definition: Creature.cpp:1055
bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const override
Definition: Creature.cpp:2467
std::array< std::string_view, 3 > m_stringIds
Definition: Creature.h:522
void LoadCreaturesSparringHealth(bool force=false)
Definition: Creature.cpp:2806
uint32 UpdateVendorItemCurrentCount(VendorItem const *vItem, uint32 used_count)
Definition: Creature.cpp:3223
void SetSpawnHealth()
Definition: Creature.cpp:1969
bool CheckNoGrayAggroConfig(uint32 playerLevel, uint32 creatureLevel) const
Definition: Creature.cpp:2138
uint8 m_equipmentId
Definition: Creature.h:503
bool IsElite() const
Definition: Creature.cpp:2476
bool isTappedBy(Player const *player) const
Definition: Creature.cpp:1381
Creature(bool isWorldObject=false)
Definition: Creature.cpp:306
CreatureGroup * GetFormation()
Definition: Creature.h:391
uint32 GetCorpseDelay() const
Definition: Creature.h:110
GuidUnorderedSet m_tapList
Definition: Creature.h:483
bool m_dontClearTapListOnEvade
Definition: Creature.h:484
uint64 GetMaxHealthByLevel(uint8 level) const
Definition: Creature.cpp:3049
void OverrideSparringHealthPct(float healthPct)
Definition: Creature.h:444
bool CanAssistTo(Unit const *u, Unit const *enemy, bool checkfaction=true) const
Definition: Creature.cpp:2585
uint32 m_originalEntry
Definition: Creature.h:512
float GetNativeObjectScale() const override
Definition: Creature.cpp:3386
bool HasScalableLevels() const
Definition: Creature.cpp:3026
void SetDefaultMount(Optional< uint32 > mountCreatureDisplayId)
Definition: Creature.cpp:3314
void ExitVehicle(Position const *exitPosition=nullptr) override
Definition: Creature.cpp:3676
Unit * SelectVictim()
Definition: Creature.cpp:1211
void SearchFormation()
Definition: Creature.cpp:375
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition: Creature.cpp:3189
float GetBaseArmorForLevel(uint8 level) const
Definition: Creature.cpp:3086
bool m_isTempWorldObject
Definition: Creature.h:414
void SetDisplayId(uint32 displayId, bool setNative=false) override
Definition: Creature.cpp:3402
std::string GetScriptName() const
Definition: Creature.cpp:3151
void LowerPlayerDamageReq(uint64 unDamage)
Definition: Creature.cpp:1680
time_t GetLastDamagedTime() const
Definition: Creature.h:426
MovementGeneratorType GetDefaultMovementType() const override
Definition: Creature.h:149
void SetSpellFocus(Spell const *focusSpell, WorldObject const *target)
Definition: Creature.cpp:3427
Optional< uint32 > _trainerId
Definition: Creature.h:567
bool HasFlag(CreatureStaticFlags flag) const
Definition: Creature.h:454
bool IsInvisibleDueToDespawn(WorldObject const *seer) const override
Definition: Creature.cpp:2080
bool IsFullyLooted() const
Definition: Creature.cpp:1397
void SaveRespawnTime(uint32 forceDelay=0)
Definition: Creature.cpp:2666
uint8 GetCurrentEquipmentId() const
Definition: Creature.h:241
bool InitEntry(uint32 entry, CreatureData const *data=nullptr)
Definition: Creature.cpp:487
Unit * SelectNearestTarget(float dist=0, bool playerOnly=false) const
Definition: Creature.cpp:2493
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition: Creature.h:104
void SetMeleeDamageSchool(SpellSchools school)
Definition: Creature.h:217
static float GetHealthMod(CreatureClassifications classification)
Definition: Creature.cpp:1657
void SaveToDB()
Definition: Creature.cpp:1417
Unit * SelectNearestTargetInAttackDistance(float dist=0) const
Definition: Creature.cpp:2506
void SelectLevel()
Definition: Creature.cpp:1576
CreatureMovementData const & GetMovementTemplate() const
Definition: Creature.cpp:2939
void SendAIReaction(AiReaction reactionType)
Definition: Creature.cpp:2521
void SetGossipMenuId(uint32 gossipMenuId)
Definition: Creature.cpp:3690
bool IsAmphibious() const
Definition: Creature.h:125
void ResetPickPocketRefillTimer()
Definition: Creature.h:280
void SetNoCallAssistance(bool val)
Definition: Creature.h:317
void SetTreatAsRaidUnit(bool treatAsRaidUnit)
Definition: Creature.h:222
void UpdateMovementCapabilities()
Definition: Creature.cpp:2919
bool m_ignoreCorpseDecayRatio
Definition: Creature.h:492
bool CanAlwaysSee(WorldObject const *obj) const override
Definition: Creature.cpp:2091
bool hasQuest(uint32 quest_id) const override
Definition: Creature.cpp:1995
void Regenerate(Powers power)
Definition: Creature.cpp:918
time_t GetRespawnTimeEx() const
Definition: Creature.cpp:2868
CreatureAddon const * GetCreatureAddon() const
Definition: Creature.cpp:2737
std::string const & GetAIName() const
Definition: Creature.cpp:3146
void CallAssistance()
Definition: Creature.cpp:2533
void SetLootId(Optional< uint32 > lootId)
Definition: Creature.cpp:1334
bool IsImmuneToPC() const
Definition: Unit.h:1030
void SetCanDualWield(bool value) override
Definition: Creature.cpp:1940
bool IsInEvadeMode() const
Definition: Creature.h:203
void ReacquireSpellFocusTarget()
Definition: Creature.cpp:3522
CreatureAI * AI() const
Definition: Creature.h:214
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
Definition: Creature.cpp:3275
std::string GetDebugInfo() const override
Definition: Creature.cpp:3667
bool CanStartAttack(Unit const *u, bool force) const
Definition: Creature.cpp:2099
bool IsMovementPreventedByCasting() const override
Definition: Creature.cpp:3551
void SetOriginalEntry(uint32 entry)
Definition: Creature.h:404
bool HasSpellFocus(Spell const *focusSpell=nullptr) const override
Definition: Creature.cpp:3481
uint32 GetGossipMenuId() const
Definition: Creature.cpp:3685
void SetIgnoreFeignDeath(bool ignoreFeignDeath)
Definition: Creature.h:323
uint32 m_combatPulseTime
Definition: Creature.h:495
uint64 m_PlayerDamageReq
Definition: Creature.h:401
virtual uint8 GetPetAutoSpellSize() const
Definition: Creature.cpp:3270
constexpr std::underlying_type_t< T > AsUnderlyingType() const
Definition: EnumFlag.h:122
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
void SetValue(FLAG_TYPE flag, T_VALUES value)
Definition: Object.h:446
Seconds const m_respawnTimer
Definition: Creature.h:594
bool Execute(uint64 e_time, uint32 p_time) override
Definition: Creature.cpp:300
Definition: Group.h:197
bool isEmpty() const
Definition: LinkedList.h:110
iterator end()
Definition: MapRefManager.h:35
iterator begin()
Definition: MapRefManager.h:34
Definition: Map.h:189
bool IsDungeon() const
Definition: Map.cpp:3238
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition: Map.cpp:1080
MapStoredObjectTypesContainer & GetObjectsStore()
Definition: Map.h:422
time_t GetLinkedRespawnTime(ObjectGuid guid) const
Definition: Map.cpp:3642
void GetFullTerrainStatusForPosition(PhaseShift const &phaseShift, float x, float y, float z, PositionFullTerrainStatus &data, Optional< map_liquidHeaderTypeFlags > reqLiquidType={}, float collisionHeight=2.03128f)
Definition: Map.cpp:1720
void ApplyDynamicModeRespawnScaling(WorldObject const *obj, ObjectGuid::LowType spawnId, uint32 &respawnDelay, uint32 mode) const
Definition: Map.cpp:2275
ObjectGuid::LowType GenerateLowGuid()
Definition: Map.h:519
time_t GetCreatureRespawnTime(ObjectGuid::LowType spawnId) const
Definition: Map.h:485
void SaveRespawnInfoDB(RespawnInfo const &info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition: Map.cpp:3584
bool IsSpawnGroupActive(uint32 groupId) const
Definition: Map.cpp:2474
void SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 gridId, CharacterDatabaseTransaction dbTrans=nullptr, bool startup=false)
Definition: Map.cpp:3551
float GetHeight(PhaseShift const &phaseShift, float x, float y, float z, bool vmap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH)
Definition: Map.h:290
CreatureBySpawnIdContainer & GetCreatureBySpawnIdStore()
Definition: Map.h:425
PlayerList const & GetPlayers() const
Definition: Map.h:367
SpawnedPoolData & GetPoolData()
Definition: Map.h:715
void Respawn(RespawnInfo *info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition: Map.cpp:2058
void Initialize()
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveFleeing(Unit *enemy, Milliseconds time=0ms)
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MoveSeekAssistance(float x, float y, float z)
MovementGenerator * GetCurrentMovementGenerator() const
void MoveFall(uint32 id=0)
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
void InitializeDefault()
virtual MovementGeneratorType GetMovementGeneratorType() const =0
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
uint64 LowType
Definition: ObjectGuid.h:278
static void ChooseCreatureFlags(CreatureTemplate const *cInfo, uint64 *npcFlags, uint32 *unitFlags, uint32 *unitFlags2, uint32 *unitFlags3, CreatureStaticFlagsHolder const &staticFlags, CreatureData const *data=nullptr)
Definition: ObjectMgr.cpp:1630
static std::string_view GetLocaleString(std::vector< std::string > const &data, LocaleConstant locale)
Definition: ObjectMgr.h:1682
static CreatureModel const * ChooseDisplayId(CreatureTemplate const *cinfo, CreatureData const *data=nullptr)
Definition: ObjectMgr.cpp:1616
void SetDynamicFlag(uint32 flag)
Definition: Object.h:169
static Creature * ToCreature(Object *o)
Definition: Object.h:219
bool IsPlayer() const
Definition: Object.h:212
float GetObjectScale() const
Definition: Object.h:164
static Unit * ToUnit(Object *o)
Definition: Object.h:225
ObjectGuid const & GetGUID() const
Definition: Object.h:160
bool IsInWorld() const
Definition: Object.h:154
bool HasDynamicFlag(uint32 flag) const
Definition: Object.h:168
TypeID GetTypeId() const
Definition: Object.h:173
CreateObjectBits m_updateFlag
Definition: Object.h:404
void SetUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:287
void ReplaceAllDynamicFlags(uint32 flag)
Definition: Object.h:171
uint32 GetEntry() const
Definition: Object.h:161
bool IsCreature() const
Definition: Object.h:218
UF::UpdateFieldHolder m_values
Definition: Object.h:266
void RemoveDynamicFlag(uint32 flag)
Definition: Object.h:170
void _Create(ObjectGuid const &guid)
Definition: Object.cpp:101
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void SetEntry(uint32 entry)
Definition: Object.h:162
virtual void SetObjectScale(float scale)
Definition: Object.h:165
static Player * ToPlayer(Object *o)
Definition: Object.h:213
static void InitDbVisibleMapId(PhaseShift &phaseShift, int32 visibleMapId)
static void InitDbPhaseShift(PhaseShift &phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
Group * GetGroup(Optional< uint8 > partyIndex)
Definition: Player.h:2606
Team GetTeam() const
Definition: Player.h:2235
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition: Player.cpp:25115
void setFloat(const uint8 index, const float value)
void setUInt8(const uint8 index, const uint8 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt16(const uint8 index, const uint16 value)
void setNull(const uint8 index)
void setString(const uint8 index, const std::string &value)
void setUInt64(const uint8 index, const uint64 value)
bool IsEffect() const
Definition: SpellInfo.cpp:451
bool IsChanneled() const
Definition: SpellInfo.cpp:1719
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
bool HasAura(AuraType aura) const
Definition: SpellInfo.cpp:1400
static CreatureImmunities const * GetCreatureImmunities(int32 creatureImmunitiesId)
Definition: SpellMgr.cpp:677
Definition: Spell.h:255
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:650
bool IsFocusDisabled() const
Definition: Spell.cpp:8163
int32 GetCastTime() const
Definition: Spell.h:612
void EvaluateSuppressed(bool canExpire=false)
Unit * GetCurrentVictim()
Unit * GetAnyTarget() const
void Update(uint32 tdiff)
bool Remove(KEY_TYPE const &handle)
bool Insert(KEY_TYPE const &handle, SPECIFIC_TYPE *obj)
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:683
Definition: UnitAI.h:50
virtual void InitializeAI()
Definition: UnitAI.cpp:43
Definition: Unit.h:627
void ClearUnitState(uint32 f)
Definition: Unit.h:733
bool IsVehicle() const
Definition: Unit.h:743
void ApplySpellImmune(uint32 spellId, SpellImmunity op, uint32 type, bool apply)
Definition: Unit.cpp:7845
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:8280
bool IsCharmed() const
Definition: Unit.h:1215
Vehicle * GetVehicle() const
Definition: Unit.h:1713
virtual bool IsMovementPreventedByCasting() const
Definition: Unit.cpp:3119
bool IsBattleMaster() const
Definition: Unit.h:998
bool isTargetableForAttack(bool checkFakeDeath=true) const
Definition: Unit.cpp:8168
bool IsHunterPet() const
Definition: Unit.h:741
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1321
float GetHealthPct() const
Definition: Unit.h:784
void AIUpdateTick(uint32 diff)
Definition: Unit.cpp:9525
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
void SetVirtualItem(uint32 slot, uint32 itemId, uint16 appearanceModId=0, uint16 itemVisual=0)
Definition: Unit.cpp:13604
bool CanHaveThreatList() const
====================== THREAT & COMBAT ====================
Definition: Unit.h:1015
void UpdateObjectVisibility(bool forced=true) override
Definition: Unit.cpp:11836
bool CannotTurn() const
Definition: Unit.h:1040
int64 ModifyHealth(int64 val)
Definition: Unit.cpp:8182
void SetFullHealth()
Definition: Unit.h:790
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
void ReplaceAllNpcFlags2(NPCFlags2 flags)
Definition: Unit.h:990
float GetDisplayScale() const
Definition: Unit.h:1568
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void ReplaceAllPvpFlags(UnitPVPStateFlags flags)
Definition: Unit.h:870
void AddToWorld() override
Definition: Unit.cpp:9603
void SetModRangedHaste(float rangedHaste)
Definition: Unit.h:828
void ReplaceAllUnitFlags3(UnitFlags3 flags)
Definition: Unit.h:845
virtual void SetCanDualWield(bool value)
Definition: Unit.h:693
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:10911
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1814
uint8 GetClass() const
Definition: Unit.h:752
uint32 m_regenTimer
Definition: Unit.h:1908
void SetCreateHealth(uint32 val)
Definition: Unit.h:1393
Vehicle * m_vehicle
Definition: Unit.h:1910
std::unique_ptr< CharmInfo > m_charmInfo
Definition: Unit.h:1902
void UpdateDisplayPower()
Definition: Unit.cpp:5625
void SetRace(uint8 race)
Definition: Unit.h:750
void UpdateSpeed(UnitMoveType mtype)
Definition: Unit.cpp:8361
bool IsPolymorphed() const
Definition: Unit.cpp:10127
bool IsAreaSpiritHealer() const
Definition: Unit.h:1002
void SetFaction(uint32 faction) override
Definition: Unit.h:859
virtual void SetPvP(bool state)
Definition: Unit.cpp:11610
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value)
Definition: Unit.h:1530
virtual void AtEngage(Unit *)
Definition: Unit.h:1930
void SetStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float val)
Definition: Unit.cpp:9021
Unit * getAttackerForHelper() const
Definition: Unit.cpp:5647
std::forward_list< AuraEffect * > AuraEffectList
Definition: Unit.h:644
void SetPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:9419
Trinity::unique_trackable_ptr< Vehicle > m_vehicleKit
Definition: Unit.h:1911
bool IsAreaSpiritHealerIndividual() const
Definition: Unit.h:1009
void SetAnimTier(AnimTier animTier, bool notifyClient=true)
Definition: Unit.cpp:10114
void ReplaceAllUnitFlags(UnitFlags flags)
Definition: Unit.h:835
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsPet() const
Definition: Unit.h:740
Powers GetPowerType() const
Definition: Unit.h:799
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:832
void Dismount()
Definition: Unit.cpp:7920
bool SetHover(bool enable, bool updateAnimTier=true)
Definition: Unit.cpp:12938
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
Aura * AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:11618
void SetModHaste(float haste)
Definition: Unit.h:827
virtual void AtDisengage()
Definition: Unit.h:1931
bool HasUnitFlag2(UnitFlags2 flags) const
Definition: Unit.h:837
std::string GetDebugInfo() const override
Definition: Unit.cpp:13774
void ReplaceAllPetFlags(UnitPetFlag flags)
Definition: Unit.h:881
bool IsAlive() const
Definition: Unit.h:1164
float GetCombatReach() const override
Definition: Unit.h:694
void ReplaceAllVisFlags(UnitVisFlags flags)
Definition: Unit.h:893
DeathState m_deathState
Definition: Unit.h:1857
int32 GetMaxPower(Powers power) const
Definition: Unit.cpp:9410
void StopMoving()
Definition: Unit.cpp:10049
TempSummon * ToTempSummon()
Definition: Unit.h:1756
bool IsQuestGiver() const
Definition: Unit.h:994
ObjectGuid GetCharmerOrOwnerGUID() const override
Definition: Unit.h:1195
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition: Unit.cpp:12725
void SetModHasteRegen(float hasteRegen)
Definition: Unit.h:829
virtual void SetInteractionAllowedWhileHostile(bool interactionAllowed)
Definition: Unit.cpp:8722
float GetNativeDisplayScale() const
Definition: Unit.h:1571
void SetUninteractible(bool apply)
Definition: Unit.cpp:8147
void SetBaseAttackTime(WeaponAttackType att, uint32 val)
Definition: Unit.cpp:10308
void AddUnitState(uint32 f)
Definition: Unit.h:731
float GetTotalAuraMultiplier(AuraType auraType) const
Definition: Unit.cpp:4934
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition: Unit.cpp:7887
bool IsTaxi() const
Definition: Unit.h:996
void SetSheath(SheathState sheathed)
Definition: Unit.cpp:5630
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.cpp:11475
void SetBoundingRadius(float boundingRadius)
Definition: Unit.h:697
void SetCreateMana(uint32 val)
Definition: Unit.h:1395
bool isInAccessiblePlaceFor(Creature const *c) const
Definition: Unit.cpp:3165
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition: Unit.h:1196
virtual void SetInteractionAllowedInCombat(bool interactionAllowed)
Definition: Unit.cpp:8732
Unit * EnsureVictim() const
Definition: Unit.h:717
void SetModSpellHaste(float spellHaste)
Definition: Unit.h:826
void RefreshAI()
Definition: Unit.cpp:9557
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1200
virtual void UpdateDamagePhysical(WeaponAttackType attType)
Definition: StatSystem.cpp:64
uint32 GetCreatureType() const
Definition: Unit.cpp:8880
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const
Definition: Unit.cpp:7561
bool SetSwim(bool enable)
Definition: Unit.cpp:12801
void SetCombatReach(float combatReach)
Definition: Unit.h:695
void SetEmoteState(Emote emote)
Definition: Unit.h:852
virtual void UpdateNearbyPlayersInteractions()
Definition: Unit.cpp:8743
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:4999
uint32 GetDisplayId() const
Definition: Unit.h:1567
bool IsAIEnabled() const
Definition: Unit.h:658
uint32 GetNativeDisplayId() const
Definition: Unit.h:1570
uint64 GetMaxHealth() const
Definition: Unit.h:777
bool IsHovering() const
Definition: Unit.h:1137
bool PopAI()
Definition: Unit.cpp:9546
float GetHoverOffset() const
Definition: Unit.h:1740
uint64 GetHealth() const
Definition: Unit.h:776
bool IsSummon() const
Definition: Unit.h:738
bool IsInWater() const
Definition: Unit.cpp:3186
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
Definition: Unit.cpp:11520
uint32 GetFaction() const override
Definition: Unit.h:858
uint32 GetCreateHealth() const
Definition: Unit.h:1394
void SetAI(UnitAI *newAI)
Definition: Unit.cpp:9540
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4674
void EngageWithTarget(Unit *who)
Definition: Unit.cpp:8077
bool HasNpcFlag(NPCFlags flags) const
Definition: Unit.h:981
uint8 GetLevelForTarget(WorldObject const *) const override
Definition: Unit.h:747
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4929
void SetFullPower(Powers power)
Definition: Unit.h:812
void SetMovementAnimKitId(uint16 animKitId)
Definition: Unit.cpp:10559
void SetMaxHealth(uint64 val)
Definition: Unit.cpp:9377
void SetPowerType(Powers power, bool sendUpdate=true)
Definition: Unit.cpp:5534
bool IsGuardian() const
Definition: Unit.h:739
Unit * GetVictim() const
Definition: Unit.h:715
int32 GetPower(Powers power) const
Definition: Unit.cpp:9401
void SetModTimeRate(float timeRate)
Definition: Unit.h:830
bool IsUnderWater() const
Definition: Unit.cpp:3191
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition: Unit.cpp:8525
DeathState getDeathState() const
Definition: Unit.h:1167
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool IsEngagedBy(Unit const *who) const
Definition: Unit.h:1020
bool IsCritter() const
Definition: Unit.h:1010
bool CreateVehicleKit(uint32 id, uint32 creatureEntry, bool loading=false)
Definition: Unit.cpp:11443
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
virtual void Update(uint32 time) override
Definition: Unit.cpp:420
void ProcessPositionDataChanged(PositionFullTerrainStatus const &data) override
Definition: Unit.cpp:3201
void SetLevel(uint8 lvl, bool sendUpdate=true)
Definition: Unit.cpp:9329
void SetCanModifyStats(bool modifyStats)
Definition: Unit.h:1506
void RemoveUnitMovementFlag(uint32 f)
Definition: Unit.h:1662
void SetClass(uint8 classId)
Definition: Unit.h:753
virtual bool CanSwim() const
Definition: Unit.cpp:12313
void RemoveFromWorld() override
Definition: Unit.cpp:9611
bool IsOnOceanFloor() const
Definition: Unit.cpp:3196
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
bool isDying() const
Definition: Unit.h:1165
void DoMeleeAttackIfReady()
Definition: Unit.cpp:2093
int32 GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:4989
void RemoveAllAuras()
Definition: Unit.cpp:4242
void ReplaceAllUnitFlags2(UnitFlags2 flags)
Definition: Unit.h:840
bool IsWildBattlePet() const
Definition: Unit.h:1006
virtual void setDeathState(DeathState s)
Definition: Unit.cpp:8592
CombatManager & GetCombatManager()
Definition: Unit.h:1023
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
bool IsFlying() const
Definition: Unit.h:1735
void SetVignette(uint32 vignetteId)
Definition: Unit.cpp:13759
bool IsUninteractible() const
Definition: Unit.h:1037
bool IsSpiritHealer() const
Definition: Unit.h:1001
bool IsTotem() const
Definition: Unit.h:742
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:12647
void SetModCastingSpeed(float castingSpeed)
Definition: Unit.h:825
Vehicle * GetVehicleKit() const
Definition: Unit.h:1711
void ReplaceAllNpcFlags(NPCFlags flags)
Definition: Unit.h:984
bool IsSpiritService() const
Definition: Unit.h:1008
bool IsFalling() const
Definition: Unit.cpp:12308
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
Definition: Unit.cpp:9012
void SetShapeshiftForm(ShapeshiftForm form)
Definition: Unit.cpp:8904
void SetMeleeAnimKitId(uint16 animKitId)
Definition: Unit.cpp:10575
ObjectGuid GetTarget() const
Definition: Unit.h:1759
uint8 GetLevel() const
Definition: Unit.h:746
void SetMountDisplayId(uint32 mountDisplayId)
Definition: Unit.h:900
virtual void SetDisplayId(uint32 displayId, bool setNative=false)
Definition: Unit.cpp:10148
bool IsInCombat() const
Definition: Unit.h:1043
void SetWildBattlePetLevel(uint32 wildBattlePetLevel)
Definition: Unit.h:1250
void SetIsCombatDisallowed(bool apply)
Definition: Unit.h:1798
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
void SetAIAnimKitId(uint16 animKitId)
Definition: Unit.cpp:10543
Player * m_playerMovingMe
Definition: Unit.h:1899
bool isDead() const
Definition: Unit.h:1166
virtual void ExitVehicle(Position const *exitPosition=nullptr)
Definition: Unit.cpp:12204
Unit * GetBase() const
Definition: Vehicle.h:49
void Reset(bool evading=false)
Reapplies immunities and reinstalls accessories. Only has effect for creatures.
Definition: Vehicle.cpp:138
void Install()
Initializes power type for vehicle. Nothing more.
Definition: Vehicle.cpp:78
constexpr uint32 GetMapId() const
Definition: Position.h:201
virtual bool IsInvisibleDueToDespawn(WorldObject const *seer) const
Definition: Object.h:823
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:1744
Map * GetMap() const
Definition: Object.h:624
void UpdateAllowedPositionZ(float x, float y, float &z, float *groundZ=nullptr) const
Definition: Object.cpp:1371
virtual void UpdateObjectVisibilityOnDestroy()
Definition: Object.h:724
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition: Object.cpp:2991
bool IsHostileTo(WorldObject const *target) const
Definition: Object.cpp:2860
float GetTransOffsetX() const
Definition: Object.h:751
uint32 LastUsedScriptID
Definition: Object.h:747
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
PhaseShift & GetPhaseShift()
Definition: Object.h:523
Unit * GetOwner() const
Definition: Object.cpp:2229
ZoneScript * GetZoneScript() const
Definition: Object.h:630
void SetZoneScript()
Definition: Object.cpp:2011
TransportBase * GetTransport() const
Definition: Object.h:750
void setActive(bool isActiveObject)
Definition: Object.cpp:922
float GetTransOffsetY() const
Definition: Object.h:752
float GetFloorZ() const
Definition: Object.cpp:3755
std::string const & GetName() const
Definition: Object.h:555
virtual void SetMap(Map *map)
Definition: Object.cpp:1794
float GetTransOffsetZ() const
Definition: Object.h:753
void AddObjectToRemoveList()
Definition: Object.cpp:1824
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition: Object.cpp:1181
bool IsNeutralToAll() const
Definition: Object.cpp:2883
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Object.cpp:2252
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
EventProcessor m_Events
Definition: Object.h:777
float GetVisibilityRange() const
Definition: Object.cpp:1447
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition: Object.h:620
uint32 GetAreaId() const
Definition: Object.h:546
float GetTransOffsetO() const
Definition: Object.h:754
void SetVisibilityDistanceOverride(VisibilityDistanceType type)
Definition: Object.cpp:945
uint32 GetZoneId() const
Definition: Object.h:545
MovementInfo m_movementInfo
Definition: Object.h:761
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition: Object.h:619
float GetDistanceZ(WorldObject const *obj) const
Definition: Object.cpp:1048
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1142
bool IsFriendlyTo(WorldObject const *target) const
Definition: Object.cpp:2865
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1115
int32 GetDBPhase() const
Definition: Object.h:540
WorldPacket const * Write() override
WorldPacket const * Write() override
virtual uint32 GetCreatureEntry(ObjectGuid::LowType, CreatureData const *data)
Definition: ZoneScript.cpp:29
virtual void OnCreatureRemove(Creature *)
Definition: ZoneScript.h:72
virtual void OnCreatureCreate(Creature *)
Definition: ZoneScript.h:71
#define sWorld
Definition: World.h:931
@ CONFIG_CORPSE_DECAY_ELITE
Definition: World.h:331
@ CONFIG_NO_GRAY_AGGRO_BELOW
Definition: World.h:424
@ CONFIG_CORPSE_DECAY_OBSOLETE
Definition: World.h:333
@ CONFIG_CREATURE_PICKPOCKET_REFILL
Definition: World.h:415
@ CONFIG_RESPAWN_DYNAMICMODE
Definition: World.h:430
@ CONFIG_MAX_PLAYER_LEVEL
Definition: World.h:259
@ CONFIG_CORPSE_DECAY_MINUSMOB
Definition: World.h:336
@ CONFIG_CORPSE_DECAY_NORMAL
Definition: World.h:330
@ CONFIG_CORPSE_DECAY_TRIVIAL
Definition: World.h:335
@ CONFIG_NO_GRAY_AGGRO_ABOVE
Definition: World.h:423
@ CONFIG_CREATURE_STOP_FOR_PLAYER
Definition: World.h:416
@ CONFIG_CORPSE_DECAY_RARE
Definition: World.h:334
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition: World.h:316
@ CONFIG_CORPSE_DECAY_RAREELITE
Definition: World.h:332
@ CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY
Definition: World.h:314
@ CONFIG_REGEN_HP_CANNOT_REACH_TARGET_IN_RAID
Definition: World.h:196
@ RATE_CREATURE_DAMAGE_NORMAL
Definition: World.h:500
@ RATE_CREATURE_DAMAGE_RAREELITE
Definition: World.h:502
@ RATE_CREATURE_AGGRO
Definition: World.h:514
@ RATE_CREATURE_HP_ELITE
Definition: World.h:494
@ RATE_CREATURE_HP_RARE
Definition: World.h:497
@ RATE_CREATURE_DAMAGE_ELITE
Definition: World.h:501
@ RATE_CREATURE_SPELLDAMAGE_TRIVIAL
Definition: World.h:512
@ RATE_CREATURE_SPELLDAMAGE_NORMAL
Definition: World.h:507
@ RATE_POWER_MANA
Definition: World.h:454
@ RATE_CREATURE_SPELLDAMAGE_RAREELITE
Definition: World.h:509
@ RATE_HEALTH
Definition: World.h:453
@ RATE_CREATURE_HP_OBSOLETE
Definition: World.h:496
@ RATE_CREATURE_DAMAGE_OBSOLETE
Definition: World.h:503
@ RATE_CREATURE_DAMAGE_MINUSMOB
Definition: World.h:506
@ RATE_POWER_FOCUS
Definition: World.h:457
@ RATE_CREATURE_HP_NORMAL
Definition: World.h:493
@ RATE_CREATURE_HP_MINUSMOB
Definition: World.h:499
@ RATE_CREATURE_HP_TRIVIAL
Definition: World.h:498
@ RATE_CORPSE_DECAY_LOOTED
Definition: World.h:524
@ RATE_CREATURE_DAMAGE_RARE
Definition: World.h:504
@ RATE_CREATURE_DAMAGE_TRIVIAL
Definition: World.h:505
@ RATE_CREATURE_SPELLDAMAGE_ELITE
Definition: World.h:508
@ RATE_CREATURE_SPELLDAMAGE_MINUSMOB
Definition: World.h:513
@ RATE_CREATURE_HP_RAREELITE
Definition: World.h:495
@ RATE_CREATURE_SPELLDAMAGE_OBSOLETE
Definition: World.h:510
@ RATE_CREATURE_SPELLDAMAGE_RARE
Definition: World.h:511
@ CONFIG_SIGHT_MONSTER
Definition: World.h:208
@ CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS
Definition: World.h:212
@ CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS
Definition: World.h:213
ObjectData const creatureData[]
TC_GAME_API uint32 GetId(std::string_view username)
void apply(T *val)
Definition: ByteConverter.h:41
CreatureAI * SelectAI(Creature *creature)
time_t GetGameTime()
Definition: GameTime.cpp:44
Definition: wmo.h:163
TC_GAME_API WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &)
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomWeightedContainerElement(C const &container, std::span< double > const &weights) -> decltype(std::begin(container))
Definition: Containers.h:126
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition: MapUtils.h:29
void MultimapErasePair(M< K, V, Rest... > &multimap, K const &key, V const &value)
Definition: MapUtils.h:39
XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
Definition: Formulas.h:87
bool IsValidMapCoord(float c)
Definition: GridDefines.h:231
GridCoord ComputeGridCoord(float x, float y)
Definition: GridDefines.h:194
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:203
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:191
bool NoBirthAnim
Definition: Object.h:83
std::vector< uint32 > auras
Definition: CreatureData.h:646
uint16 meleeAnimKit
Definition: CreatureData.h:645
uint16 movementAnimKit
Definition: CreatureData.h:644
uint16 aiAnimKit
Definition: CreatureData.h:643
VisibilityDistanceType visibilityDistanceType
Definition: CreatureData.h:647
uint32 RangedAttackPower
Definition: CreatureData.h:561
static CreatureBaseStats const * GetBaseStats(uint8 level, uint8 unitClass)
Definition: Creature.cpp:295
float wander_distance
Definition: CreatureData.h:593
Optional< uint64 > npcflag
Definition: CreatureData.h:598
uint8 movementType
Definition: CreatureData.h:597
Optional< CreatureModel > display
Definition: CreatureData.h:591
uint32 curhealth
Definition: CreatureData.h:595
uint32 curmana
Definition: CreatureData.h:596
Optional< uint32 > unit_flags2
Definition: CreatureData.h:600
uint32 currentwaypoint
Definition: CreatureData.h:594
Optional< uint32 > unit_flags3
Definition: CreatureData.h:601
Optional< uint32 > unit_flags
Definition: CreatureData.h:599
int32 GetHealthScalingExpansion() const
Definition: CreatureData.h:459
CreatureStaticFlagsHolder StaticFlags
Definition: CreatureData.h:456
std::bitset< MAX_MECHANIC > Mechanic
Definition: SpellMgr.h:611
std::vector< SpellEffectName > Effect
Definition: SpellMgr.h:612
EnumFlag< SpellOtherImmunity > Other
Definition: SpellMgr.h:614
std::bitset< MAX_SPELL_SCHOOL > School
Definition: SpellMgr.h:609
std::bitset< DISPEL_MAX > DispelType
Definition: SpellMgr.h:610
std::vector< AuraType > Aura
Definition: SpellMgr.h:613
uint32 CreatureDisplayID
Definition: CreatureData.h:432
static CreatureModel const DefaultVisibleModel
Definition: CreatureData.h:424
static CreatureModel const DefaultInvisibleModel
Definition: CreatureData.h:423
CreatureRandomMovementType Random
Definition: CreatureData.h:399
std::string ToString() const
Definition: Creature.cpp:61
CreatureChaseMovementType Chase
Definition: CreatureData.h:398
void InitializeQueryData()
Definition: Creature.cpp:162
CreatureModel const * GetRandomValidModel() const
Definition: Creature.cpp:107
CreatureModel const * GetModelByIdx(uint32 idx) const
Definition: Creature.cpp:102
CreatureDifficulty const * GetDifficulty(Difficulty difficulty) const
Definition: Creature.cpp:238
uint32 RangeAttackTime
Definition: CreatureData.h:500
CreatureClassifications Classification
Definition: CreatureData.h:497
CreatureModel const * GetFirstInvisibleModel() const
Definition: Creature.cpp:142
int32 CreatureImmunitiesId
Definition: CreatureData.h:522
CreatureFamily family
Definition: CreatureData.h:507
std::string Name
Definition: CreatureData.h:483
uint32 spells[MAX_CREATURE_SPELLS]
Definition: CreatureData.h:511
int32 resistance[MAX_SPELL_SCHOOL]
Definition: CreatureData.h:510
CreatureModel const * GetFirstValidModel() const
Definition: Creature.cpp:124
std::string StringId
Definition: CreatureData.h:525
CreatureMovementData Movement
Definition: CreatureData.h:515
uint32 KillCredit[MAX_KILL_CREDIT]
Definition: CreatureData.h:481
CreatureModel const * GetModelWithDisplayId(uint32 displayId) const
Definition: Creature.cpp:133
WorldPacket QueryData[TOTAL_LOCALES]
Definition: CreatureData.h:526
CreatureModel const * GetFirstVisibleModel() const
Definition: Creature.cpp:152
std::unordered_map< Difficulty, CreatureDifficulty > difficultyStore
Definition: CreatureData.h:489
std::string FemaleName
Definition: CreatureData.h:484
WorldPacket BuildQueryData(LocaleConstant loc, Difficulty difficulty) const
Definition: Creature.cpp:168
uint8 FallbackDifficultyID
EquipmentItem Items[MAX_EQUIPMENT_ITEMS]
Definition: CreatureData.h:584
uint16 AppearanceModId
Definition: CreatureData.h:578
uint16 ItemVisual
Definition: CreatureData.h:579
Definition: Loot.h:281
struct MovementInfo::TransportInfo transport
constexpr void SetOrientation(float orientation)
Definition: Position.h:71
constexpr float GetPositionX() const
Definition: Position.h:76
float m_positionZ
Definition: Position.h:55
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr bool IsInDist2d(float x, float y, float dist) const
Definition: Position.h:140
std::string ToString() const
Definition: Position.cpp:128
float m_positionX
Definition: Position.h:53
float m_positionY
Definition: Position.h:54
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
bool IsPositionValid() const
Definition: Position.cpp:42
constexpr void Relocate(float x, float y)
Definition: Position.h:63
constexpr Position GetPosition() const
Definition: Position.h:84
constexpr bool IsInDist(float x, float y, float z, float dist) const
Definition: Position.h:143
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78
ObjectGuid::LowType spawnId
Definition: Map.h:168
time_t respawnTime
Definition: Map.h:170
SpawnObjectType type
Definition: Map.h:167
uint8 phaseUseFlags
Definition: SpawnData.h:106
uint32 id
Definition: SpawnData.h:104
uint32 phaseId
Definition: SpawnData.h:107
Position spawnPoint
Definition: SpawnData.h:105
int32 spawntimesecs
Definition: SpawnData.h:111
int32 terrainSwapMap
Definition: SpawnData.h:109
uint32 phaseGroup
Definition: SpawnData.h:108
uint32 poolId
Definition: SpawnData.h:110
std::string StringId
Definition: SpawnData.h:114
std::vector< Difficulty > spawnDifficulties
Definition: SpawnData.h:112
std::string name
Definition: SpawnData.h:68
SpawnGroupFlags flags
Definition: SpawnData.h:70
SpawnGroupTemplateData const * spawnGroupData
Definition: SpawnData.h:96
uint64 spawnId
Definition: SpawnData.h:93
uint32 mapId
Definition: SpawnData.h:94
UpdateField< int32, 32, 39 > ScalingLevelDelta
Definition: UpdateFields.h:300
UpdateField< int32, 32, 38 > ScalingLevelMax
Definition: UpdateFields.h:299
UpdateField< uint32, 0, 7 > StateAnimID
Definition: UpdateFields.h:269
UpdateField< ObjectGuid, 0, 19 > Target
Definition: UpdateFields.h:281
UpdateField< int32, 32, 37 > ScalingLevelMin
Definition: UpdateFields.h:298
UpdateField< int32, 96, 120 > TaxiNodesID
Definition: UpdateFields.h:385
UpdateField< int32, 32, 36 > ContentTuningID
Definition: UpdateFields.h:297
time_t lastIncrementTime
Definition: Creature.h:46
VendorItemCount(uint32 _item, uint32 _count)
Definition: Creature.cpp:76
uint32 count
Definition: Creature.h:45
std::vector< VendorItem > m_items
Definition: CreatureData.h:667
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const
Definition: Creature.cpp:91
bool RemoveItem(uint32 item_id, uint8 type)
Definition: Creature.cpp:79
uint32 item
Definition: CreatureData.h:655
uint32 maxcount
Definition: CreatureData.h:656
uint32 incrtime
Definition: CreatureData.h:657
std::vector< CreatureXDisplay > CreatureDisplay
Definition: QueryPackets.h:59
std::array< uint32, 2 > Flags
Definition: QueryPackets.h:84
CreatureDisplayStats Display
Definition: QueryPackets.h:70
std::array< std::string, 4 > Name
Definition: QueryPackets.h:86
std::array< std::string, 4 > NameAlt
Definition: QueryPackets.h:87
std::array< uint32, 2 > ProxyCreatureID
Definition: QueryPackets.h:85