TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SmartScript Class Reference

#include <SmartScript.h>

Public Types

typedef std::unordered_map
< uint32, uint32
CounterMap
 

Public Member Functions

 SmartScript ()
 
 ~SmartScript ()
 
void OnInitialize (WorldObject *obj, AreaTriggerEntry const *at=NULL)
 
void GetScript ()
 
void FillScript (SmartAIEventList e, WorldObject *obj, AreaTriggerEntry const *at)
 
void ProcessEventsFor (SMART_EVENT e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
 
void ProcessEvent (SmartScriptHolder &e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
 
bool CheckTimer (SmartScriptHolder const &e) const
 
void RecalcTimer (SmartScriptHolder &e, uint32 min, uint32 max)
 
void UpdateTimer (SmartScriptHolder &e, uint32 const diff)
 
void InitTimer (SmartScriptHolder &e)
 
void ProcessAction (SmartScriptHolder &e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
 
void ProcessTimedAction (SmartScriptHolder &e, uint32 const &min, uint32 const &max, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
 
ObjectListGetTargets (SmartScriptHolder const &e, Unit *invoker=NULL)
 
ObjectListGetWorldObjectsInDist (float dist)
 
void InstallTemplate (SmartScriptHolder const &e)
 
SmartScriptHolder CreateEvent (SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask=0)
 
void AddEvent (SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask=0)
 
void SetPathId (uint32 id)
 
uint32 GetPathId () const
 
WorldObjectGetBaseObject ()
 
bool IsUnit (WorldObject *obj)
 
bool IsPlayer (WorldObject *obj)
 
bool IsCreature (WorldObject *obj)
 
bool IsGameObject (WorldObject *obj)
 
void OnUpdate (const uint32 diff)
 
void OnMoveInLineOfSight (Unit *who)
 
UnitDoSelectLowestHpFriendly (float range, uint32 MinHPDiff)
 
void DoFindFriendlyCC (std::list< Creature * > &_list, float range)
 
void DoFindFriendlyMissingBuff (std::list< Creature * > &list, float range, uint32 spellid)
 
UnitDoFindClosestFriendlyInRange (float range, bool playerOnly)
 
void StoreTargetList (ObjectList *targets, uint32 id)
 
bool IsSmart (Creature *c=NULL)
 
bool IsSmartGO (GameObject *g=NULL)
 
ObjectListGetTargetList (uint32 id)
 
void StoreCounter (uint32 id, uint32 value, uint32 reset)
 
uint32 GetCounterId (uint32 id)
 
uint32 GetCounterValue (uint32 id)
 
GameObjectFindGameObjectNear (WorldObject *searchObject, ObjectGuid::LowType guid) const
 
CreatureFindCreatureNear (WorldObject *searchObject, ObjectGuid::LowType guid) const
 
void OnReset ()
 
void ResetBaseObject ()
 
void SetScript9 (SmartScriptHolder &e, uint32 entry)
 
UnitGetLastInvoker ()
 

Public Attributes

ObjectListMapmTargetStorage
 
ObjectGuid mLastInvoker
 
CounterMap mCounterList
 

Private Member Functions

void IncPhase (int32 p=1)
 
void DecPhase (int32 p=1)
 
bool IsInPhase (uint32 p) const
 
void SetPhase (uint32 p=0)
 
void InstallEvents ()
 
void RemoveStoredEvent (uint32 id)
 

Private Attributes

SmartAIEventList mEvents
 
SmartAIEventList mInstallEvents
 
SmartAIEventList mTimedActionList
 
bool isProcessingTimedActionList
 
Creatureme
 
ObjectGuid meOrigGUID
 
GameObjectgo
 
ObjectGuid goOrigGUID
 
AreaTriggerEntry consttrigger
 
SmartScriptType mScriptType
 
uint32 mEventPhase
 
uint32 mPathId
 
SmartAIEventList mStoredEvents
 
std::list< uint32mRemIDs
 
uint32 mTextTimer
 
uint32 mLastTextID
 
uint32 mTalkerEntry
 
bool mUseTextTimer
 
SMARTAI_TEMPLATE mTemplate
 

Member Typedef Documentation

typedef std::unordered_map<uint32, uint32> SmartScript::CounterMap

Constructor & Destructor Documentation

SmartScript::SmartScript ( )
41 {
42  go = NULL;
43  me = NULL;
44  trigger = NULL;
45  mEventPhase = 0;
46  mPathId = 0;
48  mTextTimer = 0;
49  mLastTextID = 0;
50  mUseTextTimer = false;
51  mTalkerEntry = 0;
55 }
uint32 mLastTextID
Definition: SmartScript.h:277
uint32 mEventPhase
Definition: SmartScript.h:270
Definition: SmartScriptMgr.h:1062
ObjectListMap * mTargetStorage
Definition: SmartScript.h:201
SmartScriptType mScriptType
Definition: SmartScript.h:269
AreaTriggerEntry const * trigger
Definition: SmartScript.h:268
bool isProcessingTimedActionList
Definition: SmartScript.h:263
uint32 mTextTimer
Definition: SmartScript.h:276
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: SmartScriptMgr.h:1210
SMARTAI_TEMPLATE mTemplate
Definition: SmartScript.h:281
std::unordered_map< uint32, ObjectGuidList * > ObjectListMap
Definition: SmartScriptMgr.h:1443
GameObject * go
Definition: SmartScript.h:266
uint32 mTalkerEntry
Definition: SmartScript.h:278
uint32 mPathId
Definition: SmartScript.h:272
Creature * me
Definition: SmartScript.h:264
bool mUseTextTimer
Definition: SmartScript.h:279
SmartScript::~SmartScript ( )
58 {
59  for (ObjectListMap::iterator itr = mTargetStorage->begin(); itr != mTargetStorage->end(); ++itr)
60  delete itr->second;
61 
62  delete mTargetStorage;
63  mCounterList.clear();
64 }
CounterMap mCounterList
Definition: SmartScript.h:238
ObjectListMap * mTargetStorage
Definition: SmartScript.h:201

Member Function Documentation

void SmartScript::AddEvent ( SMART_EVENT  e,
uint32  event_flags,
uint32  event_param1,
uint32  event_param2,
uint32  event_param3,
uint32  event_param4,
SMART_ACTION  action,
uint32  action_param1,
uint32  action_param2,
uint32  action_param3,
uint32  action_param4,
uint32  action_param5,
uint32  action_param6,
SMARTAI_TARGETS  t,
uint32  target_param1,
uint32  target_param2,
uint32  target_param3,
uint32  phaseMask = 0 
)
2463 {
2464  mInstallEvents.push_back(CreateEvent(e, event_flags, event_param1, event_param2, event_param3, event_param4, action, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, t, target_param1, target_param2, target_param3, phaseMask));
2465 }
SmartScriptHolder CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask=0)
Definition: SmartScript.cpp:2467
SmartAIEventList mInstallEvents
Definition: SmartScript.h:261

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SmartScript::CheckTimer ( SmartScriptHolder const e) const
3426 {
3427  return e.active;
3428 }
SmartScriptHolder SmartScript::CreateEvent ( SMART_EVENT  e,
uint32  event_flags,
uint32  event_param1,
uint32  event_param2,
uint32  event_param3,
uint32  event_param4,
SMART_ACTION  action,
uint32  action_param1,
uint32  action_param2,
uint32  action_param3,
uint32  action_param4,
uint32  action_param5,
uint32  action_param6,
SMARTAI_TARGETS  t,
uint32  target_param1,
uint32  target_param2,
uint32  target_param3,
uint32  phaseMask = 0 
)
2468 {
2469  SmartScriptHolder script;
2470  script.event.type = e;
2471  script.event.raw.param1 = event_param1;
2472  script.event.raw.param2 = event_param2;
2473  script.event.raw.param3 = event_param3;
2474  script.event.raw.param4 = event_param4;
2475  script.event.event_phase_mask = phaseMask;
2476  script.event.event_flags = event_flags;
2477  script.event.event_chance = 100;
2478 
2479  script.action.type = action;
2480  script.action.raw.param1 = action_param1;
2481  script.action.raw.param2 = action_param2;
2482  script.action.raw.param3 = action_param3;
2483  script.action.raw.param4 = action_param4;
2484  script.action.raw.param5 = action_param5;
2485  script.action.raw.param6 = action_param6;
2486 
2487  script.target.type = t;
2488  script.target.raw.param1 = target_param1;
2489  script.target.raw.param2 = target_param2;
2490  script.target.raw.param3 = target_param3;
2491 
2493  InitTimer(script);
2494  return script;
2495 }
uint32 event_phase_mask
Definition: SmartScriptMgr.h:189
SmartEvent event
Definition: SmartScriptMgr.h:1372
SMARTAI_TARGETS type
Definition: SmartScriptMgr.h:1117
void InitTimer(SmartScriptHolder &e)
Definition: SmartScript.cpp:3326
struct SmartTarget::@194::@209 raw
struct SmartAction::@114::@193 raw
uint32 event_flags
Definition: SmartScriptMgr.h:191
SmartTarget target
Definition: SmartScriptMgr.h:1374
Definition: SmartScriptMgr.h:1210
struct SmartEvent::@77::@113 raw
SMART_EVENT type
Definition: SmartScriptMgr.h:188
SmartAction action
Definition: SmartScriptMgr.h:1373
SmartScriptType source_type
Definition: SmartScriptMgr.h:1368
uint32 event_chance
Definition: SmartScriptMgr.h:190
Definition: SmartScriptMgr.h:1361
SMART_ACTION type
Definition: SmartScriptMgr.h:561

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::DecPhase ( int32  p = 1)
inlineprivate
250  {
251  if (mEventPhase > (uint32)p)
252  mEventPhase -= (uint32)p;
253  else
254  mEventPhase = 0;
255  }
uint32 mEventPhase
Definition: SmartScript.h:270
uint32_t uint32
Definition: Define.h:150
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the caller graph for this function:

Unit * SmartScript::DoFindClosestFriendlyInRange ( float  range,
bool  playerOnly 
)
3691 {
3692  if (!me)
3693  return NULL;
3694 
3695  Unit* unit = NULL;
3696  Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(me, me, range, playerOnly);
3698  me->VisitNearbyObject(range, searcher);
3699  return unit;
3700 }
Definition: GridNotifiers.h:840
arena_t NULL
Definition: jemalloc_internal.h:624
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:587
Definition: GridNotifiers.h:393
Creature * me
Definition: SmartScript.h:264
Definition: Unit.h:1305

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::DoFindFriendlyCC ( std::list< Creature * > &  _list,
float  range 
)
3657 {
3658  if (!me)
3659  return;
3660 
3662  Cell cell(p);
3663  cell.SetNoCreate();
3664 
3665  Trinity::FriendlyCCedInRange u_check(me, range);
3667 
3669 
3670  cell.Visit(p, grid_creature_searcher, *me->GetMap(), *me, range);
3671 }
Definition: TypeContainerVisitor.h:32
Map * GetMap() const
Definition: Object.h:543
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:193
Definition: TypeContainer.h:86
float GetPositionY() const
Definition: Position.h:105
Definition: GridNotifiers.h:459
Definition: GridNotifiers.h:760
Definition: Cell.h:49
float GetPositionX() const
Definition: Position.h:104
Creature * me
Definition: SmartScript.h:264

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::DoFindFriendlyMissingBuff ( std::list< Creature * > &  list,
float  range,
uint32  spellid 
)
3674 {
3675  if (!me)
3676  return;
3677 
3679  Cell cell(p);
3680  cell.SetNoCreate();
3681 
3682  Trinity::FriendlyMissingBuffInRange u_check(me, range, spellid);
3684 
3686 
3687  cell.Visit(p, grid_creature_searcher, *me->GetMap(), *me, range);
3688 }
Definition: TypeContainerVisitor.h:32
Map * GetMap() const
Definition: Object.h:543
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:193
Definition: TypeContainer.h:86
Definition: GridNotifiers.h:778
float GetPositionY() const
Definition: Position.h:105
Definition: GridNotifiers.h:459
Definition: Cell.h:49
float GetPositionX() const
Definition: Position.h:104
Creature * me
Definition: SmartScript.h:264

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Unit * SmartScript::DoSelectLowestHpFriendly ( float  range,
uint32  MinHPDiff 
)
3637 {
3638  if (!me)
3639  return NULL;
3640 
3642  Cell cell(p);
3643  cell.SetNoCreate();
3644 
3645  Unit* unit = NULL;
3646 
3647  Trinity::MostHPMissingInRange u_check(me, range, MinHPDiff);
3649 
3651 
3652  cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, range);
3653  return unit;
3654 }
Definition: TypeContainerVisitor.h:32
Map * GetMap() const
Definition: Object.h:543
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:193
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: GridNotifiers.h:741
Definition: TypeContainer.h:86
float GetPositionY() const
Definition: Position.h:105
Definition: GridNotifiers.h:393
Definition: Cell.h:49
float GetPositionX() const
Definition: Position.h:104
Creature * me
Definition: SmartScript.h:264
Definition: Unit.h:1305

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::FillScript ( SmartAIEventList  e,
WorldObject obj,
AreaTriggerEntry const at 
)
3496 {
3497  if (e.empty())
3498  {
3499  if (obj)
3500  TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for Entry %u is empty but is using SmartScript.", obj->GetEntry());
3501  if (at)
3502  TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for AreaTrigger %u is empty but is using SmartScript.", at->ID);
3503  return;
3504  }
3505  for (SmartAIEventList::iterator i = e.begin(); i != e.end(); ++i)
3506  {
3507  #ifndef TRINITY_DEBUG
3508  if ((*i).event.event_flags & SMART_EVENT_FLAG_DEBUG_ONLY)
3509  continue;
3510  #endif
3511 
3512  if ((*i).event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_ALL)//if has instance flag add only if in it
3513  {
3514  if (obj && obj->GetMap()->IsDungeon())
3515  {
3516  if ((1 << (obj->GetMap()->GetSpawnMode()+1)) & (*i).event.event_flags)
3517  {
3518  mEvents.push_back((*i));
3519  }
3520  }
3521  continue;
3522  }
3523  mEvents.push_back((*i));//NOTE: 'world(0)' events still get processed in ANY instance mode
3524  }
3525  if (mEvents.empty() && obj)
3526  TC_LOG_ERROR("sql.sql", "SmartScript: Entry %u has events but no events added to list because of instance flags.", obj->GetEntry());
3527  if (mEvents.empty() && at)
3528  TC_LOG_ERROR("sql.sql", "SmartScript: AreaTrigger %u has events but no events added to list because of instance flags. NOTE: triggers can not handle any instance flags.", at->ID);
3529 }
uint8 GetSpawnMode() const
Definition: Map.h:369
Map * GetMap() const
Definition: Object.h:543
bool IsDungeon() const
Definition: Map.h:395
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
Definition: SmartScriptMgr.h:1345
Definition: SmartScriptMgr.h:1342
uint32 GetEntry() const
Definition: Object.h:107
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
SmartAIEventList mEvents
Definition: SmartScript.h:260

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Creature* SmartScript::FindCreatureNear ( WorldObject searchObject,
ObjectGuid::LowType  guid 
) const
inline
188  {
189  auto bounds = searchObject->GetMap()->GetCreatureBySpawnIdStore().equal_range(guid);
190  if (bounds.first == bounds.second)
191  return nullptr;
192 
193  auto creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair)
194  {
195  return pair.second->IsAlive();
196  });
197 
198  return creatureItr != bounds.second ? creatureItr->second : bounds.first->second;
199  }
Map * GetMap() const
Definition: Object.h:543
CreatureBySpawnIdContainer & GetCreatureBySpawnIdStore()
Definition: Map.h:469

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

GameObject* SmartScript::FindGameObjectNear ( WorldObject searchObject,
ObjectGuid::LowType  guid 
) const
inline
179  {
180  auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid);
181  if (bounds.first == bounds.second)
182  return nullptr;
183 
184  return bounds.first->second;
185  }
Map * GetMap() const
Definition: Object.h:543
GameObjectBySpawnIdContainer & GetGameObjectBySpawnIdStore()
Definition: Map.h:472

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

WorldObject* SmartScript::GetBaseObject ( )
inline
57  {
58  WorldObject* obj = NULL;
59  if (me)
60  obj = me;
61  else if (go)
62  obj = go;
63  return obj;
64  }
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: Object.h:423
GameObject * go
Definition: SmartScript.h:266
Creature * me
Definition: SmartScript.h:264

+ Here is the caller graph for this function:

uint32 SmartScript::GetCounterId ( uint32  id)
inline
163  {
164  CounterMap::iterator itr = mCounterList.find(id);
165  if (itr != mCounterList.end())
166  return itr->first;
167  return 0;
168  }
CounterMap mCounterList
Definition: SmartScript.h:238

+ Here is the caller graph for this function:

uint32 SmartScript::GetCounterValue ( uint32  id)
inline
171  {
172  CounterMap::iterator itr = mCounterList.find(id);
173  if (itr != mCounterList.end())
174  return itr->second;
175  return 0;
176  }
CounterMap mCounterList
Definition: SmartScript.h:238

+ Here is the caller graph for this function:

Unit * SmartScript::GetLastInvoker ( )
3732 {
3733  WorldObject* lookupRoot = me;
3734  if (!lookupRoot)
3735  lookupRoot = go;
3736 
3737  if (lookupRoot)
3738  return ObjectAccessor::GetUnit(*lookupRoot, mLastInvoker);
3739 
3741 }
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:163
Definition: Object.h:423
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
Definition: ObjectAccessor.cpp:209
ObjectGuid mLastInvoker
Definition: SmartScript.h:236
GameObject * go
Definition: SmartScript.h:266
Creature * me
Definition: SmartScript.h:264

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint32 SmartScript::GetPathId ( ) const
inline
55 { return mPathId; }
uint32 mPathId
Definition: SmartScript.h:272

+ Here is the caller graph for this function:

void SmartScript::GetScript ( )
3532 {
3533  SmartAIEventList e;
3534  if (me)
3535  {
3536  e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType);
3537  if (e.empty())
3538  e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType);
3539  FillScript(e, me, NULL);
3540  }
3541  else if (go)
3542  {
3543  e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType);
3544  if (e.empty())
3545  e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType);
3546  FillScript(e, go, NULL);
3547  }
3548  else if (trigger)
3549  {
3550  e = sSmartScriptMgr->GetScript((int32)trigger->ID, mScriptType);
3551  FillScript(e, NULL, trigger);
3552  }
3553 }
void FillScript(SmartAIEventList e, WorldObject *obj, AreaTriggerEntry const *at)
Definition: SmartScript.cpp:3495
std::vector< SmartScriptHolder > SmartAIEventList
Definition: SmartScriptMgr.h:1468
SmartScriptType mScriptType
Definition: SmartScript.h:269
AreaTriggerEntry const * trigger
Definition: SmartScript.h:268
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:487
arena_t NULL
Definition: jemalloc_internal.h:624
uint32 ID
Definition: DBCStructure.h:76
ObjectGuid::LowType GetSpawnId() const
Definition: GameObject.h:902
int32_t int32
Definition: Define.h:146
GameObject * go
Definition: SmartScript.h:266
uint32 GetEntry() const
Definition: Object.h:107
Creature * me
Definition: SmartScript.h:264
#define sSmartScriptMgr
Definition: SmartScriptMgr.h:1669

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ObjectList* SmartScript::GetTargetList ( uint32  id)
inline
141  {
142  ObjectListMap::iterator itr = mTargetStorage->find(id);
143  if (itr != mTargetStorage->end())
144  return (*itr).second->GetObjectList();
145  return NULL;
146  }
ObjectListMap * mTargetStorage
Definition: SmartScript.h:201
arena_t NULL
Definition: jemalloc_internal.h:624

+ Here is the caller graph for this function:

ObjectList * SmartScript::GetTargets ( SmartScriptHolder const e,
Unit invoker = NULL 
)
2498 {
2499  Unit* scriptTrigger = NULL;
2500  if (invoker)
2501  scriptTrigger = invoker;
2502  else if (Unit* tempLastInvoker = GetLastInvoker())
2503  scriptTrigger = tempLastInvoker;
2504 
2505  WorldObject* baseObject = GetBaseObject();
2506 
2507  ObjectList* l = new ObjectList();
2508  switch (e.GetTargetType())
2509  {
2510  case SMART_TARGET_SELF:
2511  if (baseObject)
2512  l->push_back(baseObject);
2513  break;
2514  case SMART_TARGET_VICTIM:
2515  if (me)
2516  if (Unit* victim = me->GetVictim())
2517  l->push_back(victim);
2518  break;
2520  if (me)
2521  if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
2522  l->push_back(u);
2523  break;
2525  if (me)
2526  if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0))
2527  l->push_back(u);
2528  break;
2530  if (me)
2531  if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0))
2532  l->push_back(u);
2533  break;
2535  if (me)
2536  if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1))
2537  l->push_back(u);
2538  break;
2540  if (scriptTrigger)
2541  l->push_back(scriptTrigger);
2542  break;
2544  if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase())
2545  l->push_back(scriptTrigger->GetVehicle()->GetBase());
2546  break;
2548  if (scriptTrigger)
2549  {
2550  if (Player* player = scriptTrigger->ToPlayer())
2551  {
2552  if (Group* group = player->GetGroup())
2553  {
2554  for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
2555  if (Player* member = groupRef->GetSource())
2556  l->push_back(member);
2557  }
2558  // We still add the player to the list if there is no group. If we do
2559  // this even if there is a group (thus the else-check), it will add the
2560  // same player to the list twice. We don't want that to happen.
2561  else
2562  l->push_back(scriptTrigger);
2563  }
2564  }
2565  break;
2567  {
2568  // will always return a valid pointer, even if empty list
2569  ObjectList* units = GetWorldObjectsInDist((float)e.target.unitRange.maxDist);
2570  for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2571  {
2572  if (!IsCreature(*itr))
2573  continue;
2574 
2575  if (me && me->GetGUID() == (*itr)->GetGUID())
2576  continue;
2577 
2578  if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))
2579  l->push_back(*itr);
2580  }
2581 
2582  delete units;
2583  break;
2584  }
2586  {
2587  // will always return a valid pointer, even if empty list
2588  ObjectList* units = GetWorldObjectsInDist((float)e.target.unitDistance.dist);
2589  for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2590  {
2591  if (!IsCreature(*itr))
2592  continue;
2593 
2594  if (me && me->GetGUID() == (*itr)->GetGUID())
2595  continue;
2596 
2597  if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature)
2598  l->push_back(*itr);
2599  }
2600 
2601  delete units;
2602  break;
2603  }
2605  {
2606  // will always return a valid pointer, even if empty list
2607  ObjectList* units = GetWorldObjectsInDist((float)e.target.goDistance.dist);
2608  for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2609  {
2610  if (!IsGameObject(*itr))
2611  continue;
2612 
2613  if (go && go->GetGUID() == (*itr)->GetGUID())
2614  continue;
2615 
2616  if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry)
2617  l->push_back(*itr);
2618  }
2619 
2620  delete units;
2621  break;
2622  }
2624  {
2625  // will always return a valid pointer, even if empty list
2626  ObjectList* units = GetWorldObjectsInDist((float)e.target.goRange.maxDist);
2627  for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2628  {
2629  if (!IsGameObject(*itr))
2630  continue;
2631 
2632  if (go && go->GetGUID() == (*itr)->GetGUID())
2633  continue;
2634 
2635  if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))
2636  l->push_back(*itr);
2637  }
2638 
2639  delete units;
2640  break;
2641  }
2643  {
2644  if (!scriptTrigger && !baseObject)
2645  {
2646  TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker");
2647  break;
2648  }
2649 
2650  if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid))
2651  if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)
2652  l->push_back(target);
2653  break;
2654  }
2656  {
2657  if (!scriptTrigger && !baseObject)
2658  {
2659  TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
2660  break;
2661  }
2662 
2663  if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid))
2664  if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)
2665  l->push_back(target);
2666  break;
2667  }
2669  {
2670  // will always return a valid pointer, even if empty list
2671  ObjectList* units = GetWorldObjectsInDist((float)e.target.playerRange.maxDist);
2672  if (!units->empty() && baseObject)
2673  for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2674  if (IsPlayer(*itr) && baseObject->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist))
2675  l->push_back(*itr);
2676 
2677  delete units;
2678  break;
2679  }
2681  {
2682  // will always return a valid pointer, even if empty list
2683  ObjectList* units = GetWorldObjectsInDist((float)e.target.playerDistance.dist);
2684  for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2685  if (IsPlayer(*itr))
2686  l->push_back(*itr);
2687 
2688  delete units;
2689  break;
2690  }
2691  case SMART_TARGET_STORED:
2692  {
2693  ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id);
2694  if (itr != mTargetStorage->end())
2695  {
2696  ObjectList* objectList = itr->second->GetObjectList();
2697  l->assign(objectList->begin(), objectList->end());
2698  }
2699 
2700  return l;
2701  }
2703  {
2704  if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead))
2705  l->push_back(target);
2706  break;
2707  }
2709  {
2710  if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100)))
2711  l->push_back(target);
2712  break;
2713  }
2715  {
2716  if (me)
2717  if (Player* target = me->SelectNearestPlayer(float(e.target.playerDistance.dist)))
2718  l->push_back(target);
2719  break;
2720  }
2722  {
2723  if (me)
2724  {
2725  ObjectGuid charmerOrOwnerGuid = me->GetCharmerOrOwnerGUID();
2726 
2727  if (!charmerOrOwnerGuid)
2728  charmerOrOwnerGuid = me->GetCreatorGUID();
2729 
2730  if (Unit* owner = ObjectAccessor::GetUnit(*me, charmerOrOwnerGuid))
2731  l->push_back(owner);
2732  }
2733  break;
2734  }
2736  {
2737  if (me)
2738  {
2740  for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
2741  if (Unit* temp = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
2742  l->push_back(temp);
2743  }
2744  break;
2745  }
2747  {
2748  if (me)
2749  if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))
2750  l->push_back(target);
2751  break;
2752  }
2754  {
2755  if (me)
2756  if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))
2757  l->push_back(target);
2758  break;
2759  }
2760  case SMART_TARGET_POSITION:
2761  case SMART_TARGET_NONE:
2762  default:
2763  break;
2764  }
2765 
2766  if (l->empty())
2767  {
2768  delete l;
2769  l = NULL;
2770  }
2771 
2772  return l;
2773 }
Definition: SmartScriptMgr.h:1086
Definition: SmartScriptMgr.h:1099
Definition: UnitAI.h:36
Definition: SmartScriptMgr.h:1081
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:163
WorldObject * GetBaseObject()
Definition: SmartScript.h:56
Definition: SmartScriptMgr.h:1085
TC_GAME_API Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive)
Definition: ScriptedCreature.cpp:611
Definition: SmartScriptMgr.h:1098
ObjectListMap * mTargetStorage
Definition: SmartScript.h:201
Unit * SelectNearestTarget(float dist=0, bool playerOnly=false) const
Definition: Creature.cpp:1944
Definition: SmartScriptMgr.h:1082
arena_t NULL
Definition: jemalloc_internal.h:624
ThreatContainer::StorageType const & getThreatList() const
Definition: ThreatManager.h:263
Player * SelectNearestPlayer(float distance=0) const
Definition: Creature.cpp:1998
Definition: Object.h:423
Definition: Creature.h:467
Definition: SmartScriptMgr.h:1084
Definition: SmartScriptMgr.h:1079
Definition: SmartScriptMgr.h:1095
bool IsPlayer(WorldObject *obj)
Definition: SmartScript.h:71
Player * ToPlayer()
Definition: Object.h:191
Definition: UnitAI.h:37
Definition: SmartScriptMgr.h:1078
std::list< WorldObject * > ObjectList
Definition: SmartScriptMgr.h:1391
Definition: SmartScriptMgr.h:1096
Definition: SmartScriptMgr.h:1074
Definition: UnitAI.h:35
Definition: SmartScriptMgr.h:1087
Unit * GetVictim() const
Definition: Unit.h:1379
CreatureAI * AI() const
Definition: Creature.h:525
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition: UnitAI.cpp:91
Definition: GameObject.h:880
bool IsGameObject(WorldObject *obj)
Definition: SmartScript.h:81
ObjectGuid GetCharmerOrOwnerGUID() const
Definition: Unit.cpp:12677
GameObject * go
Definition: SmartScript.h:266
Definition: SmartScriptMgr.h:1080
Definition: SmartScriptMgr.h:1089
Unit * GetLastInvoker()
Definition: SmartScript.cpp:3731
GameObject * FindGameObjectNear(WorldObject *searchObject, ObjectGuid::LowType guid) const
Definition: SmartScript.h:178
Definition: SmartScriptMgr.h:1088
ObjectList * GetWorldObjectsInDist(float dist)
Definition: SmartScript.cpp:2775
Definition: SmartScriptMgr.h:1091
bool IsInRange(WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
Definition: Object.cpp:1703
Definition: SmartScriptMgr.h:1093
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Vehicle * GetVehicle() const
Definition: Unit.h:2166
ObjectGuid GetCreatorGUID() const
Definition: Unit.h:1700
std::list< HostileReference * > StorageType
Definition: ThreatManager.h:149
Definition: SmartScriptMgr.h:1097
Definition: SmartScriptMgr.h:1073
Definition: SmartScriptMgr.h:1094
ThreatManager & getThreatManager()
Definition: Unit.h:1998
Definition: SmartScriptMgr.h:1090
Definition: SmartScriptMgr.h:1092
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
Definition: ObjectGuid.h:189
Definition: SmartScriptMgr.h:1075
Definition: SmartScriptMgr.h:1083
Creature * FindCreatureNear(WorldObject *searchObject, ObjectGuid::LowType guid) const
Definition: SmartScript.h:187
Definition: SmartScriptMgr.h:1076
bool IsCreature(WorldObject *obj)
Definition: SmartScript.h:76
Creature * me
Definition: SmartScript.h:264
Definition: Unit.h:1305
TC_GAME_API GameObject * GetClosestGameObjectWithEntry(WorldObject *source, uint32 entry, float maxSearchRange)
Definition: ScriptedCreature.cpp:616
Unit * GetBase() const
May be called from scripts.
Definition: Vehicle.h:49
Definition: Group.h:191
Definition: GroupReference.h:27
Definition: SmartScriptMgr.h:1077
Unit * DoFindClosestFriendlyInRange(float range, bool playerOnly)
Definition: SmartScript.cpp:3690

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

ObjectList * SmartScript::GetWorldObjectsInDist ( float  dist)
2776 {
2777  ObjectList* targets = new ObjectList();
2778  WorldObject* obj = GetBaseObject();
2779  if (obj)
2780  {
2781  Trinity::AllWorldObjectsInRange u_check(obj, dist);
2783  obj->VisitNearbyObject(dist, searcher);
2784  }
2785  return targets;
2786 }
WorldObject * GetBaseObject()
Definition: SmartScript.h:56
Definition: Object.h:423
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:587
std::list< WorldObject * > ObjectList
Definition: SmartScriptMgr.h:1391
Definition: GridNotifiers.h:218
Definition: GridNotifiers.h:1317

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::IncPhase ( int32  p = 1)
inlineprivate
242  {
243  if (p >= 0)
244  mEventPhase += (uint32)p;
245  else
246  DecPhase(abs(p));
247  }
G3D::Matrix abs(const G3D::Matrix &M)
Definition: Matrix.h:632
uint32 mEventPhase
Definition: SmartScript.h:270
void DecPhase(int32 p=1)
Definition: SmartScript.h:249
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::InitTimer ( SmartScriptHolder e)
3327 {
3328  switch (e.GetEventType())
3329  {
3330  //set only events which have initial timers
3331  case SMART_EVENT_UPDATE:
3332  case SMART_EVENT_UPDATE_IC:
3334  RecalcTimer(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max);
3335  break;
3338  RecalcTimer(e, e.event.distance.repeat, e.event.distance.repeat);
3339  break;
3340  default:
3341  e.active = true;
3342  break;
3343  }
3344 }
Definition: SmartScriptMgr.h:179
SmartEvent event
Definition: SmartScriptMgr.h:1372
uint32 GetEventType() const
Definition: SmartScriptMgr.h:1377
Definition: SmartScriptMgr.h:180
bool active
Definition: SmartScriptMgr.h:1382
struct SmartEvent::@77::@79 minMaxRepeat
void RecalcTimer(SmartScriptHolder &e, uint32 min, uint32 max)
Definition: SmartScript.cpp:3345
Definition: SmartScriptMgr.h:164
Definition: SmartScriptMgr.h:105
Definition: SmartScriptMgr.h:104
struct SmartEvent::@77::@111 distance

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::InstallEvents ( )
private
3431 {
3432  if (!mInstallEvents.empty())
3433  {
3434  for (SmartAIEventList::iterator i = mInstallEvents.begin(); i != mInstallEvents.end(); ++i)
3435  mEvents.push_back(*i);//must be before UpdateTimers
3436 
3437  mInstallEvents.clear();
3438  }
3439 }
SmartAIEventList mEvents
Definition: SmartScript.h:260
SmartAIEventList mInstallEvents
Definition: SmartScript.h:261

+ Here is the caller graph for this function:

void SmartScript::InstallTemplate ( SmartScriptHolder const e)
2389 {
2390  if (!GetBaseObject())
2391  return;
2392  if (mTemplate)
2393  {
2394  TC_LOG_ERROR("sql.sql", "SmartScript::InstallTemplate: Entry " SI64FMTD " SourceType %u AI Template can not be set more then once, skipped.", e.entryOrGuid, e.GetScriptType());
2395  return;
2396  }
2397  mTemplate = (SMARTAI_TEMPLATE)e.action.installTtemplate.id;
2398  switch ((SMARTAI_TEMPLATE)e.action.installTtemplate.id)
2399  {
2401  {
2402  AddEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, e.action.installTtemplate.param2, e.action.installTtemplate.param3, SMART_ACTION_CAST, e.action.installTtemplate.param1, e.target.raw.param1, 0, 0, 0, 0, SMART_TARGET_VICTIM, 0, 0, 0, 1);
2403  AddEvent(SMART_EVENT_RANGE, 0, e.action.installTtemplate.param4, 300, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1);
2404  AddEvent(SMART_EVENT_RANGE, 0, 0, e.action.installTtemplate.param4>10?e.action.installTtemplate.param4-10:0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1);
2405  AddEvent(SMART_EVENT_MANA_PCT, 0, e.action.installTtemplate.param5-15>100?100:e.action.installTtemplate.param5+15, 100, 1000, 1000, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2406  AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, SMART_ACTION_SET_EVENT_PHASE, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2407  AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2408  break;
2409  }
2411  {
2412  AddEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, e.action.installTtemplate.param2, e.action.installTtemplate.param3, SMART_ACTION_CAST, e.action.installTtemplate.param1, e.target.raw.param1, 0, 0, 0, 0, SMART_TARGET_VICTIM, 0, 0, 0, 0);
2413  AddEvent(SMART_EVENT_JUST_CREATED, 0, 0, 0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2414  break;
2415  }
2417  {
2418  if (!me)
2419  return;
2420  //store cage as id1
2421  AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_GAMEOBJECT, e.action.installTtemplate.param1, 10, 0, 0);
2422 
2423  //reset(close) cage on hostage(me) respawn
2424  AddEvent(SMART_EVENT_UPDATE, SMART_EVENT_FLAG_NOT_REPEATABLE, 0, 0, 0, 0, SMART_ACTION_RESET_GOBJECT, 0, 0, 0, 0, 0, 0, SMART_TARGET_GAMEOBJECT_DISTANCE, e.action.installTtemplate.param1, 5, 0, 0);
2425 
2426  AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_SET_RUN, e.action.installTtemplate.param3, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2427  AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2428 
2429  AddEvent(SMART_EVENT_UPDATE, SMART_EVENT_FLAG_NOT_REPEATABLE, 1000, 1000, 0, 0, SMART_ACTION_MOVE_FORWARD, e.action.installTtemplate.param4, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1);
2430  //phase 1: give quest credit on movepoint reached
2432  //phase 1: despawn after time on movepoint reached
2433  AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_FORCE_DESPAWN, e.action.installTtemplate.param2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1);
2434 
2435  if (sCreatureTextMgr->TextExist(me->GetEntry(), (uint8)e.action.installTtemplate.param5))
2436  AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_TALK, e.action.installTtemplate.param5, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1);
2437  break;
2438  }
2440  {
2441  if (!go)
2442  return;
2443  //store hostage as id1
2444  AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0);
2445  //store invoker as id2
2446  AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2447  //signal hostage
2448  AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);
2449  //when hostage raeched end point, give credit to invoker
2450  if (e.action.installTtemplate.param2)
2451  AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
2452  else
2453  AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
2454  break;
2455  }
2457  default:
2458  return;
2459  }
2460 }
Definition: SmartScriptMgr.h:1066
Definition: SmartScriptMgr.h:53
Definition: SmartScriptMgr.h:174
void AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask=0)
Definition: SmartScript.cpp:2462
WorldObject * GetBaseObject()
Definition: SmartScript.h:56
Definition: SmartScriptMgr.h:503
Definition: SmartScriptMgr.h:480
Definition: SmartScriptMgr.h:461
Definition: SmartScriptMgr.h:1062
Definition: SmartScriptMgr.h:1085
Definition: SmartScriptMgr.h:460
Definition: SmartScriptMgr.h:498
Definition: SmartScriptMgr.h:1335
Definition: SmartScriptMgr.h:485
SMARTAI_TEMPLATE
Definition: SmartScriptMgr.h:1060
Definition: SmartScriptMgr.h:1064
Definition: SmartScriptMgr.h:138
Definition: SmartScriptMgr.h:440
Definition: SmartScriptMgr.h:1067
Definition: SmartScriptMgr.h:142
Definition: SmartScriptMgr.h:472
Definition: SmartScriptMgr.h:167
Definition: SmartScriptMgr.h:450
Definition: SmartScriptMgr.h:471
SMARTAI_TEMPLATE mTemplate
Definition: SmartScript.h:281
#define SI64FMTD
Definition: Define.h:140
Definition: SmartScriptMgr.h:107
#define sCreatureTextMgr
Definition: CreatureTextMgr.h:113
Definition: SmartScriptMgr.h:113
Definition: SmartScriptMgr.h:164
GameObject * go
Definition: SmartScript.h:266
Definition: SmartScriptMgr.h:1088
uint8_t uint8
Definition: g3dmath.h:164
Definition: SmartScriptMgr.h:1093
Definition: SmartScriptMgr.h:1073
Definition: SmartScriptMgr.h:1063
Definition: SmartScriptMgr.h:104
Definition: SmartScriptMgr.h:1092
uint32 GetEntry() const
Definition: Object.h:107
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
Definition: SmartScriptMgr.h:1075
Definition: SmartScriptMgr.h:484
Creature * me
Definition: SmartScript.h:264
Definition: MotionMaster.h:46

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SmartScript::IsCreature ( WorldObject obj)
inline
77  {
78  return obj && obj->GetTypeId() == TYPEID_UNIT;
79  }
Definition: ObjectGuid.h:32
TypeID GetTypeId() const
Definition: Object.h:113

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SmartScript::IsGameObject ( WorldObject obj)
inline
82  {
83  return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT;
84  }
TypeID GetTypeId() const
Definition: Object.h:113
Definition: ObjectGuid.h:34

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SmartScript::IsInPhase ( uint32  p) const
inlineprivate
257 { return ((1 << (mEventPhase - 1)) & p) != 0; }
uint32 mEventPhase
Definition: SmartScript.h:270

+ Here is the caller graph for this function:

bool SmartScript::IsPlayer ( WorldObject obj)
inline
72  {
73  return obj && obj->GetTypeId() == TYPEID_PLAYER;
74  }
TypeID GetTypeId() const
Definition: Object.h:113
Definition: ObjectGuid.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SmartScript::IsSmart ( Creature c = NULL)
inline
112  {
113  bool smart = true;
114  if (c && c->GetAIName() != "SmartAI")
115  smart = false;
116 
117  if (!me || me->GetAIName() != "SmartAI")
118  smart = false;
119 
120  if (!smart)
121  TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: " UI64FMTD " Entry: %u) is not using SmartAI, action called by Creature (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(c ? c->GetSpawnId() : UI64LIT(0)), c ? c->GetEntry() : 0, uint64(me ? me->GetSpawnId() : UI64LIT(0)), me ? me->GetEntry() : 0);
122 
123  return smart;
124  }
#define UI64LIT(N)
Definition: Define.h:138
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:487
uint64_t uint64
Definition: g3dmath.h:170
#define UI64FMTD
Definition: Define.h:137
uint32 GetEntry() const
Definition: Object.h:107
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
Creature * me
Definition: SmartScript.h:264
std::string GetAIName() const
Definition: Creature.cpp:2417

+ Here is the caller graph for this function:

bool SmartScript::IsSmartGO ( GameObject g = NULL)
inline
127  {
128  bool smart = true;
129  if (g && g->GetAIName() != "SmartGameObjectAI")
130  smart = false;
131 
132  if (!go || go->GetAIName() != "SmartGameObjectAI")
133  smart = false;
134  if (!smart)
135  TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: " UI64FMTD " Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(g ? g->GetSpawnId() : UI64LIT(0)), g ? g->GetEntry() : 0, uint64(go ? go->GetSpawnId() : UI64LIT(0)), go ? go->GetEntry() : 0);
136 
137  return smart;
138  }
#define UI64LIT(N)
Definition: Define.h:138
uint64_t uint64
Definition: g3dmath.h:170
ObjectGuid::LowType GetSpawnId() const
Definition: GameObject.h:902
std::string GetAIName() const
Definition: GameObject.cpp:90
#define UI64FMTD
Definition: Define.h:137
GameObject * go
Definition: SmartScript.h:266
uint32 GetEntry() const
Definition: Object.h:107
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207

+ Here is the caller graph for this function:

bool SmartScript::IsUnit ( WorldObject obj)
inline
67  {
68  return obj && (obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER);
69  }
Definition: ObjectGuid.h:32
TypeID GetTypeId() const
Definition: Object.h:113
Definition: ObjectGuid.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::OnInitialize ( WorldObject obj,
AreaTriggerEntry const at = NULL 
)
3556 {
3557  if (obj)//handle object based scripts
3558  {
3559  switch (obj->GetTypeId())
3560  {
3561  case TYPEID_UNIT:
3563  me = obj->ToCreature();
3564  TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Creature %u", me->GetEntry());
3565  break;
3566  case TYPEID_GAMEOBJECT:
3568  go = obj->ToGameObject();
3569  TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is GameObject %u", go->GetEntry());
3570  break;
3571  default:
3572  TC_LOG_ERROR("misc", "SmartScript::OnInitialize: Unhandled TypeID !WARNING!");
3573  return;
3574  }
3575  } else if (at)
3576  {
3578  trigger = at;
3579  TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is AreaTrigger %u", trigger->ID);
3580  }
3581  else
3582  {
3583  TC_LOG_ERROR("misc", "SmartScript::OnInitialize: !WARNING! Initialized objects are NULL.");
3584  return;
3585  }
3586 
3587  GetScript();//load copy of script
3588 
3589  for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
3590  InitTimer((*i));//calculate timers for first time use
3591 
3593  InstallEvents();
3595 }
Definition: SmartScriptMgr.h:1212
SmartScriptType mScriptType
Definition: SmartScript.h:269
AreaTriggerEntry const * trigger
Definition: SmartScript.h:268
Definition: ObjectGuid.h:32
Definition: SmartScriptMgr.h:141
void InitTimer(SmartScriptHolder &e)
Definition: SmartScript.cpp:3326
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
uint32 ID
Definition: DBCStructure.h:76
GameObject * ToGameObject()
Definition: Object.h:200
TypeID GetTypeId() const
Definition: Object.h:113
void InstallEvents()
Definition: SmartScript.cpp:3430
Definition: SmartScriptMgr.h:167
void GetScript()
Definition: SmartScript.cpp:3531
Definition: SmartScriptMgr.h:1210
Definition: ObjectGuid.h:34
GameObject * go
Definition: SmartScript.h:266
void ProcessEventsFor(SMART_EVENT e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
Definition: SmartScript.cpp:83
Creature * ToCreature()
Definition: Object.h:194
uint32 GetEntry() const
Definition: Object.h:107
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
SmartAIEventList mEvents
Definition: SmartScript.h:260
Definition: SmartScriptMgr.h:1211
Creature * me
Definition: SmartScript.h:264

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::OnMoveInLineOfSight ( Unit who)
3598 {
3599  if (!me)
3600  return;
3601 
3603 }
bool IsInCombat() const
Definition: Unit.h:1584
Definition: SmartScriptMgr.h:114
Definition: SmartScriptMgr.h:130
void ProcessEventsFor(SMART_EVENT e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
Definition: SmartScript.cpp:83
Creature * me
Definition: SmartScript.h:264

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::OnReset ( )
67 {
68  SetPhase(0);
70  for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
71  {
72  if (!((*i).event.event_flags & SMART_EVENT_FLAG_DONT_RESET))
73  {
74  InitTimer((*i));
75  (*i).runOnce = false;
76  }
77  }
80  mCounterList.clear();
81 }
void ResetBaseObject()
Definition: SmartScript.h:204
CounterMap mCounterList
Definition: SmartScript.h:238
Definition: SmartScriptMgr.h:1343
void InitTimer(SmartScriptHolder &e)
Definition: SmartScript.cpp:3326
ObjectGuid mLastInvoker
Definition: SmartScript.h:236
void Clear()
Definition: ObjectGuid.h:215
void ProcessEventsFor(SMART_EVENT e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
Definition: SmartScript.cpp:83
void SetPhase(uint32 p=0)
Definition: SmartScript.h:258
SmartAIEventList mEvents
Definition: SmartScript.h:260
Definition: SmartScriptMgr.h:129

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::OnUpdate ( const uint32  diff)
3442 {
3444  return;
3445 
3446  InstallEvents();//before UpdateTimers
3447 
3448  for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
3449  UpdateTimer(*i, diff);
3450 
3451  if (!mStoredEvents.empty())
3452  for (SmartAIEventList::iterator i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i)
3453  UpdateTimer(*i, diff);
3454 
3455  bool needCleanup = true;
3456  if (!mTimedActionList.empty())
3457  {
3459  for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
3460  {
3461  if ((*i).enableTimed)
3462  {
3463  UpdateTimer(*i, diff);
3464  needCleanup = false;
3465  }
3466  }
3467 
3469  }
3470  if (needCleanup)
3471  mTimedActionList.clear();
3472 
3473  if (!mRemIDs.empty())
3474  {
3475  for (std::list<uint32>::iterator i = mRemIDs.begin(); i != mRemIDs.end(); ++i)
3476  {
3477  RemoveStoredEvent((*i));
3478  }
3479  }
3480  if (mUseTextTimer && me)
3481  {
3482  if (mTextTimer < diff)
3483  {
3484  uint32 textID = mLastTextID;
3485  mLastTextID = 0;
3486  uint32 entry = mTalkerEntry;
3487  mTalkerEntry = 0;
3488  mTextTimer = 0;
3489  mUseTextTimer = false;
3490  ProcessEventsFor(SMART_EVENT_TEXT_OVER, NULL, textID, entry);
3491  } else mTextTimer -= diff;
3492  }
3493 }
uint32 mLastTextID
Definition: SmartScript.h:277
SmartAIEventList mTimedActionList
Definition: SmartScript.h:262
WorldObject * GetBaseObject()
Definition: SmartScript.h:56
SmartAIEventList mStoredEvents
Definition: SmartScript.h:273
SmartScriptType mScriptType
Definition: SmartScript.h:269
bool isProcessingTimedActionList
Definition: SmartScript.h:263
uint32 mTextTimer
Definition: SmartScript.h:276
arena_t NULL
Definition: jemalloc_internal.h:624
void InstallEvents()
Definition: SmartScript.cpp:3430
Definition: SmartScriptMgr.h:1210
uint32_t uint32
Definition: Define.h:150
void RemoveStoredEvent(uint32 id)
Definition: SmartScript.h:284
void UpdateTimer(SmartScriptHolder &e, uint32 const diff)
Definition: SmartScript.cpp:3352
uint32 mTalkerEntry
Definition: SmartScript.h:278
void ProcessEventsFor(SMART_EVENT e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
Definition: SmartScript.cpp:83
SmartAIEventList mEvents
Definition: SmartScript.h:260
Definition: SmartScriptMgr.h:1211
Creature * me
Definition: SmartScript.h:264
bool mUseTextTimer
Definition: SmartScript.h:279
std::list< uint32 > mRemIDs
Definition: SmartScript.h:274
Definition: SmartScriptMgr.h:156

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SmartScript::ProcessAction ( SmartScriptHolder e,
Unit unit = NULL,
uint32  var0 = 0,
uint32  var1 = 0,
bool  bvar = false,
const SpellInfo spell = NULL,
GameObject gob = NULL 
)
Todo:
Resume path when reached jump location
98 {
99  //calc random
101  {
102  uint32 rnd = urand(0, 100);
103  if (e.event.event_chance <= rnd)
104  return;
105  }
106  e.runOnce = true;//used for repeat check
107 
108  if (unit)
109  mLastInvoker = unit->GetGUID();
110 
111  if (Unit* tempInvoker = GetLastInvoker())
112  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: Invoker: %s (%s)", tempInvoker->GetName().c_str(), tempInvoker->GetGUID().ToString().c_str());
113 
114  switch (e.GetActionType())
115  {
116  case SMART_ACTION_TALK:
117  {
118  ObjectList* targets = GetTargets(e, unit);
119  Creature* talker = me;
120  Player* targetPlayer = NULL;
121  Unit* talkTarget = NULL;
122 
123  if (targets)
124  {
125  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
126  {
127  if (IsCreature(*itr) && !(*itr)->ToCreature()->IsPet()) // Prevented sending text to pets.
128  {
129  if (e.action.talk.useTalkTarget)
130  talkTarget = (*itr)->ToCreature();
131  else
132  talker = (*itr)->ToCreature();
133  break;
134  }
135  else if (IsPlayer(*itr))
136  {
137  targetPlayer = (*itr)->ToPlayer();
138  break;
139  }
140  }
141 
142  delete targets;
143  }
144 
145  if (!talker)
146  break;
147 
148  mTalkerEntry = talker->GetEntry();
149  mLastTextID = e.action.talk.textGroupID;
150  mTextTimer = e.action.talk.duration;
151 
152  if (IsPlayer(GetLastInvoker())) // used for $vars in texts and whisper target
153  talkTarget = GetLastInvoker();
154  else if (targetPlayer)
155  talkTarget = targetPlayer;
156 
157  mUseTextTimer = true;
158  sCreatureTextMgr->SendChat(talker, uint8(e.action.talk.textGroupID), talkTarget);
159  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_TALK: talker: %s (%s), textGuid: %s",
160  talker->GetName().c_str(), talker->GetGUID().ToString().c_str(), talkTarget ? talkTarget->GetGUID().ToString().c_str() : "Empty");
161  break;
162  }
164  {
165  ObjectList* targets = GetTargets(e, unit);
166  if (targets)
167  {
168  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
169  {
170  if (IsCreature(*itr))
171  sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
172  else if (IsPlayer(*itr) && me)
173  {
174  Unit* templastInvoker = GetLastInvoker();
175  sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, (*itr)->ToPlayer());
176  }
177  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (%s), textGroupId: %u",
178  (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), uint8(e.action.talk.textGroupID));
179  }
180 
181  delete targets;
182  }
183  break;
184  }
186  {
187  ObjectList* targets = GetTargets(e, unit);
188  if (targets)
189  {
190  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
191  {
192  if (IsUnit(*itr))
193  {
194  (*itr)->ToUnit()->HandleEmoteCommand(e.action.emote.emote);
195  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (%s), emote: %u",
196  (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.emote.emote);
197  }
198  }
199 
200  delete targets;
201  }
202  break;
203  }
204  case SMART_ACTION_SOUND:
205  {
206  ObjectList* targets = GetTargets(e, unit);
207  if (targets)
208  {
209  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
210  {
211  if (IsUnit(*itr))
212  {
213  (*itr)->PlayDirectSound(e.action.sound.sound, e.action.sound.onlySelf ? (*itr)->ToPlayer() : nullptr);
214  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (%s), sound: %u, onlyself: %u",
215  (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.sound.sound, e.action.sound.onlySelf);
216  }
217  }
218 
219  delete targets;
220  }
221  break;
222  }
224  {
225  ObjectList* targets = GetTargets(e, unit);
226  if (targets)
227  {
228  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
229  {
230  if (IsCreature(*itr))
231  {
232  if (e.action.faction.factionID)
233  {
234  (*itr)->ToCreature()->setFaction(e.action.faction.factionID);
235  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, %s set faction to %u",
236  (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), e.action.faction.factionID);
237  }
238  else
239  {
240  if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate((*itr)->ToCreature()->GetEntry()))
241  {
242  if ((*itr)->ToCreature()->getFaction() != ci->faction)
243  {
244  (*itr)->ToCreature()->setFaction(ci->faction);
245  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, %s set faction to %u",
246  (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), ci->faction);
247  }
248  }
249  }
250  }
251  }
252 
253  delete targets;
254  }
255  break;
256  }
258  {
259  ObjectList* targets = GetTargets(e, unit);
260  if (!targets)
261  break;
262 
263  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
264  {
265  if (!IsCreature(*itr))
266  continue;
267 
268  if (e.action.morphOrMount.creature || e.action.morphOrMount.model)
269  {
270  //set model based on entry from creature_template
271  if (e.action.morphOrMount.creature)
272  {
273  if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
274  {
275  uint32 displayId = ObjectMgr::ChooseDisplayId(ci);
276  (*itr)->ToCreature()->SetDisplayId(displayId);
277  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, %s set displayid to %u",
278  (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), displayId);
279  }
280  }
281  //if no param1, then use value from param2 (modelId)
282  else
283  {
284  (*itr)->ToCreature()->SetDisplayId(e.action.morphOrMount.model);
285  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, %s set displayid to %u",
286  (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), e.action.morphOrMount.model);
287  }
288  }
289  else
290  {
291  (*itr)->ToCreature()->DeMorph();
292  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, %s demorphs.",
293  (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str());
294  }
295  }
296 
297  delete targets;
298  break;
299  }
301  {
302  ObjectList* targets = GetTargets(e, unit);
303  if (!targets)
304  break;
305 
306  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
307  {
308  if (IsPlayer(*itr))
309  {
310  (*itr)->ToPlayer()->FailQuest(e.action.quest.quest);
311  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FAIL_QUEST: Player %s fails quest %u",
312  (*itr)->GetGUID().ToString().c_str(), e.action.quest.quest);
313  }
314  }
315 
316  delete targets;
317  break;
318  }
320  {
321  ObjectList* targets = GetTargets(e, unit);
322  if (!targets)
323  break;
324 
325  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
326  {
327  if (IsPlayer(*itr))
328  {
329  if (Quest const* q = sObjectMgr->GetQuestTemplate(e.action.quest.quest))
330  {
331  (*itr)->ToPlayer()->AddQuestAndCheckCompletion(q, NULL);
332  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_QUEST: Player %s add quest %u",
333  (*itr)->GetGUID().ToString().c_str(), e.action.quest.quest);
334  }
335  }
336  }
337 
338  delete targets;
339  break;
340  }
342  {
343  ObjectList* targets = GetTargets(e, unit);
344  if (!targets)
345  break;
346 
347  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
348  {
349  if (!IsCreature(*itr))
350  continue;
351 
352  (*itr)->ToCreature()->SetReactState(ReactStates(e.action.react.state));
353  }
354 
355  delete targets;
356  break;
357  }
359  {
360  ObjectList* targets = GetTargets(e, unit);
361  if (!targets)
362  break;
363 
365  emotes[0] = e.action.randomEmote.emote1;
366  emotes[1] = e.action.randomEmote.emote2;
367  emotes[2] = e.action.randomEmote.emote3;
368  emotes[3] = e.action.randomEmote.emote4;
369  emotes[4] = e.action.randomEmote.emote5;
370  emotes[5] = e.action.randomEmote.emote6;
372  uint32 count = 0;
373  for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
374  {
375  if (emotes[i])
376  {
377  temp[count] = emotes[i];
378  ++count;
379  }
380  }
381 
382  if (count == 0)
383  {
384  delete targets;
385  break;
386  }
387 
388  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
389  {
390  if (IsUnit(*itr))
391  {
392  uint32 emote = temp[urand(0, count - 1)];
393  (*itr)->ToUnit()->HandleEmoteCommand(emote);
394  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature %s handle random emote %u",
395  (*itr)->GetGUID().ToString().c_str(), emote);
396  }
397  }
398 
399  delete targets;
400  break;
401  }
403  {
404  if (!me)
405  break;
406 
408  for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
409  {
410  if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
411  {
412  me->getThreatManager().modifyThreatPercent(target, e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
413  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_ALL_PCT: Creature %s modify threat for %s, value %i",
414  me->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str(),
415  e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
416  }
417  }
418  break;
419  }
421  {
422  if (!me)
423  break;
424 
425  ObjectList* targets = GetTargets(e, unit);
426  if (!targets)
427  break;
428 
429  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
430  {
431  if (IsUnit(*itr))
432  {
433  me->getThreatManager().modifyThreatPercent((*itr)->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
434  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_SINGLE_PCT: Creature %s modify threat for %s, value %i",
435  me->GetGUID().ToString().c_str(), (*itr)->GetGUID().ToString().c_str(),
436  e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
437  }
438  }
439 
440  delete targets;
441  break;
442  }
444  {
445  ObjectList* targets = GetTargets(e, unit);
446  if (!targets)
447  break;
448 
449  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
450  {
451  // Special handling for vehicles
452  if (IsUnit(*itr))
453  if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
454  for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
455  if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid))
456  player->AreaExploredOrEventHappens(e.action.quest.quest);
457 
458  if (IsPlayer(*itr))
459  {
460  (*itr)->ToPlayer()->GroupEventHappens(e.action.quest.quest, me);
461 
462  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: %s credited quest %u",
463  (*itr)->GetGUID().ToString().c_str(), e.action.quest.quest);
464  }
465  }
466 
467  delete targets;
468  break;
469  }
470  case SMART_ACTION_CAST:
471  {
472  ObjectList* targets = GetTargets(e, unit);
473  if (!targets)
474  break;
475 
476  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
477  {
478  if (!IsUnit(*itr))
479  continue;
480 
481  if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
482  {
483  if (me)
484  {
486  me->InterruptNonMeleeSpells(false);
487 
488  if (e.action.cast.flags & SMARTCAST_COMBAT_MOVE)
489  {
490  // If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed
491  // unless target is outside spell range, out of mana, or LOS.
492 
493  bool _allowMove = false;
494  SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(e.action.cast.spell);
495  std::vector<SpellInfo::CostData> costs = spellInfo->CalcPowerCost(me, spellInfo->GetSchoolMask());
496  bool hasPower = true;
497  for (SpellInfo::CostData const& cost : costs)
498  {
499  if (cost.Power == POWER_HEALTH)
500  {
501  if (me->GetHealth() <= uint32(cost.Amount))
502  {
503  hasPower = false;
504  break;
505  }
506  }
507  else
508  {
509  if (me->GetPower(cost.Power) < cost.Amount)
510  {
511  hasPower = false;
512  break;
513  }
514  }
515 
516  }
517 
518  if (me->GetDistance(*itr) > spellInfo->GetMaxRange(true) ||
519  me->GetDistance(*itr) < spellInfo->GetMinRange(true) ||
520  !me->IsWithinLOSInMap(*itr) || !hasPower)
521  _allowMove = true;
522 
523  ENSURE_AI(SmartAI, me->AI())->SetCombatMove(_allowMove);
524  }
525 
526  me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
527  }
528  else if (go)
529  go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
530 
531  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST:: %s casts spell %u on target %s with castflags %u",
532  (me ? me->GetGUID() : go->GetGUID()).ToString().c_str(), e.action.cast.spell, (*itr)->GetGUID().ToString().c_str(), e.action.cast.flags);
533  }
534  else
535  TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
536  }
537 
538  delete targets;
539  break;
540  }
542  {
543  Unit* tempLastInvoker = GetLastInvoker();
544  if (!tempLastInvoker)
545  break;
546 
547  ObjectList* targets = GetTargets(e, unit);
548  if (!targets)
549  break;
550 
551  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
552  {
553  if (!IsUnit(*itr))
554  continue;
555 
556  if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
557  {
559  tempLastInvoker->InterruptNonMeleeSpells(false);
560 
561  tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0);
562  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %s casts spell %u on target %s with castflags %u",
563  tempLastInvoker->GetGUID().ToString().c_str(), e.action.cast.spell, (*itr)->GetGUID().ToString().c_str(), e.action.cast.flags);
564  }
565  else
566  TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
567  }
568 
569  delete targets;
570  break;
571  }
573  {
574  ObjectList* targets = GetTargets(e, unit);
575  if (!targets)
576  break;
577 
578  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
579  {
580  if (IsUnit(*itr))
581  {
582  (*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit());
583  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura %u to %s",
584  e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
585  }
586  }
587 
588  delete targets;
589  break;
590  }
592  {
593  ObjectList* targets = GetTargets(e, unit);
594  if (!targets)
595  break;
596 
597  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
598  {
599  if (IsGameObject(*itr))
600  {
601  // Activate
602  (*itr)->ToGameObject()->SetLootState(GO_READY);
603  (*itr)->ToGameObject()->UseDoorOrButton(0, false, unit);
604  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. %s (entry: %u) activated",
605  (*itr)->GetGUID().ToString().c_str(), (*itr)->GetEntry());
606  }
607  }
608 
609  delete targets;
610  break;
611  }
613  {
614  ObjectList* targets = GetTargets(e, unit);
615  if (!targets)
616  break;
617 
618  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
619  {
620  if (IsGameObject(*itr))
621  {
622  (*itr)->ToGameObject()->ResetDoorOrButton();
623  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RESET_GOBJECT. %s (entry: %u) reset",
624  (*itr)->GetGUID().ToString().c_str(), (*itr)->GetEntry());
625  }
626  }
627 
628  delete targets;
629  break;
630  }
632  {
633  ObjectList* targets = GetTargets(e, unit);
634  if (!targets)
635  break;
636 
637  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
638  {
639  if (IsUnit(*itr))
640  {
641  (*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_EMOTESTATE, e.action.emote.emote);
642  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. %s set emotestate to %u",
643  (*itr)->GetGUID().ToString().c_str(), e.action.emote.emote);
644  }
645  }
646 
647  delete targets;
648  break;
649  }
651  {
652  ObjectList* targets = GetTargets(e, unit);
653  if (!targets)
654  break;
655 
656  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
657  {
658  if (IsUnit(*itr))
659  {
660  if (!e.action.unitFlag.type)
661  {
662  (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
663  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. %s added flag %u to UNIT_FIELD_FLAGS",
664  (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
665  }
666  else
667  {
668  (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
669  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. %s added flag %u to UNIT_FIELD_FLAGS_2",
670  (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
671  }
672  }
673  }
674 
675  delete targets;
676  break;
677  }
679  {
680  ObjectList* targets = GetTargets(e, unit);
681  if (!targets)
682  break;
683 
684  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
685  {
686  if (IsUnit(*itr))
687  {
688  if (!e.action.unitFlag.type)
689  {
690  (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
691  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. %s removed flag %u to UNIT_FIELD_FLAGS",
692  (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
693  }
694  else
695  {
696  (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
697  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. %s removed flag %u to UNIT_FIELD_FLAGS_2",
698  (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
699  }
700  }
701  }
702 
703  delete targets;
704  break;
705  }
707  {
708  if (!IsSmart())
709  break;
710 
711  ENSURE_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack != 0);
712  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: %s bool on = %u",
713  me->GetGUID().ToString().c_str(), e.action.autoAttack.attack);
714  break;
715  }
717  {
718  if (!IsSmart())
719  break;
720 
721  bool move = e.action.combatMove.move != 0;
722  ENSURE_AI(SmartAI, me->AI())->SetCombatMove(move);
723  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: %s bool on = %u",
724  me->GetGUID().ToString().c_str(), e.action.combatMove.move);
725  break;
726  }
728  {
729  if (!GetBaseObject())
730  break;
731 
732  SetPhase(e.action.setEventPhase.phase);
733  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EVENT_PHASE: %s set event phase %u",
734  GetBaseObject()->GetGUID().ToString().c_str(), e.action.setEventPhase.phase);
735  break;
736  }
738  {
739  if (!GetBaseObject())
740  break;
741 
744  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INC_EVENT_PHASE: %s inc event phase by %u, "
745  "decrease by %u", GetBaseObject()->GetGUID().ToString().c_str(), e.action.incEventPhase.inc, e.action.incEventPhase.dec);
746  break;
747  }
748  case SMART_ACTION_EVADE:
749  {
750  if (!me)
751  break;
752 
753  me->AI()->EnterEvadeMode();
754  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_EVADE: %s EnterEvadeMode", me->GetGUID().ToString().c_str());
755  break;
756  }
758  {
759  if (!me)
760  break;
761 
763  if (e.action.flee.withEmote)
764  {
767  }
768  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: %s DoFleeToGetAssistance", me->GetGUID().ToString().c_str());
769  break;
770  }
772  {
773  if (!unit)
774  break;
775 
776  if (IsPlayer(unit) && GetBaseObject())
777  {
778  unit->ToPlayer()->GroupEventHappens(e.action.quest.quest, GetBaseObject());
779  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: %s, group credit for quest %u",
780  unit->GetGUID().ToString().c_str(), e.action.quest.quest);
781  }
782 
783  // Special handling for vehicles
784  if (Vehicle* vehicle = unit->GetVehicleKit())
785  for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
786  if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid))
787  player->GroupEventHappens(e.action.quest.quest, GetBaseObject());
788  break;
789  }
791  {
792  if (!me)
793  break;
794 
795  me->CombatStop(true);
796  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_COMBAT_STOP: %s CombatStop", me->GetGUID().ToString().c_str());
797  break;
798  }
800  {
801  ObjectList* targets = GetTargets(e, unit);
802  if (!targets)
803  break;
804 
805  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
806  {
807  if (!IsUnit(*itr))
808  continue;
809 
810  if (e.action.removeAura.spell)
811  {
812  if (e.action.removeAura.charges)
813  {
814  if (Aura* aur = (*itr)->ToUnit()->GetAura(e.action.removeAura.spell))
815  aur->ModCharges(-static_cast<int32>(e.action.removeAura.charges), AURA_REMOVE_BY_EXPIRE);
816  }
817  else
818  (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
819  }
820  else
821  (*itr)->ToUnit()->RemoveAllAuras();
822 
823  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: %s, spell %u",
824  (*itr)->GetGUID().ToString().c_str(), e.action.removeAura.spell);
825  }
826 
827  delete targets;
828  break;
829  }
830  case SMART_ACTION_FOLLOW:
831  {
832  if (!IsSmart())
833  break;
834 
835  ObjectList* targets = GetTargets(e, unit);
836  if (!targets)
837  {
838  ENSURE_AI(SmartAI, me->AI())->StopFollow();
839  break;
840  }
841 
842  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
843  {
844  if (IsUnit(*itr))
845  {
846  ENSURE_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), (float)e.action.follow.dist, (float)e.action.follow.angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType);
847  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: %s following target %s",
848  me->GetGUID().ToString().c_str(), (*itr)->GetGUID().ToString().c_str());
849  break;
850  }
851  }
852 
853  delete targets;
854  break;
855  }
857  {
858  if (!GetBaseObject())
859  break;
860 
862  phases[0] = e.action.randomPhase.phase1;
863  phases[1] = e.action.randomPhase.phase2;
864  phases[2] = e.action.randomPhase.phase3;
865  phases[3] = e.action.randomPhase.phase4;
866  phases[4] = e.action.randomPhase.phase5;
867  phases[5] = e.action.randomPhase.phase6;
869  uint32 count = 0;
870  for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
871  {
872  if (phases[i] > 0)
873  {
874  temp[count] = phases[i];
875  ++count;
876  }
877  }
878 
879  if (count == 0)
880  break;
881 
882  uint32 phase = temp[urand(0, count - 1)];
883  SetPhase(phase);
884  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: %s sets event phase to %u",
885  GetBaseObject()->GetGUID().ToString().c_str(), phase);
886  break;
887  }
889  {
890  if (!GetBaseObject())
891  break;
892 
893  uint32 phase = urand(e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax);
894  SetPhase(phase);
895  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE_RANGE: %s sets event phase to %u",
896  GetBaseObject()->GetGUID().ToString().c_str(), phase);
897  break;
898  }
900  {
901  if (e.target.type == SMART_TARGET_NONE || e.target.type == SMART_TARGET_SELF) // Loot recipient and his group members
902  {
903  if (!me)
904  break;
905 
906  if (Player* player = me->GetLootRecipient())
907  {
908  player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player);
909  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: %s, Killcredit: %u",
910  player->GetGUID().ToString().c_str(), e.action.killedMonster.creature);
911  }
912  }
913  else // Specific target type
914  {
915  ObjectList* targets = GetTargets(e, unit);
916  if (!targets)
917  break;
918 
919  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
920  {
921  if (IsPlayer(*itr))
922  {
923  (*itr)->ToPlayer()->KilledMonsterCredit(e.action.killedMonster.creature);
924  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: %s, Killcredit: %u",
925  (*itr)->GetGUID().ToString().c_str(), e.action.killedMonster.creature);
926  }
927  else if (IsUnit(*itr)) // Special handling for vehicles
928  if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
929  for (SeatMap::iterator seatItr = vehicle->Seats.begin(); seatItr != vehicle->Seats.end(); ++seatItr)
930  if (Player* player = ObjectAccessor::FindPlayer(seatItr->second.Passenger.Guid))
931  player->KilledMonsterCredit(e.action.killedMonster.creature);
932  }
933 
934  delete targets;
935  }
936  break;
937  }
939  {
940  WorldObject* obj = GetBaseObject();
941  if (!obj)
942  obj = unit;
943 
944  if (!obj)
945  break;
946 
947  InstanceScript* instance = obj->GetInstanceScript();
948  if (!instance)
949  {
950  TC_LOG_ERROR("sql.sql", "SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid " SI64FMTD "", e.GetEventType(), e.entryOrGuid);
951  break;
952  }
953 
954  instance->SetData(e.action.setInstanceData.field, e.action.setInstanceData.data);
955  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA: Field: %u, data: %u",
956  e.action.setInstanceData.field, e.action.setInstanceData.data);
957  break;
958  }
960  {
961  WorldObject* obj = GetBaseObject();
962  if (!obj)
963  obj = unit;
964 
965  if (!obj)
966  break;
967 
968  InstanceScript* instance = obj->GetInstanceScript();
969  if (!instance)
970  {
971  TC_LOG_ERROR("sql.sql", "SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid " SI64FMTD "", e.GetEventType(), e.entryOrGuid);
972  break;
973  }
974 
975  ObjectList* targets = GetTargets(e, unit);
976  if (!targets)
977  break;
978 
979  instance->SetGuidData(e.action.setInstanceData64.field, targets->front()->GetGUID());
980  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: %s",
981  e.action.setInstanceData64.field, targets->front()->GetGUID().ToString().c_str());
982 
983  delete targets;
984  break;
985  }
987  {
988  ObjectList* targets = GetTargets(e, unit);
989 
990  if (!targets)
991  break;
992 
993  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
994  if (IsCreature(*itr))
995  (*itr)->ToCreature()->UpdateEntry(e.action.updateTemplate.creature);
996 
997  delete targets;
998  break;
999  }
1000  case SMART_ACTION_DIE:
1001  {
1002  if (me && !me->isDead())
1003  {
1004  me->KillSelf();
1005  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_DIE: %s", me->GetGUID().ToString().c_str());
1006  }
1007  break;
1008  }
1010  {
1011  if (me)
1012  {
1014  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: %s", me->GetGUID().ToString().c_str());
1015  }
1016  break;
1017  }
1019  {
1020  if (me)
1021  {
1022  me->CallForHelp((float)e.action.callHelp.range);
1023  if (e.action.callHelp.withEmote)
1024  {
1027  }
1028  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: %s", me->GetGUID().ToString().c_str());
1029  }
1030  break;
1031  }
1033  {
1034  if (me)
1035  {
1036  me->SetSheath(SheathState(e.action.setSheath.sheath));
1037  TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_SHEATH: %s, State: %u",
1038  me->GetGUID().ToString().c_str(), e.action.setSheath.sheath);
1039  }
1040  break;
1041  }
1043  {
1044  ObjectList* targets = GetTargets(e, unit);
1045 
1046  if (!targets)
1047  break;
1048 
1049  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1050  {
1051  if (Creature* target = (*itr)->ToCreature())
1052  {
1053  if (target->IsAlive() && IsSmart(target))
1054  {
1055  ENSURE_AI(SmartAI, target->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1); // Next tick
1056  ENSURE_AI(SmartAI, target->AI())->StartDespawn();
1057  }
1058  else
1059  target->DespawnOrUnsummon(e.action.forceDespawn.delay);
1060  }
1061  else if (GameObject* goTarget = (*itr)->ToGameObject())
1062  {
1063  if (IsSmartGO(goTarget))
1064  goTarget->SetRespawnTime(e.action.forceDespawn.delay + 1);
1065  }
1066  }
1067 
1068  delete targets;
1069  break;
1070  }
1072  {
1073  ObjectList* targets = GetTargets(e, unit);
1074 
1075  if (!targets)
1076  break;
1077 
1078  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1079  (*itr)->SetInPhase(e.action.ingamePhaseId.id, true, e.action.ingamePhaseId.apply == 1);
1080 
1081  delete targets;
1082  break;
1083  }
1085  {
1086  ObjectList* targets = GetTargets(e, unit);
1087 
1088  if (!targets)
1089  break;
1090 
1091  std::set<uint32> phases = sDB2Manager.GetPhasesForGroup(e.action.ingamePhaseGroup.groupId);
1092 
1093  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1094  for (auto phase : phases)
1095  (*itr)->SetInPhase(phase, true, e.action.ingamePhaseGroup.apply == 1);
1096 
1097  delete targets;
1098  break;
1099  }
1101  {
1102  ObjectList* targets = GetTargets(e, unit);
1103  if (!targets)
1104  break;
1105 
1106  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1107  {
1108  if (!IsUnit(*itr))
1109  continue;
1110 
1111  if (e.action.morphOrMount.creature || e.action.morphOrMount.model)
1112  {
1113  if (e.action.morphOrMount.creature > 0)
1114  {
1115  if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
1116  (*itr)->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo));
1117  }
1118  else
1119  (*itr)->ToUnit()->Mount(e.action.morphOrMount.model);
1120  }
1121  else
1122  (*itr)->ToUnit()->Dismount();
1123  }
1124 
1125  delete targets;
1126  break;
1127  }
1129  {
1130  if (!me)
1131  break;
1132 
1133  SmartAI* ai = CAST_AI(SmartAI, me->AI());
1134 
1135  if (!ai)
1136  break;
1137 
1138  if (e.action.invincHP.percent)
1140  else
1142 
1143  break;
1144  }
1145  case SMART_ACTION_SET_DATA:
1146  {
1147  ObjectList* targets = GetTargets(e, unit);
1148  if (!targets)
1149  break;
1150 
1151  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1152  {
1153  if (IsCreature(*itr))
1154  (*itr)->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
1155  else if (IsGameObject(*itr))
1156  (*itr)->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
1157  }
1158 
1159  delete targets;
1160  break;
1161  }
1163  {
1164  if (!me)
1165  break;
1166 
1167  float x, y, z;
1168  me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)e.action.moveRandom.distance);
1170  break;
1171  }
1172  case SMART_ACTION_RISE_UP:
1173  {
1174  if (!me)
1175  break;
1176 
1178  break;
1179  }
1181  {
1182  if (me)
1183  me->SetVisible(e.action.visibility.state != 0);
1184  break;
1185  }
1187  {
1188  if (WorldObject* baseObj = GetBaseObject())
1189  baseObj->setActive(e.action.active.state != 0);
1190 
1191  break;
1192  }
1194  {
1195  if (!me)
1196  break;
1197 
1198  ObjectList* targets = GetTargets(e, unit);
1199  if (!targets)
1200  break;
1201 
1202  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1203  {
1204  if (IsUnit(*itr))
1205  {
1206  me->AI()->AttackStart((*itr)->ToUnit());
1207  break;
1208  }
1209  }
1210 
1211  delete targets;
1212  break;
1213  }
1215  {
1216  ObjectList* targets = GetTargets(e, unit);
1217  if (targets)
1218  {
1219  float x, y, z, o;
1220  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1221  {
1222  (*itr)->GetPosition(x, y, z, o);
1223  x += e.target.x;
1224  y += e.target.y;
1225  z += e.target.z;
1226  o += e.target.o;
1227  if (Creature* summon = GetBaseObject()->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
1228  if (e.action.summonCreature.attackInvoker)
1229  summon->AI()->AttackStart((*itr)->ToUnit());
1230  }
1231 
1232  delete targets;
1233  }
1234 
1236  break;
1237 
1239  if (unit && e.action.summonCreature.attackInvoker)
1240  summon->AI()->AttackStart(unit);
1241  break;
1242  }
1244  {
1245  if (!GetBaseObject())
1246  break;
1247 
1248  ObjectList* targets = GetTargets(e, unit);
1249  if (targets)
1250  {
1251  float x, y, z, o;
1252  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1253  {
1254  if (!IsUnit(*itr))
1255  continue;
1256 
1257  (*itr)->GetPosition(x, y, z, o);
1258  x += e.target.x;
1259  y += e.target.y;
1260  z += e.target.z;
1261  o += e.target.o;
1262  GetBaseObject()->SummonGameObject(e.action.summonGO.entry, x, y, z, o, 0, 0, 0, 0, e.action.summonGO.despawnTime);
1263  }
1264 
1265  delete targets;
1266  }
1267 
1269  break;
1270 
1271  GetBaseObject()->SummonGameObject(e.action.summonGO.entry, e.target.x, e.target.y, e.target.z, e.target.o, 0, 0, 0, 0, e.action.summonGO.despawnTime);
1272  break;
1273  }
1275  {
1276  ObjectList* targets = GetTargets(e, unit);
1277  if (!targets)
1278  break;
1279 
1280  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1281  {
1282  if (!IsUnit(*itr))
1283  continue;
1284 
1285  (*itr)->ToUnit()->KillSelf();
1286  }
1287 
1288  delete targets;
1289  break;
1290  }
1292  {
1293  InstallTemplate(e);
1294  break;
1295  }
1296  case SMART_ACTION_ADD_ITEM:
1297  {
1298  ObjectList* targets = GetTargets(e, unit);
1299  if (!targets)
1300  break;
1301 
1302  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1303  {
1304  if (!IsPlayer(*itr))
1305  continue;
1306 
1307  (*itr)->ToPlayer()->AddItem(e.action.item.entry, e.action.item.count);
1308  }
1309 
1310  delete targets;
1311  break;
1312  }
1314  {
1315  ObjectList* targets = GetTargets(e, unit);
1316  if (!targets)
1317  break;
1318 
1319  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1320  {
1321  if (!IsPlayer(*itr))
1322  continue;
1323 
1324  (*itr)->ToPlayer()->DestroyItemCount(e.action.item.entry, e.action.item.count, true);
1325  }
1326 
1327  delete targets;
1328  break;
1329  }
1331  {
1332  ObjectList* targets = GetTargets(e, unit);
1333  StoreTargetList(targets, e.action.storeTargets.id);
1334  break;
1335  }
1336  case SMART_ACTION_TELEPORT:
1337  {
1338  ObjectList* targets = GetTargets(e, unit);
1339  if (!targets)
1340  break;
1341 
1342  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1343  {
1344  if (IsPlayer(*itr))
1345  (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o);
1346  else if (IsCreature(*itr))
1347  (*itr)->ToCreature()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o);
1348  }
1349 
1350  delete targets;
1351  break;
1352  }
1353  case SMART_ACTION_SET_FLY:
1354  {
1355  if (!IsSmart())
1356  break;
1357 
1358  ENSURE_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly != 0);
1359  break;
1360  }
1361  case SMART_ACTION_SET_RUN:
1362  {
1363  if (!IsSmart())
1364  break;
1365 
1366  ENSURE_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run != 0);
1367  break;
1368  }
1369  case SMART_ACTION_SET_SWIM:
1370  {
1371  if (!IsSmart())
1372  break;
1373 
1374  ENSURE_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim != 0);
1375  break;
1376  }
1378  {
1379  if (ObjectList* targets = GetTargets(e, unit))
1380  {
1381  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1382  {
1383  if (IsCreature(*itr))
1384  {
1385  if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()))
1386  ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
1387  else
1388  TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartAI, skipping");
1389  }
1390  else if (IsGameObject(*itr))
1391  {
1392  if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI()))
1393  ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
1394  else
1395  TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartGameObjectAI, skipping");
1396  }
1397  }
1398 
1399  delete targets;
1400  }
1401  else
1402  StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
1403 
1404  break;
1405  }
1406  case SMART_ACTION_WP_START:
1407  {
1408  if (!IsSmart())
1409  break;
1410 
1411  bool run = e.action.wpStart.run != 0;
1412  uint32 entry = e.action.wpStart.pathID;
1413  bool repeat = e.action.wpStart.repeat != 0;
1414  ObjectList* targets = GetTargets(e, unit);
1416  me->SetReactState((ReactStates)e.action.wpStart.reactState);
1417  ENSURE_AI(SmartAI, me->AI())->StartPath(run, entry, repeat, unit);
1418 
1419  uint32 quest = e.action.wpStart.quest;
1420  uint32 DespawnTime = e.action.wpStart.despawnTime;
1421  ENSURE_AI(SmartAI, me->AI())->mEscortQuestID = quest;
1422  ENSURE_AI(SmartAI, me->AI())->SetDespawnTime(DespawnTime);
1423  break;
1424  }
1425  case SMART_ACTION_WP_PAUSE:
1426  {
1427  if (!IsSmart())
1428  break;
1429 
1430  uint32 delay = e.action.wpPause.delay;
1431  ENSURE_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true);
1432  break;
1433  }
1434  case SMART_ACTION_WP_STOP:
1435  {
1436  if (!IsSmart())
1437  break;
1438 
1439  uint32 DespawnTime = e.action.wpStop.despawnTime;
1440  uint32 quest = e.action.wpStop.quest;
1441  bool fail = e.action.wpStop.fail != 0;
1442  ENSURE_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail);
1443  break;
1444  }
1446  {
1447  if (!IsSmart())
1448  break;
1449 
1450  ENSURE_AI(SmartAI, me->AI())->ResumePath();
1451  break;
1452  }
1454  {
1455  if (!me)
1456  break;
1457 
1458  if (e.GetTargetType() == SMART_TARGET_SELF)
1459  me->SetFacingTo((me->GetTransport() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
1460  else if (e.GetTargetType() == SMART_TARGET_POSITION)
1461  me->SetFacingTo(e.target.o);
1462  else if (ObjectList* targets = GetTargets(e, unit))
1463  {
1464  if (!targets->empty())
1465  me->SetFacingToObject(*targets->begin());
1466 
1467  delete targets;
1468  }
1469 
1470  break;
1471  }
1473  {
1474  ObjectList* targets = GetTargets(e, unit);
1475  if (!targets)
1476  break;
1477 
1478  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1479  {
1480  if (!IsPlayer(*itr))
1481  continue;
1482 
1483  (*itr)->ToPlayer()->SendMovieStart(e.action.movie.entry);