OregonCore  revision 3611e8a-git
Your Favourite TBC server
Creature.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore 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 "Common.h"
19 #include "Database/DatabaseEnv.h"
20 #include "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "World.h"
23 #include "ObjectMgr.h"
24 #include "MapManager.h"
25 #include "SpellMgr.h"
26 #include "Creature.h"
27 #include "QuestDef.h"
28 #include "GossipDef.h"
29 #include "Player.h"
30 #include "PoolMgr.h"
31 #include "Opcodes.h"
32 #include "Log.h"
33 #include "LootMgr.h"
34 #include "CreatureAI.h"
35 #include "CreatureAISelector.h"
36 #include "Formulas.h"
37 #include "SpellAuras.h"
38 #include "InstanceData.h"
39 #include "Battleground.h"
40 #include "Util.h"
41 #include "GridNotifiers.h"
42 #include "GridNotifiersImpl.h"
43 #include "CellImpl.h"
44 #include "GameEventMgr.h"
45 #include "CreatureGroups.h"
46 #include "MoveSpline.h"
47 
49 {
50  for (TrainerSpellList::iterator itr = spellList.begin(); itr != spellList.end(); ++itr)
51  delete (*itr);
52  spellList.clear();
53 }
54 
56 {
57  for (TrainerSpellList::const_iterator itr = spellList.begin(); itr != spellList.end(); ++itr)
58  if ((*itr)->spell == spell_id)
59  return *itr;
60 
61  return NULL;
62 }
63 
65 {
66  bool found = false;
67  for (VendorItemList::iterator i = m_items.begin(); i != m_items.end();)
68  {
69  if ((*i)->item == item_id)
70  {
71  i = m_items.erase(i++);
72  found = true;
73  }
74  else
75  ++i;
76  }
77  return found;
78 }
79 
80 size_t VendorItemData::FindItemSlot(uint32 item_id) const
81 {
82  for (size_t i = 0; i < m_items.size(); ++i)
83  if (m_items[i]->item == item_id)
84  return i;
85  return m_items.size();
86 }
87 
89 {
90  for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i)
91  if ((*i)->item == item_id)
92  return *i;
93  return NULL;
94 }
95 
97 {
98  uint32 c = 0;
99  uint32 modelIDs[4];
100 
101  if (modelid1) modelIDs[c++] = modelid1;
102  if (modelid2) modelIDs[c++] = modelid2;
103  if (modelid3) modelIDs[c++] = modelid3;
104  if (modelid4) modelIDs[c++] = modelid4;
105 
106  return ((c > 0) ? modelIDs[urand(0, c - 1)] : 0);
107 }
108 
110 {
111  if (modelid1) return modelid1;
112  if (modelid2) return modelid2;
113  if (modelid3) return modelid3;
114  if (modelid4) return modelid4;
115  return 0;
116 }
117 
118 bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
119 {
120  if (Unit* victim = Unit::GetUnit(m_owner, m_victim))
121  {
122  while (!m_assistants.empty())
123  {
124  Creature* assistant = Unit::GetCreature(m_owner, *m_assistants.begin());
125  m_assistants.pop_front();
126 
127  if (assistant && assistant->CanAssistTo(&m_owner, victim))
128  {
129  assistant->SetNoCallAssistance(true);
130  assistant->CombatStart(victim);
131  if (assistant->IsAIEnabled)
132  assistant->AI()->AttackStart(victim);
133  }
134  }
135  }
136  return true;
137 }
138 
139 bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
140 {
141  m_owner.DespawnOrUnsummon();
142  return true;
143 }
144 
145 Creature::Creature(bool isWorldObject): Unit(isWorldObject),
146  _pickpocketLootRestore(0),
147  _skinner(0),
148  m_GlobalCooldown(0),
149  hasPlayerDamaged(false), m_SightDistance(sWorld.getConfig(CONFIG_SIGHT_MONSTER)),
150  m_CombatDistance(MELEE_RANGE), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(25),
151  m_corpseDelay(60), m_respawnradius(0.0f), m_combatPulseTime(0), m_combatPulseDelay(0), m_emoteState(0), m_reactState(REACT_AGGRESSIVE), m_regenTimer(2000),
152  m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0),
153  m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false),
154  m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), DisableReputationGain(false), m_creatureData(NULL),
155  m_formation(NULL), m_creatureInfo(NULL)
156 {
159 
160  for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
161  m_spells[i] = 0;
162 
163  m_CreatureSpellCooldowns.clear();
165 
167  m_CombatDistance = 0; // MELEE_RANGE
168 
169  TriggerJustRespawned = false;
170  m_isTempWorldObject = false;
171 }
172 
174 {
175  m_vendorItemCounts.clear();
176 
177  delete i_AI;
178  i_AI = NULL;
179 }
180 
182 {
183  // Register the creature for guid lookup
184  if (!IsInWorld())
185  {
186  if (m_zoneScript)
187  m_zoneScript->OnCreatureCreate(this, true);
188 
191  SearchFormation();
192  AIM_Initialize();
193  }
194 }
195 
197 {
198  if (IsInWorld())
199  {
200  if (m_zoneScript)
201  m_zoneScript->OnCreatureCreate(this, false);
202 
203  if (m_formation)
204  sFormationMgr.RemoveCreatureFromGroup(m_formation, this);
205 
207 
209  }
210 }
211 
213 {
215  if (IsAlive())
217  RemoveCorpse(false);
218 }
219 
221 {
222  if (IsSummon())
223  return;
224 
225  uint32 lowguid = GetDBTableGUIDLow();
226  if (!lowguid)
227  return;
228 
229  CreatureGroupInfoType::iterator frmdata = sFormationMgr.CreatureGroupMap.find(lowguid);
230  if (frmdata != sFormationMgr.CreatureGroupMap.end())
231  sFormationMgr.AddCreatureToGroup(frmdata->second->leaderGUID, this);
232 }
233 
234 void Creature::RemoveCorpse(bool setSpawnTime)
235 {
236  if (getDeathState() != CORPSE)
237  return;
238 
239  m_corpseRemoveTime = time(NULL);
242  loot.clear();
243  uint32 respawnDelay = m_respawnDelay;
244  if (IsAIEnabled)
245  AI()->CorpseRemoved(respawnDelay);
246 
247  // Should get removed later, just keep "compatibility" with scripts
248  if (setSpawnTime)
249  m_respawnTime = time(NULL) + respawnDelay;
250 
251  float x, y, z, o;
252  GetRespawnPosition(x, y, z, &o);
253  SetHomePosition(x, y, z, o);
254  GetMap()->CreatureRelocation(this, x, y, z, o);
255 }
256 
260 bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData* data)
261 {
262  CreatureInfo const* normalInfo = sObjectMgr.GetCreatureTemplate(Entry);
263  if (!normalInfo)
264  {
265  sLog.outErrorDb("Creature::UpdateEntry creature entry %u does not exist.", Entry);
266  return false;
267  }
268 
269  // get heroic mode entry
270  uint32 actualEntry = Entry;
271  CreatureInfo const* cinfo = normalInfo;
272  if (normalInfo->HeroicEntry)
273  {
274  //we already have valid Map pointer for current creature!
275  if (GetMap()->IsHeroic())
276  {
277  cinfo = sObjectMgr.GetCreatureTemplate(normalInfo->HeroicEntry);
278  if (!cinfo)
279  {
280  sLog.outErrorDb("Creature::UpdateEntry creature heroic entry %u does not exist.", actualEntry);
281  return false;
282  }
283  }
284  }
285 
286  SetEntry(Entry); // normal entry always
287  m_creatureInfo = cinfo; // map mode related always
288 
289  // equal to player Race field, but creature does not have race
291 
292  // known valid are: CLASS_WARRIOR, CLASS_PALADIN, CLASS_ROGUE, CLASS_MAGE
294 
295  // Cancel load if no model defined
296  if (!(cinfo->GetFirstValidModelId()))
297  {
298  sLog.outErrorDb("Creature (Entry: %u) has no model defined in table creature_template, can't load. ", Entry);
299  return false;
300  }
301 
302  uint32 display_id = sObjectMgr.ChooseDisplayId(team, GetCreatureTemplate(), data);
303  CreatureModelInfo const* minfo = sObjectMgr.GetCreatureModelRandomGender(display_id);
304  if (!minfo) // Cancel load if no model defined
305  {
306  sLog.outErrorDb("Creature (Entry: %u) has model %u not found in table creature_model_info, can't load. ", Entry, display_id);
307  return false;
308  }
309 
310  display_id = minfo->modelid; // it can be different (for another gender)
311 
312  SetDisplayId(display_id);
313  SetNativeDisplayId(display_id);
315 
316  // Load creature equipment
317  if (!data || data->equipmentId == 0)
318  {
319  // use default from the template
320  LoadEquipment(cinfo->equipmentId);
321  }
322  else if (data && data->equipmentId != -1)
323  {
324  // override, -1 means no equipment
325  LoadEquipment(data->equipmentId);
326  }
327 
328  SetName(normalInfo->Name); // at normal entry always
329 
332 
334 
335  SetSpeed(MOVE_WALK, cinfo->speed_walk);
336  SetSpeed(MOVE_RUN, cinfo->speed_run);
337  SetSpeed(MOVE_SWIM, 1.0f); // using 1.0 rate
338  SetSpeed(MOVE_FLIGHT, 1.0f); // using 1.0 rate
339 
340  SetObjectScale(cinfo->scale);
341 
342  // checked at loading
346 
347  for (int i = 0; i < CREATURE_MAX_SPELLS; ++i)
349 
350  return true;
351 }
352 
353 bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data)
354 {
355  if (!InitEntry(Entry, team, data))
356  return false;
357 
358  CreatureInfo const* cInfo = GetCreatureTemplate();
359 
360  m_regenHealth = cInfo->RegenHealth;
361 
362  // creatures always have melee weapon ready if any unless specified otherwise
363  if (!GetCreatureAddon())
365 
367 
368  setFaction(cInfo->faction);
369 
371  SetUInt32Value(UNIT_NPC_FLAGS, cInfo->npcflag | sGameEventMgr.GetNPCFlag(this));
372  else
374 
377 
379 
383 
384  SelectLevel();
385 
388 
389  if (cInfo->resistance1 < 0)
390  {
393  }
394  else
396 
397  if (cInfo->resistance2 < 0)
398  {
401  }
402  else
404 
405  if (cInfo->resistance3 < 0)
406  {
409  }
410  else
412 
413  if (cInfo->resistance4 < 0)
414  {
417  }
418  else
420 
421  if (cInfo->resistance5 < 0)
422  {
425  }
426  else
428 
429  if (cInfo->resistance6 < 0)
430  {
433  }
434  else
436 
437 
438  SetCanModifyStats(true);
439  UpdateAllStats();
440 
441  // checked and error show at loading templates
442  if (FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction))
443  {
444  if (factionTemplate->factionFlags & FACTION_TEMPLATE_FLAG_PVP || IsPvP()) // PvP state may be set in UnitFlags.. Prevent overwrite
445  SetPvP(true);
446  else
447  SetPvP(false);
448  }
449 
450  // trigger creature is always not selectable and can not be attacked
451  if (isTrigger())
453 
455 
457  {
460  }
461 
463  LoadCreaturesAddon(true);
464  return true;
465 }
466 
468 {
469  if (m_GlobalCooldown <= diff)
470  m_GlobalCooldown = 0;
471  else
472  m_GlobalCooldown -= diff;
473 
475  {
476  TriggerJustRespawned = false;
477  AI()->JustRespawned();
478  }
479 
481 
482  switch (m_deathState)
483  {
484  case JUST_RESPAWNED:
485  // Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting.
486  sLog.outError("Creature (GUIDLow: %u Entry: %u) in wrong state: JUST_RESPAWNED (4)", GetGUIDLow(), GetEntry());
487  break;
488  case JUST_DIED:
489  // Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
490  sLog.outError("Creature (GUIDLow: %u Entry: %u) in wrong state: JUST_DEAD (1)", GetGUIDLow(), GetEntry());
491  break;
492  case DEAD:
493  {
494  time_t now = time(NULL);
495  if (m_respawnTime <= time(NULL))
496  {
497  time_t linkedRespawntime = GetLinkedCreatureRespawnTime();
498  if (!linkedRespawntime) // Can respawn
499  Respawn();
500  else // the master is dead
501  {
502  uint32 targetGuid = sObjectMgr.GetLinkedRespawnGuid(m_DBTableGuid);
503  if (targetGuid == m_DBTableGuid) // if linking self, never respawn (check delayed to next day)
505  else
506  m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little
507  SaveRespawnTime(); // also save to DB immediately
508  }
509  }
510  break;
511  }
512  case CORPSE:
513  {
514  Unit::Update(diff);
515  // deathstate changed on spells update, prevent problems
516  if (m_deathState != CORPSE)
517  break;
518 
520  {
521  if (m_groupLootTimer <= diff)
522  {
523  Group* group = sObjectMgr.GetGroupByLeader(lootingGroupLeaderGUID);
524  if (group)
525  group->EndRoll();
526  m_groupLootTimer = 0;
528  }
529  else m_groupLootTimer -= diff;
530  }
531  else if (m_corpseRemoveTime <= time(NULL))
532  {
533  RemoveCorpse(false);
534  DEBUG_LOG("Removing corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY));
535  }
536  break;
537  }
538  case ALIVE:
539  {
540  Unit::Update(diff);
541 
542  // creature can be dead after Unit::Update call
543  // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
544  if (!IsAlive())
545  break;
546 
547  // if creature is charmed, switch to charmed AI
548  if (NeedChangeAI)
549  {
550  UpdateCharmAI();
551  NeedChangeAI = false;
552  IsAIEnabled = true;
553  if (!IsInEvadeMode() && LastCharmerGUID)
554  if (Unit* charmer = ObjectAccessor::GetUnit(*this, LastCharmerGUID))
555  if (canStartAttack(charmer, true))
556  i_AI->AttackStart(charmer);
557 
558  LastCharmerGUID = 0;
559  }
560 
561  // if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now
562  if (m_combatPulseDelay > 0 && IsInCombat() && GetMap()->IsDungeon())
563  {
564  if (diff > m_combatPulseTime)
565  m_combatPulseTime = 0;
566  else
567  m_combatPulseTime -= diff;
568 
569  if (m_combatPulseTime == 0)
570  {
571  Map::PlayerList const &players = GetMap()->GetPlayers();
572  if (!players.isEmpty())
573  for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it)
574  {
575  if (Player* player = it->GetSource())
576  {
577  if (player->IsGameMaster())
578  continue;
579 
580  if (player->IsAlive() && this->IsHostileTo(player))
581  {
582  if (CanHaveThreatList())
583  AddThreat(player, 0.0f);
584  this->SetInCombatWith(player);
585  player->SetInCombatWith(this);
586  }
587  }
588  }
589 
591  }
592  }
593 
594  if (!IsInEvadeMode() && IsAIEnabled)
595  {
596  // do not allow the AI to be changed during update
597  m_AI_locked = true;
598 
599  i_AI->UpdateAI(diff);
600  m_AI_locked = false;
601  }
602 
603  // creature can be dead after UpdateAI call
604  // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly)
605  if (!IsAlive())
606  break;
607 
608  if (m_regenTimer > 0)
609  {
610  if (diff >= m_regenTimer)
611  m_regenTimer = 0;
612  else
613  m_regenTimer -= diff;
614  }
615 
616  if (m_regenTimer != 0)
617  break;
618 
619  if (!IsInEvadeMode() && (!IsInCombat() || IsPolymorphed())) // regenerate health if not in combat or if polymorphed
621 
622  RegenerateMana();
623 
625  break;
626  }
627  case DEAD_FALLING:
629  break;
630  default:
631  break;
632  }
633 }
634 
636 {
637  uint32 curValue = GetPower(POWER_MANA);
638  uint32 maxValue = GetMaxPower(POWER_MANA);
639 
640  if (curValue >= maxValue)
641  return;
642 
643  uint32 addvalue = 0;
644 
645  // Combat and any controlled creature
647  {
649  {
650  float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA);
651  float Spirit = GetStat(STAT_SPIRIT);
652 
653  addvalue = uint32((Spirit / 5.0f + 17.0f) * ManaIncreaseRate);
654  }
655  }
656  else
657  addvalue = maxValue / 3;
658 
659  // Apply modifiers (if any).
660  AuraList const& ModPowerRegenPCTAuras = this->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
661  for (AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
662  if ((*i)->GetMiscValue() == POWER_MANA)
663  AddPct(addvalue, (*i)->GetAmount());
664 
666 
667  ModifyPower(POWER_MANA, addvalue);
668 }
669 
671 {
672  if (!isRegeneratingHealth())
673  return;
674 
675  uint32 curValue = GetHealth();
676  uint32 maxValue = GetMaxHealth();
677 
678  if (curValue >= maxValue)
679  return;
680 
681  uint32 addvalue = 0;
682 
683  // Not only pet, but any controlled creature
684  if (GetCharmerOrOwnerGUID())
685  {
686  float HealthIncreaseRate = sWorld.getRate(RATE_HEALTH);
687  float Spirit = GetStat(STAT_SPIRIT);
688 
689  if (GetPower(POWER_MANA) > 0)
690  addvalue = uint32(Spirit * 0.25 * HealthIncreaseRate);
691  else
692  addvalue = uint32(Spirit * 0.80 * HealthIncreaseRate);
693  }
694  else
695  addvalue = maxValue / 3;
696 
697  // Apply modifiers (if any).
698  AuraList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
699  for (AuraList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
700  AddPct(addvalue, (*i)->GetAmount());
701 
703 
704  ModifyHealth(addvalue);
705 }
706 
708 {
709  if (!GetVictim())
710  return;
711 
713  return;
714 
715  float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS);
716  if (radius > 0)
717  {
718  Creature* creature = NULL;
719 
721  Cell cell(p);
722  cell.SetNoCreate();
725 
727 
728  cell.Visit(p, grid_creature_searcher, *GetMap(), *this, radius);
729 
730  SetNoSearchAssistance(true);
731  UpdateSpeed(MOVE_RUN, false);
732 
733  if (!creature)
735  else
736  GetMotionMaster()->MoveSeekAssistance(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ());
737  }
738 
739 }
740 
742 {
743  // make sure nothing can change the AI during AI update
744  if (m_AI_locked)
745  {
746  sLog.outDebug("AIM_Initialize: failed to init, locked.");
747  return false;
748  }
749 
750  UnitAI* oldAI = i_AI;
752  i_AI = ai ? ai : FactorySelector::selectAI(this);
753  delete oldAI;
754  IsAIEnabled = true;
755  i_AI->InitializeAI();
756  return true;
757 }
758 
759 bool Creature::Create(uint32 guidlow, Map* map, uint32 entry, uint32 team, float x, float y, float z, float ang, const CreatureData* data)
760 {
761  ASSERT(map);
762  SetMap(map);
763 
764  CreatureInfo const* cinfo = sObjectMgr.GetCreatureTemplate(entry);
765  if (!cinfo)
766  {
767  sLog.outError("Creature::Create(): creature template (guidlow: %u, entry: %u) does not exist.", guidlow, entry);
768  return false;
769  }
770 
773  Relocate(x, y, z, ang);
774 
775  if (!IsPositionValid())
776  {
777  sLog.outError("Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, entry, x, y);
778  return false;
779  }
780 
781  // Allow players to see those units while dead, do it here (mayby altered by addon auras)
784 
785  if (!CreateFromProto(guidlow, entry, team, data))
786  return false;
787 
788  switch (GetCreatureTemplate()->rank)
789  {
790  case CREATURE_ELITE_RARE:
792  break;
795  break;
798  break;
801  break;
802  default:
804  break;
805  }
806 
808  if (isSpiritHealer() || isSpiritGuide())
809  {
812  }
813 
814  return true;
815 }
816 
818 {
819  if (IsTotem() || isTrigger() || IsCritter() || isSpiritService())
821  else
823 }
824 
825 bool Creature::IsTrainerOf(Player* pPlayer, bool msg) const
826 {
827  if (!isTrainer())
828  return false;
829 
830  TrainerSpellData const* trainer_spells = GetTrainerSpells();
831 
832  if (!trainer_spells || trainer_spells->spellList.empty())
833  {
834  sLog.outErrorDb("Creature %u (Entry: %u) has UNIT_NPC_FLAG_TRAINER but trainer spell list is empty.",
835  GetGUIDLow(), GetEntry());
836  return false;
837  }
838 
839  switch (GetCreatureTemplate()->trainer_type)
840  {
841  case TRAINER_TYPE_CLASS:
842  if (pPlayer->getClass() != GetCreatureTemplate()->classNum)
843  {
844  if (msg)
845  {
846  pPlayer->PlayerTalkClass->ClearMenus();
847  switch (GetCreatureTemplate()->classNum)
848  {
849  case CLASS_DRUID:
850  pPlayer->PlayerTalkClass->SendGossipMenu(4913, GetGUID());
851  break;
852  case CLASS_HUNTER:
853  pPlayer->PlayerTalkClass->SendGossipMenu(10090, GetGUID());
854  break;
855  case CLASS_MAGE:
856  pPlayer->PlayerTalkClass->SendGossipMenu( 328, GetGUID());
857  break;
858  case CLASS_PALADIN:
859  pPlayer->PlayerTalkClass->SendGossipMenu(1635, GetGUID());
860  break;
861  case CLASS_PRIEST:
862  pPlayer->PlayerTalkClass->SendGossipMenu(4436, GetGUID());
863  break;
864  case CLASS_ROGUE:
865  pPlayer->PlayerTalkClass->SendGossipMenu(4797, GetGUID());
866  break;
867  case CLASS_SHAMAN:
868  pPlayer->PlayerTalkClass->SendGossipMenu(5003, GetGUID());
869  break;
870  case CLASS_WARLOCK:
871  pPlayer->PlayerTalkClass->SendGossipMenu(5836, GetGUID());
872  break;
873  case CLASS_WARRIOR:
874  pPlayer->PlayerTalkClass->SendGossipMenu(4985, GetGUID());
875  break;
876  }
877  }
878  return false;
879  }
880  break;
881  case TRAINER_TYPE_PETS:
882  if (pPlayer->getClass() != CLASS_HUNTER)
883  {
884  pPlayer->PlayerTalkClass->ClearMenus();
885  pPlayer->PlayerTalkClass->SendGossipMenu(3620, GetGUID());
886  return false;
887  }
888  break;
889  case TRAINER_TYPE_MOUNTS:
890  if (GetCreatureTemplate()->race && pPlayer->getRace() != GetCreatureTemplate()->race)
891  {
892  // Allowed to train if exalted
893  if (FactionTemplateEntry const* faction_template = GetFactionTemplateEntry())
894  {
895  if (pPlayer->GetReputationRank(faction_template->faction) == REP_EXALTED)
896  return true;
897  }
898 
899  if (msg)
900  {
901  pPlayer->PlayerTalkClass->ClearMenus();
902  switch (GetCreatureTemplate()->classNum)
903  {
904  case RACE_DWARF:
905  pPlayer->PlayerTalkClass->SendGossipMenu(5865, GetGUID());
906  break;
907  case RACE_GNOME:
908  pPlayer->PlayerTalkClass->SendGossipMenu(4881, GetGUID());
909  break;
910  case RACE_HUMAN:
911  pPlayer->PlayerTalkClass->SendGossipMenu(5861, GetGUID());
912  break;
913  case RACE_NIGHTELF:
914  pPlayer->PlayerTalkClass->SendGossipMenu(5862, GetGUID());
915  break;
916  case RACE_ORC:
917  pPlayer->PlayerTalkClass->SendGossipMenu(5863, GetGUID());
918  break;
919  case RACE_TAUREN:
920  pPlayer->PlayerTalkClass->SendGossipMenu(5864, GetGUID());
921  break;
922  case RACE_TROLL:
923  pPlayer->PlayerTalkClass->SendGossipMenu(5816, GetGUID());
924  break;
925  case RACE_UNDEAD_PLAYER:
926  pPlayer->PlayerTalkClass->SendGossipMenu(624, GetGUID());
927  break;
928  case RACE_BLOODELF:
929  pPlayer->PlayerTalkClass->SendGossipMenu(5862, GetGUID());
930  break;
931  case RACE_DRAENEI:
932  pPlayer->PlayerTalkClass->SendGossipMenu(5864, GetGUID());
933  break;
934  }
935  }
936  return false;
937  }
938  break;
940  if (GetCreatureTemplate()->trainer_spell && !pPlayer->HasSpell(GetCreatureTemplate()->trainer_spell))
941  {
942  if (msg)
943  {
944  pPlayer->PlayerTalkClass->ClearMenus();
945  pPlayer->PlayerTalkClass->SendGossipMenu(11031, GetGUID());
946  }
947  return false;
948  }
949  break;
950  default:
951  return false; // checked and error output at creature_template loading
952  }
953  return true;
954 }
955 
956 bool Creature::CanInteractWithBattleMaster(Player* player, bool msg) const
957 {
958  if (!isBattleMaster())
959  return false;
960 
961  uint32 bgTypeId = sObjectMgr.GetBattleMasterBG(GetEntry());
962  if (!msg)
963  return player->GetBGAccessByLevel(bgTypeId);
964 
965  if (!player->GetBGAccessByLevel(bgTypeId))
966  {
967  player->PlayerTalkClass->ClearMenus();
968  switch (bgTypeId)
969  {
970  case BATTLEGROUND_AV: player->PlayerTalkClass->SendGossipMenu(7616, GetGUID()); break;
971  case BATTLEGROUND_WS: player->PlayerTalkClass->SendGossipMenu(7599, GetGUID()); break;
972  case BATTLEGROUND_AB: player->PlayerTalkClass->SendGossipMenu(7642, GetGUID()); break;
973  case BATTLEGROUND_EY:
974  case BATTLEGROUND_NA:
975  case BATTLEGROUND_BE:
976  case BATTLEGROUND_AA:
977  case BATTLEGROUND_RL: player->PlayerTalkClass->SendGossipMenu(10024, GetGUID()); break;
978  default: break;
979  }
980  return false;
981  }
982  return true;
983 }
984 
986 {
987  return player->getLevel() >= 10
989  && player->getClass() == GetCreatureTemplate()->classNum;
990 }
991 
993 {
994  if (!m_lootRecipient)
995  return NULL;
997 }
998 
1000 {
1001  if (!m_lootRecipientGroup)
1002  return NULL;
1003  return sObjectMgr.GetGroupByLeader(m_lootRecipientGroup);
1004 }
1005 
1007 {
1008  // set the player whose group should receive the right
1009  // to loot the creature after it dies
1010  // should be set to NULL after the loot disappears
1011 
1012  if (!unit)
1013  {
1014  m_lootRecipient = 0;
1017  return;
1018  }
1019 
1021  if (!player) // normal creature, no player involved
1022  return;
1023 
1024  m_lootRecipient = player->GetGUID();
1025  if (Group* group = player->GetGroup())
1026  m_lootRecipientGroup = group->GetLeaderGUID();
1027 
1029 }
1030 
1031 // return true if this creature is tapped by the player or by a member of his group.
1032 bool Creature::isTappedBy(Player const* player) const
1033 {
1034  if (player->GetGUID() == m_lootRecipient)
1035  return true;
1036 
1037  Group const* playerGroup = player->GetGroup();
1038  if (!playerGroup || playerGroup != GetLootRecipientGroup()) // if we dont have a group we arent the recipient
1039  return false; // if creature doesnt have group bound it means it was solo killed by someone else
1040 
1041  return true;
1042 }
1043 
1045 {
1046  // this should only be used when the creature has already been loaded
1047  // preferably after adding to map, because mapid may not be valid otherwise
1048  CreatureData const* data = sObjectMgr.GetCreatureData(m_DBTableGuid);
1049  if (!data)
1050  {
1051  sLog.outError("Creature::SaveToDB failed, cannot get creature data!");
1052  return;
1053  }
1054 
1055  SaveToDB(GetMapId(), data->spawnMask);
1056 }
1057 
1058 void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
1059 {
1060  // update in loaded data
1061  if (!m_DBTableGuid)
1063 
1064  CreatureData& data = sObjectMgr.NewOrExistCreatureData(m_DBTableGuid);
1065 
1066  uint32 displayId = GetNativeDisplayId();
1067 
1068  // check if it's a custom model and if not, use 0 for displayId
1069  CreatureInfo const* cinfo = GetCreatureTemplate();
1070  if (cinfo)
1071  {
1072  if (displayId == cinfo->modelid1 || displayId == cinfo->modelid2 ||
1073  displayId == cinfo->modelid3 || displayId == cinfo->modelid4)
1074  displayId = 0;
1075  }
1076 
1077  // data->guid = guid must not be update at save
1078  data.id = GetEntry();
1079  data.mapid = mapid;
1080  data.displayid = displayId;
1082  data.posX = GetPositionX();
1083  data.posY = GetPositionY();
1084  data.posZ = GetPositionZ();
1085  data.orientation = GetOrientation();
1087  // prevent add data integrity problems
1089  data.currentwaypoint = 0;
1090  data.curhealth = GetHealth();
1091  data.curmana = GetPower(POWER_MANA);
1092  // prevent add data integrity problems
1095  data.spawnMask = spawnMask;
1096 
1097  // updated in DB
1099 
1100  WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
1101 
1102  std::ostringstream ss;
1103  ss << "INSERT INTO creature VALUES ("
1104  << m_DBTableGuid << ","
1105  << GetEntry() << ","
1106  << mapid << ","
1107  << (uint32)spawnMask << ","
1108  << displayId << ","
1109  << GetEquipmentId() << ","
1110  << GetPositionX() << ","
1111  << GetPositionY() << ","
1112  << GetPositionZ() << ","
1113  << GetOrientation() << ","
1114  << m_respawnDelay << "," //respawn time
1115  << (float) m_respawnradius << "," //spawn distance (float)
1116  << (uint32) (0) << "," //currentwaypoint
1117  << GetHealth() << "," //curhealth
1118  << GetPower(POWER_MANA) << "," //curmana
1119  << GetDefaultMovementType() << ")"; //default movement generator type
1120 
1121  WorldDatabase.PExecuteLog("%s", ss.str().c_str());
1122 
1124 }
1125 
1127 {
1128  CreatureInfo const* cInfo = GetCreatureTemplate();
1129 
1130  uint32 rank = IsPet() ? 0 : cInfo->rank;
1131 
1132  // level
1133  uint32 const minlevel = cInfo->minlevel;
1134  uint32 const maxlevel = cInfo->maxlevel;
1135  uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel);
1136  SetLevel(level);
1137 
1138  uint32 health;
1139  uint32 mana;
1140 
1141  if (CreatureBaseStats const* cCLS = sObjectMgr.GetCreatureClassLvlStats(level, cInfo->unit_class, cInfo->exp))
1142  {
1143  // Use Creature Stats to calculate stat values
1144 
1145  // health
1146  health = cCLS->BaseHealth * cInfo->ModHealth;
1147 
1148  // mana
1149  mana = cCLS->BaseMana * cInfo->ModMana;
1150  }
1151  else
1152  {
1153  // Use old style to calculate stat values
1154  float rellevel = maxlevel == minlevel ? 0 : (float(level - minlevel)) / (maxlevel - minlevel);
1155 
1156  uint32 minhealth = std::min(cInfo->maxhealth, cInfo->minhealth);
1157  uint32 maxhealth = std::max(cInfo->maxhealth, cInfo->minhealth);
1158  health = uint32(minhealth + uint32(rellevel * (maxhealth - minhealth)));
1159 
1160  // mana
1161  uint32 minmana = std::min(cInfo->maxmana, cInfo->minmana);
1162  uint32 maxmana = std::max(cInfo->maxmana, cInfo->minmana);
1163  mana = minmana + uint32(rellevel * (maxmana - minmana));
1164  }
1165 
1166  health *= _GetHealthMod(rank); // Apply custom config settting
1167  if (health < 1)
1168  health = 1;
1169 
1170  SetCreateHealth(health);
1171  SetMaxHealth(health);
1172  SetHealth(health);
1173  SetPlayerDamaged(false);
1174 
1175  SetCreateMana(mana);
1176  SetMaxPower(POWER_MANA, mana); //MAX Mana
1177  SetPower(POWER_MANA, mana);
1178 
1179  SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
1180  SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana);
1181 
1182  // damage
1183  float damagemod = _GetDamageMod(rank);
1184 
1185  SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cInfo->mindmg * damagemod);
1186  SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cInfo->maxdmg * damagemod);
1187  SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, cInfo->mindmg * damagemod);
1188  SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, cInfo->maxdmg * damagemod);
1191 
1192  // this value is not accurate, but should be close to the real value
1195  //SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod);
1196  //SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, cinfo->rangedattackpower * damagemod);
1197  UpdateAllStats();
1198 }
1199 
1201 {
1202  switch (Rank) // define rates for each elite rank
1203  {
1204  case CREATURE_ELITE_NORMAL:
1205  return sWorld.getRate(RATE_CREATURE_NORMAL_HP);
1206  case CREATURE_ELITE_ELITE:
1207  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP);
1209  return sWorld.getRate(RATE_CREATURE_ELITE_RAREELITE_HP);
1211  return sWorld.getRate(RATE_CREATURE_ELITE_WORLDBOSS_HP);
1212  case CREATURE_ELITE_RARE:
1213  return sWorld.getRate(RATE_CREATURE_ELITE_RARE_HP);
1214  default:
1215  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP);
1216  }
1217 }
1218 
1220 {
1221  hasPlayerDamaged = set;
1222 }
1223 
1225 {
1226  switch (Rank) // define rates for each elite rank
1227  {
1228  case CREATURE_ELITE_NORMAL:
1229  return sWorld.getRate(RATE_CREATURE_NORMAL_DAMAGE);
1230  case CREATURE_ELITE_ELITE:
1231  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
1236  case CREATURE_ELITE_RARE:
1237  return sWorld.getRate(RATE_CREATURE_ELITE_RARE_DAMAGE);
1238  default:
1239  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
1240  }
1241 }
1242 
1244 {
1245  switch (Rank) // define rates for each elite rank
1246  {
1247  case CREATURE_ELITE_NORMAL:
1248  return sWorld.getRate(RATE_CREATURE_NORMAL_SPELLDAMAGE);
1249  case CREATURE_ELITE_ELITE:
1255  case CREATURE_ELITE_RARE:
1257  default:
1259  }
1260 }
1261 
1262 bool Creature::CreateFromProto(uint32 guidlow, uint32 entry, uint32 team, const CreatureData* data)
1263 {
1264  SetZoneScript();
1265  if (m_zoneScript && data)
1266  {
1267  entry = m_zoneScript->GetCreatureEntry(guidlow, data);
1268  if (!entry)
1269  return false;
1270  }
1271 
1272  CreatureInfo const* cinfo = sObjectMgr.GetCreatureTemplate(entry);
1273  if (!cinfo)
1274  {
1275  sLog.outErrorDb("Creature::CreateFromProto(): creature template (guidlow: %u, entry: %u) does not exist.", guidlow, entry);
1276  return false;
1277  }
1278 
1279  SetOriginalEntry(entry);
1280 
1281  Object::_Create(guidlow, entry, HIGHGUID_UNIT);
1282 
1283  if (!UpdateEntry(entry, team, data))
1284  return false;
1285 
1286  return true;
1287 }
1288 
1289 bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
1290 {
1291  CreatureData const* data = sObjectMgr.GetCreatureData(guid);
1292 
1293  if (!data)
1294  {
1295  sLog.outErrorDb("Creature (GUID: %u) not found in table creature, can't load. ", guid);
1296  return false;
1297  }
1298 
1299  m_DBTableGuid = guid;
1300  if (map->GetInstanceId() != 0)
1301  guid = sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT);
1302 
1303  uint16 team = 0;
1304  if (!Create(guid, map, data->id, team, data->posX, data->posY, data->posZ, data->orientation, data))
1305  return false;
1306 
1307  //We should set first home position, because then AI calls home movement
1308  SetHomePosition(data->posX, data->posY, data->posZ, data->orientation);
1309 
1310  m_respawnradius = data->spawndist;
1311 
1312  m_respawnDelay = data->spawntimesecs;
1313  m_deathState = ALIVE;
1314 
1315  m_respawnTime = sObjectMgr.GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
1316  if (m_respawnTime) // respawn on Update
1317  {
1318  m_deathState = DEAD;
1319  if (canFly())
1320  {
1321  float tz = GetMap()->GetHeight(data->posX, data->posY, data->posZ, false);
1322  if (data->posZ - tz > 0.1)
1323  Relocate(data->posX, data->posY, tz);
1324  }
1325  }
1326 
1327  uint32 curhealth;
1328 
1329  if (!m_regenHealth)
1330  {
1331  curhealth = data->curhealth;
1332  if (curhealth)
1333  {
1334  curhealth = uint32(curhealth * _GetHealthMod(GetCreatureTemplate()->rank));
1335  if (curhealth < 1)
1336  curhealth = 1;
1337  }
1338  SetPower(POWER_MANA, data->curmana);
1339  }
1340  else
1341  {
1342  curhealth = GetMaxHealth();
1344  }
1345 
1346  SetHealth(m_deathState == ALIVE ? curhealth : 0);
1347 
1348  // checked at creature_template loading
1350 
1351  m_creatureData = data;
1352 
1353  if (addToMap && !GetMap()->AddToMap(this))
1354  return false;
1355  return true;
1356 }
1357 
1358 void Creature::LoadEquipment(uint32 equip_entry, bool force)
1359 {
1360  if (equip_entry == 0)
1361  {
1362  if (force)
1363  {
1364  for (uint8 i = 0; i < 3; ++i)
1365  {
1367  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0);
1368  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0);
1369  }
1370  m_equipmentId = 0;
1371  }
1372  return;
1373  }
1374 
1375  if (EquipmentInfo const* einfo = sObjectMgr.GetEquipmentInfo(equip_entry))
1376  {
1377  m_equipmentId = equip_entry;
1378  for (uint8 i = 0; i < MAX_VIRTUAL_ITEM_SLOT; ++i)
1379  SetVirtualItem(VirtualItemSlot(i), einfo->equipentry[i]);
1380  }
1381  else if (EquipmentInfoRaw const* einfo = sObjectMgr.GetEquipmentInfoRaw(equip_entry))
1382  {
1383  m_equipmentId = equip_entry;
1384  for (uint8 i = 0; i < MAX_VIRTUAL_ITEM_SLOT; ++i)
1385  SetVirtualItemRaw(VirtualItemSlot(i), einfo->equipmodel[i], einfo->equipinfo[i], einfo->equipslot[i]);
1386  }
1387 }
1388 
1390 {
1391  if (item_id == 0)
1392  {
1394  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, 0);
1395  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, 0);
1396  return;
1397  }
1398 
1399  ItemTemplate const* proto = ObjectMgr::GetItemTemplate(item_id);
1400  if (!proto)
1401  {
1402  sLog.outError("Not listed in 'item_template' item (ID:%u) used as virtual item for " UI64FMTD "", item_id, GetGUID());
1403  return;
1404  }
1405 
1413 }
1414 
1416 {
1417  SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + slot, display_id);
1418  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, info0);
1419  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, info1);
1420 }
1421 
1422 bool Creature::hasQuest(uint32 quest_id) const
1423 {
1424  QuestRelations qr = sObjectMgr.mCreatureQuestRelations;
1425  for (QuestRelations::const_iterator itr = qr.lower_bound(GetEntry()); itr != qr.upper_bound(GetEntry()); ++itr)
1426  {
1427  if (itr->second == quest_id)
1428  return true;
1429  }
1430  return false;
1431 }
1432 
1434 {
1435  QuestRelations qir = sObjectMgr.mCreatureQuestInvolvedRelations;
1436  for (QuestRelations::const_iterator itr = qir.lower_bound(GetEntry()); itr != qir.upper_bound(GetEntry()); ++itr)
1437  {
1438  if (itr->second == quest_id)
1439  return true;
1440  }
1441  return false;
1442 }
1443 
1445 {
1446  if (!m_DBTableGuid)
1447  {
1448  sLog.outDebug("Trying to delete not saved creature!");
1449  return;
1450  }
1451 
1452  sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), 0);
1453  sObjectMgr.DeleteCreatureData(m_DBTableGuid);
1454 
1456  WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
1457  WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
1458  WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
1459  WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
1461 }
1462 
1464 {
1466  return true;
1467 
1468  if (IsAlive() || isDying() || m_corpseRemoveTime > time(NULL))
1469  return false;
1470 
1471  return true;
1472 }
1473 
1474 bool Creature::CanAlwaysSee(WorldObject const* obj) const
1475 {
1476  if (IsAIEnabled && AI()->CanSeeAlways(obj))
1477  return true;
1478 
1479  return false;
1480 }
1481 
1482 bool Creature::canStartAttack(Unit const* who, bool force) const
1483 {
1484  if (isCivilian())
1485  return false;
1486 
1487  // This set of checks is should be done only for creatures
1488  if ((HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC) && who->GetTypeId() != TYPEID_PLAYER) // flag is valid only for non player characters
1489  || (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) && who->GetTypeId() == TYPEID_PLAYER) // immune to PC and target is a player, return false
1490  || (who->GetOwner() && who->GetOwner()->GetTypeId() == TYPEID_PLAYER && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))) // player pets are immune to pc as well
1491  return false;
1492 
1493  // Do not attack non-combat pets
1495  return false;
1496 
1498  return false;
1499 
1500  if (!force)
1501  {
1502  if (!_IsTargetAcceptable(who))
1503  return false;
1504 
1505  if (who->IsInCombat() && IsWithinDist(who, ATTACK_DISTANCE))
1506  if (Unit* victim = who->getAttackerForHelper())
1508  force = true;
1509 
1510  if (!force && (IsNeutralToAll() || !IsWithinDistInMap(who, GetAttackDistance(who) + m_CombatDistance)))
1511  return false;
1512  }
1513 
1514  if (!CanCreatureAttack(who, force))
1515  return false;
1516 
1517  return IsWithinLOSInMap(who);
1518 }
1519 
1520 float Creature::GetAttackDistance(Unit const* player) const
1521 {
1522  float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO);
1523  if (aggroRate == 0)
1524  return 0.0f;
1525 
1526  uint32 playerlevel = player->getLevelForTarget(this);
1527  uint32 creaturelevel = getLevelForTarget(player);
1528 
1529  int32 leveldif = int32(playerlevel) - int32(creaturelevel);
1530 
1531  // "The maximum Aggro Radius has a cap of 25 levels under. Example: A level 30 char has the same Aggro Radius of a level 5 char on a level 60 mob."
1532  if (leveldif < - 25)
1533  leveldif = -25;
1534 
1535  // "The aggro radius of a mob having the same level as the player is roughly 20 yards"
1536  float RetDistance = 20;
1537 
1538  // "Aggro Radius varies with level difference at a rate of roughly 1 yard/level"
1539  // radius grow if playlevel < creaturelevel
1540  RetDistance -= (float)leveldif;
1541 
1542  if (creaturelevel + 5 <= int32(sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)))
1543  {
1544  // detect range auras
1546 
1547  // detected range auras
1548  RetDistance += player->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE);
1549  }
1550 
1551  // "Minimum Aggro Radius for a mob seems to be combat range (5 yards)"
1552  if (RetDistance < 5)
1553  RetDistance = 5;
1554 
1555  return (RetDistance * aggroRate);
1556 }
1557 
1559 {
1561 
1562  if (s == JUST_DIED)
1563  {
1564  m_corpseRemoveTime = time(NULL) + m_corpseDelay;
1565  m_respawnTime = time(NULL) + m_respawnDelay + m_corpseDelay;
1566 
1567  // always save boss respawn time at death to prevent crash cheating
1569  SaveRespawnTime();
1570 
1571  SetTarget(0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState)
1573 
1574  SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); // if creature is mounted on a virtual mount, remove it at death
1575 
1576  setActive(false);
1577 
1578  if (HasSearchedAssistance())
1579  {
1580  SetNoSearchAssistance(false);
1581  UpdateSpeed(MOVE_RUN, false);
1582  }
1583 
1584  //Dismiss group if is leader
1585  if (m_formation && m_formation->getLeader() == this)
1586  m_formation->FormationReset(true);
1587 
1588  if ((canFly() || IsFlying()))
1590 
1591  SetHealth(0);
1592  SetPower(getPowerType(), 0);
1593 
1594  if (m_zoneScript)
1596 
1598  }
1599  else if (s == JUST_RESPAWNED)
1600  {
1601  SetFullHealth();
1602  SetLootRecipient(nullptr);
1603  SetPlayerDamaged(false);
1604 
1606 
1608 
1609  if (!IsPet())
1610  {
1611  CreatureInfo const* cinfo = GetCreatureTemplate();
1612 
1614 
1616 
1618  }
1619 
1621  LoadCreaturesAddon(true);
1622 
1624 
1625  // Prevents the creature from re-spawning at the location of it's death
1627  }
1628 }
1629 
1630 void Creature::Respawn(bool force)
1631 {
1633 
1634  if (force)
1635  {
1636  if (IsAlive())
1638  else if (getDeathState() != CORPSE)
1640  }
1641 
1642  RemoveCorpse(false);
1643 
1644  if (getDeathState() == DEAD)
1645  {
1646  if (m_DBTableGuid)
1647  sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), 0);
1648 
1649  DEBUG_LOG("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry());
1650  m_respawnTime = 0;
1652  loot.clear();
1653  if (m_originalEntry != GetEntry())
1655 
1656  SelectLevel();
1657 
1659 
1661 
1662  //Call AI respawn virtual function
1663  if (IsAIEnabled)
1664  {
1665  //reset the AI to be sure no dirty or uninitialized values will be used till next tick
1666  AI()->Reset();
1667  TriggerJustRespawned = true; //delay event to next tick so all creatures are created on the map before processing
1668  }
1669 
1670  uint32 poolid = sPoolMgr.IsPartOfAPool<Creature>(GetDBTableGUIDLow());
1671  if (poolid)
1672  sPoolMgr.UpdatePool<Creature>(poolid, GetDBTableGUIDLow());
1673 
1674  //Re-initialize reactstate that could be altered by movementgenerators
1676  }
1677 
1679 }
1680 
1681 void Creature::ForcedDespawn(uint32 timeMSToDespawn)
1682 {
1683  if (timeMSToDespawn)
1684  {
1685  ForcedDespawnDelayEvent* pEvent = new ForcedDespawnDelayEvent(*this);
1686 
1687  m_Events.AddEvent(pEvent, m_Events.CalculateTime(timeMSToDespawn));
1688  return;
1689  }
1690 
1691  if (IsAlive())
1693 
1694  RemoveCorpse(false);
1695 }
1696 
1697 void Creature::DespawnOrUnsummon(uint32 msTimeToDespawn /*= 0*/)
1698 {
1699  if (TempSummon* summon = this->ToTempSummon())
1700  summon->UnSummon(msTimeToDespawn);
1701  else
1702  ForcedDespawn(msTimeToDespawn);
1703 }
1704 
1705 bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo, bool useCharges)
1706 {
1707  if (!spellInfo)
1708  return false;
1709 
1710  if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))
1711  return true;
1712 
1713  return Unit::IsImmuneToSpell(spellInfo, useCharges);
1714 }
1715 
1716 bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool castOnSelf) const
1717 {
1718  if (!castOnSelf && GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
1719  return true;
1720 
1721  if (GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && spellInfo->Effect[index] == SPELL_EFFECT_HEAL)
1722  return true;
1723 
1724  return Unit::IsImmuneToSpellEffect(spellInfo, index, castOnSelf);
1725 }
1726 
1727 bool Creature::isElite() const
1728 {
1729  if (IsPet())
1730  return false;
1731 
1732  uint32 rank = GetCreatureTemplate()->rank;
1733  return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
1734 }
1735 
1737 {
1738  if (IsPet())
1739  return false;
1740 
1741  return (GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_BOSS_MOB) != 0;
1742 }
1743 
1745 {
1746  if (!victim)
1747  return NULL;
1748 
1749  for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
1750  {
1751  if (!m_spells[i])
1752  continue;
1753  SpellEntry const* spellInfo = sSpellStore.LookupEntry(m_spells[i]);
1754  if (!spellInfo)
1755  {
1756  sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
1757  continue;
1758  }
1759 
1760  bool bcontinue = true;
1761  for (uint32 j = 0; j < 3; j++)
1762  {
1763  if ((spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE) ||
1764  (spellInfo->Effect[j] == SPELL_EFFECT_INSTAKILL) ||
1765  (spellInfo->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) ||
1766  (spellInfo->Effect[j] == SPELL_EFFECT_HEALTH_LEECH)
1767  )
1768  {
1769  bcontinue = false;
1770  break;
1771  }
1772  }
1773  if (bcontinue)
1774  continue;
1775 
1776  if (spellInfo->manaCost > GetPower(POWER_MANA))
1777  continue;
1778 
1779  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
1780  float range = GetSpellMaxRange(srange);
1781  float minrange = GetSpellMinRange(srange);
1782  float dist = GetDistance(victim);
1783  if (dist > range || dist < minrange)
1784  continue;
1786  continue;
1788  continue;
1789  return spellInfo;
1790  }
1791  return NULL;
1792 }
1793 
1795 {
1796  if (!victim)
1797  return NULL;
1798 
1799  for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
1800  {
1801  if (!m_spells[i])
1802  continue;
1803  SpellEntry const* spellInfo = sSpellStore.LookupEntry(m_spells[i]);
1804  if (!spellInfo)
1805  {
1806  sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
1807  continue;
1808  }
1809 
1810  bool bcontinue = true;
1811  for (uint32 j = 0; j < 3; j++)
1812  {
1813  if ((spellInfo->Effect[j] == SPELL_EFFECT_HEAL))
1814  {
1815  bcontinue = false;
1816  break;
1817  }
1818  }
1819  if (bcontinue)
1820  continue;
1821 
1822  if (spellInfo->manaCost > GetPower(POWER_MANA))
1823  continue;
1824 
1825  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
1826  float range = GetSpellMaxRange(srange);
1827  float minrange = GetSpellMinRange(srange);
1828  float dist = GetDistance(victim);
1829  //if (!isInFront(victim, range) && spellInfo->AttributesEx)
1830  // continue;
1831  if (dist > range || dist < minrange)
1832  continue;
1834  continue;
1836  continue;
1837  return spellInfo;
1838  }
1839  return NULL;
1840 }
1841 
1842 // select nearest hostile unit within the given distance (regardless of threat list).
1843 Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const
1844 {
1846  Cell cell(p);
1847  cell.SetNoCreate();
1848 
1849  Unit* target = NULL;
1850 
1851  {
1852  Oregon::NearestHostileUnitCheck u_check(this, dist, playerOnly);
1854 
1857 
1858  cell.Visit(p, world_unit_searcher, *GetMap(), *this, dist);
1859  cell.Visit(p, grid_unit_searcher, *GetMap(), *this, dist);
1860  }
1861 
1862  return target;
1863 }
1864 
1865 // select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list.
1867 {
1869  Cell cell(p);
1870  cell.SetNoCreate();
1871 
1872  Unit *target = NULL;
1873 
1874  if (dist > MAX_VISIBILITY_DISTANCE)
1875  {
1876  sLog.outError("Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUIDLow(), GetEntry());
1877  dist = ATTACK_DISTANCE;
1878  }
1879 
1880  {
1883 
1886 
1887  cell.Visit(p, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
1888  cell.Visit(p, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
1889  }
1890 
1891  return target;
1892 }
1893 
1895 {
1896  WorldPacket data(SMSG_AI_REACTION, 12);
1897 
1898  data << uint64(GetGUID());
1899  data << uint32(reactionType);
1900 
1901  ((WorldObject*)this)->SendMessageToSet(&data, true);
1902 
1903  sLog.outDebug("WORLD: Sent SMSG_AI_REACTION, type %u.", reactionType);
1904 }
1905 
1907 {
1908  if (!m_AlreadyCallAssistance && GetVictim() && !IsPet() && !isCharmed())
1909  {
1910  SetNoCallAssistance(true);
1911 
1912  float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
1913 
1914  if (radius > 0)
1915  {
1916  std::list<Creature*> assistList;
1917 
1918  {
1920  Cell cell(p);
1921  cell.SetNoCreate();
1922 
1923  Oregon::AnyAssistCreatureInRangeCheck u_check(this, GetVictim(), radius);
1925 
1927 
1928  cell.Visit(p, grid_creature_searcher, *GetMap(), *this, radius);
1929  }
1930 
1931  if (!assistList.empty())
1932  {
1933  AssistDelayEvent* e = new AssistDelayEvent(GetVictim()->GetGUID(), *this);
1934  while (!assistList.empty())
1935  {
1936  // Pushing guids because in delay can happen some creature gets despawned => invalid pointer
1937  e->AddAssistant((*assistList.begin())->GetGUID());
1938  assistList.pop_front();
1939  }
1941  }
1942  }
1943  }
1944 }
1945 
1946 void Creature::CallForHelp(float radius)
1947 {
1948  if (radius <= 0.0f || !GetVictim() || IsPet() || isCharmed())
1949  return;
1950 
1952  Cell cell(p);
1953  cell.SetNoCreate();
1954 
1955  Oregon::CallOfHelpCreatureInRangeDo u_do(this, GetVictim(), radius);
1957 
1959 
1960  cell.Visit(p, grid_creature_searcher, *GetMap(), *this, radius);
1961 }
1962 
1963 bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const
1964 {
1965  if (IsInEvadeMode())
1966  return false;
1967 
1968  // is it true?
1970  return false;
1971 
1972  // we don't need help from zombies :)
1973  if (!IsAlive())
1974  return false;
1975 
1976  // we don't need help from non-combatant ;)
1977  if (isCivilian())
1978  return false;
1979 
1981  return false;
1982 
1983  // skip fighting creature
1984  if (IsInCombat())
1985  return false;
1986 
1987  // only free creature
1988  if (GetCharmerOrOwnerGUID())
1989  return false;
1990 
1991  // only from same creature faction
1992  if (checkfaction)
1993  {
1994  if (getFaction() != u->getFaction())
1995  return false;
1996  }
1997  else
1998  {
1999  if (!IsFriendlyTo(u))
2000  return false;
2001  }
2002 
2003  // skip non hostile to caster enemy creatures
2004  if (!IsHostileTo(enemy))
2005  return false;
2006 
2007  return true;
2008 }
2009 
2010 // use this function to avoid having hostile creatures attack
2011 // friendlies and other mobs they shouldn't attack
2012 bool Creature::_IsTargetAcceptable(Unit const* target) const
2013 {
2014  ASSERT(target);
2015 
2016  // if the target cannot be attacked, the target is not acceptable
2017  if (IsFriendlyTo(target)
2018  || !target->isTargetableForAttack(false))
2019  return false;
2020 
2021  if (target->HasUnitState(UNIT_STATE_DIED))
2022  {
2023  // guards can detect fake death
2025  return true;
2026  else
2027  return false;
2028  }
2029 
2030  Unit const* targetVictim = target->getAttackerForHelper();
2031 
2032  // if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
2033  if (GetVictim() == target || IsHostileTo(target))
2034  return true;
2035 
2036  // a player is targeting me, but I'm not hostile towards it, and not currently attacking it, the target is not acceptable
2037  // (players may set their victim from a distance, and doesn't mean we should attack)
2038  if (target->GetTypeId() == TYPEID_PLAYER && targetVictim == this)
2039  return false;
2040 
2041  // if the target's victim is friendly, and the target is neutral, the target is acceptable
2042  if (targetVictim && IsFriendlyTo(targetVictim))
2043  return true;
2044 
2045  // if the target's victim is not friendly, or the target is friendly, the target is not acceptable
2046  return false;
2047 }
2048 
2050 {
2052  return;
2053 
2054  sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
2055 }
2056 
2057 bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
2058 {
2059  if (!victim)
2060  return false;
2061 
2062  if (!victim->IsInMap(this))
2063  return false;
2064 
2065  if (!IsValidAttackTarget(victim))
2066  return false;
2067 
2068  if (!victim->isInAccessiblePlaceFor(this))
2069  return false;
2070 
2071  if (IsAIEnabled && !AI()->CanAIAttack(victim))
2072  return false;
2073 
2074  // we cannot attack in evade mode
2075  if (IsInEvadeMode())
2076  return false;
2077 
2078  // or if enemy is in evade mode
2079  if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
2080  return false;
2081 
2082  if (Unit* u = GetCharmerOrOwner())
2083  {
2084  if (u->GetTypeId() == TYPEID_PLAYER)
2085  {
2086  if (GetMap()->IsDungeon())
2087  return true;
2088 
2089  // don't check distance to home position if recently damaged, this should include taunt auras
2091  return true;
2092  }
2093  }
2094 
2095  // Get the correct threat range from the config.
2096  float dist = std::max<float>(GetAttackDistance(victim), sWorld.getConfig(CONFIG_THREAT_RADIUS) + m_CombatDistance);
2097 
2098  if (Unit* unit = GetCharmerOrOwner())
2099  return victim->IsWithinDist(unit, dist);
2100  else
2101  {
2102  // include sizes for huge npcs
2103  dist += GetObjectSize() + victim->GetObjectSize();
2104 
2105  // to prevent creatures in air ignore attacks because distance is already too high...
2106  if (GetCreatureTemplate()->InhabitType & INHABIT_AIR)
2107  return victim->IsInDist2d(&m_homePosition, dist);
2108  else
2109  return victim->IsInDist(&m_homePosition, dist);
2110  }
2111 }
2112 
2114 {
2115  if (m_DBTableGuid)
2116  {
2118  return addon;
2119  }
2120 
2121  // dependent from heroic mode entry
2123 }
2124 
2125 //creature_addon table
2127 {
2128  CreatureDataAddon const* cainfo = GetCreatureAddon();
2129  if (!cainfo)
2130  return false;
2131 
2132  if (cainfo->mount != 0)
2133  Mount(cainfo->mount);
2134 
2135  if (cainfo->bytes1 != 0)
2137 
2138  // Sheath State
2140 
2141  if (cainfo->emote != 0)
2143 
2144  //Load Path
2145  if (cainfo->path_id != 0)
2146  m_path_id = cainfo->path_id;
2147 
2148  if (cainfo->auras)
2149  {
2150  for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura)
2151  {
2152  SpellEntry const* AdditionalSpellInfo = sSpellStore.LookupEntry(cAura->spell_id);
2153  if (!AdditionalSpellInfo)
2154  {
2155  sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u) has wrong spell %u defined in auras field.", GetGUIDLow(), GetEntry(), cAura->spell_id);
2156  continue;
2157  }
2158 
2159  // skip already applied aura
2160  if (HasAura(cAura->spell_id, cAura->effect_idx))
2161  {
2162  if (!reload)
2163  sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u) has duplicate aura (spell %u effect %u) in auras field.", GetGUIDLow(), GetEntry(), cAura->spell_id, cAura->effect_idx);
2164 
2165  continue;
2166  }
2167 
2168  Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0);
2169  AddAura(AdditionalAura);
2170  sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u)", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[0], GetGUIDLow(), GetEntry());
2171  }
2172  }
2173  return true;
2174 }
2175 
2176 // Send a message to LocalDefense channel for players opposition team in the zone
2178 {
2179  uint32 enemy_team = attacker->GetTeam();
2180 
2182  data << (uint32)GetZoneId();
2183  sWorld.SendGlobalMessage(&data, NULL, (enemy_team == ALLIANCE ? HORDE : ALLIANCE));
2184 }
2185 
2187 {
2188  if (!CanHaveThreatList())
2189  {
2190  sLog.outError("Creature entry %u call SetInCombatWithZone but creature cannot have threat list.", GetEntry());
2191  return;
2192  }
2193 
2194  Map* pMap = GetMap();
2195 
2196  if (!pMap->IsDungeon())
2197  {
2198  sLog.outError("Creature entry %u call SetInCombatWithZone for map (id: %u) that isn't an instance.", GetEntry(), pMap->GetId());
2199  return;
2200  }
2201 
2202  Map::PlayerList const& PlList = pMap->GetPlayers();
2203 
2204  if (PlList.isEmpty())
2205  return;
2206 
2207  for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
2208  {
2209  if (Player* pPlayer = i->GetSource())
2210  {
2211  if (pPlayer->IsGameMaster())
2212  continue;
2213 
2214  if (pPlayer->IsAlive())
2215  {
2216  pPlayer->SetInCombatWith(this);
2217  AddThreat(pPlayer, 0.0f);
2218  }
2219  }
2220  }
2221 }
2222 
2223 void Creature::_AddCreatureSpellCooldown(uint32 spell_id, time_t end_time)
2224 {
2225  m_CreatureSpellCooldowns[spell_id] = end_time;
2226 }
2227 
2228 void Creature::_AddCreatureCategoryCooldown(uint32 category, time_t end_time)
2229 {
2230  m_CreatureCategoryCooldowns[category] = end_time;
2231 }
2232 
2234 {
2235  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
2236  if (!spellInfo)
2237  return;
2238 
2239  uint32 cooldown = GetSpellRecoveryTime(spellInfo);
2240  if (Player* modOwner = GetSpellModOwner())
2241  modOwner->ApplySpellMod(spellid, SPELLMOD_COOLDOWN, cooldown);
2242 
2243  if (cooldown)
2244  _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown / IN_MILLISECONDS);
2245 
2246  if (spellInfo->Category)
2247  _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL));
2248 
2249  m_GlobalCooldown = spellInfo->StartRecoveryTime;
2250 
2251  if (Unit* owner = GetCharmerOrOwner())
2252  if (owner->GetTypeId() == TYPEID_PLAYER)
2253  {
2254  WorldPacket data(SMSG_SPELL_COOLDOWN, (4 + 8));
2255  data << uint64(GetGUID());
2256  data << uint8(0x0); // flags (0x1, 0x2)
2257  data << uint32(spellid);
2258  data << uint32(cooldown); // in m.secs
2259 
2260  owner->ToPlayer()->GetSession()->SendPacket(&data);
2261  }
2262 }
2263 
2265 {
2266  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
2267  if (!spellInfo)
2268  return false;
2269 
2270  // check global cooldown if spell affected by it
2271  if (spellInfo->StartRecoveryCategory > 0 && m_GlobalCooldown > 0)
2272  return true;
2273 
2274  CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category);
2275  return (itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL));
2276 }
2277 
2279 {
2280  CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id);
2281  return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id);
2282 }
2283 
2285 {
2287 }
2288 
2289 bool Creature::HasSpell(uint32 spellID) const
2290 {
2291  uint8 i;
2292  for (i = 0; i < CREATURE_MAX_SPELLS; ++i)
2293  if (spellID == m_spells[i])
2294  break;
2295  return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells
2296 }
2297 
2299 {
2300  time_t now = time(NULL);
2301  if (m_respawnTime > now)
2302  return m_respawnTime;
2303  else
2304  return now;
2305 }
2306 
2307 void Creature::GetRespawnPosition(float& x, float& y, float& z, float* ori, float* dist) const
2308 {
2309  if (m_DBTableGuid)
2310  {
2311  if (CreatureData const* data = sObjectMgr.GetCreatureData(GetDBTableGUIDLow()))
2312  {
2313  x = data->posX;
2314  y = data->posY;
2315  z = data->posZ;
2316  if (ori)
2317  *ori = data->orientation;
2318  if (dist)
2319  *dist = data->spawndist;
2320 
2321  return;
2322  }
2323  }
2324 
2325  x = GetPositionX();
2326  y = GetPositionY();
2327  z = GetPositionZ();
2328  if (ori)
2329  *ori = GetOrientation();
2330  if (dist)
2331  *dist = 0;
2332 }
2333 
2335 {
2336  if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
2339 
2340  time_t now = time(NULL);
2341  // Do not reset corpse remove time if corpse is already removed
2342  if (m_corpseRemoveTime <= now)
2343  return;
2344 
2345  float decayRate = sWorld.getRate(RATE_CORPSE_DECAY_LOOTED);
2346 
2347  // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
2348  if (loot.loot_type == LOOT_SKINNING)
2349  m_corpseRemoveTime = now;
2350  else
2351  m_corpseRemoveTime = now + uint32(m_corpseDelay * decayRate);
2352 
2354 }
2355 
2357 {
2358  if (!isWorldBoss() || !target->ToUnit())
2359  return Unit::getLevelForTarget(target);
2360 
2361  uint16 level = target->ToUnit()->getLevel() + sWorld.getConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF);
2362  if (level < 1)
2363  return 1;
2364  if (level > 255)
2365  return 255;
2366  return uint8(level);
2367 }
2368 
2369 std::string Creature::GetAIName() const
2370 {
2371  return sObjectMgr.GetCreatureTemplate(GetEntry())->AIName;
2372 }
2373 
2375 {
2376  return sObjectMgr.GetScriptName(GetScriptId());
2377 }
2378 
2380 {
2382 }
2383 
2385 {
2386  return sObjectMgr.GetNpcVendorItemList(GetEntry());
2387 }
2388 
2390 {
2391  if (!vItem->maxcount)
2392  return vItem->maxcount;
2393 
2394  VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
2395  for (; itr != m_vendorItemCounts.end(); ++itr)
2396  if (itr->itemId == vItem->item)
2397  break;
2398 
2399  if (itr == m_vendorItemCounts.end())
2400  return vItem->maxcount;
2401 
2402  VendorItemCount* vCount = &*itr;
2403 
2404  time_t ptime = time(NULL);
2405 
2406  if (vCount->lastIncrementTime + vItem->incrtime <= uint32(ptime))
2407  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(vItem->item))
2408  {
2409  uint32 diff = uint32((ptime - vCount->lastIncrementTime) / vItem->incrtime);
2410  if ((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount)
2411  {
2412  m_vendorItemCounts.erase(itr);
2413  return vItem->maxcount;
2414  }
2415 
2416  vCount->count += diff * pProto->BuyCount;
2417  vCount->lastIncrementTime = ptime;
2418  }
2419 
2420  return vCount->count;
2421 }
2422 
2424 {
2425  if (!vItem->maxcount)
2426  return 0;
2427 
2428  VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
2429  for (; itr != m_vendorItemCounts.end(); ++itr)
2430  if (itr->itemId == vItem->item)
2431  break;
2432 
2433  if (itr == m_vendorItemCounts.end())
2434  {
2435  uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount - used_count : 0;
2436  m_vendorItemCounts.push_back(VendorItemCount(vItem->item, new_count));
2437  return new_count;
2438  }
2439 
2440  VendorItemCount* vCount = &*itr;
2441 
2442  time_t ptime = time(NULL);
2443 
2444  if (vCount->lastIncrementTime + vItem->incrtime <= uint32(ptime))
2445  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(vItem->item))
2446  {
2447  uint32 diff = uint32((ptime - vCount->lastIncrementTime) / vItem->incrtime);
2448  if ((vCount->count + diff * pProto->BuyCount) < vItem->maxcount)
2449  vCount->count += diff * pProto->BuyCount;
2450  else
2451  vCount->count = vItem->maxcount;
2452  }
2453 
2454  vCount->count = vCount->count > used_count ? vCount->count - used_count : 0;
2455  vCount->lastIncrementTime = ptime;
2456  return vCount->count;
2457 }
2458 
2460 {
2461  return sObjectMgr.GetNpcTrainerSpells(GetEntry());
2462 }
2463 
2464 // overwrite WorldObject function for proper name localization
2465 const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const
2466 {
2467  if (loc_idx >= 0)
2468  {
2469  CreatureLocale const* cl = sObjectMgr.GetCreatureLocale(GetEntry());
2470  if (cl)
2471  {
2472  if (cl->Name.size() > uint32(loc_idx) && !cl->Name[loc_idx].empty())
2473  return cl->Name[loc_idx].c_str();
2474  }
2475  }
2476 
2477  return GetName();
2478 }
2479 
2481 {
2482  if (!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master
2483  return NULL;
2484 
2485  if (uint32 targetGuid = sObjectMgr.GetLinkedRespawnGuid(m_DBTableGuid))
2486  return sObjectMgr.GetCreatureData(targetGuid);
2487 
2488  return NULL;
2489 }
2490 
2491 // returns master's remaining respawn time if any
2493 {
2494  if (!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master
2495  return 0;
2496 
2497  if (uint32 targetGuid = sObjectMgr.GetLinkedRespawnGuid(m_DBTableGuid))
2498  {
2499  Map* targetMap = NULL;
2500  if (const CreatureData* data = sObjectMgr.GetCreatureData(targetGuid))
2501  {
2502  if (data->mapid == GetMapId()) // look up on the same map
2503  targetMap = GetMap();
2504  else // it shouldn't be instanceable map here
2505  targetMap = MapManager::Instance().FindMap(data->mapid);
2506  }
2507  if (targetMap)
2508  return sObjectMgr.GetCreatureRespawnTime(targetGuid, targetMap->GetInstanceId());
2509  }
2510 
2511  return 0;
2512 }
2513 
2514 bool Creature::SetWalk(bool enable)
2515 {
2516  if (!Unit::SetWalk(enable))
2517  return false;
2518 
2520  data << GetPackGUID();
2521  SendMessageToSet(&data, false);
2522  return true;
2523 }
2524 
2525 bool Creature::SetSwim(bool enable)
2526 {
2527  if (!Unit::SetSwim(enable))
2528  return false;
2529 
2530  if (!movespline->Initialized())
2531  return true;
2532 
2534  data << GetPackGUID();
2535  SendMessageToSet(&data, true);
2536  return true;
2537 }
2538 
2539 bool Creature::SetCanFly(bool enable, bool /*packetOnly = false */)
2540 {
2541  if (!Unit::SetCanFly(enable))
2542  return false;
2543 
2544  if (!movespline->Initialized())
2545  return true;
2546 
2548  data << GetPackGUID();
2549  SendMessageToSet(&data, false);
2550  return true;
2551 }
2552 
2553 bool Creature::SetWaterWalking(bool enable, bool packetOnly /* = false */)
2554 {
2555  if (!packetOnly && !Unit::SetWaterWalking(enable))
2556  return false;
2557 
2558  if (!movespline->Initialized())
2559  return true;
2560 
2562  data << GetPackGUID();
2563  SendMessageToSet(&data, true);
2564  return true;
2565 }
2566 
2567 bool Creature::SetFeatherFall(bool enable, bool packetOnly /* = false */)
2568 {
2569  if (!packetOnly && !Unit::SetFeatherFall(enable))
2570  return false;
2571 
2572  if (!movespline->Initialized())
2573  return true;
2574 
2576  data << GetPackGUID();
2577  SendMessageToSet(&data, true);
2578  return true;
2579 }
2580 
2581 bool Creature::SetHover(bool enable, bool packetOnly /*= false*/)
2582 {
2583  if (!packetOnly && !Unit::SetHover(enable))
2584  return false;
2585 
2586  if (!movespline->Initialized())
2587  return true;
2588 
2590  data << GetPackGUID();
2591  SendMessageToSet(&data, false);
2592  return true;
2593 }
2594 
2595 bool Creature::SetLevitate(bool apply, bool packetOnly)
2596 {
2597  if (!packetOnly && !Unit::SetLevitate(apply))
2598  return false;
2599 
2600  if (!movespline->Initialized())
2601  return true;
2602 
2604  data << GetPackGUID();
2605  SendMessageToSet(&data, true);
2606  return true;
2607 }
2608 
2609 void Creature::UpdateMovementFlags(bool packetOnly)
2610 {
2612  return;
2613 
2614  // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
2615  float ground = GetMap()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ());
2616 
2617  if (ground < INVALID_HEIGHT)
2618  {
2619  sLog.outDebug("FallGround: creature %u at map %u (x: %f, y: %f, z: %f), not able to retrive a proper GetHeight (z: %f).",
2620  GetEntry(), GetMap()->GetId(), GetPositionX(), GetPositionX(), GetPositionZ(), ground);
2621  return;
2622  }
2623 
2624  bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZ(), ground - 0.05f)); // Can be underground too, prevent the falling
2625 
2626  if (GetCreatureTemplate()->InhabitType & INHABIT_AIR && isInAir && !IsFalling())
2627  SetLevitate(true, packetOnly);
2628  else
2629  SetLevitate(false);
2630 
2631  if (!isInAir)
2633 
2634  SetSwim(canSwim() && GetBaseMap()->IsSwimmable(GetPositionX(), GetPositionY(), GetPositionZ()));
2635 }
2636 
2638 {
2640 }
2641 
2643 {
2644  CreatureTextRepeatIds& repeats = m_textRepeat[textGroup];
2645  if (std::find(repeats.begin(), repeats.end(), id) == repeats.end())
2646  repeats.push_back(id);
2647  else
2648  sLog.outError("CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), GetName(), GetGUIDLow(), GetEntry(), uint32(id));
2649 }
2650 
2652 {
2654 
2655  CreatureTextRepeatGroup::const_iterator groupItr = m_textRepeat.find(textGroup);
2656  if (groupItr != m_textRepeat.end())
2657  ids = groupItr->second;
2658 
2659  return ids;
2660 }
2661 
2663 {
2664  CreatureTextRepeatGroup::iterator groupItr = m_textRepeat.find(textGroup);
2665  if (groupItr != m_textRepeat.end())
2666  groupItr->second.clear();
2667 }
2668 
2669 
2670 float Creature::GetAggroRange(Unit const* target) const
2671 {
2672  // Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
2673  // Based on data from wowwiki due to lack of 3.3.5a data
2674 
2675  if (target && this->IsPet())
2676  {
2677  uint32 targetLevel = 0;
2678 
2679  if (target->GetTypeId() == TYPEID_PLAYER)
2680  targetLevel = target->getLevelForTarget(this);
2681  else if (target->GetTypeId() == TYPEID_UNIT)
2682  targetLevel = target->ToCreature()->getLevelForTarget(this);
2683 
2684  uint32 myLevel = getLevelForTarget(target);
2685  int32 levelDiff = int32(targetLevel) - int32(myLevel);
2686 
2687  // The maximum Aggro Radius is capped at 45 yards (25 level difference)
2688  if (levelDiff < -25)
2689  levelDiff = -25;
2690 
2691  // The base aggro radius for mob of same level
2692  float aggroRadius = 20;
2693 
2694  // Aggro Radius varies with level difference at a rate of roughly 1 yard/level
2695  aggroRadius -= (float)levelDiff;
2696 
2697  // detect range auras
2699 
2700  // detected range auras
2701  aggroRadius += target->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE);
2702 
2703  // Just in case, we don't want pets running all over the map
2704  if (aggroRadius > MAX_AGGRO_RADIUS)
2705  aggroRadius = MAX_AGGRO_RADIUS;
2706 
2707  // Minimum Aggro Radius for a mob seems to be combat range (5 yards)
2708  // hunter pets seem to ignore minimum aggro radius so we'll default it a little higher
2709  if (aggroRadius < 10)
2710  aggroRadius = 10;
2711 
2712  return (aggroRadius);
2713  }
2714 
2715  // Default
2716  return 0.0f;
2717 }
2718 
2720 {
2721  // Selects nearest hostile target within creature's aggro range. Used primarily by
2722  // pets set to aggressive. Will not return neutral or friendly targets.
2723 
2724  Unit* target = NULL;
2725 
2726  {
2727  Oregon::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS);
2729 
2731  }
2732 
2733  return target;
2734 }
uint32 GetCurrentEquipmentId()
Definition: Creature.h:586
void RemoveFromWorld() override
Definition: Unit.cpp:11056
bool IsImmuneToSpellEffect(SpellEntry const *spellInfo, uint32 index, bool castOnSelf) const override
Definition: Creature.cpp:1716
uint32 m_corpseDelay
Definition: Creature.h:902
uint32 Category
Definition: DBCStructure.h:675
int32 ModifyPower(Powers power, int32 val)
Definition: Unit.cpp:9725
uint32 UpdateVendorItemCurrentCount(VendorItem const *vItem, uint32 used_count)
Definition: Creature.cpp:2423
uint32 maxlevel
Definition: Creature.h:143
void SetTextRepeatId(uint8 textGroup, uint8 id)
Definition: Creature.cpp:2642
time_t GetLastDamagedTime() const
Definition: Unit.h:2106
bool SetWalk(bool enable) override
Definition: Creature.cpp:2514
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition: Map.cpp:734
uint32 baseattacktime
Definition: Creature.h:160
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
Definition: Creature.cpp:1697
#define ATTACK_DISTANCE
Definition: Object.h:36
float GetSpellDamageMod(int32 Rank) const
Definition: Creature.cpp:1243
Group * GetGroup()
Definition: Player.h:2589
int32 resistance3
Definition: Creature.h:180
EventProcessor m_Events
Definition: Unit.h:1746
void SetRespawnTime(uint32 respawn)
Definition: Creature.h:732
uint32 npcflag
Definition: Creature.h:151
bool LoadCreatureFromDB(uint32 guid, Map *map, bool addToMap=true)
Definition: Creature.cpp:1289
virtual bool IsImmuneToSpell(SpellEntry const *spellInfo, bool useCharges=false)
Definition: Unit.cpp:8868
virtual void OnCreatureDeath(Creature *)
Definition: ZoneScript.h:46
const CreatureData * GetLinkedRespawnCreatureData() const
Definition: Creature.cpp:2480
uint32 EffectMechanic[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:730
Definition: Unit.h:416
uint32 InventoryType
const uint32 & GetUInt32Value(uint16 index) const
Definition: Object.h:228
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:3727
bool IsFlying() const
Definition: Unit.h:2084
uint32 minmana
Definition: Creature.h:147
CreatureData const * m_creatureData
Definition: Creature.h:929
virtual bool SetCanFly(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13604
float ModMana
Definition: Creature.h:192
void Mount(uint32 mount, uint32 spellId=0)
Definition: Unit.cpp:9194
uint8 getLevelForTarget(WorldObject const *) const override
Definition: Unit.h:1034
Position m_homePosition
Definition: Creature.h:925
void SetTarget(uint64 guid=0)
Definition: Unit.h:1700
float maxdmg
Definition: Creature.h:157
uint32 GetMaxHealth() const
Definition: Unit.h:1052
void AddToWorld() override
Definition: Creature.cpp:181
uint32 maxcount
Definition: Creature.h:352
bool SetCanFly(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2539
uint32 rank
Definition: Creature.h:155
PlayerMenu * PlayerTalkClass
Definition: Player.h:2194
void UpdateMovementFlags(bool packetOnly=false)
Definition: Creature.cpp:2609
Unit * SelectNearestTargetInAttackDistance(float dist=0) const
Definition: Creature.cpp:1866
Map * GetMap() const
Definition: Object.h:829
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
bool m_isTempWorldObject
Definition: Creature.h:878
uint8 spawnMask
Definition: Creature.h:285
uint8 movementType
Definition: Creature.h:284
uint32 spells[CREATURE_MAX_SPELLS]
Definition: Creature.h:184
int32 resistance6
Definition: Creature.h:183
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData *data=NULL)
Definition: Creature.cpp:260
void SetNoCallAssistance(bool val)
Definition: Creature.h:697
bool IsTrainerOf(Player *player, bool msg) const
Definition: Creature.cpp:825
void ClearMenus()
Definition: GossipDef.cpp:116
uint32 GetDBTableGUIDLow() const
Definition: Creature.h:476
uint32 id
Definition: Creature.h:271
bool BeginTransaction()
Definition: Database.cpp:533
char * Name
Definition: Creature.h:138
uint32 getFaction() const
Definition: Unit.h:1111
void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value)
Definition: Unit.h:1750
uint32 displayid
Definition: Creature.h:273
pet will not attack
Definition: Unit.h:736
bool RemoveItem(uint32 item_id)
Definition: Creature.cpp:64
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:3615
void SetAttackTime(WeaponAttackType att, uint32 val)
Definition: Unit.h:1094
void AddThreat(Unit *victim, float threat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell=NULL)
Definition: Unit.cpp:10129
uint32 modelid4
Definition: Creature.h:137
void SendZoneUnderAttackMessage(Player *attacker)
Definition: Creature.cpp:2177
SpellSchools
bool CanTrainAndResetTalentsOf(Player *pPlayer) const
Definition: Creature.cpp:985
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
const char * GetNameForLocaleIdx(int32 locale_idx) const override
Definition: Creature.cpp:2465
time_t m_respawnTime
Definition: Creature.h:900
void InitializeReactState()
Definition: Creature.cpp:817
void SetObjectScale(float scale)
Definition: Object.h:199
AiReaction
bool IsUnderLastManaUseEffect() const
Definition: Unit.cpp:12220
#define CREATURE_Z_ATTACK_RANGE
Definition: Creature.h:451
Unit * SelectNearestTarget(float dist=0, bool playerOnly=false) const
Definition: Creature.cpp:1843
Movement::MoveSpline * movespline
Definition: Unit.h:2018
void setActive(bool isActiveObject)
Definition: Object.cpp:1122
void UpdateSpeed(UnitMoveType mtype, bool forced)
Definition: Unit.cpp:9806
uint32 curhealth
Definition: Creature.h:282
bool IsPvP() const
Definition: Unit.h:1140
bool HasSpellCooldown(uint32 spell_id) const
Definition: Creature.cpp:2278
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition: Object.h:821
uint64 lootingGroupLeaderGUID
Definition: Object.h:913
MotionMaster * GetMotionMaster()
Definition: Unit.h:2001
uint32 GetZoneId() const
Definition: Object.cpp:1176
uint32 race
Definition: Creature.h:169
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
bool IsInCombat() const
Definition: Unit.h:1318
bool m_AlreadyCallAssistance
Definition: Creature.h:917
std::vector< uint8 > CreatureTextRepeatIds
Definition: Creature.h:456
TrainerSpellData const * GetTrainerSpells() const
Definition: Creature.cpp:2459
virtual void SetMap(Map *map)
Definition: Object.cpp:1951
Loot loot
Definition: Creature.h:662
uint32 curmana
Definition: Creature.h:283
uint32 getMSTime()
Definition: Timer.h:32
bool IsValidAttackTarget(Unit const *target) const
Definition: Unit.cpp:9433
bool SetSwim(bool enable) override
Definition: Creature.cpp:2525
void SetCreateHealth(uint32 val)
Definition: Unit.h:1655
Definition: Unit.h:413
bool hasPlayerDamaged
Definition: Creature.h:859
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:1590
void SetValue(FLAG_TYPE flag, T_VALUES value)
Definition: Object.h:620
void AddObject(T *object)
float speed_walk
Definition: Creature.h:152
#define sLog
Log class singleton.
Definition: Log.h:187
uint32 trainer_type
Definition: Creature.h:166
virtual void SaveToDB()
Definition: Creature.cpp:1044
void SetCanModifyStats(bool modifyStats)
Definition: Unit.h:1764
MovementGeneratorType GetDefaultMovementType() const
Definition: Creature.h:703
virtual void JustRespawned()
Definition: CreatureAI.h:139
void AddToWorld() override
Definition: Unit.cpp:11050
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:779
ACE_INT32 int32
Definition: Define.h:67
bool IsWithinLOSInMap(const WorldObject *obj) const
Definition: Object.cpp:1226
uint32 armor
Definition: Creature.h:149
TrainerSpellList spellList
Definition: Creature.h:418
uint32 GetNativeDisplayId()
Definition: Unit.h:1896
void UpdateObjectVisibility(bool forced=true) override
Definition: Unit.cpp:13418
std::list< Aura * > AuraList
Definition: Unit.h:893
bool HasReactState(ReactStates state) const
Definition: Creature.h:527
bool IsInEvadeMode() const
Definition: Creature.cpp:2284
bool isSpiritGuide() const
Definition: Unit.h:1272
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:794
NULL Dbg ErrDB Arena Chat Char Map MMap false
Definition: Log.cpp:556
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:9657
static CreatureDataAddon const * GetCreatureAddon(uint32 lowguid)
Definition: ObjectMgr.h:623
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition: Unit.cpp:9133
SpellEntry const * reachWithSpellAttack(Unit *pVictim)
Definition: Creature.cpp:1744
void UpdateCharmAI()
Definition: Unit.cpp:11115
float spawndist
Definition: Creature.h:280
bool IsDungeon() const
Definition: Map.h:427
bool HasSearchedAssistance() const
Definition: Creature.h:699
VirtualItemSlot
Definition: Creature.h:426
Creature * getLeader() const
void SetNativeDisplayId(uint32 modelId)
Definition: Unit.h:1900
bool IsInvisibleDueToDespawn() const override
Definition: Creature.cpp:1463
bool SetHover(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2581
void SetNoCreate()
Definition: Cell.h:76
void AddAssistant(const uint64 &guid)
Definition: Creature.h:954
void MoveFall(float z=0, uint32 id=0)
bool Initialized() const
Definition: MoveSpline.h:94
virtual bool CanAIAttack(const Unit *) const
Definition: UnitAI.h:48
float mindmg
Definition: Creature.h:156
uint32 GetGUIDLow() const
Definition: Object.h:160
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
MovementGeneratorType m_defaultMovementType
Definition: Creature.h:912
void SetEntry(uint32 entry)
Definition: Object.h:190
uint32 dynamicflags
Definition: Creature.h:164
uint64 CalculateTime(uint64 t_offset)
Definition: Unit.h:415
bool UpdateAllStats() override
Definition: StatSystem.cpp:765
uint64 LastCharmerGUID
Definition: Unit.h:2102
void AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:13382
Aura * CreateAura(SpellEntry const *spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item *castItem)
Definition: SpellAuras.cpp:502
uint32 GetCreatureType() const
Definition: Unit.cpp:10607
bool dbData
Definition: Creature.h:286
uint32 minlevel
Definition: Creature.h:142
void AllLootRemovedFromCorpse()
Definition: Creature.cpp:2334
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:985
size_t FindItemSlot(uint32 item_id) const
Definition: Creature.cpp:80
uint32 modelid1
Definition: Creature.h:134
void clear()
Definition: LootMgr.h:327
bool AIM_Initialize(CreatureAI *ai=NULL)
Definition: Creature.cpp:741
void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time)
Definition: Creature.cpp:2223
static ItemTemplate const * GetItemTemplate(uint32 id)
Definition: ObjectMgr.h:633
iterator begin()
Definition: MapRefManager.h:48
void apply(T *val)
Definition: ByteConverter.h:41
bool IsAIEnabled
Definition: Unit.h:2101
void SendGossipMenu(uint32 TitleTextId, uint64 npcGUID)
Definition: GossipDef.cpp:137
#define sObjectMgr
Definition: ObjectMgr.h:1285
CreatureTextRepeatGroup m_textRepeat
Definition: Creature.h:945
bool CommitTransaction()
Definition: Database.cpp:551
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition: Object.h:777
time_t _pickpocketLootRestore
Timers.
Definition: Creature.h:898
bool CanAssistTo(const Unit *u, const Unit *enemy, bool checkfaction=true) const
Definition: Creature.cpp:1963
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
bool canStartAttack(Unit const *u, bool force) const
Definition: Creature.cpp:1482
virtual void DeleteFromDB()
Definition: Creature.cpp:1444
time_t GetLinkedCreatureRespawnTime() const
Definition: Creature.cpp:2492
void ForcedDespawn(uint32 timeMSToDespawn=0)
Definition: Creature.cpp:1681
bool PExecuteLog(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:221
uint32 rangeIndex
Definition: DBCStructure.h:714
void VisitNearbyGridObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:910
uint32 m_combatPulseDelay
Definition: Creature.h:905
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition: Object.h:762
Definition: Common.h:181
uint32 GetPower(Powers power) const
Definition: Unit.h:1076
virtual bool SetSwim(bool enable)
Definition: Unit.cpp:13591
float posX
Definition: Creature.h:275
UnitAI * i_AI
Definition: Unit.h:2115
void SetLootRecipient(Unit *unit)
Definition: Creature.cpp:1006
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3813
uint32 flags_extra
Definition: Creature.h:197
virtual void OnCreatureCreate(Creature *, bool)
Definition: ZoneScript.h:44
void InitDefault()
uint64 GetCharmerOrOwnerGUID() const
Definition: Unit.h:1496
virtual bool IsInvisibleDueToDespawn() const
Definition: Object.h:806
TempSummon * ToTempSummon()
Definition: Unit.h:2109
void CallAssistance()
Definition: Creature.cpp:1906
bool CanAlwaysSee(WorldObject const *obj) const override
Definition: Creature.cpp:1474
Definition: Common.h:179
void setFaction(uint32 faction)
Definition: Unit.h:1115
float m_respawnradius
Definition: Creature.h:903
uint32 GetId(void) const
Definition: Map.h:333
virtual void InitializeAI()
Definition: UnitAI.h:55
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition: Object.h:758
void ClearUnitState(uint32 f)
Definition: Unit.h:1006
Powers getPowerType() const
Definition: Unit.h:1071
bool canFly() const
Definition: Creature.h:520
void DoFleeToGetAssistance()
Definition: Creature.cpp:707
bool _IsTargetAcceptable(const Unit *target) const
Definition: Creature.cpp:2012
uint8 GetTypeId() const
Definition: Object.h:204
time_t GetRespawnTimeEx() const
Definition: Creature.cpp:2298
bool isBattleMaster() const
Definition: Unit.h:1256
uint32 spawntimesecs
Definition: Creature.h:279
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
Definition: Object.cpp:125
virtual bool SetHover(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13646
uint32 m_lootRecipientGroup
Definition: Creature.h:894
uint32 unit_class
Definition: Creature.h:162
void SetMeleeDamageSchool(SpellSchools school)
Definition: Creature.h:562
uint32 m_corpseRemoveTime
Definition: Creature.h:899
uint32 m_spells[CREATURE_MAX_SPELLS]
Definition: Creature.h:679
bool SetLevitate(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2595
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1080
float GetOrientation() const
Definition: Position.h:100
void setDeathState(DeathState s) override
Definition: Creature.cpp:1558
#define UI64FMTD
Definition: Common.h:149
int32 resistance4
Definition: Creature.h:181
static CreatureDataAddon const * GetCreatureTemplateAddon(uint32 entry)
Definition: ObjectMgr.h:628
void Relocate(float x, float y)
Definition: Position.h:65
bool isTrainer() const
Definition: Unit.h:1236
float minrangedmg
Definition: Creature.h:170
uint32 DisplayInfoID
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:12792
CreatureGroup * m_formation
Definition: Creature.h:939
const bool & IsInWorld() const
Definition: Object.h:129
#define CREATURE_REGEN_INTERVAL
Definition: Creature.h:125
std::multimap< uint32, uint32 > QuestRelations
Definition: ObjectMgr.h:390
float GetAggroRange(Unit const *target) const
Definition: Creature.cpp:2670
#define sPoolMgr
Definition: PoolMgr.h:162
static float _GetHealthMod(int32 Rank)
Definition: Creature.cpp:1200
uint32 m_DBTableGuid
Definition: Creature.h:914
ZoneScript * m_zoneScript
Definition: Object.h:922
uint32 faction
Definition: Creature.h:150
bool isCivilian() const
Definition: Creature.h:503
void SetDisplayId(uint32 modelId)
Definition: Unit.cpp:11896
bool IsNeutralToAll() const
Definition: Unit.cpp:7302
TrainerSpell const * Find(uint32 spell_id) const
Definition: Creature.cpp:55
static CreatureInfo const * GetCreatureTemplate(uint32 id)
Definition: ObjectMgr.cpp:439
float speed_run
Definition: Creature.h:153
void MoveSeekAssistance(float x, float y, float z)
uint32 equipmentId
Definition: Creature.h:195
bool IsAlive() const
Definition: Unit.h:1433
Unit * GetVictim() const
Definition: Unit.h:985
float posY
Definition: Creature.h:276
void SetCreateMana(uint32 val)
Definition: Unit.h:1663
float GetDistance(const WorldObject *obj) const
Definition: Object.h:706
virtual void UpdateAI(const uint32)=0
bool IsFalling() const
Definition: Unit.cpp:13560
virtual bool SetWaterWalking(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13620
float GetPositionY() const
Definition: Position.h:98
void Update(uint32 time) override
Definition: Unit.cpp:522
uint32 maxhealth
Definition: Creature.h:146
bool Execute(uint64 e_time, uint32 p_time) override
Definition: Creature.cpp:139
int32 resistance5
Definition: Creature.h:182
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:878
DeathState m_deathState
Definition: Unit.h:2133
CreatureAI * selectAI(Creature *creature)
CreatureAI * AI() const
Definition: Creature.h:548
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition: Object.h:822
static Player * FindPlayer(uint64, bool force=false)
bool CanInteractWithBattleMaster(Player *player, bool msg) const
Definition: Creature.cpp:956
VendorItemData const * GetVendorItems() const
Definition: Creature.cpp:2384
uint32 GetInstanceId() const
Definition: Object.h:682
uint32 m_GlobalCooldown
Definition: Creature.h:682
float GetPositionZ() const
Definition: Position.h:99
CreatureInfo const * m_creatureInfo
Definition: Creature.h:943
bool m_regenHealth
Definition: Creature.h:919
uint32 GetFirstValidModelId() const
Definition: Creature.cpp:109
bool HasCategoryCooldown(uint32 spell_id) const
Definition: Creature.cpp:2264
bool HasSpell(uint32 spellID) const override
Definition: Creature.cpp:2289
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:7284
void SetOriginalEntry(uint32 entry)
Definition: Creature.h:862
void CallForHelp(float fRadius)
Definition: Creature.cpp:1946
PackedGuid const & GetPackGUID() const
Definition: Object.h:172
virtual void CorpseRemoved(time_t)
Definition: CreatureAI.h:198
#define DEBUG_LOG(...)
Definition: Log.h:194
virtual bool SetFeatherFall(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13633
bool m_AI_locked
Definition: Creature.h:920
SpellEntry const * reachWithSpellCure(Unit *pVictim)
Definition: Creature.cpp:1794
uint32 maxmana
Definition: Creature.h:148
uint32 m_combatPulseTime
Definition: Creature.h:904
float GetSpellMinRange(SpellRangeEntry const *range)
Definition: SpellMgr.h:139
void SetVirtualItemRaw(VirtualItemSlot slot, uint32 display_id, uint32 info0, uint32 info1)
Definition: Creature.cpp:1415
float GetAttackDistance(Unit const *pl) const
Definition: Creature.cpp:1520
uint32 GetMapId() const
Definition: Object.h:585
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:10859
bool isRegeneratingHealth()
Definition: Creature.h:776
bool Execute(uint64 e_time, uint32 p_time) override
Definition: Creature.cpp:118
VendorItemCounts m_vendorItemCounts
Definition: Creature.h:885
bool isEmpty() const
Definition: LinkedList.h:97
bool IsInMap(const WorldObject *obj) const
Definition: Object.h:733
uint32 m_originalEntry
Definition: Creature.h:923
bool NeedChangeAI
Definition: Unit.h:2101
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data=NULL)
Definition: Creature.cpp:1262
float combat_reach
Definition: Creature.h:313
virtual void SetSheath(SheathState sheathed)
Definition: Unit.h:1105
Definition: Map.h:266
Map * FindMap(uint32 mapid, uint32 instanceId=0) const
Definition: MapManager.cpp:137
virtual bool SetLevitate(bool apply, bool packetOnly=false)
Definition: Unit.cpp:13578
float ModHealth
Definition: Creature.h:191
uint32 m_path_id
Definition: Creature.h:936
bool isInAccessiblePlaceFor(Creature const *c) const
Definition: Unit.cpp:3592
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:680
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:184
void RemoveUnitMovementFlag(uint32 f)
Definition: Unit.h:2013
uint32 PreventionType
Definition: DBCStructure.h:764
Group * GetLootRecipientGroup() const
Definition: Creature.cpp:999
uint32 modelid3
Definition: Creature.h:136
virtual uint32 GetCreatureEntry(uint32, const CreatureData *data)
Definition: ZoneScript.h:35
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:167
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value)
Definition: Unit.h:1779
uint32 unit_flags
Definition: Creature.h:163
bool TriggerJustRespawned
Definition: Creature.h:941
bool hasInvolvedQuest(uint32 quest_id) const override
Definition: Creature.cpp:1433
int32 equipmentId
Definition: Creature.h:274
virtual bool canSwim() const
Definition: Creature.h:516
bool IsPet() const
Definition: Unit.h:1020
#define MAX_VISIBILITY_DISTANCE
Definition: Object.h:38
bool IsInDist2d(float x, float y, float dist) const
Definition: Position.h:178
const char * GetName() const
Definition: Object.h:692
void SetPlayerDamaged(bool set)
Definition: Creature.cpp:1219
bool RegenHealth
Definition: Creature.h:194
void RemoveObject(T *object)
bool isDying() const
Definition: Unit.h:1437
void RegenerateMana()
Definition: Creature.cpp:635
DeathState
Definition: Unit.h:411
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:1006
ACE_UINT64 uint64
Definition: Define.h:70
PlayerList const & GetPlayers() const
Definition: Map.h:491
Definition: Cell.h:46
uint32 modelid2
Definition: Creature.h:135
uint32 CategoryRecoveryTime
Definition: DBCStructure.h:698
Player * GetLootRecipient() const
Definition: Creature.cpp:992
void Respawn(bool force=false)
Definition: Creature.cpp:1630
uint32 MovementType
Definition: Creature.h:189
void SendAIReaction(AiReaction reactionType)
Definition: Creature.cpp:1894
uint8 getRace() const
Definition: Unit.h:1037
void RegenerateHealth()
Definition: Creature.cpp:670
Definition: Unit.h:461
bool IsGuard() const
Definition: Creature.h:511
#define sGameEventMgr
Definition: GameEventMgr.h:179
float maxrangedmg
Definition: Creature.h:171
uint32 m_respawnDelay
Definition: Creature.h:901
CreatureInfo const * GetCreatureTemplate() const
Definition: Creature.h:598
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1519
uint32 GetRandomValidModelId() const
Definition: Creature.cpp:96
MotionMaster i_motionMaster
Definition: Unit.h:2166
CreatureDataAddonAura const * auras
Definition: Creature.h:306
int32 exp
Definition: Creature.h:144
void SelectLevel()
Definition: Creature.cpp:1126
virtual void setDeathState(DeathState s)
Definition: Unit.cpp:10035
uint64 m_lootRecipient
Definition: Creature.h:893
Map const * GetBaseMap() const
Definition: Object.cpp:1981
bool isSpiritService() const
Definition: Unit.h:1296
void RemoveFromWorld() override
Definition: Creature.cpp:196
VendorItem const * FindItem(uint32 item_id) const
Definition: Creature.cpp:88
void SetVirtualItem(VirtualItemSlot slot, uint32 item_id)
Definition: Creature.cpp:1389
bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData *data=NULL)
Definition: Creature.cpp:353
Player * GetSpellModOwner() const
Definition: Unit.cpp:11748
void SaveRespawnTime() override
Definition: Creature.cpp:2049
void EndRoll()
Definition: Group.cpp:761
#define CREATURE_MAX_SPELLS
Definition: Unit.h:249
bool IsTotem() const
Definition: Unit.h:1022
bool IsCritter() const
Definition: Unit.h:1300
LootType loot_type
Definition: LootMgr.h:312
bool CreatureRespawnRelocation(Creature *c)
Definition: Map.cpp:873
int32 resistance1
Definition: Creature.h:178
bool CanCreatureAttack(Unit const *victim, bool force=true) const
Definition: Creature.cpp:2057
void SetNoSearchAssistance(bool val)
Definition: Creature.h:698
Unit * GetOwner() const
Definition: Unit.cpp:7549
Creature * ToCreature()
Definition: Object.h:389
uint32 GetEquipmentId() const
Definition: Creature.h:488
void SetZoneScript()
Definition: Object.cpp:2099
float m_SightDistance
Definition: Creature.h:864
void ResetPickPocketRefillTimer()
Definition: Creature.h:664
uint32 currentwaypoint
Definition: Creature.h:281
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:9277
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition: Unit.cpp:10602
void SetFloatValue(uint16 index, float value)
Definition: Object.cpp:859
bool IsPolymorphed() const
Definition: Unit.cpp:11887
bool isElite() const
Definition: Creature.cpp:1727
T AddPct(T &base, U pct)
Definition: Util.h:109
uint32 item
Definition: Creature.h:351
#define sFormationMgr
uint16 m_valuesCount
Definition: Object.h:432
uint32 m_regenTimer
Definition: Creature.h:911
uint8 getClass() const
Definition: Unit.h:1039
virtual bool SetWalk(bool enable)
Definition: Unit.cpp:13565
MovementGeneratorType
Definition: MotionMaster.h:33
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:7279
uint32 GetTeam() const
Definition: Player.h:2075
void SetPvP(bool state)
Definition: Unit.h:1144
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1002
void SetName(const std::string &newname)
Definition: Object.h:696
void SetPower(Powers power, uint32 val)
Definition: Unit.cpp:10918
float orientation
Definition: Creature.h:278
uint8 getLevelForTarget(Unit const *target) const
Definition: Creature.cpp:2356
std::vector< std::string > Name
Definition: Creature.h:242
void SetInCombatWithZone()
Definition: Creature.cpp:2186
uint32 Mechanic
Definition: DBCStructure.h:678
Unit * SelectNearestHostileUnitInAggroRange(bool useLOS=false) const
Definition: Creature.cpp:2719
#define MAX_AGGRO_RADIUS
Definition: Unit.h:254
Creature(bool isWorldObject=false)
Definition: Creature.cpp:145
void RemoveCorpse(bool setSpawnTime=true)
Definition: Creature.cpp:234
bool isTappedBy(Player const *player) const
Definition: Creature.cpp:1032
bool hasLootRecipient() const
Definition: Creature.h:670
void SearchFormation()
Definition: Creature.cpp:220
uint32 incrtime
Definition: Creature.h:353
#define ASSERT
Definition: Errors.h:33
uint32 minhealth
Definition: Creature.h:145
void SetMaxPower(Powers power, uint32 val)
Definition: Unit.cpp:10951
bool CanHaveThreatList() const
Definition: Unit.cpp:10090
uint32 rangeattacktime
Definition: Creature.h:161
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition: Unit.cpp:9935
void Update(uint32 time) override
Definition: Creature.cpp:467
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition: Unit.cpp:10592
uint16 mapid
Definition: Creature.h:272
void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time)
Definition: Creature.cpp:2228
static Unit * GetUnit(WorldObject const &, uint64 guid)
void DestroyForNearbyPlayers()
Definition: Object.cpp:2554
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:783
#define INVALID_HEIGHT
Definition: Map.h:259
void SetLevel(uint32 lvl)
Definition: Unit.cpp:10817
uint32 InhabitType
Definition: Creature.h:190
uint32 GetEntry() const
Definition: Object.h:186
void LoadEquipment(uint32 equip_entry, bool force=false)
Definition: Creature.cpp:1358
bool LoadCreaturesAddon(bool reload=false)
Definition: Creature.cpp:2126
bool IsPositionValid() const
Definition: Position.cpp:40
static float _GetDamageMod(int32 Rank)
Definition: Creature.cpp:1224
float scale
Definition: Creature.h:154
uint32 StartRecoveryTime
Definition: DBCStructure.h:758
#define MELEE_RANGE
Definition: Object.h:48
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition: Creature.cpp:2389
#define sWorld
Definition: World.h:860
void SetFullHealth()
Definition: Unit.h:1068
AuraList const & GetAurasByType(AuraType type) const
Definition: Unit.h:1856
CreatureTextRepeatIds GetTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:2651
uint32 classNum
Definition: Creature.h:168
float bounding_radius
Definition: Creature.h:312
void SetHealth(uint32 val)
Definition: Unit.cpp:10826
uint32 type_flags
Definition: Creature.h:174
uint32 m_equipmentId
Definition: Creature.h:915
ACE_UINT16 uint16
Definition: Define.h:72
float GetDistanceZ(const WorldObject *obj) const
Definition: Object.cpp:1192
bool isCharmed() const
Definition: Unit.h:1543
uint32 dmgschool
Definition: Creature.h:158
#define MAX_VIRTUAL_ITEM_SLOT
Definition: Creature.h:433
CreatureSpellCooldowns m_CreatureCategoryCooldowns
Definition: Creature.h:681
uint32 GetScriptId()
Definition: Creature.cpp:2379
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:7132
uint32 ScriptID
Definition: Creature.h:198
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.h:299
ACE_UINT32 uint32
Definition: Define.h:71
void GetRespawnPosition(float &x, float &y, float &z, float *ori=NULL, float *dist=NULL) const
Definition: Creature.cpp:2307
ReputationRank GetReputationRank(uint32 faction_id) const
Definition: Player.cpp:5922
void Initialize()
float GetPositionX() const
Definition: Position.h:97
time_t lastIncrementTime
Definition: Creature.h:398
bool IsSummon() const
Definition: Unit.h:1018
LootStore LootTemplates_Skinning("skinning_loot_template","creature skinning id")
uint32 GetHealth() const
Definition: Unit.h:1051
bool isWorldBoss() const
Definition: Creature.cpp:1736
true
Definition: Log.cpp:534
bool isTrigger() const
Definition: Creature.h:507
CreatureDataAddon const * GetCreatureAddon() const
Definition: Creature.cpp:2113
virtual void Reset()
Definition: UnitAI.h:60
void AddCreatureSpellCooldown(uint32 spellid)
Definition: Creature.cpp:2233
std::string GetAIName() const
Definition: Creature.cpp:2369
Definition: Unit.h:884
float m_CombatDistance
Definition: Creature.h:864
bool isSpiritHealer() const
Definition: Unit.h:1268
float GetObjectSize() const
Definition: Object.h:663
uint32 getLevel() const
Definition: Unit.h:1029
bool GetBGAccessByLevel(uint32 bgTypeId) const
Definition: Player.cpp:19403
virtual bool IsImmuneToSpellEffect(SpellEntry const *spellInfo, uint32 index, bool castOnSelf) const
Definition: Unit.cpp:8931
bool IsImmuneToSpell(SpellEntry const *spellInfo, bool useCharges=false) override
Definition: Creature.cpp:1705
void DisappearAndDie()
Definition: Creature.cpp:212
void SetReactState(ReactStates st)
Definition: Creature.h:525
std::string GetScriptName()
Definition: Creature.cpp:2374
Definition: Player.h:922
int32 resistance2
Definition: Creature.h:179
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:25
uint32 GetInstanceId() const
Definition: Map.h:390
~Creature() override
Definition: Creature.cpp:173
uint32 m_groupLootTimer
Definition: Object.h:912
uint32 SoundOverrideSubclass
DeathState getDeathState()
Definition: Unit.h:1445
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition: CellImpl.h:121
bool isTargetableForAttack(bool checkFakeDeath=true) const
Definition: Unit.cpp:9418
float GetStat(Stats stat) const
Definition: Unit.h:1043
DBCStorage< SpellRangeEntry > sSpellRangeStore(SpellRangefmt)
Unit * getAttackerForHelper() const
Definition: Unit.h:966
float posZ
Definition: Creature.h:277
Unit * ToUnit()
Definition: Object.h:392
void StartPickPocketRefillTimer()
Definition: Creature.cpp:2637
void ClearTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:2662
bool SetFeatherFall(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2567
iterator end()
Definition: MapRefManager.h:52
void SetInCombatWith(Unit *enemy)
Definition: Unit.cpp:9255
bool SetWaterWalking(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2553
bool IsInDist(float x, float y, float z, float dist) const
Definition: Position.h:188
Definition: Group.h:154
void FormationReset(bool dismiss)
uint32 manaCost
Definition: DBCStructure.h:710
uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo)
Definition: SpellMgr.h:151
Definition: UnitAI.h:40
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:71
uint32 HeroicEntry
Definition: Creature.h:132
uint32 count
Definition: Creature.h:397
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:7565
bool hasQuest(uint32 quest_id) const override
Definition: Creature.cpp:1422
const uint64 & GetGUID() const
Definition: Object.h:156
bool HasAura(uint32 spellId, uint8 effIndex=0) const
Definition: Unit.h:1342
uint32 StartRecoveryCategory
Definition: DBCStructure.h:757
float GetSpellMaxRange(SpellRangeEntry const *range)
Definition: SpellMgr.h:143
bool Create(uint32 guidlow, Map *map, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data=NULL)
Definition: Creature.cpp:759