diff options
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 11 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.h | 3 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 33 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 13 |
4 files changed, 53 insertions, 7 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index edb81d6f176..f5bf2b975e3 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -790,8 +790,10 @@ void SmartAI::SetFollow(Unit* target, float dist, float angle, uint32 credit, ui mFollowCreditType = creditType; } -void SmartAI::SetScript9(SmartScriptHolder &e, uint32 entry) +void SmartAI::SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker) { + if (invoker) + GetScript()->mLastInvoker = invoker; GetScript()->SetScript9(e, entry); } /* @@ -889,6 +891,13 @@ void SmartGameObjectAI::SetData(uint32 id, uint32 value) GetScript()->ProcessEventsFor(SMART_EVENT_DATA_SET, NULL, id, value); } +void SmartGameObjectAI::SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker) +{ + if (invoker) + GetScript()->mLastInvoker = invoker; + GetScript()->SetScript9(e, entry); +} + class SmartTrigger : public AreaTriggerScript { public: diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index ac67704b120..30aeef323a6 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -65,7 +65,7 @@ class SmartAI : public CreatureAI void SetCombatMove(bool on); void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0); - void SetScript9(SmartScriptHolder &e, uint32 entry); + void SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker); SmartScript* GetScript() { return &mScript; } bool IsEscortInvokerInRange(); @@ -248,6 +248,7 @@ public: uint32 GetDialogStatus(Player* /*player*/); void Destroyed(Player* player, uint32 eventId); void SetData(uint32 id, uint32 value); + void SetScript9(SmartScriptHolder &e, uint32 entry, Unit* invoker); protected: GameObject * const go; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 11f38ed40c8..087aee750ba 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1063,6 +1063,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u } case SMART_ACTION_CALL_TIMED_ACTIONLIST: { + if (e.GetTargetType() == SMART_TARGET_NONE) + { + sLog.outErrorDb("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()); + return; + } ObjectList* targets = GetTargets(e, unit); if (targets) { @@ -1071,7 +1076,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u if (Creature* target = (*itr)->ToCreature()) { if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id); + CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, mLastInvoker); + } else if (GameObject* target = (*itr)->ToGameObject()) + { + if (IsSmartGO(target)) + CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, e.action.timedActionList.id, mLastInvoker); } } } @@ -1147,6 +1156,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u } } uint32 id = temp[urand(0, count)]; + if (e.GetTargetType() == SMART_TARGET_NONE) + { + sLog.outErrorDb("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()); + return; + } ObjectList* targets = GetTargets(e, unit); if (targets) { @@ -1155,7 +1169,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u if (Creature* target = (*itr)->ToCreature()) { if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, id); + CAST_AI(SmartAI, target->AI())->SetScript9(e, id, mLastInvoker); + } else if (GameObject* target = (*itr)->ToGameObject()) + { + if (IsSmartGO(target)) + CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, id, mLastInvoker); } } } @@ -1164,6 +1182,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST: { uint32 id = urand(e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2); + if (e.GetTargetType() == SMART_TARGET_NONE) + { + sLog.outErrorDb("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()); + return; + } ObjectList* targets = GetTargets(e, unit); if (targets) { @@ -1172,7 +1195,11 @@ void SmartScript::ProcessAction(SmartScriptHolder &e, Unit* unit, uint32 var0, u if (Creature* target = (*itr)->ToCreature()) { if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, id); + CAST_AI(SmartAI, target->AI())->SetScript9(e, id, mLastInvoker); + } else if (GameObject* target = (*itr)->ToGameObject()) + { + if (IsSmartGO(target)) + CAST_AI(SmartGameObjectAI, target->AI())->SetScript9(e, id, mLastInvoker); } } } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 16064d6591d..7c43abba155 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -111,7 +111,16 @@ class SmartScript if (c && c->GetAIName() != "SmartAI") smart = false; if (!me || me->GetAIName() != "SmartAI") smart = false; if (!smart) - sLog.outErrorDb("SmartScript: Action target creature(entry: %u) is not using SmartAI, action skipped to prevent crash.", c?c->GetEntry():(me?me->GetEntry():0)); + sLog.outErrorDb("SmartScript: Action target Creature(entry: %u) is not using SmartAI, action skipped to prevent crash.", c?c->GetEntry():(me?me->GetEntry():0)); + return smart; + } + bool IsSmartGO(GameObject* g = NULL) + { + bool smart = true; + if (g && g->GetAIName() != "SmartGameObjectAI") smart = false; + if (!go || go->GetAIName() != "SmartGameObjectAI") smart = false; + if (!smart) + sLog.outErrorDb("SmartScript: Action target GameObject(entry: %u) is not using SmartGameObjectAI, action skipped to prevent crash.", g?g->GetEntry():(go?go->GetEntry():0)); return smart; } ObjectList* GetTargetList(uint32 id) @@ -182,6 +191,7 @@ class SmartScript //TIMED_ACTIONLIST (script type 9 aka script9) void SetScript9(SmartScriptHolder &e, uint32 entry); + Unit* mLastInvoker; private: void IncPhase(int32 p = 1) { @@ -217,7 +227,6 @@ class SmartScript uint64 mTextGUID; Creature* talker; bool mUseTextTimer; - Unit* mLastInvoker; SMARTAI_TEMPLATE mTemplate; void InstallEvents(); |