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