Advertisement
Guest User

ScriptMgr.cpp

a guest
Sep 24th, 2016
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 82.26 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
  3.  * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License as published by the
  7.  * Free Software Foundation; either version 2 of the License, or (at your
  8.  * option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful, but WITHOUT
  11.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12.  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13.  * more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program. If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. #include "ScriptMgr.h"
  20. #include "ScriptReloadMgr.h"
  21. #include "Config.h"
  22. #include "DatabaseEnv.h"
  23. #include "DBCStores.h"
  24. #include "ObjectMgr.h"
  25. #include "OutdoorPvPMgr.h"
  26. #include "ScriptSystem.h"
  27. #include "Transport.h"
  28. #include "Vehicle.h"
  29. #include "SmartAI.h"
  30. #include "SpellInfo.h"
  31. #include "SpellScript.h"
  32. #include "GossipDef.h"
  33. #include "CreatureAIImpl.h"
  34. #include "Player.h"
  35. #include "WorldPacket.h"
  36. #ifdef ELUNA
  37. #include "LuaEngine.h"
  38. #include "ElunaUtility.h"
  39. #endif
  40. #include "WorldSession.h"
  41. #include "Chat.h"
  42. #include "MapManager.h"
  43. #include "LFGScripts.h"
  44. #include "InstanceScript.h"
  45.  
  46. // Trait which indicates whether this script type
  47. // must be assigned in the database.
  48. template<typename>
  49. struct is_script_database_bound
  50.     : std::false_type { };
  51.  
  52. template<>
  53. struct is_script_database_bound<SpellScriptLoader>
  54.     : std::true_type { };
  55.  
  56. template<>
  57. struct is_script_database_bound<InstanceMapScript>
  58.     : std::true_type { };
  59.  
  60. template<>
  61. struct is_script_database_bound<ItemScript>
  62.     : std::true_type { };
  63.  
  64. template<>
  65. struct is_script_database_bound<CreatureScript>
  66.     : std::true_type { };
  67.  
  68. template<>
  69. struct is_script_database_bound<GameObjectScript>
  70.     : std::true_type { };
  71.  
  72. template<>
  73. struct is_script_database_bound<VehicleScript>
  74.     : std::true_type { };
  75.  
  76. template<>
  77. struct is_script_database_bound<AreaTriggerScript>
  78.     : std::true_type { };
  79.  
  80. template<>
  81. struct is_script_database_bound<BattlegroundScript>
  82.     : std::true_type { };
  83.  
  84. template<>
  85. struct is_script_database_bound<OutdoorPvPScript>
  86.     : std::true_type { };
  87.  
  88. template<>
  89. struct is_script_database_bound<WeatherScript>
  90.     : std::true_type { };
  91.  
  92. template<>
  93. struct is_script_database_bound<ConditionScript>
  94.     : std::true_type { };
  95.  
  96. template<>
  97. struct is_script_database_bound<TransportScript>
  98.     : std::true_type { };
  99.  
  100. template<>
  101. struct is_script_database_bound<AchievementCriteriaScript>
  102.     : std::true_type { };
  103.  
  104. enum Spells
  105. {
  106.     SPELL_HOTSWAP_VISUAL_SPELL_EFFECT = 40162 // 59084
  107. };
  108.  
  109. class ScriptRegistryInterface
  110. {
  111. public:
  112.     ScriptRegistryInterface() { }
  113.     virtual ~ScriptRegistryInterface() { }
  114.  
  115.     ScriptRegistryInterface(ScriptRegistryInterface const&) = delete;
  116.     ScriptRegistryInterface(ScriptRegistryInterface&&) = delete;
  117.  
  118.     ScriptRegistryInterface& operator= (ScriptRegistryInterface const&) = delete;
  119.     ScriptRegistryInterface& operator= (ScriptRegistryInterface&&) = delete;
  120.  
  121.     /// Removes all scripts associated with the given script context.
  122.     /// Requires ScriptRegistryBase::SwapContext to be called after all transfers have finished.
  123.     virtual void ReleaseContext(std::string const& context) = 0;
  124.  
  125.     /// Injects and updates the changed script objects.
  126.     virtual void SwapContext(bool initialize) = 0;
  127.  
  128.     /// Removes the scripts used by this registry from the given container.
  129.     /// Used to find unused script names.
  130.     virtual void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) = 0;
  131.  
  132.     /// Unloads the script registry.
  133.     virtual void Unload() = 0;
  134. };
  135.  
  136. template<class>
  137. class ScriptRegistry;
  138.  
  139. class ScriptRegistryCompositum
  140.     : public ScriptRegistryInterface
  141. {
  142.     ScriptRegistryCompositum() { }
  143.  
  144.     template<class>
  145.     friend class ScriptRegistry;
  146.  
  147.     /// Type erasure wrapper for objects
  148.     class DeleteableObjectBase
  149.     {
  150.     public:
  151.         DeleteableObjectBase() { }
  152.         virtual ~DeleteableObjectBase() { }
  153.  
  154.         DeleteableObjectBase(DeleteableObjectBase const&) = delete;
  155.         DeleteableObjectBase& operator= (DeleteableObjectBase const&) = delete;
  156.     };
  157.  
  158.     template<typename T>
  159.     class DeleteableObject
  160.         : public DeleteableObjectBase
  161.     {
  162.     public:
  163.         DeleteableObject(T&& object)
  164.             : _object(std::forward<T>(object)) { }
  165.  
  166.     private:
  167.         T _object;
  168.     };
  169.  
  170. public:
  171.     void SetScriptNameInContext(std::string const& scriptname, std::string const& context)
  172.     {
  173.         ASSERT(_scriptnames_to_context.find(scriptname) == _scriptnames_to_context.end(),
  174.                "Scriptname was assigned to this context already!");
  175.         _scriptnames_to_context.insert(std::make_pair(scriptname, context));
  176.     }
  177.  
  178.     std::string const& GetScriptContextOfScriptName(std::string const& scriptname) const
  179.     {
  180.         auto itr = _scriptnames_to_context.find(scriptname);
  181.         ASSERT(itr != _scriptnames_to_context.end() &&
  182.                "Given scriptname doesn't exist!");
  183.         return itr->second;
  184.     }
  185.  
  186.     void ReleaseContext(std::string const& context) final override
  187.     {
  188.         for (auto const registry : _registries)
  189.             registry->ReleaseContext(context);
  190.  
  191.         // Clear the script names in context after calling the release hooks
  192.         // since it's possible that new references to a shared library
  193.        // are acquired when releasing.
  194.        for (auto itr = _scriptnames_to_context.begin();
  195.                        itr != _scriptnames_to_context.end();)
  196.            if (itr->second == context)
  197.                itr = _scriptnames_to_context.erase(itr);
  198.            else
  199.                ++itr;
  200.    }
  201.  
  202.    void SwapContext(bool initialize) final override
  203.    {
  204.        for (auto const registry : _registries)
  205.            registry->SwapContext(initialize);
  206.  
  207.        DoDelayedDelete();
  208.    }
  209.  
  210.    void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) final override
  211.    {
  212.        for (auto const registry : _registries)
  213.            registry->RemoveUsedScriptsFromContainer(scripts);
  214.    }
  215.  
  216.    void Unload() final override
  217.    {
  218.        for (auto const registry : _registries)
  219.            registry->Unload();
  220.    }
  221.  
  222.    template<typename T>
  223.    void QueueForDelayedDelete(T&& any)
  224.    {
  225.        _delayed_delete_queue.push_back(
  226.            Trinity::make_unique<
  227.                DeleteableObject<typename std::decay<T>::type>
  228.            >(std::forward<T>(any))
  229.        );
  230.    }
  231.  
  232.    static ScriptRegistryCompositum* Instance()
  233.    {
  234.        static ScriptRegistryCompositum instance;
  235.        return &instance;
  236.    }
  237.  
  238. private:
  239.    void Register(ScriptRegistryInterface* registry)
  240.    {
  241.        _registries.insert(registry);
  242.    }
  243.  
  244.    void DoDelayedDelete()
  245.    {
  246.        _delayed_delete_queue.clear();
  247.    }
  248.  
  249.    std::unordered_set<ScriptRegistryInterface*> _registries;
  250.  
  251.    std::vector<std::unique_ptr<DeleteableObjectBase>> _delayed_delete_queue;
  252.  
  253.    std::unordered_map<
  254.        std::string /*script name*/,
  255.        std::string /*context*/
  256.    > _scriptnames_to_context;
  257. };
  258.  
  259. #define sScriptRegistryCompositum ScriptRegistryCompositum::Instance()
  260.  
  261. template<typename /*ScriptType*/, bool /*IsDatabaseBound*/>
  262. class SpecializedScriptRegistry;
  263.  
  264. // This is the global static registry of scripts.
  265. template<class ScriptType>
  266. class ScriptRegistry final
  267.    : public SpecializedScriptRegistry<
  268.        ScriptType, is_script_database_bound<ScriptType>::value>
  269. {
  270.    ScriptRegistry()
  271.    {
  272.        sScriptRegistryCompositum->Register(this);
  273.    }
  274.  
  275. public:
  276.    static ScriptRegistry* Instance()
  277.    {
  278.        static ScriptRegistry instance;
  279.        return &instance;
  280.    }
  281.  
  282.    void LogDuplicatedScriptPointerError(ScriptType const* first, ScriptType const* second)
  283.    {
  284.        // See if the script is using the same memory as another script. If this happens, it means that
  285.        // someone forgot to allocate new memory for a script.
  286.        TC_LOG_ERROR("scripts", "Script '%s' has same memory pointer as '%s'.",
  287.            first->GetName().c_str(), second->GetName().c_str());
  288.    }
  289. };
  290.  
  291. class ScriptRegistrySwapHookBase
  292. {
  293. public:
  294.    ScriptRegistrySwapHookBase() { }
  295.    virtual ~ScriptRegistrySwapHookBase() { }
  296.  
  297.    ScriptRegistrySwapHookBase(ScriptRegistrySwapHookBase const&) = delete;
  298.    ScriptRegistrySwapHookBase(ScriptRegistrySwapHookBase&&) = delete;
  299.  
  300.    ScriptRegistrySwapHookBase& operator= (ScriptRegistrySwapHookBase const&) = delete;
  301.    ScriptRegistrySwapHookBase& operator= (ScriptRegistrySwapHookBase&&) = delete;
  302.  
  303.    /// Called before the actual context release happens
  304.    virtual void BeforeReleaseContext(std::string const& /*context*/) { }
  305.  
  306.    /// Called before SwapContext
  307.    virtual void BeforeSwapContext(bool /*initialize*/) { }
  308.  
  309.    /// Called before Unload
  310.    virtual void BeforeUnload() { }
  311. };
  312.  
  313. template<typename ScriptType, typename Base>
  314. class ScriptRegistrySwapHooks
  315.    : public ScriptRegistrySwapHookBase
  316. {
  317. };
  318.  
  319. /// This hook is responsible for swapping OutdoorPvP's
  320. template<typename Base>
  321. class UnsupportedScriptRegistrySwapHooks
  322.     : public ScriptRegistrySwapHookBase
  323. {
  324. public:
  325.     void BeforeReleaseContext(std::string const& context) final override
  326.     {
  327.         auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
  328.         ASSERT(bounds.first == bounds.second);
  329.     }
  330. };
  331.  
  332. /// This hook is responsible for swapping Creature and GameObject AI's
  333. template<typename ObjectType, typename ScriptType, typename Base>
  334. class CreatureGameObjectScriptRegistrySwapHooks
  335.    : public ScriptRegistrySwapHookBase
  336. {
  337.    template<typename W>
  338.    class AIFunctionMapWorker
  339.    {
  340.    public:
  341.        template<typename T>
  342.        AIFunctionMapWorker(T&& worker)
  343.            : _worker(std::forward<T>(worker)) { }
  344.  
  345.        void Visit(std::unordered_map<ObjectGuid, ObjectType*>& objects)
  346.        {
  347.            _worker(objects);
  348.        }
  349.  
  350.        template<typename O>
  351.        void Visit(std::unordered_map<ObjectGuid, O*>&) { }
  352.  
  353.    private:
  354.        W _worker;
  355.    };
  356.  
  357.    class AsyncCastHotswapEffectEvent : public BasicEvent
  358.    {
  359.    public:
  360.        explicit AsyncCastHotswapEffectEvent(Unit* owner) : owner_(owner) { }
  361.  
  362.        bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
  363.        {
  364.            owner_->CastSpell(owner_, SPELL_HOTSWAP_VISUAL_SPELL_EFFECT, true);
  365.            return true;
  366.        }
  367.  
  368.    private:
  369.        Unit* owner_;
  370.    };
  371.  
  372.    // Hook which is called before a creature is swapped
  373.    static void UnloadStage1(Creature* creature)
  374.    {
  375.        creature->m_Events.KillAllEvents(true);
  376.  
  377.        if (creature->IsCharmed())
  378.            creature->RemoveCharmedBy(nullptr);
  379.  
  380.        ASSERT(!creature->IsCharmed(),
  381.               "There is a disabled AI which is still loaded.");
  382.  
  383.        creature->AI()->EnterEvadeMode();
  384.    }
  385.  
  386.    static void UnloadStage2(Creature* creature)
  387.    {
  388.        bool const destroyed = creature->AIM_Destroy();
  389.        ASSERT(destroyed,
  390.               "Destroying the AI should never fail here!");
  391.        (void)destroyed;
  392.  
  393.        ASSERT(!creature->AI(),
  394.               "The AI should be null here!");
  395.    }
  396.  
  397.    // Hook which is called before a gameobject is swapped
  398.    static void UnloadStage1(GameObject* gameobject)
  399.    {
  400.        gameobject->AI()->Reset();
  401.    }
  402.  
  403.    static void UnloadStage2(GameObject* gameobject)
  404.    {
  405.        gameobject->AIM_Destroy();
  406.  
  407.        ASSERT(!gameobject->AI(),
  408.               "The AI should be null here!");
  409.    }
  410.  
  411.    // Hook which is called after a creature was swapped
  412.    static void LoadStage1(Creature* creature)
  413.    {
  414.        ASSERT(!creature->AI(),
  415.               "The AI should be null here!");
  416.  
  417.        if (creature->IsAlive())
  418.            creature->ClearUnitState(UNIT_STATE_EVADE);
  419.  
  420.        bool const created = creature->AIM_Initialize();
  421.        ASSERT(created,
  422.               "Creating the AI should never fail here!");
  423.        (void)created;
  424.    }
  425.  
  426.    static void LoadStage2(Creature* creature)
  427.    {
  428.        if (!creature->IsAlive())
  429.            return;
  430.  
  431.        creature->AI()->EnterEvadeMode();
  432.  
  433.        // Cast a dummy visual spell asynchronously here to signal
  434.        // that the AI was hot swapped
  435.        creature->m_Events.AddEvent(new AsyncCastHotswapEffectEvent(creature),
  436.            creature->m_Events.CalculateTime(0));
  437.    }
  438.  
  439.    // Hook which is called after a gameobject was swapped
  440.    static void LoadStage1(GameObject* gameobject)
  441.    {
  442.        ASSERT(!gameobject->AI(),
  443.               "The AI should be null here!");
  444.  
  445.        gameobject->AIM_Initialize();
  446.    }
  447.  
  448.    static void LoadStage2(GameObject* gameobject)
  449.    {
  450.        gameobject->AI()->Reset();
  451.    }
  452.  
  453.    template<typename T>
  454.    void RunOverAllEntities(T fn)
  455.    {
  456.        auto evaluator = [&](std::unordered_map<ObjectGuid, ObjectType*>& objects)
  457.        {
  458.            for (auto object : objects)
  459.                fn(object.second);
  460.        };
  461.  
  462.        AIFunctionMapWorker<typename std::decay<decltype(evaluator)>::type> worker(std::move(evaluator));
  463.        TypeContainerVisitor<decltype(worker), MapStoredObjectTypesContainer> visitor(worker);
  464.  
  465.        sMapMgr->DoForAllMaps([&](Map* map)
  466.        {
  467.            // Run the worker over all maps
  468.            visitor.Visit(map->GetObjectsStore());
  469.        });
  470.    }
  471.  
  472. public:
  473.    void BeforeReleaseContext(std::string const& context) final override
  474.    {
  475.        auto ids_to_remove = static_cast<Base*>(this)->GetScriptIDsToRemove(context);
  476.  
  477.        std::vector<ObjectType*> stage2;
  478.  
  479.        RunOverAllEntities([&](ObjectType* object)
  480.        {
  481.            if (ids_to_remove.find(object->GetScriptId()) != ids_to_remove.end())
  482.            {
  483.                UnloadStage1(object);
  484.                stage2.push_back(object);
  485.            }
  486.        });
  487.  
  488.        for (auto object : stage2)
  489.            UnloadStage2(object);
  490.  
  491.        // Add the new ids which are removed to the global ids to remove set
  492.        ids_removed_.insert(ids_to_remove.begin(), ids_to_remove.end());
  493.    }
  494.  
  495.    void BeforeSwapContext(bool initialize) override
  496.    {
  497.        // Never swap creature or gameobject scripts when initializing
  498.        if (initialize)
  499.            return;
  500.  
  501.        // Add the recently added scripts to the deleted scripts to replace
  502.        // default AI's with recently added core scripts.
  503.         ids_removed_.insert(static_cast<Base*>(this)->GetRecentlyAddedScriptIDs().begin(),
  504.                             static_cast<Base*>(this)->GetRecentlyAddedScriptIDs().end());
  505.  
  506.         std::vector<ObjectType*> remove;
  507.         std::vector<ObjectType*> stage2;
  508.  
  509.         RunOverAllEntities([&](ObjectType* object)
  510.         {
  511.             if (ids_removed_.find(object->GetScriptId()) != ids_removed_.end())
  512.             {
  513.                 if (object->AI())
  514.                 {
  515.                     // Overwrite existing (default) AI's which are replaced by a new script
  516.                    UnloadStage1(object);
  517.                    remove.push_back(object);
  518.                }
  519.  
  520.                stage2.push_back(object);
  521.            }
  522.        });
  523.  
  524.        for (auto object : remove)
  525.            UnloadStage2(object);
  526.  
  527.        for (auto object : stage2)
  528.            LoadStage1(object);
  529.  
  530.        for (auto object : stage2)
  531.            LoadStage2(object);
  532.  
  533.        ids_removed_.clear();
  534.    }
  535.  
  536.    void BeforeUnload() final override
  537.    {
  538.        ASSERT(ids_removed_.empty());
  539.    }
  540.  
  541. private:
  542.    std::unordered_set<uint32> ids_removed_;
  543. };
  544.  
  545. // This hook is responsible for swapping CreatureAI's
  546. template<typename Base>
  547. class ScriptRegistrySwapHooks<CreatureScript, Base>
  548.     : public CreatureGameObjectScriptRegistrySwapHooks<
  549.         Creature, CreatureScript, Base
  550.       > { };
  551.  
  552. // This hook is responsible for swapping GameObjectAI's
  553. template<typename Base>
  554. class ScriptRegistrySwapHooks<GameObjectScript, Base>
  555.    : public CreatureGameObjectScriptRegistrySwapHooks<
  556.        GameObject, GameObjectScript, Base
  557.      > { };
  558.  
  559. /// This hook is responsible for swapping BattlegroundScript's
  560. template<typename Base>
  561. class ScriptRegistrySwapHooks<BattlegroundScript, Base>
  562.     : public UnsupportedScriptRegistrySwapHooks<Base> { };
  563.  
  564. /// This hook is responsible for swapping OutdoorPvP's
  565. template<typename Base>
  566. class ScriptRegistrySwapHooks<OutdoorPvPScript, Base>
  567.    : public ScriptRegistrySwapHookBase
  568. {
  569. public:
  570.    ScriptRegistrySwapHooks() : swapped(false) { }
  571.  
  572.    void BeforeReleaseContext(std::string const& context) final override
  573.    {
  574.        auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
  575.  
  576.        if ((!swapped) && (bounds.first != bounds.second))
  577.        {
  578.            swapped = true;
  579.            sOutdoorPvPMgr->Die();
  580.        }
  581.    }
  582.  
  583.    void BeforeSwapContext(bool initialize) override
  584.    {
  585.        // Never swap outdoor pvp scripts when initializing
  586.        if ((!initialize) && swapped)
  587.        {
  588.            sOutdoorPvPMgr->InitOutdoorPvP();
  589.            swapped = false;
  590.        }
  591.    }
  592.  
  593.    void BeforeUnload() final override
  594.    {
  595.        ASSERT(!swapped);
  596.    }
  597.  
  598. private:
  599.    bool swapped;
  600. };
  601.  
  602. /// This hook is responsible for swapping InstanceMapScript's
  603. template<typename Base>
  604. class ScriptRegistrySwapHooks<InstanceMapScript, Base>
  605.     : public ScriptRegistrySwapHookBase
  606. {
  607. public:
  608.     ScriptRegistrySwapHooks()  : swapped(false) { }
  609.  
  610.     void BeforeReleaseContext(std::string const& context) final override
  611.     {
  612.         auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
  613.         if (bounds.first != bounds.second)
  614.             swapped = true;
  615.     }
  616.  
  617.     void BeforeSwapContext(bool /*initialize*/) override
  618.     {
  619.         swapped = false;
  620.     }
  621.  
  622.     void BeforeUnload() final override
  623.     {
  624.         ASSERT(!swapped);
  625.     }
  626.  
  627. private:
  628.     bool swapped;
  629. };
  630.  
  631. /// This hook is responsible for swapping SpellScriptLoader's
  632. template<typename Base>
  633. class ScriptRegistrySwapHooks<SpellScriptLoader, Base>
  634.    : public ScriptRegistrySwapHookBase
  635. {
  636. public:
  637.    ScriptRegistrySwapHooks() : swapped(false) { }
  638.  
  639.    void BeforeReleaseContext(std::string const& context) final override
  640.    {
  641.        auto const bounds = static_cast<Base*>(this)->_ids_of_contexts.equal_range(context);
  642.  
  643.        if (bounds.first != bounds.second)
  644.            swapped = true;
  645.    }
  646.  
  647.    void BeforeSwapContext(bool /*initialize*/) override
  648.    {
  649.        if (swapped)
  650.        {
  651.            sObjectMgr->ValidateSpellScripts();
  652.            swapped = false;
  653.        }
  654.    }
  655.  
  656.    void BeforeUnload() final override
  657.    {
  658.        ASSERT(!swapped);
  659.    }
  660.  
  661. private:
  662.    bool swapped;
  663. };
  664.  
  665. // Database bound script registry
  666. template<typename ScriptType>
  667. class SpecializedScriptRegistry<ScriptType, true>
  668.    : public ScriptRegistryInterface,
  669.      public ScriptRegistrySwapHooks<ScriptType, ScriptRegistry<ScriptType>>
  670. {
  671.    template<typename>
  672.    friend class UnsupportedScriptRegistrySwapHooks;
  673.  
  674.    template<typename, typename>
  675.    friend class ScriptRegistrySwapHooks;
  676.  
  677.    template<typename, typename, typename>
  678.    friend class CreatureGameObjectScriptRegistrySwapHooks;
  679.  
  680. public:
  681.    SpecializedScriptRegistry() { }
  682.  
  683.    typedef std::unordered_map<
  684.        uint32 /*script id*/,
  685.        std::unique_ptr<ScriptType>
  686.    > ScriptStoreType;
  687.  
  688.    typedef typename ScriptStoreType::iterator ScriptStoreIteratorType;
  689.  
  690.    void ReleaseContext(std::string const& context) final override
  691.    {
  692.        this->BeforeReleaseContext(context);
  693.  
  694.        auto const bounds = _ids_of_contexts.equal_range(context);
  695.        for (auto itr = bounds.first; itr != bounds.second; ++itr)
  696.            _scripts.erase(itr->second);
  697.    }
  698.  
  699.    void SwapContext(bool initialize) final override
  700.    {
  701.      this->BeforeSwapContext(initialize);
  702.  
  703.      _recently_added_ids.clear();
  704.    }
  705.  
  706.    void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) final override
  707.    {
  708.        for (auto const& script : _scripts)
  709.            scripts.erase(script.second->GetName());
  710.    }
  711.  
  712.    void Unload() final override
  713.    {
  714.        this->BeforeUnload();
  715.  
  716.        ASSERT(_recently_added_ids.empty(),
  717.               "Recently added script ids should be empty here!");
  718.  
  719.        _scripts.clear();
  720.        _ids_of_contexts.clear();
  721.    }
  722.  
  723.    // Adds a database bound script
  724.    void AddScript(ScriptType* script)
  725.    {
  726.        ASSERT(script,
  727.               "Tried to call AddScript with a nullpointer!");
  728.        ASSERT(!sScriptMgr->GetCurrentScriptContext().empty(),
  729.               "Tried to register a script without being in a valid script context!");
  730.  
  731.        std::unique_ptr<ScriptType> script_ptr(script);
  732.  
  733.        // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
  734.         // through a script name (or similar).
  735.         if (uint32 const id = sObjectMgr->GetScriptId(script->GetName()))
  736.         {
  737.             // Try to find an existing script.
  738.             for (auto const& stored_script : _scripts)
  739.             {
  740.                 // If the script names match...
  741.                 if (stored_script.second->GetName() == script->GetName())
  742.                 {
  743.                     // If the script is already assigned -> delete it!
  744.                     TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, "
  745.                         "so the script can't work.", script->GetName().c_str());
  746.  
  747.                     // Error that should be fixed ASAP.
  748.                     sScriptRegistryCompositum->QueueForDelayedDelete(std::move(script_ptr));
  749.                     ABORT();
  750.                     return;
  751.                 }
  752.             }
  753.  
  754.             // If the script isn't assigned -> assign it!
  755.            _scripts.insert(std::make_pair(id, std::move(script_ptr)));
  756.            _ids_of_contexts.insert(std::make_pair(sScriptMgr->GetCurrentScriptContext(), id));
  757.            _recently_added_ids.insert(id);
  758.  
  759.            sScriptRegistryCompositum->SetScriptNameInContext(script->GetName(),
  760.                sScriptMgr->GetCurrentScriptContext());
  761.        }
  762.        else
  763.        {
  764.            // The script uses a script name from database, but isn't assigned to anything.
  765.             TC_LOG_ERROR("sql.sql", "Script named '%s' does not have a script name assigned in database.",
  766.                 script->GetName().c_str());
  767.  
  768.             // Avoid calling "delete script;" because we are currently in the script constructor
  769.             // In a valid scenario this will not happen because every script has a name assigned in the database
  770.             sScriptRegistryCompositum->QueueForDelayedDelete(std::move(script_ptr));
  771.             return;
  772.         }
  773.     }
  774.  
  775.     // Gets a script by its ID (assigned by ObjectMgr).
  776.     ScriptType* GetScriptById(uint32 id)
  777.     {
  778.         auto const itr = _scripts.find(id);
  779.         if (itr != _scripts.end())
  780.             return itr->second.get();
  781.  
  782.         return nullptr;
  783.     }
  784.  
  785.     ScriptStoreType& GetScripts()
  786.     {
  787.         return _scripts;
  788.     }
  789.  
  790. protected:
  791.     // Returns the script id's which are registered to a certain context
  792.    std::unordered_set<uint32> GetScriptIDsToRemove(std::string const& context) const
  793.    {
  794.        // Create a set of all ids which are removed
  795.        std::unordered_set<uint32> scripts_to_remove;
  796.  
  797.        auto const bounds = _ids_of_contexts.equal_range(context);
  798.        for (auto itr = bounds.first; itr != bounds.second; ++itr)
  799.            scripts_to_remove.insert(itr->second);
  800.  
  801.        return scripts_to_remove;
  802.    }
  803.  
  804.    std::unordered_set<uint32> const& GetRecentlyAddedScriptIDs() const
  805.    {
  806.        return _recently_added_ids;
  807.    }
  808.  
  809. private:
  810.    ScriptStoreType _scripts;
  811.  
  812.    // Scripts of a specific context
  813.    std::unordered_multimap<std::string /*context*/, uint32 /*id*/> _ids_of_contexts;
  814.  
  815.    // Script id's which were registered recently
  816.     std::unordered_set<uint32> _recently_added_ids;
  817. };
  818.  
  819. /// This hook is responsible for swapping CommandScript's
  820. template<typename Base>
  821. class ScriptRegistrySwapHooks<CommandScript, Base>
  822.    : public ScriptRegistrySwapHookBase
  823. {
  824. public:
  825.    void BeforeReleaseContext(std::string const& /*context*/) final override
  826.    {
  827.        ChatHandler::invalidateCommandTable();
  828.    }
  829.  
  830.    void BeforeSwapContext(bool /*initialize*/) override
  831.    {
  832.        ChatHandler::invalidateCommandTable();
  833.    }
  834.  
  835.    void BeforeUnload() final override
  836.    {
  837.        ChatHandler::invalidateCommandTable();
  838.    }
  839. };
  840.  
  841. // Database unbound script registry
  842. template<typename ScriptType>
  843. class SpecializedScriptRegistry<ScriptType, false>
  844.    : public ScriptRegistryInterface,
  845.      public ScriptRegistrySwapHooks<ScriptType, ScriptRegistry<ScriptType>>
  846. {
  847.    template<typename, typename>
  848.    friend class ScriptRegistrySwapHooks;
  849.  
  850. public:
  851.    typedef std::unordered_multimap<std::string /*context*/, std::unique_ptr<ScriptType>> ScriptStoreType;
  852.    typedef typename ScriptStoreType::iterator ScriptStoreIteratorType;
  853.  
  854.    SpecializedScriptRegistry() { }
  855.  
  856.    void ReleaseContext(std::string const& context) final override
  857.    {
  858.        this->BeforeReleaseContext(context);
  859.  
  860.        _scripts.erase(context);
  861.    }
  862.  
  863.    void SwapContext(bool initialize) final override
  864.    {
  865.        this->BeforeSwapContext(initialize);
  866.    }
  867.  
  868.    void RemoveUsedScriptsFromContainer(std::unordered_set<std::string>& scripts) final override
  869.    {
  870.        for (auto const& script : _scripts)
  871.            scripts.erase(script.second->GetName());
  872.    }
  873.  
  874.    void Unload() final override
  875.    {
  876.        this->BeforeUnload();
  877.  
  878.        _scripts.clear();
  879.    }
  880.  
  881.    // Adds a non database bound script
  882.    void AddScript(ScriptType* script)
  883.    {
  884.        ASSERT(script,
  885.               "Tried to call AddScript with a nullpointer!");
  886.        ASSERT(!sScriptMgr->GetCurrentScriptContext().empty(),
  887.               "Tried to register a script without being in a valid script context!");
  888.  
  889.        std::unique_ptr<ScriptType> script_ptr(script);
  890.  
  891.        for (auto const& entry : _scripts)
  892.            if (entry.second.get() == script)
  893.            {
  894.                static_cast<ScriptRegistry<ScriptType>*>(this)->
  895.                    LogDuplicatedScriptPointerError(script, entry.second.get());
  896.  
  897.                sScriptRegistryCompositum->QueueForDelayedDelete(std::move(script_ptr));
  898.                return;
  899.            }
  900.  
  901.        // We're dealing with a code-only script, just add it.
  902.         _scripts.insert(std::make_pair(sScriptMgr->GetCurrentScriptContext(), std::move(script_ptr)));
  903.     }
  904.  
  905.     ScriptStoreType& GetScripts()
  906.     {
  907.         return _scripts;
  908.     }
  909.  
  910. private:
  911.     ScriptStoreType _scripts;
  912. };
  913.  
  914. // Utility macros to refer to the script registry.
  915. #define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptStoreType
  916. #define SCR_REG_ITR(T) ScriptRegistry<T>::ScriptStoreIteratorType
  917. #define SCR_REG_LST(T) ScriptRegistry<T>::Instance()->GetScripts()
  918.  
  919. // Utility macros for looping over scripts.
  920. #define FOR_SCRIPTS(T, C, E) \
  921.     if (SCR_REG_LST(T).empty()) \
  922.         return; \
  923.     \
  924.     for (SCR_REG_ITR(T) C = SCR_REG_LST(T).begin(); \
  925.         C != SCR_REG_LST(T).end(); ++C)
  926.  
  927. #define FOR_SCRIPTS_RET(T, C, E, R) \
  928.     if (SCR_REG_LST(T).empty()) \
  929.         return R; \
  930.     \
  931.     for (SCR_REG_ITR(T) C = SCR_REG_LST(T).begin(); \
  932.         C != SCR_REG_LST(T).end(); ++C)
  933.  
  934. #define FOREACH_SCRIPT(T) \
  935.     FOR_SCRIPTS(T, itr, end) \
  936.         itr->second
  937.  
  938. // Utility macros for finding specific scripts.
  939. #define GET_SCRIPT(T, I, V) \
  940.     T* V = ScriptRegistry<T>::Instance()->GetScriptById(I); \
  941.     if (!V) \
  942.         return;
  943.  
  944. #define GET_SCRIPT_RET(T, I, V, R) \
  945.     T* V = ScriptRegistry<T>::Instance()->GetScriptById(I); \
  946.     if (!V) \
  947.         return R;
  948.  
  949. struct TSpellSummary
  950. {
  951.     uint8 Targets;                                          // set of enum SelectTarget
  952.     uint8 Effects;                                          // set of enum SelectEffect
  953. } *SpellSummary;
  954.  
  955. ScriptObject::ScriptObject(const char* name) : _name(name)
  956. {
  957.     sScriptMgr->IncreaseScriptCount();
  958. }
  959.  
  960. ScriptObject::~ScriptObject()
  961. {
  962.     sScriptMgr->DecreaseScriptCount();
  963. }
  964.  
  965. ScriptMgr::ScriptMgr()
  966.   : _scriptCount(0), _script_loader_callback(nullptr)
  967. {
  968. }
  969.  
  970. ScriptMgr::~ScriptMgr() { }
  971.  
  972. ScriptMgr* ScriptMgr::instance()
  973. {
  974.     static ScriptMgr instance;
  975.     return &instance;
  976. }
  977.  
  978. void ScriptMgr::Initialize()
  979. {
  980.     ASSERT(sSpellMgr->GetSpellInfo(SPELL_HOTSWAP_VISUAL_SPELL_EFFECT)
  981.            && "Reload hotswap spell effect for creatures isn't valid!");
  982.  
  983.     uint32 oldMSTime = getMSTime();
  984.  
  985.     LoadDatabase();
  986.  
  987.     TC_LOG_INFO("server.loading", "Loading C++ scripts");
  988.  
  989.     FillSpellSummary();
  990.  
  991.     // Load core scripts
  992.     SetScriptContext("___static___");
  993.  
  994.     // SmartAI
  995.     AddSC_SmartScripts();
  996.  
  997.     // LFGScripts
  998.     lfg::AddSC_LFGScripts();
  999.  
  1000.     // Load all static linked scripts through the script loader function.
  1001.     ASSERT(_script_loader_callback,
  1002.            "Script loader callback wasn't registered!");
  1003.     _script_loader_callback();
  1004.  
  1005.     // Initialize all dynamic scripts
  1006.     // and finishes the context switch to do
  1007.     // bulk loading
  1008.     sScriptReloadMgr->Initialize();
  1009.  
  1010.     // Loads all scripts from the current context
  1011.     sScriptMgr->SwapScriptContext(true);
  1012.  
  1013.     // Print unused script names.
  1014.     std::unordered_set<std::string> unusedScriptNames(
  1015.         sObjectMgr->GetAllScriptNames().begin(),
  1016.         sObjectMgr->GetAllScriptNames().end());
  1017.  
  1018.     // Remove the used scripts from the given container.
  1019.     sScriptRegistryCompositum->RemoveUsedScriptsFromContainer(unusedScriptNames);
  1020.  
  1021.     for (std::string const& scriptName : unusedScriptNames)
  1022.     {
  1023.         // Avoid complaining about empty script names since the
  1024.         // script name container contains a placeholder as the 0 element.
  1025.         if (scriptName.empty())
  1026.             continue;
  1027.  
  1028.         TC_LOG_ERROR("sql.sql", "ScriptName '%s' exists in database, "
  1029.                      "but no core script found!", scriptName.c_str());
  1030.     }
  1031.  
  1032.     TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms",
  1033.         GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
  1034. }
  1035.  
  1036. void ScriptMgr::SetScriptContext(std::string const& context)
  1037. {
  1038.     _currentContext = context;
  1039. }
  1040.  
  1041. void ScriptMgr::SwapScriptContext(bool initialize)
  1042. {
  1043.     sScriptRegistryCompositum->SwapContext(initialize);
  1044.     _currentContext.clear();
  1045. }
  1046.  
  1047. void ScriptMgr::ReleaseScriptContext(std::string const& context)
  1048. {
  1049.     sScriptRegistryCompositum->ReleaseContext(context);
  1050. }
  1051.  
  1052. std::shared_ptr<ModuleReference>
  1053.     ScriptMgr::AcquireModuleReferenceOfScriptName(std::string const& scriptname) const
  1054. {
  1055. #ifdef TRINITY_API_USE_DYNAMIC_LINKING
  1056.     // Returns the reference to the module of the given scriptname
  1057.     return ScriptReloadMgr::AcquireModuleReferenceOfContext(
  1058.         sScriptRegistryCompositum->GetScriptContextOfScriptName(scriptname));
  1059. #else
  1060.     (void)scriptname;
  1061.     // Something went wrong when this function is used in
  1062.     // a static linked context.
  1063.     WPAbort();
  1064. #endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
  1065. }
  1066.  
  1067. void ScriptMgr::Unload()
  1068. {
  1069.     sScriptRegistryCompositum->Unload();
  1070.  
  1071.     delete[] SpellSummary;
  1072.     delete[] UnitAI::AISpellInfo;
  1073. }
  1074.  
  1075. void ScriptMgr::LoadDatabase()
  1076. {
  1077.     sScriptSystemMgr->LoadScriptWaypoints();
  1078. }
  1079.  
  1080. void ScriptMgr::FillSpellSummary()
  1081. {
  1082.     UnitAI::FillAISpellInfo();
  1083.  
  1084.     SpellSummary = new TSpellSummary[sSpellMgr->GetSpellInfoStoreSize()];
  1085.  
  1086.     SpellInfo const* pTempSpell;
  1087.  
  1088.     for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
  1089.     {
  1090.         SpellSummary[i].Effects = 0;
  1091.         SpellSummary[i].Targets = 0;
  1092.  
  1093.         pTempSpell = sSpellMgr->GetSpellInfo(i);
  1094.         // This spell doesn't exist.
  1095.        if (!pTempSpell)
  1096.            continue;
  1097.  
  1098.        for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
  1099.        {
  1100.            // Spell targets self.
  1101.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER)
  1102.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);
  1103.  
  1104.            // Spell targets a single enemy.
  1105.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY ||
  1106.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY)
  1107.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
  1108.  
  1109.            // Spell targets AoE at enemy.
  1110.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY ||
  1111.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY ||
  1112.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER ||
  1113.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
  1114.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
  1115.  
  1116.            // Spell targets an enemy.
  1117.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY ||
  1118.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY ||
  1119.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY ||
  1120.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY ||
  1121.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER ||
  1122.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
  1123.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
  1124.  
  1125.            // Spell targets a single friend (or self).
  1126.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER ||
  1127.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY ||
  1128.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY)
  1129.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
  1130.  
  1131.            // Spell targets AoE friends.
  1132.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY ||
  1133.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY ||
  1134.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER)
  1135.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
  1136.  
  1137.            // Spell targets any friend (or self).
  1138.            if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER ||
  1139.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY ||
  1140.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY ||
  1141.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY ||
  1142.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY ||
  1143.                pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER)
  1144.                SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
  1145.  
  1146.            // Make sure that this spell includes a damage effect.
  1147.            if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE ||
  1148.                pTempSpell->Effects[j].Effect == SPELL_EFFECT_INSTAKILL ||
  1149.                pTempSpell->Effects[j].Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
  1150.                pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH)
  1151.                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE-1);
  1152.  
  1153.            // Make sure that this spell includes a healing effect (or an apply aura with a periodic heal).
  1154.            if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL ||
  1155.                pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL_MAX_HEALTH ||
  1156.                pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL_MECHANICAL ||
  1157.                (pTempSpell->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA  && pTempSpell->Effects[j].ApplyAuraName == 8))
  1158.                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);
  1159.  
  1160.            // Make sure that this spell applies an aura.
  1161.            if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA)
  1162.                SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
  1163.        }
  1164.    }
  1165. }
  1166.  
  1167. template<typename T, typename F>
  1168. void CreateSpellOrAuraScripts(uint32 spellId, std::list<T*>& scriptVector, F&& extractor)
  1169. {
  1170.    SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId);
  1171.  
  1172.    for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr)
  1173.    {
  1174.        // When the script is disabled continue with the next one
  1175.        if (!itr->second.second)
  1176.            continue;
  1177.  
  1178.        SpellScriptLoader* tmpscript = sScriptMgr->GetSpellScriptLoader(itr->second.first);
  1179.        if (!tmpscript)
  1180.            continue;
  1181.  
  1182.        T* script = (*tmpscript.*extractor)();
  1183.  
  1184.        if (!script)
  1185.            continue;
  1186.  
  1187.        script->_Init(&tmpscript->GetName(), spellId);
  1188.  
  1189.        scriptVector.push_back(script);
  1190.    }
  1191. }
  1192.  
  1193. void ScriptMgr::CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector)
  1194. {
  1195.    CreateSpellOrAuraScripts(spellId, scriptVector, &SpellScriptLoader::GetSpellScript);
  1196. }
  1197.  
  1198. void ScriptMgr::CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector)
  1199. {
  1200.    CreateSpellOrAuraScripts(spellId, scriptVector, &SpellScriptLoader::GetAuraScript);
  1201. }
  1202.  
  1203. SpellScriptLoader* ScriptMgr::GetSpellScriptLoader(uint32 scriptId)
  1204. {
  1205.    return ScriptRegistry<SpellScriptLoader>::Instance()->GetScriptById(scriptId);
  1206. }
  1207.  
  1208. void ScriptMgr::OnNetworkStart()
  1209. {
  1210.    FOREACH_SCRIPT(ServerScript)->OnNetworkStart();
  1211. }
  1212.  
  1213. void ScriptMgr::OnNetworkStop()
  1214. {
  1215.    FOREACH_SCRIPT(ServerScript)->OnNetworkStop();
  1216. }
  1217.  
  1218. void ScriptMgr::OnSocketOpen(std::shared_ptr<WorldSocket> socket)
  1219. {
  1220.    ASSERT(socket);
  1221.  
  1222.    FOREACH_SCRIPT(ServerScript)->OnSocketOpen(socket);
  1223. }
  1224.  
  1225. void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket)
  1226. {
  1227.    ASSERT(socket);
  1228.  
  1229.    FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket);
  1230. }
  1231.  
  1232. void ScriptMgr::OnPacketReceive(WorldSession* session, WorldPacket const& packet)
  1233. {
  1234.    if (SCR_REG_LST(ServerScript).empty())
  1235.        return;
  1236.  
  1237.    WorldPacket copy(packet);
  1238.    FOREACH_SCRIPT(ServerScript)->OnPacketReceive(session, copy);
  1239. }
  1240.  
  1241. void ScriptMgr::OnPacketSend(WorldSession* session, WorldPacket const& packet)
  1242. {
  1243.    ASSERT(session);
  1244.  
  1245.    if (SCR_REG_LST(ServerScript).empty())
  1246.        return;
  1247.  
  1248.    WorldPacket copy(packet);
  1249.    FOREACH_SCRIPT(ServerScript)->OnPacketSend(session, copy);
  1250. }
  1251.  
  1252. void ScriptMgr::OnOpenStateChange(bool open)
  1253. {
  1254. #ifdef ELUNA
  1255.    sEluna->OnOpenStateChange(open);
  1256. #endif
  1257.    FOREACH_SCRIPT(WorldScript)->OnOpenStateChange(open);
  1258. }
  1259.  
  1260. void ScriptMgr::OnConfigLoad(bool reload)
  1261. {
  1262. #ifdef ELUNA
  1263.    sEluna->OnConfigLoad(reload);
  1264. #endif
  1265.    FOREACH_SCRIPT(WorldScript)->OnConfigLoad(reload);
  1266. }
  1267.  
  1268. void ScriptMgr::OnMotdChange(std::string& newMotd)
  1269. {
  1270.    FOREACH_SCRIPT(WorldScript)->OnMotdChange(newMotd);
  1271. }
  1272.  
  1273. void ScriptMgr::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask)
  1274. {
  1275. #ifdef ELUNA
  1276.    sEluna->OnShutdownInitiate(code, mask);
  1277. #endif
  1278.    FOREACH_SCRIPT(WorldScript)->OnShutdownInitiate(code, mask);
  1279. }
  1280.  
  1281. void ScriptMgr::OnShutdownCancel()
  1282. {
  1283. #ifdef ELUNA
  1284.    sEluna->OnShutdownCancel();
  1285. #endif
  1286.    FOREACH_SCRIPT(WorldScript)->OnShutdownCancel();
  1287. }
  1288.  
  1289. void ScriptMgr::OnWorldUpdate(uint32 diff)
  1290. {
  1291. #ifdef ELUNA
  1292.    sEluna->OnWorldUpdate(diff);
  1293. #endif
  1294.    FOREACH_SCRIPT(WorldScript)->OnUpdate(diff);
  1295. }
  1296.  
  1297. void ScriptMgr::OnHonorCalculation(float& honor, uint8 level, float multiplier)
  1298. {
  1299.    FOREACH_SCRIPT(FormulaScript)->OnHonorCalculation(honor, level, multiplier);
  1300. }
  1301.  
  1302. void ScriptMgr::OnGrayLevelCalculation(uint8& grayLevel, uint8 playerLevel)
  1303. {
  1304.    FOREACH_SCRIPT(FormulaScript)->OnGrayLevelCalculation(grayLevel, playerLevel);
  1305. }
  1306.  
  1307. void ScriptMgr::OnColorCodeCalculation(XPColorChar& color, uint8 playerLevel, uint8 mobLevel)
  1308. {
  1309.    FOREACH_SCRIPT(FormulaScript)->OnColorCodeCalculation(color, playerLevel, mobLevel);
  1310. }
  1311.  
  1312. void ScriptMgr::OnZeroDifferenceCalculation(uint8& diff, uint8 playerLevel)
  1313. {
  1314.    FOREACH_SCRIPT(FormulaScript)->OnZeroDifferenceCalculation(diff, playerLevel);
  1315. }
  1316.  
  1317. void ScriptMgr::OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content)
  1318. {
  1319.    FOREACH_SCRIPT(FormulaScript)->OnBaseGainCalculation(gain, playerLevel, mobLevel, content);
  1320. }
  1321.  
  1322. void ScriptMgr::OnGainCalculation(uint32& gain, Player* player, Unit* unit)
  1323. {
  1324.    ASSERT(player);
  1325.    ASSERT(unit);
  1326.  
  1327.    FOREACH_SCRIPT(FormulaScript)->OnGainCalculation(gain, player, unit);
  1328. }
  1329.  
  1330. void ScriptMgr::OnGroupRateCalculation(float& rate, uint32 count, bool isRaid)
  1331. {
  1332.    FOREACH_SCRIPT(FormulaScript)->OnGroupRateCalculation(rate, count, isRaid);
  1333. }
  1334.  
  1335. #define SCR_MAP_BGN(M, V, I, E, C, T) \
  1336.    if (V->GetEntry() && V->GetEntry()->T()) \
  1337.    { \
  1338.        FOR_SCRIPTS(M, I, E) \
  1339.        { \
  1340.            MapEntry const* C = I->second->GetEntry(); \
  1341.            if (!C) \
  1342.                continue; \
  1343.            if (C->MapID == V->GetId()) \
  1344.            {
  1345.  
  1346. #define SCR_MAP_END \
  1347.                return; \
  1348.            } \
  1349.        } \
  1350.    }
  1351.  
  1352. void ScriptMgr::OnCreateMap(Map* map)
  1353. {
  1354.    ASSERT(map);
  1355.  
  1356. #ifdef ELUNA
  1357.    sEluna->OnCreate(map);
  1358. #endif
  1359.  
  1360.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1361.        itr->second->OnCreate(map);
  1362.    SCR_MAP_END;
  1363.  
  1364.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1365.        itr->second->OnCreate((InstanceMap*)map);
  1366.    SCR_MAP_END;
  1367.  
  1368.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1369.        itr->second->OnCreate((BattlegroundMap*)map);
  1370.    SCR_MAP_END;
  1371. }
  1372.  
  1373. void ScriptMgr::OnDestroyMap(Map* map)
  1374. {
  1375.    ASSERT(map);
  1376.  
  1377. #ifdef ELUNA
  1378.    sEluna->OnDestroy(map);
  1379. #endif
  1380.  
  1381.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1382.        itr->second->OnDestroy(map);
  1383.    SCR_MAP_END;
  1384.  
  1385.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1386.        itr->second->OnDestroy((InstanceMap*)map);
  1387.    SCR_MAP_END;
  1388.  
  1389.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1390.        itr->second->OnDestroy((BattlegroundMap*)map);
  1391.    SCR_MAP_END;
  1392. }
  1393.  
  1394. void ScriptMgr::OnLoadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy)
  1395. {
  1396.    ASSERT(map);
  1397.    ASSERT(gmap);
  1398.  
  1399.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1400.        itr->second->OnLoadGridMap(map, gmap, gx, gy);
  1401.    SCR_MAP_END;
  1402.  
  1403.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1404.        itr->second->OnLoadGridMap((InstanceMap*)map, gmap, gx, gy);
  1405.    SCR_MAP_END;
  1406.  
  1407.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1408.        itr->second->OnLoadGridMap((BattlegroundMap*)map, gmap, gx, gy);
  1409.    SCR_MAP_END;
  1410. }
  1411.  
  1412. void ScriptMgr::OnUnloadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy)
  1413. {
  1414.    ASSERT(map);
  1415.    ASSERT(gmap);
  1416.  
  1417.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1418.        itr->second->OnUnloadGridMap(map, gmap, gx, gy);
  1419.    SCR_MAP_END;
  1420.  
  1421.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1422.        itr->second->OnUnloadGridMap((InstanceMap*)map, gmap, gx, gy);
  1423.    SCR_MAP_END;
  1424.  
  1425.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1426.        itr->second->OnUnloadGridMap((BattlegroundMap*)map, gmap, gx, gy);
  1427.    SCR_MAP_END;
  1428. }
  1429.  
  1430. void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player)
  1431. {
  1432.    ASSERT(map);
  1433.    ASSERT(player);
  1434.  
  1435. #ifdef ELUNA
  1436.    sEluna->OnMapChanged(player);
  1437.    sEluna->OnPlayerEnter(map, player);
  1438. #endif
  1439.  
  1440.    FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player);
  1441.  
  1442.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1443.        itr->second->OnPlayerEnter(map, player);
  1444.    SCR_MAP_END;
  1445.  
  1446.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1447.        itr->second->OnPlayerEnter((InstanceMap*)map, player);
  1448.    SCR_MAP_END;
  1449.  
  1450.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1451.        itr->second->OnPlayerEnter((BattlegroundMap*)map, player);
  1452.    SCR_MAP_END;
  1453. }
  1454.  
  1455. void ScriptMgr::OnPlayerLeaveMap(Map* map, Player* player)
  1456. {
  1457.    ASSERT(map);
  1458.    ASSERT(player);
  1459.  
  1460. #ifdef ELUNA
  1461.    sEluna->OnPlayerLeave(map, player);
  1462. #endif
  1463.  
  1464.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1465.        itr->second->OnPlayerLeave(map, player);
  1466.    SCR_MAP_END;
  1467.  
  1468.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1469.        itr->second->OnPlayerLeave((InstanceMap*)map, player);
  1470.    SCR_MAP_END;
  1471.  
  1472.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1473.        itr->second->OnPlayerLeave((BattlegroundMap*)map, player);
  1474.    SCR_MAP_END;
  1475. }
  1476.  
  1477. void ScriptMgr::OnMapUpdate(Map* map, uint32 diff)
  1478. {
  1479.    ASSERT(map);
  1480.  
  1481. #ifdef ELUNA
  1482.    sEluna->OnUpdate(map, diff);
  1483. #endif
  1484.  
  1485.    SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap);
  1486.        itr->second->OnUpdate(map, diff);
  1487.    SCR_MAP_END;
  1488.  
  1489.    SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
  1490.        itr->second->OnUpdate((InstanceMap*)map, diff);
  1491.    SCR_MAP_END;
  1492.  
  1493.    SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground);
  1494.        itr->second->OnUpdate((BattlegroundMap*)map, diff);
  1495.    SCR_MAP_END;
  1496. }
  1497.  
  1498. #undef SCR_MAP_BGN
  1499. #undef SCR_MAP_END
  1500.  
  1501. InstanceScript* ScriptMgr::CreateInstanceData(InstanceMap* map)
  1502. {
  1503.    ASSERT(map);
  1504.  
  1505.    GET_SCRIPT_RET(InstanceMapScript, map->GetScriptId(), tmpscript, NULL);
  1506.    return tmpscript->GetInstanceScript(map);
  1507. }
  1508.  
  1509. bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Item* target)
  1510. {
  1511.    ASSERT(caster);
  1512.    ASSERT(target);
  1513. #ifdef ELUNA
  1514.    if (sEluna->OnDummyEffect(caster, spellId, effIndex, target))
  1515.        return false;
  1516. #endif
  1517.  
  1518.    GET_SCRIPT_RET(ItemScript, target->GetScriptId(), tmpscript, false);
  1519.    return tmpscript->OnDummyEffect(caster, spellId, effIndex, target);
  1520. }
  1521.  
  1522. bool ScriptMgr::OnQuestAccept(Player* player, Item* item, Quest const* quest)
  1523. {
  1524.    ASSERT(player);
  1525.    ASSERT(item);
  1526.    ASSERT(quest);
  1527. #ifdef ELUNA
  1528.    if (sEluna->OnQuestAccept(player, item, quest))
  1529.        return false;
  1530. #endif
  1531.  
  1532.    GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false);
  1533.    player->PlayerTalkClass->ClearMenus();
  1534.    return tmpscript->OnQuestAccept(player, item, quest);
  1535. }
  1536.  
  1537. bool ScriptMgr::OnItemUse(Player* player, Item* item, SpellCastTargets const& targets)
  1538. {
  1539.    ASSERT(player);
  1540.    ASSERT(item);
  1541. #ifdef ELUNA
  1542.    if (!sEluna->OnUse(player, item, targets))
  1543.        return true;
  1544. #endif
  1545.  
  1546.    GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false);
  1547.    return tmpscript->OnUse(player, item, targets);
  1548. }
  1549.  
  1550. bool ScriptMgr::OnItemExpire(Player* player, ItemTemplate const* proto)
  1551. {
  1552.    ASSERT(player);
  1553.    ASSERT(proto);
  1554. #ifdef ELUNA
  1555.    if (sEluna->OnExpire(player, proto))
  1556.        return false;
  1557. #endif
  1558.  
  1559.    GET_SCRIPT_RET(ItemScript, proto->ScriptId, tmpscript, false);
  1560.    return tmpscript->OnExpire(player, proto);
  1561. }
  1562.  
  1563. bool ScriptMgr::OnItemRemove(Player* player, Item* item)
  1564. {
  1565.    ASSERT(player);
  1566.    ASSERT(item);
  1567. #ifdef ELUNA
  1568.    if (sEluna->OnRemove(player, item))
  1569.        return false;
  1570. #endif
  1571.  
  1572.    GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false);
  1573.    return tmpscript->OnRemove(player, item);
  1574. }
  1575.  
  1576. void ScriptMgr::OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action)
  1577. {
  1578.    ASSERT(player);
  1579.    ASSERT(item);
  1580.  
  1581.    GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript);
  1582.    tmpscript->OnGossipSelect(player, item, sender, action);
  1583. }
  1584.  
  1585. void ScriptMgr::OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code)
  1586. {
  1587.    ASSERT(player);
  1588.    ASSERT(item);
  1589.  
  1590.    GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript);
  1591.    tmpscript->OnGossipSelectCode(player, item, sender, action, code);
  1592. }
  1593.  
  1594. bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Creature* target)
  1595. {
  1596.    ASSERT(caster);
  1597.    ASSERT(target);
  1598. #ifdef ELUNA
  1599.    if (sEluna->OnDummyEffect(caster, spellId, effIndex, target))
  1600.        return false;
  1601. #endif
  1602.  
  1603.    GET_SCRIPT_RET(CreatureScript, target->GetScriptId(), tmpscript, false);
  1604.    return tmpscript->OnDummyEffect(caster, spellId, effIndex, target);
  1605. }
  1606.  
  1607. bool ScriptMgr::OnGossipHello(Player* player, Creature* creature)
  1608. {
  1609.    ASSERT(player);
  1610.    ASSERT(creature);
  1611. #ifdef ELUNA
  1612.    if (sEluna->OnGossipHello(player, creature))
  1613.        return true;
  1614. #endif
  1615.  
  1616.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
  1617.    player->PlayerTalkClass->ClearMenus();
  1618.    return tmpscript->OnGossipHello(player, creature);
  1619. }
  1620.  
  1621. bool ScriptMgr::OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
  1622. {
  1623.    ASSERT(player);
  1624.    ASSERT(creature);
  1625. #ifdef ELUNA
  1626.    if (sEluna->OnGossipSelect(player, creature, sender, action))
  1627.        return true;
  1628. #endif
  1629.  
  1630.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
  1631.    return tmpscript->OnGossipSelect(player, creature, sender, action);
  1632. }
  1633.  
  1634. bool ScriptMgr::OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code)
  1635. {
  1636.    ASSERT(player);
  1637.    ASSERT(creature);
  1638.    ASSERT(code);
  1639. #ifdef ELUNA
  1640.    if (sEluna->OnGossipSelectCode(player, creature, sender, action, code))
  1641.        return true;
  1642. #endif
  1643.  
  1644.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
  1645.    return tmpscript->OnGossipSelectCode(player, creature, sender, action, code);
  1646. }
  1647.  
  1648. bool ScriptMgr::OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
  1649. {
  1650.    ASSERT(player);
  1651.    ASSERT(creature);
  1652.    ASSERT(quest);
  1653. #ifdef ELUNA
  1654.    if (sEluna->OnQuestAccept(player, creature, quest))
  1655.    {
  1656.        player->PlayerTalkClass->ClearMenus();
  1657.        return false;
  1658.    }
  1659. #endif
  1660.  
  1661.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
  1662.    player->PlayerTalkClass->ClearMenus();
  1663.    return tmpscript->OnQuestAccept(player, creature, quest);
  1664. }
  1665.  
  1666. bool ScriptMgr::OnQuestSelect(Player* player, Creature* creature, Quest const* quest)
  1667. {
  1668.    ASSERT(player);
  1669.    ASSERT(creature);
  1670.    ASSERT(quest);
  1671.  
  1672.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
  1673.    player->PlayerTalkClass->ClearMenus();
  1674.    return tmpscript->OnQuestSelect(player, creature, quest);
  1675. }
  1676.  
  1677. bool ScriptMgr::OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt)
  1678. {
  1679.    ASSERT(player);
  1680.    ASSERT(creature);
  1681.    ASSERT(quest);
  1682. #ifdef ELUNA
  1683.    if (sEluna->OnQuestReward(player, creature, quest, opt))
  1684.    {
  1685.        player->PlayerTalkClass->ClearMenus();
  1686.        return false;
  1687.    }
  1688. #endif
  1689.  
  1690.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
  1691.    player->PlayerTalkClass->ClearMenus();
  1692.    return tmpscript->OnQuestReward(player, creature, quest, opt);
  1693. }
  1694.  
  1695. uint32 ScriptMgr::GetDialogStatus(Player* player, Creature* creature)
  1696. {
  1697.    ASSERT(player);
  1698.    ASSERT(creature);
  1699. #ifdef ELUNA
  1700.    if (uint32 dialogid = sEluna->GetDialogStatus(player, creature))
  1701.    {
  1702.        player->PlayerTalkClass->ClearMenus();
  1703.        return dialogid;
  1704.    }
  1705. #endif
  1706.  
  1707.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, DIALOG_STATUS_SCRIPTED_NO_STATUS);
  1708.    player->PlayerTalkClass->ClearMenus();
  1709.    return tmpscript->GetDialogStatus(player, creature);
  1710. }
  1711.  
  1712. CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature)
  1713. {
  1714.    ASSERT(creature);
  1715. #ifdef ELUNA
  1716.    if (CreatureAI* luaAI = sEluna->GetAI(creature))
  1717.        return luaAI;
  1718. #endif
  1719.  
  1720.    GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, NULL);
  1721.    return tmpscript->GetAI(creature);
  1722. }
  1723.  
  1724. GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* gameobject)
  1725. {
  1726.    ASSERT(gameobject);
  1727. #ifdef ELUNA
  1728.    sEluna->OnSpawn(gameobject);
  1729. #endif
  1730.  
  1731.    GET_SCRIPT_RET(GameObjectScript, gameobject->GetScriptId(), tmpscript, NULL);
  1732.    return tmpscript->GetAI(gameobject);
  1733. }
  1734.  
  1735. void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff)
  1736. {
  1737.    ASSERT(creature);
  1738.  
  1739.    GET_SCRIPT(CreatureScript, creature->GetScriptId(), tmpscript);
  1740.    tmpscript->OnUpdate(creature, diff);
  1741. }
  1742.  
  1743. bool ScriptMgr::OnGossipHello(Player* player, GameObject* go)
  1744. {
  1745.    ASSERT(player);
  1746.    ASSERT(go);
  1747. #ifdef ELUNA
  1748.    if (sEluna->OnGossipHello(player, go))
  1749.        return true;
  1750.    if (sEluna->OnGameObjectUse(player, go))
  1751.        return true;
  1752. #endif
  1753.  
  1754.    GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
  1755.    player->PlayerTalkClass->ClearMenus();
  1756.    return tmpscript->OnGossipHello(player, go);
  1757. }
  1758.  
  1759. bool ScriptMgr::OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action)
  1760. {
  1761.    ASSERT(player);
  1762.    ASSERT(go);
  1763. #ifdef ELUNA
  1764.    if (sEluna->OnGossipSelect(player, go, sender, action))
  1765.        return true;
  1766. #endif
  1767.  
  1768.    GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
  1769.    return tmpscript->OnGossipSelect(player, go, sender, action);
  1770. }
  1771.  
  1772. bool ScriptMgr::OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code)
  1773. {
  1774.    ASSERT(player);
  1775.    ASSERT(go);
  1776.    ASSERT(code);
  1777. #ifdef ELUNA
  1778.    if (sEluna->OnGossipSelectCode(player, go, sender, action, code))
  1779.        return true;
  1780. #endif
  1781.  
  1782.    GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
  1783.    return tmpscript->OnGossipSelectCode(player, go, sender, action, code);
  1784. }
  1785.  
  1786. bool ScriptMgr::OnQuestAccept(Player* player, GameObject* go, Quest const* quest)
  1787. {
  1788.    ASSERT(player);
  1789.    ASSERT(go);
  1790.    ASSERT(quest);
  1791. #ifdef ELUNA
  1792.    if (sEluna->OnQuestAccept(player, go, quest))
  1793.        return false;
  1794. #endif
  1795.  
  1796.    GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
  1797.    player->PlayerTalkClass->ClearMenus();
  1798.    return tmpscript->OnQuestAccept(player, go, quest);
  1799. }
  1800.  
  1801. bool ScriptMgr::OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt)
  1802. {
  1803.    ASSERT(player);
  1804.    ASSERT(go);
  1805.    ASSERT(quest);
  1806. #ifdef ELUNA
  1807.    if (sEluna->OnQuestReward(player, go, quest, opt))
  1808.        return false;
  1809. #endif
  1810.  
  1811.    GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
  1812.    player->PlayerTalkClass->ClearMenus();
  1813.    return tmpscript->OnQuestReward(player, go, quest, opt);
  1814. }
  1815.  
  1816. uint32 ScriptMgr::GetDialogStatus(Player* player, GameObject* go)
  1817. {
  1818.    ASSERT(player);
  1819.    ASSERT(go);
  1820. #ifdef ELUNA
  1821.    if (uint32 dialogid = sEluna->GetDialogStatus(player, go))
  1822.    {
  1823.        player->PlayerTalkClass->ClearMenus();
  1824.        return dialogid;
  1825.    }
  1826. #endif
  1827.  
  1828.    GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, DIALOG_STATUS_SCRIPTED_NO_STATUS);
  1829.    player->PlayerTalkClass->ClearMenus();
  1830.    return tmpscript->GetDialogStatus(player, go);
  1831. }
  1832.  
  1833. void ScriptMgr::OnGameObjectDestroyed(GameObject* go, Player* player)
  1834. {
  1835.    ASSERT(go);
  1836. #ifdef ELUNA
  1837.    sEluna->OnDestroyed(go, player);
  1838. #endif
  1839.  
  1840.    GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
  1841.    tmpscript->OnDestroyed(go, player);
  1842. }
  1843.  
  1844. void ScriptMgr::OnGameObjectDamaged(GameObject* go, Player* player)
  1845. {
  1846.    ASSERT(go);
  1847. #ifdef ELUNA
  1848.    sEluna->OnDamaged(go, player);
  1849. #endif
  1850.  
  1851.    GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
  1852.    tmpscript->OnDamaged(go, player);
  1853. }
  1854.  
  1855. void ScriptMgr::OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit)
  1856. {
  1857.    ASSERT(go);
  1858. #ifdef ELUNA
  1859.    sEluna->OnLootStateChanged(go, state);
  1860. #endif
  1861.  
  1862.    GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
  1863.    tmpscript->OnLootStateChanged(go, state, unit);
  1864. }
  1865.  
  1866. void ScriptMgr::OnGameObjectStateChanged(GameObject* go, uint32 state)
  1867. {
  1868.    ASSERT(go);
  1869. #ifdef ELUNA
  1870.    sEluna->OnGameObjectStateChanged(go, state);
  1871. #endif
  1872.  
  1873.    GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
  1874.    tmpscript->OnGameObjectStateChanged(go, state);
  1875. }
  1876.  
  1877. void ScriptMgr::OnGameObjectUpdate(GameObject* go, uint32 diff)
  1878. {
  1879.    ASSERT(go);
  1880. #ifdef ELUNA
  1881.    sEluna->UpdateAI(go, diff);
  1882. #endif
  1883.  
  1884.    GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
  1885.    tmpscript->OnUpdate(go, diff);
  1886. }
  1887.  
  1888. bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, GameObject* target)
  1889. {
  1890.    ASSERT(caster);
  1891.    ASSERT(target);
  1892. #ifdef ELUNA
  1893.    if (sEluna->OnDummyEffect(caster, spellId, effIndex, target))
  1894.        return false;
  1895. #endif
  1896.  
  1897.    GET_SCRIPT_RET(GameObjectScript, target->GetScriptId(), tmpscript, false);
  1898.    return tmpscript->OnDummyEffect(caster, spellId, effIndex, target);
  1899. }
  1900.  
  1901. bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger)
  1902. {
  1903.    ASSERT(player);
  1904.    ASSERT(trigger);
  1905. #ifdef ELUNA
  1906.    if (sEluna->OnAreaTrigger(player, trigger))
  1907.        return false;
  1908. #endif
  1909.  
  1910.    GET_SCRIPT_RET(AreaTriggerScript, sObjectMgr->GetAreaTriggerScriptId(trigger->id), tmpscript, false);
  1911.    return tmpscript->OnTrigger(player, trigger);
  1912. }
  1913.  
  1914. Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/)
  1915. {
  1916.    /// @todo Implement script-side battlegrounds.
  1917.    ABORT();
  1918.    return NULL;
  1919. }
  1920.  
  1921. OutdoorPvP* ScriptMgr::CreateOutdoorPvP(OutdoorPvPData const* data)
  1922. {
  1923.    ASSERT(data);
  1924.  
  1925.    GET_SCRIPT_RET(OutdoorPvPScript, data->ScriptId, tmpscript, NULL);
  1926.    return tmpscript->GetOutdoorPvP();
  1927. }
  1928.  
  1929. std::vector<ChatCommand> ScriptMgr::GetChatCommands()
  1930. {
  1931.    std::vector<ChatCommand> table;
  1932.  
  1933.    FOR_SCRIPTS_RET(CommandScript, itr, end, table)
  1934.    {
  1935.        std::vector<ChatCommand> cmds = itr->second->GetCommands();
  1936.        table.insert(table.end(), cmds.begin(), cmds.end());
  1937.    }
  1938.  
  1939.    // Sort commands in alphabetical order
  1940.    std::sort(table.begin(), table.end(), [](const ChatCommand& a, const ChatCommand&b)
  1941.    {
  1942.        return strcmp(a.Name, b.Name) < 0;
  1943.    });
  1944.  
  1945.    return table;
  1946. }
  1947.  
  1948. void ScriptMgr::OnWeatherChange(Weather* weather, WeatherState state, float grade)
  1949. {
  1950.    ASSERT(weather);
  1951. #ifdef ELUNA
  1952.    sEluna->OnChange(weather, weather->GetZone(), state, grade);
  1953. #endif
  1954.  
  1955.    GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript);
  1956.    tmpscript->OnChange(weather, state, grade);
  1957. }
  1958.  
  1959. void ScriptMgr::OnWeatherUpdate(Weather* weather, uint32 diff)
  1960. {
  1961.    ASSERT(weather);
  1962.  
  1963.    GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript);
  1964.    tmpscript->OnUpdate(weather, diff);
  1965. }
  1966.  
  1967. void ScriptMgr::OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry)
  1968. {
  1969.    ASSERT(ah);
  1970.    ASSERT(entry);
  1971. #ifdef ELUNA
  1972.    sEluna->OnAdd(ah, entry);
  1973. #endif
  1974.  
  1975.    FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionAdd(ah, entry);
  1976. }
  1977.  
  1978. void ScriptMgr::OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry)
  1979. {
  1980.    ASSERT(ah);
  1981.    ASSERT(entry);
  1982. #ifdef ELUNA
  1983.    sEluna->OnRemove(ah, entry);
  1984. #endif
  1985.  
  1986.    FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionRemove(ah, entry);
  1987. }
  1988.  
  1989. void ScriptMgr::OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry)
  1990. {
  1991.    ASSERT(ah);
  1992.    ASSERT(entry);
  1993. #ifdef ELUNA
  1994.    sEluna->OnSuccessful(ah, entry);
  1995. #endif
  1996.  
  1997.    FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionSuccessful(ah, entry);
  1998. }
  1999.  
  2000. void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry)
  2001. {
  2002.    ASSERT(ah);
  2003.    ASSERT(entry);
  2004. #ifdef ELUNA
  2005.    sEluna->OnExpire(ah, entry);
  2006. #endif
  2007.  
  2008.    FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry);
  2009. }
  2010.  
  2011. bool ScriptMgr::OnConditionCheck(Condition const* condition, ConditionSourceInfo& sourceInfo)
  2012. {
  2013.    ASSERT(condition);
  2014.  
  2015.    GET_SCRIPT_RET(ConditionScript, condition->ScriptId, tmpscript, true);
  2016.    return tmpscript->OnConditionCheck(condition, sourceInfo);
  2017. }
  2018.  
  2019. void ScriptMgr::OnInstall(Vehicle* veh)
  2020. {
  2021.    ASSERT(veh);
  2022.    ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT);
  2023. #ifdef ELUNA
  2024.    sEluna->OnInstall(veh);
  2025. #endif
  2026.  
  2027.    GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript);
  2028.    tmpscript->OnInstall(veh);
  2029. }
  2030.  
  2031. void ScriptMgr::OnUninstall(Vehicle* veh)
  2032. {
  2033.    ASSERT(veh);
  2034.    ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT);
  2035. #ifdef ELUNA
  2036.    sEluna->OnUninstall(veh);
  2037. #endif
  2038.  
  2039.    GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript);
  2040.    tmpscript->OnUninstall(veh);
  2041. }
  2042.  
  2043. void ScriptMgr::OnReset(Vehicle* veh)
  2044. {
  2045.    ASSERT(veh);
  2046.    ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT);
  2047.  
  2048.    GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript);
  2049.    tmpscript->OnReset(veh);
  2050. }
  2051.  
  2052. void ScriptMgr::OnInstallAccessory(Vehicle* veh, Creature* accessory)
  2053. {
  2054.    ASSERT(veh);
  2055.    ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT);
  2056.    ASSERT(accessory);
  2057. #ifdef ELUNA
  2058.    sEluna->OnInstallAccessory(veh, accessory);
  2059. #endif
  2060.  
  2061.    GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript);
  2062.    tmpscript->OnInstallAccessory(veh, accessory);
  2063. }
  2064.  
  2065. void ScriptMgr::OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId)
  2066. {
  2067.    ASSERT(veh);
  2068.    ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT);
  2069.    ASSERT(passenger);
  2070. #ifdef ELUNA
  2071.    sEluna->OnAddPassenger(veh, passenger, seatId);
  2072. #endif
  2073.  
  2074.    GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript);
  2075.    tmpscript->OnAddPassenger(veh, passenger, seatId);
  2076. }
  2077.  
  2078. void ScriptMgr::OnRemovePassenger(Vehicle* veh, Unit* passenger)
  2079. {
  2080.    ASSERT(veh);
  2081.    ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT);
  2082.    ASSERT(passenger);
  2083. #ifdef ELUNA
  2084.    sEluna->OnRemovePassenger(veh, passenger);
  2085. #endif
  2086.  
  2087.    GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript);
  2088.    tmpscript->OnRemovePassenger(veh, passenger);
  2089. }
  2090.  
  2091. void ScriptMgr::OnDynamicObjectUpdate(DynamicObject* dynobj, uint32 diff)
  2092. {
  2093.    ASSERT(dynobj);
  2094.  
  2095.    FOR_SCRIPTS(DynamicObjectScript, itr, end)
  2096.        itr->second->OnUpdate(dynobj, diff);
  2097. }
  2098.  
  2099. void ScriptMgr::OnAddPassenger(Transport* transport, Player* player)
  2100. {
  2101.    ASSERT(transport);
  2102.    ASSERT(player);
  2103.  
  2104.    GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript);
  2105.    tmpscript->OnAddPassenger(transport, player);
  2106. }
  2107.  
  2108. void ScriptMgr::OnAddCreaturePassenger(Transport* transport, Creature* creature)
  2109. {
  2110.    ASSERT(transport);
  2111.    ASSERT(creature);
  2112.  
  2113.    GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript);
  2114.    tmpscript->OnAddCreaturePassenger(transport, creature);
  2115. }
  2116.  
  2117. void ScriptMgr::OnRemovePassenger(Transport* transport, Player* player)
  2118. {
  2119.    ASSERT(transport);
  2120.    ASSERT(player);
  2121.  
  2122.    GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript);
  2123.    tmpscript->OnRemovePassenger(transport, player);
  2124. }
  2125.  
  2126. void ScriptMgr::OnTransportUpdate(Transport* transport, uint32 diff)
  2127. {
  2128.    ASSERT(transport);
  2129.  
  2130.    GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript);
  2131.    tmpscript->OnUpdate(transport, diff);
  2132. }
  2133.  
  2134. void ScriptMgr::OnRelocate(Transport* transport, uint32 waypointId, uint32 mapId, float x, float y, float z)
  2135. {
  2136.    GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript);
  2137.    tmpscript->OnRelocate(transport, waypointId, mapId, x, y, z);
  2138. }
  2139.  
  2140. void ScriptMgr::OnStartup()
  2141. {
  2142. #ifdef ELUNA
  2143.    sEluna->OnStartup();
  2144. #endif
  2145.    FOREACH_SCRIPT(WorldScript)->OnStartup();
  2146. }
  2147.  
  2148. void ScriptMgr::OnShutdown()
  2149. {
  2150. #ifdef ELUNA
  2151.    sEluna->OnShutdown();
  2152. #endif
  2153.    FOREACH_SCRIPT(WorldScript)->OnShutdown();
  2154. }
  2155.  
  2156. bool ScriptMgr::OnCriteriaCheck(uint32 scriptId, Player* source, Unit* target)
  2157. {
  2158.    ASSERT(source);
  2159.    // target can be NULL.
  2160.  
  2161.    GET_SCRIPT_RET(AchievementCriteriaScript, scriptId, tmpscript, false);
  2162.    return tmpscript->OnCheck(source, target);
  2163. }
  2164.  
  2165. // Player
  2166. void ScriptMgr::OnPVPKill(Player* killer, Player* killed)
  2167. {
  2168. #ifdef ELUNA
  2169.    sEluna->OnPVPKill(killer, killed);
  2170. #endif
  2171.    FOREACH_SCRIPT(PlayerScript)->OnPVPKill(killer, killed);
  2172. }
  2173.  
  2174. void ScriptMgr::OnCreatureKill(Player* killer, Creature* killed)
  2175. {
  2176. #ifdef ELUNA
  2177.    sEluna->OnCreatureKill(killer, killed);
  2178. #endif
  2179.    FOREACH_SCRIPT(PlayerScript)->OnCreatureKill(killer, killed);
  2180. }
  2181.  
  2182. void ScriptMgr::OnPlayerKilledByCreature(Creature* killer, Player* killed)
  2183. {
  2184. #ifdef ELUNA
  2185.    sEluna->OnPlayerKilledByCreature(killer, killed);
  2186. #endif
  2187.    FOREACH_SCRIPT(PlayerScript)->OnPlayerKilledByCreature(killer, killed);
  2188. }
  2189.  
  2190. void ScriptMgr::OnPlayerLevelChanged(Player* player, uint8 oldLevel)
  2191. {
  2192. #ifdef ELUNA
  2193.    sEluna->OnLevelChanged(player, oldLevel);
  2194. #endif
  2195.    FOREACH_SCRIPT(PlayerScript)->OnLevelChanged(player, oldLevel);
  2196. }
  2197.  
  2198. void ScriptMgr::OnPlayerFreeTalentPointsChanged(Player* player, uint32 points)
  2199. {
  2200. #ifdef ELUNA
  2201.    sEluna->OnFreeTalentPointsChanged(player, points);
  2202. #endif
  2203.    FOREACH_SCRIPT(PlayerScript)->OnFreeTalentPointsChanged(player, points);
  2204. }
  2205.  
  2206. void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost)
  2207. {
  2208. #ifdef ELUNA
  2209.    sEluna->OnTalentsReset(player, noCost);
  2210. #endif
  2211.    FOREACH_SCRIPT(PlayerScript)->OnTalentsReset(player, noCost);
  2212. }
  2213.  
  2214. void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount)
  2215. {
  2216. #ifdef ELUNA
  2217.    sEluna->OnMoneyChanged(player, amount);
  2218. #endif
  2219.    FOREACH_SCRIPT(PlayerScript)->OnMoneyChanged(player, amount);
  2220. }
  2221.  
  2222. void ScriptMgr::OnPlayerMoneyLimit(Player* player, int32 amount)
  2223. {
  2224.    FOREACH_SCRIPT(PlayerScript)->OnMoneyLimit(player, amount);
  2225. }
  2226.  
  2227. void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim)
  2228. {
  2229. #ifdef ELUNA
  2230.    sEluna->OnGiveXP(player, amount, victim);
  2231. #endif
  2232.    FOREACH_SCRIPT(PlayerScript)->OnGiveXP(player, amount, victim);
  2233. }
  2234.  
  2235. void ScriptMgr::OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental)
  2236. {
  2237. #ifdef ELUNA
  2238.    sEluna->OnReputationChange(player, factionID, standing, incremental);
  2239. #endif
  2240.    FOREACH_SCRIPT(PlayerScript)->OnReputationChange(player, factionID, standing, incremental);
  2241. }
  2242.  
  2243. void ScriptMgr::OnPlayerDuelRequest(Player* target, Player* challenger)
  2244. {
  2245. #ifdef ELUNA
  2246.    sEluna->OnDuelRequest(target, challenger);
  2247. #endif
  2248.    FOREACH_SCRIPT(PlayerScript)->OnDuelRequest(target, challenger);
  2249. }
  2250.  
  2251. void ScriptMgr::OnPlayerDuelStart(Player* player1, Player* player2)
  2252. {
  2253. #ifdef ELUNA
  2254.    sEluna->OnDuelStart(player1, player2);
  2255. #endif
  2256.    FOREACH_SCRIPT(PlayerScript)->OnDuelStart(player1, player2);
  2257. }
  2258.  
  2259. void ScriptMgr::OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type)
  2260. {
  2261. #ifdef ELUNA
  2262.    sEluna->OnDuelEnd(winner, loser, type);
  2263. #endif
  2264.    FOREACH_SCRIPT(PlayerScript)->OnDuelEnd(winner, loser, type);
  2265. }
  2266.  
  2267. void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg)
  2268. {
  2269.    FOREACH_SCRIPT(PlayerScript)->OnChat(player, type, lang, msg);
  2270. }
  2271.  
  2272. void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver)
  2273. {
  2274.    FOREACH_SCRIPT(PlayerScript)->OnChat(player, type, lang, msg, receiver);
  2275. }
  2276.  
  2277. void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group)
  2278. {
  2279.    FOREACH_SCRIPT(PlayerScript)->OnChat(player, type, lang, msg, group);
  2280. }
  2281.  
  2282. void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild)
  2283. {
  2284.    FOREACH_SCRIPT(PlayerScript)->OnChat(player, type, lang, msg, guild);
  2285. }
  2286.  
  2287. void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel)
  2288. {
  2289.    FOREACH_SCRIPT(PlayerScript)->OnChat(player, type, lang, msg, channel);
  2290. }
  2291.  
  2292. void ScriptMgr::OnPlayerEmote(Player* player, uint32 emote)
  2293. {
  2294. #ifdef ELUNA
  2295.    sEluna->OnEmote(player, emote);
  2296. #endif
  2297.    FOREACH_SCRIPT(PlayerScript)->OnEmote(player, emote);
  2298. }
  2299.  
  2300. void ScriptMgr::OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid)
  2301. {
  2302. #ifdef ELUNA
  2303.    sEluna->OnTextEmote(player, textEmote, emoteNum, guid);
  2304. #endif
  2305.    FOREACH_SCRIPT(PlayerScript)->OnTextEmote(player, textEmote, emoteNum, guid);
  2306. }
  2307.  
  2308. void ScriptMgr::OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck)
  2309. {
  2310. #ifdef ELUNA
  2311.    sEluna->OnSpellCast(player, spell, skipCheck);
  2312. #endif
  2313.    FOREACH_SCRIPT(PlayerScript)->OnSpellCast(player, spell, skipCheck);
  2314. }
  2315.  
  2316. void ScriptMgr::OnPlayerLogin(Player* player, bool firstLogin)
  2317. {
  2318. #ifdef ELUNA
  2319.    if (firstLogin)
  2320.        sEluna->OnFirstLogin(player);
  2321.    sEluna->OnLogin(player);
  2322. #endif
  2323.    FOREACH_SCRIPT(PlayerScript)->OnLogin(player, firstLogin);
  2324. }
  2325.  
  2326. void ScriptMgr::OnPlayerLogout(Player* player)
  2327. {
  2328. #ifdef ELUNA
  2329.    sEluna->OnLogout(player);
  2330. #endif
  2331.    FOREACH_SCRIPT(PlayerScript)->OnLogout(player);
  2332. }
  2333.  
  2334. void ScriptMgr::OnPlayerCreate(Player* player)
  2335. {
  2336. #ifdef ELUNA
  2337.    sEluna->OnCreate(player);
  2338. #endif
  2339.    FOREACH_SCRIPT(PlayerScript)->OnCreate(player);
  2340. }
  2341.  
  2342. void ScriptMgr::OnPlayerDelete(ObjectGuid guid, uint32 accountId)
  2343. {
  2344. #ifdef ELUNA
  2345.    sEluna->OnDelete(GUID_LOPART(guid));
  2346. #endif
  2347.    FOREACH_SCRIPT(PlayerScript)->OnDelete(guid, accountId);
  2348. }
  2349.  
  2350. void ScriptMgr::OnPlayerFailedDelete(ObjectGuid guid, uint32 accountId)
  2351. {
  2352.    FOREACH_SCRIPT(PlayerScript)->OnFailedDelete(guid, accountId);
  2353. }
  2354.  
  2355. void ScriptMgr::OnPlayerSave(Player* player)
  2356. {
  2357. #ifdef ELUNA
  2358.    sEluna->OnSave(player);
  2359. #endif
  2360.    FOREACH_SCRIPT(PlayerScript)->OnSave(player);
  2361. }
  2362.  
  2363. void ScriptMgr::OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent, uint8 extendState)
  2364. {
  2365. #ifdef ELUNA
  2366.    sEluna->OnBindToInstance(player, difficulty, mapid, permanent);
  2367. #endif
  2368.    FOREACH_SCRIPT(PlayerScript)->OnBindToInstance(player, difficulty, mapid, permanent, extendState);
  2369. }
  2370.  
  2371. void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea)
  2372. {
  2373. #ifdef ELUNA
  2374.    sEluna->OnUpdateZone(player, newZone, newArea);
  2375. #endif
  2376.    FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea);
  2377. }
  2378.  
  2379. void ScriptMgr::OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action)
  2380. {
  2381.    FOREACH_SCRIPT(PlayerScript)->OnGossipSelect(player, menu_id, sender, action);
  2382. }
  2383.  
  2384. void ScriptMgr::OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code)
  2385. {
  2386.    FOREACH_SCRIPT(PlayerScript)->OnGossipSelectCode(player, menu_id, sender, action, code);
  2387. }
  2388.  
  2389. void ScriptMgr::OnQuestStatusChange(Player* player, uint32 questId, QuestStatus status)
  2390. {
  2391.    FOREACH_SCRIPT(PlayerScript)->OnQuestStatusChange(player, questId, status);
  2392. }
  2393.  
  2394. // Account
  2395. void ScriptMgr::OnAccountLogin(uint32 accountId)
  2396. {
  2397.    FOREACH_SCRIPT(AccountScript)->OnAccountLogin(accountId);
  2398. }
  2399.  
  2400. void ScriptMgr::OnFailedAccountLogin(uint32 accountId)
  2401. {
  2402.    FOREACH_SCRIPT(AccountScript)->OnFailedAccountLogin(accountId);
  2403. }
  2404.  
  2405. void ScriptMgr::OnEmailChange(uint32 accountId)
  2406. {
  2407.    FOREACH_SCRIPT(AccountScript)->OnEmailChange(accountId);
  2408. }
  2409.  
  2410. void ScriptMgr::OnFailedEmailChange(uint32 accountId)
  2411. {
  2412.    FOREACH_SCRIPT(AccountScript)->OnFailedEmailChange(accountId);
  2413. }
  2414.  
  2415. void ScriptMgr::OnPasswordChange(uint32 accountId)
  2416. {
  2417.    FOREACH_SCRIPT(AccountScript)->OnPasswordChange(accountId);
  2418. }
  2419.  
  2420. void ScriptMgr::OnFailedPasswordChange(uint32 accountId)
  2421. {
  2422.    FOREACH_SCRIPT(AccountScript)->OnFailedPasswordChange(accountId);
  2423. }
  2424.  
  2425. // Guild
  2426. void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank)
  2427. {
  2428. #ifdef ELUNA
  2429.    sEluna->OnAddMember(guild, player, plRank);
  2430. #endif
  2431.    FOREACH_SCRIPT(GuildScript)->OnAddMember(guild, player, plRank);
  2432. }
  2433.  
  2434. void ScriptMgr::OnGuildRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool isKicked)
  2435. {
  2436. #ifdef ELUNA
  2437.    sEluna->OnRemoveMember(guild, player, isDisbanding);
  2438. #endif
  2439.    FOREACH_SCRIPT(GuildScript)->OnRemoveMember(guild, player, isDisbanding, isKicked);
  2440. }
  2441.  
  2442. void ScriptMgr::OnGuildMOTDChanged(Guild* guild, const std::string& newMotd)
  2443. {
  2444. #ifdef ELUNA
  2445.    sEluna->OnMOTDChanged(guild, newMotd);
  2446. #endif
  2447.    FOREACH_SCRIPT(GuildScript)->OnMOTDChanged(guild, newMotd);
  2448. }
  2449.  
  2450. void ScriptMgr::OnGuildInfoChanged(Guild* guild, const std::string& newInfo)
  2451. {
  2452. #ifdef ELUNA
  2453.    sEluna->OnInfoChanged(guild, newInfo);
  2454. #endif
  2455.    FOREACH_SCRIPT(GuildScript)->OnInfoChanged(guild, newInfo);
  2456. }
  2457.  
  2458. void ScriptMgr::OnGuildCreate(Guild* guild, Player* leader, const std::string& name)
  2459. {
  2460. #ifdef ELUNA
  2461.    sEluna->OnCreate(guild, leader, name);
  2462. #endif
  2463.    FOREACH_SCRIPT(GuildScript)->OnCreate(guild, leader, name);
  2464. }
  2465.  
  2466. void ScriptMgr::OnGuildDisband(Guild* guild)
  2467. {
  2468. #ifdef ELUNA
  2469.    sEluna->OnDisband(guild);
  2470. #endif
  2471.    FOREACH_SCRIPT(GuildScript)->OnDisband(guild);
  2472. }
  2473.  
  2474. void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair)
  2475. {
  2476. #ifdef ELUNA
  2477.    sEluna->OnMemberWitdrawMoney(guild, player, amount, isRepair);
  2478. #endif
  2479.    FOREACH_SCRIPT(GuildScript)->OnMemberWitdrawMoney(guild, player, amount, isRepair);
  2480. }
  2481.  
  2482. void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount)
  2483. {
  2484. #ifdef ELUNA
  2485.    sEluna->OnMemberDepositMoney(guild, player, amount);
  2486. #endif
  2487.    FOREACH_SCRIPT(GuildScript)->OnMemberDepositMoney(guild, player, amount);
  2488. }
  2489.  
  2490. void ScriptMgr::OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId,
  2491.            bool isDestBank, uint8 destContainer, uint8 destSlotId)
  2492. {
  2493. #ifdef ELUNA
  2494.    sEluna->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId);
  2495. #endif
  2496.    FOREACH_SCRIPT(GuildScript)->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId);
  2497. }
  2498.  
  2499. void ScriptMgr::OnGuildEvent(Guild* guild, uint8 eventType, ObjectGuid::LowType playerGuid1, ObjectGuid::LowType playerGuid2, uint8 newRank)
  2500. {
  2501. #ifdef ELUNA
  2502.    sEluna->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank);
  2503. #endif
  2504.    FOREACH_SCRIPT(GuildScript)->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank);
  2505. }
  2506.  
  2507. void ScriptMgr::OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, ObjectGuid::LowType playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId)
  2508. {
  2509. #ifdef ELUNA
  2510.    sEluna->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId);
  2511. #endif
  2512.    FOREACH_SCRIPT(GuildScript)->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId);
  2513. }
  2514.  
  2515. // Group
  2516. void ScriptMgr::OnGroupAddMember(Group* group, ObjectGuid guid)
  2517. {
  2518.    ASSERT(group);
  2519. #ifdef ELUNA
  2520.    sEluna->OnAddMember(group, guid);
  2521. #endif
  2522.    FOREACH_SCRIPT(GroupScript)->OnAddMember(group, guid);
  2523. }
  2524.  
  2525. void ScriptMgr::OnGroupInviteMember(Group* group, ObjectGuid guid)
  2526. {
  2527.    ASSERT(group);
  2528. #ifdef ELUNA
  2529.    sEluna->OnInviteMember(group, guid);
  2530. #endif
  2531.    FOREACH_SCRIPT(GroupScript)->OnInviteMember(group, guid);
  2532. }
  2533.  
  2534. void ScriptMgr::OnGroupRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, const char* reason)
  2535. {
  2536.    ASSERT(group);
  2537. #ifdef ELUNA
  2538.    sEluna->OnRemoveMember(group, guid, method);
  2539. #endif
  2540.    FOREACH_SCRIPT(GroupScript)->OnRemoveMember(group, guid, method, kicker, reason);
  2541. }
  2542.  
  2543. void ScriptMgr::OnGroupChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid)
  2544. {
  2545.    ASSERT(group);
  2546. #ifdef ELUNA
  2547.    sEluna->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid);
  2548. #endif
  2549.    FOREACH_SCRIPT(GroupScript)->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid);
  2550. }
  2551.  
  2552. void ScriptMgr::OnGroupDisband(Group* group)
  2553. {
  2554.    ASSERT(group);
  2555. #ifdef ELUNA
  2556.    sEluna->OnDisband(group);
  2557. #endif
  2558.    FOREACH_SCRIPT(GroupScript)->OnDisband(group);
  2559. }
  2560.  
  2561. // Unit
  2562. void ScriptMgr::OnHeal(Unit* healer, Unit* reciever, uint32& gain)
  2563. {
  2564.    FOREACH_SCRIPT(UnitScript)->OnHeal(healer, reciever, gain);
  2565.    FOREACH_SCRIPT(PlayerScript)->OnHeal(healer, reciever, gain);
  2566. }
  2567.  
  2568. void ScriptMgr::OnDamage(Unit* attacker, Unit* victim, uint32& damage)
  2569. {
  2570.    FOREACH_SCRIPT(UnitScript)->OnDamage(attacker, victim, damage);
  2571.    FOREACH_SCRIPT(PlayerScript)->OnDamage(attacker, victim, damage);
  2572. }
  2573.  
  2574. void ScriptMgr::ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage)
  2575. {
  2576.    FOREACH_SCRIPT(UnitScript)->ModifyPeriodicDamageAurasTick(target, attacker, damage);
  2577.    FOREACH_SCRIPT(PlayerScript)->ModifyPeriodicDamageAurasTick(target, attacker, damage);
  2578. }
  2579.  
  2580. void ScriptMgr::ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage)
  2581. {
  2582.    FOREACH_SCRIPT(UnitScript)->ModifyMeleeDamage(target, attacker, damage);
  2583.    FOREACH_SCRIPT(PlayerScript)->ModifyMeleeDamage(target, attacker, damage);
  2584. }
  2585.  
  2586. void ScriptMgr::ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage)
  2587. {
  2588.    FOREACH_SCRIPT(UnitScript)->ModifySpellDamageTaken(target, attacker, damage);
  2589.    FOREACH_SCRIPT(PlayerScript)->ModifySpellDamageTaken(target, attacker, damage);
  2590. }
  2591.  
  2592. SpellScriptLoader::SpellScriptLoader(const char* name)
  2593.    : ScriptObject(name)
  2594. {
  2595.    ScriptRegistry<SpellScriptLoader>::Instance()->AddScript(this);
  2596. }
  2597.  
  2598. ServerScript::ServerScript(const char* name)
  2599.    : ScriptObject(name)
  2600. {
  2601.    ScriptRegistry<ServerScript>::Instance()->AddScript(this);
  2602. }
  2603.  
  2604. WorldScript::WorldScript(const char* name)
  2605.    : ScriptObject(name)
  2606. {
  2607.    ScriptRegistry<WorldScript>::Instance()->AddScript(this);
  2608. }
  2609.  
  2610. FormulaScript::FormulaScript(const char* name)
  2611.    : ScriptObject(name)
  2612. {
  2613.    ScriptRegistry<FormulaScript>::Instance()->AddScript(this);
  2614. }
  2615.  
  2616. UnitScript::UnitScript(const char* name, bool addToScripts)
  2617.    : ScriptObject(name)
  2618. {
  2619.    if (addToScripts)
  2620.        ScriptRegistry<UnitScript>::Instance()->AddScript(this);
  2621. }
  2622.  
  2623. WorldMapScript::WorldMapScript(const char* name, uint32 mapId)
  2624.    : ScriptObject(name), MapScript<Map>(mapId)
  2625. {
  2626.    if (GetEntry() && !GetEntry()->IsWorldMap())
  2627.        TC_LOG_ERROR("scripts", "WorldMapScript for map %u is invalid.", mapId);
  2628.  
  2629.    ScriptRegistry<WorldMapScript>::Instance()->AddScript(this);
  2630. }
  2631.  
  2632. InstanceMapScript::InstanceMapScript(const char* name, uint32 mapId)
  2633.    : ScriptObject(name), MapScript<InstanceMap>(mapId)
  2634. {
  2635.    if (GetEntry() && !GetEntry()->IsDungeon())
  2636.        TC_LOG_ERROR("scripts", "InstanceMapScript for map %u is invalid.", mapId);
  2637.  
  2638.    ScriptRegistry<InstanceMapScript>::Instance()->AddScript(this);
  2639. }
  2640.  
  2641. BattlegroundMapScript::BattlegroundMapScript(const char* name, uint32 mapId)
  2642.    : ScriptObject(name), MapScript<BattlegroundMap>(mapId)
  2643. {
  2644.    if (GetEntry() && !GetEntry()->IsBattleground())
  2645.        TC_LOG_ERROR("scripts", "BattlegroundMapScript for map %u is invalid.", mapId);
  2646.  
  2647.    ScriptRegistry<BattlegroundMapScript>::Instance()->AddScript(this);
  2648. }
  2649.  
  2650. ItemScript::ItemScript(const char* name)
  2651.    : ScriptObject(name)
  2652. {
  2653.    ScriptRegistry<ItemScript>::Instance()->AddScript(this);
  2654. }
  2655.  
  2656. CreatureScript::CreatureScript(const char* name)
  2657.    : UnitScript(name, false)
  2658. {
  2659.    ScriptRegistry<CreatureScript>::Instance()->AddScript(this);
  2660. }
  2661.  
  2662. GameObjectScript::GameObjectScript(const char* name)
  2663.    : ScriptObject(name)
  2664. {
  2665.    ScriptRegistry<GameObjectScript>::Instance()->AddScript(this);
  2666. }
  2667.  
  2668. AreaTriggerScript::AreaTriggerScript(const char* name)
  2669.    : ScriptObject(name)
  2670. {
  2671.    ScriptRegistry<AreaTriggerScript>::Instance()->AddScript(this);
  2672. }
  2673.  
  2674. BattlegroundScript::BattlegroundScript(const char* name)
  2675.    : ScriptObject(name)
  2676. {
  2677.    ScriptRegistry<BattlegroundScript>::Instance()->AddScript(this);
  2678. }
  2679.  
  2680. OutdoorPvPScript::OutdoorPvPScript(const char* name)
  2681.    : ScriptObject(name)
  2682. {
  2683.    ScriptRegistry<OutdoorPvPScript>::Instance()->AddScript(this);
  2684. }
  2685.  
  2686. CommandScript::CommandScript(const char* name)
  2687.    : ScriptObject(name)
  2688. {
  2689.    ScriptRegistry<CommandScript>::Instance()->AddScript(this);
  2690. }
  2691.  
  2692. WeatherScript::WeatherScript(const char* name)
  2693.    : ScriptObject(name)
  2694. {
  2695.    ScriptRegistry<WeatherScript>::Instance()->AddScript(this);
  2696. }
  2697.  
  2698. AuctionHouseScript::AuctionHouseScript(const char* name)
  2699.    : ScriptObject(name)
  2700. {
  2701.    ScriptRegistry<AuctionHouseScript>::Instance()->AddScript(this);
  2702. }
  2703.  
  2704. ConditionScript::ConditionScript(const char* name)
  2705.    : ScriptObject(name)
  2706. {
  2707.    ScriptRegistry<ConditionScript>::Instance()->AddScript(this);
  2708. }
  2709.  
  2710. VehicleScript::VehicleScript(const char* name)
  2711.    : ScriptObject(name)
  2712. {
  2713.    ScriptRegistry<VehicleScript>::Instance()->AddScript(this);
  2714. }
  2715.  
  2716. DynamicObjectScript::DynamicObjectScript(const char* name)
  2717.    : ScriptObject(name)
  2718. {
  2719.    ScriptRegistry<DynamicObjectScript>::Instance()->AddScript(this);
  2720. }
  2721.  
  2722. TransportScript::TransportScript(const char* name)
  2723.    : ScriptObject(name)
  2724. {
  2725.    ScriptRegistry<TransportScript>::Instance()->AddScript(this);
  2726. }
  2727.  
  2728. AchievementCriteriaScript::AchievementCriteriaScript(const char* name)
  2729.    : ScriptObject(name)
  2730. {
  2731.    ScriptRegistry<AchievementCriteriaScript>::Instance()->AddScript(this);
  2732. }
  2733.  
  2734. PlayerScript::PlayerScript(const char* name)
  2735.    : UnitScript(name, false)
  2736. {
  2737.    ScriptRegistry<PlayerScript>::Instance()->AddScript(this);
  2738. }
  2739.  
  2740. AccountScript::AccountScript(const char* name)
  2741.    : ScriptObject(name)
  2742. {
  2743.    ScriptRegistry<AccountScript>::Instance()->AddScript(this);
  2744. }
  2745.  
  2746. GuildScript::GuildScript(const char* name)
  2747.    : ScriptObject(name)
  2748. {
  2749.    ScriptRegistry<GuildScript>::Instance()->AddScript(this);
  2750. }
  2751.  
  2752. GroupScript::GroupScript(const char* name)
  2753.    : ScriptObject(name)
  2754. {
  2755.    ScriptRegistry<GroupScript>::Instance()->AddScript(this);
  2756. }
  2757.  
  2758. // Specialize for each script type class like so:
  2759. template class TC_GAME_API ScriptRegistry<SpellScriptLoader>;
  2760. template class TC_GAME_API ScriptRegistry<ServerScript>;
  2761. template class TC_GAME_API ScriptRegistry<WorldScript>;
  2762. template class TC_GAME_API ScriptRegistry<FormulaScript>;
  2763. template class TC_GAME_API ScriptRegistry<WorldMapScript>;
  2764. template class TC_GAME_API ScriptRegistry<InstanceMapScript>;
  2765. template class TC_GAME_API ScriptRegistry<BattlegroundMapScript>;
  2766. template class TC_GAME_API ScriptRegistry<ItemScript>;
  2767. template class TC_GAME_API ScriptRegistry<CreatureScript>;
  2768. template class TC_GAME_API ScriptRegistry<GameObjectScript>;
  2769. template class TC_GAME_API ScriptRegistry<AreaTriggerScript>;
  2770. template class TC_GAME_API ScriptRegistry<BattlegroundScript>;
  2771. template class TC_GAME_API ScriptRegistry<OutdoorPvPScript>;
  2772. template class TC_GAME_API ScriptRegistry<CommandScript>;
  2773. template class TC_GAME_API ScriptRegistry<WeatherScript>;
  2774. template class TC_GAME_API ScriptRegistry<AuctionHouseScript>;
  2775. template class TC_GAME_API ScriptRegistry<ConditionScript>;
  2776. template class TC_GAME_API ScriptRegistry<VehicleScript>;
  2777. template class TC_GAME_API ScriptRegistry<DynamicObjectScript>;
  2778. template class TC_GAME_API ScriptRegistry<TransportScript>;
  2779. template class TC_GAME_API ScriptRegistry<AchievementCriteriaScript>;
  2780. template class TC_GAME_API ScriptRegistry<PlayerScript>;
  2781. template class TC_GAME_API ScriptRegistry<GuildScript>;
  2782. template class TC_GAME_API ScriptRegistry<GroupScript>;
  2783. template class TC_GAME_API ScriptRegistry<UnitScript>;
  2784. template class TC_GAME_API ScriptRegistry<AccountScript>;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement