Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SmartScript.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Cell.h"
7#include "CellImpl.h"
8#include "CreatureTextMgr.h"
9#include "DatabaseEnv.h"
10#include "GameEventMgr.h"
11#include "GossipDef.h"
12#include "GridDefines.h"
13#include "GridNotifiers.h"
14#include "GridNotifiersImpl.h"
15#include "Group.h"
16#include "InstanceScript.h"
17#include "Language.h"
18#include "MoveSplineInit.h"
19#include "ObjectDefines.h"
20#include "ObjectMgr.h"
21#include "ScriptedCreature.h"
22#include "ScriptedGossip.h"
23#include "SmartAI.h"
24#include "SmartScript.h"
25#include "SpellMgr.h"
26#include "Vehicle.h"
27
29{
30public:
31 SkyFireStringTextBuilder(WorldObject* obj, ChatMsg msgtype, int32 id, Language language, uint64 targetGUID)
32 : _source(obj), _msgType(msgtype), _textId(id), _language(language), _targetGUID(targetGUID)
33 {
34 }
35
36 size_t operator()(WorldPacket* data, LocaleConstant locale) const
37 {
38 std::string text = sObjectMgr->GetSkyFireString(_textId, locale);
39 std::string localizedName = _source->GetNameForLocaleIdx(locale);
40
41 *data << uint8(_msgType);
42 *data << uint32(_language);
43 *data << uint64(_source->GetGUID());
44 *data << uint32(1); // 2.1.0
45 *data << uint32(localizedName.size() + 1);
46 *data << localizedName;
47 size_t whisperGUIDpos = data->wpos();
48 *data << uint64(_targetGUID); // Unit Target
50 {
51 *data << uint32(1); // target name length
52 *data << uint8(0); // target name
53 }
54 *data << uint32(text.length() + 1);
55 *data << text;
56 *data << uint8(0); // ChatTag
57
58 return whisperGUIDpos;
59 }
60
66};
67
74
76{
77 for (ObjectListMap::iterator itr = mTargetStorage->begin(); itr != mTargetStorage->end(); ++itr)
78 delete itr->second;
79
80 delete mTargetStorage;
81}
82
84{
85 SetPhase(0);
87 for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
88 {
89 if (!((*i).event.event_flags & SMART_EVENT_FLAG_DONT_RESET))
90 {
91 InitTimer((*i));
92 (*i).runOnce = false;
93 }
94 }
96 mLastInvoker = 0;
97}
98
100{
101 if (meOrigGUID)
102 {
104 {
105 me = m;
106 go = NULL;
107 }
108 }
109 if (goOrigGUID)
110 {
112 {
113 me = NULL;
114 go = o;
115 }
116 }
117 goOrigGUID = 0;
118 meOrigGUID = 0;
119}
120
121void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
122{
123 for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
124 {
125 SMART_EVENT eventType = SMART_EVENT((*i).GetEventType());
126 if (eventType == SMART_EVENT_LINK)//special handling
127 continue;
128
129 if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/)
130 {
131 ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type);
133
134 if (sConditionMgr->IsObjectMeetToConditions(info, conds))
135 ProcessEvent(*i, unit, var0, var1, bvar, spell, gob);
136 }
137 }
138}
139
140void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
141{
142 //calc random
144 {
145 uint32 rnd = std::rand() % 100;
146 if (e.event.event_chance <= rnd)
147 return;
148 }
149 e.runOnce = true;//used for repeat check
150
151 if (unit)
152 mLastInvoker = unit->GetGUID();
153
154 if (Unit* tempInvoker = GetLastInvoker())
155 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: Invoker: %s (guidlow: %u)", tempInvoker->GetName().c_str(), tempInvoker->GetGUIDLow());
156
157 switch (e.GetActionType())
158 {
160 {
161 ObjectList* targets = GetTargets(e, unit);
162 Creature* talker = me;
163 Player* targetPlayer = NULL;
164 if (targets)
165 {
166 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
167 {
168 if (IsCreature((*itr)) && !(*itr)->ToCreature()->IsPet()) // Prevented sending text to pets.
169 {
170 talker = (*itr)->ToCreature();
171 break;
172 }
173 else if (IsPlayer((*itr)))
174 {
175 targetPlayer = (*itr)->ToPlayer();
176 break;
177 }
178 }
179
180 delete targets;
181 }
182
183 if (!talker)
184 break;
185
186 mTalkerEntry = talker->GetEntry();
189 Unit* talkTarget = NULL;
190 if (IsPlayer(GetLastInvoker())) // used for $vars in texts and whisper target
191 talkTarget = GetLastInvoker();
192 else
193 talkTarget = targetPlayer;
194
195 mUseTextTimer = true;
196 sCreatureTextMgr->SendChat(talker, uint8(e.action.talk.textGroupID), talkTarget);
197 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_TALK: talker: %s (GuidLow: %u), textGuid: %u",
198 talker->GetName().c_str(), talker->GetGUIDLow(), talkTarget ? talkTarget->GetGUIDLow() : 0);
199 break;
200 }
202 {
203 ObjectList* targets = GetTargets(e, unit);
204 if (targets)
205 {
206 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
207 {
208 if (IsCreature(*itr))
209 sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
210 else if (IsPlayer(*itr) && me)
211 {
212 Unit* templastInvoker = GetLastInvoker();
213 sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, ChatMsg::CHAT_MSG_ADDON, Language::LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, (*itr)->ToPlayer());
214 }
215 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (GuidLow: %u), textGroupId: %u",
216 (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), uint8(e.action.talk.textGroupID));
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 (IsUnit(*itr))
231 {
232 (*itr)->ToUnit()->HandleEmoteCommand(e.action.emote.emote);
233 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (GuidLow: %u), emote: %u",
234 (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.emote.emote);
235 }
236 }
237
238 delete targets;
239 }
240 break;
241 }
243 {
244 ObjectList* targets = GetTargets(e, unit);
245 if (targets)
246 {
247 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
248 {
249 if (IsUnit(*itr))
250 {
251 (*itr)->SendPlaySound(e.action.sound.sound, e.action.sound.onlySelf > 0);
252 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (GuidLow: %u), sound: %u, onlyself: %u",
253 (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.sound.sound, e.action.sound.onlySelf);
254 }
255 }
256
257 delete targets;
258 }
259 break;
260 }
262 {
263 ObjectList* targets = GetTargets(e, unit);
264 if (targets)
265 {
266 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
267 {
268 if (IsCreature(*itr))
269 {
271 {
272 (*itr)->ToCreature()->setFaction(e.action.faction.factionID);
273 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u",
274 (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.faction.factionID);
275 }
276 else
277 {
278 if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate((*itr)->ToCreature()->GetEntry()))
279 {
280 if ((*itr)->ToCreature()->getFaction() != ci->faction_A)
281 {
282 (*itr)->ToCreature()->setFaction(ci->faction_A);
283 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u",
284 (*itr)->GetEntry(), (*itr)->GetGUIDLow(), ci->faction_A);
285 }
286 }
287 }
288 }
289 }
290
291 delete targets;
292 }
293 break;
294 }
296 {
297 ObjectList* targets = GetTargets(e, unit);
298 if (!targets)
299 break;
300
301 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
302 {
303 if (!IsCreature(*itr))
304 continue;
305
307 {
308 //set model based on entry from creature_template
310 {
311 if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
312 {
313 uint32 displayId = ObjectMgr::ChooseDisplayId(ci);
314 (*itr)->ToCreature()->SetDisplayId(displayId);
315 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u",
316 (*itr)->GetEntry(), (*itr)->GetGUIDLow(), displayId);
317 }
318 }
319 //if no param1, then use value from param2 (modelId)
320 else
321 {
322 (*itr)->ToCreature()->SetDisplayId(e.action.morphOrMount.model);
323 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u",
324 (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.morphOrMount.model);
325 }
326 }
327 else
328 {
329 (*itr)->ToCreature()->DeMorph();
330 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u demorphs.",
331 (*itr)->GetEntry(), (*itr)->GetGUIDLow());
332 }
333 }
334
335 delete targets;
336 break;
337 }
339 {
340 ObjectList* targets = GetTargets(e, unit);
341 if (!targets)
342 break;
343
344 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
345 {
346 if (IsPlayer(*itr))
347 {
348 (*itr)->ToPlayer()->FailQuest(e.action.quest.quest);
349 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FAIL_QUEST: Player guidLow %u fails quest %u",
350 (*itr)->GetGUIDLow(), e.action.quest.quest);
351 }
352 }
353
354 delete targets;
355 break;
356 }
358 {
359 ObjectList* targets = GetTargets(e, unit);
360 if (!targets)
361 break;
362
363 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
364 {
365 if (IsPlayer(*itr))
366 if (Quest const* q = sObjectMgr->GetQuestTemplate(e.action.quest.quest))
367 {
368 (*itr)->ToPlayer()->AddQuest(q, NULL);
369 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_QUEST: Player guidLow %u add quest %u",
370 (*itr)->GetGUIDLow(), e.action.quest.quest);
371 }
372 }
373
374 delete targets;
375 break;
376 }
378 {
379 if (!me)
380 break;
381
382 me->SetReactState(ReactStates(e.action.react.state));
383 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_REACT_STATE: Creature guidLow %u set reactstate %u",
384 me->GetGUIDLow(), e.action.react.state);
385 break;
386 }
388 {
389 ObjectList* targets = GetTargets(e, unit);
390 if (!targets)
391 break;
392
394 emotes[0] = e.action.randomEmote.emote1;
395 emotes[1] = e.action.randomEmote.emote2;
396 emotes[2] = e.action.randomEmote.emote3;
397 emotes[3] = e.action.randomEmote.emote4;
398 emotes[4] = e.action.randomEmote.emote5;
399 emotes[5] = e.action.randomEmote.emote6;
401 uint32 count = 0;
402 for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
403 {
404 if (emotes[i])
405 {
406 temp[count] = emotes[i];
407 ++count;
408 }
409 }
410
411 if (count == 0)
412 {
413 delete targets;
414 break;
415 }
416
417 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
418 {
419 if (IsUnit(*itr))
420 {
421 uint32 emote = temp[std::rand() % count];
422 (*itr)->ToUnit()->HandleEmoteCommand(emote);
423 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature guidLow %u handle random emote %u",
424 (*itr)->GetGUIDLow(), emote);
425 }
426 }
427
428 delete targets;
429 break;
430 }
432 {
433 if (!me)
434 break;
435
436 ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
437 for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
438 {
439 if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid()))
440 {
441 me->getThreatManager().modifyThreatPercent(target, e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
442 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_ALL_PCT: Creature guidLow %u modify threat for unit %u, value %i",
443 me->GetGUIDLow(), target->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
444 }
445 }
446 break;
447 }
449 {
450 if (!me)
451 break;
452
453 ObjectList* targets = GetTargets(e, unit);
454 if (!targets)
455 break;
456
457 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
458 {
459 if (IsUnit(*itr))
460 {
461 me->getThreatManager().modifyThreatPercent((*itr)->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
462 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_SINGLE_PCT: Creature guidLow %u modify threat for unit %u, value %i",
463 me->GetGUIDLow(), (*itr)->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
464 }
465 }
466
467 delete targets;
468 break;
469 }
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 // Special handling for vehicles
479 if (IsUnit(*itr))
480 if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
481 for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
482 if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid))
483 player->AreaExploredOrEventHappens(e.action.quest.quest);
484
485 if (IsPlayer(*itr))
486 {
487 (*itr)->ToPlayer()->AreaExploredOrEventHappens(e.action.quest.quest);
488 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: Player guidLow %u credited quest %u",
489 (*itr)->GetGUIDLow(), e.action.quest.quest);
490 }
491 }
492
493 delete targets;
494 break;
495 }
497 {
498 if (!me)
499 break;
500
501 ObjectList* targets = GetTargets(e, unit);
502 if (!targets)
503 break;
504
505 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
506 {
507 if (!IsUnit(*itr))
508 continue;
509
510 if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
511 {
513 me->InterruptNonMeleeSpells(false);
514
515 me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
516 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST:: Creature %u casts spell %u on target %u with castflags %u",
517 me->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags);
518 }
519 else
520 SF_LOG_DEBUG("scripts.ai", "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*itr)->GetGUID(), (*itr)->GetEntry(), uint32((*itr)->GetTypeId()));
521 }
522
523 delete targets;
524 break;
525 }
527 {
528 Unit* tempLastInvoker = GetLastInvoker();
529 if (!tempLastInvoker)
530 break;
531
532 ObjectList* targets = GetTargets(e, unit);
533 if (!targets)
534 break;
535
536 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
537 {
538 if (!IsUnit(*itr))
539 continue;
540
541 if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
542 {
544 tempLastInvoker->InterruptNonMeleeSpells(false);
545
546 tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
547 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %u casts spell %u on target %u with castflags %u",
548 tempLastInvoker->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags);
549 }
550 else
551 SF_LOG_DEBUG("scripts.ai", "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*itr)->GetGUID(), (*itr)->GetEntry(), uint32((*itr)->GetTypeId()));
552 }
553
554 delete targets;
555 break;
556 }
558 {
559 ObjectList* targets = GetTargets(e, unit);
560 if (!targets)
561 break;
562
563 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
564 {
565 if (IsUnit(*itr))
566 {
567 (*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit());
568 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura %u to unit %u",
569 e.action.cast.spell, (*itr)->GetGUIDLow());
570 }
571 }
572
573 delete targets;
574 break;
575 }
577 {
578 ObjectList* targets = GetTargets(e, unit);
579 if (!targets)
580 break;
581
582 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
583 {
584 if (IsGameObject(*itr))
585 {
586 // Activate
587 (*itr)->ToGameObject()->SetLootState(LootState::GO_READY);
588 (*itr)->ToGameObject()->UseDoorOrButton(0, false, unit);
589 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject %u (entry: %u) activated",
590 (*itr)->GetGUIDLow(), (*itr)->GetEntry());
591 }
592 }
593
594 delete targets;
595 break;
596 }
598 {
599 ObjectList* targets = GetTargets(e, unit);
600 if (!targets)
601 break;
602
603 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
604 {
605 if (IsGameObject(*itr))
606 {
607 (*itr)->ToGameObject()->ResetDoorOrButton();
608 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RESET_GOBJECT. Gameobject %u (entry: %u) reset",
609 (*itr)->GetGUIDLow(), (*itr)->GetEntry());
610 }
611 }
612
613 delete targets;
614 break;
615 }
617 {
618 ObjectList* targets = GetTargets(e, unit);
619 if (!targets)
620 break;
621
622 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
623 {
624 if (IsUnit(*itr))
625 {
626 (*itr)->ToUnit()->SetUInt32Value(UNIT_FIELD_NPC_EMOTESTATE, e.action.emote.emote);
627 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. Unit %u set emotestate to %u",
628 (*itr)->GetGUIDLow(), e.action.emote.emote);
629 }
630 }
631
632 delete targets;
633 break;
634 }
636 {
637 ObjectList* targets = GetTargets(e, unit);
638 if (!targets)
639 break;
640
641 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
642 {
643 if (IsUnit(*itr))
644 {
645 if (!e.action.unitFlag.type)
646 {
647 (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
648 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS",
649 (*itr)->GetGUIDLow(), e.action.unitFlag.flag);
650 }
651 else
652 {
653 (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS2, e.action.unitFlag.flag);
654 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS2",
655 (*itr)->GetGUIDLow(), e.action.unitFlag.flag);
656 }
657 }
658 }
659
660 delete targets;
661 break;
662 }
664 {
665 ObjectList* targets = GetTargets(e, unit);
666 if (!targets)
667 break;
668
669 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
670 {
671 if (IsUnit(*itr))
672 {
673 if (!e.action.unitFlag.type)
674 {
675 (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
676 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS",
677 (*itr)->GetGUIDLow(), e.action.unitFlag.flag);
678 }
679 else
680 {
681 (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS2, e.action.unitFlag.flag);
682 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS2",
683 (*itr)->GetGUIDLow(), e.action.unitFlag.flag);
684 }
685 }
686 }
687
688 delete targets;
689 break;
690 }
692 {
693 if (!IsSmart())
694 break;
695
696 CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack);
697 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u",
698 me->GetGUIDLow(), e.action.autoAttack.attack);
699 break;
700 }
702 {
703 if (!IsSmart())
704 break;
705
706 bool move = e.action.combatMove.move;
707 CAST_AI(SmartAI, me->AI())->SetCombatMove(move);
708 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: Creature %u bool on = %u",
709 me->GetGUIDLow(), e.action.combatMove.move);
710 break;
711 }
713 {
714 if (!GetBaseObject())
715 break;
716
718 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EVENT_PHASE: Creature %u set event phase %u",
719 GetBaseObject()->GetGUIDLow(), e.action.setEventPhase.phase);
720 break;
721 }
723 {
724 if (!GetBaseObject())
725 break;
726
729 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INC_EVENT_PHASE: Creature %u inc event phase by %u, "
730 "decrease by %u", GetBaseObject()->GetGUIDLow(), e.action.incEventPhase.inc, e.action.incEventPhase.dec);
731 break;
732 }
734 {
735 if (!me)
736 break;
737
738 me->AI()->EnterEvadeMode();
739 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_EVADE: Creature %u EnterEvadeMode", me->GetGUIDLow());
740 break;
741 }
743 {
744 if (!me)
745 break;
746
747 me->DoFleeToGetAssistance();
748 if (e.action.flee.withEmote)
749 {
751 sCreatureTextMgr->SendChatPacket(me, builder, ChatMsg::CHAT_MSG_MONSTER_EMOTE);
752 }
753 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %u DoFleeToGetAssistance", me->GetGUIDLow());
754 break;
755 }
757 {
758 if (!unit)
759 break;
760
761 if (IsPlayer(unit) && GetBaseObject())
762 {
764 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player %u, group credit for quest %u",
765 unit->GetGUIDLow(), e.action.quest.quest);
766 }
767
768 // Special handling for vehicles
769 if (Vehicle* vehicle = unit->GetVehicleKit())
770 for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
771 if (Player* player = ObjectAccessor::FindPlayer(it->second.Passenger.Guid))
772 player->GroupEventHappens(e.action.quest.quest, GetBaseObject());
773 break;
774 }
776 {
777 ObjectList* targets = GetTargets(e, unit);
778 if (!targets)
779 break;
780
781 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
782 {
783 if (!IsUnit((*itr)))
784 continue;
785
786 if (e.action.removeAura.spell == 0)
787 (*itr)->ToUnit()->RemoveAllAuras();
788 else
789 (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
790
791 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u",
792 (*itr)->GetGUIDLow(), e.action.removeAura.spell);
793 }
794
795 delete targets;
796 break;
797 }
799 {
800 if (!IsSmart())
801 break;
802
803 ObjectList* targets = GetTargets(e, unit);
804 if (!targets)
805 break;
806
807 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
808 {
809 if (IsUnit((*itr)))
810 {
811 CAST_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);
812 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: Creature %u following target %u",
813 me->GetGUIDLow(), (*itr)->GetGUIDLow());
814 break;
815 }
816 }
817
818 delete targets;
819 break;
820 }
822 {
823 if (!GetBaseObject())
824 break;
825
827 phases[0] = e.action.randomPhase.phase1;
828 phases[1] = e.action.randomPhase.phase2;
829 phases[2] = e.action.randomPhase.phase3;
830 phases[3] = e.action.randomPhase.phase4;
831 phases[4] = e.action.randomPhase.phase5;
832 phases[5] = e.action.randomPhase.phase6;
834 uint32 count = 0;
835 for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
836 {
837 if (phases[i] > 0)
838 {
839 temp[count] = phases[i];
840 ++count;
841 }
842 }
843
844 if (count == 0)
845 break;
846
847 uint32 phase = temp[std::rand() % count];
848 SetPhase(phase);
849 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: Creature %u sets event phase to %u",
850 GetBaseObject()->GetGUIDLow(), phase);
851 break;
852 }
854 {
855 if (!GetBaseObject())
856 break;
857
860 uint32 phase = (phaseMax > phaseMin) ? (std::rand() % (phaseMax - phaseMin + 1) + phaseMin) : phaseMin;
861 SetPhase(phase);
862 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE_RANGE: Creature %u sets event phase to %u",
863 GetBaseObject()->GetGUIDLow(), phase);
864 break;
865 }
867 {
868 if (e.target.type == SMART_TARGET_NONE || e.target.type == SMART_TARGET_SELF) // Loot recipient and his group members
869 {
870 if (!me)
871 break;
872
873 if (Player* player = me->GetLootRecipient())
874 {
875 player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player);
876 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u",
877 player->GetGUIDLow(), e.action.killedMonster.creature);
878 }
879 }
880 else // Specific target type
881 {
882 ObjectList* targets = GetTargets(e, unit);
883 if (!targets)
884 break;
885
886 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
887 {
888 if (IsPlayer(*itr))
889 {
890 (*itr)->ToPlayer()->KilledMonsterCredit(e.action.killedMonster.creature);
891 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u",
892 (*itr)->GetGUIDLow(), e.action.killedMonster.creature);
893 }
894 else if (IsUnit(*itr)) // Special handling for vehicles
895 if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
896 for (SeatMap::iterator itr = vehicle->Seats.begin(); itr != vehicle->Seats.end(); ++itr)
897 if (Player* player = ObjectAccessor::FindPlayer(itr->second.Passenger.Guid))
898 player->KilledMonsterCredit(e.action.killedMonster.creature);
899 }
900
901 delete targets;
902 }
903 break;
904 }
906 {
907 WorldObject* obj = GetBaseObject();
908 if (!obj)
909 obj = unit;
910
911 if (!obj)
912 break;
913
914 InstanceScript* instance = obj->GetInstanceScript();
915 if (!instance)
916 {
917 SF_LOG_ERROR("sql.sql", "SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid);
918 break;
919 }
920
922 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA: Field: %u, data: %u",
924 break;
925 }
927 {
928 WorldObject* obj = GetBaseObject();
929 if (!obj)
930 obj = unit;
931
932 if (!obj)
933 break;
934
935 InstanceScript* instance = obj->GetInstanceScript();
936 if (!instance)
937 {
938 SF_LOG_ERROR("sql.sql", "SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid);
939 break;
940 }
941
942 ObjectList* targets = GetTargets(e, unit);
943 if (!targets)
944 break;
945
946 instance->SetData64(e.action.setInstanceData64.field, targets->front()->GetGUID());
947 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: " UI64FMTD,
948 e.action.setInstanceData64.field, targets->front()->GetGUID());
949
950 delete targets;
951 break;
952 }
954 {
955 if (!me || me->GetEntry() == e.action.updateTemplate.creature)
956 break;
957
959 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_UPDATE_TEMPLATE: Creature %u, Template: %u, Team: %u",
960 me->GetGUIDLow(), me->GetEntry(), e.action.updateTemplate.team ? HORDE : ALLIANCE);
961 break;
962 }
963 case SMART_ACTION_DIE:
964 {
965 if (me && !me->isDead())
966 {
967 me->Kill(me);
968 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature %u", me->GetGUIDLow());
969 }
970 break;
971 }
973 {
974 if (me)
975 {
976 me->SetInCombatWithZone();
977 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: Creature %u", me->GetGUIDLow());
978 }
979 break;
980 }
982 {
983 if (me)
984 {
985 me->CallForHelp((float)e.action.callHelp.range);
987 {
989 sCreatureTextMgr->SendChatPacket(me, builder, ChatMsg::CHAT_MSG_MONSTER_EMOTE);
990 }
991 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %u", me->GetGUIDLow());
992 }
993 break;
994 }
996 {
997 if (me)
998 {
999 me->SetSheath(SheathState(e.action.setSheath.sheath));
1000 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_SHEATH: Creature %u, State: %u",
1001 me->GetGUIDLow(), e.action.setSheath.sheath);
1002 }
1003 break;
1004 }
1006 {
1007 if (!IsSmart())
1008 break;
1009
1010 // The AI is only updated if the creature is alive
1011 if (me->IsAlive())
1012 {
1013 CAST_AI(SmartAI, me->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1); // Next tick
1014 CAST_AI(SmartAI, me->AI())->StartDespawn();
1015 }
1016 // Otherwise we call the despawn directly
1017 else
1018 me->DespawnOrUnsummon(e.action.forceDespawn.delay);
1019
1020 break;
1021 }
1023 {
1024 //break;
1025 ObjectList* targets = GetTargets(e, unit);
1026
1027 if (!targets)
1028 break;
1029
1030 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1031 (*itr)->ToUnit()->SetPhased(e.action.ingamePhaseId.id, true, e.action.ingamePhaseId.apply);
1032
1033 delete targets;
1034 break;
1035 }
1037 {
1038 ObjectList* targets = GetTargets(e, unit);
1039 if (!targets)
1040 break;
1041
1042 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1043 {
1044 if (!IsUnit(*itr))
1045 continue;
1046
1048 {
1049 if (e.action.morphOrMount.creature > 0)
1050 {
1051 if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
1052 (*itr)->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo));
1053 }
1054 else
1055 (*itr)->ToUnit()->Mount(e.action.morphOrMount.model);
1056 }
1057 else
1058 (*itr)->ToUnit()->Dismount();
1059 }
1060
1061 delete targets;
1062 break;
1063 }
1065 {
1066 if (!me)
1067 break;
1068
1069 SmartAI* ai = CAST_AI(SmartAI, me->AI());
1070
1071 if (!ai)
1072 break;
1073
1074 if (e.action.invincHP.percent)
1075 ai->SetInvincibilityHpLevel(me->CountPctFromMaxHealth(e.action.invincHP.percent));
1076 else
1078 break;
1079 }
1081 {
1082 ObjectList* targets = GetTargets(e, unit);
1083 if (!targets)
1084 break;
1085
1086 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1087 {
1088 if (IsCreature(*itr))
1089 (*itr)->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
1090 else if (IsGameObject(*itr))
1091 (*itr)->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
1092 }
1093
1094 delete targets;
1095 break;
1096 }
1098 {
1099 if (!me)
1100 break;
1101
1102 float x, y, z;
1103 me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)e.action.moveRandom.distance);
1104 me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, x, y, z);
1105 break;
1106 }
1108 {
1109 if (me)
1110 me->SetVisible(e.action.visibility.state);
1111 break;
1112 }
1114 {
1115 if (WorldObject* baseObj = GetBaseObject())
1116 baseObj->setActive(e.action.active.state);
1117 break;
1118 }
1120 {
1121 if (!me)
1122 break;
1123
1124 ObjectList* targets = GetTargets(e, unit);
1125 if (!targets)
1126 break;
1127
1128 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1129 {
1130 if (IsUnit(*itr))
1131 {
1132 me->AI()->AttackStart((*itr)->ToUnit());
1133 break;
1134 }
1135 }
1136
1137 delete targets;
1138 break;
1139 }
1141 {
1142 ObjectList* targets = GetTargets(e, unit);
1143 if (targets)
1144 {
1145 float x, y, z, o;
1146 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1147 {
1148 (*itr)->GetPosition(x, y, z, o);
1149 x += e.target.x;
1150 y += e.target.y;
1151 z += e.target.z;
1152 o += e.target.o;
1155 summon->AI()->AttackStart((*itr)->ToUnit());
1156 }
1157
1158 delete targets;
1159 }
1160
1162 break;
1163
1165 if (unit && e.action.summonCreature.attackInvoker)
1166 summon->AI()->AttackStart(unit);
1167 break;
1168 }
1170 {
1171 if (!GetBaseObject())
1172 break;
1173
1174 ObjectList* targets = GetTargets(e, unit);
1175 if (targets)
1176 {
1177 float x, y, z, o;
1178 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1179 {
1180 if (!IsUnit(*itr))
1181 continue;
1182
1183 (*itr)->GetPosition(x, y, z, o);
1184 x += e.target.x;
1185 y += e.target.y;
1186 z += e.target.z;
1187 o += e.target.o;
1189 }
1190
1191 delete targets;
1192 }
1193
1195 break;
1196
1198 break;
1199 }
1201 {
1202 ObjectList* targets = GetTargets(e, unit);
1203 if (!targets)
1204 break;
1205
1206 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1207 {
1208 if (!IsUnit(*itr))
1209 continue;
1210
1211 (*itr)->ToUnit()->Kill((*itr)->ToUnit());
1212 }
1213
1214 delete targets;
1215 break;
1216 }
1218 {
1219 InstallTemplate(e);
1220 break;
1221 }
1223 {
1224 ObjectList* targets = GetTargets(e, unit);
1225 if (!targets)
1226 break;
1227
1228 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1229 {
1230 if (!IsPlayer(*itr))
1231 continue;
1232
1233 (*itr)->ToPlayer()->AddItem(e.action.item.entry, e.action.item.count);
1234 }
1235
1236 delete targets;
1237 break;
1238 }
1240 {
1241 ObjectList* targets = GetTargets(e, unit);
1242 if (!targets)
1243 break;
1244
1245 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1246 {
1247 if (!IsPlayer(*itr))
1248 continue;
1249
1250 (*itr)->ToPlayer()->DestroyItemCount(e.action.item.entry, e.action.item.count, true);
1251 }
1252
1253 delete targets;
1254 break;
1255 }
1257 {
1258 if (mStoredDecimals.find(e.action.storeVar.id) != mStoredDecimals.end())
1261 break;
1262 }
1264 {
1265 ObjectList* targets = GetTargets(e, unit);
1267 break;
1268 }
1270 {
1271 ObjectList* targets = GetTargets(e, unit);
1272 if (!targets)
1273 break;
1274
1275 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1276 {
1277 if (IsPlayer(*itr))
1278 (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o);
1279 else if (IsCreature(*itr))
1280 (*itr)->ToCreature()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o);
1281 }
1282
1283 delete targets;
1284 break;
1285 }
1287 {
1288 if (!IsSmart())
1289 break;
1290
1291 CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly);
1292 break;
1293 }
1295 {
1296 if (!IsSmart())
1297 break;
1298
1299 CAST_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run);
1300 break;
1301 }
1303 {
1304 if (!IsSmart())
1305 break;
1306
1307 CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim);
1308 break;
1309 }
1311 {
1312 if (!IsSmart())
1313 break;
1314
1315 bool run = e.action.wpStart.run;
1316 uint32 entry = e.action.wpStart.pathID;
1317 bool repeat = e.action.wpStart.repeat;
1318 ObjectList* targets = GetTargets(e, unit);
1320 me->SetReactState((ReactStates)e.action.wpStart.reactState);
1321 CAST_AI(SmartAI, me->AI())->StartPath(run, entry, repeat, unit);
1322
1323 uint32 quest = e.action.wpStart.quest;
1324 uint32 DespawnTime = e.action.wpStart.despawnTime;
1325 CAST_AI(SmartAI, me->AI())->mEscortQuestID = quest;
1326 CAST_AI(SmartAI, me->AI())->SetDespawnTime(DespawnTime);
1327 break;
1328 }
1330 {
1331 if (!IsSmart())
1332 break;
1333
1334 uint32 delay = e.action.wpPause.delay;
1335 CAST_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true);
1336 break;
1337 }
1339 {
1340 if (!IsSmart())
1341 break;
1342
1343 uint32 DespawnTime = e.action.wpStop.despawnTime;
1344 uint32 quest = e.action.wpStop.quest;
1345 bool fail = e.action.wpStop.fail;
1346 CAST_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail);
1347 break;
1348 }
1350 {
1351 if (!IsSmart())
1352 break;
1353
1354 CAST_AI(SmartAI, me->AI())->ResumePath();
1355 break;
1356 }
1358 {
1359 if (!me)
1360 break;
1361
1363 me->SetFacingTo((me->GetTransport() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
1364 else if (e.GetTargetType() == SMART_TARGET_POSITION)
1365 me->SetFacingTo(e.target.o);
1366 else if (ObjectList* targets = GetTargets(e, unit))
1367 {
1368 if (!targets->empty())
1369 me->SetFacingToObject(*targets->begin());
1370
1371 delete targets;
1372 }
1373
1374 break;
1375 }
1377 {
1378 ObjectList* targets = GetTargets(e, unit);
1379 if (!targets)
1380 break;
1381
1382 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1383 {
1384 if (!IsPlayer(*itr))
1385 continue;
1386
1387 (*itr)->ToPlayer()->SendMovieStart(e.action.movie.entry);
1388 }
1389
1390 delete targets;
1391 break;
1392 }
1394 {
1395 if (!IsSmart())
1396 break;
1397
1398 WorldObject* target = NULL;
1399
1406 {
1407 ObjectList* targets = GetTargets(e, unit);
1408 if (!targets)
1409 break;
1410
1411 target = targets->front();
1412 delete targets;
1413 }
1414
1415 if (!target)
1416 {
1417 G3D::Vector3 dest(e.target.x, e.target.y, e.target.z);
1419 if (TransportBase* trans = me->GetDirectTransport())
1420 trans->CalculatePassengerPosition(dest.x, dest.y, dest.z);
1421
1422 me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, dest.x, dest.y, dest.z);
1423 }
1424 else
1425 me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
1426 break;
1427 }
1429 {
1430 ObjectList* targets = GetTargets(e, unit);
1431 if (!targets)
1432 break;
1433
1434 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1435 {
1436 if (IsCreature(*itr))
1437 (*itr)->ToCreature()->Respawn();
1438 else if (IsGameObject(*itr))
1439 (*itr)->ToGameObject()->SetRespawnTime(e.action.RespawnTarget.goRespawnTime);
1440 }
1441
1442 delete targets;
1443 break;
1444 }
1446 {
1447 ObjectList* targets = GetTargets(e, unit);
1448 if (!targets)
1449 break;
1450
1451 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1452 if (IsPlayer(*itr))
1453 (*itr)->ToPlayer()->PlayerTalkClass->SendCloseGossip();
1454
1455 delete targets;
1456 break;
1457 }
1458 case SMART_ACTION_EQUIP:
1459 {
1460 ObjectList* targets = GetTargets(e, unit);
1461 if (!targets)
1462 break;
1463
1464 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1465 {
1466 if (Creature* npc = (*itr)->ToCreature())
1467 {
1468 uint32 slot[3];
1469 int8 equipId = (int8)e.action.equip.entry;
1470 if (equipId)
1471 {
1472 EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(npc->GetEntry(), equipId);
1473 if (!einfo)
1474 {
1475 SF_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry());
1476 break;
1477 }
1478
1479 npc->SetCurrentEquipmentId(equipId);
1480 slot[0] = einfo->ItemEntry[0];
1481 slot[1] = einfo->ItemEntry[1];
1482 slot[2] = einfo->ItemEntry[2];
1483 }
1484 else
1485 {
1486 slot[0] = e.action.equip.slot1;
1487 slot[1] = e.action.equip.slot2;
1488 slot[2] = e.action.equip.slot3;
1489 }
1490 if (!e.action.equip.mask || (e.action.equip.mask & 1))
1491 npc->SetUInt32Value(UNIT_FIELD_VIRTUAL_ITEM_ID + 0, slot[0]);
1492 if (!e.action.equip.mask || (e.action.equip.mask & 2))
1493 npc->SetUInt32Value(UNIT_FIELD_VIRTUAL_ITEM_ID + 1, slot[1]);
1494 if (!e.action.equip.mask || (e.action.equip.mask & 4))
1495 npc->SetUInt32Value(UNIT_FIELD_VIRTUAL_ITEM_ID + 2, slot[2]);
1496 }
1497 }
1498
1499 delete targets;
1500 break;
1501 }
1503 {
1504 SmartEvent ne = SmartEvent();
1507 if (!ne.event_chance) ne.event_chance = 100;
1508
1513
1514 ne.event_flags = 0;
1517
1518 SmartAction ac = SmartAction();
1521
1523 ev.event = ne;
1524 ev.event_id = e.action.timeEvent.id;
1525 ev.target = e.target;
1526 ev.action = ac;
1527 InitTimer(ev);
1528 mStoredEvents.push_back(ev);
1529 break;
1530 }
1533 break;
1535 mRemIDs.push_back(e.action.timeEvent.id);
1536 break;
1538 {
1539 ObjectList* targets = GetTargets(e, unit);
1540 if (!targets)
1541 break;
1542
1543 for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
1544 {
1545 if (IsCreature(*itr))
1546 {
1547 if (!meOrigGUID)
1548 meOrigGUID = me ? me->GetGUID() : 0;
1549 if (!goOrigGUID)
1550 goOrigGUID = go ? go->GetGUID() : 0;
1551 go = NULL;
1552 me = (*itr)->ToCreature();
1553 break;
1554 }
1555 else if (IsGameObject(*itr))
1556 {
1557 if (!meOrigGUID)
1558 meOrigGUID = me ? me->GetGUID() : 0;
1559 if (!goOrigGUID)
1560 goOrigGUID = go ? go->GetGUID() : 0;
1561 go = (*itr)->ToGameObject();
1562 me = NULL;
1563 break;
1564 }
1565 }
1566
1567 delete targets;
1568 break;
1569 }
1572 break;
1574 OnReset();
1575 break;
1577 {
1578 if (!IsSmart())
1579 break;
1580
1581 float attackDistance = float(e.action.setRangedMovement.distance);
1582 float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI;
1583
1584 ObjectList* targets = GetTargets(e, unit);
1585 if (targets)
1586 {
1587 for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
1588 if (Creature* target = (*itr)->ToCreature())
1589 if (IsSmart(target) && target->GetVictim())
1590 if (CAST_AI(SmartAI, target->AI())->CanCombatMove())
1591 target->GetMotionMaster()->MoveChase(target->GetVictim(), attackDistance, attackAngle);
1592
1593 delete targets;
1594 }
1595 break;
1596 }
1598 {
1600 {
1601 SF_LOG_ERROR("sql.sql", "SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
1602 break;
1603 }
1604
1605 if (ObjectList* targets = GetTargets(e, unit))
1606 {
1607 for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
1608 {
1609 if (Creature* target = (*itr)->ToCreature())
1610 {
1611 if (IsSmart(target))
1612 CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
1613 }
1614 else if (GameObject* goTarget = (*itr)->ToGameObject())
1615 {
1616 if (IsSmartGO(goTarget))
1617 CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
1618 }
1619 }
1620
1621 delete targets;
1622 }
1623 break;
1624 }
1626 {
1627 ObjectList* targets = GetTargets(e, unit);
1628 if (!targets)
1629 break;
1630
1631 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1632 if (IsUnit(*itr))
1633 (*itr)->ToUnit()->SetUInt32Value(UNIT_FIELD_NPC_FLAGS, e.action.unitFlag.flag);
1634
1635 delete targets;
1636 break;
1637 }
1639 {
1640 ObjectList* targets = GetTargets(e, unit);
1641 if (!targets)
1642 break;
1643
1644 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1645 if (IsUnit(*itr))
1646 (*itr)->ToUnit()->SetFlag(UNIT_FIELD_NPC_FLAGS, e.action.unitFlag.flag);
1647
1648 delete targets;
1649 break;
1650 }
1652 {
1653 ObjectList* targets = GetTargets(e, unit);
1654 if (!targets)
1655 break;
1656
1657 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1658 if (IsUnit(*itr))
1659 (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_NPC_FLAGS, e.action.unitFlag.flag);
1660
1661 delete targets;
1662 break;
1663 }
1665 {
1667 if (!casters)
1668 break;
1669
1670 ObjectList* targets = GetTargets(e, unit);
1671 if (!targets)
1672 {
1673 delete casters; // casters already validated, delete now
1674 break;
1675 }
1676
1677 for (ObjectList::const_iterator itr = casters->begin(); itr != casters->end(); ++itr)
1678 {
1679 if (!IsUnit(*itr))
1680 continue;
1681
1682 bool interruptedSpell = false;
1683
1684 for (ObjectList::const_iterator it = targets->begin(); it != targets->end(); ++it)
1685 {
1686 if (!IsUnit(*it))
1687 continue;
1688
1689 if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.cast.spell))
1690 {
1691 if (!interruptedSpell && e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
1692 {
1693 (*itr)->ToUnit()->InterruptNonMeleeSpells(false);
1694 interruptedSpell = true;
1695 }
1696
1697 (*itr)->ToUnit()->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
1698 }
1699 else
1700 SF_LOG_DEBUG("scripts.ai", "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*it)->GetGUID(), (*it)->GetEntry(), uint32((*it)->GetTypeId()));
1701 }
1702 }
1703
1704 delete targets;
1705 delete casters;
1706 break;
1707 }
1709 {
1711 actions[0] = e.action.randTimedActionList.entry1;
1712 actions[1] = e.action.randTimedActionList.entry2;
1713 actions[2] = e.action.randTimedActionList.entry3;
1714 actions[3] = e.action.randTimedActionList.entry4;
1715 actions[4] = e.action.randTimedActionList.entry5;
1716 actions[5] = e.action.randTimedActionList.entry6;
1718 uint32 count = 0;
1719 for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
1720 {
1721 if (actions[i] > 0)
1722 {
1723 temp[count] = actions[i];
1724 ++count;
1725 }
1726 }
1727
1728 if (count == 0)
1729 break;
1730
1731 uint32 id = temp[std::rand() % count];
1733 {
1734 SF_LOG_ERROR("sql.sql", "SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
1735 break;
1736 }
1737
1738 ObjectList* targets = GetTargets(e, unit);
1739 if (targets)
1740 {
1741 for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
1742 {
1743 if (Creature* target = (*itr)->ToCreature())
1744 {
1745 if (IsSmart(target))
1746 CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker());
1747 }
1748 else if (GameObject* goTarget = (*itr)->ToGameObject())
1749 {
1750 if (IsSmartGO(goTarget))
1751 CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker());
1752 }
1753 }
1754
1755 delete targets;
1756 }
1757 break;
1758 }
1760 {
1763 uint32 id = (entry2 > entry1) ? (std::rand() % (entry2 - entry1 + 1) + entry1) : entry1;
1765 {
1766 SF_LOG_ERROR("sql.sql", "SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
1767 break;
1768 }
1769
1770 ObjectList* targets = GetTargets(e, unit);
1771 if (targets)
1772 {
1773 for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
1774 {
1775 if (Creature* target = (*itr)->ToCreature())
1776 {
1777 if (IsSmart(target))
1778 CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker());
1779 }
1780 else if (GameObject* goTarget = (*itr)->ToGameObject())
1781 {
1782 if (IsSmartGO(goTarget))
1783 CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker());
1784 }
1785 }
1786
1787 delete targets;
1788 }
1789 break;
1790 }
1792 {
1793 ObjectList* targets = GetTargets(e, unit);
1794 if (!targets)
1795 break;
1796
1797 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1798 if (IsPlayer(*itr))
1799 (*itr)->ToPlayer()->ActivateTaxiPathTo(e.action.taxi.id);
1800
1801 delete targets;
1802 break;
1803 }
1805 {
1806 ObjectList* targets = GetTargets(e, unit);
1807 if (!targets)
1808 break;
1809
1810 bool foundTarget = false;
1811
1812 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1813 {
1814 if (IsCreature((*itr)))
1815 {
1816 foundTarget = true;
1817
1819 (*itr)->ToCreature()->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance);
1820 else
1821 (*itr)->ToCreature()->GetMotionMaster()->MoveIdle();
1822 }
1823 }
1824
1825 if (!foundTarget && me && IsCreature(me))
1826 {
1828 me->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance);
1829 else
1830 me->GetMotionMaster()->MoveIdle();
1831 }
1832
1833 delete targets;
1834 break;
1835 }
1837 {
1838 ObjectList* targets = GetTargets(e, unit);
1839 if (!targets)
1840 break;
1841 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1842 if (IsUnit(*itr))
1843 (*itr)->ToUnit()->SetByteFlag(UNIT_FIELD_ANIM_TIER, e.action.setunitByte.type, e.action.setunitByte.byte1);
1844
1845 delete targets;
1846 break;
1847 }
1849 {
1850 ObjectList* targets = GetTargets(e, unit);
1851 if (!targets)
1852 break;
1853
1854 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1855 if (IsUnit(*itr))
1856 (*itr)->ToUnit()->RemoveByteFlag(UNIT_FIELD_ANIM_TIER, e.action.delunitByte.type, e.action.delunitByte.byte1);
1857
1858 delete targets;
1859 break;
1860 }
1862 {
1863 ObjectList* targets = GetTargets(e, unit);
1864 if (!targets)
1865 break;
1866
1867 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1868 if (IsUnit(*itr))
1870
1871 delete targets;
1872 break;
1873 }
1875 {
1876 ObjectList* targets = GetTargets(e, unit);
1877 if (!targets)
1878 break;
1879
1880 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1881 if (IsGameObject(*itr))
1882 (*itr)->ToGameObject()->SendCustomAnim(e.action.sendGoCustomAnim.anim);
1883
1884 delete targets;
1885 break;
1886 }
1888 {
1889 ObjectList* targets = GetTargets(e, unit);
1890 if (!targets)
1891 break;
1892
1893 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1894 if (IsUnit(*itr))
1895 (*itr)->ToUnit()->SetUInt32Value(OBJECT_FIELD_DYNAMIC_FLAGS, e.action.unitFlag.flag);
1896
1897 delete targets;
1898 break;
1899 }
1901 {
1902 ObjectList* targets = GetTargets(e, unit);
1903 if (!targets)
1904 break;
1905
1906 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1907 if (IsUnit(*itr))
1908 (*itr)->ToUnit()->SetFlag(OBJECT_FIELD_DYNAMIC_FLAGS, e.action.unitFlag.flag);
1909
1910 delete targets;
1911 break;
1912 }
1914 {
1915 ObjectList* targets = GetTargets(e, unit);
1916 if (!targets)
1917 break;
1918
1919 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1920 if (IsUnit(*itr))
1921 (*itr)->ToUnit()->RemoveFlag(OBJECT_FIELD_DYNAMIC_FLAGS, e.action.unitFlag.flag);
1922
1923 delete targets;
1924 break;
1925 }
1927 {
1928 ObjectList* targets = GetTargets(e, unit);
1929 if (!targets)
1930 break;
1931
1932 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1933 {
1934 if (Creature* creature = (*itr)->ToCreature())
1935 {
1936 creature->GetMotionMaster()->Clear();
1937 creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz);
1938 }
1939 }
1941
1942 delete targets;
1943 break;
1944 }
1946 {
1947 ObjectList* targets = GetTargets(e, unit);
1948
1949 if (!targets)
1950 break;
1951
1952 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1953 if (IsGameObject(*itr))
1954 (*itr)->ToGameObject()->SetLootState((LootState)e.action.setGoLootState.state);
1955
1956 delete targets;
1957 break;
1958 }
1960 {
1961 ObjectList* targets = GetTargets(e, unit);
1962 if (!targets)
1963 break;
1964
1966 if (!storedTargets)
1967 {
1968 delete targets;
1969 break;
1970 }
1971
1972 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
1973 {
1974 if (IsCreature(*itr))
1975 {
1976 if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()))
1977 ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list
1978 else
1979 SF_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping");
1980 }
1981 else if (IsGameObject(*itr))
1982 {
1983 if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI()))
1984 ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list
1985 else
1986 SF_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping");
1987 }
1988 }
1989
1990 delete targets;
1991 break;
1992 }
1994 {
1995 if (!GetBaseObject())
1996 break;
1997
1998 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d",
2000
2001 if (me)
2002 {
2003 if (SmartAI* ai = CAST_AI(SmartAI, me->AI()))
2004 ai->SetGossipReturn(true);
2005 }
2006 else if (go)
2007 {
2009 ai->SetGossipReturn(true);
2010 }
2011
2012 ObjectList* targets = GetTargets(e, unit);
2013 if (!targets)
2014 break;
2015
2016 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2017 {
2018 if (Player* player = (*itr)->ToPlayer())
2019 {
2021 player->PrepareGossipMenu(GetBaseObject(), e.action.sendGossipMenu.gossipMenuId, true);
2022 else
2023 player->PlayerTalkClass->ClearMenus();
2024
2025 player->SEND_GOSSIP_MENU(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID());
2026 }
2027 }
2028
2029 delete targets;
2030 break;
2031 }
2033 {
2034 ObjectList* targets = GetTargets(e, unit);
2035 if (!targets)
2036 break;
2037
2038 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2039 {
2040 if (IsCreature(*itr))
2041 {
2043 (*itr)->ToCreature()->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
2044 else if (e.GetTargetType() == SMART_TARGET_POSITION)
2045 (*itr)->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o);
2052 {
2053 (*itr)->ToCreature()->SetHomePosition((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), (*itr)->GetOrientation());
2054 }
2055 else
2056 SF_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is invalid, skipping");
2057 }
2058 }
2059
2060 delete targets;
2061 break;
2062 }
2064 {
2065 ObjectList* targets = GetTargets(e, unit);
2066 if (!targets)
2067 break;
2068
2069 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2070 if (IsCreature(*itr))
2071 (*itr)->ToCreature()->setRegeneratingHealth(e.action.setHealthRegen.regenHealth);
2072
2073 delete targets;
2074 break;
2075 }
2077 {
2078 ObjectList* targets = GetTargets(e, unit);
2079 if (!targets)
2080 break;
2081
2082 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2083 if (IsCreature(*itr))
2084 (*itr)->ToCreature()->SetControlled(e.action.setRoot.root, UNIT_STATE_ROOT);
2085
2086 delete targets;
2087 break;
2088 }
2090 {
2091 ObjectList* targets = GetTargets(e, unit);
2092 if (!targets)
2093 break;
2094
2095 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2096 if (IsGameObject(*itr))
2097 (*itr)->ToGameObject()->SetUInt32Value(GAMEOBJECT_FIELD_FLAGS, e.action.goFlag.flag);
2098
2099 delete targets;
2100 break;
2101 }
2103 {
2104 ObjectList* targets = GetTargets(e, unit);
2105 if (!targets)
2106 break;
2107
2108 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2109 if (IsGameObject(*itr))
2110 (*itr)->ToGameObject()->SetFlag(GAMEOBJECT_FIELD_FLAGS, e.action.goFlag.flag);
2111
2112 delete targets;
2113 break;
2114 }
2116 {
2117 ObjectList* targets = GetTargets(e, unit);
2118 if (!targets)
2119 break;
2120
2121 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2122 if (IsGameObject(*itr))
2123 (*itr)->ToGameObject()->RemoveFlag(GAMEOBJECT_FIELD_FLAGS, e.action.goFlag.flag);
2124
2125 delete targets;
2126 break;
2127 }
2129 {
2130 std::list<TempSummon*> summonList;
2132
2133 for (std::list<TempSummon*>::const_iterator itr = summonList.begin(); itr != summonList.end(); ++itr)
2134 if (unit && e.action.creatureGroup.attackInvoker)
2135 (*itr)->AI()->AttackStart(unit);
2136
2137 break;
2138 }
2140 {
2141 ObjectList* targets = GetTargets(e, unit);
2142
2143 if (targets)
2144 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2145 if (IsUnit(*itr))
2146 (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), e.action.power.newPower);
2147
2148 delete targets;
2149 break;
2150 }
2152 {
2153 ObjectList* targets = GetTargets(e, unit);
2154
2155 if (targets)
2156 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2157 if (IsUnit(*itr))
2158 (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) + e.action.power.newPower);
2159
2160 delete targets;
2161 break;
2162 }
2164 {
2165 ObjectList* targets = GetTargets(e, unit);
2166
2167 if (targets)
2168 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2169 if (IsUnit(*itr))
2170 (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) - e.action.power.newPower);
2171
2172 delete targets;
2173 break;
2174 }
2176 {
2177 uint32 eventId = e.action.gameEventStop.id;
2178 if (!sGameEventMgr->IsActiveEvent(eventId))
2179 {
2180 SF_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_STOP, inactive event (id: %u)", eventId);
2181 break;
2182 }
2183 sGameEventMgr->StopEvent(eventId, true);
2184 break;
2185 }
2187 {
2188 uint32 eventId = e.action.gameEventStart.id;
2189 if (sGameEventMgr->IsActiveEvent(eventId))
2190 {
2191 SF_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_START, already activated event (id: %u)", eventId);
2192 break;
2193 }
2194 sGameEventMgr->StartEvent(eventId, true);
2195 break;
2196 }
2198 {
2199 ObjectList* targets = GetTargets(e, unit);
2200 if (!targets)
2201 break;
2202
2203 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2204 {
2205 if (IsUnit(*itr))
2206 {
2208 {
2210 (*itr)->ToUnit()->ModifyHealth(int32((*itr)->ToUnit()->CountPctFromMaxHealth(healthpct)));
2211 }
2213 {
2214 int32 missingHealth = int32((*itr)->ToUnit()->GetMaxHealth() - (*itr)->ToUnit()->GetHealth());
2215 (*itr)->ToUnit()->ModifyHealth(missingHealth);
2216 }
2218 (*itr)->ToUnit()->SetHealth(me->GetHealth());
2220 me->SetHealth((*itr)->ToUnit()->GetHealth());
2222 (*itr)->ToUnit()->SetMaxHealth(me->GetMaxHealth());
2224 me->SetMaxHealth((*itr)->ToUnit()->GetMaxHealth());
2226 {
2228 (*itr)->ToUnit()->SetMaxHealth(health);
2229 }
2231 {
2233 (*itr)->ToUnit()->SetHealth(health);
2234 }
2235 else
2236 {
2237 SF_LOG_ERROR("sql.sql", "SmartScript: Invalid type for SMART_ACTION_SET_HEALTH, skipping");
2238 break;
2239 }
2240 }
2241 }
2242 delete targets;
2243 break;
2244 }
2246 {
2247 ObjectList* targets = GetTargets(e, unit);
2248 if (!targets)
2249 break;
2250
2251 uint32 sounds[SMART_ACTION_PARAM_COUNT - 1];
2252 sounds[0] = e.action.randomSound.sound1;
2253 sounds[1] = e.action.randomSound.sound2;
2254 sounds[2] = e.action.randomSound.sound3;
2255 sounds[3] = e.action.randomSound.sound4;
2256 sounds[4] = e.action.randomSound.sound5;
2257
2258 bool onlySelf = e.action.randomSound.onlySelf != 0;
2259
2261 uint32 count = 0;
2262 for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT - 1; i++)
2263 {
2264 if (sounds[i])
2265 {
2266 temp[count] = sounds[i];
2267 ++count;
2268 }
2269 }
2270
2271 if (count == 0)
2272 {
2273 delete targets;
2274 break;
2275 }
2276
2277 if (ObjectList* targets = GetTargets(e, unit))
2278 {
2279 for (WorldObject* const obj : *targets)
2280 {
2281 if (IsUnit(obj))
2282 {
2283 uint32 sound = temp[std::rand() % count];
2284 obj->PlayDirectSound(sound, onlySelf ? obj->ToPlayer() : nullptr);
2285 SF_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_SOUND: target: %s (" UI64FMTD "), sound: %u, onlyself: %s",
2286 obj->GetName().c_str(), obj->GetGUID(), sound, onlySelf ? "true" : "false");
2287 }
2288 }
2289
2290 delete targets;
2291 break;
2292 }
2293
2294 delete targets;
2295 break;
2296 }
2298 {
2299 ObjectList* targets = GetTargets(e, unit);
2300 if (!targets)
2301 break;
2302
2303 for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
2304 {
2305 if (IsCreature(*itr))
2306 (*itr)->ToCreature()->CombatStop();
2307 }
2308
2309 delete targets;
2310 break;
2311 }
2312 default:
2313 SF_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
2314 break;
2315 }
2316
2317 if (e.link && e.link != e.event_id)
2318 {
2320 if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
2321 ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
2322 else
2323 SF_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
2324 }
2325}
2326
2327void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
2328{
2329 ConditionList const conds = sConditionMgr->GetConditionsForSmartEvent(e.entryOrGuid, e.event_id, e.source_type);
2331
2332 if (sConditionMgr->IsObjectMeetToConditions(info, conds))
2333 ProcessAction(e, unit, var0, var1, bvar, spell, gob);
2334
2335 RecalcTimer(e, min, max);
2336}
2337
2339{
2340 if (!GetBaseObject())
2341 return;
2342 if (mTemplate)
2343 {
2344 SF_LOG_ERROR("sql.sql", "SmartScript::InstallTemplate: Entry %d SourceType %u AI Template can not be set more then once, skipped.", e.entryOrGuid, e.GetScriptType());
2345 return;
2346 }
2349 {
2351 {
2355 AddEvent(SMART_EVENT_MANA_PCT, 0, e.action.installTtemplate.param5 - 15 > 100 ? 100 : e.action.installTtemplate.param5 + 15, 100, 1000, 1000, 0, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2356 AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, 0, SMART_ACTION_SET_EVENT_PHASE, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2358 break;
2359 }
2361 {
2363 AddEvent(SMART_EVENT_JUST_CREATED, 0, 0, 0, 0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2364 break;
2365 }
2367 {
2368 if (!me)
2369 return;
2370 //store cage as id1
2372
2373 //reset(close) cage on hostage(me) respawn
2375
2376 AddEvent(SMART_EVENT_DATA_SET, 0, 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);
2377 AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, 0, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2378
2380 //phase 1: give quest credit on movepoint reached
2382 //phase 1: despawn after time on movepoint reached
2384
2385 if (sCreatureTextMgr->TextExist(me->GetEntry(), (uint8)e.action.installTtemplate.param5))
2387 break;
2388 }
2390 {
2391 if (!go)
2392 return;
2393 //store hostage as id1
2395 //store invoker as id2
2396 AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
2397 //signal hostage
2398 AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);
2399 //when hostage raeched end point, give credit to invoker
2402 else
2404 break;
2405 }
2407 default:
2408 return;
2409 }
2410}
2411
2412void SmartScript::AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, 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)
2413{
2414 mInstallEvents.push_back(CreateEvent(e, event_flags, event_param1, event_param2, event_param3, event_param4, event_param5, action, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, t, target_param1, target_param2, target_param3, phaseMask));
2415}
2416
2417SmartScriptHolder SmartScript::CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, 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)
2418{
2419 SmartScriptHolder script;
2420 script.event.type = e;
2421 script.event.raw.param1 = event_param1;
2422 script.event.raw.param2 = event_param2;
2423 script.event.raw.param3 = event_param3;
2424 script.event.raw.param4 = event_param4;
2425 script.event.raw.param5 = event_param5;
2426 script.event.event_phase_mask = phaseMask;
2427 script.event.event_flags = event_flags;
2428 script.event.event_chance = 100;
2429
2430 script.action.type = action;
2431 script.action.raw.param1 = action_param1;
2432 script.action.raw.param2 = action_param2;
2433 script.action.raw.param3 = action_param3;
2434 script.action.raw.param4 = action_param4;
2435 script.action.raw.param5 = action_param5;
2436 script.action.raw.param6 = action_param6;
2437
2438 script.target.type = t;
2439 script.target.raw.param1 = target_param1;
2440 script.target.raw.param2 = target_param2;
2441 script.target.raw.param3 = target_param3;
2442
2444 InitTimer(script);
2445 return script;
2446}
2447
2449{
2450 Unit* scriptTrigger = NULL;
2451 if (invoker)
2452 scriptTrigger = invoker;
2453 else if (Unit* tempLastInvoker = GetLastInvoker())
2454 scriptTrigger = tempLastInvoker;
2455
2456 WorldObject* baseObject = GetBaseObject();
2457
2458 ObjectList* l = new ObjectList();
2459 switch (e.GetTargetType())
2460 {
2461 case SMART_TARGET_SELF:
2462 if (baseObject)
2463 l->push_back(baseObject);
2464 break;
2466 if (me)
2467 if (Unit* victim = me->GetVictim())
2468 l->push_back(victim);
2469 break;
2471 if (me)
2472 if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
2473 l->push_back(u);
2474 break;
2476 if (me)
2477 if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0))
2478 l->push_back(u);
2479 break;
2481 if (me)
2482 if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0))
2483 l->push_back(u);
2484 break;
2486 if (me)
2487 if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1))
2488 l->push_back(u);
2489 break;
2491 if (scriptTrigger)
2492 l->push_back(scriptTrigger);
2493 break;
2495 if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase())
2496 l->push_back(scriptTrigger->GetVehicle()->GetBase());
2497 break;
2499 if (scriptTrigger)
2500 {
2501 if (Player* player = scriptTrigger->ToPlayer())
2502 {
2503 if (Group* group = player->GetGroup())
2504 {
2505 for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
2506 if (Player* member = groupRef->GetSource())
2507 l->push_back(member);
2508 }
2509 // We still add the player to the list if there is no group. If we do
2510 // this even if there is a group (thus the else-check), it will add the
2511 // same player to the list twice. We don't want that to happen.
2512 else
2513 l->push_back(scriptTrigger);
2514 }
2515 }
2516 break;
2518 {
2519 // will always return a valid pointer, even if empty list
2521 for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2522 {
2523 if (!IsCreature(*itr))
2524 continue;
2525
2526 if (me && me == *itr)
2527 continue;
2528
2529 if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist))
2530 l->push_back(*itr);
2531 }
2532
2533 delete units;
2534 break;
2535 }
2537 {
2538 // will always return a valid pointer, even if empty list
2540 for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2541 {
2542 if (!IsCreature(*itr))
2543 continue;
2544
2545 if (me && me == *itr)
2546 continue;
2547
2548 if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature)
2549 l->push_back(*itr);
2550 }
2551
2552 delete units;
2553 break;
2554 }
2556 {
2557 // will always return a valid pointer, even if empty list
2559 for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2560 {
2561 if (!IsGameObject(*itr))
2562 continue;
2563
2564 if (go && go == *itr)
2565 continue;
2566
2567 if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry)
2568 l->push_back(*itr);
2569 }
2570
2571 delete units;
2572 break;
2573 }
2575 {
2576 // will always return a valid pointer, even if empty list
2578 for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2579 {
2580 if (!IsGameObject(*itr))
2581 continue;
2582
2583 if (go && go == *itr)
2584 continue;
2585
2586 if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist))
2587 l->push_back(*itr);
2588 }
2589
2590 delete units;
2591 break;
2592 }
2594 {
2595 Creature* target = NULL;
2596 if (!scriptTrigger && !baseObject)
2597 {
2598 SF_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker");
2599 break;
2600 }
2601
2602 target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid);
2603
2604 if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry))
2605 l->push_back(target);
2606 break;
2607 }
2609 {
2610 GameObject* target = NULL;
2611 if (!scriptTrigger && !baseObject)
2612 {
2613 SF_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");
2614 break;
2615 }
2616
2617 target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid);
2618
2619 if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry))
2620 l->push_back(target);
2621 break;
2622 }
2624 {
2625 // will always return a valid pointer, even if empty list
2627 if (!units->empty() && baseObject)
2628 for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2629 if (IsPlayer(*itr) && baseObject->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist))
2630 l->push_back(*itr);
2631
2632 delete units;
2633 break;
2634 }
2636 {
2637 // will always return a valid pointer, even if empty list
2639 for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
2640 if (IsPlayer(*itr))
2641 l->push_back(*itr);
2642
2643 delete units;
2644 break;
2645 }
2647 {
2648 ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id);
2649 if (itr != mTargetStorage->end())
2650 l->assign(itr->second->begin(), itr->second->end());
2651
2652 return l;
2653 }
2655 {
2656 Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead);
2657 if (target)
2658 l->push_back(target);
2659 break;
2660 }
2662 {
2663 GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100));
2664 if (target)
2665 l->push_back(target);
2666 break;
2667 }
2669 {
2670 if (me)
2671 {
2672 Player* target = me->SelectNearestPlayer((float)e.target.playerDistance.dist);
2673 if (target)
2674 l->push_back(target);
2675 }
2676 break;
2677 }
2679 {
2680 if (me)
2681 {
2682 uint64 charmerOrOwnerGuid = me->GetCharmerOrOwnerGUID();
2683
2684 if (!charmerOrOwnerGuid)
2685 charmerOrOwnerGuid = me->GetCreatorGUID();
2686
2687 if (Unit* owner = ObjectAccessor::GetUnit(*me, charmerOrOwnerGuid))
2688 l->push_back(owner);
2689 }
2690 break;
2691 }
2693 {
2694 if (me)
2695 {
2696 ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
2697 for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
2698 if (Unit* temp = Unit::GetUnit(*me, (*i)->getUnitGuid()))
2699 l->push_back(temp);
2700 }
2701 break;
2702 }
2704 {
2705 if (me)
2706 if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly))
2707 l->push_back(target);
2708
2709 break;
2710 }
2712 {
2713 if (me)
2715 l->push_back(target);
2716
2717 break;
2718 }
2720 case SMART_TARGET_NONE:
2721 default:
2722 break;
2723 }
2724
2725 if (l->empty())
2726 {
2727 delete l;
2728 l = NULL;
2729 }
2730
2731 return l;
2732}
2733
2735{
2736 ObjectList* targets = new ObjectList();
2737 WorldObject* obj = GetBaseObject();
2738 if (obj)
2739 {
2740 Skyfire::AllWorldObjectsInRange u_check(obj, dist);
2742 obj->VisitNearbyObject(dist, searcher);
2743 }
2744 return targets;
2745}
2746
2747void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
2748{
2749 if (!e.active && e.GetEventType() != SMART_EVENT_LINK)
2750 return;
2751
2753 return;
2754
2755 switch (e.GetEventType())
2756 {
2757 case SMART_EVENT_LINK://special handling
2758 ProcessAction(e, unit, var0, var1, bvar, spell, gob);
2759 break;
2760 //called from Update tick
2761 case SMART_EVENT_UPDATE:
2763 break;
2765 if (me && me->IsInCombat())
2766 return;
2768 break;
2770 if (!me || !me->IsInCombat())
2771 return;
2773 break;
2775 {
2776 if (!me || !me->IsInCombat() || !me->GetMaxHealth())
2777 return;
2778 uint32 perc = (uint32)me->GetHealthPct();
2779 if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
2780 return;
2782 break;
2783 }
2785 {
2786 if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxHealth())
2787 return;
2788 uint32 perc = (uint32)me->GetVictim()->GetHealthPct();
2789 if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
2790 return;
2792 break;
2793 }
2795 {
2796 if (!me || !me->IsInCombat() || !me->GetMaxPower(POWER_MANA))
2797 return;
2798 uint32 perc = uint32(100.0f * me->GetPower(POWER_MANA) / me->GetMaxPower(POWER_MANA));
2799 if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
2800 return;
2802 break;
2803 }
2805 {
2806 if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxPower(POWER_MANA))
2807 return;
2808 uint32 perc = uint32(100.0f * me->GetVictim()->GetPower(POWER_MANA) / me->GetVictim()->GetMaxPower(POWER_MANA));
2809 if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
2810 return;
2812 break;
2813 }
2814 case SMART_EVENT_RANGE:
2815 {
2816 if (!me || !me->IsInCombat() || !me->GetVictim())
2817 return;
2818
2819 if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max))
2821 break;
2822 }
2824 {
2825 if (!me || !me->IsInCombat())
2826 return;
2827
2828 Unit* victim = me->GetVictim();
2829
2830 if (!victim || !victim->IsNonMeleeSpellCasted(false, false, true))
2831 return;
2832
2833 if (e.event.targetCasting.spellId > 0)
2834 if (Spell* currSpell = victim->GetCurrentSpell(CURRENT_GENERIC_SPELL))
2835 if (currSpell->m_spellInfo->Id != e.event.targetCasting.spellId)
2836 return;
2837
2839 break;
2840 }
2842 {
2843 if (!me || !me->IsInCombat())
2844 return;
2845
2847 if (!target || !target->IsInCombat())
2848 return;
2850 break;
2851 }
2853 {
2854 if (!me || !me->IsInCombat())
2855 return;
2856
2857 std::list<Creature*> pList;
2858 DoFindFriendlyCC(pList, (float)e.event.friendlyCC.radius);
2859 if (pList.empty())
2860 return;
2862 break;
2863 }
2865 {
2866 std::list<Creature*> pList;
2868
2869 if (pList.empty())
2870 return;
2871
2873 break;
2874 }
2876 {
2877 if (!me)
2878 return;
2879 uint32 count = me->GetAuraCount(e.event.aura.spell);
2880 if ((!e.event.aura.count && !count) || (e.event.aura.count && count >= e.event.aura.count))
2882 break;
2883 }
2885 {
2886 if (!me || !me->GetVictim())
2887 return;
2888 uint32 count = me->GetVictim()->GetAuraCount(e.event.aura.spell);
2889 if (count < e.event.aura.count)
2890 return;
2892 break;
2893 }
2894 //no params
2895 case SMART_EVENT_AGGRO:
2896 case SMART_EVENT_DEATH:
2897 case SMART_EVENT_EVADE:
2911 case SMART_EVENT_RESET:
2916 ProcessAction(e, unit, var0, var1, bvar, spell, gob);
2917 break;
2919 {
2920 if (!me)
2921 return;
2922
2923 if (Unit* victim = me->GetVictim())
2924 {
2925 if (!victim->HasInArc(static_cast<float>(M_PI), me))
2927 }
2928 break;
2929 }
2931 if (e.event.emote.emote == var0)
2932 {
2933 ProcessAction(e, unit);
2934 RecalcTimer(e, e.event.emote.cooldownMin, e.event.emote.cooldownMax);
2935 }
2936 break;
2937 case SMART_EVENT_KILL:
2938 {
2939 if (!me || !unit)
2940 return;
2942 return;
2943 if (e.event.kill.creature && unit->GetEntry() != e.event.kill.creature)
2944 return;
2945 ProcessAction(e, unit);
2947 break;
2948 }
2951 {
2952 if (!spell)
2953 return;
2954 if ((!e.event.spellHit.spell || spell->Id == e.event.spellHit.spell) &&
2955 (!e.event.spellHit.school || (spell->SchoolMask & e.event.spellHit.school)))
2956 {
2957 ProcessAction(e, unit, 0, 0, bvar, spell);
2959 }
2960 break;
2961 }
2963 {
2964 if (!me || me->IsInCombat())
2965 return;
2966 //can trigger if closer than fMaxAllowedRange
2967 float range = (float)e.event.los.maxDist;
2968
2969 //if range is ok and we are actually in LOS
2970 if (me->IsWithinDistInMap(unit, range) && me->IsWithinLOSInMap(unit))
2971 {
2972 //if friendly event&&who is not hostile OR hostile event&&who is hostile
2973 if ((e.event.los.noHostile && !me->IsHostileTo(unit)) ||
2974 (!e.event.los.noHostile && me->IsHostileTo(unit)))
2975 if (!me || !unit)
2976 return;
2978 return;
2980 ProcessAction(e, unit);
2981 }
2982 break;
2983 }
2984 case SMART_EVENT_IC_LOS:
2985 {
2986 if (!me || !me->IsInCombat())
2987 return;
2988 //can trigger if closer than fMaxAllowedRange
2989 float range = (float)e.event.los.maxDist;
2990
2991 //if range is ok and we are actually in LOS
2992 if (me->IsWithinDistInMap(unit, range) && me->IsWithinLOSInMap(unit))
2993 {
2994 //if friendly event&&who is not hostile OR hostile event&&who is hostile
2995 if ((e.event.los.noHostile && !me->IsHostileTo(unit)) ||
2996 (!e.event.los.noHostile && me->IsHostileTo(unit)))
2997 if (!me || !unit)
2998 return;
3000 return;
3002 ProcessAction(e, unit);
3003 }
3004 break;
3005 }
3007 {
3008 if (!GetBaseObject())
3009 return;
3011 return;
3013 return;
3014 ProcessAction(e);
3015 break;
3016 }
3018 {
3019 if (!IsCreature(unit))
3020 return;
3021 if (e.event.summoned.creature && unit->GetEntry() != e.event.summoned.creature)
3022 return;
3023 ProcessAction(e, unit);
3025 break;
3026 }
3030 {
3031 if (var0 > e.event.minMaxRepeat.max || var0 < e.event.minMaxRepeat.min)
3032 return;
3033 ProcessAction(e, unit);
3035 break;
3036 }
3038 {
3039 if ((e.event.movementInform.type && var0 != e.event.movementInform.type) || (e.event.movementInform.id && var1 != e.event.movementInform.id))
3040 return;
3041 ProcessAction(e, unit, var0, var1);
3042 break;
3043 }
3046 {
3047 if (e.event.waypoint.pathID && var0 != e.event.waypoint.pathID)
3048 return;
3049 ProcessAction(e, unit, var0);
3050 break;
3051 }
3057 {
3058 if (!me || (e.event.waypoint.pointID && var0 != e.event.waypoint.pointID) || (e.event.waypoint.pathID && GetPathId() != e.event.waypoint.pathID))
3059 return;
3060 ProcessAction(e, unit);
3061 break;
3062 }
3065 {
3067 return;
3068 ProcessAction(e, unit, var0);
3070 break;
3071 }
3074 {
3075 if (e.event.quest.quest && var0 != e.event.quest.quest)
3076 return;
3077 ProcessAction(e, unit, var0);
3078 break;
3079 }
3081 {
3083 return;
3084 ProcessAction(e, unit, var0);
3085 break;
3086 }
3088 {
3089 if (e.event.areatrigger.id && var0 != e.event.areatrigger.id)
3090 return;
3091 ProcessAction(e, unit, var0);
3092 break;
3093 }
3095 {
3097 return;
3098 ProcessAction(e, unit, var0);
3099 break;
3100 }
3102 {
3103 if (e.event.dataSet.id != var0 || e.event.dataSet.value != var1)
3104 return;
3105 ProcessAction(e, unit, var0, var1);
3107 break;
3108 }
3111 {
3112 if (!unit)
3113 return;
3114 ProcessAction(e, unit);
3116 break;
3117 }
3119 {
3120 if (e.event.timedEvent.id == var0)
3121 ProcessAction(e, unit);
3122 break;
3123 }
3125 {
3126 SF_LOG_DEBUG("scripts.ai", "SmartScript: Gossip Select: menu %u action %u", var0, var1);//little help for scripters
3127 if (e.event.gossip.sender != var0 || e.event.gossip.action != var1)
3128 return;
3129 ProcessAction(e, unit, var0, var1);
3130 break;
3131 }
3133 {
3134 if (e.event.dummy.spell != var0 || e.event.dummy.effIndex != var1)
3135 return;
3136 ProcessAction(e, unit, var0, var1);
3137 break;
3138 }
3141 {
3142 if (e.event.gameEvent.gameEventId != var0)
3143 return;
3144 ProcessAction(e, NULL, var0);
3145 break;
3146 }
3148 {
3149 if (e.event.goStateChanged.state != var0)
3150 return;
3151 ProcessAction(e, unit, var0, var1);
3152 break;
3153 }
3155 {
3156 if (e.event.eventInform.eventId != var0)
3157 return;
3158 ProcessAction(e, NULL, var0);
3159 break;
3160 }
3162 {
3163 if (e.event.doAction.eventId != var0)
3164 return;
3165 ProcessAction(e, unit, var0);
3166 break;
3167 }
3169 {
3170 if (!me || !me->IsInCombat())
3171 return;
3172
3173 ObjectList* _targets = NULL;
3174
3175 switch (e.GetTargetType())
3176 {
3184 _targets = GetTargets(e);
3185 break;
3186 default:
3187 return;
3188 }
3189
3190 if (!_targets)
3191 return;
3192
3193 Unit* target = NULL;
3194
3195 for (ObjectList::const_iterator itr = _targets->begin(); itr != _targets->end(); ++itr)
3196 {
3197 if (IsUnit(*itr) && me->IsFriendlyTo((*itr)->ToUnit()) && (*itr)->ToUnit()->IsAlive() && (*itr)->ToUnit()->IsInCombat())
3198 {
3199 uint32 healthPct = uint32((*itr)->ToUnit()->GetHealthPct());
3200
3201 if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct)
3202 continue;
3203
3204 target = (*itr)->ToUnit();
3205 break;
3206 }
3207 }
3208
3209 delete _targets;
3210
3211 if (!target)
3212 return;
3213
3215 break;
3216 }
3217 default:
3218 SF_LOG_ERROR("sql.sql", "SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
3219 break;
3220 }
3221}
3222
3224{
3225 switch (e.GetEventType())
3226 {
3227 //set only events which have initial timers
3228 case SMART_EVENT_UPDATE:
3232 break;
3233 case SMART_EVENT_IC_LOS:
3236 break;
3237 default:
3238 e.active = true;
3239 break;
3240 }
3241}
3243{
3244 uint32 timer = 0;
3245 if (max > 0 && min > 0)
3246 {
3247 // min/max was checked at loading!
3248 if (max > min)
3249 timer = std::rand() % (max - min + 1) + min;
3250 else
3251 timer = min;
3252 }
3253 e.timer = timer ? timer : 0;
3254 e.active = e.timer ? false : true;
3255}
3256
3258{
3259 if (e.GetEventType() == SMART_EVENT_LINK)
3260 return;
3261
3263 return;
3264
3265 if (e.GetEventType() == SMART_EVENT_UPDATE_IC && (!me || !me->IsInCombat()))
3266 return;
3267
3268 if (e.GetEventType() == SMART_EVENT_UPDATE_OOC && (me && me->IsInCombat()))//can be used with me=NULL (go script)
3269 return;
3270
3271 if (e.timer < diff)
3272 {
3273 // delay spell cast event if another spell is being casted
3275 {
3277 {
3278 if (me && me->HasUnitState(UNIT_STATE_CASTING))
3279 {
3280 e.timer = 1;
3281 return;
3282 }
3283 }
3284 }
3285
3286 e.active = true;//activate events with cooldown
3287 switch (e.GetEventType())//process ONLY timed events
3288 {
3289 case SMART_EVENT_UPDATE:
3296 case SMART_EVENT_RANGE:
3305 {
3306 ProcessEvent(e);
3308 {
3309 e.enableTimed = false;//disable event if it is in an ActionList and was processed once
3310 for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
3311 {
3312 //find the first event which is not the current one and enable it
3313 if (i->event_id > e.event_id)
3314 {
3315 i->enableTimed = true;
3316 break;
3317 }
3318 }
3319 }
3320 break;
3321 }
3322 }
3323 }
3324 else
3325 e.timer -= diff;
3326}
3327
3329{
3330 return e.active;
3331}
3332
3334{
3335 if (!mInstallEvents.empty())
3336 {
3337 for (SmartAIEventList::iterator i = mInstallEvents.begin(); i != mInstallEvents.end(); ++i)
3338 mEvents.push_back(*i);//must be before UpdateTimers
3339
3340 mInstallEvents.clear();
3341 }
3342}
3343
3345{
3346 if (!mStoredEvents.empty())
3347 {
3348 for (SmartAIEventList::iterator i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i)
3349 {
3350 if (i->event_id == id)
3351 {
3352 mStoredEvents.erase(i);
3353 return;
3354 }
3355 }
3356 }
3357}
3358
3360{
3362 return;
3363
3364 InstallEvents();//before UpdateTimers
3365
3366 for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
3367 UpdateTimer(*i, diff);
3368
3369 if (!mStoredEvents.empty())
3370 for (SmartAIEventList::iterator i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i)
3371 UpdateTimer(*i, diff);
3372
3373 bool needCleanup = true;
3374 if (!mTimedActionList.empty())
3375 {
3376 for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
3377 {
3378 if ((*i).enableTimed)
3379 {
3380 UpdateTimer(*i, diff);
3381 needCleanup = false;
3382 }
3383 }
3384 }
3385 if (needCleanup)
3386 mTimedActionList.clear();
3387
3388 if (!mRemIDs.empty())
3389 {
3390 for (std::list<uint32>::iterator i = mRemIDs.begin(); i != mRemIDs.end(); ++i)
3391 {
3392 RemoveStoredEvent((*i));
3393 }
3394 }
3395 if (mUseTextTimer && me)
3396 {
3397 if (mTextTimer < diff)
3398 {
3399 uint32 textID = mLastTextID;
3400 mLastTextID = 0;
3401 uint32 entry = mTalkerEntry;
3402 mTalkerEntry = 0;
3403 mTextTimer = 0;
3404 mUseTextTimer = false;
3405 ProcessEventsFor(SMART_EVENT_TEXT_OVER, NULL, textID, entry);
3406 }
3407 else mTextTimer -= diff;
3408 }
3409}
3410
3412{
3413 if (e.empty())
3414 {
3415 if (obj)
3416 SF_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for Entry %u is empty but is using SmartScript.", obj->GetEntry());
3417 if (at)
3418 SF_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for AreaTrigger %u is empty but is using SmartScript.", at->id);
3419 return;
3420 }
3421 for (SmartAIEventList::iterator i = e.begin(); i != e.end(); ++i)
3422 {
3423#ifndef SKYFIRE_DEBUG
3424 if ((*i).event.event_flags & SMART_EVENT_FLAG_DEBUG_ONLY)
3425 continue;
3426#endif
3427
3428 if ((*i).event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_ALL)//if has instance flag add only if in it
3429 {
3430 if (obj && obj->GetMap()->IsInstance())
3431 {
3432 if ((1 << (obj->GetMap()->GetSpawnMode() + 1)) & (*i).event.event_flags)
3433 {
3434 mEvents.push_back((*i));
3435 }
3436 }
3437 continue;
3438 }
3439 mEvents.push_back((*i));//NOTE: 'world(0)' events still get processed in ANY instance mode
3440 }
3441 if (mEvents.empty() && obj)
3442 SF_LOG_ERROR("sql.sql", "SmartScript: Entry %u has events but no events added to list because of instance flags.", obj->GetEntry());
3443 if (mEvents.empty() && at)
3444 SF_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);
3445}
3446
3448{
3450 if (me)
3451 {
3452 e = sSmartScriptMgr->GetScript(-((int32)me->GetDBTableGUIDLow()), mScriptType);
3453 if (e.empty())
3454 e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType);
3455 FillScript(e, me, NULL);
3456 }
3457 else if (go)
3458 {
3459 e = sSmartScriptMgr->GetScript(-((int32)go->GetDBTableGUIDLow()), mScriptType);
3460 if (e.empty())
3461 e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType);
3462 FillScript(e, go, NULL);
3463 }
3464 else if (trigger)
3465 {
3466 e = sSmartScriptMgr->GetScript((int32)trigger->id, mScriptType);
3467 FillScript(e, NULL, trigger);
3468 }
3469}
3470
3472{
3473 if (obj)//handle object based scripts
3474 {
3475 switch (obj->GetTypeId())
3476 {
3479 me = obj->ToCreature();
3480 SF_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Creature %u", me->GetEntry());
3481 break;
3484 go = obj->ToGameObject();
3485 SF_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is GameObject %u", go->GetEntry());
3486 break;
3487 default:
3488 SF_LOG_ERROR("misc", "SmartScript::OnInitialize: Unhandled TypeID !WARNING!");
3489 return;
3490 }
3491 }
3492 else if (at)
3493 {
3495 trigger = at;
3496 SF_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is AreaTrigger %u", trigger->id);
3497 }
3498 else
3499 {
3500 SF_LOG_ERROR("misc", "SmartScript::OnInitialize: !WARNING! Initialized objects are NULL.");
3501 return;
3502 }
3503
3504 GetScript();//load copy of script
3505
3506 for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
3507 InitTimer((*i));//calculate timers for first time use
3508
3510 InstallEvents();
3512}
3513
3515{
3517
3518 if (!me)
3519 return;
3520
3521 if (me->GetVictim())
3522 return;
3523
3525}
3526
3527/*
3528void SmartScript::UpdateAIWhileCharmed(const uint32 diff) { }
3529
3530void SmartScript::DoAction(const int32 param) { }
3531
3532uint32 SmartScript::GetData(uint32 id)
3533{
3534 return 0;
3535}
3536
3537void SmartScript::SetData(uint32 id, uint32 value) { }
3538
3539void SmartScript::SetGUID(uint64 guid, int32 id) { }
3540
3541uint64 SmartScript::GetGUID(int32 id)
3542{
3543 return 0;
3544}
3545
3546void SmartScript::MovepointStart(uint32 id) { }
3547
3548void SmartScript::SetRun(bool run) { }
3549
3550void SmartScript::SetMovePathEndAction(SMART_ACTION action) { }
3551
3552uint32 SmartScript::DoChat(int8 id, uint64 whisperGuid)
3553{
3554 return 0;
3555}*/
3556// SmartScript end
3557
3559{
3560 if (!me)
3561 return NULL;
3562
3563 CellCoord p(Skyfire::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
3564 Cell cell(p);
3565 cell.SetNoCreate();
3566
3567 Unit* unit = NULL;
3568
3569 Skyfire::MostHPMissingInRange u_check(me, range, MinHPDiff);
3571
3573
3574 cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, range);
3575 return unit;
3576}
3577
3578void SmartScript::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
3579{
3580 if (!me)
3581 return;
3582
3583 CellCoord p(Skyfire::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
3584 Cell cell(p);
3585 cell.SetNoCreate();
3586
3587 Skyfire::FriendlyCCedInRange u_check(me, range);
3589
3591
3592 cell.Visit(p, grid_creature_searcher, *me->GetMap(), *me, range);
3593}
3594
3595void SmartScript::DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid)
3596{
3597 if (!me)
3598 return;
3599
3600 CellCoord p(Skyfire::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
3601 Cell cell(p);
3602 cell.SetNoCreate();
3603
3604 Skyfire::FriendlyMissingBuffInRange u_check(me, range, spellid);
3606
3608
3609 cell.Visit(p, grid_creature_searcher, *me->GetMap(), *me, range);
3610}
3611
3613{
3614 if (!me)
3615 return NULL;
3616
3617 Unit* unit = NULL;
3618 Skyfire::AnyFriendlyUnitInObjectRangeCheck u_check(me, me, range, playerOnly);
3620 me->VisitNearbyObject(range, searcher);
3621 return unit;
3622}
3623
3625{
3626 if (!targets)
3627 return;
3628
3629 if (mTargetStorage->find(id) != mTargetStorage->end())
3630 {
3631 // check if already stored
3632 if ((*mTargetStorage)[id] == targets)
3633 return;
3634
3635 delete (*mTargetStorage)[id];
3636 }
3637
3638 (*mTargetStorage)[id] = targets;
3639}
3640
3642{
3643 mTimedActionList.clear();
3645 if (mTimedActionList.empty())
3646 return;
3647 for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
3648 {
3649 i->enableTimed = i == mTimedActionList.begin();//enable processing only for the first action
3650
3651 if (e.action.timedActionList.timerType == 0)
3652 i->event.type = SMART_EVENT_UPDATE_OOC;
3653 else if (e.action.timedActionList.timerType == 1)
3654 i->event.type = SMART_EVENT_UPDATE_IC;
3655 else if (e.action.timedActionList.timerType > 1)
3656 i->event.type = SMART_EVENT_UPDATE;
3657
3658 InitTimer((*i));
3659 }
3660}
3661
LocaleConstant
Definition Common.h:138
#define M_PI
Definition Common.h:192
#define sConditionMgr
std::list< Condition * > ConditionList
#define sCreatureTextMgr
@ TEXT_RANGE_NORMAL
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
#define sGameEventMgr
LootState
Definition GameObject.h:615
TypeMapContainer< AllGridObjectTypes > GridTypeMapContainer
Definition GridDefines.h:71
CoordPair< TOTAL_NUMBER_OF_CELLS_PER_MAP > CellCoord
@ LANG_FLEE
Definition Language.h:1098
@ LANG_CALL_FOR_HELP
Definition Language.h:1103
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ POINT_MOTION_TYPE
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_GAMEOBJECT
Definition Object.h:56
@ TYPEID_UNIT
Definition Object.h:54
TempSummonType
Definition Object.h:67
bool IS_PLAYER_GUID(uint64 guid)
#define sObjectMgr
Definition ObjectMgr.h:1617
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive)
GameObject * GetClosestGameObjectWithEntry(WorldObject *source, uint32 entry, float maxSearchRange)
#define CAST_AI(a, b)
Powers
@ POWER_MANA
ChatMsg
@ CHAT_MSG_MONSTER_EMOTE
Language
@ TEAM_OTHER
@ ALLIANCE
@ HORDE
@ SMART_SCRIPT_TYPE_TIMED_ACTIONLIST
@ SMART_SCRIPT_TYPE_CREATURE
@ SMART_SCRIPT_TYPE_GAMEOBJECT
@ SMART_SCRIPT_TYPE_AREATRIGGER
SMARTAI_TEMPLATE
@ SMARTAI_TEMPLATE_CAGED_GO_PART
@ SMARTAI_TEMPLATE_CAGED_NPC_PART
@ SMARTAI_TEMPLATE_BASIC
@ SMARTAI_TEMPLATE_CASTER
@ SMARTAI_TEMPLATE_TURRET
std::vector< SmartScriptHolder > SmartAIEventList
@ SMART_EVENT_FLAG_DIFFICULTY_ALL
@ SMART_EVENT_FLAG_DONT_RESET
@ SMART_EVENT_FLAG_DEBUG_ONLY
@ SMART_EVENT_FLAG_NOT_REPEATABLE
SMARTAI_TARGETS
@ SMART_TARGET_CLOSEST_CREATURE
@ SMART_TARGET_CREATURE_DISTANCE
@ SMART_TARGET_HOSTILE_RANDOM_NOT_TOP
@ SMART_TARGET_INVOKER_PARTY
@ SMART_TARGET_CLOSEST_FRIENDLY
@ SMART_TARGET_CLOSEST_GAMEOBJECT
@ SMART_TARGET_GAMEOBJECT_RANGE
@ SMART_TARGET_CREATURE_GUID
@ SMART_TARGET_PLAYER_RANGE
@ SMART_TARGET_VICTIM
@ SMART_TARGET_GAMEOBJECT_DISTANCE
@ SMART_TARGET_CREATURE_RANGE
@ SMART_TARGET_CLOSEST_PLAYER
@ SMART_TARGET_HOSTILE_RANDOM
@ SMART_TARGET_GAMEOBJECT_GUID
@ SMART_TARGET_HOSTILE_SECOND_AGGRO
@ SMART_TARGET_OWNER_OR_SUMMONER
@ SMART_TARGET_SELF
@ SMART_TARGET_ACTION_INVOKER
@ SMART_TARGET_POSITION
@ SMART_TARGET_HOSTILE_LAST_AGGRO
@ SMART_TARGET_ACTION_INVOKER_VEHICLE
@ SMART_TARGET_THREAT_LIST
@ SMART_TARGET_CLOSEST_ENEMY
@ SMART_TARGET_NONE
@ SMART_TARGET_PLAYER_DISTANCE
@ SMART_TARGET_STORED
@ SMART_SCRIPT_RESPAWN_CONDITION_AREA
@ SMART_SCRIPT_RESPAWN_CONDITION_MAP
#define sSmartScriptMgr
SMART_ACTION
@ SMART_ACTION_REMOVE_TIMED_EVENT
@ SMART_ACTION_NONE
@ SMART_ACTION_ADD_QUEST
@ SMART_ACTION_SET_GO_FLAG
@ SMART_ACTION_WP_RESUME
@ SMART_ACTION_UPDATE_TEMPLATE
@ SMART_ACTION_STORE_TARGET_LIST
@ SMART_ACTION_SET_HEALTH_REGEN
@ SMART_ACTION_ACTIVATE_GOBJECT
@ SMART_ACTION_FORCE_DESPAWN
@ SMART_ACTION_GAME_EVENT_START
@ SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST
@ SMART_ACTION_SET_INST_DATA64
@ SMART_ACTION_SET_FACTION
@ SMART_ACTION_THREAT_SINGLE_PCT
@ SMART_ACTION_SET_INGAME_PHASE_MASK
@ SMART_ACTION_CLOSE_GOSSIP
@ SMART_ACTION_ADD_GO_FLAG
@ SMART_ACTION_ADD_DYNAMIC_FLAG
@ SMART_ACTION_KILL_UNIT
@ SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS
@ SMART_ACTION_ATTACK_START
@ SMART_ACTION_SET_UNIT_FLAG
@ SMART_ACTION_CALL_GROUPEVENTHAPPENS
@ SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL
@ SMART_ACTION_INVOKER_CAST
@ SMART_ACTION_JUMP_TO_POS
@ SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST
@ SMART_ACTION_SEND_GOSSIP_MENU
@ SMART_ACTION_FLEE_FOR_ASSIST
@ SMART_ACTION_EQUIP
@ SMART_ACTION_SET_ROOT
@ SMART_ACTION_SUMMON_GO
@ SMART_ACTION_WP_PAUSE
@ SMART_ACTION_SIMPLE_TALK
@ SMART_ACTION_CAST
@ SMART_ACTION_ALLOW_COMBAT_MOVEMENT
@ SMART_ACTION_ADD_AURA
@ SMART_ACTION_THREAT_ALL_PCT
@ SMART_ACTION_STORE_VARIABLE_DECIMAL
@ SMART_ACTION_SET_HEALTH
@ SMART_ACTION_RESPAWN_TARGET
@ SMART_ACTION_SOUND
@ SMART_ACTION_ADD_NPC_FLAG
@ SMART_ACTION_EVADE
@ SMART_ACTION_FAIL_QUEST
@ SMART_ACTION_INTERRUPT_SPELL
@ SMART_ACTION_ADD_POWER
@ SMART_ACTION_REMOVE_DYNAMIC_FLAG
@ SMART_ACTION_RANDOM_SOUND
@ SMART_ACTION_SET_POWER
@ SMART_ACTION_MOVE_FORWARD
@ SMART_ACTION_SEND_TARGET_TO_TARGET
@ SMART_ACTION_REMOVE_POWER
@ SMART_ACTION_SET_DYNAMIC_FLAG
@ SMART_ACTION_REMOVE_ITEM
@ SMART_ACTION_SEND_GO_CUSTOM_ANIM
@ SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL
@ SMART_ACTION_REMOVE_UNIT_FLAG
@ SMART_ACTION_RANDOM_PHASE
@ SMART_ACTION_SET_EMOTE_STATE
@ SMART_ACTION_CROSS_CAST
@ SMART_ACTION_WP_STOP
@ SMART_ACTION_GAME_EVENT_STOP
@ SMART_ACTION_CALL_KILLEDMONSTER
@ SMART_ACTION_TALK
@ SMART_ACTION_CALL_SCRIPT_RESET
@ SMART_ACTION_SET_DATA
@ SMART_ACTION_WP_START
@ SMART_ACTION_COMBAT_STOP
@ SMART_ACTION_SET_RUN
@ SMART_ACTION_AUTO_ATTACK
@ SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL
@ SMART_ACTION_SET_VISIBILITY
@ SMART_ACTION_RANDOM_PHASE_RANGE
@ SMART_ACTION_GO_SET_LOOT_STATE
@ SMART_ACTION_SET_SWIM
@ SMART_ACTION_SET_INST_DATA
@ SMART_ACTION_REMOVE_GO_FLAG
@ SMART_ACTION_CALL_FOR_HELP
@ SMART_ACTION_TELEPORT
@ SMART_ACTION_PLAYMOVIE
@ SMART_ACTION_FOLLOW
@ SMART_ACTION_PLAY_EMOTE
@ SMART_ACTION_SET_EVENT_PHASE
@ SMART_ACTION_SET_SHEATH
@ SMART_ACTION_SET_ORIENTATION
@ SMART_ACTION_SET_NPC_FLAG
@ SMART_ACTION_REMOVE_UNIT_FIELD_ANIM_TIER
@ SMART_ACTION_MOVE_TO_POS
@ SMART_ACTION_RANDOM_EMOTE
@ SMART_ACTION_INC_EVENT_PHASE
@ SMART_ACTION_CREATE_TIMED_EVENT
@ SMART_ACTION_DIE
@ SMART_ACTION_RESET_SCRIPT_BASE_OBJECT
@ SMART_ACTION_REMOVE_NPC_FLAG
@ SMART_ACTION_SET_FLY
@ SMART_ACTION_INSTALL_AI_TEMPLATE
@ SMART_ACTION_SUMMON_CREATURE
@ SMART_ACTION_RESET_GOBJECT
@ SMART_ACTION_CALL_TIMED_ACTIONLIST
@ SMART_ACTION_SET_IN_COMBAT_WITH_ZONE
@ SMART_ACTION_SET_UNIT_FIELD_ANIM_TIER
@ SMART_ACTION_SET_HOME_POS
@ SMART_ACTION_ADD_ITEM
@ SMART_ACTION_SET_ACTIVE
@ SMART_ACTION_SET_RANGED_MOVEMENT
@ SMART_ACTION_ACTIVATE_TAXI
@ SMART_ACTION_SUMMON_CREATURE_GROUP
@ SMART_ACTION_SET_REACT_STATE
@ SMART_ACTION_RANDOM_MOVE
@ SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT
@ SMART_ACTION_TRIGGER_TIMED_EVENT
@ SMART_ACTION_REMOVEAURASFROMSPELL
SMART_EVENT
@ SMART_EVENT_IC_LOS
@ SMART_EVENT_EVADE
@ SMART_EVENT_ACTION_DONE
@ SMART_EVENT_SUMMON_DESPAWNED
@ SMART_EVENT_SPELLHIT
@ SMART_EVENT_RECEIVE_EMOTE
@ SMART_EVENT_FRIENDLY_HEALTH_PCT
@ SMART_EVENT_QUEST_FAIL
@ SMART_EVENT_DATA_SET
@ SMART_EVENT_RECEIVE_HEAL
@ SMART_EVENT_DUMMY_EFFECT
@ SMART_EVENT_TIMED_EVENT_TRIGGERED
@ SMART_EVENT_CHARMED_TARGET
@ SMART_EVENT_TARGET_MANA_PCT
@ SMART_EVENT_QUEST_COMPLETION
@ SMART_EVENT_JUST_CREATED
@ SMART_EVENT_AREATRIGGER_ONTRIGGER
@ SMART_EVENT_ON_SPELLCLICK
@ SMART_EVENT_MOVEMENTINFORM
@ SMART_EVENT_RANGE
@ SMART_EVENT_MANA_PCT
@ SMART_EVENT_PASSENGER_REMOVED
@ SMART_EVENT_INSTANCE_PLAYER_ENTER
@ SMART_EVENT_LINK
@ SMART_EVENT_WAYPOINT_PAUSED
@ SMART_EVENT_REACHED_HOME
@ SMART_EVENT_TRANSPORT_ADDCREATURE
@ SMART_EVENT_REWARD_QUEST
@ SMART_EVENT_GO_EVENT_INFORM
@ SMART_EVENT_UPDATE_IC
@ SMART_EVENT_RESET
@ SMART_EVENT_JUST_SUMMONED
@ SMART_EVENT_CHARMED
@ SMART_EVENT_AI_INIT
@ SMART_EVENT_WAYPOINT_START
@ SMART_EVENT_SPELLHIT_TARGET
@ SMART_EVENT_GAME_EVENT_START
@ SMART_EVENT_KILL
@ SMART_EVENT_TRANSPORT_REMOVE_PLAYER
@ SMART_EVENT_GOSSIP_HELLO
@ SMART_EVENT_GOSSIP_SELECT
@ SMART_EVENT_CORPSE_REMOVED
@ SMART_EVENT_QUEST_OBJ_COPLETETION
@ SMART_EVENT_PASSENGER_BOARDED
@ SMART_EVENT_UPDATE
@ SMART_EVENT_TRANSPORT_ADDPLAYER
@ SMART_EVENT_WAYPOINT_ENDED
@ SMART_EVENT_IS_BEHIND_TARGET
@ SMART_EVENT_UPDATE_OOC
@ SMART_EVENT_ACCEPTED_QUEST
@ SMART_EVENT_FRIENDLY_MISSING_BUFF
@ SMART_EVENT_WAYPOINT_RESUMED
@ SMART_EVENT_WAYPOINT_REACHED
@ SMART_EVENT_TARGET_BUFFED
@ SMART_EVENT_RESPAWN
@ SMART_EVENT_QUEST_ACCEPTED
@ SMART_EVENT_HEALT_PCT
@ SMART_EVENT_FRIENDLY_HEALTH
@ SMART_EVENT_QUEST_REWARDED
@ SMART_EVENT_TEXT_OVER
@ SMART_EVENT_DEATH
@ SMART_EVENT_TRANSPORT_RELOCATE
@ SMART_EVENT_GAME_EVENT_END
@ SMART_EVENT_DAMAGED
@ SMART_EVENT_FOLLOW_COMPLETED
@ SMART_EVENT_WAYPOINT_STOPPED
@ SMART_EVENT_FRIENDLY_IS_CC
@ SMART_EVENT_GO_STATE_CHANGED
@ SMART_EVENT_OOC_LOS
@ SMART_EVENT_AGGRO
@ SMART_EVENT_TARGET_HEALTH_PCT
@ SMART_EVENT_VICTIM_CASTING
@ SMART_EVENT_DAMAGED_TARGET
@ SMART_EVENT_HAS_AURA
@ SMART_EVENT_SUMMONED_UNIT
@ SMART_RANDOM_POINT
@ SMART_ACTION_PARAM_COUNT
@ SMART_ESCORT_TARGETS
UNORDERED_MAP< uint32, ObjectList * > ObjectListMap
@ SMARTCAST_TRIGGERED
@ SMARTCAST_INTERRUPT_PREVIOUS
@ SMARTCAST_AURA_NOT_PRESENT
std::list< WorldObject * > ObjectList
@ CURRENT_GENERIC_SPELL
Definition Unit.h:1109
SheathState
Definition Unit.h:244
@ UNIT_STATE_ROOT
Definition Unit.h:522
@ UNIT_STATE_CASTING
Definition Unit.h:527
ReactStates
Definition Unit.h:1155
@ SELECT_TARGET_BOTTOMAGGRO
Definition UnitAI.h:25
@ SELECT_TARGET_TOPAGGRO
Definition UnitAI.h:24
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS2
@ UNIT_FIELD_VIRTUAL_ITEM_ID
@ UNIT_FIELD_NPC_FLAGS
@ UNIT_FIELD_ANIM_TIER
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_NPC_EMOTESTATE
@ OBJECT_FIELD_DYNAMIC_FLAGS
@ GAMEOBJECT_FIELD_FLAGS
size_t wpos() const
Definition ByteBuffer.h:483
Definition Group.h:147
GroupReference * next()
static T * Find(uint64 guid)
uint8 GetSpawnMode() const
Definition Map.h:358
bool IsInstance() const
Definition Map.h:368
static Unit * GetUnit(WorldObject const &, uint64 guid)
static Player * FindPlayer(uint64)
static Unit * FindUnit(uint64)
uint64 GetGUID() const
Definition Object.h:119
Player * ToPlayer()
Definition Object.h:204
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
GameObject * ToGameObject()
Definition Object.h:213
uint32 GetEntry() const
Definition Object.h:125
Creature * ToCreature()
Definition Object.h:207
Unit * ToUnit()
Definition Object.h:210
static uint32 ChooseDisplayId(CreatureTemplate const *cinfo, CreatureData const *data=NULL)
void GroupEventHappens(uint32 questId, WorldObject const *pEventObject)
size_t operator()(WorldPacket *data, LocaleConstant locale) const
SkyFireStringTextBuilder(WorldObject *obj, ChatMsg msgtype, int32 id, Language language, uint64 targetGUID)
void SetInvincibilityHpLevel(uint32 level)
Definition SmartAI.h:164
bool CheckTimer(SmartScriptHolder const &e) const
uint32 mEventPhase
SmartAIEventList mStoredEvents
SMARTAI_TEMPLATE mTemplate
uint64 goOrigGUID
Creature * FindCreatureNear(WorldObject *searchObject, uint32 guid) const
Creature * me
uint32 mPathId
void OnUpdate(const uint32 diff)
SmartScriptType mScriptType
ObjectList * GetWorldObjectsInDist(float dist)
void InstallEvents()
void UpdateTimer(SmartScriptHolder &e, uint32 const diff)
void SetScript9(SmartScriptHolder &e, uint32 entry)
SmartScriptHolder CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, 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)
bool mUseTextTimer
uint32 mLastTextID
void DoFindFriendlyCC(std::list< Creature * > &_list, float range)
void RecalcTimer(SmartScriptHolder &e, uint32 min, uint32 max)
void ProcessEventsFor(SMART_EVENT e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
Unit * DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
SmartScriptHolder FindLinkedEvent(uint32 link)
bool IsUnit(WorldObject *obj)
Definition SmartScript.h:53
ObjectList * GetTargets(SmartScriptHolder const &e, Unit *invoker=NULL)
uint32 mTextTimer
void DecPhase(int32 p=1)
void OnInitialize(WorldObject *obj, AreaTriggerEntry const *at=NULL)
bool IsPlayer(WorldObject *obj)
Definition SmartScript.h:58
uint64 mLastInvoker
void AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, 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)
Unit * DoFindClosestFriendlyInRange(float range, bool playerOnly)
bool IsCreature(WorldObject *obj)
Definition SmartScript.h:63
void FillScript(SmartAIEventList e, WorldObject *obj, AreaTriggerEntry const *at)
GameObject * FindGameObjectNear(WorldObject *searchObject, uint32 guid) const
void OnMoveInLineOfSight(Unit *who)
uint32 GetPathId() const
Definition SmartScript.h:42
GameObject * go
ObjectList * GetTargetList(uint32 id)
bool IsInPhase(uint32 p) const
SmartAIEventList mInstallEvents
void InitTimer(SmartScriptHolder &e)
AreaTriggerEntry const * trigger
void IncPhase(int32 p=1)
ObjectListMap * mTargetStorage
UNORDERED_MAP< int32, int32 > mStoredDecimals
void DoFindFriendlyMissingBuff(std::list< Creature * > &list, float range, uint32 spellid)
std::list< uint32 > mRemIDs
uint32 mTalkerEntry
bool IsGameObject(WorldObject *obj)
Definition SmartScript.h:68
void ProcessEvent(SmartScriptHolder &e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
bool IsSmartGO(GameObject *g=NULL)
Definition SmartScript.h:98
void SetPhase(uint32 p=0)
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)
SmartAIEventList mEvents
void InstallTemplate(SmartScriptHolder const &e)
bool IsSmart(Creature *c=NULL)
Definition SmartScript.h:83
WorldObject * GetBaseObject()
Definition SmartScript.h:43
SmartAIEventList mTimedActionList
void ProcessAction(SmartScriptHolder &e, Unit *unit=NULL, uint32 var0=0, uint32 var1=0, bool bvar=false, const SpellInfo *spell=NULL, GameObject *gob=NULL)
Unit * GetLastInvoker()
uint64 meOrigGUID
void StoreTargetList(ObjectList *targets, uint32 id)
void RemoveStoredEvent(uint32 id)
void ResetBaseObject()
Definition Spell.h:289
uint32 Id
Definition SpellInfo.h:160
uint32 SchoolMask
Definition SpellInfo.h:231
std::list< HostileReference * > StorageType
Definition Unit.h:1367
Vehicle * GetVehicle() const
Definition Unit.h:2743
bool IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:1402
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:1433
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
Vehicle * GetVehicleKit() const
Definition Unit.h:2739
bool IsInCombat() const
Definition Unit.h:1896
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:2363
Unit * GetBase() const
May be called from scripts.
Definition Vehicle.h:38
Map * GetMap() const
Definition Object.h:740
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
std::string const & GetName() const
Definition Object.h:664
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:782
GameObject * SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
Definition Object.cpp:2729
bool IsInRange(WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
Definition Object.cpp:1775
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=NULL)
Definition Object.cpp:2787
virtual void SetData64(uint32, uint64)
Definition ZoneScript.h:33
virtual void SetData(uint32, uint32)
Definition ZoneScript.h:37
CellCoord ComputeCellCoord(float x, float y)
uint32 id
Definition Cell.h:37
void SetNoCreate()
Definition Cell.h:66
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition CellImpl.h:109
uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]
Definition Creature.h:245
float GetPositionZ() const
Definition Object.h:330
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
struct SmartAction::@137136306204214247065175315134144360247331017331::@063217247236027134221310037325112126070263107200 installTtemplate
uint32 healthpointmod
uint32 targetParam2
struct SmartAction::@137136306204214247065175315134144360247331017331::@223221030233146165101047364315320356273243300160 killedMonster
struct SmartAction::@137136306204214247065175315134144360247331017331::@362126153056054377271167251121034140104172033254 sendTargetToTarget
struct SmartAction::@137136306204214247065175315134144360247331017331::@056037146104051216040022366365070022176220102015 setEventPhase
struct SmartAction::@137136306204214247065175315134144360247331017331::@202121053104314201255122102201207263246120035036 setRangedMovement
struct SmartAction::@137136306204214247065175315134144360247331017331::@225326137357300251213255332357005062365342332334 taxi
struct SmartAction::@137136306204214247065175315134144360247331017331::@125305003154321137305003172072215042325305172115 setSwim
struct SmartAction::@137136306204214247065175315134144360247331017331::@032247343121317314325033254113252354347071044324 timedActionList
struct SmartAction::@137136306204214247065175315134144360247331017331::@263337113206264100344005071314123271031160215224 incEventPhase
struct SmartAction::@137136306204214247065175315134144360247331017331::@262062362063376054103076310127135246225346312115 follow
struct SmartAction::@137136306204214247065175315134144360247331017331::@323250253076201247247032355216135323066263226166 summonGO
struct SmartAction::@137136306204214247065175315134144360247331017331::@260014043352000167110056244356272120365357113047 power
int32 healthpointpercent
struct SmartAction::@137136306204214247065175315134144360247331017331::@211024050222126232204263041344063334075351151253 storeVar
struct SmartAction::@137136306204214247065175315134144360247331017331::@056307337001341304225116105052047116305102131322 ingamePhaseId
struct SmartAction::@137136306204214247065175315134144360247331017331::@023276076022007070341053170160156071313157015060 moveRandom
struct SmartAction::@137136306204214247065175315134144360247331017331::@146025204151373170035336166324347315111301135304 goFlag
uint32 targetParam1
struct SmartAction::@137136306204214247065175315134144360247331017331::@322335154115274224237056033042154141310270174273 randTimedActionList
struct SmartAction::@137136306204214247065175315134144360247331017331::@312023305216037355162221347243201252312370300333 unitFlag
struct SmartAction::@137136306204214247065175315134144360247331017331::@170222221015243003166361030047273347230060275030 setInstanceData64
struct SmartAction::@137136306204214247065175315134144360247331017331::@105154066270000205250254221004375132270204111257 faction
struct SmartAction::@137136306204214247065175315134144360247331017331::@237106077034177101205127163210006223365202222163 talk
struct SmartAction::@137136306204214247065175315134144360247331017331::@013257352102053165303132060302205025211375037125 setHealthRegen
struct SmartAction::@137136306204214247065175315134144360247331017331::@232263171056172116357036326052343214356025224311 setRun
struct SmartAction::@137136306204214247065175315134144360247331017331::@275255223343355134011263135140247005064156134156 removeAura
struct SmartAction::@137136306204214247065175315134144360247331017331::@106331226105025351167175306102157241205132176043 threatPCT
struct SmartAction::@137136306204214247065175315134144360247331017331::@017017301336332264150073045027362135176250171251 delunitByte
struct SmartAction::@137136306204214247065175315134144360247331017331::@340117101002077274057262132157002056007011042371 item
uint32 targetParam3
struct SmartAction::@137136306204214247065175315134144360247331017331::@321334216220214152324067135252322006365237051372 summonCreature
struct SmartAction::@137136306204214247065175315134144360247331017331::@102027324320366347114036112231276256216375356341 forceDespawn
struct SmartAction::@137136306204214247065175315134144360247331017331::@234064157343222026123004206306000221273052034177 interruptSpellCasting
struct SmartAction::@137136306204214247065175315134144360247331017331::@327043224271174220045213146224240101337012120173 combatMove
struct SmartAction::@137136306204214247065175315134144360247331017331::@253050363250105135033216017175137100101324053136 flee
struct SmartAction::@137136306204214247065175315134144360247331017331::@271373373116125344236343321340152150140162062203 updateTemplate
struct SmartAction::@137136306204214247065175315134144360247331017331::@237127210277144266063211043133264370366070237302 storeTargets
struct SmartAction::@137136306204214247065175315134144360247331017331::@275214002000035051002312305231375170105074073031 react
struct SmartAction::@137136306204214247065175315134144360247331017331::@222323075055020043337006115334025200027336144060 setGoLootState
struct SmartAction::@137136306204214247065175315134144360247331017331::@244305372364075262301351325221332130061212111120 equip
struct SmartAction::@137136306204214247065175315134144360247331017331::@030016163313022245256210315150151222345056203275 randomPhaseRange
SMART_ACTION type
struct SmartAction::@137136306204214247065175315134144360247331017331::@364140021337216071013031072126362152213217361022 gameEventStart
struct SmartAction::@137136306204214247065175315134144360247331017331::@231234170206337120370317003230107262076077176377 sethealthpointorpercent
struct SmartAction::@137136306204214247065175315134144360247331017331::@366346013116331267251301000101176066154005153314 wpStart
uint32 gossipMenuId
uint32 gossipNpcTextId
struct SmartAction::@137136306204214247065175315134144360247331017331::@252203015076101372213105211340142002040360102025 jump
struct SmartAction::@137136306204214247065175315134144360247331017331::@053047050057114047035035162205275317245206006202 visibility
struct SmartAction::@137136306204214247065175315134144360247331017331::@304307032125035107043074211115267356000271173275 invincHP
struct SmartAction::@137136306204214247065175315134144360247331017331::@077320174144025067034346062363121331330116113042 sendGossipMenu
struct SmartAction::@137136306204214247065175315134144360247331017331::@125064266206015146053042115264002074265057332210 RespawnTarget
struct SmartAction::@137136306204214247065175315134144360247331017331::@154353352031206117237307025011150000165343160075 gameEventStop
struct SmartAction::@137136306204214247065175315134144360247331017331::@017204072246217361054270126345157054047267131155 timeEvent
struct SmartAction::@137136306204214247065175315134144360247331017331::@113375321062033017213200334254054264335370016350 setRoot
struct SmartAction::@137136306204214247065175315134144360247331017331::@012013052354341222130370041241340206147214340017 active
struct SmartAction::@137136306204214247065175315134144360247331017331::@070027157377176027211043175361120005242332321041 cast
struct SmartAction::@137136306204214247065175315134144360247331017331::@361253355005363233353246257362125371204257066324 wpStop
struct SmartAction::@137136306204214247065175315134144360247331017331::@072015025131263067117155164031252072143036172206 setFly
struct SmartAction::@137136306204214247065175315134144360247331017331::@034027334375127044264311057312165257123120035111 setSheath
uint32 attackInvoker
struct SmartAction::@137136306204214247065175315134144360247331017331::@047257325033252011304017203222214205224131346024 randomEmote
struct SmartAction::@137136306204214247065175315134144360247331017331::@146067006045202033167137301332374134247215001225 morphOrMount
struct SmartAction::@137136306204214247065175315134144360247331017331::@134276106155246334274174066250006371264262265141 movie
struct SmartAction::@137136306204214247065175315134144360247331017331::@314010003225126163310372071105334257143315207166 MoveToPos
struct SmartAction::@137136306204214247065175315134144360247331017331::@155372325360324370022313255343031333045270217002 setInstanceData
struct SmartAction::@137136306204214247065175315134144360247331017331::@124325320104077343177176052310130023304351310216 randomSound
struct SmartAction::@137136306204214247065175315134144360247331017331::@036364267355312211235014262213357013044042051306 callHelp
struct SmartAction::@137136306204214247065175315134144360247331017331::@017345322206322315133100210307152010072305326222 teleport
uint32 goRespawnTime
struct SmartAction::@137136306204214247065175315134144360247331017331::@247156106221324315321034033112331371231160171352 setunitByte
struct SmartAction::@137136306204214247065175315134144360247331017331::@110372216333363233013275026147121341347021271102 raw
struct SmartAction::@137136306204214247065175315134144360247331017331::@216226275100333317146042116304160061113317344104 randomPhase
struct SmartAction::@137136306204214247065175315134144360247331017331::@211003267135025237246004137032245170325052026370 sendGoCustomAnim
struct SmartAction::@137136306204214247065175315134144360247331017331::@375336150123327052355224140114304021206245264240 wpPause
struct SmartAction::@137136306204214247065175315134144360247331017331::@231354224040032224162034026304373127302354021157 creatureGroup
struct SmartAction::@137136306204214247065175315134144360247331017331::@073131015240006350100116003135343265143231067154 setData
struct SmartAction::@137136306204214247065175315134144360247331017331::@111103063200063043211267272370026157313266151007 autoAttack
struct SmartEvent::@166073203170024010224000246043245045265275236352::@205334221103210356102216306336035204273105217373 doAction
struct SmartEvent::@166073203170024010224000246043245045265275236352::@035124263137161112271324316211040076034364300254 friendlyHealthPct
uint32 event_flags
uint32 event_phase_mask
struct SmartEvent::@166073203170024010224000246043245045265275236352::@151214011253067366266013227241263175352330107015 spellHit
struct SmartEvent::@166073203170024010224000246043245045265275236352::@153240210013057316073206114055356342200322004153 areatrigger
struct SmartEvent::@166073203170024010224000246043245045265275236352::@331123367372304044150027144120234260063243315361 raw
struct SmartEvent::@166073203170024010224000246043245045265275236352::@071217147231100355344130024153246046254076175303 minMax
struct SmartEvent::@166073203170024010224000246043245045265275236352::@014244365015242120343050241027342311345320231372 kill
uint32 cooldownMax
struct SmartEvent::@166073203170024010224000246043245045265275236352::@221026305077317174075143035236341220146202106111 summoned
struct SmartEvent::@166073203170024010224000246043245045265275236352::@346027276323067131151203154341341353172275342001 textOver
struct SmartEvent::@166073203170024010224000246043245045265275236352::@202207111237273327363141057053252156066031227127 targetCasting
struct SmartEvent::@166073203170024010224000246043245045265275236352::@362275236245375345071356133116337307370006121222 goStateChanged
struct SmartEvent::@166073203170024010224000246043245045265275236352::@143336307355047137005241062216153351167151345337 transportAddCreature
struct SmartEvent::@166073203170024010224000246043245045265275236352::@374352063271056252122325060177325011004327327320 dummy
struct SmartEvent::@166073203170024010224000246043245045265275236352::@317215266053337235107156201003013251003136307007 dataSet
struct SmartEvent::@166073203170024010224000246043245045265275236352::@334243344311240353276325365000066230155007140117 timedEvent
struct SmartEvent::@166073203170024010224000246043245045265275236352::@126332302352372325113370275237377071315133246044 instancePlayerEnter
struct SmartEvent::@166073203170024010224000246043245045265275236352::@316052106375244313267206021344134155050363137163 gameEvent
uint32 event_chance
struct SmartEvent::@166073203170024010224000246043245045265275236352::@307010223035152345021275132122032265112355252253 eventInform
uint32 creatureEntry
struct SmartEvent::@166073203170024010224000246043245045265275236352::@257367200352143300221314024050114266124250256202 waypoint
struct SmartEvent::@166073203170024010224000246043245045265275236352::@231361362314252335147144320331135255146044361230 friendlyHealth
struct SmartEvent::@166073203170024010224000246043245045265275236352::@176246375035351301250241104017222341335356255101 minMaxRepeat
struct SmartEvent::@166073203170024010224000246043245045265275236352::@215225270007231027007174002122072040103111365225 aura
struct SmartEvent::@166073203170024010224000246043245045265275236352::@334366012233311313242122122157342315242332057236 gossip
struct SmartEvent::@166073203170024010224000246043245045265275236352::@153222357016331217240244030161351100040203125306 missingBuff
uint32 gameEventId
uint32 playerOnly
uint32 textGroupID
uint32 cooldownMin
struct SmartEvent::@166073203170024010224000246043245045265275236352::@133146201062172166200111053367224171220224362315 movementInform
struct SmartEvent::@166073203170024010224000246043245045265275236352::@010250233120134241015123153125242336170064340121 friendlyCC
struct SmartEvent::@166073203170024010224000246043245045265275236352::@140352011036232354166330333342335043070367211016 respawn
struct SmartEvent::@166073203170024010224000246043245045265275236352::@206071060360274252071246267136154353111152272204 los
SMART_EVENT type
struct SmartEvent::@166073203170024010224000246043245045265275236352::@201273004001225050106107035207231367176035206120 behindTarget
uint32 GetScriptType() const
uint32 GetEventType() const
uint32 GetTargetType() const
SmartScriptType source_type
uint32 GetActionType() const
struct SmartTarget::@333075361354170120173166243340237372226003166270::@110256257245272044322021152036011326202127237137 playerRange
struct SmartTarget::@333075361354170120173166243340237372226003166270::@245074100075004133116202301110122270342210362333 stored
struct SmartTarget::@333075361354170120173166243340237372226003166270::@331304071055133014342035021265106076261007323121 raw
struct SmartTarget::@333075361354170120173166243340237372226003166270::@164140207365237140026212144235174166326315355055 closestAttackable
struct SmartTarget::@333075361354170120173166243340237372226003166270::@252242265355222362137233075236171264264255250353 goDistance
struct SmartTarget::@333075361354170120173166243340237372226003166270::@336062220142255354121274120211064254344004061316 closest
struct SmartTarget::@333075361354170120173166243340237372226003166270::@002214221374016261141032233225077144161065220344 unitGUID
SMARTAI_TARGETS type
struct SmartTarget::@333075361354170120173166243340237372226003166270::@172360030245270120053010162234377345135043301307 unitDistance
struct SmartTarget::@333075361354170120173166243340237372226003166270::@333153342272102313242245202311020165275131037122 goRange
struct SmartTarget::@333075361354170120173166243340237372226003166270::@262226145054070224013345240063324147141336277263 playerDistance
struct SmartTarget::@333075361354170120173166243340237372226003166270::@350332235033377264000372176067130337053021314362 closestFriendly
struct SmartTarget::@333075361354170120173166243340237372226003166270::@067073135241122173103324205206246325065313214360 unitRange
struct SmartTarget::@333075361354170120173166243340237372226003166270::@163054074026206351133353217237356273245266110331 goGUID