OregonCore  revision be9e804-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 <https://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 "Utilities/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  SetObjectScale(cinfo->scale);
336 
337  // checked at loading
341 
342  for (int i = 0; i < CREATURE_MAX_SPELLS; ++i)
344 
345  return true;
346 }
347 
348 bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData* data)
349 {
350  if (!InitEntry(Entry, team, data))
351  return false;
352 
353  CreatureInfo const* cInfo = GetCreatureTemplate();
354 
355  m_regenHealth = cInfo->RegenHealth;
356 
357  // creatures always have melee weapon ready if any unless specified otherwise
358  if (!GetCreatureAddon())
360 
362 
363  SetFaction(cInfo->faction);
364 
365  uint32 npcflag, unit_flags, dynamicflags;
366  ObjectMgr::ChooseCreatureFlags(cInfo, npcflag, unit_flags, dynamicflags, data);
367 
369  SetUInt32Value(UNIT_NPC_FLAGS, npcflag | sGameEventMgr.GetNPCFlag(this));
370  else
371  SetUInt32Value(UNIT_NPC_FLAGS, npcflag);
372 
373  SetUInt32Value(UNIT_FIELD_FLAGS, unit_flags);
374  SetUInt32Value(UNIT_DYNAMIC_FLAGS, dynamicflags);
375 
377 
381 
382  SelectLevel();
383 
385  CreatureBaseStats const* cCLS = sObjectMgr.GetCreatureClassLvlStats(getLevel(), cInfo->unit_class, cInfo->exp);
386  float armor = cCLS->BaseArmor * cInfo->ModArmor;
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 phaseMask, uint32 entry, uint32 team, float x, float y, float z, float ang, const CreatureData* data)
760 {
761  ASSERT(map);
762  SetMap(map);
763  SetPhaseMask(phaseMask, false);
764 
765  CreatureInfo const* cinfo = sObjectMgr.GetCreatureTemplate(entry);
766  if (!cinfo)
767  {
768  sLog.outError("Creature::Create(): creature template (guidlow: %u, entry: %u) does not exist.", guidlow, entry);
769  return false;
770  }
771 
774  Relocate(x, y, z, ang);
775 
776  if (!IsPositionValid())
777  {
778  sLog.outError("Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, entry, x, y);
779  return false;
780  }
781 
782  // Allow players to see those units while dead, do it here (mayby altered by addon auras)
785 
786  if (!CreateFromProto(guidlow, entry, team, data))
787  return false;
788 
789  switch (GetCreatureTemplate()->rank)
790  {
791  case CREATURE_ELITE_RARE:
793  break;
796  break;
799  break;
802  break;
803  default:
805  break;
806  }
807 
809  if (IsSpiritHealer() || IsSpiritGuide())
810  {
813  }
814 
815  return true;
816 }
817 
819 {
820  if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService())
822  else
824 }
825 
826 bool Creature::IsTrainerOf(Player* pPlayer, bool msg) const
827 {
828  if (!IsTrainer())
829  return false;
830 
831  TrainerSpellData const* trainer_spells = GetTrainerSpells();
832 
833  if (!trainer_spells || trainer_spells->spellList.empty())
834  {
835  sLog.outErrorDb("Creature %u (Entry: %u) has UNIT_NPC_FLAG_TRAINER but trainer spell list is empty.",
836  GetGUIDLow(), GetEntry());
837  return false;
838  }
839 
840  switch (GetCreatureTemplate()->trainer_type)
841  {
842  case TRAINER_TYPE_CLASS:
843  if (pPlayer->getClass() != GetCreatureTemplate()->classNum)
844  {
845  if (msg)
846  {
847  pPlayer->PlayerTalkClass->ClearMenus();
848  switch (GetCreatureTemplate()->classNum)
849  {
850  case CLASS_DRUID:
851  pPlayer->PlayerTalkClass->SendGossipMenu(4913, GetGUID());
852  break;
853  case CLASS_HUNTER:
854  pPlayer->PlayerTalkClass->SendGossipMenu(10090, GetGUID());
855  break;
856  case CLASS_MAGE:
857  pPlayer->PlayerTalkClass->SendGossipMenu( 328, GetGUID());
858  break;
859  case CLASS_PALADIN:
860  pPlayer->PlayerTalkClass->SendGossipMenu(1635, GetGUID());
861  break;
862  case CLASS_PRIEST:
863  pPlayer->PlayerTalkClass->SendGossipMenu(4436, GetGUID());
864  break;
865  case CLASS_ROGUE:
866  pPlayer->PlayerTalkClass->SendGossipMenu(4797, GetGUID());
867  break;
868  case CLASS_SHAMAN:
869  pPlayer->PlayerTalkClass->SendGossipMenu(5003, GetGUID());
870  break;
871  case CLASS_WARLOCK:
872  pPlayer->PlayerTalkClass->SendGossipMenu(5836, GetGUID());
873  break;
874  case CLASS_WARRIOR:
875  pPlayer->PlayerTalkClass->SendGossipMenu(4985, GetGUID());
876  break;
877  }
878  }
879  return false;
880  }
881  break;
882  case TRAINER_TYPE_PETS:
883  if (pPlayer->getClass() != CLASS_HUNTER)
884  {
885  pPlayer->PlayerTalkClass->ClearMenus();
886  pPlayer->PlayerTalkClass->SendGossipMenu(3620, GetGUID());
887  return false;
888  }
889  break;
890  case TRAINER_TYPE_MOUNTS:
891  if (GetCreatureTemplate()->race && pPlayer->getRace() != GetCreatureTemplate()->race)
892  {
893  // Allowed to train if exalted
894  if (FactionTemplateEntry const* faction_template = GetFactionTemplateEntry())
895  {
896  if (pPlayer->GetReputationRank(faction_template->faction) == REP_EXALTED)
897  return true;
898  }
899 
900  if (msg)
901  {
902  pPlayer->PlayerTalkClass->ClearMenus();
903  switch (GetCreatureTemplate()->classNum)
904  {
905  case RACE_DWARF:
906  pPlayer->PlayerTalkClass->SendGossipMenu(5865, GetGUID());
907  break;
908  case RACE_GNOME:
909  pPlayer->PlayerTalkClass->SendGossipMenu(4881, GetGUID());
910  break;
911  case RACE_HUMAN:
912  pPlayer->PlayerTalkClass->SendGossipMenu(5861, GetGUID());
913  break;
914  case RACE_NIGHTELF:
915  pPlayer->PlayerTalkClass->SendGossipMenu(5862, GetGUID());
916  break;
917  case RACE_ORC:
918  pPlayer->PlayerTalkClass->SendGossipMenu(5863, GetGUID());
919  break;
920  case RACE_TAUREN:
921  pPlayer->PlayerTalkClass->SendGossipMenu(5864, GetGUID());
922  break;
923  case RACE_TROLL:
924  pPlayer->PlayerTalkClass->SendGossipMenu(5816, GetGUID());
925  break;
926  case RACE_UNDEAD_PLAYER:
927  pPlayer->PlayerTalkClass->SendGossipMenu(624, GetGUID());
928  break;
929  case RACE_BLOODELF:
930  pPlayer->PlayerTalkClass->SendGossipMenu(5862, GetGUID());
931  break;
932  case RACE_DRAENEI:
933  pPlayer->PlayerTalkClass->SendGossipMenu(5864, GetGUID());
934  break;
935  }
936  }
937  return false;
938  }
939  break;
941  if (GetCreatureTemplate()->trainer_spell && !pPlayer->HasSpell(GetCreatureTemplate()->trainer_spell))
942  {
943  if (msg)
944  {
945  pPlayer->PlayerTalkClass->ClearMenus();
946  pPlayer->PlayerTalkClass->SendGossipMenu(11031, GetGUID());
947  }
948  return false;
949  }
950  break;
951  default:
952  return false; // checked and error output at creature_template loading
953  }
954  return true;
955 }
956 
957 bool Creature::CanInteractWithBattleMaster(Player* player, bool msg) const
958 {
959  if (!IsBattleMaster())
960  return false;
961 
962  uint32 bgTypeId = sObjectMgr.GetBattleMasterBG(GetEntry());
963  if (!msg)
964  return player->GetBGAccessByLevel(bgTypeId);
965 
966  if (!player->GetBGAccessByLevel(bgTypeId))
967  {
968  player->PlayerTalkClass->ClearMenus();
969  switch (bgTypeId)
970  {
971  case BATTLEGROUND_AV: player->PlayerTalkClass->SendGossipMenu(7616, GetGUID()); break;
972  case BATTLEGROUND_WS: player->PlayerTalkClass->SendGossipMenu(7599, GetGUID()); break;
973  case BATTLEGROUND_AB: player->PlayerTalkClass->SendGossipMenu(7642, GetGUID()); break;
974  case BATTLEGROUND_EY:
975  case BATTLEGROUND_NA:
976  case BATTLEGROUND_BE:
977  case BATTLEGROUND_AA:
978  case BATTLEGROUND_RL: player->PlayerTalkClass->SendGossipMenu(10024, GetGUID()); break;
979  default: break;
980  }
981  return false;
982  }
983  return true;
984 }
985 
987 {
988  return player->getLevel() >= 10
990  && player->getClass() == GetCreatureTemplate()->classNum;
991 }
992 
994 {
995  if (!m_lootRecipient)
996  return NULL;
998 }
999 
1001 {
1002  if (!m_lootRecipientGroup)
1003  return NULL;
1004  return sObjectMgr.GetGroupByLeader(m_lootRecipientGroup);
1005 }
1006 
1008 {
1009  // set the player whose group should receive the right
1010  // to loot the creature after it dies
1011  // should be set to NULL after the loot disappears
1012 
1013  if (!unit)
1014  {
1015  m_lootRecipient = 0;
1018  return;
1019  }
1020 
1022  if (!player) // normal creature, no player involved
1023  return;
1024 
1025  m_lootRecipient = player->GetGUID();
1026  if (Group* group = player->GetGroup())
1027  m_lootRecipientGroup = group->GetLeaderGUID();
1028 
1030 }
1031 
1032 // return true if this creature is tapped by the player or by a member of his group.
1033 bool Creature::isTappedBy(Player const* player) const
1034 {
1035  if (player->GetGUID() == m_lootRecipient)
1036  return true;
1037 
1038  Group const* playerGroup = player->GetGroup();
1039  if (!playerGroup || playerGroup != GetLootRecipientGroup()) // if we dont have a group we arent the recipient
1040  return false; // if creature doesnt have group bound it means it was solo killed by someone else
1041 
1042  return true;
1043 }
1044 
1046 {
1047  // this should only be used when the creature has already been loaded
1048  // preferably after adding to map, because mapid may not be valid otherwise
1049  CreatureData const* data = sObjectMgr.GetCreatureData(m_DBTableGuid);
1050  if (!data)
1051  {
1052  sLog.outError("Creature::SaveToDB failed, cannot get creature data!");
1053  return;
1054  }
1055 
1056  SaveToDB(GetMapId(), data->spawnMask, GetPhaseMask());
1057 }
1058 
1059 void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
1060 {
1061  // update in loaded data
1062  if (!m_DBTableGuid)
1064 
1065  CreatureData& data = sObjectMgr.NewOrExistCreatureData(m_DBTableGuid);
1066 
1067  uint32 displayId = GetNativeDisplayId();
1069  uint32 unit_flags = GetUInt32Value(UNIT_FIELD_FLAGS);
1070  uint32 dynamicflags = GetUInt32Value(UNIT_DYNAMIC_FLAGS);
1071 
1072  // check if it's a custom model and if not, use 0 for displayId
1073  CreatureInfo const* cinfo = GetCreatureTemplate();
1074  if (cinfo)
1075  {
1076  if (displayId == cinfo->modelid1 || displayId == cinfo->modelid2 ||
1077  displayId == cinfo->modelid3 || displayId == cinfo->modelid4)
1078  displayId = 0;
1079  }
1080 
1081  if (npcflag == cinfo->npcflag)
1082  npcflag = 0;
1083 
1084  if (unit_flags == cinfo->unit_flags)
1085  unit_flags = 0;
1086 
1087  if (dynamicflags == cinfo->dynamicflags)
1088  dynamicflags = 0;
1089 
1090  // data->guid = guid must not be update at save
1091  data.id = GetEntry();
1092  data.mapid = mapid;
1093  data.phaseMask = phaseMask;
1094  data.displayid = displayId;
1096  data.posX = GetPositionX();
1097  data.posY = GetPositionY();
1098  data.posZ = GetPositionZ();
1099  data.orientation = GetOrientation();
1101  // prevent add data integrity problems
1103  data.currentwaypoint = 0;
1104  data.curhealth = GetHealth();
1105  data.curmana = GetPower(POWER_MANA);
1106  // prevent add data integrity problems
1109  data.spawnMask = spawnMask;
1110  data.npcflag = npcflag;
1111  data.unit_flags = unit_flags;
1112  data.dynamicflags = dynamicflags;
1113 
1114  // updated in DB
1116 
1117  WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
1118 
1119  std::ostringstream ss;
1120  ss << "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES ("
1121  << m_DBTableGuid << ","
1122  << GetEntry() << ","
1123  << mapid << ","
1124  << (uint32)spawnMask << ","
1125  << (uint32)phaseMask << ","
1126  << displayId << ","
1127  << GetEquipmentId() << ","
1128  << GetPositionX() << ","
1129  << GetPositionY() << ","
1130  << GetPositionZ() << ","
1131  << GetOrientation() << ","
1132  << m_respawnDelay << "," //respawn time
1133  << (float) m_respawnradius << "," //spawn distance (float)
1134  << (uint32) (0) << "," //currentwaypoint
1135  << GetHealth() << "," //curhealth
1136  << GetPower(POWER_MANA) << "," //curmana
1137  << GetDefaultMovementType() << "," //default movement generator type
1138  << npcflag << ","
1139  << unit_flags << ","
1140  << dynamicflags << ")";
1141 
1142  WorldDatabase.PExecuteLog("%s", ss.str().c_str());
1143 
1145 }
1146 
1148 {
1149  CreatureInfo const* cInfo = GetCreatureTemplate();
1150 
1151  uint32 rank = IsPet() ? 0 : cInfo->rank;
1152 
1153  // level
1154  uint32 const minlevel = cInfo->minlevel;
1155  uint32 const maxlevel = cInfo->maxlevel;
1156  uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel);
1157  SetLevel(level);
1158 
1159  uint32 health;
1160  uint32 mana;
1161 
1162  CreatureBaseStats const* cCLS = sObjectMgr.GetCreatureClassLvlStats(level, cInfo->unit_class, cInfo->exp);
1163 
1164  // health
1165  health = cCLS->BaseHealth * cInfo->ModHealth;
1166 
1167  health *= _GetHealthMod(rank); // Apply custom config settting
1168  if (health < 1)
1169  health = 1;
1170 
1171  SetCreateHealth(health);
1172  SetMaxHealth(health);
1173  SetHealth(health);
1174  SetPlayerDamaged(false);
1175 
1176  // mana
1177  mana = cCLS->BaseMana * cInfo->ModMana;
1178  SetCreateMana(mana);
1179  SetMaxPower(POWER_MANA, mana); //MAX Mana
1180  SetPower(POWER_MANA, mana);
1181 
1182  SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
1183  SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana);
1184 
1185  // damage
1186  float basedamage = cCLS->BaseDamage;
1187 
1188  float weaponBaseMinDamage = basedamage;
1189  float weaponBaseMaxDamage = basedamage * 1.5;
1190 
1191  SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1192  SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1193 
1194  SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1195  SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1196 
1197  SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage);
1198  SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
1199 
1202 
1203  UpdateAllStats();
1204 }
1205 
1207 {
1208  switch (Rank) // define rates for each elite rank
1209  {
1210  case CREATURE_ELITE_NORMAL:
1211  return sWorld.getRate(RATE_CREATURE_NORMAL_HP);
1212  case CREATURE_ELITE_ELITE:
1213  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP);
1215  return sWorld.getRate(RATE_CREATURE_ELITE_RAREELITE_HP);
1217  return sWorld.getRate(RATE_CREATURE_ELITE_WORLDBOSS_HP);
1218  case CREATURE_ELITE_RARE:
1219  return sWorld.getRate(RATE_CREATURE_ELITE_RARE_HP);
1220  default:
1221  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP);
1222  }
1223 }
1224 
1226 {
1227  hasPlayerDamaged = set;
1228 }
1229 
1231 {
1232  switch (Rank) // define rates for each elite rank
1233  {
1234  case CREATURE_ELITE_NORMAL:
1235  return sWorld.getRate(RATE_CREATURE_NORMAL_DAMAGE);
1236  case CREATURE_ELITE_ELITE:
1237  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
1242  case CREATURE_ELITE_RARE:
1243  return sWorld.getRate(RATE_CREATURE_ELITE_RARE_DAMAGE);
1244  default:
1245  return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE);
1246  }
1247 }
1248 
1250 {
1251  switch (Rank) // define rates for each elite rank
1252  {
1253  case CREATURE_ELITE_NORMAL:
1254  return sWorld.getRate(RATE_CREATURE_NORMAL_SPELLDAMAGE);
1255  case CREATURE_ELITE_ELITE:
1261  case CREATURE_ELITE_RARE:
1263  default:
1265  }
1266 }
1267 
1268 bool Creature::CreateFromProto(uint32 guidlow, uint32 entry, uint32 team, const CreatureData* data)
1269 {
1270  SetZoneScript();
1271  if (m_zoneScript && data)
1272  {
1273  entry = m_zoneScript->GetCreatureEntry(guidlow, data);
1274  if (!entry)
1275  return false;
1276  }
1277 
1278  CreatureInfo const* cinfo = sObjectMgr.GetCreatureTemplate(entry);
1279  if (!cinfo)
1280  {
1281  sLog.outErrorDb("Creature::CreateFromProto(): creature template (guidlow: %u, entry: %u) does not exist.", guidlow, entry);
1282  return false;
1283  }
1284 
1285  SetOriginalEntry(entry);
1286 
1287  Object::_Create(guidlow, entry, HIGHGUID_UNIT);
1288 
1289  if (!UpdateEntry(entry, team, data))
1290  return false;
1291 
1292  return true;
1293 }
1294 
1295 bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
1296 {
1297  CreatureData const* data = sObjectMgr.GetCreatureData(guid);
1298 
1299  if (!data)
1300  {
1301  sLog.outErrorDb("Creature (GUID: %u) not found in table creature, can't load. ", guid);
1302  return false;
1303  }
1304 
1305  m_DBTableGuid = guid;
1306  if (map->GetInstanceId() != 0)
1307  guid = sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT);
1308 
1309  uint16 team = 0;
1310  if (!Create(guid, map, data->phaseMask, data->id, team, data->posX, data->posY, data->posZ, data->orientation, data))
1311  return false;
1312 
1313  //We should set first home position, because then AI calls home movement
1314  SetHomePosition(data->posX, data->posY, data->posZ, data->orientation);
1315 
1316  m_respawnradius = data->spawndist;
1317 
1318  m_respawnDelay = data->spawntimesecs;
1319  m_deathState = ALIVE;
1320 
1321  m_respawnTime = sObjectMgr.GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
1322  if (m_respawnTime) // respawn on Update
1323  {
1324  m_deathState = DEAD;
1325  if (CanFly())
1326  {
1327  float tz = GetMap()->GetHeight(data->posX, data->posY, data->posZ, false);
1328  if (data->posZ - tz > 0.1)
1329  Relocate(data->posX, data->posY, tz);
1330  }
1331  }
1332 
1333  uint32 curhealth;
1334 
1335  if (!m_regenHealth)
1336  {
1337  curhealth = data->curhealth;
1338  if (curhealth)
1339  {
1340  curhealth = uint32(curhealth * _GetHealthMod(GetCreatureTemplate()->rank));
1341  if (curhealth < 1)
1342  curhealth = 1;
1343  }
1344  SetPower(POWER_MANA, data->curmana);
1345  }
1346  else
1347  {
1348  curhealth = GetMaxHealth();
1350  }
1351 
1352  SetHealth(m_deathState == ALIVE ? curhealth : 0);
1353 
1354  // checked at creature_template loading
1356 
1357  m_creatureData = data;
1358 
1359  if (addToMap && !GetMap()->AddToMap(this))
1360  return false;
1361  return true;
1362 }
1363 
1365 {
1366  Unit::SetCanDualWield(value);
1368 }
1369 
1370 void Creature::LoadEquipment(uint32 equip_entry, bool force)
1371 {
1372  if (equip_entry == 0)
1373  {
1374  if (force)
1375  {
1376  for (uint8 i = 0; i < 3; ++i)
1377  {
1379  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0);
1380  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0);
1381  }
1382  m_equipmentId = 0;
1383  }
1384  return;
1385  }
1386 
1387  if (EquipmentInfo const* einfo = sObjectMgr.GetEquipmentInfo(equip_entry))
1388  {
1389  m_equipmentId = equip_entry;
1390  for (uint8 i = 0; i < MAX_VIRTUAL_ITEM_SLOT; ++i)
1391  SetVirtualItem(VirtualItemSlot(i), einfo->equipentry[i]);
1392  }
1393  else if (EquipmentInfoRaw const* einfo = sObjectMgr.GetEquipmentInfoRaw(equip_entry))
1394  {
1395  m_equipmentId = equip_entry;
1396  for (uint8 i = 0; i < MAX_VIRTUAL_ITEM_SLOT; ++i)
1397  SetVirtualItemRaw(VirtualItemSlot(i), einfo->equipmodel[i], einfo->equipinfo[i], einfo->equipslot[i]);
1398  }
1399 }
1400 
1402 {
1403  if (item_id == 0)
1404  {
1406  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, 0);
1407  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, 0);
1408  return;
1409  }
1410 
1411  ItemTemplate const* proto = ObjectMgr::GetItemTemplate(item_id);
1412  if (!proto)
1413  {
1414  sLog.outError("Not listed in 'item_template' item (ID:%u) used as virtual item for " UI64FMTD "", item_id, GetGUID());
1415  return;
1416  }
1417 
1425 }
1426 
1428 {
1429  SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + slot, display_id);
1430  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 0, info0);
1431  SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO + (slot * 2) + 1, info1);
1432 }
1433 
1434 bool Creature::hasQuest(uint32 quest_id) const
1435 {
1436  QuestRelations qr = sObjectMgr.mCreatureQuestRelations;
1437  for (QuestRelations::const_iterator itr = qr.lower_bound(GetEntry()); itr != qr.upper_bound(GetEntry()); ++itr)
1438  {
1439  if (itr->second == quest_id)
1440  return true;
1441  }
1442  return false;
1443 }
1444 
1446 {
1447  QuestRelations qir = sObjectMgr.mCreatureQuestInvolvedRelations;
1448  for (QuestRelations::const_iterator itr = qir.lower_bound(GetEntry()); itr != qir.upper_bound(GetEntry()); ++itr)
1449  {
1450  if (itr->second == quest_id)
1451  return true;
1452  }
1453  return false;
1454 }
1455 
1457 {
1458  if (!m_DBTableGuid)
1459  {
1460  sLog.outDebug("Trying to delete not saved creature!");
1461  return;
1462  }
1463 
1464  sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), 0);
1465  sObjectMgr.DeleteCreatureData(m_DBTableGuid);
1466 
1468  WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
1469  WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
1470  WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
1471  WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
1473 }
1474 
1476 {
1478  return true;
1479 
1480  if (IsAlive() || isDying() || m_corpseRemoveTime > time(NULL))
1481  return false;
1482 
1483  return true;
1484 }
1485 
1486 bool Creature::CanAlwaysSee(WorldObject const* obj) const
1487 {
1488  if (IsAIEnabled && AI()->CanSeeAlways(obj))
1489  return true;
1490 
1491  return false;
1492 }
1493 
1494 bool Creature::canStartAttack(Unit const* who, bool force) const
1495 {
1496  if (IsCivilian())
1497  return false;
1498 
1499  // This set of checks is should be done only for creatures
1500  if ((HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC) && who->GetTypeId() != TYPEID_PLAYER) // flag is valid only for non player characters
1501  || (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) && who->GetTypeId() == TYPEID_PLAYER) // immune to PC and target is a player, return false
1502  || (who->GetOwner() && who->GetOwner()->GetTypeId() == TYPEID_PLAYER && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))) // player pets are immune to pc as well
1503  return false;
1504 
1505  // Do not attack non-combat pets
1507  return false;
1508 
1510  return false;
1511 
1512  if (!force)
1513  {
1514  if (!_IsTargetAcceptable(who))
1515  return false;
1516 
1517  if (who->IsInCombat() && IsWithinDist(who, ATTACK_DISTANCE))
1518  if (Unit* victim = who->getAttackerForHelper())
1520  force = true;
1521 
1522  if (!force && (IsNeutralToAll() || !IsWithinDistInMap(who, GetAttackDistance(who) + m_CombatDistance)))
1523  return false;
1524  }
1525 
1526  if (!CanCreatureAttack(who, force))
1527  return false;
1528 
1529  return IsWithinLOSInMap(who);
1530 }
1531 
1532 float Creature::GetAttackDistance(Unit const* player) const
1533 {
1534  float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO);
1535  if (aggroRate == 0)
1536  return 0.0f;
1537 
1538  uint32 playerlevel = player->getLevelForTarget(this);
1539  uint32 creaturelevel = getLevelForTarget(player);
1540 
1541  int32 leveldif = int32(playerlevel) - int32(creaturelevel);
1542 
1543  // "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."
1544  if (leveldif < - 25)
1545  leveldif = -25;
1546 
1547  // "The aggro radius of a mob having the same level as the player is roughly 20 yards"
1548  float RetDistance = 20;
1549 
1550  // "Aggro Radius varies with level difference at a rate of roughly 1 yard/level"
1551  // radius grow if playlevel < creaturelevel
1552  RetDistance -= (float)leveldif;
1553 
1554  if (creaturelevel + 5 <= int32(sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)))
1555  {
1556  // detect range auras
1558 
1559  // detected range auras
1560  RetDistance += player->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE);
1561  }
1562 
1563  // "Minimum Aggro Radius for a mob seems to be combat range (5 yards)"
1564  if (RetDistance < 5)
1565  RetDistance = 5;
1566 
1567  return (RetDistance * aggroRate);
1568 }
1569 
1571 {
1573 
1574  if (s == JUST_DIED)
1575  {
1576  m_corpseRemoveTime = time(NULL) + m_corpseDelay;
1577  m_respawnTime = time(NULL) + m_respawnDelay + m_corpseDelay;
1578 
1579  // always save boss respawn time at death to prevent crash cheating
1581  SaveRespawnTime();
1582 
1583  SetTarget(0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState)
1585 
1586  SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); // if creature is mounted on a virtual mount, remove it at death
1587 
1588  setActive(false);
1589 
1590  if (HasSearchedAssistance())
1591  {
1592  SetNoSearchAssistance(false);
1593  UpdateSpeed(MOVE_RUN, false);
1594  }
1595 
1596  //Dismiss group if is leader
1597  if (m_formation && m_formation->getLeader() == this)
1598  m_formation->FormationReset(true);
1599 
1600  if ((CanFly() || IsFlying()))
1602 
1603  SetHealth(0);
1604  SetPower(getPowerType(), 0);
1605 
1606  if (m_zoneScript)
1608 
1610  }
1611  else if (s == JUST_RESPAWNED)
1612  {
1613  SetFullHealth();
1614  SetLootRecipient(nullptr);
1615  SetPlayerDamaged(false);
1616 
1618 
1620 
1621  if (!IsPet())
1622  {
1623  CreatureData const* creatureData = GetCreatureData();
1624  CreatureInfo const* cinfo = GetCreatureTemplate();
1625 
1627 
1629 
1631 
1632  if (creatureData && GetPhaseMask() != creatureData->phaseMask)
1633  SetPhaseMask(creatureData->phaseMask, false);
1634  }
1635 
1637  LoadCreaturesAddon(true);
1638 
1640 
1641  // Prevents the creature from re-spawning at the location of it's death
1643  }
1644 }
1645 
1646 void Creature::Respawn(bool force)
1647 {
1649 
1650  if (force)
1651  {
1652  if (IsAlive())
1654  else if (getDeathState() != CORPSE)
1656  }
1657 
1658  RemoveCorpse(false);
1659 
1660  if (getDeathState() == DEAD)
1661  {
1662  if (m_DBTableGuid)
1663  sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), 0);
1664 
1665  DEBUG_LOG("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry());
1666  m_respawnTime = 0;
1668  loot.clear();
1669  if (m_originalEntry != GetEntry())
1671 
1672  SelectLevel();
1673 
1675 
1677 
1678  //Call AI respawn virtual function
1679  if (IsAIEnabled)
1680  {
1681  //reset the AI to be sure no dirty or uninitialized values will be used till next tick
1682  AI()->Reset();
1683  TriggerJustRespawned = true; //delay event to next tick so all creatures are created on the map before processing
1684  }
1685 
1686  uint32 poolid = sPoolMgr.IsPartOfAPool<Creature>(GetDBTableGUIDLow());
1687  if (poolid)
1688  sPoolMgr.UpdatePool<Creature>(poolid, GetDBTableGUIDLow());
1689 
1690  //Re-initialize reactstate that could be altered by movementgenerators
1692  }
1693 
1695 }
1696 
1697 void Creature::ForcedDespawn(uint32 timeMSToDespawn)
1698 {
1699  if (timeMSToDespawn)
1700  {
1701  ForcedDespawnDelayEvent* pEvent = new ForcedDespawnDelayEvent(*this);
1702 
1703  m_Events.AddEvent(pEvent, m_Events.CalculateTime(timeMSToDespawn));
1704  return;
1705  }
1706 
1707  if (IsAlive())
1709 
1710  RemoveCorpse(false);
1711 }
1712 
1713 void Creature::DespawnOrUnsummon(uint32 msTimeToDespawn /*= 0*/)
1714 {
1715  if (TempSummon* summon = this->ToTempSummon())
1716  summon->UnSummon(msTimeToDespawn);
1717  else
1718  ForcedDespawn(msTimeToDespawn);
1719 }
1720 
1721 bool Creature::IsImmuneToSpell(SpellEntry const* spellInfo, bool useCharges)
1722 {
1723  if (!spellInfo)
1724  return false;
1725 
1726  if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))
1727  return true;
1728 
1729  return Unit::IsImmuneToSpell(spellInfo, useCharges);
1730 }
1731 
1732 bool Creature::IsImmuneToSpellEffect(SpellEntry const* spellInfo, uint32 index, bool castOnSelf) const
1733 {
1734  if (!castOnSelf && GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1)))
1735  return true;
1736 
1737  if (GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && spellInfo->Effect[index] == SPELL_EFFECT_HEAL)
1738  return true;
1739 
1740  return Unit::IsImmuneToSpellEffect(spellInfo, index, castOnSelf);
1741 }
1742 
1743 bool Creature::isElite() const
1744 {
1745  if (IsPet())
1746  return false;
1747 
1748  uint32 rank = GetCreatureTemplate()->rank;
1749  return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
1750 }
1751 
1753 {
1754  if (IsPet())
1755  return false;
1756 
1757  return (GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_BOSS_MOB) != 0;
1758 }
1759 
1761 {
1762  if (!victim)
1763  return NULL;
1764 
1765  for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
1766  {
1767  if (!m_spells[i])
1768  continue;
1769  SpellEntry const* spellInfo = sSpellStore.LookupEntry(m_spells[i]);
1770  if (!spellInfo)
1771  {
1772  sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
1773  continue;
1774  }
1775 
1776  bool bcontinue = true;
1777  for (uint32 j = 0; j < 3; j++)
1778  {
1779  if ((spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE) ||
1780  (spellInfo->Effect[j] == SPELL_EFFECT_INSTAKILL) ||
1781  (spellInfo->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) ||
1782  (spellInfo->Effect[j] == SPELL_EFFECT_HEALTH_LEECH)
1783  )
1784  {
1785  bcontinue = false;
1786  break;
1787  }
1788  }
1789  if (bcontinue)
1790  continue;
1791 
1792  if (spellInfo->manaCost > GetPower(POWER_MANA))
1793  continue;
1794 
1795  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
1796  float range = GetSpellMaxRange(srange);
1797  float minrange = GetSpellMinRange(srange);
1798  float dist = GetDistance(victim);
1799  if (dist > range || dist < minrange)
1800  continue;
1802  continue;
1804  continue;
1805  return spellInfo;
1806  }
1807  return NULL;
1808 }
1809 
1811 {
1812  if (!victim)
1813  return NULL;
1814 
1815  for (uint32 i = 0; i < CREATURE_MAX_SPELLS; i++)
1816  {
1817  if (!m_spells[i])
1818  continue;
1819  SpellEntry const* spellInfo = sSpellStore.LookupEntry(m_spells[i]);
1820  if (!spellInfo)
1821  {
1822  sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]);
1823  continue;
1824  }
1825 
1826  bool bcontinue = true;
1827  for (uint32 j = 0; j < 3; j++)
1828  {
1829  if ((spellInfo->Effect[j] == SPELL_EFFECT_HEAL))
1830  {
1831  bcontinue = false;
1832  break;
1833  }
1834  }
1835  if (bcontinue)
1836  continue;
1837 
1838  if (spellInfo->manaCost > GetPower(POWER_MANA))
1839  continue;
1840 
1841  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
1842  float range = GetSpellMaxRange(srange);
1843  float minrange = GetSpellMinRange(srange);
1844  float dist = GetDistance(victim);
1845  //if (!isInFront(victim, range) && spellInfo->AttributesEx)
1846  // continue;
1847  if (dist > range || dist < minrange)
1848  continue;
1850  continue;
1852  continue;
1853  return spellInfo;
1854  }
1855  return NULL;
1856 }
1857 
1858 // select nearest hostile unit within the given distance (regardless of threat list).
1859 Unit* Creature::SelectNearestTarget(float dist, bool playerOnly /* = false */) const
1860 {
1862  Cell cell(p);
1863  cell.SetNoCreate();
1864 
1865  Unit* target = NULL;
1866 
1867  {
1868  Oregon::NearestHostileUnitCheck u_check(this, dist, playerOnly);
1869  Oregon::UnitLastSearcher<Oregon::NearestHostileUnitCheck> searcher(this, target, u_check);
1870 
1873 
1874  cell.Visit(p, world_unit_searcher, *GetMap(), *this, dist);
1875  cell.Visit(p, grid_unit_searcher, *GetMap(), *this, dist);
1876  }
1877 
1878  return target;
1879 }
1880 
1881 // select nearest hostile unit within the given attack distance (i.e. distance is ignored if > than ATTACK_DISTANCE), regardless of threat list.
1883 {
1885  Cell cell(p);
1886  cell.SetNoCreate();
1887 
1888  Unit *target = nullptr;
1889 
1890  if (dist > MAX_VISIBILITY_DISTANCE)
1891  {
1892  sLog.outError("Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUIDLow(), GetEntry());
1893  dist = ATTACK_DISTANCE;
1894  }
1895 
1898 
1901 
1902  cell.Visit(p, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
1903  cell.Visit(p, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
1904 
1905  return target;
1906 }
1907 
1909 {
1910  WorldPacket data(SMSG_AI_REACTION, 12);
1911 
1912  data << uint64(GetGUID());
1913  data << uint32(reactionType);
1914 
1915  ((WorldObject*)this)->SendMessageToSet(&data, true);
1916 
1917  sLog.outDebug("WORLD: Sent SMSG_AI_REACTION, type %u.", reactionType);
1918 }
1919 
1921 {
1922  if (!m_AlreadyCallAssistance && GetVictim() && !IsPet() && !isCharmed())
1923  {
1924  SetNoCallAssistance(true);
1925 
1926  float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS);
1927 
1928  if (radius > 0)
1929  {
1930  std::list<Creature*> assistList;
1931 
1932  {
1934  Cell cell(p);
1935  cell.SetNoCreate();
1936 
1937  Oregon::AnyAssistCreatureInRangeCheck u_check(this, GetVictim(), radius);
1938  Oregon::CreatureListSearcher<Oregon::AnyAssistCreatureInRangeCheck> searcher(this, assistList, u_check);
1939 
1941 
1942  cell.Visit(p, grid_creature_searcher, *GetMap(), *this, radius);
1943  }
1944 
1945  if (!assistList.empty())
1946  {
1947  AssistDelayEvent* e = new AssistDelayEvent(GetVictim()->GetGUID(), *this);
1948  while (!assistList.empty())
1949  {
1950  // Pushing guids because in delay can happen some creature gets despawned => invalid pointer
1951  e->AddAssistant((*assistList.begin())->GetGUID());
1952  assistList.pop_front();
1953  }
1955  }
1956  }
1957  }
1958 }
1959 
1960 void Creature::CallForHelp(float radius)
1961 {
1962  if (radius <= 0.0f || !GetVictim() || IsPet() || isCharmed())
1963  return;
1964 
1966  Cell cell(p);
1967  cell.SetNoCreate();
1968 
1969  Oregon::CallOfHelpCreatureInRangeDo u_do(this, GetVictim(), radius);
1971 
1973 
1974  cell.Visit(p, grid_creature_searcher, *GetMap(), *this, radius);
1975 }
1976 
1977 bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const
1978 {
1979  if (IsInEvadeMode())
1980  return false;
1981 
1982  // is it true?
1984  return false;
1985 
1986  // we don't need help from zombies :)
1987  if (!IsAlive())
1988  return false;
1989 
1990  // we don't need help from non-combatant ;)
1991  if (IsCivilian())
1992  return false;
1993 
1995  return false;
1996 
1997  // skip fighting creature
1998  if (IsInCombat())
1999  return false;
2000 
2001  // only free creature
2002  if (GetCharmerOrOwnerGUID())
2003  return false;
2004 
2005  // only from same creature faction
2006  if (checkfaction)
2007  {
2008  if (GetFaction() != u->GetFaction())
2009  return false;
2010  }
2011  else
2012  {
2013  if (!IsFriendlyTo(u))
2014  return false;
2015  }
2016 
2017  // skip non hostile to caster enemy creatures
2018  if (!IsHostileTo(enemy))
2019  return false;
2020 
2021  return true;
2022 }
2023 
2024 // use this function to avoid having hostile creatures attack
2025 // friendlies and other mobs they shouldn't attack
2026 bool Creature::_IsTargetAcceptable(Unit const* target) const
2027 {
2028  ASSERT(target);
2029 
2030  // if the target cannot be attacked, the target is not acceptable
2031  if (IsFriendlyTo(target)
2032  || !target->isTargetableForAttack(false))
2033  return false;
2034 
2035  if (target->HasUnitState(UNIT_STATE_DIED))
2036  {
2037  // guards can detect fake death
2039  return true;
2040  else
2041  return false;
2042  }
2043 
2044  Unit const* targetVictim = target->getAttackerForHelper();
2045 
2046  // if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
2047  if (IsInCombatWith(target) || IsHostileTo(target))
2048  return true;
2049 
2050  // if the target's victim is friendly, and the target is neutral, the target is acceptable
2051  if (targetVictim && IsFriendlyTo(targetVictim))
2052  return true;
2053 
2054  // if the target's victim is not friendly, or the target is friendly, the target is not acceptable
2055  return false;
2056 }
2057 
2059 {
2061  return;
2062 
2063  sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
2064 }
2065 
2066 bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const
2067 {
2068  if (!victim)
2069  return false;
2070 
2071  if (!victim->IsInMap(this))
2072  return false;
2073 
2074  if (!IsValidAttackTarget(victim))
2075  return false;
2076 
2077  if (!victim->isInAccessiblePlaceFor(this))
2078  return false;
2079 
2080  if (IsAIEnabled && !AI()->CanAIAttack(victim))
2081  return false;
2082 
2083  // we cannot attack in evade mode
2084  if (IsInEvadeMode())
2085  return false;
2086 
2087  // or if enemy is in evade mode
2088  if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
2089  return false;
2090 
2091  if (GetMap()->IsDungeon())
2092  return true;
2093 
2094  if (Unit* u = GetCharmerOrOwner())
2095  {
2096  if (u->GetTypeId() != TYPEID_PLAYER)
2097  {
2098  // don't check distance to home position if recently damaged, this should include taunt auras
2100  return true;
2101  }
2102  }
2103 
2104  // Get the correct threat range from the config.
2105  float dist = std::max<float>(GetAttackDistance(victim), sWorld.getConfig(CONFIG_THREAT_RADIUS) + m_CombatDistance);
2106 
2107  if (Unit* unit = GetCharmerOrOwner())
2108  return victim->IsWithinDist(unit, dist);
2109  else
2110  {
2111  // include sizes for huge npcs
2112  dist += GetObjectSize() + victim->GetObjectSize();
2113 
2114  // to prevent creatures in air ignore attacks because distance is already too high...
2115  if (GetCreatureTemplate()->InhabitType & INHABIT_AIR)
2116  return victim->IsInDist2d(&m_homePosition, dist);
2117  else
2118  return victim->IsInDist(&m_homePosition, dist);
2119  }
2120 }
2121 
2123 {
2124  if (m_DBTableGuid)
2125  {
2127  return addon;
2128  }
2129 
2130  // dependent from heroic mode entry
2132 }
2133 
2134 //creature_addon table
2136 {
2137  CreatureDataAddon const* cainfo = GetCreatureAddon();
2138  if (!cainfo)
2139  return false;
2140 
2141  if (cainfo->mount != 0)
2142  Mount(cainfo->mount);
2143 
2144  if (cainfo->bytes1 != 0)
2146 
2147  // Sheath State
2149 
2150  if (cainfo->emote != 0)
2152 
2153  // Check if visibility distance different
2154  if (cainfo->visibilityDistanceType != VISDIST_DEFAULT)
2156 
2157  // Load Path
2158  if (cainfo->path_id != 0)
2159  m_path_id = cainfo->path_id;
2160 
2161  if (cainfo->auras)
2162  {
2163  for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura)
2164  {
2165  SpellEntry const* AdditionalSpellInfo = sSpellStore.LookupEntry(cAura->spell_id);
2166  if (!AdditionalSpellInfo)
2167  {
2168  sLog.outErrorDb("Creature (GUIDLow: %u Entry: %u) has wrong spell %u defined in auras field.", GetGUIDLow(), GetEntry(), cAura->spell_id);
2169  continue;
2170  }
2171 
2172  // skip already applied aura
2173  if (HasAura(cAura->spell_id, cAura->effect_idx))
2174  {
2175  if (!reload)
2176  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);
2177 
2178  continue;
2179  }
2180 
2181  Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0);
2182  AddAura(AdditionalAura);
2183  sLog.outDebug("Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u)", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[0], GetGUIDLow(), GetEntry());
2184  }
2185  }
2186  return true;
2187 }
2188 
2189 // Send a message to LocalDefense channel for players opposition team in the zone
2191 {
2192  uint32 enemy_team = attacker->GetTeam();
2193 
2195  data << (uint32)GetZoneId();
2196  sWorld.SendGlobalMessage(&data, NULL, (enemy_team == ALLIANCE ? HORDE : ALLIANCE));
2197 }
2198 
2200 {
2201  if (!CanHaveThreatList())
2202  {
2203  sLog.outError("Creature entry %u call SetInCombatWithZone but creature cannot have threat list.", GetEntry());
2204  return;
2205  }
2206 
2207  Map* pMap = GetMap();
2208 
2209  if (!pMap->IsDungeon())
2210  {
2211  sLog.outError("Creature entry %u call SetInCombatWithZone for map (id: %u) that isn't an instance.", GetEntry(), pMap->GetId());
2212  return;
2213  }
2214 
2215  Map::PlayerList const& PlList = pMap->GetPlayers();
2216 
2217  if (PlList.isEmpty())
2218  return;
2219 
2220  for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
2221  {
2222  if (Player* pPlayer = i->GetSource())
2223  {
2224  if (pPlayer->IsGameMaster())
2225  continue;
2226 
2227  if (pPlayer->IsAlive())
2228  {
2229  pPlayer->SetInCombatWith(this);
2230  AddThreat(pPlayer, 0.0f);
2231  }
2232  }
2233  }
2234 }
2235 
2236 void Creature::_AddCreatureSpellCooldown(uint32 spell_id, time_t end_time)
2237 {
2238  m_CreatureSpellCooldowns[spell_id] = end_time;
2239 }
2240 
2241 void Creature::_AddCreatureCategoryCooldown(uint32 category, time_t end_time)
2242 {
2243  m_CreatureCategoryCooldowns[category] = end_time;
2244 }
2245 
2247 {
2248  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
2249  if (!spellInfo)
2250  return;
2251 
2252  uint32 cooldown = GetSpellRecoveryTime(spellInfo);
2253  if (Player* modOwner = GetSpellModOwner())
2254  modOwner->ApplySpellMod(spellid, SPELLMOD_COOLDOWN, cooldown);
2255 
2256  if (cooldown)
2257  _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown / IN_MILLISECONDS);
2258 
2259  if (spellInfo->Category)
2260  _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL));
2261 
2262  m_GlobalCooldown = spellInfo->StartRecoveryTime;
2263 
2264  if (Unit* owner = GetCharmerOrOwner())
2265  if (owner->GetTypeId() == TYPEID_PLAYER)
2266  {
2267  WorldPacket data(SMSG_SPELL_COOLDOWN, (4 + 8));
2268  data << uint64(GetGUID());
2269  data << uint8(0x0); // flags (0x1, 0x2)
2270  data << uint32(spellid);
2271  data << uint32(cooldown); // in m.secs
2272 
2273  owner->ToPlayer()->GetSession()->SendPacket(&data);
2274  }
2275 }
2276 
2278 {
2279  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);
2280  if (!spellInfo)
2281  return false;
2282 
2283  // check global cooldown if spell affected by it
2284  if (spellInfo->StartRecoveryCategory > 0 && m_GlobalCooldown > 0)
2285  return true;
2286 
2287  CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category);
2288  return (itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL));
2289 }
2290 
2292 {
2293  CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id);
2294  return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id);
2295 }
2296 
2298 {
2300 }
2301 
2302 bool Creature::HasSpell(uint32 spellID) const
2303 {
2304  uint8 i;
2305  for (i = 0; i < CREATURE_MAX_SPELLS; ++i)
2306  if (spellID == m_spells[i])
2307  break;
2308  return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells
2309 }
2310 
2312 {
2313  time_t now = time(NULL);
2314  if (m_respawnTime > now)
2315  return m_respawnTime;
2316  else
2317  return now;
2318 }
2319 
2320 void Creature::GetRespawnPosition(float& x, float& y, float& z, float* ori, float* dist) const
2321 {
2322  if (m_DBTableGuid)
2323  {
2324  if (CreatureData const* data = sObjectMgr.GetCreatureData(GetDBTableGUIDLow()))
2325  {
2326  x = data->posX;
2327  y = data->posY;
2328  z = data->posZ;
2329  if (ori)
2330  *ori = data->orientation;
2331  if (dist)
2332  *dist = data->spawndist;
2333 
2334  return;
2335  }
2336  }
2337 
2338  x = GetPositionX();
2339  y = GetPositionY();
2340  z = GetPositionZ();
2341  if (ori)
2342  *ori = GetOrientation();
2343  if (dist)
2344  *dist = 0;
2345 }
2346 
2348 {
2349  if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
2352 
2353  time_t now = time(NULL);
2354  // Do not reset corpse remove time if corpse is already removed
2355  if (m_corpseRemoveTime <= now)
2356  return;
2357 
2358  float decayRate = sWorld.getRate(RATE_CORPSE_DECAY_LOOTED);
2359 
2360  // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
2361  if (loot.loot_type == LOOT_SKINNING)
2362  m_corpseRemoveTime = now;
2363  else
2364  m_corpseRemoveTime = now + uint32(m_corpseDelay * decayRate);
2365 
2367 }
2368 
2370 {
2371  if (!isWorldBoss() || !target->ToUnit())
2372  return Unit::getLevelForTarget(target);
2373 
2374  uint16 level = target->ToUnit()->getLevel() + sWorld.getConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF);
2375  if (level < 1)
2376  return 1;
2377  if (level > 255)
2378  return 255;
2379  return uint8(level);
2380 }
2381 
2382 std::string Creature::GetAIName() const
2383 {
2384  return sObjectMgr.GetCreatureTemplate(GetEntry())->AIName;
2385 }
2386 
2388 {
2389  return sObjectMgr.GetScriptName(GetScriptId());
2390 }
2391 
2393 {
2395 }
2396 
2398 {
2399  return sObjectMgr.GetNpcVendorItemList(GetEntry());
2400 }
2401 
2403 {
2404  if (!vItem->maxcount)
2405  return vItem->maxcount;
2406 
2407  VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
2408  for (; itr != m_vendorItemCounts.end(); ++itr)
2409  if (itr->itemId == vItem->item)
2410  break;
2411 
2412  if (itr == m_vendorItemCounts.end())
2413  return vItem->maxcount;
2414 
2415  VendorItemCount* vCount = &*itr;
2416 
2417  time_t ptime = time(NULL);
2418 
2419  if (vCount->lastIncrementTime + vItem->incrtime <= uint32(ptime))
2420  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(vItem->item))
2421  {
2422  uint32 diff = uint32((ptime - vCount->lastIncrementTime) / vItem->incrtime);
2423  if ((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount)
2424  {
2425  m_vendorItemCounts.erase(itr);
2426  return vItem->maxcount;
2427  }
2428 
2429  vCount->count += diff * pProto->BuyCount;
2430  vCount->lastIncrementTime = ptime;
2431  }
2432 
2433  return vCount->count;
2434 }
2435 
2437 {
2438  if (!vItem->maxcount)
2439  return 0;
2440 
2441  VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
2442  for (; itr != m_vendorItemCounts.end(); ++itr)
2443  if (itr->itemId == vItem->item)
2444  break;
2445 
2446  if (itr == m_vendorItemCounts.end())
2447  {
2448  uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount - used_count : 0;
2449  m_vendorItemCounts.push_back(VendorItemCount(vItem->item, new_count));
2450  return new_count;
2451  }
2452 
2453  VendorItemCount* vCount = &*itr;
2454 
2455  time_t ptime = time(NULL);
2456 
2457  if (vCount->lastIncrementTime + vItem->incrtime <= uint32(ptime))
2458  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(vItem->item))
2459  {
2460  uint32 diff = uint32((ptime - vCount->lastIncrementTime) / vItem->incrtime);
2461  if ((vCount->count + diff * pProto->BuyCount) < vItem->maxcount)
2462  vCount->count += diff * pProto->BuyCount;
2463  else
2464  vCount->count = vItem->maxcount;
2465  }
2466 
2467  vCount->count = vCount->count > used_count ? vCount->count - used_count : 0;
2468  vCount->lastIncrementTime = ptime;
2469  return vCount->count;
2470 }
2471 
2473 {
2474  return sObjectMgr.GetNpcTrainerSpells(GetEntry());
2475 }
2476 
2477 // overwrite WorldObject function for proper name localization
2478 const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const
2479 {
2480  if (loc_idx >= 0)
2481  {
2482  CreatureLocale const* cl = sObjectMgr.GetCreatureLocale(GetEntry());
2483  if (cl)
2484  {
2485  if (cl->Name.size() > uint32(loc_idx) && !cl->Name[loc_idx].empty())
2486  return cl->Name[loc_idx].c_str();
2487  }
2488  }
2489 
2490  return GetName();
2491 }
2492 
2494 {
2495  if (!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master
2496  return NULL;
2497 
2498  if (uint32 targetGuid = sObjectMgr.GetLinkedRespawnGuid(m_DBTableGuid))
2499  return sObjectMgr.GetCreatureData(targetGuid);
2500 
2501  return NULL;
2502 }
2503 
2504 // returns master's remaining respawn time if any
2506 {
2507  if (!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master
2508  return 0;
2509 
2510  if (uint32 targetGuid = sObjectMgr.GetLinkedRespawnGuid(m_DBTableGuid))
2511  {
2512  Map* targetMap = NULL;
2513  if (const CreatureData* data = sObjectMgr.GetCreatureData(targetGuid))
2514  {
2515  if (data->mapid == GetMapId()) // look up on the same map
2516  targetMap = GetMap();
2517  else // it shouldn't be instanceable map here
2518  targetMap = MapManager::Instance().FindMap(data->mapid);
2519  }
2520  if (targetMap)
2521  return sObjectMgr.GetCreatureRespawnTime(targetGuid, targetMap->GetInstanceId());
2522  }
2523 
2524  return 0;
2525 }
2526 
2527 bool Creature::SetWalk(bool enable)
2528 {
2529  if (!Unit::SetWalk(enable))
2530  return false;
2531 
2533  data << GetPackGUID();
2534  SendMessageToSet(&data, false);
2535  return true;
2536 }
2537 
2538 bool Creature::SetSwim(bool enable)
2539 {
2540  if (!Unit::SetSwim(enable))
2541  return false;
2542 
2543  if (!movespline->Initialized())
2544  return true;
2545 
2547  data << GetPackGUID();
2548  SendMessageToSet(&data, true);
2549  return true;
2550 }
2551 
2552 bool Creature::SetCanFly(bool enable, bool /*packetOnly = false */)
2553 {
2554  if (!Unit::SetCanFly(enable))
2555  return false;
2556 
2557  if (!movespline->Initialized())
2558  return true;
2559 
2561  data << GetPackGUID();
2562  SendMessageToSet(&data, false);
2563  return true;
2564 }
2565 
2566 bool Creature::SetWaterWalking(bool enable, bool packetOnly /* = false */)
2567 {
2568  if (!packetOnly && !Unit::SetWaterWalking(enable))
2569  return false;
2570 
2571  if (!movespline->Initialized())
2572  return true;
2573 
2575  data << GetPackGUID();
2576  SendMessageToSet(&data, true);
2577  return true;
2578 }
2579 
2580 bool Creature::SetFeatherFall(bool enable, bool packetOnly /* = false */)
2581 {
2582  if (!packetOnly && !Unit::SetFeatherFall(enable))
2583  return false;
2584 
2585  if (!movespline->Initialized())
2586  return true;
2587 
2589  data << GetPackGUID();
2590  SendMessageToSet(&data, true);
2591  return true;
2592 }
2593 
2594 bool Creature::SetHover(bool enable, bool packetOnly /*= false*/)
2595 {
2596  if (!packetOnly && !Unit::SetHover(enable))
2597  return false;
2598 
2599  if (!movespline->Initialized())
2600  return true;
2601 
2603  data << GetPackGUID();
2604  SendMessageToSet(&data, false);
2605  return true;
2606 }
2607 
2608 bool Creature::SetLevitate(bool apply, bool packetOnly)
2609 {
2610  if (!packetOnly && !Unit::SetLevitate(apply))
2611  return false;
2612 
2613  if (!movespline->Initialized())
2614  return true;
2615 
2617  data << GetPackGUID();
2618  SendMessageToSet(&data, true);
2619  return true;
2620 }
2621 
2622 void Creature::UpdateMovementFlags(bool packetOnly)
2623 {
2625  return;
2626 
2627  // Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
2628  float ground = GetMap()->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ());
2629 
2630  if (ground < INVALID_HEIGHT)
2631  {
2632  sLog.outDebug("FallGround: creature %u at map %u (x: %f, y: %f, z: %f), not able to retrive a proper GetHeight (z: %f).",
2633  GetEntry(), GetMap()->GetId(), GetPositionX(), GetPositionX(), GetPositionZ(), ground);
2634  return;
2635  }
2636 
2637  bool isInAir = (G3D::fuzzyGt(GetPositionZ(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZ(), ground - 0.05f)); // Can be underground too, prevent the falling
2638 
2639  if (GetCreatureTemplate()->InhabitType & INHABIT_AIR && isInAir && !IsFalling())
2640  SetLevitate(true, packetOnly);
2641  else
2642  SetLevitate(false);
2643 
2644  if (!isInAir)
2646 
2647  SetSwim(CanSwim() && GetBaseMap()->IsSwimmable(GetPositionX(), GetPositionY(), GetPositionZ()));
2648 }
2649 
2651 {
2653 }
2654 
2656 {
2657  CreatureTextRepeatIds& repeats = m_textRepeat[textGroup];
2658  if (std::find(repeats.begin(), repeats.end(), id) == repeats.end())
2659  repeats.push_back(id);
2660  else
2661  sLog.outError("CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), GetName(), GetGUIDLow(), GetEntry(), uint32(id));
2662 }
2663 
2665 {
2667 
2668  CreatureTextRepeatGroup::const_iterator groupItr = m_textRepeat.find(textGroup);
2669  if (groupItr != m_textRepeat.end())
2670  ids = groupItr->second;
2671 
2672  return ids;
2673 }
2674 
2676 {
2677  CreatureTextRepeatGroup::iterator groupItr = m_textRepeat.find(textGroup);
2678  if (groupItr != m_textRepeat.end())
2679  groupItr->second.clear();
2680 }
2681 
2682 
2683 float Creature::GetAggroRange(Unit const* target) const
2684 {
2685  // Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
2686  // Based on data from wowwiki due to lack of 3.3.5a data
2687 
2688  if (target && this->IsPet())
2689  {
2690  uint32 targetLevel = 0;
2691 
2692  if (target->GetTypeId() == TYPEID_PLAYER)
2693  targetLevel = target->getLevelForTarget(this);
2694  else if (target->GetTypeId() == TYPEID_UNIT)
2695  targetLevel = target->ToCreature()->getLevelForTarget(this);
2696 
2697  uint32 myLevel = getLevelForTarget(target);
2698  int32 levelDiff = int32(targetLevel) - int32(myLevel);
2699 
2700  // The maximum Aggro Radius is capped at 45 yards (25 level difference)
2701  if (levelDiff < -25)
2702  levelDiff = -25;
2703 
2704  // The base aggro radius for mob of same level
2705  float aggroRadius = 20;
2706 
2707  // Aggro Radius varies with level difference at a rate of roughly 1 yard/level
2708  aggroRadius -= (float)levelDiff;
2709 
2710  // detect range auras
2712 
2713  // detected range auras
2714  aggroRadius += target->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE);
2715 
2716  // Just in case, we don't want pets running all over the map
2717  if (aggroRadius > MAX_AGGRO_RADIUS)
2718  aggroRadius = MAX_AGGRO_RADIUS;
2719 
2720  // Minimum Aggro Radius for a mob seems to be combat range (5 yards)
2721  // hunter pets seem to ignore minimum aggro radius so we'll default it a little higher
2722  if (aggroRadius < 10)
2723  aggroRadius = 10;
2724 
2725  return (aggroRadius);
2726  }
2727 
2728  // Default
2729  return 0.0f;
2730 }
2731 
2733 {
2734  // Selects nearest hostile target within creature's aggro range. Used primarily by
2735  // pets set to aggressive. Will not return neutral or friendly targets.
2736 
2737  Unit* target = NULL;
2738 
2739  {
2740  Oregon::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS);
2742 
2744  }
2745 
2746  return target;
2747 }
2749 {
2750  float newSpeed = speed;
2751  if (m_creatureInfo->speed_walk) // Creature template should still override
2752  newSpeed = m_creatureInfo->speed_walk;
2753 
2754  if (newSpeed != m_baseSpeedWalk)
2755  {
2756  m_baseSpeedWalk = newSpeed;
2757  UpdateSpeed(MOVE_WALK, false);
2758  }
2759 }
2760 
2761 void Creature::SetBaseRunSpeed(float speed)
2762 {
2763  float newSpeed = speed;
2764  if (m_creatureInfo->speed_run) // Creature template should still override
2765  newSpeed = m_creatureInfo->speed_run;
2766 
2767  if (newSpeed != m_baseSpeedWalk)
2768  {
2769  m_baseSpeedRun = newSpeed;
2770  UpdateSpeed(MOVE_RUN, false);
2771  }
2772 }
uint32 GetCurrentEquipmentId()
Definition: Creature.h:556
void RemoveFromWorld() override
Definition: Unit.cpp:11170
bool IsImmuneToSpellEffect(SpellEntry const *spellInfo, uint32 index, bool castOnSelf) const override
Definition: Creature.cpp:1732
uint32 m_corpseDelay
Definition: Creature.h:835
uint32 Category
Definition: DBCStructure.h:675
int32 ModifyPower(Powers power, int32 val)
Definition: Unit.cpp:9839
uint32 UpdateVendorItemCurrentCount(VendorItem const *vItem, uint32 used_count)
Definition: Creature.cpp:2436
uint32 maxlevel
Definition: Creature.h:143
void SetTextRepeatId(uint8 textGroup, uint8 id)
Definition: Creature.cpp:2655
time_t GetLastDamagedTime() const
Definition: Unit.h:1998
bool SetWalk(bool enable) override
Definition: Creature.cpp:2527
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition: Map.cpp:734
void DespawnOrUnsummon(uint32 msTimeToDespawn=0)
Definition: Creature.cpp:1713
#define ATTACK_DISTANCE
Definition: Object.h:36
float GetSpellDamageMod(int32 Rank) const
Definition: Creature.cpp:1249
Group * GetGroup()
Definition: Player.h:2577
int32 resistance3
Definition: Creature.h:176
EventProcessor m_Events
Definition: Unit.h:1636
void SetBaseRunSpeed(float speed) override
Definition: Creature.cpp:2761
void SetRespawnTime(uint32 respawn)
Definition: Creature.h:665
uint32 npcflag
Definition: Creature.h:151
bool LoadCreatureFromDB(uint32 guid, Map *map, bool addToMap=true)
Definition: Creature.cpp:1295
virtual bool IsImmuneToSpell(SpellEntry const *spellInfo, bool useCharges=false)
Definition: Unit.cpp:8979
virtual void OnCreatureDeath(Creature *)
Definition: ZoneScript.h:46
const CreatureData * GetLinkedRespawnCreatureData() const
Definition: Creature.cpp:2493
uint32 EffectMechanic[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:730
Definition: Unit.h:440
uint32 InventoryType
const uint32 & GetUInt32Value(uint16 index) const
Definition: Object.h:210
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:3812
bool IsFlying() const
Definition: Unit.h:1976
CreatureData const * m_creatureData
Definition: Creature.h:862
virtual bool SetCanFly(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13766
float ModMana
Definition: Creature.h:188
float ModArmor
Definition: Creature.h:189
void Mount(uint32 mount, uint32 spellId=0)
Definition: Unit.cpp:9305
uint8 getLevelForTarget(WorldObject const *) const override
Definition: Unit.h:1058
Position m_homePosition
Definition: Creature.h:858
void SetTarget(uint64 guid=0)
Definition: Unit.h:1591
uint32 GetMaxHealth() const
Definition: Unit.h:1075
void AddToWorld() override
Definition: Creature.cpp:181
uint32 maxcount
Definition: Creature.h:360
bool SetCanFly(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2552
bool IsSpiritHealer() const
Definition: Unit.h:1223
uint32 rank
Definition: Creature.h:155
PlayerMenu * PlayerTalkClass
Definition: Player.h:2182
void UpdateMovementFlags(bool packetOnly=false)
Definition: Creature.cpp:2622
Unit * SelectNearestTargetInAttackDistance(float dist=0) const
Definition: Creature.cpp:1882
Map * GetMap() const
Definition: Object.h:817
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
bool m_isTempWorldObject
Definition: Creature.h:811
uint8 spawnMask
Definition: Creature.h:289
uint8 movementType
Definition: Creature.h:288
uint32 spells[CREATURE_MAX_SPELLS]
Definition: Creature.h:180
uint32 GetFaction() const
Definition: Unit.h:1116
int32 resistance6
Definition: Creature.h:179
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData *data=NULL)
Definition: Creature.cpp:260
void SetNoCallAssistance(bool val)
Definition: Creature.h:630
bool IsTrainerOf(Player *player, bool msg) const
Definition: Creature.cpp:826
void ClearMenus()
Definition: GossipDef.cpp:118
uint32 GetDBTableGUIDLow() const
Definition: Creature.h:484
uint32 id
Definition: Creature.h:274
bool BeginTransaction()
Definition: Database.cpp:533
char * Name
Definition: Creature.h:138
void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value)
Definition: Unit.h:1640
uint32 displayid
Definition: Creature.h:277
pet will not attack
Definition: Unit.h:760
bool RemoveItem(uint32 item_id)
Definition: Creature.cpp:64
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:3700
void SetAttackTime(WeaponAttackType att, uint32 val)
Definition: Unit.h:1108
void AddThreat(Unit *victim, float threat, SpellSchoolMask schoolMask=SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell=NULL)
Definition: Unit.cpp:10243
uint32 modelid4
Definition: Creature.h:137
void SendZoneUnderAttackMessage(Player *attacker)
Definition: Creature.cpp:2190
SpellSchools
bool CanTrainAndResetTalentsOf(Player *pPlayer) const
Definition: Creature.cpp:986
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
const char * GetNameForLocaleIdx(int32 locale_idx) const override
Definition: Creature.cpp:2478
time_t m_respawnTime
Definition: Creature.h:833
float BaseMeleeAttackPower
Definition: Creature.h:233
void InitializeReactState()
Definition: Creature.cpp:818
void SetObjectScale(float scale)
Definition: Object.h:190
AiReaction
bool IsUnderLastManaUseEffect() const
Definition: Unit.cpp:12354
#define CREATURE_Z_ATTACK_RANGE
Definition: Creature.h:459
Unit * SelectNearestTarget(float dist=0, bool playerOnly=false) const
Definition: Creature.cpp:1859
Movement::MoveSpline * movespline
Definition: Unit.h:1910
void setActive(bool isActiveObject)
Definition: Object.cpp:1122
void UpdateSpeed(UnitMoveType mtype, bool forced)
Definition: Unit.cpp:9920
uint32 curhealth
Definition: Creature.h:286
bool IsPvP() const
Definition: Unit.h:1139
bool HasSpellCooldown(uint32 spell_id) const
Definition: Creature.cpp:2291
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition: Object.h:809
bool IsBattleMaster() const
Definition: Unit.h:1220
uint64 lootingGroupLeaderGUID
Definition: Object.h:888
MotionMaster * GetMotionMaster()
Definition: Unit.h:1893
uint32 GetZoneId() const
Definition: Object.cpp:1202
uint32 race
Definition: Creature.h:168
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
bool IsInCombat() const
Definition: Unit.h:1243
bool m_AlreadyCallAssistance
Definition: Creature.h:850
std::vector< uint8 > CreatureTextRepeatIds
Definition: Creature.h:464
TrainerSpellData const * GetTrainerSpells() const
Definition: Creature.cpp:2472
bool CanFly() const
Definition: Creature.h:501
virtual void SetMap(Map *map)
Definition: Object.cpp:1981
Loot loot
Definition: Creature.h:595
uint32 curmana
Definition: Creature.h:287
uint32 getMSTime()
Definition: Timer.h:32
bool IsValidAttackTarget(Unit const *target) const
Definition: Unit.cpp:9545
bool SetSwim(bool enable) override
Definition: Creature.cpp:2538
void SetCreateHealth(uint32 val)
Definition: Unit.h:1546
Definition: Unit.h:437
bool hasPlayerDamaged
Definition: Creature.h:792
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:1591
void SetValue(FLAG_TYPE flag, T_VALUES value)
Definition: Object.h:602
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:165
virtual void SaveToDB()
Definition: Creature.cpp:1045
void SetCanModifyStats(bool modifyStats)
Definition: Unit.h:1654
MovementGeneratorType GetDefaultMovementType() const
Definition: Creature.h:636
CreatureData const * GetCreatureData() const
Definition: Creature.h:566
virtual void JustRespawned()
Definition: CreatureAI.h:139
void AddToWorld() override
Definition: Unit.cpp:11164
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:777
ACE_INT32 int32
Definition: Define.h:67
bool IsWithinLOSInMap(const WorldObject *obj) const
Definition: Object.cpp:1252
TrainerSpellList spellList
Definition: Creature.h:426
uint32 GetNativeDisplayId()
Definition: Unit.h:1787
void UpdateObjectVisibility(bool forced=true) override
Definition: Unit.cpp:13580
std::list< Aura * > AuraList
Definition: Unit.h:917
bool HasReactState(ReactStates state) const
Definition: Creature.h:505
bool IsInEvadeMode() const
Definition: Creature.cpp:2297
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:727
NULL Dbg ErrDB Arena Chat Char Map MMap false
Definition: Log.cpp:556
int32 ModifyHealth(int32 val)
Definition: Unit.cpp:9771
static CreatureDataAddon const * GetCreatureAddon(uint32 lowguid)
Definition: ObjectMgr.h:638
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
Definition: Unit.cpp:9244
SpellEntry const * reachWithSpellAttack(Unit *pVictim)
Definition: Creature.cpp:1760
void UpdateCharmAI()
Definition: Unit.cpp:11229
bool IsTrigger() const
Definition: Creature.h:497
float spawndist
Definition: Creature.h:284
bool IsDungeon() const
Definition: Map.h:427
bool HasSearchedAssistance() const
Definition: Creature.h:632
VirtualItemSlot
Definition: Creature.h:434
Creature * getLeader() const
void SetNativeDisplayId(uint32 modelId)
Definition: Unit.h:1791
void SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const
Definition: GossipDef.cpp:124
bool IsInvisibleDueToDespawn() const override
Definition: Creature.cpp:1475
bool SetHover(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2594
void SetNoCreate()
Definition: Cell.h:76
void AddAssistant(const uint64 &guid)
Definition: Creature.h:890
float m_baseSpeedRun
Definition: Unit.h:2076
void MoveFall(float z=0, uint32 id=0)
bool Initialized() const
Definition: MoveSpline.h:94
virtual bool CanAIAttack(const Unit *) const
Definition: UnitAI.h:49
uint32 GetGUIDLow() const
Definition: Object.h:178
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
MovementGeneratorType m_defaultMovementType
Definition: Creature.h:845
void SetEntry(uint32 entry)
Definition: Object.h:187
uint32 dynamicflags
Definition: Creature.h:163
uint64 CalculateTime(uint64 t_offset)
Definition: Unit.h:439
bool UpdateAllStats() override
Definition: StatSystem.cpp:765
uint64 LastCharmerGUID
Definition: Unit.h:1994
void AddAura(uint32 spellId, Unit *target)
Definition: Unit.cpp:13518
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:10721
bool dbData
Definition: Creature.h:293
uint32 minlevel
Definition: Creature.h:142
void AllLootRemovedFromCorpse()
Definition: Creature.cpp:2347
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:983
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:2236
static ItemTemplate const * GetItemTemplate(uint32 id)
Definition: ObjectMgr.h:648
iterator begin()
Definition: MapRefManager.h:48
void apply(T *val)
Definition: ByteConverter.h:41
bool IsAIEnabled
Definition: Unit.h:1993
bool CanSwim() const
Definition: Creature.h:500
#define sObjectMgr
Definition: ObjectMgr.h:1317
CreatureTextRepeatGroup m_textRepeat
Definition: Creature.h:881
bool CommitTransaction()
Definition: Database.cpp:551
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition: Object.h:765
time_t _pickpocketLootRestore
Timers.
Definition: Creature.h:831
bool CanAssistTo(const Unit *u, const Unit *enemy, bool checkfaction=true) const
Definition: Creature.cpp:1977
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
bool canStartAttack(Unit const *u, bool force) const
Definition: Creature.cpp:1494
virtual void DeleteFromDB()
Definition: Creature.cpp:1456
time_t GetLinkedCreatureRespawnTime() const
Definition: Creature.cpp:2505
void ForcedDespawn(uint32 timeMSToDespawn=0)
Definition: Creature.cpp:1697
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:885
uint32 m_combatPulseDelay
Definition: Creature.h:838
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition: Object.h:750
Definition: Common.h:181
uint32 GetPower(Powers power) const
Definition: Unit.h:1096
virtual bool SetSwim(bool enable)
Definition: Unit.cpp:13753
float posX
Definition: Creature.h:279
UnitAI * i_AI
Definition: Unit.h:2007
uint8 getLevel() const
Definition: Unit.h:1057
void SetLootRecipient(Unit *unit)
Definition: Creature.cpp:1007
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3744
uint32 flags_extra
Definition: Creature.h:195
virtual void OnCreatureCreate(Creature *, bool)
Definition: ZoneScript.h:44
void InitDefault()
uint64 GetCharmerOrOwnerGUID() const
Definition: Unit.h:1387
virtual bool IsInvisibleDueToDespawn() const
Definition: Object.h:794
float m_baseSpeedWalk
Definition: Unit.h:2075
TempSummon * ToTempSummon()
Definition: Unit.h:2001
void CallAssistance()
Definition: Creature.cpp:1920
bool CanAlwaysSee(WorldObject const *obj) const override
Definition: Creature.cpp:1486
Definition: Common.h:179
bool IsSpiritGuide() const
Definition: Unit.h:1224
float m_respawnradius
Definition: Creature.h:836
uint32 GetId(void) const
Definition: Map.h:333
virtual void InitializeAI()
Definition: UnitAI.h:56
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition: Object.h:746
uint64 GetGUID() const
Definition: Object.h:177
void ClearUnitState(uint32 f)
Definition: Unit.h:1034
Powers getPowerType() const
Definition: Unit.h:1094
void DoFleeToGetAssistance()
Definition: Creature.cpp:707
bool _IsTargetAcceptable(const Unit *target) const
Definition: Creature.cpp:2026
uint8 GetTypeId() const
Definition: Object.h:192
time_t GetRespawnTimeEx() const
Definition: Creature.cpp:2311
uint32 spawntimesecs
Definition: Creature.h:283
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
Definition: Object.cpp:125
virtual bool SetHover(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13808
uint32 m_lootRecipientGroup
Definition: Creature.h:827
uint32 unit_class
Definition: Creature.h:161
void SetMeleeDamageSchool(SpellSchools school)
Definition: Creature.h:533
uint32 m_corpseRemoveTime
Definition: Creature.h:832
uint32 m_spells[CREATURE_MAX_SPELLS]
Definition: Creature.h:612
bool SetLevitate(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2608
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1097
float GetOrientation() const
Definition: Position.h:100
void setDeathState(DeathState s) override
Definition: Creature.cpp:1570
#define UI64FMTD
Definition: Common.h:149
int32 resistance4
Definition: Creature.h:177
static CreatureDataAddon const * GetCreatureTemplateAddon(uint32 entry)
Definition: ObjectMgr.h:643
void Relocate(float x, float y)
Definition: Position.h:65
uint32 DisplayInfoID
void SetControlled(bool apply, UnitState state)
Definition: Unit.cpp:12927
CreatureGroup * m_formation
Definition: Creature.h:875
const bool & IsInWorld() const
Definition: Object.h:150
#define CREATURE_REGEN_INTERVAL
Definition: Creature.h:125
std::multimap< uint32, uint32 > QuestRelations
Definition: ObjectMgr.h:391
float GetAggroRange(Unit const *target) const
Definition: Creature.cpp:2683
void SetPhaseMask(uint32 newPhaseMask, bool update) override
Definition: Unit.cpp:13554
#define sPoolMgr
Definition: PoolMgr.h:162
static float _GetHealthMod(int32 Rank)
Definition: Creature.cpp:1206
uint32 m_DBTableGuid
Definition: Creature.h:847
ZoneScript * m_zoneScript
Definition: Object.h:897
uint32 GetPhaseMask() const
Definition: Object.h:670
uint32 faction
Definition: Creature.h:150
void SetDisplayId(uint32 modelId)
Definition: Unit.cpp:12010
bool IsNeutralToAll() const
Definition: Unit.cpp:7392
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
virtual void SetCanDualWield(bool value)
Definition: Unit.h:977
void MoveSeekAssistance(float x, float y, float z)
uint32 equipmentId
Definition: Creature.h:193
bool IsAlive() const
Definition: Unit.h:1336
Unit * GetVictim() const
Definition: Unit.h:1013
float posY
Definition: Creature.h:280
void SetCreateMana(uint32 val)
Definition: Unit.h:1554
float GetDistance(const WorldObject *obj) const
Definition: Object.h:694
virtual void UpdateAI(const uint32)=0
bool IsFalling() const
Definition: Unit.cpp:13722
virtual bool SetWaterWalking(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13782
float GetPositionY() const
Definition: Position.h:98
void Update(uint32 time) override
Definition: Unit.cpp:523
bool Execute(uint64 e_time, uint32 p_time) override
Definition: Creature.cpp:139
int32 resistance5
Definition: Creature.h:178
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:876
DeathState m_deathState
Definition: Unit.h:2025
CreatureAI * selectAI(Creature *creature)
CreatureAI * AI() const
Definition: Creature.h:525
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition: Object.h:810
static Player * FindPlayer(uint64, bool force=false)
bool CanInteractWithBattleMaster(Player *player, bool msg) const
Definition: Creature.cpp:957
VendorItemData const * GetVendorItems() const
Definition: Creature.cpp:2397
uint32 GetInstanceId() const
Definition: Object.h:664
etc mysql my cnf *Then change max_allowed_packet to a bigger value
uint32 m_GlobalCooldown
Definition: Creature.h:615
float GetPositionZ() const
Definition: Position.h:99
CreatureInfo const * m_creatureInfo
Definition: Creature.h:879
bool m_regenHealth
Definition: Creature.h:852
uint32 GetFirstValidModelId() const
Definition: Creature.cpp:109
bool HasCategoryCooldown(uint32 spell_id) const
Definition: Creature.cpp:2277
bool HasSpell(uint32 spellID) const override
Definition: Creature.cpp:2302
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:7374
void SetOriginalEntry(uint32 entry)
Definition: Creature.h:795
void CallForHelp(float fRadius)
Definition: Creature.cpp:1960
PackedGuid const & GetPackGUID() const
Definition: Object.h:181
virtual void CorpseRemoved(time_t)
Definition: CreatureAI.h:198
#define DEBUG_LOG(...)
Definition: Log.h:194
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data=NULL)
Definition: Creature.cpp:759
virtual bool SetFeatherFall(bool enable, bool packetOnly=false)
Definition: Unit.cpp:13795
bool m_AI_locked
Definition: Creature.h:853
SpellEntry const * reachWithSpellCure(Unit *pVictim)
Definition: Creature.cpp:1810
uint32 m_combatPulseTime
Definition: Creature.h:837
float GetSpellMinRange(SpellRangeEntry const *range)
Definition: SpellMgr.h:139
void SetVirtualItemRaw(VirtualItemSlot slot, uint32 display_id, uint32 info0, uint32 info1)
Definition: Creature.cpp:1427
float GetAttackDistance(Unit const *pl) const
Definition: Creature.cpp:1532
uint32 GetMapId() const
Definition: Object.h:567
void SetCanDualWield(bool value)
Definition: Creature.cpp:1364
void SetMaxHealth(uint32 val)
Definition: Unit.cpp:10973
bool isRegeneratingHealth()
Definition: Creature.h:709
bool Execute(uint64 e_time, uint32 p_time) override
Definition: Creature.cpp:118
VendorItemCounts m_vendorItemCounts
Definition: Creature.h:818
bool isEmpty() const
Definition: LinkedList.h:97
bool IsInMap(const WorldObject *obj) const
Definition: Object.h:721
uint32 m_originalEntry
Definition: Creature.h:856
bool NeedChangeAI
Definition: Unit.h:1993
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data=NULL)
Definition: Creature.cpp:1268
uint32 npcflag
Definition: Creature.h:290
float combat_reach
Definition: Creature.h:319
virtual void SetSheath(SheathState sheathed)
Definition: Unit.h:1113
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:13740
float ModHealth
Definition: Creature.h:187
uint32 m_path_id
Definition: Creature.h:872
bool isInAccessiblePlaceFor(Creature const *c) const
Definition: Unit.cpp:3677
CreatureSpellCooldowns m_CreatureSpellCooldowns
Definition: Creature.h:613
bool HaveLootFor(uint32 loot_id) const
Definition: LootMgr.h:184
void RemoveUnitMovementFlag(uint32 f)
Definition: Unit.h:1905
uint32 PreventionType
Definition: DBCStructure.h:764
Group * GetLootRecipientGroup() const
Definition: Creature.cpp:1000
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:1669
uint32 unit_flags
Definition: Creature.h:162
bool TriggerJustRespawned
Definition: Creature.h:877
bool hasInvolvedQuest(uint32 quest_id) const override
Definition: Creature.cpp:1445
int32 equipmentId
Definition: Creature.h:278
bool IsPet() const
Definition: Unit.h:1048
#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:680
void SetPlayerDamaged(bool set)
Definition: Creature.cpp:1225
bool RegenHealth
Definition: Creature.h:192
void RemoveObject(T *object)
bool isDying() const
Definition: Unit.h:1337
void RegenerateMana()
Definition: Creature.cpp:635
DeathState
Definition: Unit.h:435
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:1004
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:993
void Respawn(bool force=false)
Definition: Creature.cpp:1646
uint32 MovementType
Definition: Creature.h:185
void SendAIReaction(AiReaction reactionType)
Definition: Creature.cpp:1908
uint8 getRace() const
Definition: Unit.h:1060
void RegenerateHealth()
Definition: Creature.cpp:670
Definition: Unit.h:485
bool IsGuard() const
Definition: Creature.h:498
#define sGameEventMgr
Definition: GameEventMgr.h:179
uint32 m_respawnDelay
Definition: Creature.h:834
CreatureInfo const * GetCreatureTemplate() const
Definition: Creature.h:565
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1410
uint32 GetRandomValidModelId() const
Definition: Creature.cpp:96
uint32 dynamicflags
Definition: Creature.h:292
bool IsCivilian() const
Definition: Creature.h:496
MotionMaster i_motionMaster
Definition: Unit.h:2058
CreatureDataAddonAura const * auras
Definition: Creature.h:312
float BaseRangedAttackPower
Definition: Creature.h:234
int32 exp
Definition: Creature.h:144
void SelectLevel()
Definition: Creature.cpp:1147
virtual void setDeathState(DeathState s)
Definition: Unit.cpp:10149
uint64 m_lootRecipient
Definition: Creature.h:826
uint32 unit_flags
Definition: Creature.h:291
Map const * GetBaseMap() const
Definition: Object.cpp:2011
uint32 BaseArmor
Definition: Creature.h:235
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:1401
bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData *data=NULL)
Definition: Creature.cpp:348
Player * GetSpellModOwner() const
Definition: Unit.cpp:11862
virtual void UpdateDamagePhysical(WeaponAttackType attType)
Definition: StatSystem.cpp:37
uint32 RangeAttackTime
Definition: Creature.h:158
void SaveRespawnTime() override
Definition: Creature.cpp:2058
void EndRoll()
Definition: Group.cpp:761
#define CREATURE_MAX_SPELLS
Definition: Unit.h:249
bool IsTotem() const
Definition: Unit.h:1050
bool IsCritter() const
Definition: Unit.h:1237
LootType loot_type
Definition: LootMgr.h:312
bool CreatureRespawnRelocation(Creature *c)
Definition: Map.cpp:873
int32 resistance1
Definition: Creature.h:174
bool CanCreatureAttack(Unit const *victim, bool force=true) const
Definition: Creature.cpp:2066
void SetNoSearchAssistance(bool val)
Definition: Creature.h:631
Unit * GetOwner() const
Definition: Unit.cpp:7660
Creature * ToCreature()
Definition: Object.h:371
uint32 GetEquipmentId() const
Definition: Creature.h:490
void SetZoneScript()
Definition: Object.cpp:2129
float m_SightDistance
Definition: Creature.h:797
void SetBaseWalkSpeed(float speed) override
Definition: Creature.cpp:2748
void ResetPickPocketRefillTimer()
Definition: Creature.h:597
void SetFaction(uint32 faction)
Definition: Unit.h:1117
uint32 currentwaypoint
Definition: Creature.h:285
static void ChooseCreatureFlags(const CreatureInfo *cinfo, uint32 &npcflag, uint32 &unit_flags, uint32 &dynamicflags, const CreatureData *data=NULL)
Definition: ObjectMgr.cpp:1079
void CombatStart(Unit *target, bool initialAggro=true)
Definition: Unit.cpp:9386
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition: Unit.cpp:10716
void SetFloatValue(uint16 index, float value)
Definition: Object.cpp:857
bool IsPolymorphed() const
Definition: Unit.cpp:12001
bool isElite() const
Definition: Creature.cpp:1743
T AddPct(T &base, U pct)
Definition: Util.h:103
uint32 item
Definition: Creature.h:359
#define sFormationMgr
uint16 m_valuesCount
Definition: Object.h:414
uint32 m_regenTimer
Definition: Creature.h:844
uint8 getClass() const
Definition: Unit.h:1062
virtual bool SetWalk(bool enable)
Definition: Unit.cpp:13727
MovementGeneratorType
Definition: MotionMaster.h:33
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:7369
Unit * getAttackerForHelper() const
Definition: Unit.cpp:7405
uint32 GetTeam() const
Definition: Player.h:2066
void SetPvP(bool state)
Definition: Unit.h:1143
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1030
void SetName(const std::string &newname)
Definition: Object.h:684
void SetPower(Powers power, uint32 val)
Definition: Unit.cpp:11032
float orientation
Definition: Creature.h:282
uint8 getLevelForTarget(Unit const *target) const
Definition: Creature.cpp:2369
std::vector< std::string > Name
Definition: Creature.h:240
void SetInCombatWithZone()
Definition: Creature.cpp:2199
uint32 Mechanic
Definition: DBCStructure.h:678
Unit * SelectNearestHostileUnitInAggroRange(bool useLOS=false) const
Definition: Creature.cpp:2732
#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:1033
bool hasLootRecipient() const
Definition: Creature.h:603
void SearchFormation()
Definition: Creature.cpp:220
uint32 incrtime
Definition: Creature.h:361
#define ASSERT
Definition: Errors.h:29
void SetMaxPower(Powers power, uint32 val)
Definition: Unit.cpp:11065
bool CanHaveThreatList() const
Definition: Unit.cpp:10204
void Update(uint32 time) override
Definition: Creature.cpp:467
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition: Unit.cpp:10706
uint16 mapid
Definition: Creature.h:275
void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time)
Definition: Creature.cpp:2241
static Unit * GetUnit(WorldObject const &, uint64 guid)
void DestroyForNearbyPlayers()
Definition: Object.cpp:2616
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:869
#define INVALID_HEIGHT
Definition: Map.h:259
void SetLevel(uint32 lvl)
Definition: Unit.cpp:10931
uint32 InhabitType
Definition: Creature.h:186
uint32 GetEntry() const
Definition: Object.h:186
void LoadEquipment(uint32 equip_entry, bool force=false)
Definition: Creature.cpp:1370
bool LoadCreaturesAddon(bool reload=false)
Definition: Creature.cpp:2135
bool IsPositionValid() const
Definition: Position.cpp:40
static float _GetDamageMod(int32 Rank)
Definition: Creature.cpp:1230
float scale
Definition: Creature.h:154
uint32 StartRecoveryTime
Definition: DBCStructure.h:758
uint32 phaseMask
Definition: Creature.h:276
#define MELEE_RANGE
Definition: Object.h:53
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition: Creature.cpp:2402
#define sWorld
Definition: World.h:860
void SetFullHealth()
Definition: Unit.h:1091
AuraList const & GetAurasByType(AuraType type) const
Definition: Unit.h:1747
CreatureTextRepeatIds GetTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:2664
uint32 classNum
Definition: Creature.h:167
void SetVisibilityDistanceOverride(VisibilityDistanceType type)
Definition: Object.cpp:1155
float bounding_radius
Definition: Creature.h:318
void SetHealth(uint32 val)
Definition: Unit.cpp:10940
uint32 type_flags
Definition: Creature.h:170
uint32 m_equipmentId
Definition: Creature.h:848
ACE_UINT16 uint16
Definition: Define.h:72
float GetDistanceZ(const WorldObject *obj) const
Definition: Object.cpp:1218
bool isCharmed() const
Definition: Unit.h:1434
uint32 dmgschool
Definition: Creature.h:156
#define MAX_VIRTUAL_ITEM_SLOT
Definition: Creature.h:441
CreatureSpellCooldowns m_CreatureCategoryCooldowns
Definition: Creature.h:614
uint32 GetScriptId()
Definition: Creature.cpp:2392
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:7222
uint32 ScriptID
Definition: Creature.h:196
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.h:281
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:2320
ReputationRank GetReputationRank(uint32 faction_id) const
Definition: Player.cpp:5856
bool IsTrainer() const
Definition: Unit.h:1215
void Initialize()
float GetPositionX() const
Definition: Position.h:97
time_t lastIncrementTime
Definition: Creature.h:406
VisibilityDistanceType visibilityDistanceType
Definition: Creature.h:311
bool IsSummon() const
Definition: Unit.h:1046
LootStore LootTemplates_Skinning("skinning_loot_template","creature skinning id")
uint32 GetHealth() const
Definition: Unit.h:1074
bool isWorldBoss() const
Definition: Creature.cpp:1752
uint32 BaseAttackTime
Definition: Creature.h:157
true
Definition: Log.cpp:534
CreatureDataAddon const * GetCreatureAddon() const
Definition: Creature.cpp:2122
virtual void Reset()
Definition: UnitAI.h:61
bool IsInCombatWith(Unit const *who) const
Definition: Unit.cpp:501
void AddCreatureSpellCooldown(uint32 spellid)
Definition: Creature.cpp:2246
std::string GetAIName() const
Definition: Creature.cpp:2382
Definition: Unit.h:908
float m_CombatDistance
Definition: Creature.h:797
float GetObjectSize() const
Definition: Object.h:645
uint32 BaseHealth
Definition: Creature.h:230
bool GetBGAccessByLevel(uint32 bgTypeId) const
Definition: Player.cpp:19432
virtual bool IsImmuneToSpellEffect(SpellEntry const *spellInfo, uint32 index, bool castOnSelf) const
Definition: Unit.cpp:9042
bool IsImmuneToSpell(SpellEntry const *spellInfo, bool useCharges=false) override
Definition: Creature.cpp:1721
void DisappearAndDie()
Definition: Creature.cpp:212
void SetReactState(ReactStates st)
Definition: Creature.h:503
std::string GetScriptName()
Definition: Creature.cpp:2387
Definition: Player.h:923
int32 resistance2
Definition: Creature.h:175
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:887
uint32 SoundOverrideSubclass
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:9530
float GetStat(Stats stat) const
Definition: Unit.h:1066
DBCStorage< SpellRangeEntry > sSpellRangeStore(SpellRangefmt)
float posZ
Definition: Creature.h:281
Unit * ToUnit()
Definition: Object.h:374
void StartPickPocketRefillTimer()
Definition: Creature.cpp:2650
void ClearTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:2675
bool SetFeatherFall(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2580
iterator end()
Definition: MapRefManager.h:52
void SetInCombatWith(Unit *enemy)
Definition: Unit.cpp:9364
bool SetWaterWalking(bool enable, bool packetOnly=false) override
Definition: Creature.cpp:2566
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
DeathState getDeathState() const
Definition: Unit.h:1339
uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo)
Definition: SpellMgr.h:151
Definition: UnitAI.h:41
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:33
uint32 HeroicEntry
Definition: Creature.h:132
uint32 count
Definition: Creature.h:405
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:7676
bool IsSpiritService() const
Definition: Unit.h:1236
bool hasQuest(uint32 quest_id) const override
Definition: Creature.cpp:1434
bool HasAura(uint32 spellId, uint8 effIndex=0) const
Definition: Unit.h:1262
uint32 StartRecoveryCategory
Definition: DBCStructure.h:757
float GetSpellMaxRange(SpellRangeEntry const *range)
Definition: SpellMgr.h:143