diff options
Diffstat (limited to 'src/server/game/Scripting/ScriptMgr.cpp')
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 1459 |
1 files changed, 1459 insertions, 0 deletions
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp new file mode 100644 index 0000000000..4c744753ff --- /dev/null +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -0,0 +1,1459 @@ +/* + * Copyright (C) + * Copyright (C) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "Config.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "ObjectMgr.h" +#include "OutdoorPvPMgr.h" +#include "ScriptLoader.h" +#include "ScriptSystem.h" +#include "Transport.h" +#include "Vehicle.h" +#include "SpellInfo.h" +#include "SpellScript.h" +#include "GossipDef.h" +#include "CreatureAI.h" +#include "Player.h" +#include "WorldPacket.h" + +// This is the global static registry of scripts. +/*template<class TScript> +class ScriptRegistry +{ + public: + + typedef std::map<uint32, TScript*> ScriptMap; + typedef typename ScriptMap::iterator ScriptMapIterator; + + // The actual list of scripts. This will be accessed concurrently, so it must not be modified + // after server startup. + static ScriptMap ScriptPointerList; + + static void AddScript(TScript* const script) + { + ASSERT(script); + + // See if the script is using the same memory as another script. If this happens, it means that + // someone forgot to allocate new memory for a script. + for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it) + { + if (it->second == script) + { + sLog->outError("Script '%s' has same memory pointer as '%s'.", + script->GetName().c_str(), it->second->GetName().c_str()); + + return; + } + } + + if (script->IsDatabaseBound()) + { + // Get an ID for the script. An ID only exists if it's a script that is assigned in the database + // through a script name (or similar). + uint32 id = sObjectMgr->GetScriptId(script->GetName().c_str()); + if (id) + { + // Try to find an existing script. + bool existing = false; + for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it) + { + // If the script names match... + if (it->second->GetName() == script->GetName()) + { + // ... It exists. + existing = true; + break; + } + } + + // If the script isn't assigned -> assign it! + if (!existing) + { + ScriptPointerList[id] = script; + sScriptMgr->IncrementScriptCount(); + } + else + { + // If the script is already assigned -> delete it! + sLog->outError("Script '%s' already assigned with the same script name, so the script can't work.", + script->GetName().c_str()); + + ASSERT(false); // Error that should be fixed ASAP. + } + } + else + { + // The script uses a script name from database, but isn't assigned to anything. + if (script->GetName().find("example") == std::string::npos && script->GetName().find("Smart") == std::string::npos) + sLog->outErrorDb("Script named '%s' does not have a script name assigned in database.", + script->GetName().c_str()); + } + } + else + { + // We're dealing with a code-only script; just add it. + ScriptPointerList[_scriptIdCounter++] = script; + sScriptMgr->IncrementScriptCount(); + } + } + + // Gets a script by its ID (assigned by ObjectMgr). + static TScript* GetScriptById(uint32 id) + { + ScriptMapIterator it = ScriptPointerList.find(id); + if (it != ScriptPointerList.end()) + return it->second; + + return NULL; + } + + private: + + // Counter used for code-only scripts. + static uint32 _scriptIdCounter; +};*/ + +// Utility macros to refer to the script registry. +#define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptMap +#define SCR_REG_ITR(T) ScriptRegistry<T>::ScriptMapIterator +#define SCR_REG_LST(T) ScriptRegistry<T>::ScriptPointerList + +// Utility macros for looping over scripts. +#define FOR_SCRIPTS(T, C, E) \ + if (SCR_REG_LST(T).empty()) \ + return; \ + for (SCR_REG_ITR(T) C = SCR_REG_LST(T).begin(); \ + C != SCR_REG_LST(T).end(); ++C) +#define FOR_SCRIPTS_RET(T, C, E, R) \ + if (SCR_REG_LST(T).empty()) \ + return R; \ + for (SCR_REG_ITR(T) C = SCR_REG_LST(T).begin(); \ + C != SCR_REG_LST(T).end(); ++C) +#define FOREACH_SCRIPT(T) \ + FOR_SCRIPTS(T, itr, end) \ + itr->second + +// Utility macros for finding specific scripts. +#define GET_SCRIPT(T, I, V) \ + T* V = ScriptRegistry<T>::GetScriptById(I); \ + if (!V) \ + return; +#define GET_SCRIPT_RET(T, I, V, R) \ + T* V = ScriptRegistry<T>::GetScriptById(I); \ + if (!V) \ + return R; + +ScriptMgr::ScriptMgr() + : _scriptCount(0), _scheduledScripts(0) +{ +} + +ScriptMgr::~ScriptMgr() +{ +} + +void ScriptMgr::Initialize() +{ + uint32 oldMSTime = getMSTime(); + + LoadDatabase(); + + sLog->outString("Loading C++ scripts"); + + FillSpellSummary(); + AddScripts(); + CheckIfScriptsInDatabaseExist(); + + sLog->outString(">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(); +} + +void ScriptMgr::Unload() +{ + #define SCR_CLEAR(T) \ + for (SCR_REG_ITR(T) itr = SCR_REG_LST(T).begin(); itr != SCR_REG_LST(T).end(); ++itr) \ + delete itr->second; \ + SCR_REG_LST(T).clear(); + + // Clear scripts for every script type. + SCR_CLEAR(SpellScriptLoader); + SCR_CLEAR(ServerScript); + SCR_CLEAR(WorldScript); + SCR_CLEAR(FormulaScript); + SCR_CLEAR(WorldMapScript); + SCR_CLEAR(InstanceMapScript); + SCR_CLEAR(BattlegroundMapScript); + SCR_CLEAR(ItemScript); + SCR_CLEAR(CreatureScript); + SCR_CLEAR(GameObjectScript); + SCR_CLEAR(AreaTriggerScript); + SCR_CLEAR(BattlegroundScript); + SCR_CLEAR(OutdoorPvPScript); + SCR_CLEAR(CommandScript); + SCR_CLEAR(WeatherScript); + SCR_CLEAR(AuctionHouseScript); + SCR_CLEAR(ConditionScript); + SCR_CLEAR(VehicleScript); + SCR_CLEAR(DynamicObjectScript); + SCR_CLEAR(TransportScript); + SCR_CLEAR(AchievementCriteriaScript); + SCR_CLEAR(PlayerScript); + SCR_CLEAR(GuildScript); + SCR_CLEAR(GroupScript); + + #undef SCR_CLEAR +} + +void ScriptMgr::LoadDatabase() +{ + sScriptSystemMgr->LoadScriptWaypoints(); +} + +struct TSpellSummary +{ + uint8 Targets; // set of enum SelectTarget + uint8 Effects; // set of enum SelectEffect +} *SpellSummary; + +void ScriptMgr::FillSpellSummary() +{ + SpellSummary = new TSpellSummary[sSpellMgr->GetSpellInfoStoreSize()]; + + SpellInfo const* pTempSpell; + + for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) + { + SpellSummary[i].Effects = 0; + SpellSummary[i].Targets = 0; + + pTempSpell = sSpellMgr->GetSpellInfo(i); + // This spell doesn't exist. + if (!pTempSpell) + continue; + + for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) + { + // Spell targets self. + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1); + + // Spell targets a single enemy. + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1); + + // Spell targets AoE at enemy. + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1); + + // Spell targets an enemy. + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1); + + // Spell targets a single friend (or self). + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1); + + // Spell targets AoE friends. + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1); + + // Spell targets any friend (or self). + if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY || + pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER) + SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1); + + // Make sure that this spell includes a damage effect. + if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE || + pTempSpell->Effects[j].Effect == SPELL_EFFECT_INSTAKILL || + pTempSpell->Effects[j].Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE || + pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH) + SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE-1); + + // Make sure that this spell includes a healing effect (or an apply aura with a periodic heal). + if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL || + pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL_MAX_HEALTH || + pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL_MECHANICAL || + (pTempSpell->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && pTempSpell->Effects[j].ApplyAuraName == 8)) + SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1); + + // Make sure that this spell applies an aura. + if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA) + SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1); + } + } +} + +void ScriptMgr::CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector) +{ + SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId); + + for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr) + { + SpellScriptLoader* tmpscript = ScriptRegistry<SpellScriptLoader>::GetScriptById(itr->second); + if (!tmpscript) + continue; + + SpellScript* script = tmpscript->GetSpellScript(); + + if (!script) + continue; + + script->_Init(&tmpscript->GetName(), spellId); + + scriptVector.push_back(script); + } +} + +void ScriptMgr::CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector) +{ + SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId); + + for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr) + { + SpellScriptLoader* tmpscript = ScriptRegistry<SpellScriptLoader>::GetScriptById(itr->second); + if (!tmpscript) + continue; + + AuraScript* script = tmpscript->GetAuraScript(); + + if (!script) + continue; + + script->_Init(&tmpscript->GetName(), spellId); + + scriptVector.push_back(script); + } +} + +void ScriptMgr::CreateSpellScriptLoaders(uint32 spellId, std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> >& scriptVector) +{ + SpellScriptsBounds bounds = sObjectMgr->GetSpellScriptsBounds(spellId); + scriptVector.reserve(std::distance(bounds.first, bounds.second)); + + for (SpellScriptsContainer::iterator itr = bounds.first; itr != bounds.second; ++itr) + { + SpellScriptLoader* tmpscript = ScriptRegistry<SpellScriptLoader>::GetScriptById(itr->second); + if (!tmpscript) + continue; + + scriptVector.push_back(std::make_pair(tmpscript, itr)); + } +} + +void ScriptMgr::OnNetworkStart() +{ + FOREACH_SCRIPT(ServerScript)->OnNetworkStart(); +} + +void ScriptMgr::OnNetworkStop() +{ + FOREACH_SCRIPT(ServerScript)->OnNetworkStop(); +} + +void ScriptMgr::OnSocketOpen(WorldSocket* socket) +{ + ASSERT(socket); + + FOREACH_SCRIPT(ServerScript)->OnSocketOpen(socket); +} + +void ScriptMgr::OnSocketClose(WorldSocket* socket, bool wasNew) +{ + ASSERT(socket); + + FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket, wasNew); +} + +void ScriptMgr::OnOpenStateChange(bool open) +{ + FOREACH_SCRIPT(WorldScript)->OnOpenStateChange(open); +} + +void ScriptMgr::OnConfigLoad(bool reload) +{ + FOREACH_SCRIPT(WorldScript)->OnConfigLoad(reload); +} + +void ScriptMgr::OnMotdChange(std::string& newMotd) +{ + FOREACH_SCRIPT(WorldScript)->OnMotdChange(newMotd); +} + +void ScriptMgr::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) +{ + FOREACH_SCRIPT(WorldScript)->OnShutdownInitiate(code, mask); +} + +void ScriptMgr::OnShutdownCancel() +{ + FOREACH_SCRIPT(WorldScript)->OnShutdownCancel(); +} + +void ScriptMgr::OnWorldUpdate(uint32 diff) +{ + FOREACH_SCRIPT(WorldScript)->OnUpdate(diff); +} + +void ScriptMgr::OnHonorCalculation(float& honor, uint8 level, float multiplier) +{ + FOREACH_SCRIPT(FormulaScript)->OnHonorCalculation(honor, level, multiplier); +} + +void ScriptMgr::OnGrayLevelCalculation(uint8& grayLevel, uint8 playerLevel) +{ + FOREACH_SCRIPT(FormulaScript)->OnGrayLevelCalculation(grayLevel, playerLevel); +} + +void ScriptMgr::OnColorCodeCalculation(XPColorChar& color, uint8 playerLevel, uint8 mobLevel) +{ + FOREACH_SCRIPT(FormulaScript)->OnColorCodeCalculation(color, playerLevel, mobLevel); +} + +void ScriptMgr::OnZeroDifferenceCalculation(uint8& diff, uint8 playerLevel) +{ + FOREACH_SCRIPT(FormulaScript)->OnZeroDifferenceCalculation(diff, playerLevel); +} + +void ScriptMgr::OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content) +{ + FOREACH_SCRIPT(FormulaScript)->OnBaseGainCalculation(gain, playerLevel, mobLevel, content); +} + +void ScriptMgr::OnGainCalculation(uint32& gain, Player* player, Unit* unit) +{ + ASSERT(player); + ASSERT(unit); + + FOREACH_SCRIPT(FormulaScript)->OnGainCalculation(gain, player, unit); +} + +void ScriptMgr::OnGroupRateCalculation(float& rate, uint32 count, bool isRaid) +{ + FOREACH_SCRIPT(FormulaScript)->OnGroupRateCalculation(rate, count, isRaid); +} + +#define SCR_MAP_BGN(M, V, I, E, C, T) \ + if (V->GetEntry() && V->GetEntry()->T()) \ + { \ + FOR_SCRIPTS(M, I, E) \ + { \ + MapEntry const* C = I->second->GetEntry(); \ + if (!C) \ + continue; \ + if (C->MapID == V->GetId()) \ + { + +#define SCR_MAP_END \ + return; \ + } \ + } \ + } + +void ScriptMgr::OnCreateMap(Map* map) +{ + ASSERT(map); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnCreate(map); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnCreate((InstanceMap*)map); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnCreate((BattlegroundMap*)map); + SCR_MAP_END; +} + +void ScriptMgr::OnDestroyMap(Map* map) +{ + ASSERT(map); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnDestroy(map); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnDestroy((InstanceMap*)map); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnDestroy((BattlegroundMap*)map); + SCR_MAP_END; +} + +void ScriptMgr::OnLoadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy) +{ + ASSERT(map); + ASSERT(gmap); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnLoadGridMap(map, gmap, gx, gy); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnLoadGridMap((InstanceMap*)map, gmap, gx, gy); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnLoadGridMap((BattlegroundMap*)map, gmap, gx, gy); + SCR_MAP_END; +} + +void ScriptMgr::OnUnloadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy) +{ + ASSERT(map); + ASSERT(gmap); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnUnloadGridMap(map, gmap, gx, gy); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnUnloadGridMap((InstanceMap*)map, gmap, gx, gy); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnUnloadGridMap((BattlegroundMap*)map, gmap, gx, gy); + SCR_MAP_END; +} + +void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) +{ + ASSERT(map); + ASSERT(player); + + FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnPlayerEnter(map, player); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnPlayerEnter((InstanceMap*)map, player); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnPlayerEnter((BattlegroundMap*)map, player); + SCR_MAP_END; +} + +void ScriptMgr::OnPlayerLeaveMap(Map* map, Player* player) +{ + ASSERT(map); + ASSERT(player); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnPlayerLeave(map, player); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnPlayerLeave((InstanceMap*)map, player); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnPlayerLeave((BattlegroundMap*)map, player); + SCR_MAP_END; +} + +void ScriptMgr::OnMapUpdate(Map* map, uint32 diff) +{ + ASSERT(map); + + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); + itr->second->OnUpdate(map, diff); + SCR_MAP_END; + + SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon); + itr->second->OnUpdate((InstanceMap*)map, diff); + SCR_MAP_END; + + SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleground); + itr->second->OnUpdate((BattlegroundMap*)map, diff); + SCR_MAP_END; +} + +#undef SCR_MAP_BGN +#undef SCR_MAP_END + +InstanceScript* ScriptMgr::CreateInstanceScript(InstanceMap* map) +{ + ASSERT(map); + + GET_SCRIPT_RET(InstanceMapScript, map->GetScriptId(), tmpscript, NULL); + return tmpscript->GetInstanceScript(map); +} + +bool ScriptMgr::OnQuestAccept(Player* player, Item* item, Quest const* quest) +{ + ASSERT(player); + ASSERT(item); + ASSERT(quest); + + GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestAccept(player, item, quest); +} + +bool ScriptMgr::OnItemUse(Player* player, Item* item, SpellCastTargets const& targets) +{ + ASSERT(player); + ASSERT(item); + + GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); + return tmpscript->OnUse(player, item, targets); +} + +bool ScriptMgr::OnItemExpire(Player* player, ItemTemplate const* proto) +{ + ASSERT(player); + ASSERT(proto); + + GET_SCRIPT_RET(ItemScript, proto->ScriptId, tmpscript, false); + return tmpscript->OnExpire(player, proto); +} + +bool ScriptMgr::OnGossipHello(Player* player, Creature* creature) +{ + ASSERT(player); + ASSERT(creature); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnGossipHello(player, creature); +} + +bool ScriptMgr::OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) +{ + ASSERT(player); + ASSERT(creature); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + return tmpscript->OnGossipSelect(player, creature, sender, action); +} + +bool ScriptMgr::OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code) +{ + ASSERT(player); + ASSERT(creature); + ASSERT(code); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + return tmpscript->OnGossipSelectCode(player, creature, sender, action, code); +} + +bool ScriptMgr::OnQuestAccept(Player* player, Creature* creature, Quest const* quest) +{ + ASSERT(player); + ASSERT(creature); + ASSERT(quest); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestAccept(player, creature, quest); +} + +bool ScriptMgr::OnQuestSelect(Player* player, Creature* creature, Quest const* quest) +{ + ASSERT(player); + ASSERT(creature); + ASSERT(quest); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestSelect(player, creature, quest); +} + +bool ScriptMgr::OnQuestComplete(Player* player, Creature* creature, Quest const* quest) +{ + ASSERT(player); + ASSERT(creature); + ASSERT(quest); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestComplete(player, creature, quest); +} + +bool ScriptMgr::OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt) +{ + ASSERT(player); + ASSERT(creature); + ASSERT(quest); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestReward(player, creature, quest, opt); +} + +uint32 ScriptMgr::GetDialogStatus(Player* player, Creature* creature) +{ + ASSERT(player); + ASSERT(creature); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, DIALOG_STATUS_SCRIPTED_NO_STATUS); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->GetDialogStatus(player, creature); +} + +CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature) +{ + ASSERT(creature); + + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, NULL); + return tmpscript->GetAI(creature); +} + +void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff) +{ + ASSERT(creature); + + GET_SCRIPT(CreatureScript, creature->GetScriptId(), tmpscript); + tmpscript->OnUpdate(creature, diff); +} + +bool ScriptMgr::OnGossipHello(Player* player, GameObject* go) +{ + ASSERT(player); + ASSERT(go); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnGossipHello(player, go); +} + +bool ScriptMgr::OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action) +{ + ASSERT(player); + ASSERT(go); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); + return tmpscript->OnGossipSelect(player, go, sender, action); +} + +bool ScriptMgr::OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code) +{ + ASSERT(player); + ASSERT(go); + ASSERT(code); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); + return tmpscript->OnGossipSelectCode(player, go, sender, action, code); +} + +bool ScriptMgr::OnQuestAccept(Player* player, GameObject* go, Quest const* quest) +{ + ASSERT(player); + ASSERT(go); + ASSERT(quest); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestAccept(player, go, quest); +} + +bool ScriptMgr::OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt) +{ + ASSERT(player); + ASSERT(go); + ASSERT(quest); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->OnQuestReward(player, go, quest, opt); +} + +uint32 ScriptMgr::GetDialogStatus(Player* player, GameObject* go) +{ + ASSERT(player); + ASSERT(go); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, DIALOG_STATUS_SCRIPTED_NO_STATUS); + player->PlayerTalkClass->ClearMenus(); + return tmpscript->GetDialogStatus(player, go); +} + +void ScriptMgr::OnGameObjectDestroyed(GameObject* go, Player* player) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnDestroyed(go, player); +} + +void ScriptMgr::OnGameObjectDamaged(GameObject* go, Player* player) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnDamaged(go, player); +} + +void ScriptMgr::OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnLootStateChanged(go, state, unit); +} + +void ScriptMgr::OnGameObjectStateChanged(GameObject* go, uint32 state) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnGameObjectStateChanged(go, state); +} + +void ScriptMgr::OnGameObjectUpdate(GameObject* go, uint32 diff) +{ + ASSERT(go); + + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); + tmpscript->OnUpdate(go, diff); +} + +GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* go) +{ + ASSERT(go); + + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, NULL); + return tmpscript->GetAI(go); +} + +bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger) +{ + ASSERT(player); + ASSERT(trigger); + + GET_SCRIPT_RET(AreaTriggerScript, sObjectMgr->GetAreaTriggerScriptId(trigger->id), tmpscript, false); + return tmpscript->OnTrigger(player, trigger); +} + +Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/) +{ + // TODO: Implement script-side battlegrounds. + ASSERT(false); + return NULL; +} + +OutdoorPvP* ScriptMgr::CreateOutdoorPvP(OutdoorPvPData const* data) +{ + ASSERT(data); + + GET_SCRIPT_RET(OutdoorPvPScript, data->ScriptId, tmpscript, NULL); + return tmpscript->GetOutdoorPvP(); +} + +std::vector<ChatCommand*> ScriptMgr::GetChatCommands() +{ + std::vector<ChatCommand*> table; + + FOR_SCRIPTS_RET(CommandScript, itr, end, table) + table.push_back(itr->second->GetCommands()); + + return table; +} + +void ScriptMgr::OnWeatherChange(Weather* weather, WeatherState state, float grade) +{ + ASSERT(weather); + + GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript); + tmpscript->OnChange(weather, state, grade); +} + +void ScriptMgr::OnWeatherUpdate(Weather* weather, uint32 diff) +{ + ASSERT(weather); + + GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript); + tmpscript->OnUpdate(weather, diff); +} + +void ScriptMgr::OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry) +{ + ASSERT(ah); + ASSERT(entry); + + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionAdd(ah, entry); +} + +void ScriptMgr::OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry) +{ + ASSERT(ah); + ASSERT(entry); + + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionRemove(ah, entry); +} + +void ScriptMgr::OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry) +{ + ASSERT(ah); + ASSERT(entry); + + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionSuccessful(ah, entry); +} + +void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry) +{ + ASSERT(ah); + ASSERT(entry); + + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry); +} + +bool ScriptMgr::OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo) +{ + ASSERT(condition); + + GET_SCRIPT_RET(ConditionScript, condition->ScriptId, tmpscript, true); + return tmpscript->OnConditionCheck(condition, sourceInfo); +} + +void ScriptMgr::OnInstall(Vehicle* veh) +{ + ASSERT(veh); + ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); + + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); + tmpscript->OnInstall(veh); +} + +void ScriptMgr::OnUninstall(Vehicle* veh) +{ + ASSERT(veh); + ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); + + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); + tmpscript->OnUninstall(veh); +} + +void ScriptMgr::OnReset(Vehicle* veh) +{ + ASSERT(veh); + ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); + + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); + tmpscript->OnReset(veh); +} + +void ScriptMgr::OnInstallAccessory(Vehicle* veh, Creature* accessory) +{ + ASSERT(veh); + ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); + ASSERT(accessory); + + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); + tmpscript->OnInstallAccessory(veh, accessory); +} + +void ScriptMgr::OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId) +{ + ASSERT(veh); + ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); + ASSERT(passenger); + + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); + tmpscript->OnAddPassenger(veh, passenger, seatId); +} + +void ScriptMgr::OnRemovePassenger(Vehicle* veh, Unit* passenger) +{ + ASSERT(veh); + ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); + ASSERT(passenger); + + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); + tmpscript->OnRemovePassenger(veh, passenger); +} + +void ScriptMgr::OnDynamicObjectUpdate(DynamicObject* dynobj, uint32 diff) +{ + ASSERT(dynobj); + + FOR_SCRIPTS(DynamicObjectScript, itr, end) + itr->second->OnUpdate(dynobj, diff); +} + +void ScriptMgr::OnAddPassenger(Transport* transport, Player* player) +{ + ASSERT(transport); + ASSERT(player); + + GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript); + tmpscript->OnAddPassenger(transport, player); +} + +void ScriptMgr::OnAddCreaturePassenger(Transport* transport, Creature* creature) +{ + ASSERT(transport); + ASSERT(creature); + + GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript); + tmpscript->OnAddCreaturePassenger(transport, creature); +} + +void ScriptMgr::OnRemovePassenger(Transport* transport, Player* player) +{ + ASSERT(transport); + ASSERT(player); + + GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript); + tmpscript->OnRemovePassenger(transport, player); +} + +void ScriptMgr::OnTransportUpdate(Transport* transport, uint32 diff) +{ + ASSERT(transport); + + GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript); + tmpscript->OnUpdate(transport, diff); +} + +void ScriptMgr::OnRelocate(Transport* transport, uint32 waypointId, uint32 mapId, float x, float y, float z) +{ + GET_SCRIPT(TransportScript, transport->GetScriptId(), tmpscript); + tmpscript->OnRelocate(transport, waypointId, mapId, x, y, z); +} + +void ScriptMgr::OnStartup() +{ + FOREACH_SCRIPT(WorldScript)->OnStartup(); +} + +void ScriptMgr::OnShutdown() +{ + FOREACH_SCRIPT(WorldScript)->OnShutdown(); +} + +bool ScriptMgr::OnCriteriaCheck(uint32 scriptId, Player* source, Unit* target) +{ + ASSERT(source); + // target can be NULL. + + GET_SCRIPT_RET(AchievementCriteriaScript, scriptId, tmpscript, false); + return tmpscript->OnCheck(source, target); +} + +// Player +void ScriptMgr::OnPVPKill(Player* killer, Player* killed) +{ + FOREACH_SCRIPT(PlayerScript)->OnPVPKill(killer, killed); +} + +void ScriptMgr::OnCreatureKill(Player* killer, Creature* killed) +{ + FOREACH_SCRIPT(PlayerScript)->OnCreatureKill(killer, killed); +} + +void ScriptMgr::OnPlayerKilledByCreature(Creature* killer, Player* killed) +{ + FOREACH_SCRIPT(PlayerScript)->OnPlayerKilledByCreature(killer, killed); +} + +void ScriptMgr::OnPlayerLevelChanged(Player* player, uint8 oldLevel) +{ + FOREACH_SCRIPT(PlayerScript)->OnLevelChanged(player, oldLevel); +} + +void ScriptMgr::OnPlayerFreeTalentPointsChanged(Player* player, uint32 points) +{ + FOREACH_SCRIPT(PlayerScript)->OnFreeTalentPointsChanged(player, points); +} + +void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost) +{ + FOREACH_SCRIPT(PlayerScript)->OnTalentsReset(player, noCost); +} + +void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount) +{ + FOREACH_SCRIPT(PlayerScript)->OnMoneyChanged(player, amount); +} + +void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim) +{ + FOREACH_SCRIPT(PlayerScript)->OnGiveXP(player, amount, victim); +} + +void ScriptMgr::OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental) +{ + FOREACH_SCRIPT(PlayerScript)->OnReputationChange(player, factionID, standing, incremental); +} + +void ScriptMgr::OnPlayerDuelRequest(Player* target, Player* challenger) +{ + FOREACH_SCRIPT(PlayerScript)->OnDuelRequest(target, challenger); +} + +void ScriptMgr::OnPlayerDuelStart(Player* player1, Player* player2) +{ + FOREACH_SCRIPT(PlayerScript)->OnDuelStart(player1, player2); +} + +void ScriptMgr::OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type) +{ + FOREACH_SCRIPT(PlayerScript)->OnDuelEnd(winner, loser, type); +} + +void ScriptMgr::OnPlayerEmote(Player* player, uint32 emote) +{ + FOREACH_SCRIPT(PlayerScript)->OnEmote(player, emote); +} + +void ScriptMgr::OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, uint64 guid) +{ + FOREACH_SCRIPT(PlayerScript)->OnTextEmote(player, textEmote, emoteNum, guid); +} + +void ScriptMgr::OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck) +{ + FOREACH_SCRIPT(PlayerScript)->OnSpellCast(player, spell, skipCheck); +} + +void ScriptMgr::OnPlayerLogin(Player* player) +{ + FOREACH_SCRIPT(PlayerScript)->OnLogin(player); +} + +void ScriptMgr::OnPlayerLogout(Player* player) +{ + FOREACH_SCRIPT(PlayerScript)->OnLogout(player); +} + +void ScriptMgr::OnPlayerCreate(Player* player) +{ + FOREACH_SCRIPT(PlayerScript)->OnCreate(player); +} + +void ScriptMgr::OnPlayerDelete(uint64 guid) +{ + FOREACH_SCRIPT(PlayerScript)->OnDelete(guid); +} + +void ScriptMgr::OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent) +{ + FOREACH_SCRIPT(PlayerScript)->OnBindToInstance(player, difficulty, mapid, permanent); +} + +void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea) +{ + FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea); +} + +// Guild +void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank) +{ + FOREACH_SCRIPT(GuildScript)->OnAddMember(guild, player, plRank); +} + +void ScriptMgr::OnGuildRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool isKicked) +{ + FOREACH_SCRIPT(GuildScript)->OnRemoveMember(guild, player, isDisbanding, isKicked); +} + +void ScriptMgr::OnGuildMOTDChanged(Guild* guild, const std::string& newMotd) +{ + FOREACH_SCRIPT(GuildScript)->OnMOTDChanged(guild, newMotd); +} + +void ScriptMgr::OnGuildInfoChanged(Guild* guild, const std::string& newInfo) +{ + FOREACH_SCRIPT(GuildScript)->OnInfoChanged(guild, newInfo); +} + +void ScriptMgr::OnGuildCreate(Guild* guild, Player* leader, const std::string& name) +{ + FOREACH_SCRIPT(GuildScript)->OnCreate(guild, leader, name); +} + +void ScriptMgr::OnGuildDisband(Guild* guild) +{ + FOREACH_SCRIPT(GuildScript)->OnDisband(guild); +} + +void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair) +{ + FOREACH_SCRIPT(GuildScript)->OnMemberWitdrawMoney(guild, player, amount, isRepair); +} + +void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount) +{ + FOREACH_SCRIPT(GuildScript)->OnMemberDepositMoney(guild, player, amount); +} + +void ScriptMgr::OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, + bool isDestBank, uint8 destContainer, uint8 destSlotId) +{ + FOREACH_SCRIPT(GuildScript)->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); +} + +void ScriptMgr::OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) +{ + FOREACH_SCRIPT(GuildScript)->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); +} + +void ScriptMgr::OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) +{ + FOREACH_SCRIPT(GuildScript)->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); +} + +// Group +void ScriptMgr::OnGroupAddMember(Group* group, uint64 guid) +{ + ASSERT(group); + FOREACH_SCRIPT(GroupScript)->OnAddMember(group, guid); +} + +void ScriptMgr::OnGroupInviteMember(Group* group, uint64 guid) +{ + ASSERT(group); + FOREACH_SCRIPT(GroupScript)->OnInviteMember(group, guid); +} + +void ScriptMgr::OnGroupRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason) +{ + ASSERT(group); + FOREACH_SCRIPT(GroupScript)->OnRemoveMember(group, guid, method, kicker, reason); +} + +void ScriptMgr::OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) +{ + ASSERT(group); + FOREACH_SCRIPT(GroupScript)->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); +} + +void ScriptMgr::OnGroupDisband(Group* group) +{ + ASSERT(group); + FOREACH_SCRIPT(GroupScript)->OnDisband(group); +} + +SpellScriptLoader::SpellScriptLoader(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<SpellScriptLoader>::AddScript(this); +} + +ServerScript::ServerScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<ServerScript>::AddScript(this); +} + +WorldScript::WorldScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<WorldScript>::AddScript(this); +} + +FormulaScript::FormulaScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<FormulaScript>::AddScript(this); +} + +WorldMapScript::WorldMapScript(const char* name, uint32 mapId) + : ScriptObject(name), MapScript<Map>(mapId) +{ + if (GetEntry() && !GetEntry()->IsWorldMap()) + sLog->outError("WorldMapScript for map %u is invalid.", mapId); + + ScriptRegistry<WorldMapScript>::AddScript(this); +} + +InstanceMapScript::InstanceMapScript(const char* name, uint32 mapId) + : ScriptObject(name), MapScript<InstanceMap>(mapId) +{ + if (GetEntry() && !GetEntry()->IsDungeon()) + sLog->outError("InstanceMapScript for map %u is invalid.", mapId); + + ScriptRegistry<InstanceMapScript>::AddScript(this); +} + +BattlegroundMapScript::BattlegroundMapScript(const char* name, uint32 mapId) + : ScriptObject(name), MapScript<BattlegroundMap>(mapId) +{ + if (GetEntry() && !GetEntry()->IsBattleground()) + sLog->outError("BattlegroundMapScript for map %u is invalid.", mapId); + + ScriptRegistry<BattlegroundMapScript>::AddScript(this); +} + +ItemScript::ItemScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<ItemScript>::AddScript(this); +} + +CreatureScript::CreatureScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<CreatureScript>::AddScript(this); +} + +GameObjectScript::GameObjectScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<GameObjectScript>::AddScript(this); +} + +AreaTriggerScript::AreaTriggerScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<AreaTriggerScript>::AddScript(this); +} + +BattlegroundScript::BattlegroundScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<BattlegroundScript>::AddScript(this); +} + +OutdoorPvPScript::OutdoorPvPScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<OutdoorPvPScript>::AddScript(this); +} + +CommandScript::CommandScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<CommandScript>::AddScript(this); +} + +WeatherScript::WeatherScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<WeatherScript>::AddScript(this); +} + +AuctionHouseScript::AuctionHouseScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<AuctionHouseScript>::AddScript(this); +} + +ConditionScript::ConditionScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<ConditionScript>::AddScript(this); +} + +VehicleScript::VehicleScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<VehicleScript>::AddScript(this); +} + +DynamicObjectScript::DynamicObjectScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<DynamicObjectScript>::AddScript(this); +} + +TransportScript::TransportScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<TransportScript>::AddScript(this); +} + +AchievementCriteriaScript::AchievementCriteriaScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<AchievementCriteriaScript>::AddScript(this); +} + +PlayerScript::PlayerScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<PlayerScript>::AddScript(this); +} + +GuildScript::GuildScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<GuildScript>::AddScript(this); +} + +GroupScript::GroupScript(const char* name) + : ScriptObject(name) +{ + ScriptRegistry<GroupScript>::AddScript(this); +} + +// Instantiate static members of ScriptRegistry. +template<class TScript> std::map<uint32, TScript*> ScriptRegistry<TScript>::ScriptPointerList; +template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0; + +// Specialize for each script type class like so: +template class ScriptRegistry<SpellScriptLoader>; +template class ScriptRegistry<ServerScript>; +template class ScriptRegistry<WorldScript>; +template class ScriptRegistry<FormulaScript>; +template class ScriptRegistry<WorldMapScript>; +template class ScriptRegistry<InstanceMapScript>; +template class ScriptRegistry<BattlegroundMapScript>; +template class ScriptRegistry<ItemScript>; +template class ScriptRegistry<CreatureScript>; +template class ScriptRegistry<GameObjectScript>; +template class ScriptRegistry<AreaTriggerScript>; +template class ScriptRegistry<BattlegroundScript>; +template class ScriptRegistry<OutdoorPvPScript>; +template class ScriptRegistry<CommandScript>; +template class ScriptRegistry<WeatherScript>; +template class ScriptRegistry<AuctionHouseScript>; +template class ScriptRegistry<ConditionScript>; +template class ScriptRegistry<VehicleScript>; +template class ScriptRegistry<DynamicObjectScript>; +template class ScriptRegistry<TransportScript>; +template class ScriptRegistry<AchievementCriteriaScript>; +template class ScriptRegistry<PlayerScript>; +template class ScriptRegistry<GuildScript>; +template class ScriptRegistry<GroupScript>; + +// Undefine utility macros. +#undef GET_SCRIPT_RET +#undef GET_SCRIPT +#undef FOREACH_SCRIPT +#undef FOR_SCRIPTS_RET +#undef FOR_SCRIPTS +#undef SCR_REG_LST +#undef SCR_REG_ITR +#undef SCR_REG_MAP |