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();  | 
