TrinityCore
Loading...
Searching...
No Matches
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 "CombatPackets.h"
22#include "Common.h"
23#include "Containers.h"
24#include "CreatureAI.h"
25#include "CreatureAISelector.h"
26#include "CreatureGroups.h"
27#include "DatabaseEnv.h"
28#include "Formulas.h"
29#include "GameEventMgr.h"
30#include "GameTime.h"
31#include "GossipDef.h"
32#include "GridNotifiersImpl.h"
33#include "Group.h"
34#include "GroupMgr.h"
35#include "InstanceScript.h"
36#include "Log.h"
37#include "LootMgr.h"
38#include "MapManager.h"
39#include "MotionMaster.h"
40#include "MoveSpline.h"
41#include "ObjectAccessor.h"
42#include "ObjectMgr.h"
43#include "Player.h"
44#include "PoolMgr.h"
45#include "QueryPackets.h"
46#include "QuestDef.h"
47#include "ScriptedGossip.h"
48#include "SpellAuraEffects.h"
49#include "SpellMgr.h"
50#include "TemporarySummon.h"
51#include "Transport.h"
52#include "Util.h"
53#include "Vehicle.h"
54#include "World.h"
55#include "WorldPacket.h"
56#include <G3D/g3dmath.h>
57
60
62{
63 char const* const GroundStates[] = { "None", "Run", "Hover" };
64 char const* const FlightStates[] = { "None", "DisableGravity", "CanFly" };
65 char const* const ChaseStates[] = { "Run", "CanWalk", "AlwaysWalk" };
66 char const* const RandomStates[] = { "Walk", "CanRun", "AlwaysRun" };
67
68 std::ostringstream str;
69 str << std::boolalpha
70 << "Ground: " << GroundStates[AsUnderlyingType(Ground)]
71 << ", Swim: " << Swim
72 << ", Flight: " << FlightStates[AsUnderlyingType(Flight)]
73 << ", Chase: " << ChaseStates[AsUnderlyingType(Chase)]
74 << ", Random: " << RandomStates[AsUnderlyingType(Random)];
75 if (Rooted)
76 str << ", Rooted";
77 str << ", InteractionPauseTimer: " << InteractionPauseTimer;
78
79 return str.str();
80}
81
83 : itemId(_item), count(_count), lastIncrementTime(GameTime::GetGameTime()) { }
84
86{
88}
89
91{
92 auto newEnd = std::remove_if(m_items.begin(), m_items.end(), [=](VendorItem const& vendorItem)
93 {
94 return vendorItem.item == item_id;
95 });
96
97 bool found = (newEnd != m_items.end());
98 m_items.erase(newEnd, m_items.end());
99 return found;
100}
101
102VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost) const
103{
104 for (VendorItem const& vendorItem : m_items)
105 if (vendorItem.item == item_id && vendorItem.ExtendedCost == extendedCost)
106 return &vendorItem;
107 return nullptr;
108}
109
111{
112 uint8 c = 0;
113 uint32 modelIDs[4];
114
115 if (Modelid1) modelIDs[c++] = Modelid1;
116 if (Modelid2) modelIDs[c++] = Modelid2;
117 if (Modelid3) modelIDs[c++] = Modelid3;
118 if (Modelid4) modelIDs[c++] = Modelid4;
119
120 return ((c>0) ? modelIDs[urand(0, c-1)] : 0);
121}
122
124{
125 if (Modelid1) return Modelid1;
126 if (Modelid2) return Modelid2;
127 if (Modelid3) return Modelid3;
128 if (Modelid4) return Modelid4;
129 return 0;
130}
131
133{
134 CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid1);
135 if (modelInfo && modelInfo->is_trigger)
136 return Modelid1;
137
138 modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid2);
139 if (modelInfo && modelInfo->is_trigger)
140 return Modelid2;
141
142 modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid3);
143 if (modelInfo && modelInfo->is_trigger)
144 return Modelid3;
145
146 modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid4);
147 if (modelInfo && modelInfo->is_trigger)
148 return Modelid4;
149
150 return 11686;
151}
152
154{
155 CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid1);
156 if (modelInfo && !modelInfo->is_trigger)
157 return Modelid1;
158
159 modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid2);
160 if (modelInfo && !modelInfo->is_trigger)
161 return Modelid2;
162
163 modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid3);
164 if (modelInfo && !modelInfo->is_trigger)
165 return Modelid3;
166
167 modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid4);
168 if (modelInfo && !modelInfo->is_trigger)
169 return Modelid4;
170
171 return 17519;
172}
173
175{
176 for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc)
177 QueryData[loc] = BuildQueryData(static_cast<LocaleConstant>(loc));
178}
179
181{
183
184 std::string locName = Name, locTitle = Title;
185 if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(Entry))
186 {
187 ObjectMgr::GetLocaleString(cl->Name, loc, locName);
188 ObjectMgr::GetLocaleString(cl->Title, loc, locTitle);
189 }
190
191 queryTemp.CreatureID = Entry;
192 queryTemp.Allow = true;
193
194 queryTemp.Stats.Name = locName;
195 queryTemp.Stats.Title = locTitle;
196 queryTemp.Stats.CursorName = IconName;
197 queryTemp.Stats.Flags = type_flags;
198 queryTemp.Stats.CreatureType = type;
199 queryTemp.Stats.CreatureFamily = family;
200 queryTemp.Stats.Classification = rank;
201 memcpy(queryTemp.Stats.ProxyCreatureID, KillCredit, sizeof(uint32) * MAX_KILL_CREDIT);
202 queryTemp.Stats.CreatureDisplayID[0] = Modelid1;
203 queryTemp.Stats.CreatureDisplayID[1] = Modelid2;
204 queryTemp.Stats.CreatureDisplayID[2] = Modelid3;
205 queryTemp.Stats.CreatureDisplayID[3] = Modelid4;
206 queryTemp.Stats.HpMulti = ModHealth;
207 queryTemp.Stats.EnergyMulti = ModMana;
208 queryTemp.Stats.Leader = RacialLeader;
209
210 for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
211 queryTemp.Stats.QuestItems[i] = 0;
212
213 if (std::vector<uint32> const* items = sObjectMgr->GetCreatureQuestItemList(Entry))
214 for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
215 if (i < items->size())
216 queryTemp.Stats.QuestItems[i] = (*items)[i];
217
219 queryTemp.Write();
220 queryTemp.ShrinkToFit();
221 return queryTemp.Move();
222}
223
224bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
225{
227 {
228 while (!m_assistants.empty())
229 {
231 m_assistants.pop_front();
232
233 if (assistant && assistant->CanAssistTo(&m_owner, victim))
234 {
235 assistant->SetNoCallAssistance(true);
236 assistant->EngageWithTarget(victim);
237 }
238 }
239 }
240 return true;
241}
242
244{
245 return sObjectMgr->GetCreatureBaseStats(level, unitClass);
246}
247
249{
250 m_owner.DespawnOrUnsummon(0s, m_respawnTimer); // since we are here, we are not TempSummon as object type cannot change during runtime
251 return true;
252}
253
254Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), m_groupLootTimer(0), m_PlayerDamageReq(0), _pickpocketLootRestore(0),
255 m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_ignoreCorpseDecayRatio(false), m_wanderDistance(0.0f),
256 m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
257 m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0),
258 m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_cannotReachTarget(false), m_cannotReachTimer(0),
259 m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_baseAttackPower(0), m_baseRangedAttackPower(0), m_originalEntry(0),
260 m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_stringIds(),
261 _waypointPathId(0), _currentWaypointNodeInfo(0, 0), m_formation(nullptr), m_triggerJustAppeared(true), m_respawnCompatibilityMode(false),
262 _lastDamagedTime(0), _regenerateHealth(true), _regenerateHealthLock(false), _isMissingCanSwimFlagOutOfCombat(false)
263{
266
267 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
268 m_spells[i] = 0;
269
270 DisableReputationGain = false;
271
273 m_CombatDistance = 0;//MELEE_RANGE;
274
275 ResetLootMode(); // restore default loot mode
276 m_isTempWorldObject = false;
277}
278
280{
282 if (!IsInWorld())
283 {
285 if (m_spawnId)
286 GetMap()->GetCreatureBySpawnIdStore().insert(std::make_pair(m_spawnId, this));
287
288 TC_LOG_DEBUG("entities.unit", "Adding creature {} with DBGUID {} to world in map {}", GetGUID().ToString(), m_spawnId, GetMap()->GetId());
289
293 if (IsVehicle())
295
296 if (GetZoneScript())
298 }
299}
300
302{
303 if (IsInWorld())
304 {
305 if (GetZoneScript())
307
308 if (m_formation)
309 sFormationMgr->RemoveCreatureFromGroup(m_formation, this);
310
312
313 if (m_spawnId)
314 Trinity::Containers::MultimapErasePair(GetMap()->GetCreatureBySpawnIdStore(), m_spawnId, this);
315
316 TC_LOG_DEBUG("entities.unit", "Removing creature {} with DBGUID {} to world in map {}", GetGUID().ToString(), m_spawnId, GetMap()->GetId());
318 }
319}
320
322{
323 if (GetMotionMaster()->GetCurrentMovementGeneratorType() == HOME_MOTION_TYPE)
324 return true;
325
326 return false;
327}
328
330{
331 if (IsSummon())
332 return;
333
335 if (!lowguid)
336 return;
337
338 if (FormationInfo const* formationInfo = sFormationMgr->GetFormationInfo(lowguid))
339 sFormationMgr->AddCreatureToGroup(formationInfo->LeaderSpawnId, this);
340}
341
343{
344 if (!m_formation)
345 return false;
346
347 return m_formation->IsLeader(this);
348}
349
351{
352 if (!m_formation)
353 return;
354
355 if (!m_formation->IsLeader(this))
356 return;
357
359}
360
362{
363 if (!m_formation)
364 return false;
365
367}
368
369void Creature::RemoveCorpse(bool setSpawnTime, bool destroyForNearbyPlayers)
370{
371 if (getDeathState() != CORPSE)
372 return;
373
375 {
379 loot.clear();
380 uint32 respawnDelay = m_respawnDelay;
381 if (CreatureAI* ai = AI())
382 ai->CorpseRemoved(respawnDelay);
383
384 if (destroyForNearbyPlayers)
386
387 // Should get removed later, just keep "compatibility" with scripts
388 if (setSpawnTime)
389 m_respawnTime = std::max<time_t>(GameTime::GetGameTime() + respawnDelay, m_respawnTime);
390
391 // if corpse was removed during falling, the falling will continue and override relocation to respawn position
392 if (IsFalling())
393 StopMoving();
394
395 float x, y, z, o;
396 GetRespawnPosition(x, y, z, &o);
397
398 // We were spawned on transport, calculate real position
400 {
402 pos.m_positionX = x;
403 pos.m_positionY = y;
404 pos.m_positionZ = z;
405 pos.SetOrientation(o);
406
407 if (TransportBase* transport = GetDirectTransport())
408 transport->CalculatePassengerPosition(x, y, z, &o);
409 }
410
411 UpdateAllowedPositionZ(x, y, z);
412 SetHomePosition(x, y, z, o);
413 GetMap()->CreatureRelocation(this, x, y, z, o);
414 }
415 else
416 {
417 if (CreatureAI* ai = AI())
418 ai->CorpseRemoved(m_respawnDelay);
419
420 // In case this is called directly and normal respawn timer not set
421 // Since this timer will be longer than the already present time it
422 // will be ignored if the correct place added a respawn timer
423 if (setSpawnTime)
424 {
425 uint32 respawnDelay = m_respawnDelay;
426 m_respawnTime = std::max<time_t>(GameTime::GetGameTime() + respawnDelay, m_respawnTime);
427
429 }
430
431 if (TempSummon* summon = ToTempSummon())
432 summon->UnSummon();
433 else
435 }
436}
437
441bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
442{
443 CreatureTemplate const* normalInfo = sObjectMgr->GetCreatureTemplate(entry);
444 if (!normalInfo)
445 {
446 TC_LOG_ERROR("sql.sql", "Creature::InitEntry creature entry {} does not exist.", entry);
447 return false;
448 }
449
450 // get difficulty 1 mode entry, skip for pets
451 CreatureTemplate const* cinfo = normalInfo;
452 for (uint8 diff = uint8(GetMap()->GetSpawnMode()); diff > 0 && !IsPet();)
453 {
454 // we already have valid Map pointer for current creature!
455 if (normalInfo->DifficultyEntry[diff - 1])
456 {
457 cinfo = sObjectMgr->GetCreatureTemplate(normalInfo->DifficultyEntry[diff - 1]);
458 if (cinfo)
459 break; // template found
460
461 // check and reported at startup, so just ignore (restore normalInfo)
462 cinfo = normalInfo;
463 }
464
465 // for instances heroic to normal, other cases attempt to retrieve previous difficulty
466 if (diff >= RAID_DIFFICULTY_10MAN_HEROIC && GetMap()->IsRaid())
467 diff -= 2; // to normal raid difficulty cases
468 else
469 --diff;
470 }
471
472 // Initialize loot duplicate count depending on raid difficulty
473 if (GetMap()->Is25ManRaid())
475
476 SetEntry(entry); // normal entry always
477 m_creatureInfo = cinfo; // map mode related always
478
479 // equal to player Race field, but creature does not have race
481
482 // known valid are: CLASS_WARRIOR, CLASS_PALADIN, CLASS_ROGUE, CLASS_MAGE
483 SetClass(uint8(cinfo->unit_class));
484
485 // Cancel load if no model defined
486 if (!(cinfo->GetFirstValidModelId()))
487 {
488 TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has no model defined in table `creature_template`, can't load. ", entry);
489 return false;
490 }
491
493 CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID);
494 if (!minfo) // Cancel load if no model defined
495 {
496 TC_LOG_ERROR("sql.sql", "Creature (Entry: {}) has invalid model {} defined in table `creature_template`, can't load.", entry, displayID);
497 return false;
498 }
499
500 SetDisplayId(displayID);
501 SetNativeDisplayId(displayID);
502
503 // Load creature equipment
504 if (!data)
505 LoadEquipment(); // use default equipment (if available) for summons
506 else if (data->equipmentId == 0)
507 LoadEquipment(0); // 0 means no equipment for creature table
508 else
509 {
512 }
513
514 SetName(normalInfo->Name); // at normal entry always
515
516 SetModCastingSpeed(1.0f);
517
520 SetSpeedRate(MOVE_SWIM, 1.0f); // using 1.0 rate
521 SetSpeedRate(MOVE_FLIGHT, 1.0f); // using 1.0 rate
522
523 // Will set UNIT_FIELD_BOUNDINGRADIUS and UNIT_FIELD_COMBATREACH
525
527
529
530 // checked at loading
534
535 for (uint8 i = 0; i < MAX_CREATURE_SPELLS; ++i)
537
538 return true;
539}
540
541bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, bool updateLevel /* = true */)
542{
543 if (!InitEntry(entry, data))
544 return false;
545
546 CreatureTemplate const* cInfo = GetCreatureTemplate();
547
549
550 // creatures always have melee weapon ready if any unless specified otherwise
551 if (!GetCreatureAddon())
553
554 SetFaction(cInfo->faction);
555
556 uint32 npcFlags, unitFlags, dynamicFlags;
557 ObjectMgr::ChooseCreatureFlags(cInfo, &npcFlags, &unitFlags, &dynamicFlags, data);
558
560 npcFlags |= sGameEventMgr->GetNPCFlag(this);
561
562 ReplaceAllNpcFlags(NPCFlags(npcFlags));
563
564 // if unit is in combat, keep this flag
565 unitFlags &= ~UNIT_FLAG_IN_COMBAT;
566 if (IsInCombat())
567 unitFlags |= UNIT_FLAG_IN_COMBAT;
568
569 ReplaceAllUnitFlags(UnitFlags(unitFlags));
571
572 ReplaceAllDynamicFlags(dynamicFlags);
573
575
579
580 if (updateLevel)
581 SelectLevel();
582
583 // Do not update guardian stats here - they are handled in Guardian::InitStatsForLevel()
584 if (!IsGuardian())
585 {
586 uint32 previousHealth = GetHealth();
588 if (previousHealth > 0)
589 SetHealth(previousHealth);
590
598
599 SetCanModifyStats(true);
601 }
602
603 // checked and error show at loading templates
604 if (FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction))
605 SetPvP((factionTemplate->Flags & FACTION_TEMPLATE_FLAG_PVP) != 0);
606
607 // updates spell bars for vehicles and set player's faction - should be called here, to overwrite faction that is set from the new template
608 if (IsVehicle())
609 {
610 if (Player* owner = Creature::GetCharmerOrOwnerPlayerOrPlayerItself()) // this check comes in case we don't have a player
611 {
612 SetFaction(owner->GetFaction()); // vehicles should have same as owner faction
613 owner->VehicleSpellInitialize();
614 }
615 }
616
617 // trigger creature is always uninteractible and can not be attacked
618 if (IsTrigger())
620
622
624 {
627 }
628
630
635
637
638 //We must update last scriptId or it looks like we reloaded a script, breaking some things such as gossip temporarily
640
642
643 if (IsSpiritGuide() && sWorld->IsFFAPvPRealm())
644 {
645 // client will only send spirit guide query for units that can assist them
646 // for ffa pvp flagged players its only other ffa pvp flagged units
648 }
649
650 return true;
651}
652
653void Creature::SetPhaseMask(uint32 newPhaseMask, bool update)
654{
655 if (newPhaseMask == GetPhaseMask())
656 return;
657
658 Unit::SetPhaseMask(newPhaseMask, false);
659
660 if (Vehicle* vehicle = GetVehicleKit())
661 {
662 for (auto seat = vehicle->Seats.begin(); seat != vehicle->Seats.end(); seat++)
663 if (Unit* passenger = ObjectAccessor::GetUnit(*this, seat->second.Passenger.Guid))
664 passenger->SetPhaseMask(newPhaseMask, update);
665 }
666
667 if (update)
669}
670
672{
674 {
677 m_triggerJustAppeared = false;
678 AI()->JustAppeared();
679 }
680
682
683 switch (m_deathState)
684 {
685 case JUST_RESPAWNED:
686 // Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting.
687 TC_LOG_ERROR("entities.unit", "Creature {} in wrong state: JUST_RESPAWNED (4)", GetGUID().ToString());
688 break;
689 case JUST_DIED:
690 // Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
691 TC_LOG_ERROR("entities.unit", "Creature {} in wrong state: JUST_DIED (1)", GetGUID().ToString());
692 break;
693 case DEAD:
694 {
696 {
697 TC_LOG_ERROR("entities.unit", "Creature {} in wrong state: DEAD (3)", GetGUID().ToString());
698 break;
699 }
700 time_t now = GameTime::GetGameTime();
701 if (m_respawnTime <= now)
702 {
703 // Delay respawn if spawn group is not active
704 if (m_creatureData && !GetMap()->IsSpawnGroupActive(m_creatureData->spawnGroupData->groupId))
705 {
706 m_respawnTime = now + urand(4,7);
707 break; // Will be rechecked on next Update call after delay expires
708 }
709
710 ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Unit>(GetEntry(), m_spawnId);
711 time_t linkedRespawnTime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
712 if (!linkedRespawnTime) // Can respawn
713 Respawn();
714 else // the master is dead
715 {
716 ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
717 if (targetGuid == dbtableHighGuid) // if linking self, never respawn
719 else
720 {
721 // else copy time from master and add a little
722 time_t baseRespawnTime = std::max(linkedRespawnTime, now);
723 time_t const offset = urand(5, MINUTE);
724
725 // linked guid can be a boss, uses std::numeric_limits<time_t>::max to never respawn in that instance
726 // we shall inherit it instead of adding and causing an overflow
727 if (baseRespawnTime <= std::numeric_limits<time_t>::max() - offset)
728 m_respawnTime = baseRespawnTime + offset;
729 else
730 m_respawnTime = std::numeric_limits<time_t>::max();
731 }
732 SaveRespawnTime(); // also save to DB immediately
733 }
734 }
735 break;
736 }
737 case CORPSE:
738 {
739 Unit::Update(diff);
740 // deathstate changed on spells update, prevent problems
741 if (m_deathState != CORPSE)
742 break;
743
744 if (IsEngaged())
745 Unit::AIUpdateTick(diff);
746
748 {
749 if (m_groupLootTimer <= diff)
750 {
751 if (Group* group = sGroupMgr->GetGroupByGUID(lootingGroupLowGUID))
752 group->EndRoll(&loot, GetMap());
753
756 }
757 else
758 m_groupLootTimer -= diff;
759 }
761 {
762 RemoveCorpse(false);
763 TC_LOG_DEBUG("entities.unit", "Removing corpse... {} ", GetEntry());
764 }
765 break;
766 }
767 case ALIVE:
768 {
769 Unit::Update(diff);
770
771 // creature can be dead after Unit::Update call
772 // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
773 if (!IsAlive())
774 break;
775
776 GetThreatManager().Update(diff);
777 if (_spellFocusInfo.Delay)
778 {
779 if (_spellFocusInfo.Delay <= diff)
781 else
782 _spellFocusInfo.Delay -= diff;
783 }
784
785 // periodic check to see if the creature has passed an evade boundary
786 if (IsAIEnabled() && !IsInEvadeMode() && IsEngaged())
787 {
788 if (diff >= m_boundaryCheckTime)
789 {
790 AI()->CheckInRoom();
791 m_boundaryCheckTime = 2500;
792 } else
793 m_boundaryCheckTime -= diff;
794 }
795
796 // if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now
797 if (m_combatPulseDelay > 0 && IsEngaged() && GetMap()->IsDungeon())
798 {
799 if (diff > m_combatPulseTime)
801 else
802 m_combatPulseTime -= diff;
803
804 if (m_combatPulseTime == 0)
805 {
806 Map::PlayerList const& players = GetMap()->GetPlayers();
807 if (!players.isEmpty())
808 for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
809 {
810 if (Player* player = it->GetSource())
811 {
812 if (player->IsGameMaster())
813 continue;
814
815 if (player->IsAlive() && IsHostileTo(player))
816 EngageWithTarget(player);
817 }
818 }
819
821 }
822 }
823
824 Unit::AIUpdateTick(diff);
825
826 // creature can be dead after UpdateAI call
827 // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
828 if (!IsAlive())
829 break;
830
831 if (m_regenTimer > 0)
832 {
833 if (diff >= m_regenTimer)
834 m_regenTimer = 0;
835 else
836 m_regenTimer -= diff;
837 }
838
839 if (m_regenTimer == 0)
840 {
841 if (!IsInEvadeMode())
842 {
843 // regenerate health if not in combat or if polymorphed)
844 if (!IsEngaged() || IsPolymorphed())
846 else if (CanNotReachTarget())
847 {
848 // regenerate health if cannot reach the target and the setting is set to do so.
849 // this allows to disable the health regen of raid bosses if pathfinding has issues for whatever reason
850 if (sWorld->getBoolConfig(CONFIG_REGEN_HP_CANNOT_REACH_TARGET_IN_RAID) || !GetMap()->IsRaid())
851 {
853 TC_LOG_DEBUG("entities.unit.chase", "RegenerateHealth() enabled because Creature cannot reach the target. Detail: {}", GetDebugInfo());
854 }
855 else
856 TC_LOG_DEBUG("entities.unit.chase", "RegenerateHealth() disabled even if the Creature cannot reach the target. Detail: {}", GetDebugInfo());
857 }
858 }
859
860 if (GetPowerType() == POWER_ENERGY)
862 else
864
866 }
867
868 if (CanNotReachTarget() && !IsInEvadeMode() && !GetMap()->IsRaid())
869 {
870 m_cannotReachTimer += diff;
872 if (CreatureAI* ai = AI())
873 ai->EnterEvadeMode(CreatureAI::EVADE_REASON_NO_PATH);
874 }
875 break;
876 }
877 default:
878 break;
879 }
880}
881
883{
884 uint32 curValue = GetPower(power);
885 uint32 maxValue = GetMaxPower(power);
886
888 return;
889
890 if (curValue >= maxValue)
891 return;
892
893 float addvalue = 0.0f;
894
895 switch (power)
896 {
897 case POWER_FOCUS:
898 {
899 // For hunter pets.
900 addvalue = 24 * sWorld->getRate(RATE_POWER_FOCUS);
901 break;
902 }
903 case POWER_ENERGY:
904 {
905 // For deathknight's ghoul.
906 addvalue = 20;
907 break;
908 }
909 case POWER_MANA:
910 {
911 // Combat and any controlled creature
912 if (IsInCombat() || !GetCharmerOrOwnerGUID().IsEmpty())
913 {
915 {
916 float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
917 float Spirit = GetStat(STAT_SPIRIT);
918
919 addvalue = uint32((Spirit / 5.0f + 17.0f) * ManaIncreaseRate);
920 }
921 }
922 else
923 addvalue = maxValue / 3;
924
925 break;
926 }
927 default:
928 return;
929 }
930
931 // Apply modifiers (if any).
933
935
936 ModifyPower(power, int32(addvalue));
937}
938
940{
941 if (!CanRegenerateHealth())
942 return;
943
944 uint32 curValue = GetHealth();
945 uint32 maxValue = GetMaxHealth();
946
947 if (curValue >= maxValue)
948 return;
949
950 uint32 addvalue = 0;
951
952 // Not only pet, but any controlled creature (and not polymorphed)
953 if (!GetCharmerOrOwnerGUID().IsEmpty() && !IsPolymorphed())
954 {
955 float HealthIncreaseRate = sWorld->getRate(RATE_HEALTH);
956 float Spirit = GetStat(STAT_SPIRIT);
957
958 if (GetPower(POWER_MANA) > 0)
959 addvalue = uint32(Spirit * 0.25 * HealthIncreaseRate);
960 else
961 addvalue = uint32(Spirit * 0.80 * HealthIncreaseRate);
962 }
963 else
964 addvalue = maxValue/3;
965
966 // Apply modifiers (if any).
968
970
971 ModifyHealth(addvalue);
972}
973
975{
976 if (!GetVictim())
977 return;
978
980 return;
981
982 float radius = sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS);
983 if (radius >0)
984 {
985 Creature* creature = nullptr;
988 Cell::VisitGridObjects(this, searcher, radius);
989
991
992 if (!creature)
995 else
996 GetMotionMaster()->MoveSeekAssistance(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ());
997 }
998}
999
1001{
1002 PopAI();
1003 RefreshAI();
1004 return true;
1005}
1006
1007bool Creature::AIM_Create(CreatureAI* ai /*= nullptr*/)
1008{
1010
1011 SetAI(ai ? ai : FactorySelector::SelectAI(this));
1012
1013 return true;
1014}
1015
1017{
1018 if (!AIM_Create(ai))
1019 return false;
1020
1021 AI()->InitializeAI();
1022 if (GetVehicleKit())
1023 GetVehicleKit()->Reset();
1024 return true;
1025}
1026
1028{
1029 if (m_formation)
1030 {
1031 if (m_formation->GetLeader() == this)
1033 else if (m_formation->IsFormed())
1034 {
1035 GetMotionMaster()->MoveIdle(); // wait the order of leader
1036 return;
1037 }
1038 }
1039
1041}
1042
1043bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, uint32 entry, Position const& pos, CreatureData const* data /*= nullptr*/, uint32 vehId /*= 0*/, bool dynamic)
1044{
1045 ASSERT(map);
1046 SetMap(map);
1047 SetPhaseMask(phaseMask, false);
1048
1049 // Set if this creature can handle dynamic spawns
1050 if (!dynamic)
1052
1053 CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
1054 if (!cinfo)
1055 {
1056 TC_LOG_ERROR("sql.sql", "Creature::Create(): creature template (guidlow: {}, entry: {}) does not exist.", guidlow, entry);
1057 return false;
1058 }
1059
1062 Relocate(pos);
1063
1064 // Check if the position is valid before calling CreateFromProto(), otherwise we might add Auras to Creatures at
1065 // invalid position, triggering a crash about Auras not removed in the destructor
1066 if (!IsPositionValid())
1067 {
1068 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());
1069 return false;
1070 }
1071 {
1072 // area/zone id is needed immediately for ZoneScript::GetCreatureEntry hook before it is known which creature template to load (no model/scale available yet)
1073 PositionFullTerrainStatus terrainStatus;
1075 ProcessPositionDataChanged(terrainStatus);
1076 }
1077
1078 // Allow players to see those units while dead, do it here (mayby altered by addon auras)
1081
1082 if (!CreateFromProto(guidlow, entry, data, vehId))
1083 return false;
1084
1085 if (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS && map->IsDungeon())
1086 m_respawnDelay = 0; // special value, prevents respawn for dungeon bosses unless overridden
1087
1088 switch (GetCreatureTemplate()->rank)
1089 {
1092 break;
1095 break;
1098 break;
1101 break;
1102 default:
1104 break;
1105 }
1106
1108
1110 {
1113 }
1114
1117
1119 {
1122 }
1123
1125
1126 return true;
1127}
1128
1130{
1131 Unit* target = nullptr;
1132
1133 if (CanHaveThreatList())
1135 else if (!HasReactState(REACT_PASSIVE))
1136 {
1137 // We're a player pet, probably
1138 target = getAttackerForHelper();
1139 if (!target && IsSummon())
1140 {
1141 if (Unit* owner = ToTempSummon()->GetOwner())
1142 {
1143 if (owner->IsInCombat())
1144 target = owner->getAttackerForHelper();
1145 if (!target)
1146 {
1147 for (ControlList::const_iterator itr = owner->m_Controlled.begin(); itr != owner->m_Controlled.end(); ++itr)
1148 {
1149 if ((*itr)->IsInCombat())
1150 {
1151 target = (*itr)->getAttackerForHelper();
1152 if (target)
1153 break;
1154 }
1155 }
1156 }
1157 }
1158 }
1159 }
1160 else
1161 return nullptr;
1162
1163 if (target && _IsTargetAcceptable(target) && CanCreatureAttack(target))
1164 {
1165 if (!HasSpellFocus())
1166 SetInFront(target);
1167 return target;
1168 }
1169
1171 if (GetVehicle())
1172 return nullptr;
1173
1175 if (!iAuras.empty())
1176 {
1177 for (Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
1178 {
1179 if ((*itr)->GetBase()->IsPermanent())
1180 {
1182 break;
1183 }
1184 }
1185 return nullptr;
1186 }
1187
1188 // enter in evade mode in other case
1190
1191 return nullptr;
1192}
1193
1195{
1196 if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService())
1198 /*
1199 else if (IsCivilian())
1200 SetReactState(REACT_DEFENSIVE);
1201 */
1202 else
1204}
1205
1207{
1208 if (!IsBattleMaster())
1209 return false;
1210
1211 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(GetEntry());
1212 if (!msg)
1213 return player->GetBGAccessByLevel(bgTypeId);
1214
1215 if (!player->GetBGAccessByLevel(bgTypeId))
1216 {
1217 ClearGossipMenuFor(player);
1218 switch (bgTypeId)
1219 {
1220 case BATTLEGROUND_AV: SendGossipMenuFor(player, 7616, this); break;
1221 case BATTLEGROUND_WS: SendGossipMenuFor(player, 7599, this); break;
1222 case BATTLEGROUND_AB: SendGossipMenuFor(player, 7642, this); break;
1223 case BATTLEGROUND_EY:
1224 case BATTLEGROUND_NA:
1225 case BATTLEGROUND_BE:
1226 case BATTLEGROUND_AA:
1227 case BATTLEGROUND_RL:
1228 case BATTLEGROUND_SA:
1229 case BATTLEGROUND_DS:
1230 case BATTLEGROUND_RV: SendGossipMenuFor(player, 10024, this); break;
1231 default: break;
1232 }
1233 return false;
1234 }
1235 return true;
1236}
1237
1238bool Creature::CanResetTalents(Player* player, bool pet) const
1239{
1240 Trainer::Trainer const* trainer = sObjectMgr->GetTrainer(GetEntry());
1241 if (!trainer)
1242 return false;
1243
1244 return player->GetLevel() >= 10 &&
1245 (trainer->GetTrainerType() == (pet ? Trainer::Type::Pet : Trainer::Type::Class)) &&
1246 trainer->IsTrainerValidForPlayer(player);
1247}
1248
1250{
1251 if (!m_lootRecipient)
1252 return nullptr;
1253
1255}
1256
1258{
1260 return nullptr;
1261
1262 return sGroupMgr->GetGroupByGUID(m_lootRecipientGroup);
1263}
1264
1265void Creature::SetLootRecipient(Unit* unit, bool withGroup)
1266{
1267 // set the player whose group should receive the right
1268 // to loot the creature after it dies
1269 // should be set to nullptr after the loot disappears
1270
1271 if (!unit)
1272 {
1276 return;
1277 }
1278
1279 if (unit->GetTypeId() != TYPEID_PLAYER && !unit->IsVehicle())
1280 return;
1281
1283 if (!player) // normal creature, no player involved
1284 return;
1285
1286 m_lootRecipient = player->GetGUID();
1287 if (withGroup)
1288 {
1289 if (Group* group = player->GetGroup())
1290 m_lootRecipientGroup = group->GetGUID();
1291 }
1292 else
1294
1296}
1297
1298// return true if this creature is tapped by the player or by a member of his group.
1299bool Creature::isTappedBy(Player const* player) const
1300{
1301 if (player->GetGUID() == m_lootRecipient)
1302 return true;
1303
1304 Group const* playerGroup = player->GetGroup();
1305 if (!playerGroup || playerGroup != GetLootRecipientGroup()) // if we dont have a group we arent the recipient
1306 return false; // if creature doesnt have group bound it means it was solo killed by someone else
1307
1308 return true;
1309}
1310
1312{
1313 // this should only be used when the creature has already been loaded
1314 // preferably after adding to map, because mapid may not be valid otherwise
1315 CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
1316 if (!data)
1317 {
1318 TC_LOG_ERROR("entities.unit", "Creature::SaveToDB failed, cannot get creature data!");
1319 return;
1320 }
1321
1323 SaveToDB(mapId, data->spawnMask, GetPhaseMask());
1324}
1325
1326void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
1327{
1328 // update in loaded data
1329 if (!m_spawnId)
1330 m_spawnId = sObjectMgr->GenerateCreatureSpawnId();
1331
1332 CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId);
1333
1334 uint32 displayId = GetNativeDisplayId();
1335 uint32 npcflag = GetNpcFlags();
1336 uint32 unit_flags = GetUnitFlags();
1337 uint32 dynamicflags = GetDynamicFlags();
1338
1339 // check if it's a custom model and if not, use 0 for displayId
1340 CreatureTemplate const* cinfo = GetCreatureTemplate();
1341 if (cinfo)
1342 {
1343 if (displayId == cinfo->Modelid1 || displayId == cinfo->Modelid2 ||
1344 displayId == cinfo->Modelid3 || displayId == cinfo->Modelid4)
1345 displayId = 0;
1346
1347 if (npcflag == cinfo->npcflag)
1348 npcflag = 0;
1349
1350 if (unit_flags == cinfo->unit_flags)
1351 unit_flags = 0;
1352
1353 if (dynamicflags == cinfo->dynamicflags)
1354 dynamicflags = 0;
1355 }
1356
1357 if (!data.spawnId)
1358 data.spawnId = m_spawnId;
1359 ASSERT(data.spawnId == m_spawnId);
1360 data.id = GetEntry();
1361 data.phaseMask = phaseMask;
1362 data.displayid = displayId;
1364 if (!GetTransport())
1365 {
1366 data.mapId = GetMapId();
1367 data.spawnPoint.Relocate(this);
1368 }
1369 else
1370 {
1371 data.mapId = mapid;
1373 }
1375 // prevent add data integrity problems
1377 data.currentwaypoint = 0;
1378 data.curhealth = GetHealth();
1379 data.curmana = GetPower(POWER_MANA);
1380 // prevent add data integrity problems
1383 data.spawnMask = spawnMask;
1384 data.npcflag = npcflag;
1385 data.unit_flags = unit_flags;
1386 data.dynamicflags = dynamicflags;
1387 if (!data.spawnGroupData)
1388 data.spawnGroupData = sObjectMgr->GetDefaultSpawnGroup();
1389
1390 // update in DB
1391 WorldDatabaseTransaction trans = WorldDatabase.BeginTransaction();
1392
1394 stmt->setUInt32(0, m_spawnId);
1395
1396 trans->Append(stmt);
1397
1398 uint8 index = 0;
1399
1400 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE);
1401 stmt->setUInt32(index++, m_spawnId);
1402 stmt->setUInt32(index++, GetEntry());
1403 stmt->setUInt16(index++, uint16(mapid));
1404 stmt->setUInt8(index++, spawnMask);
1405 stmt->setUInt32(index++, GetPhaseMask());
1406 stmt->setUInt32(index++, displayId);
1407 stmt->setUInt8(index++, GetCurrentEquipmentId());
1408 stmt->setFloat(index++, GetPositionX());
1409 stmt->setFloat(index++, GetPositionY());
1410 stmt->setFloat(index++, GetPositionZ());
1411 stmt->setFloat(index++, GetOrientation());
1412 stmt->setUInt32(index++, m_respawnDelay);
1413 stmt->setFloat(index++, m_wanderDistance);
1414 stmt->setUInt32(index++, 0);
1415 stmt->setUInt32(index++, GetHealth());
1416 stmt->setUInt32(index++, GetPower(POWER_MANA));
1417 stmt->setUInt8(index++, uint8(GetDefaultMovementType()));
1418 stmt->setUInt32(index++, npcflag);
1419 stmt->setUInt32(index++, unit_flags);
1420 stmt->setUInt32(index++, dynamicflags);
1421 trans->Append(stmt);
1422
1423 WorldDatabase.CommitTransaction(trans);
1424}
1425
1427{
1428 CreatureTemplate const* cInfo = GetCreatureTemplate();
1429
1430 // level
1431 uint8 minlevel = std::min(cInfo->maxlevel, cInfo->minlevel);
1432 uint8 maxlevel = std::max(cInfo->maxlevel, cInfo->minlevel);
1433 uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel);
1434 SetLevel(level);
1435}
1436
1438{
1439 CreatureTemplate const* cInfo = GetCreatureTemplate();
1440 uint32 rank = IsPet() ? 0 : cInfo->rank;
1441 CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(GetLevel(), cInfo->unit_class);
1442
1443 // health
1444 float healthmod = _GetHealthMod(rank);
1445
1446 uint32 basehp = stats->GenerateHealth(cInfo);
1447 uint32 health = uint32(basehp * healthmod);
1448
1449 SetCreateHealth(health);
1450 SetMaxHealth(health);
1451 SetHealth(health);
1453
1454 // mana
1455 uint32 mana = stats->GenerateMana(cInfo);
1456 SetCreateMana(mana);
1457
1458 switch (GetClass())
1459 {
1460 case UNIT_CLASS_PALADIN:
1461 case UNIT_CLASS_MAGE:
1462 SetMaxPower(POWER_MANA, mana);
1464 break;
1465 default: // We don't set max power here, 0 makes power bar hidden
1466 break;
1467 }
1468
1470
1471 // damage
1472 float basedamage = stats->GenerateBaseDamage(cInfo);
1473
1474 float weaponBaseMinDamage = basedamage;
1475 float weaponBaseMaxDamage = basedamage * 1.5f;
1476
1477 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1478 SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1479
1480 SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1481 SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1482
1483 SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1484 SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1485
1488
1489 float armor = (float)stats->GenerateArmor(cInfo);
1491}
1492
1494{
1495 switch (Rank) // define rates for each elite rank
1496 {
1498 return sWorld->getRate(RATE_CREATURE_NORMAL_HP);
1500 return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_HP);
1506 return sWorld->getRate(RATE_CREATURE_ELITE_RARE_HP);
1507 default:
1508 return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_HP);
1509 }
1510}
1511
1513{
1515 m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0;
1516}
1517
1519{
1520 switch (Rank) // define rates for each elite rank
1521 {
1523 return sWorld->getRate(RATE_CREATURE_NORMAL_DAMAGE);
1531 return sWorld->getRate(RATE_CREATURE_ELITE_RARE_DAMAGE);
1532 default:
1534 }
1535}
1536
1538{
1539 switch (Rank) // define rates for each elite rank
1540 {
1551 default:
1553 }
1554}
1555
1556bool Creature::CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data /*= nullptr*/, uint32 vehId /*= 0*/)
1557{
1558 SetZoneScript();
1559 if (GetZoneScript() && data)
1560 {
1561 entry = GetZoneScript()->GetCreatureEntry(guidlow, data);
1562 if (!entry)
1563 return false;
1564 }
1565
1566 CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
1567 if (!cinfo)
1568 {
1569 TC_LOG_ERROR("sql.sql", "Creature::CreateFromProto(): creature template (guidlow: {}, entry: {}) does not exist.", guidlow, entry);
1570 return false;
1571 }
1572
1573 SetOriginalEntry(entry);
1574
1575 if (vehId || cinfo->VehicleId)
1576 Object::_Create(ObjectGuid::Create<HighGuid::Vehicle>(entry, guidlow));
1577 else
1578 Object::_Create(ObjectGuid::Create<HighGuid::Unit>(entry, guidlow));
1579
1580 if (!UpdateEntry(entry, data))
1581 return false;
1582
1583 if (!vehId)
1584 {
1585 if (GetCreatureTemplate()->VehicleId)
1586 {
1587 vehId = GetCreatureTemplate()->VehicleId;
1588 entry = GetCreatureTemplate()->Entry;
1589 }
1590 else
1591 vehId = cinfo->VehicleId;
1592 }
1593
1594 if (vehId)
1595 if (CreateVehicleKit(vehId, entry))
1597
1598 return true;
1599}
1600
1601bool Creature::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate)
1602{
1603 if (!allowDuplicate)
1604 {
1605 // If an alive instance of this spawnId is already found, skip creation
1606 // If only dead instance(s) exist, despawn them and spawn a new (maybe also dead) version
1607 const auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(spawnId);
1608 std::vector <Creature*> despawnList;
1609
1610 if (creatureBounds.first != creatureBounds.second)
1611 {
1612 for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr)
1613 {
1614 if (itr->second->IsAlive())
1615 {
1616 TC_LOG_DEBUG("maps", "Would have spawned {} but {} already exists", spawnId, creatureBounds.first->second->GetGUID().ToString());
1617 return false;
1618 }
1619 else
1620 {
1621 despawnList.push_back(itr->second);
1622 TC_LOG_DEBUG("maps", "Despawned dead instance of spawn {} ({})", spawnId, itr->second->GetGUID().ToString());
1623 }
1624 }
1625
1626 for (Creature* despawnCreature : despawnList)
1627 {
1628 despawnCreature->AddObjectToRemoveList();
1629 }
1630 }
1631 }
1632
1633 CreatureData const* data = sObjectMgr->GetCreatureData(spawnId);
1634
1635 if (!data)
1636 {
1637 TC_LOG_ERROR("sql.sql", "Creature (SpawnID {}) not found in table `creature`, can't load. ", spawnId);
1638 return false;
1639 }
1640
1641 m_spawnId = spawnId;
1642
1644 m_creatureData = data;
1647
1648 if (!Create(map->GenerateLowGuid<HighGuid::Unit>(), map, data->phaseMask, data->id, data->spawnPoint, data, 0U , !m_respawnCompatibilityMode))
1649 return false;
1650
1651 //We should set first home position, because then AI calls home movement
1652 SetHomePosition(*this);
1653
1655
1657
1659 {
1661 {
1662 // @todo pools need fixing! this is just a temporary thing, but they violate dynspawn principles
1663 if (!sPoolMgr->IsPartOfAPool<Creature>(spawnId))
1664 {
1665 TC_LOG_ERROR("entities.unit", "Creature (SpawnID {}) trying to load in inactive spawn group '{}':\n{}", spawnId, data->spawnGroupData->name, GetDebugInfo());
1666 return false;
1667 }
1668 }
1669
1671 }
1672
1673 if (m_respawnTime)
1674 {
1676 {
1677 // @todo same as above
1678 if (!sPoolMgr->IsPartOfAPool<Creature>(spawnId))
1679 {
1680 TC_LOG_ERROR("entities.unit", "Creature (SpawnID {}) trying to load despite a respawn timer in progress:\n{}", spawnId, GetDebugInfo());
1681 return false;
1682 }
1683 }
1684 else
1685 {
1686 // compatibility mode creatures will be respawned in ::Update()
1688 }
1689
1690 if (CanFly())
1691 {
1692 float tz = map->GetHeight(GetPhaseMask(), data->spawnPoint, true, MAX_FALL_DISTANCE);
1693 if (data->spawnPoint.GetPositionZ() - tz > 0.1f && Trinity::IsValidMapCoord(tz))
1695 }
1696 }
1697
1699
1700 // checked at creature_template loading
1702
1704
1705 if (addToMap && !GetMap()->AddToMap(this))
1706 return false;
1707 return true;
1708}
1709
1715
1716void Creature::LoadEquipment(int8 id, bool force /*= true*/)
1717{
1718 if (id == 0)
1719 {
1720 if (force)
1721 {
1722 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1723 SetVirtualItem(i, 0);
1724 m_equipmentId = 0;
1725 }
1726
1727 return;
1728 }
1729
1730 EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(GetEntry(), id);
1731 if (!einfo)
1732 return;
1733
1734 m_equipmentId = id;
1735 for (uint8 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
1736 SetVirtualItem(i, einfo->ItemEntry[i]);
1737}
1738
1740{
1742 return;
1743
1744 uint32 curhealth;
1746 {
1747 curhealth = m_creatureData->curhealth;
1748 if (curhealth)
1749 {
1750 curhealth = uint32(curhealth*_GetHealthMod(GetCreatureTemplate()->rank));
1751 if (curhealth < 1)
1752 curhealth = 1;
1753 }
1755 }
1756 else
1757 {
1758 curhealth = GetMaxHealth();
1760 }
1761
1762 SetHealth((m_deathState == ALIVE || m_deathState == JUST_RESPAWNED) ? curhealth : 0);
1763}
1764
1770
1771bool Creature::hasQuest(uint32 quest_id) const
1772{
1773 return sObjectMgr->GetCreatureQuestRelations(GetEntry()).HasQuest(quest_id);
1774}
1775
1777{
1778 return sObjectMgr->GetCreatureQuestInvolvedRelations(GetEntry()).HasQuest(quest_id);
1779}
1780
1782{
1783 CreatureData const* data = sObjectMgr->GetCreatureData(spawnId);
1784 if (!data)
1785 return false;
1786
1787 CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
1788
1789 sMapMgr->DoForAllMapsWithMapId(data->mapId,
1790 [spawnId, charTrans](Map* map) -> void
1791 {
1792 // despawn all active creatures, and remove their respawns
1793 std::vector<Creature*> toUnload;
1794 for (auto const& pair : Trinity::Containers::MapEqualRange(map->GetCreatureBySpawnIdStore(), spawnId))
1795 toUnload.push_back(pair.second);
1796 for (Creature* creature : toUnload)
1797 map->AddObjectToRemoveList(creature);
1798 map->RemoveRespawnTime(SPAWN_TYPE_CREATURE, spawnId, charTrans);
1799 }
1800 );
1801
1802 // delete data from memory ...
1803 sObjectMgr->DeleteCreatureData(spawnId);
1804
1805 CharacterDatabase.CommitTransaction(charTrans);
1806
1807 WorldDatabaseTransaction trans = WorldDatabase.BeginTransaction();
1808
1809 // ... and the database
1811 stmt->setUInt32(0, spawnId);
1812 trans->Append(stmt);
1813
1814 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_SPAWNGROUP_MEMBER);
1816 stmt->setUInt32(1, spawnId);
1817 trans->Append(stmt);
1818
1819 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON);
1820 stmt->setUInt32(0, spawnId);
1821 trans->Append(stmt);
1822
1823 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_CREATURE);
1824 stmt->setUInt32(0, spawnId);
1825 trans->Append(stmt);
1826
1827 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP);
1828 stmt->setUInt32(0, spawnId);
1829 trans->Append(stmt);
1830
1831 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN);
1832 stmt->setUInt32(0, spawnId);
1834 trans->Append(stmt);
1835
1836 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN);
1837 stmt->setUInt32(0, spawnId);
1839 trans->Append(stmt);
1840
1841 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN_MASTER);
1842 stmt->setUInt32(0, spawnId);
1844 trans->Append(stmt);
1845
1846 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_LINKED_RESPAWN_MASTER);
1847 stmt->setUInt32(0, spawnId);
1849 trans->Append(stmt);
1850
1851 WorldDatabase.CommitTransaction(trans);
1852
1853 return true;
1854}
1855
1857{
1859 return true;
1860
1862 return false;
1863
1864 return true;
1865}
1866
1868{
1869 if (IsAIEnabled() && AI()->CanSeeAlways(obj))
1870 return true;
1871
1872 return false;
1873}
1874
1875bool Creature::CanStartAttack(Unit const* who, bool force) const
1876{
1877 if (IsCivilian())
1878 return false;
1879
1880 // This set of checks is should be done only for creatures
1883 return false;
1884
1885 // Do not attack non-combat pets
1887 return false;
1888
1890 //|| who->IsControlledByPlayer() && who->IsFlying()))
1891 // we cannot check flying for other creatures, too much map/vmap calculation
1893 return false;
1894
1895 if (!force)
1896 {
1897 if (!_IsTargetAcceptable(who))
1898 return false;
1899
1901 return false;
1902 }
1903
1904 if (!CanCreatureAttack(who, force))
1905 return false;
1906
1907 // No aggro from gray creatures
1909 return false;
1910
1911 return IsWithinLOSInMap(who);
1912}
1913
1914bool Creature::CheckNoGrayAggroConfig(uint32 playerLevel, uint32 creatureLevel) const
1915{
1916 if (Trinity::XP::GetColorCode(playerLevel, creatureLevel) != XP_GRAY)
1917 return false;
1918
1919 uint32 notAbove = sWorld->getIntConfig(CONFIG_NO_GRAY_AGGRO_ABOVE);
1920 uint32 notBelow = sWorld->getIntConfig(CONFIG_NO_GRAY_AGGRO_BELOW);
1921 if (notAbove == 0 && notBelow == 0)
1922 return false;
1923
1924 if (playerLevel <= notBelow || (playerLevel >= notAbove && notAbove > 0))
1925 return true;
1926 return false;
1927}
1928
1929float Creature::GetAttackDistance(Unit const* player) const
1930{
1931 float aggroRate = sWorld->getRate(RATE_CREATURE_AGGRO);
1932 if (aggroRate == 0)
1933 return 0.0f;
1934
1935 // WoW Wiki: the minimum radius seems to be 5 yards, while the maximum range is 45 yards
1936 float maxRadius = (45.0f * sWorld->getRate(RATE_CREATURE_AGGRO));
1937 float minRadius = (5.0f * sWorld->getRate(RATE_CREATURE_AGGRO));
1938
1939 uint8 expansionMaxLevel = uint8(GetMaxLevelForExpansion(GetCreatureTemplate()->expansion));
1940 int32 levelDifference = GetLevel() - player->GetLevel();
1941
1942 // The aggro radius for creatures with equal level as the player is 20 yards.
1943 // The combatreach should not get taken into account for the distance so we drop it from the range (see Supremus as expample)
1944 float baseAggroDistance = 20.0f - GetCombatReach();
1945
1946 // + - 1 yard for each level difference between player and creature
1947 float aggroRadius = baseAggroDistance + float(levelDifference);
1948
1949 // detect range auras
1950 if (float(GetLevel() + 5) <= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
1951 {
1954 }
1955
1956 // The aggro range of creatures with higher levels than the total player level for the expansion should get the maxlevel treatment
1957 // This makes sure that creatures such as bosses wont have a bigger aggro range than the rest of the npc's
1958 // The following code is used for blizzlike behaivior such as skippable bosses
1959 if (GetLevel() > expansionMaxLevel)
1960 aggroRadius = baseAggroDistance + float(expansionMaxLevel - player->GetLevel());
1961
1962 // Make sure that we wont go over the total range limits
1963 if (aggroRadius > maxRadius)
1964 aggroRadius = maxRadius;
1965 else if (aggroRadius < minRadius)
1966 aggroRadius = minRadius;
1967
1968 return (aggroRadius * aggroRate);
1969}
1970
1972{
1974
1975 if (s == JUST_DIED)
1976 {
1978
1979 uint32 respawnDelay = m_respawnDelay;
1980 if (uint32 scalingMode = sWorld->getIntConfig(CONFIG_RESPAWN_DYNAMICMODE))
1981 GetMap()->ApplyDynamicModeRespawnScaling(this, m_spawnId, respawnDelay, scalingMode);
1982
1983 // @todo remove the boss respawn time hack in a dynspawn follow-up once we have creature groups in instances
1985 {
1986 if (IsDungeonBoss() && !m_respawnDelay)
1987 m_respawnTime = std::numeric_limits<time_t>::max(); // never respawn in this instance
1988 else
1990 }
1991 else
1992 {
1993 if (IsDungeonBoss() && !m_respawnDelay)
1994 m_respawnTime = std::numeric_limits<time_t>::max(); // never respawn in this instance
1995 else
1996 m_respawnTime = GameTime::GetGameTime() + respawnDelay;
1997 }
1998
2000
2001 ReleaseSpellFocus(nullptr, false); // remove spellcast focus
2002 DoNotReacquireSpellFocusTarget(); // cancel delayed re-target
2003 SetTarget(ObjectGuid::Empty); // drop target - dead mobs shouldn't ever target things
2004
2006
2007 SetMountDisplayId(0); // if creature is mounted on a virtual mount, remove it at death
2008
2009 setActive(false);
2010
2011 SetNoSearchAssistance(false);
2012
2013 //Dismiss group if is leader
2014 if (m_formation && m_formation->GetLeader() == this)
2016
2017 bool needsFalling = (IsFlying() || IsHovering()) && !IsUnderWater();
2018 SetHover(false);
2019 SetDisableGravity(false);
2020
2021 if (needsFalling)
2023
2025 }
2026 else if (s == JUST_RESPAWNED)
2027 {
2028 if (IsPet())
2029 SetFullHealth();
2030 else
2032
2033 SetLootRecipient(nullptr);
2035
2036 SetCannotReachTarget(false);
2038
2040
2041 if (!IsPet())
2042 {
2044 CreatureTemplate const* cinfo = GetCreatureTemplate();
2045
2046 uint32 npcflag, unit_flags, dynamicflags;
2047 ObjectMgr::ChooseCreatureFlags(cinfo, &npcflag, &unit_flags, &dynamicflags, creatureData);
2048
2049 ReplaceAllNpcFlags(NPCFlags(npcflag));
2050 ReplaceAllUnitFlags(UnitFlags(unit_flags));
2051 ReplaceAllDynamicFlags(dynamicflags);
2052
2054
2055 if (creatureData && GetPhaseMask() != creatureData->phaseMask)
2056 SetPhaseMask(creatureData->phaseMask, false);
2057 }
2058
2061
2062 if (!IsPet())
2064 }
2065}
2066
2067void Creature::Respawn(bool force)
2068{
2069 if (force)
2070 {
2071 if (IsAlive())
2073 else if (getDeathState() != CORPSE)
2075 }
2076
2078 {
2080 RemoveCorpse(false, false);
2081
2082 if (getDeathState() == DEAD)
2083 {
2084 TC_LOG_DEBUG("entities.unit", "Respawning creature {} ({})", GetName(), GetGUID().ToString());
2085 m_respawnTime = 0;
2087 loot.clear();
2088
2089 if (m_originalEntry != GetEntry())
2091
2092 SelectLevel();
2093
2095
2096 uint32 displayID = GetNativeDisplayId();
2097 if (sObjectMgr->GetCreatureModelRandomGender(&displayID))
2098 {
2099 SetDisplayId(displayID);
2100 SetNativeDisplayId(displayID);
2101 }
2102
2104
2105 // Re-initialize reactstate that could be altered by movementgenerators
2107
2108 if (UnitAI* ai = AI()) // reset the AI to be sure no dirty or uninitialized values will be used till next tick
2109 ai->Reset();
2110
2111 m_triggerJustAppeared = true;
2112
2113 uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<Creature>(GetSpawnId()) : 0;
2114 if (poolid)
2115 sPoolMgr->UpdatePool<Creature>(poolid, GetSpawnId());
2116 }
2118 }
2119 else
2120 {
2121 if (m_spawnId)
2123 }
2124
2125 TC_LOG_DEBUG("entities.unit", "Respawning creature {} ({})",
2126 GetName(), GetGUID().ToString());
2127
2128}
2129
2130void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
2131{
2132 if (timeMSToDespawn)
2133 {
2134 m_Events.AddEvent(new ForcedDespawnDelayEvent(*this, forceRespawnTimer), m_Events.CalculateTime(Milliseconds(timeMSToDespawn)));
2135 return;
2136 }
2137
2139 {
2140 uint32 corpseDelay = GetCorpseDelay();
2141 uint32 respawnDelay = GetRespawnDelay();
2142
2143 // do it before killing creature
2145
2146 bool overrideRespawnTime = false;
2147 if (IsAlive())
2148 {
2149 if (forceRespawnTimer > Seconds::zero())
2150 {
2151 SetCorpseDelay(0);
2152 SetRespawnDelay(forceRespawnTimer.count());
2153 overrideRespawnTime = true;
2154 }
2155
2157 }
2158
2159 // Skip corpse decay time
2160 RemoveCorpse(!overrideRespawnTime, false);
2161
2162 SetCorpseDelay(corpseDelay);
2163 SetRespawnDelay(respawnDelay);
2164 }
2165 else
2166 {
2167 if (forceRespawnTimer > Seconds::zero())
2168 SaveRespawnTime(forceRespawnTimer.count());
2169 else
2170 {
2171 uint32 respawnDelay = m_respawnDelay;
2172 if (uint32 scalingMode = sWorld->getIntConfig(CONFIG_RESPAWN_DYNAMICMODE))
2173 GetMap()->ApplyDynamicModeRespawnScaling(this, m_spawnId, respawnDelay, scalingMode);
2174 m_respawnTime = GameTime::GetGameTime() + respawnDelay;
2176 }
2177
2179 }
2180}
2181
2182void Creature::DespawnOrUnsummon(Milliseconds timeToDespawn /*= 0s*/, Seconds forceRespawnTimer /*= 0s*/)
2183{
2184 if (TempSummon* summon = ToTempSummon())
2185 summon->UnSummon(timeToDespawn.count());
2186 else
2187 ForcedDespawn(timeToDespawn.count(), forceRespawnTimer);
2188}
2189
2191{
2192 // uint32 max used for "spell id", the immunity system will not perform SpellInfo checks against invalid spells
2193 // used so we know which immunities were loaded from template
2194 static uint32 const placeholderSpellId = std::numeric_limits<uint32>::max();
2195
2196 // unapply template immunities (in case we're updating entry)
2197 for (uint32 i = MECHANIC_NONE + 1; i < MAX_MECHANIC; ++i)
2198 ApplySpellImmune(placeholderSpellId, IMMUNITY_MECHANIC, i, false);
2199
2200 for (uint32 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
2201 ApplySpellImmune(placeholderSpellId, IMMUNITY_SCHOOL, 1 << i, false);
2202
2203 // don't inherit immunities for hunter pets
2204 if (GetOwnerGUID().IsPlayer() && IsHunterPet())
2205 return;
2206
2207 if (uint32 mask = GetCreatureTemplate()->MechanicImmuneMask)
2208 {
2209 for (uint32 i = MECHANIC_NONE + 1; i < MAX_MECHANIC; ++i)
2210 {
2211 if (mask & (1 << (i - 1)))
2212 ApplySpellImmune(placeholderSpellId, IMMUNITY_MECHANIC, i, true);
2213 }
2214 }
2215
2216 if (uint32 mask = GetCreatureTemplate()->SpellSchoolImmuneMask)
2217 {
2218 for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; ++i)
2219 {
2220 if (mask & (1 << i))
2221 ApplySpellImmune(placeholderSpellId, IMMUNITY_SCHOOL, 1 << i, true);
2222 }
2223 }
2224}
2225
2226bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caster, bool requireImmunityPurgesEffectAttribute /*= false*/) const
2227{
2228 if (!spellInfo)
2229 return false;
2230
2231 bool immunedToAllEffects = true;
2232 for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
2233 {
2234 if (spellEffectInfo.IsEffect() && !IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute))
2235 {
2236 immunedToAllEffects = false;
2237 break;
2238 }
2239 }
2240
2241 if (immunedToAllEffects)
2242 return true;
2243
2244 return Unit::IsImmunedToSpell(spellInfo, caster, requireImmunityPurgesEffectAttribute);
2245}
2246
2247bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster,
2248 bool requireImmunityPurgesEffectAttribute /*= false*/) const
2249{
2251 return true;
2252
2253 return Unit::IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute);
2254}
2255
2257{
2258 if (IsPet())
2259 return false;
2260
2262 return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
2263}
2264
2266{
2267 if (IsPet())
2268 return false;
2269
2270 return (GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_BOSS_MOB) != 0;
2271}
2272
2273// select nearest hostile unit within the given distance (regardless of threat list).
2274Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const
2275{
2276 if (dist == 0.0f)
2278
2279 Unit* target = nullptr;
2280 Trinity::NearestHostileUnitCheck u_check(this, dist, playerOnly);
2282 Cell::VisitAllObjects(this, searcher, dist);
2283 return target;
2284}
2285
2286// select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list.
2288{
2289 if (dist > MAX_VISIBILITY_DISTANCE)
2290 {
2291 TC_LOG_ERROR("entities.unit", "Creature {} SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUID().ToString());
2292 dist = ATTACK_DISTANCE;
2293 }
2294
2295 Unit* target = nullptr;
2298 Cell::VisitAllObjects(this, searcher, std::max(dist, ATTACK_DISTANCE));
2299 return target;
2300}
2301
2303{
2305
2306 packet.UnitGUID = GetGUID();
2307 packet.Reaction = reactionType;
2308
2309 SendMessageToSet(packet.Write(), true);
2310
2311 TC_LOG_DEBUG("network", "WORLD: Sent SMSG_AI_REACTION, type {}.", reactionType);
2312}
2313
2315{
2316 if (!m_AlreadyCallAssistance && GetVictim() && !IsPet() && !IsCharmed())
2317 {
2318 SetNoCallAssistance(true);
2319
2320 float radius = sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
2321
2322 if (radius > 0)
2323 {
2324 std::list<Creature*> assistList;
2325 Trinity::AnyAssistCreatureInRangeCheck u_check(this, GetVictim(), radius);
2327 Cell::VisitGridObjects(this, searcher, radius);
2328
2329 if (!assistList.empty())
2330 {
2332 while (!assistList.empty())
2333 {
2334 // Pushing guids because in delay can happen some creature gets despawned => invalid pointer
2335 e->AddAssistant((*assistList.begin())->GetGUID());
2336 assistList.pop_front();
2337 }
2339 }
2340 }
2341 }
2342}
2343
2344void Creature::CallForHelp(float radius)
2345{
2346 if (radius <= 0.0f || !IsEngaged() || !IsAlive() || IsPet() || IsCharmed())
2347 return;
2348
2350 if (!target)
2351 target = GetThreatManager().GetAnyTarget();
2352 if (!target)
2353 target = GetCombatManager().GetAnyTarget();
2354
2355 if (!target)
2356 {
2357 TC_LOG_ERROR("entities.unit", "Creature {} ({}) trying to call for help without being in combat.", GetEntry(), GetName());
2358 return;
2359 }
2360
2361 Trinity::CallOfHelpCreatureInRangeDo u_do(this, target, radius);
2363 Cell::VisitGridObjects(this, worker, radius);
2364}
2365
2366bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /*= true*/) const
2367{
2368 // is it true?
2370 return false;
2371
2372 // we don't need help from zombies :)
2373 if (!IsAlive())
2374 return false;
2375
2376 // we cannot assist in evade mode
2377 if (IsInEvadeMode())
2378 return false;
2379
2380 // or if enemy is in evade mode
2381 if (enemy->GetTypeId() == TYPEID_UNIT && enemy->ToCreature()->IsInEvadeMode())
2382 return false;
2383
2384 // we don't need help from non-combatant ;)
2385 if (IsCivilian())
2386 return false;
2387
2389 return false;
2390
2391 // skip fighting creature
2392 if (IsEngaged())
2393 return false;
2394
2395 // only free creature
2396 if (!GetCharmerOrOwnerGUID().IsEmpty())
2397 return false;
2398
2399 // only from same creature faction
2400 if (checkfaction)
2401 {
2402 if (GetFaction() != u->GetFaction())
2403 return false;
2404 }
2405 else
2406 {
2407 if (!IsFriendlyTo(u))
2408 return false;
2409 }
2410
2411 // skip non hostile to caster enemy creatures
2412 if (!IsHostileTo(enemy))
2413 return false;
2414
2415 return true;
2416}
2417
2418// use this function to avoid having hostile creatures attack
2419// friendlies and other mobs they shouldn't attack
2420bool Creature::_IsTargetAcceptable(Unit const* target) const
2421{
2422 ASSERT(target);
2423
2424 // if the target cannot be attacked, the target is not acceptable
2425 if (IsFriendlyTo(target)
2426 || !target->isTargetableForAttack(false)
2427 || (m_vehicle && (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target))))
2428 return false;
2429
2430 if (target->HasUnitState(UNIT_STATE_DIED))
2431 {
2432 // some creatures can detect fake death
2434 return true;
2435 else
2436 return false;
2437 }
2438
2439 // if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
2440 if (IsEngagedBy(target) || IsHostileTo(target))
2441 return true;
2442
2443 // if the target's victim is not friendly, or the target is friendly, the target is not acceptable
2444 return false;
2445}
2446
2448{
2450 return;
2451
2453 {
2454 RespawnInfo ri;
2456 ri.spawnId = m_spawnId;
2459 return;
2460 }
2461
2462 time_t thisRespawnTime = forceDelay ? GameTime::GetGameTime() + forceDelay : m_respawnTime;
2464}
2465
2466// this should not be called by petAI or
2467bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
2468{
2469 if (!victim->IsInMap(this))
2470 return false;
2471
2472 if (!IsValidAttackTarget(victim))
2473 return false;
2474
2475 if (!victim->isInAccessiblePlaceFor(this))
2476 return false;
2477
2478 if (CreatureAI* ai = AI())
2479 if (!ai->CanAIAttack(victim))
2480 return false;
2481
2482 // we cannot attack in evade mode
2483 if (IsInEvadeMode())
2484 return false;
2485
2486 // or if enemy is in evade mode
2487 if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
2488 return false;
2489
2491 {
2492 if (GetMap()->IsDungeon())
2493 return true;
2494
2495 // don't check distance to home position if recently damaged, this should include taunt auras
2497 return true;
2498 }
2499
2500 // Map visibility range, but no more than 2*cell size
2501 float dist = std::min<float>(GetMap()->GetVisibilityRange(), SIZE_OF_GRID_CELL*2);
2502
2503 if (Unit* unit = GetCharmerOrOwner())
2504 return victim->IsWithinDist(unit, dist);
2505 else
2506 {
2507 // include sizes for huge npcs
2508 dist += GetCombatReach() + victim->GetCombatReach();
2509
2510 // to prevent creatures in air ignore attacks because distance is already too high...
2511 if (GetMovementTemplate().IsFlightAllowed())
2512 return victim->IsInDist2d(&m_homePosition, dist);
2513 else
2514 return victim->IsInDist(&m_homePosition, dist);
2515 }
2516}
2517
2519{
2520 if (m_spawnId)
2521 {
2522 if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_spawnId))
2523 return addon;
2524 }
2525
2526 // dependent from difficulty mode entry
2527 return sObjectMgr->GetCreatureTemplateAddon(GetCreatureTemplate()->Entry);
2528}
2529
2530//creature_addon table
2532{
2533 CreatureAddon const* creatureAddon = GetCreatureAddon();
2534 if (!creatureAddon)
2535 return false;
2536
2537 if (creatureAddon->mount != 0)
2538 Mount(creatureAddon->mount);
2539
2540 // UNIT_FIELD_BYTES_1 values
2542 SetAnimTier(AnimTier(creatureAddon->animTier));
2543 ReplaceAllVisFlags(UnitVisFlags(creatureAddon->visFlags));
2544
2545 // UNIT_FIELD_BYTES_2 values
2546 SetSheath(SheathState(creatureAddon->sheathState));
2548
2549 // These fields must only be handled by core internals and must not be modified via scripts/DB data
2552
2553 if (creatureAddon->emote != 0)
2554 SetEmoteState(Emote(creatureAddon->emote));
2555
2556 // Check if visibility distance different
2559
2560 // Load Path
2561 if (creatureAddon->path_id != 0)
2562 _waypointPathId = creatureAddon->path_id;
2563
2564 if (!creatureAddon->auras.empty())
2565 {
2566 for (std::vector<uint32>::const_iterator itr = creatureAddon->auras.begin(); itr != creatureAddon->auras.end(); ++itr)
2567 {
2568 SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(*itr);
2569 if (!AdditionalSpellInfo)
2570 {
2571 TC_LOG_ERROR("sql.sql", "Creature {} has wrong spell {} defined in `auras` field.", GetGUID().ToString(), *itr);
2572 continue;
2573 }
2574
2575 // skip already applied aura
2576 if (HasAura(*itr))
2577 continue;
2578
2579 AddAura(*itr, this);
2580 TC_LOG_DEBUG("entities.unit", "Spell: {} added to creature {}", *itr, GetGUID().ToString());
2581 }
2582 }
2583
2584 return true;
2585}
2586
2589{
2590 uint32 enemy_team = attacker->GetTeam();
2591
2593 data << (uint32)GetAreaId();
2594 sWorld->SendGlobalMessage(&data, nullptr, (enemy_team == ALLIANCE ? HORDE : ALLIANCE));
2595}
2596
2597uint32 Creature::GetShieldBlockValue() const //dunno mob block value
2598{
2599 return (GetLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
2600}
2601
2602bool Creature::HasSpell(uint32 spellID) const
2603{
2604 return std::find(std::begin(m_spells), std::end(m_spells), spellID) != std::end(m_spells);
2605}
2606
2608{
2609 time_t now = GameTime::GetGameTime();
2610 if (m_respawnTime > now)
2611 return m_respawnTime;
2612 else
2613 return now;
2614}
2615
2617{
2618 m_respawnTime = respawn ? GameTime::GetGameTime() + respawn : 0;
2619}
2620
2621void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, float* dist) const
2622{
2623 if (m_creatureData)
2624 {
2625 if (ori)
2626 m_creatureData->spawnPoint.GetPosition(x, y, z, *ori);
2627 else
2629
2630 if (dist)
2632 }
2633 else
2634 {
2635 Position const& homePos = GetHomePosition();
2636 if (ori)
2637 homePos.GetPosition(x, y, z, *ori);
2638 else
2639 homePos.GetPosition(x, y, z);
2640 if (dist)
2641 *dist = 0;
2642 }
2643}
2644
2646{
2647 // It does the same, for now
2649}
2650
2652{
2653 // Do not update movement flags if creature is controlled by a player (charm/vehicle)
2654 if (IsMovedByClient())
2655 return;
2656
2657 // Creatures with CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE should control MovementFlags in your own scripts
2659 return;
2660
2661 // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
2662 float ground = GetFloorZ();
2663
2664 bool canHover = CanHover();
2665 bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + (canHover ? GetFloatValue(UNIT_FIELD_HOVERHEIGHT) : 0.0f) + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE)); // Can be underground too, prevent the falling
2666
2667 if (GetMovementTemplate().IsFlightAllowed() && isInAir && !IsFalling())
2668 {
2670 SetCanFly(true);
2671 else
2672 SetDisableGravity(true);
2673
2675 SetHover(false);
2676 }
2677 else
2678 {
2679 SetCanFly(false);
2680 SetDisableGravity(false);
2682 SetHover(true);
2683 }
2684
2685 if (!isInAir)
2686 SetFall(false);
2687
2688 SetSwim(CanSwim() && IsInWater());
2689}
2690
2692{
2693 if (CreatureMovementData const* movementOverride = sObjectMgr->GetCreatureMovementOverride(m_spawnId))
2694 return *movementOverride;
2695
2696 return GetCreatureTemplate()->Movement;
2697}
2698
2700{
2701 if (Unit::CanSwim())
2702 return true;
2703
2704 if (IsPet())
2705 return true;
2706
2707 return false;
2708}
2709
2711{
2712 if (CanSwim())
2713 return true;
2714
2716}
2717
2719{
2720 if (!_isMissingCanSwimFlagOutOfCombat || recheck)
2722
2723 // Check if the creature has UNIT_FLAG_CAN_SWIM and add it if it's missing
2724 // Creatures must be able to chase a target in water if they can enter water
2727}
2728
2730{
2731 if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
2734
2735 time_t now = GameTime::GetGameTime();
2736 // Do not reset corpse remove time if corpse is already removed
2737 if (m_corpseRemoveTime <= now)
2738 return;
2739
2740 // Scripts can choose to ignore RATE_CORPSE_DECAY_LOOTED by calling SetCorpseDelay(timer, true)
2741 float decayRate = m_ignoreCorpseDecayRatio ? 1.f : sWorld->getRate(RATE_CORPSE_DECAY_LOOTED);
2742
2743 // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
2745 m_corpseRemoveTime = now;
2746 else
2747 m_corpseRemoveTime = now + uint32(m_corpseDelay * decayRate);
2748
2750}
2751
2753{
2754 if (!isWorldBoss() || !target->ToUnit())
2755 return Unit::GetLevelForTarget(target);
2756
2757 uint16 level = target->ToUnit()->GetLevel() + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF);
2758 if (level < 1)
2759 return 1;
2760 if (level > 255)
2761 return 255;
2762 return uint8(level);
2763}
2764
2765std::string const& Creature::GetAIName() const
2766{
2767 return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName;
2768}
2769
2770std::string Creature::GetScriptName() const
2771{
2772 return sObjectMgr->GetScriptName(GetScriptId());
2773}
2774
2776{
2778 if (uint32 scriptId = creatureData->scriptId)
2779 return scriptId;
2780
2781 return ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(GetEntry()))->ScriptID;
2782}
2783
2785{
2786 // copy references to stringIds from template and spawn
2787 m_stringIds = parent->m_stringIds;
2788
2789 // then copy script stringId, not just its reference
2790 SetScriptStringId(std::string(parent->GetStringId(StringIdType::Script)));
2791}
2792
2793bool Creature::HasStringId(std::string_view id) const
2794{
2795 return std::ranges::any_of(m_stringIds, [id](std::string const* stringId) { return stringId && *stringId == id; });
2796}
2797
2799{
2800 if (!id.empty())
2801 {
2802 m_scriptStringId.emplace(std::move(id));
2804 }
2805 else
2806 {
2807 m_scriptStringId.reset();
2809 }
2810}
2811
2813{
2814 return sObjectMgr->GetNpcVendorItemList(GetEntry());
2815}
2816
2818{
2819 if (!vItem->maxcount)
2820 return vItem->maxcount;
2821
2822 VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
2823 for (; itr != m_vendorItemCounts.end(); ++itr)
2824 if (itr->itemId == vItem->item)
2825 break;
2826
2827 if (itr == m_vendorItemCounts.end())
2828 return vItem->maxcount;
2829
2830 VendorItemCount* vCount = &*itr;
2831
2832 time_t ptime = GameTime::GetGameTime();
2833
2834 if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime)
2835 if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item))
2836 {
2837 uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
2838 if ((vCount->count + diff * pProto->GetBuyCount()) >= vItem->maxcount)
2839 {
2840 m_vendorItemCounts.erase(itr);
2841 return vItem->maxcount;
2842 }
2843
2844 vCount->count += diff * pProto->GetBuyCount();
2845 vCount->lastIncrementTime = ptime;
2846 }
2847
2848 return vCount->count;
2849}
2850
2852{
2853 if (!vItem->maxcount)
2854 return 0;
2855
2856 VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
2857 for (; itr != m_vendorItemCounts.end(); ++itr)
2858 if (itr->itemId == vItem->item)
2859 break;
2860
2861 if (itr == m_vendorItemCounts.end())
2862 {
2863 uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount-used_count : 0;
2864 m_vendorItemCounts.push_back(VendorItemCount(vItem->item, new_count));
2865 return new_count;
2866 }
2867
2868 VendorItemCount* vCount = &*itr;
2869
2870 time_t ptime = GameTime::GetGameTime();
2871
2872 if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime)
2873 if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item))
2874 {
2875 uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
2876 if ((vCount->count + diff * pProto->GetBuyCount()) < vItem->maxcount)
2877 vCount->count += diff * pProto->GetBuyCount();
2878 else
2879 vCount->count = vItem->maxcount;
2880 }
2881
2882 vCount->count = vCount->count > used_count ? vCount->count-used_count : 0;
2883 vCount->lastIncrementTime = ptime;
2884 return vCount->count;
2885}
2886
2887// overwrite WorldObject function for proper name localization
2888std::string const & Creature::GetNameForLocaleIdx(LocaleConstant loc_idx) const
2889{
2890 if (loc_idx != DEFAULT_LOCALE)
2891 {
2892 uint8 uloc_idx = uint8(loc_idx);
2893 CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(GetEntry());
2894 if (cl)
2895 {
2896 if (cl->Name.size() > uloc_idx && !cl->Name[uloc_idx].empty())
2897 return cl->Name[uloc_idx];
2898 }
2899 }
2900
2901 return GetName();
2902}
2903
2905{
2907 return 0;
2908 else
2909 return m_charmInfo->GetCharmSpell(pos)->GetAction();
2910}
2911
2913{
2914 float range = 0.f;
2915
2916 for (uint8 i = 0; i < GetPetAutoSpellSize(); ++i)
2917 {
2918 uint32 spellID = GetPetAutoSpellOnPos(i);
2919 if (!spellID)
2920 continue;
2921
2922 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID))
2923 {
2924 if (spellInfo->GetRecoveryTime() == 0 && spellInfo->RangeEntry->ID != 1 /*Self*/ && spellInfo->RangeEntry->ID != 2 /*Combat Range*/ && spellInfo->GetMaxRange() > range)
2925 range = spellInfo->GetMaxRange();
2926 }
2927 }
2928
2929 return range;
2930}
2931
2933{
2934 if (cannotReach == m_cannotReachTarget)
2935 return;
2936 m_cannotReachTarget = cannotReach;
2938
2939 if (cannotReach)
2940 TC_LOG_DEBUG("entities.unit.chase", "Creature::SetCannotReachTarget() called with true. Details: {}", GetDebugInfo());
2941}
2942
2943float Creature::GetAggroRange(Unit const* target) const
2944{
2945 // Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
2946 // Based on data from wowwiki due to lack of 3.3.5a data
2947
2948 if (target && IsPet())
2949 {
2950 uint32 targetLevel = 0;
2951
2952 if (target->GetTypeId() == TYPEID_PLAYER)
2953 targetLevel = target->GetLevelForTarget(this);
2954 else if (target->GetTypeId() == TYPEID_UNIT)
2955 targetLevel = target->ToCreature()->GetLevelForTarget(this);
2956
2957 uint32 myLevel = GetLevelForTarget(target);
2958 int32 levelDiff = int32(targetLevel) - int32(myLevel);
2959
2960 // The maximum Aggro Radius is capped at 45 yards (25 level difference)
2961 if (levelDiff < -25)
2962 levelDiff = -25;
2963
2964 // The base aggro radius for mob of same level
2965 float aggroRadius = 20;
2966
2967 // Aggro Radius varies with level difference at a rate of roughly 1 yard/level
2968 aggroRadius -= (float)levelDiff;
2969
2970 // detect range auras
2972
2973 // detected range auras
2975
2976 // Just in case, we don't want pets running all over the map
2977 if (aggroRadius > MAX_AGGRO_RADIUS)
2978 aggroRadius = MAX_AGGRO_RADIUS;
2979
2980 // Minimum Aggro Radius for a mob seems to be combat range (5 yards)
2981 // hunter pets seem to ignore minimum aggro radius so we'll default it a little higher
2982 if (aggroRadius < 10)
2983 aggroRadius = 10;
2984
2985 return (aggroRadius);
2986 }
2987
2988 // Default
2989 return 0.0f;
2990}
2991
2992Unit* Creature::SelectNearestHostileUnitInAggroRange(bool useLOS, bool ignoreCivilians) const
2993{
2994 // Selects nearest hostile target within creature's aggro range. Used primarily by
2995 // pets set to aggressive. Will not return neutral or friendly targets.
2996
2997 Unit* target = nullptr;
2998
2999 Trinity::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS, ignoreCivilians);
3001
3003
3004 return target;
3005}
3006
3008{
3009 return GetCreatureTemplate()->scale;
3010}
3011
3013{
3014 Unit::SetObjectScale(scale);
3015
3016 if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(GetDisplayId()))
3017 {
3018 SetBoundingRadius((IsPet() ? 1.0f : minfo->bounding_radius) * scale);
3019 SetCombatReach((IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * scale);
3020 }
3021}
3022
3024{
3025 Unit::SetDisplayId(modelId);
3026
3027 if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
3028 {
3029 SetBoundingRadius((IsPet() ? 1.0f : minfo->bounding_radius) * GetObjectScale());
3030 SetCombatReach((IsPet() ? DEFAULT_PLAYER_COMBAT_REACH : minfo->combat_reach) * GetObjectScale());
3031 }
3032}
3033
3035{
3036 if (HasSpellFocus())
3037 _spellFocusInfo.Target = guid;
3038 else
3040}
3041
3042void Creature::SetSpellFocus(Spell const* focusSpell, WorldObject const* target)
3043{
3044 // Pointer validation and checking for a already existing focus
3045 if (_spellFocusInfo.Spell || !focusSpell)
3046 return;
3047
3048 // Prevent dead / feign death creatures from setting a focus target
3050 return;
3051
3052 // Don't allow stunned creatures to set a focus target
3054 return;
3055
3056 // some spells shouldn't track targets
3057 if (focusSpell->IsFocusDisabled())
3058 return;
3059
3060 SpellInfo const* spellInfo = focusSpell->GetSpellInfo();
3061
3062 // don't use spell focus for vehicle spells
3063 if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
3064 return;
3065
3066 // instant non-channeled casts and non-target spells don't need facing updates
3067 if (!target && (!focusSpell->GetCastTime() && !spellInfo->IsChanneled()))
3068 return;
3069
3070 // store pre-cast values for target and orientation (used to later restore)
3071 if (!_spellFocusInfo.Delay)
3072 { // only overwrite these fields if we aren't transitioning from one spell focus to another
3074 _spellFocusInfo.Orientation = GetOrientation();
3075 }
3076 else // don't automatically reacquire target for the previous spellcast
3077 _spellFocusInfo.Delay = 0;
3078
3079 _spellFocusInfo.Spell = focusSpell;
3080
3081 bool const noTurnDuringCast = spellInfo->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST);
3082 bool const turnDisabled = HasUnitFlag2(UNIT_FLAG2_CANNOT_TURN);
3083 // set target, then force send update packet to players if it changed to provide appropriate facing
3084 ObjectGuid newTarget = (target && !noTurnDuringCast && !turnDisabled) ? target->GetGUID() : ObjectGuid::Empty;
3085 if (GetGuidValue(UNIT_FIELD_TARGET) != newTarget)
3086 SetGuidValue(UNIT_FIELD_TARGET, newTarget);
3087
3088 // If we are not allowed to turn during cast but have a focus target, face the target
3089 if (!turnDisabled && noTurnDuringCast && target)
3090 SetFacingToObject(target, false);
3091
3092 if (noTurnDuringCast)
3094}
3095
3096bool Creature::HasSpellFocus(Spell const* focusSpell) const
3097{
3098 if (isDead()) // dead creatures cannot focus
3099 {
3100 if (_spellFocusInfo.Spell || _spellFocusInfo.Delay)
3101 {
3102 TC_LOG_WARN("entities.unit", "Creature '{}' (entry {}) has spell focus (spell id {}, delay {}ms) despite being dead.",
3103 GetName(), GetEntry(), _spellFocusInfo.Spell ? _spellFocusInfo.Spell->GetSpellInfo()->Id : 0, _spellFocusInfo.Delay);
3104 }
3105 return false;
3106 }
3107
3108 if (focusSpell)
3109 return (focusSpell == _spellFocusInfo.Spell);
3110 else
3111 return (_spellFocusInfo.Spell || _spellFocusInfo.Delay);
3112}
3113
3114void Creature::ReleaseSpellFocus(Spell const* focusSpell, bool withDelay)
3115{
3116 if (!_spellFocusInfo.Spell)
3117 return;
3118
3119 // focused to something else
3120 if (focusSpell && focusSpell != _spellFocusInfo.Spell)
3121 return;
3122
3123 if (_spellFocusInfo.Spell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_DONT_TURN_DURING_CAST))
3125
3126 if (IsPet()) // player pets do not use delay system
3127 {
3130 }
3131 else // don't allow re-target right away to prevent visual bugs
3132 _spellFocusInfo.Delay = withDelay ? 1000 : 1;
3133
3134 _spellFocusInfo.Spell = nullptr;
3135}
3136
3138{
3139 if (!HasSpellFocus())
3140 {
3141 TC_LOG_ERROR("entities.unit", "Creature::ReacquireSpellFocusTarget() being called with HasSpellFocus() returning false. {}", GetDebugInfo());
3142 return;
3143 }
3144
3146
3148 {
3149 if (!_spellFocusInfo.Target.IsEmpty())
3150 {
3151 if (WorldObject const* objTarget = ObjectAccessor::GetWorldObject(*this, _spellFocusInfo.Target))
3152 SetFacingToObject(objTarget, false);
3153 }
3154 else
3155 SetFacingTo(_spellFocusInfo.Orientation, false);
3156 }
3157 _spellFocusInfo.Delay = 0;
3158}
3159
3161{
3162 _spellFocusInfo.Delay = 0;
3163 _spellFocusInfo.Spell = nullptr;
3164}
3165
3167{
3169 return false;
3170
3171 return true;
3172}
3173
3178
3183
3185{
3186 CreatureTextRepeatIds& repeats = m_textRepeat[textGroup];
3187 if (std::find(repeats.begin(), repeats.end(), id) == repeats.end())
3188 repeats.push_back(id);
3189 else
3190 TC_LOG_ERROR("sql.sql", "CreatureTextMgr: TextGroup {} for Creature({}) {}, id {} already added", uint32(textGroup), GetName(), GetGUID().ToString(), uint32(id));
3191}
3192
3194{
3196
3197 CreatureTextRepeatGroup::const_iterator groupItr = m_textRepeat.find(textGroup);
3198 if (groupItr != m_textRepeat.end())
3199 ids = groupItr->second;
3200
3201 return ids;
3202}
3203
3205{
3206 CreatureTextRepeatGroup::iterator groupItr = m_textRepeat.find(textGroup);
3207 if (groupItr != m_textRepeat.end())
3208 groupItr->second.clear();
3209}
3210
3212{
3213 return !IsCritter()
3214 && !IsPet()
3215 && !IsTotem()
3217}
3218
3220{
3221 if (CreatureAI const* ai = AI())
3222 return ai->IsEngaged();
3223 return false;
3224}
3225
3227{
3228 Unit::AtEngage(target);
3229
3231 Dismount();
3232
3234
3235 if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
3236 {
3240 }
3241
3243 if (movetype == WAYPOINT_MOTION_TYPE || movetype == POINT_MOTION_TYPE || (IsAIEnabled() && AI()->IsEscorted()))
3244 {
3246
3247 // if its a vehicle, set the home positon of every creature passenger at engage
3248 // so that they are in combat range if hostile
3249 if (Vehicle* vehicle = GetVehicleKit())
3250 {
3251 for (auto seat = vehicle->Seats.begin(); seat != vehicle->Seats.end(); ++seat)
3252 if (Unit* passenger = ObjectAccessor::GetUnit(*this, seat->second.Passenger.Guid))
3253 if (Creature* creature = passenger->ToCreature())
3254 creature->SetHomePosition(GetPosition());
3255 }
3256 }
3257
3258 if (CreatureAI* ai = AI())
3259 ai->JustEngagedWith(target);
3260 if (CreatureGroup* formation = GetFormation())
3261 formation->MemberEngagingTarget(this, target);
3262}
3263
3265{
3267
3271
3272 if (IsPet() || IsGuardian()) // update pets' speed for catchup OOC speed
3273 {
3277 }
3278}
3279
3281{
3282 if (CreatureAI const* ai = AI())
3283 return ai->IsEscorted();
3284 return false;
3285}
3286
3287std::string Creature::GetDebugInfo() const
3288{
3289 std::stringstream sstr;
3290 sstr << Unit::GetDebugInfo() << "\n"
3291 << "AIName: " << GetAIName() << " ScriptName: " << GetScriptName()
3292 << " WaypointPath: " << GetWaypointPath() << " SpawnId: " << GetSpawnId();
3293 return sstr.str();
3294}
3295
3296void Creature::ExitVehicle(Position const* /*exitPosition*/)
3297{
3298 bool const isInVehicle = GetVehicle();
3300
3301 // if alive creature exits a vehicle, set it's home position to the
3302 // exited position so it won't run away (home) and evade if it's hostile
3303 if (isInVehicle && IsAlive())
3305}
#define sBattlegroundMgr
LocaleConstant
Definition Common.h:48
@ TOTAL_LOCALES
Definition Common.h:59
@ LOCALE_enUS
Definition Common.h:49
#define DEFAULT_LOCALE
Definition Common.h:62
@ IN_MILLISECONDS
Definition Common.h:35
@ MINUTE
Definition Common.h:29
@ WEEK
Definition Common.h:32
static const uint32 MAX_CREATURE_QUEST_ITEMS
static const uint32 CREATURE_REGEN_INTERVAL
@ CREATURE_FLAG_EXTRA_DUNGEON_BOSS
@ CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING
@ CREATURE_FLAG_EXTRA_CANNOT_ENTER_COMBAT
@ CREATURE_FLAG_EXTRA_NO_XP
@ CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE
@ CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK
@ CREATURE_FLAG_EXTRA_NO_TAUNT
@ CREATURE_FLAG_EXTRA_GHOST_VISIBILITY
@ CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK
@ CREATURE_FLAG_EXTRA_WORLDEVENT
CreatureFlightMovementType
CreatureChaseMovementType
CreatureGroundMovementType
static const uint8 MAX_KILL_CREDIT
CreatureRandomMovementType
static const uint32 CREATURE_NOPATH_EVADE_TIME
static const uint32 MAX_CREATURE_SPELLS
static const uint32 PET_FOCUS_REGEN_INTERVAL
#define sFormationMgr
std::vector< uint8 > CreatureTextRepeatIds
Definition Creature.h:67
#define CREATURE_Z_ATTACK_RANGE
Definition Creature.h:53
@ RAID_DIFFICULTY_10MAN_HEROIC
Definition DBCEnums.h:288
@ FACTION_TEMPLATE_FLAG_PVP
Definition DBCEnums.h:317
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
SQLTransaction< WorldDatabaseConnection > WorldDatabaseTransaction
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
uint8_t uint8
Definition Define.h:135
int8_t int8
Definition Define.h:131
int32_t int32
Definition Define.h:129
uint64_t uint64
Definition Define.h:132
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:27
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:84
#define ASSERT
Definition Errors.h:68
#define sGameEventMgr
#define SIZE_OF_GRID_CELL
Definition GridDefines.h:46
#define sGroupMgr
Definition GroupMgr.h:58
@ ITEM_FLAG2_DONT_IGNORE_BUY_PRICE
#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
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true)
@ LOOT_SKINNING
Definition Loot.h:97
#define sMapMgr
Definition MapManager.h:211
#define MAX_FALL_DISTANCE
Definition Map.h:263
MovementGeneratorType
@ IDLE_MOTION_TYPE
@ WAYPOINT_MOTION_TYPE
@ HOME_MOTION_TYPE
@ POINT_MOTION_TYPE
@ RANDOM_MOTION_TYPE
#define ATTACK_DISTANCE
#define MAX_VISIBILITY_DISTANCE
#define DEFAULT_PLAYER_COMBAT_REACH
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define sObjectMgr
Definition ObjectMgr.h:1721
#define sPoolMgr
Definition PoolMgr.h:148
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
SpellSchools
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_NORMAL
@ SPELL_SCHOOL_NATURE
@ SPELL_SCHOOL_FROST
@ SPELL_SCHOOL_ARCANE
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
@ MAX_SPELL_SCHOOL
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_ATTACK_ME
@ SPELL_EFFECT_KNOCK_BACK_DEST
@ SPELL_EFFECT_KNOCK_BACK
@ SPELL_ATTR5_DONT_TURN_DURING_CAST
@ UNIT_CLASS_MAGE
@ UNIT_CLASS_PALADIN
@ XP_GRAY
@ SPELL_SCHOOL_MASK_NORMAL
@ CREATURE_TYPE_NON_COMBAT_PET
@ CREATURE_TYPE_MECHANICAL
@ UNIT_DYNFLAG_TAPPED
@ UNIT_DYNFLAG_LOOTABLE
AiReaction
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
float const GROUND_HEIGHT_TOLERANCE
@ CREATURE_ELITE_NORMAL
@ CREATURE_ELITE_WORLDBOSS
@ CREATURE_ELITE_RARE
@ CREATURE_ELITE_RAREELITE
@ CREATURE_ELITE_ELITE
@ MECHANIC_NONE
@ MAX_MECHANIC
@ IMMUNITY_STATE
@ IMMUNITY_EFFECT
@ IMMUNITY_MECHANIC
@ IMMUNITY_SCHOOL
@ 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
@ RACE_NONE
@ STAT_SPIRIT
@ STAT_STRENGTH
@ CREATURE_TYPE_FLAG_VISIBLE_TO_GHOSTS
@ CREATURE_TYPE_FLAG_BOSS_MOB
@ CREATURE_TYPE_FLAG_ALLOW_MOUNTED_COMBAT
uint32 GetMaxLevelForExpansion(uint32 expansion)
@ SPAWNGROUP_FLAG_COMPATIBILITY_MODE
Definition SpawnData.h:50
@ LINKED_RESPAWN_CREATURE_TO_GO
Definition SpawnData.h:111
@ LINKED_RESPAWN_CREATURE_TO_CREATURE
Definition SpawnData.h:110
@ LINKED_RESPAWN_GO_TO_CREATURE
Definition SpawnData.h:113
@ SPAWN_TYPE_CREATURE
Definition SpawnData.h:31
@ 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_HOVER
@ 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:738
UnitFlags2
@ UNIT_FLAG2_CANNOT_TURN
@ UNIT_FLAG2_FEIGN_DEATH
@ UNIT_FLAG2_REGENERATE_POWER
@ UNIT_PET_FLAG_NONE
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
UnitStandStateType
Definition UnitDefines.h:33
@ ACT_ENABLED
NPCFlags
Non Player Character flags.
@ UNIT_NPC_FLAG_NONE
SheathState
Definition UnitDefines.h:97
@ SHEATH_STATE_MELEE
Definition UnitDefines.h:99
#define MAX_EQUIPMENT_ITEMS
Definition UnitDefines.h:29
UnitPVPStateFlags
@ UNIT_BYTE2_FLAG_FFA_PVP
AnimTier
Definition UnitDefines.h:85
UnitVisFlags
Definition UnitDefines.h:50
@ MOVE_FLIGHT
@ MOVE_SWIM
@ MOVE_RUN
@ MOVE_WALK
UnitFlags
@ UNIT_FLAG_STUNNED
@ UNIT_FLAG_NON_ATTACKABLE
@ UNIT_FLAG_IN_COMBAT
@ UNIT_FLAG_CAN_SWIM
@ UNIT_FLAG_UNINTERACTIBLE
@ UNIT_FLAG_PLAYER_CONTROLLED
@ UNIT_FLAG_SKINNABLE
@ BASE_VALUE
Definition Unit.h:139
#define MAX_SPELL_CHARM
Definition Unit.h:36
@ MINDAMAGE
Definition Unit.h:153
@ MAXDAMAGE
Definition Unit.h:154
@ UNIT_MOD_ARMOR
Definition Unit.h:172
@ UNIT_MOD_RESISTANCE_SHADOW
Definition Unit.h:177
@ UNIT_MOD_RESISTANCE_FROST
Definition Unit.h:176
@ UNIT_MOD_RESISTANCE_HOLY
Definition Unit.h:173
@ UNIT_MOD_RESISTANCE_ARCANE
Definition Unit.h:178
@ UNIT_MOD_HEALTH
Definition Unit.h:164
@ UNIT_MOD_RESISTANCE_FIRE
Definition Unit.h:174
@ UNIT_MOD_RESISTANCE_NATURE
Definition Unit.h:175
#define MAX_AGGRO_RADIUS
Definition Unit.h:42
DeathState
Definition Unit.h:224
@ CORPSE
Definition Unit.h:227
@ DEAD
Definition Unit.h:228
@ ALIVE
Definition Unit.h:225
@ JUST_RESPAWNED
Definition Unit.h:229
@ JUST_DIED
Definition Unit.h:226
@ UNIT_STATE_DIED
Definition Unit.h:234
@ UNIT_STATE_ATTACK_PLAYER
Definition Unit.h:248
@ UNIT_STATE_ROOT
Definition Unit.h:244
@ UNIT_STATE_IGNORE_PATHFINDING
Definition Unit.h:262
@ UNIT_STATE_FLEEING
Definition Unit.h:241
@ UNIT_STATE_FOCUSING
Definition Unit.h:240
@ UNIT_STATE_ALL_ERASABLE
Definition Unit.h:281
@ UNIT_END
@ UNIT_FIELD_TARGET
@ UNIT_FIELD_HOVERHEIGHT
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:554
@ WORLD_DEL_SPAWNGROUP_MEMBER
@ WORLD_DEL_GAME_EVENT_MODEL_EQUIP
@ WORLD_DEL_CREATURE_ADDON
@ WORLD_DEL_LINKED_RESPAWN
@ WORLD_DEL_GAME_EVENT_CREATURE
@ WORLD_DEL_CREATURE
@ WORLD_DEL_LINKED_RESPAWN_MASTER
@ WORLD_INS_CREATURE
ObjectGuid m_victim
Definition Creature.h:482
bool Execute(uint64 e_time, uint32 p_time) override
Definition Creature.cpp:224
void AddAssistant(ObjectGuid guid)
Definition Creature.h:478
GuidList m_assistants
Definition Creature.h:483
Unit * GetAnyTarget() const
@ EVADE_REASON_OTHER
Definition CreatureAI.h:98
@ EVADE_REASON_NO_HOSTILES
Definition CreatureAI.h:94
@ EVADE_REASON_NO_PATH
Definition CreatureAI.h:96
virtual void JustAppeared()
virtual bool CheckInRoom()
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
Creature * GetLeader() const
void FormationReset(bool dismiss)
bool IsFormed() const
bool IsLeader(Creature const *creature) const
bool CanLeaderStartMoving() const
float GetSpellDamageMod(int32 Rank) const
bool LoadCreaturesAddon()
time_t _pickpocketLootRestore
Timers.
Definition Creature.h:395
bool HasSpell(uint32 spellID) const override
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition Creature.cpp:653
bool AIM_Destroy()
VendorItemCounts m_vendorItemCounts
Definition Creature.h:387
virtual uint8 GetPetAutoSpellSize() const
Definition Creature.h:295
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:302
float m_wanderDistance
Definition Creature.h:401
void SetNoSearchAssistance(bool val)
Definition Creature.h:254
Loot loot
Definition Creature.h:218
void ReleaseSpellFocus(Spell const *focusSpell=nullptr, bool withDelay=true)
ObjectGuid lootingGroupLowGUID
Definition Creature.h:286
bool IsTrigger() const
Definition Creature.h:107
void Respawn(bool force=false)
std::array< std::string const *, 3 > m_stringIds
Definition Creature.h:431
void ResetLootMode()
Definition Creature.h:236
bool IsImmunedToSpell(SpellInfo const *spellInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const override
bool CanSwim() const override
void RegenerateHealth()
Definition Creature.cpp:939
CreatureTextRepeatGroup m_textRepeat
Definition Creature.h:463
void GetRespawnPosition(float &x, float &y, float &z, float *ori=nullptr, float *dist=nullptr) const
VendorItemData const * GetVendorItems() const
void InitializeMovementFlags()
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const *data=nullptr, uint32 vehId=0)
bool _regenerateHealth
Definition Creature.h:466
bool IsDungeonBoss() const
Definition Creature.h:123
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool allowDuplicate)
bool isWorldBoss() const
bool IsReturningHome() const
Definition Creature.cpp:321
void UpdateLevelDependantStats()
int8 m_originalEquipmentId
Definition Creature.h:412
void setDeathState(DeathState s) override
bool UpdateAllStats() override
void CallForHelp(float fRadius)
float GetAttackDistance(Unit const *player) const
uint32 GetShieldBlockValue() const override
ObjectGuid::LowType m_spawnId
For new or temporary creatures is 0 for saved it is lowguid.
Definition Creature.h:410
void SetDisplayId(uint32 modelId) override
void Update(uint32 time) override
Definition Creature.cpp:671
bool _IsTargetAcceptable(Unit const *target) const
bool IsCivilian() const
Definition Creature.h:106
void SetRespawnTime(uint32 respawn)
void SetObjectScale(float scale) override
Optional< std::string > m_scriptStringId
Definition Creature.h:432
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition Creature.h:238
void SetLootRecipient(Unit *unit, bool withGroup=true)
bool m_cannotReachTarget
Definition Creature.h:416
bool m_respawnCompatibilityMode
Definition Creature.h:450
CreatureTemplate const * m_creatureInfo
Definition Creature.h:429
bool IsSpawnedOnTransport() const
Definition Creature.h:96
bool CanFly() const override
Definition Creature.h:117
Position const & GetHomePosition() const
Definition Creature.h:305
bool CanGiveExperience() const
CreatureTextRepeatIds GetTextRepeatGroup(uint8 textGroup)
bool CanResetTalents(Player *player, bool pet) const
uint32 GetWaypointPath() const
Definition Creature.h:312
void LoadEquipment(int8 id=1, bool force=false)
uint8 GetLevelForTarget(WorldObject const *target) const override
bool HasReactState(ReactStates state) const
Definition Creature.h:130
bool AIM_Initialize(CreatureAI *ai=nullptr)
void DoNotReacquireSpellFocusTarget()
void RemoveCorpse(bool setSpawnTime=true, bool destroyForNearbyPlayers=true)
Definition Creature.cpp:369
void SendZoneUnderAttackMessage(Player *attacker)
Send a message to LocalDefense channel for players opposition team in the zone.
bool m_triggerJustAppeared
Definition Creature.h:449
void StartPickPocketRefillTimer()
void AllLootRemovedFromCorpse()
float GetAggroRange(Unit const *target) const
uint32 m_baseAttackPower
Definition Creature.h:420
void LoadTemplateImmunities()
void SignalFormationMovement()
Definition Creature.cpp:350
bool IsEngaged() const override
MovementGeneratorType m_defaultMovementType
Definition Creature.h:409
Unit * SelectNearestHostileUnitInAggroRange(bool useLOS=false, bool ignoreCivilians=false) const
void SetReactState(ReactStates st)
Definition Creature.h:128
bool CanHover() const
Definition Creature.h:118
void RemoveFromWorld() override
Definition Creature.cpp:301
void SetTextRepeatId(uint8 textGroup, uint8 id)
uint32 _waypointPathId
Definition Creature.h:444
void ResetPlayerDamageReq()
Definition Creature.h:332
float m_SightDistance
Definition Creature.h:344
bool hasLootRecipient() const
Definition Creature.h:225
void SetRespawnCompatibilityMode(bool mode=true)
Definition Creature.h:339
void SetCannotReachTarget(bool cannotReach)
void ClearTextRepeatGroup(uint8 textGroup)
void SetRespawnDelay(uint32 delay)
Definition Creature.h:271
void AddToWorld() override
Definition Creature.cpp:279
uint32 m_cannotReachTimer
Definition Creature.h:417
uint32 m_respawnDelay
Definition Creature.h:398
void SetScriptStringId(std::string id)
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const override
time_t m_corpseRemoveTime
Definition Creature.h:396
void ForcedDespawn(uint32 timeMSToDespawn=0, Seconds forceRespawnTimer=0s)
uint32 m_combatPulseDelay
Definition Creature.h:404
float GetPetChaseDistance() const
bool IsFormationLeaderMoveAllowed() const
Definition Creature.cpp:361
bool IsImmuneToNPC() const
Definition Unit.h:1154
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:541
bool HasStringId(std::string_view id) const
time_t m_respawnTime
Definition Creature.h:397
void DoFleeToGetAssistance()
Definition Creature.cpp:974
bool IsEscorted() const
void AtEngage(Unit *target) override
uint32 GetScriptId() const
CreatureData const * m_creatureData
Definition Creature.h:430
float m_CombatDistance
Definition Creature.h:344
void AtDisengage() override
bool hasInvolvedQuest(uint32 quest_id) const override
uint32 m_boundaryCheckTime
Definition Creature.h:402
bool isCanInteractWithBattleMaster(Player *player, bool msg) const
ObjectGuid m_lootRecipient
Definition Creature.h:391
Position m_homePosition
Definition Creature.h:424
Player * GetLootRecipient() const
static float _GetHealthMod(int32 Rank)
CreatureData const * GetCreatureData() const
Definition Creature.h:196
bool IsInvisibleDueToDespawn() const override
bool CanGeneratePickPocketLoot() const
uint32 m_PlayerDamageReq
Definition Creature.h:333
bool CanIgnoreFeignDeath() const
Definition Creature.h:258
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:92
bool CanNotReachTarget() const
Definition Creature.h:300
bool m_AlreadyCallAssistance
Definition Creature.h:414
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:195
uint32 GetRespawnDelay() const
Definition Creature.h:270
bool IsFormationLeader() const
Definition Creature.cpp:342
bool CanCreatureAttack(Unit const *victim, bool force=true) const
bool CanRegenerateHealth() const
Definition Creature.h:293
void RefreshCanSwimFlag(bool recheck=false)
bool DisableReputationGain
Definition Creature.h:427
void SetTarget(ObjectGuid const &guid) override
CreatureGroup * m_formation
Definition Creature.h:448
static bool DeleteFromDB(ObjectGuid::LowType spawnId)
void InitializeReactState()
bool AIM_Create(CreatureAI *ai=nullptr)
uint32 m_corpseDelay
Definition Creature.h:399
bool _regenerateHealthLock
Definition Creature.h:467
void Motion_Initialize()
bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const override
uint32 UpdateVendorItemCurrentCount(VendorItem const *vItem, uint32 used_count)
void SetSpawnHealth()
bool CheckNoGrayAggroConfig(uint32 playerLevel, uint32 creatureLevel) const
uint8 m_equipmentId
Definition Creature.h:411
bool isTappedBy(Player const *player) const
Creature(bool isWorldObject=false)
Definition Creature.cpp:254
CreatureGroup * GetFormation()
Definition Creature.h:322
uint32 GetCorpseDelay() const
Definition Creature.h:104
void UpdateMovementFlags()
bool CanAssistTo(Unit const *u, Unit const *enemy, bool checkfaction=true) const
std::string_view GetStringId(StringIdType type) const
Definition Creature.h:205
bool CanEnterWater() const override
uint32 m_originalEntry
Definition Creature.h:422
float GetNativeObjectScale() const override
void ExitVehicle(Position const *exitPosition=nullptr) override
Unit * SelectVictim()
void SearchFormation()
Definition Creature.cpp:329
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
bool m_isTempWorldObject
Definition Creature.h:346
Group * GetLootRecipientGroup() const
struct Creature::@185 _spellFocusInfo
std::string GetScriptName() const
time_t GetLastDamagedTime() const
Definition Creature.h:358
ObjectGuid m_lootRecipientGroup
Definition Creature.h:392
MovementGeneratorType GetDefaultMovementType() const override
Definition Creature.h:120
void SetSpellFocus(Spell const *focusSpell, WorldObject const *target)
void SaveRespawnTime(uint32 forceDelay=0)
uint8 GetCurrentEquipmentId() const
Definition Creature.h:186
bool InitEntry(uint32 entry, CreatureData const *data=nullptr)
Definition Creature.cpp:441
void LoadTemplateRoot()
Unit * SelectNearestTarget(float dist=0, bool playerOnly=false) const
void SetCorpseDelay(uint32 delay, bool ignoreCorpseDecayRatio=false)
Definition Creature.h:98
void SetMeleeDamageSchool(SpellSchools school)
Definition Creature.h:168
void SaveToDB()
Unit * SelectNearestTargetInAttackDistance(float dist=0) const
void SelectLevel()
CreatureMovementData const & GetMovementTemplate() const
void SendAIReaction(AiReaction reactionType)
static float _GetDamageMod(int32 Rank)
void ResetPickPocketRefillTimer()
Definition Creature.h:220
void SetNoCallAssistance(bool val)
Definition Creature.h:253
bool m_ignoreCorpseDecayRatio
Definition Creature.h:400
bool CanAlwaysSee(WorldObject const *obj) const override
bool hasQuest(uint32 quest_id) const override
void Regenerate(Powers power)
Definition Creature.cpp:882
time_t GetRespawnTimeEx() const
CreatureAddon const * GetCreatureAddon() const
std::string const & GetAIName() const
void CallAssistance()
void InheritStringIds(Creature const *parent)
bool IsImmuneToPC() const
Definition Unit.h:1151
void SetCanDualWield(bool value) override
bool IsInEvadeMode() const
Definition Creature.h:155
bool Create(ObjectGuid::LowType guidlow, Map *map, uint32 phaseMask, uint32 entry, Position const &pos, CreatureData const *data=nullptr, uint32 vehId=0, bool dynamic=false)
void ReacquireSpellFocusTarget()
CreatureAI * AI() const
Definition Creature.h:163
uint32 m_baseRangedAttackPower
Definition Creature.h:421
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
uint32 m_groupLootTimer
Definition Creature.h:285
bool isElite() const
std::string GetDebugInfo() const override
bool CanStartAttack(Unit const *u, bool force) const
void LowerPlayerDamageReq(uint32 unDamage)
bool IsMovementPreventedByCasting() const override
void SetOriginalEntry(uint32 entry)
Definition Creature.h:336
bool _isMissingCanSwimFlagOutOfCombat
Definition Creature.h:469
bool HasSpellFocus(Spell const *focusSpell=nullptr) const override
uint32 m_combatPulseTime
Definition Creature.h:403
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:293
Seconds const m_respawnTimer
Definition Creature.h:495
bool Execute(uint64 e_time, uint32 p_time) override
Definition Creature.cpp:248
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:102
Definition Group.h:165
bool isEmpty() const
Definition LinkedList.h:108
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:78
iterator end()
iterator begin()
Definition Map.h:302
bool IsDungeon() const
Definition Map.cpp:4231
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition Map.cpp:1108
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:509
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:2484
time_t GetLinkedRespawnTime(ObjectGuid guid) const
Definition Map.cpp:4537
bool IsRaid() const
Definition Map.cpp:4241
bool Is25ManRaid() const
Definition Map.cpp:4256
void ApplyDynamicModeRespawnScaling(WorldObject const *obj, ObjectGuid::LowType spawnId, uint32 &respawnDelay, uint32 mode) const
Definition Map.cpp:3312
ObjectGuid::LowType GenerateLowGuid()
Definition Map.h:607
time_t GetCreatureRespawnTime(ObjectGuid::LowType spawnId) const
Definition Map.h:574
void SaveRespawnInfoDB(RespawnInfo const &info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:4488
bool IsSpawnGroupActive(uint32 groupId) const
Definition Map.cpp:3495
void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, PositionFullTerrainStatus &data, Optional< uint8 > reqLiquidType={}, float collisionHeight=2.03128f) const
Definition Map.cpp:2723
void SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 gridId, CharacterDatabaseTransaction dbTrans=nullptr, bool startup=false)
Definition Map.cpp:4455
CreatureBySpawnIdContainer & GetCreatureBySpawnIdStore()
Definition Map.h:512
PlayerList const & GetPlayers() const
Definition Map.h:468
void Respawn(RespawnInfo *info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:3105
MovementGeneratorType GetCurrentMovementGeneratorType() const
void MoveSeekAssistance(float x, float y, float z)
void MoveFall(uint32 id=0)
void InitializeDefault()
static ObjectGuid const Empty
Definition ObjectGuid.h:140
bool IsEmpty() const
Definition ObjectGuid.h:172
uint32 LowType
Definition ObjectGuid.h:142
void Clear()
Definition ObjectGuid.h:150
static void ChooseCreatureFlags(CreatureTemplate const *cinfo, uint32 *npcflag, uint32 *unit_flags, uint32 *dynamicflags, CreatureData const *data=nullptr)
static std::string_view GetLocaleString(std::vector< std::string > const &data, LocaleConstant locale)
Definition ObjectMgr.h:1519
static uint32 ChooseDisplayId(CreatureTemplate const *cinfo, CreatureData const *data=nullptr)
virtual void RemoveDynamicFlag(uint32 flag)
Definition Object.h:90
static Creature * ToCreature(Object *o)
Definition Object.h:189
bool IsPlayer() const
Definition Object.h:182
float GetObjectScale() const
Definition Object.h:84
static Unit * ToUnit(Object *o)
Definition Object.h:195
bool IsInWorld() const
Definition Object.h:73
bool HasDynamicFlag(uint32 flag) const
Definition Object.h:88
TypeID GetTypeId() const
Definition Object.h:93
uint16 m_valuesCount
Definition Object.h:248
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:89
float GetFloatValue(uint16 index) const
Definition Object.cpp:253
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:691
uint32 GetEntry() const
Definition Object.h:81
void _Create(ObjectGuid const &guid)
Definition Object.cpp:109
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
void SetEntry(uint32 entry)
Definition Object.h:82
virtual void SetObjectScale(float scale)
Definition Object.h:85
ObjectGuid GetGUID() const
Definition Object.h:79
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:273
uint32 GetTeam() const
Definition Player.h:1818
Group * GetGroup()
Definition Player.h:2159
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition Player.cpp:23132
void setUInt16(uint8 index, uint16 value)
void setUInt32(uint8 index, uint32 value)
void setFloat(uint8 index, float value)
void setUInt8(uint8 index, uint8 value)
bool IsEffect() const
bool IsChanneled() const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:375
bool HasAura(AuraType aura) const
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition SpellInfo.h:482
Definition Spell.h:152
SpellInfo const * GetSpellInfo() const
Definition Spell.h:459
bool IsFocusDisabled() const
Definition Spell.cpp:7513
int32 GetCastTime() const
Definition Spell.h:427
Spell(WorldObject *caster, SpellInfo const *info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID=ObjectGuid::Empty)
Definition Spell.cpp:552
void EvaluateSuppressed(bool canExpire=false)
Unit * GetCurrentVictim()
Unit * GetAnyTarget() const
void Update(uint32 tdiff)
bool IsTrainerValidForPlayer(Player const *player) const
Definition Trainer.cpp:209
Type GetTrainerType() const
Definition Trainer.h:76
bool Remove(KEY_TYPE const &handle)
bool Insert(KEY_TYPE const &handle, SPECIFIC_TYPE *obj)
virtual void InitializeAI()
Definition UnitAI.cpp:36
Definition Unit.h:783
int32 ModifyHealth(int32 val)
Definition Unit.cpp:8321
void ClearUnitState(uint32 f)
Definition Unit.h:891
bool IsVehicle() const
Definition Unit.h:901
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:833
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:8379
bool IsUnderLastManaUseEffect() const
Definition Unit.cpp:10822
bool IsCharmed() const
Definition Unit.h:1293
Vehicle * GetVehicle() const
Definition Unit.h:1753
virtual bool IsMovementPreventedByCasting() const
Definition Unit.cpp:3146
bool IsBattleMaster() const
Definition Unit.h:1121
bool isTargetableForAttack(bool checkFakeDeath=true) const
Definition Unit.cpp:8307
bool IsHunterPet() const
Definition Unit.h:899
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1397
void SetAnimTier(AnimTier animTier)
Definition Unit.cpp:10367
void AIUpdateTick(uint32 diff)
Definition Unit.cpp:9491
bool CanHaveThreatList() const
====================== THREAT & COMBAT ====================
Definition Unit.h:1136
bool SetFall(bool enable)
Definition Unit.cpp:13314
void UpdateObjectVisibility(bool forced=true) override
Definition Unit.cpp:12151
void SetFullHealth()
Definition Unit.h:941
void SetHoverHeight(float hoverHeight)
Definition Unit.h:1229
ThreatManager & GetThreatManager()
Definition Unit.h:1169
void ReplaceAllPvpFlags(UnitPVPStateFlags flags)
Definition Unit.h:999
void AddToWorld() override
Definition Unit.cpp:9569
virtual void SetCanDualWield(bool value)
Definition Unit.h:852
void SetControlled(bool apply, UnitState state)
Definition Unit.cpp:11227
uint8 GetClass() const
Definition Unit.h:909
uint32 m_regenTimer
Definition Unit.h:1914
void SetCreateHealth(uint32 val)
Definition Unit.h:1462
Vehicle * m_vehicle
Definition Unit.h:1916
void UpdateDisplayPower()
Definition Unit.cpp:5395
void SetRace(uint8 race)
Definition Unit.h:907
NPCFlags GetNpcFlags() const
Definition Unit.h:1109
void UpdateSpeed(UnitMoveType mtype)
Definition Unit.cpp:8463
bool IsMovedByClient() const
Definition Unit.h:1313
bool IsPolymorphed() const
Definition Unit.cpp:10354
void SetFaction(uint32 faction) override
Definition Unit.h:988
virtual void SetPvP(bool state)
Definition Unit.cpp:11927
ObjectGuid GetOwnerGUID() const override
Definition Unit.h:1254
void StopMoving(bool force=false)
Definition Unit.cpp:10289
Unit * getAttackerForHelper() const
Definition Unit.cpp:5454
Trinity::unique_trackable_ptr< Vehicle > m_vehicleKit
Definition Unit.h:1917
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, WorldObject const *caster, bool requireImmunityPurgesEffectAttribute=false) const
Definition Unit.cpp:7631
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value, uint8 damageIndex=0)
Definition Unit.h:1568
CharmInfo * m_charmInfo
Definition Unit.h:1907
void ReplaceAllUnitFlags(UnitFlags flags)
Definition Unit.h:970
MotionMaster * GetMotionMaster()
Definition Unit.h:1683
bool IsPet() const
Definition Unit.h:898
Powers GetPowerType() const
Definition Unit.h:945
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:967
void Dismount()
Definition Unit.cpp:8174
bool SetHover(bool enable, bool updateAnimTier=true)
Definition Unit.cpp:13475
uint32 GetMaxHealth() const
Definition Unit.h:928
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:11935
virtual void AtDisengage()
Definition Unit.h:1935
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:973
std::string GetDebugInfo() const override
Definition Unit.cpp:13921
void ReplaceAllPetFlags(UnitPetFlag flags)
Definition Unit.h:1010
bool IsAlive() const
Definition Unit.h:1247
float GetCombatReach() const override
Definition Unit.h:853
void ReplaceAllVisFlags(UnitVisFlags flags)
Definition Unit.h:1022
DeathState m_deathState
Definition Unit.h:1868
void SetHealth(uint32 val)
Definition Unit.cpp:9338
UnitFlags GetUnitFlags() const
Definition Unit.h:966
TempSummon * ToTempSummon()
Definition Unit.h:1810
void SetMaxPower(Powers power, uint32 val)
Definition Unit.cpp:9439
ObjectGuid GetCharmerOrOwnerGUID() const override
Definition Unit.h:1273
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:4558
void SetNativeDisplayId(uint32 displayId)
Definition Unit.h:1602
bool SetDisableGravity(bool disable, bool updateAnimTier=true)
Definition Unit.cpp:13262
void SetVirtualItem(uint32 slot, uint32 itemId)
Definition Unit.cpp:13839
void AddUnitState(uint32 f)
Definition Unit.h:889
float GetTotalAuraMultiplier(AuraType auraType) const
Definition Unit.cpp:4820
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition Unit.cpp:8124
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.cpp:11792
void SetBoundingRadius(float boundingRadius)
Definition Unit.h:856
void SetCreateMana(uint32 val)
Definition Unit.h:1464
bool isInAccessiblePlaceFor(Creature const *c) const
Definition Unit.cpp:3177
Unit * EnsureVictim() const
Definition Unit.h:875
void RefreshAI()
Definition Unit.cpp:9523
virtual void SetSheath(SheathState sheathed)
Definition Unit.h:984
Unit * GetCharmerOrOwner() const
Definition Unit.h:1278
virtual void UpdateDamagePhysical(WeaponAttackType attType)
void SetFacingToObject(WorldObject const *object, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13235
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:7751
bool SetSwim(bool enable)
Definition Unit.cpp:13330
void SetCombatReach(float combatReach)
Definition Unit.h:854
void SetEmoteState(Emote emote)
Definition Unit.h:981
void SetPvpFlag(UnitPVPStateFlags flags)
Definition Unit.h:997
bool SetCanFly(bool enable, bool packetOnly=false)
Definition Unit.cpp:13349
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
Definition Unit.cpp:4885
uint32 GetDisplayId() const
Definition Unit.h:1598
bool IsAIEnabled() const
Definition Unit.h:812
uint32 GetNativeDisplayId() const
Definition Unit.h:1600
bool IsHovering() const
Definition Unit.h:1233
bool PopAI()
Definition Unit.cpp:9512
uint32 GetMaxPower(Powers power) const
Definition Unit.h:950
bool IsSummon() const
Definition Unit.h:896
bool IsInWater() const
Definition Unit.cpp:3185
uint32 GetHealth() const
Definition Unit.h:927
TransportBase * GetDirectTransport() const
Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
Definition Unit.cpp:11837
uint32 GetFaction() const override
Definition Unit.h:987
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool force=false)
Definition Unit.cpp:9398
void SetAI(UnitAI *newAI)
Definition Unit.cpp:9506
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4565
void EngageWithTarget(Unit *who)
Definition Unit.cpp:8232
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition Unit.cpp:12123
uint8 GetLevelForTarget(WorldObject const *) const override
Definition Unit.h:904
int32 GetTotalAuraModifier(AuraType auraType) const
Definition Unit.cpp:4815
void SetFullPower(Powers power)
Definition Unit.h:955
bool IsRooted() const
Definition Unit.h:1182
bool CreateVehicleKit(uint32 id, uint32 creatureEntry)
Definition Unit.cpp:11767
virtual void SetDisplayId(uint32 modelId)
Definition Unit.cpp:10383
bool IsGuardian() const
Definition Unit.h:897
Unit * GetVictim() const
Definition Unit.h:873
bool IsUnderWater() const
Definition Unit.cpp:3190
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition Unit.cpp:8618
DeathState getDeathState() const
Definition Unit.h:1251
bool IsEngagedBy(Unit const *who) const
Definition Unit.h:1141
bool IsCritter() const
Definition Unit.h:1131
bool HasUnitState(const uint32 f) const
Definition Unit.h:890
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition Unit.cpp:8082
virtual void Update(uint32 time) override
Definition Unit.cpp:440
void ProcessPositionDataChanged(PositionFullTerrainStatus const &data) override
Definition Unit.cpp:3195
void SetLevel(uint8 lvl, bool sendUpdate=true)
Definition Unit.cpp:9321
void SetCanModifyStats(bool modifyStats)
Definition Unit.h:1548
void SetClass(uint8 classId)
Definition Unit.h:910
void SetFacingTo(float ori, bool force=true, uint32 movementId=EVENT_FACE)
Definition Unit.cpp:13226
virtual bool CanSwim() const
Definition Unit.cpp:12789
void RemoveFromWorld() override
Definition Unit.cpp:9578
void SetStandState(UnitStandStateType state)
Definition Unit.cpp:10340
bool isDying() const
Definition Unit.h:1248
float GetStat(Stats stat) const
Definition Unit.h:917
int32 GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
Definition Unit.cpp:4875
void RemoveAllAuras()
Definition Unit.cpp:4180
void ReplaceAllUnitFlags2(UnitFlags2 flags)
Definition Unit.h:976
virtual void setDeathState(DeathState s)
Definition Unit.cpp:8668
void SetMaxHealth(uint32 val)
Definition Unit.cpp:9370
virtual void AtEngage(Unit *target)
Definition Unit.cpp:8725
uint32 GetPower(Powers power) const
Definition Unit.h:948
CombatManager & GetCombatManager()
Definition Unit.h:1144
void SetUnitFlag(UnitFlags flags)
Definition Unit.h:968
bool IsFlying() const
Definition Unit.h:1778
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:801
void SetAttackTime(WeaponAttackType att, uint32 val)
Definition Unit.h:960
bool IsSpiritHealer() const
Definition Unit.h:1124
bool IsTotem() const
Definition Unit.h:900
void SetInFront(WorldObject const *target)
Definition Unit.cpp:13220
void SetModCastingSpeed(float castingSpeed)
Definition Unit.h:964
Vehicle * GetVehicleKit() const
Definition Unit.h:1751
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:1113
bool IsSpiritService() const
Definition Unit.h:1130
bool IsFalling() const
Definition Unit.cpp:12784
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
Definition Unit.cpp:9011
void SetShapeshiftForm(ShapeshiftForm form)
Definition Unit.cpp:8904
uint8 GetLevel() const
Definition Unit.h:903
void SetMountDisplayId(uint32 mountDisplayId)
Definition Unit.h:1029
bool IsInCombat() const
Definition Unit.h:1158
void SetIsCombatDisallowed(bool apply)
Definition Unit.h:1844
uint32 GetDynamicFlags() const override
Definition Unit.h:832
bool IsSpiritGuide() const
Definition Unit.h:1125
bool isDead() const
Definition Unit.h:1249
virtual void ExitVehicle(Position const *exitPosition=nullptr)
Definition Unit.cpp:12632
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:45
void Reset(bool evading=false)
Reapplies immunities and reinstalls accessories. Only has effect for creatures.
Definition Vehicle.cpp:137
void Install()
Initializes power type for vehicle. Nothing more.
Definition Vehicle.cpp:77
uint32 GetMapId() const
Definition Position.h:193
uint32 GetPhaseMask() const
Definition Object.h:370
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1784
Map * GetMap() const
Definition Object.h:451
void UpdateAllowedPositionZ(float x, float y, float &z, float *groundZ=nullptr) const
Definition Object.cpp:1417
virtual bool IsInvisibleDueToDespawn() const
Definition Object.h:627
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2857
bool IsHostileTo(WorldObject const *target) const
Definition Object.cpp:2797
float GetTransOffsetX() const
Definition Object.h:567
uint32 LastUsedScriptID
Definition Object.h:563
Unit * GetOwner() const
Definition Object.cpp:2181
ZoneScript * GetZoneScript() const
Definition Object.h:457
void SetZoneScript()
Definition Object.cpp:1972
void setActive(bool isActiveObject)
Definition Object.cpp:992
float GetTransOffsetY() const
Definition Object.h:568
float GetFloorZ() const
Definition Object.cpp:3585
std::string const & GetName() const
Definition Object.h:384
virtual void SetMap(Map *map)
Definition Object.cpp:1809
float GetTransOffsetZ() const
Definition Object.h:569
void AddObjectToRemoveList()
Definition Object.cpp:1839
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition Object.cpp:1227
void DestroyForNearbyPlayers()
Definition Object.cpp:3448
Transport * GetTransport() const
Definition Object.h:566
bool IsNeutralToAll() const
Definition Object.cpp:2820
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Object.cpp:2204
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1193
void SetName(std::string newname)
Definition Object.h:385
EventProcessor m_Events
Definition Object.h:593
float GetVisibilityRange() const
Definition Object.cpp:1493
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition Object.h:447
uint32 GetAreaId() const
Definition Object.h:376
float GetTransOffsetO() const
Definition Object.h:570
void SetVisibilityDistanceOverride(VisibilityDistanceType type)
Definition Object.cpp:1023
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1188
MovementInfo m_movementInfo
Definition Object.h:577
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition Object.h:446
float GetDistanceZ(WorldObject const *obj) const
Definition Object.cpp:1094
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:2802
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1161
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket && Move()
Definition Packet.h:53
virtual uint32 GetCreatureEntry(ObjectGuid::LowType, CreatureData const *data)
virtual void OnCreatureRemove(Creature *)
Definition ZoneScript.h:40
virtual void OnCreatureCreate(Creature *)
Definition ZoneScript.h:39
@ SMSG_ZONE_UNDER_ATTACK
Definition Opcodes.h:625
#define sWorld
Definition World.h:901
@ CONFIG_CORPSE_DECAY_ELITE
Definition World.h:308
@ CONFIG_NO_GRAY_AGGRO_BELOW
Definition World.h:391
@ CONFIG_CREATURE_PICKPOCKET_REFILL
Definition World.h:383
@ CONFIG_RESPAWN_DYNAMICMODE
Definition World.h:396
@ CONFIG_MAX_PLAYER_LEVEL
Definition World.h:237
@ CONFIG_CORPSE_DECAY_NORMAL
Definition World.h:306
@ CONFIG_CORPSE_DECAY_WORLDBOSS
Definition World.h:310
@ CONFIG_NO_GRAY_AGGRO_ABOVE
Definition World.h:390
@ CONFIG_CREATURE_STOP_FOR_PLAYER
Definition World.h:384
@ CONFIG_CORPSE_DECAY_RARE
Definition World.h:307
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition World.h:291
@ CONFIG_CORPSE_DECAY_RAREELITE
Definition World.h:309
@ CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY
Definition World.h:289
@ RATE_CREATURE_NORMAL_SPELLDAMAGE
Definition World.h:449
@ RATE_CREATURE_NORMAL_HP
Definition World.h:439
@ RATE_CREATURE_NORMAL_DAMAGE
Definition World.h:444
@ RATE_CREATURE_ELITE_RARE_DAMAGE
Definition World.h:448
@ RATE_CREATURE_AGGRO
Definition World.h:454
@ RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE
Definition World.h:450
@ RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE
Definition World.h:447
@ RATE_CREATURE_ELITE_RAREELITE_DAMAGE
Definition World.h:446
@ RATE_POWER_MANA
Definition World.h:412
@ RATE_CREATURE_ELITE_WORLDBOSS_HP
Definition World.h:442
@ RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE
Definition World.h:451
@ RATE_HEALTH
Definition World.h:411
@ RATE_CREATURE_ELITE_ELITE_DAMAGE
Definition World.h:445
@ RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE
Definition World.h:452
@ RATE_CREATURE_ELITE_RARE_SPELLDAMAGE
Definition World.h:453
@ RATE_CREATURE_ELITE_ELITE_HP
Definition World.h:440
@ RATE_CREATURE_ELITE_RARE_HP
Definition World.h:443
@ RATE_POWER_FOCUS
Definition World.h:417
@ RATE_CORPSE_DECAY_LOOTED
Definition World.h:465
@ RATE_CREATURE_ELITE_RAREELITE_HP
Definition World.h:441
@ CONFIG_SIGHT_MONSTER
Definition World.h:189
@ CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS
Definition World.h:193
@ CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS
Definition World.h:194
@ CONFIG_REGEN_HP_CANNOT_REACH_TARGET_IN_RAID
Definition World.h:179
ObjectData const creatureData[]
uint32 const Entry[5]
CreatureAI * SelectAI(Creature *creature)
time_t GetGameTime()
Definition GameTime.cpp:42
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)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
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:66
bool IsValidMapCoord(float c)
GridCoord ComputeGridCoord(float x, float y)
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:192
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:168
CharmSpellInfo * GetCharmSpell(uint8 index)
Definition Unit.h:718
std::vector< uint32 > auras
VisibilityDistanceType visibilityDistanceType
static CreatureBaseStats const * GetBaseStats(uint8 level, uint8 unitClass)
Definition Creature.cpp:243
float GenerateBaseDamage(CreatureTemplate const *info) const
uint32 GenerateMana(CreatureTemplate const *info) const
uint32 GenerateHealth(CreatureTemplate const *info) const
uint32 GenerateArmor(CreatureTemplate const *info) const
float wander_distance
uint32 dynamicflags
uint32 unit_flags
uint32 currentwaypoint
std::vector< std::string > Name
CreatureRandomMovementType Random
bool IsSwimAllowed() const
CreatureFlightMovementType Flight
bool IsFlightAllowed() const
std::string ToString() const
Definition Creature.cpp:61
CreatureChaseMovementType Chase
CreatureGroundMovementType Ground
void InitializeQueryData()
Definition Creature.cpp:174
CreatureFamily family
uint32 GetFirstValidModelId() const
Definition Creature.cpp:123
std::string Name
uint32 spells[MAX_CREATURE_SPELLS]
int32 resistance[MAX_SPELL_SCHOOL]
std::string StringId
uint32 GetFirstVisibleModel() const
Definition Creature.cpp:153
CreatureMovementData Movement
uint32 KillCredit[MAX_KILL_CREDIT]
uint32 GetFirstInvisibleModel() const
Definition Creature.cpp:132
WorldPacket QueryData[TOTAL_LOCALES]
std::string Title
WorldPacket BuildQueryData(LocaleConstant loc) const
Definition Creature.cpp:180
uint32 DifficultyEntry[MAX_DIFFICULTY - 1]
uint32 GetRandomValidModelId() const
Definition Creature.cpp:110
std::string IconName
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]
struct GameObjectTemplate::@191::@206 moTransport
bool HasFlag(ItemFlags flag) const
void clear()
Definition Loot.cpp:149
uint8 maxDuplicates
Definition Loot.h:238
LootType loot_type
Definition Loot.h:237
struct MovementInfo::TransportInfo transport
float m_positionZ
Definition Position.h:58
std::string ToString() const
Definition Position.cpp:149
float m_positionX
Definition Position.h:56
float GetPositionZ() const
Definition Position.h:81
float m_positionY
Definition Position.h:57
bool IsInDist2d(float x, float y, float dist) const
Definition Position.h:145
float GetOrientation() const
Definition Position.h:82
bool IsInDist(float x, float y, float z, float dist) const
Definition Position.h:148
bool IsPositionValid() const
Definition Position.cpp:44
void SetOrientation(float orientation)
Definition Position.h:74
Position GetPosition() const
Definition Position.h:87
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80
void Relocate(float x, float y)
Definition Position.h:66
ObjectGuid::LowType spawnId
Definition Map.h:281
time_t respawnTime
Definition Map.h:283
SpawnObjectType type
Definition Map.h:280
uint32 phaseMask
Definition SpawnData.h:98
uint8 spawnMask
Definition SpawnData.h:100
uint32 id
Definition SpawnData.h:96
Position spawnPoint
Definition SpawnData.h:97
int32 spawntimesecs
Definition SpawnData.h:99
std::string StringId
Definition SpawnData.h:102
SpawnGroupFlags flags
Definition SpawnData.h:63
uint32 spawnId
Definition SpawnData.h:85
SpawnGroupTemplateData const * spawnGroupData
Definition SpawnData.h:88
uint32 mapId
Definition SpawnData.h:86
ActiveStates GetType() const
Definition Unit.h:640
uint32 GetAction() const
Definition Unit.h:641
time_t lastIncrementTime
Definition Creature.h:47
VendorItemCount(uint32 _item, uint32 _count)
Definition Creature.cpp:82
std::vector< VendorItem > m_items
VendorItem const * FindItemCostPair(uint32 item_id, uint32 extendedCost) const
Definition Creature.cpp:102
bool RemoveItem(uint32 item_id)
Definition Creature.cpp:90
uint32 ExtendedCost
bool IsGoldRequired(ItemTemplate const *pProto) const
Definition Creature.cpp:85
uint32 maxcount
uint32 incrtime
uint32 QuestItems[MAX_CREATURE_QUEST_ITEMS]
uint32 ProxyCreatureID[MAX_KILL_CREDIT]
uint32 CreatureDisplayID[MAX_CREATURE_MODELS]