aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/CreatureAISelector.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp106
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp2
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp18
-rw-r--r--src/server/game/Chat/Chat.cpp25
-rw-r--r--src/server/game/Chat/Chat.h5
-rw-r--r--src/server/game/Chat/Commands/Debugcmds.cpp4
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp80
-rw-r--r--src/server/game/Conditions/ConditionMgr.h5
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/DynamicObject/DynamicObject.cpp3
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/Item/Item.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp5
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp16
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.cpp20
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp139
-rw-r--r--src/server/game/Maps/Map.h10
-rw-r--r--src/server/game/Miscellaneous/Formulas.h161
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h9
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvP.h3
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp106
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.h4
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp1282
-rw-r--r--src/server/game/Scripting/ScriptMgr.h1006
-rw-r--r--src/server/game/Scripting/ScriptSystem.h2
-rw-r--r--src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp47
-rw-r--r--src/server/game/Server/Protocol/Handlers/MiscHandler.cpp10
-rw-r--r--src/server/game/Server/Protocol/Handlers/NPCHandler.cpp2
-rw-r--r--src/server/game/Server/Protocol/Handlers/QuestHandler.cpp20
-rw-r--r--src/server/game/Server/Protocol/Handlers/SpellHandler.cpp7
-rw-r--r--src/server/game/Server/WorldSession.cpp11
-rw-r--r--src/server/game/Server/WorldSession.h9
-rw-r--r--src/server/game/Server/WorldSocket.cpp14
-rw-r--r--src/server/game/Server/WorldSocketMgr.cpp13
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp3
-rw-r--r--src/server/game/Spells/SpellEffects.cpp8
-rw-r--r--src/server/game/Weather/Weather.cpp7
-rw-r--r--src/server/game/World/World.cpp51
-rw-r--r--src/server/game/World/World.h16
-rw-r--r--src/server/scripts/CMakeLists.txt2
-rw-r--r--src/server/scripts/Custom/on_events.cpp125
-rw-r--r--src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.h48
-rw-r--r--src/server/shared/Utilities/Util.h4
48 files changed, 2303 insertions, 1122 deletions
diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp
index 67e3e42f2ae..c2677953027 100644
--- a/src/server/game/AI/CreatureAISelector.cpp
+++ b/src/server/game/AI/CreatureAISelector.cpp
@@ -40,7 +40,7 @@ namespace FactorySelector
//scriptname in db
if (!ai_factory)
- if (CreatureAI* scriptedAI = sScriptMgr.GetAI(creature))
+ if (CreatureAI* scriptedAI = sScriptMgr.GetCreatureAI(creature))
return scriptedAI;
// AIname in db
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 9ab9e06b624..c3b132026a1 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -16,7 +16,7 @@ struct TSpellSummary
{
uint8 Targets; // set of enum SelectTarget
uint8 Effects; // set of enum SelectEffect
-} *SpellSummary;
+} extern *SpellSummary;
void SummonList::DoZoneInCombat(uint32 entry)
{
@@ -309,91 +309,6 @@ bool ScriptedAI::CanCast(Unit* pTarget, SpellEntry const* pSpell, bool bTriggere
return true;
}
-void FillSpellSummary()
-{
- SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];
-
- SpellEntry const* pTempSpell;
-
- for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
- {
- SpellSummary[i].Effects = 0;
- SpellSummary[i].Targets = 0;
-
- pTempSpell = GetSpellStore()->LookupEntry(i);
- //This spell doesn't exist
- if (!pTempSpell)
- continue;
-
- for (uint32 j = 0; j < 3; ++j)
- {
- //Spell targets self
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);
-
- //Spell targets a single enemy
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
-
- //Spell targets AoE at enemy
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
-
- //Spell targets an enemy
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
-
- //Spell targets a single friend(or self)
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
-
- //Spell targets aoe friends
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
-
- //Spell targets any friend(or self)
- if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
- pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
- SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
-
- //Make sure that this spell includes a damage effect
- if (pTempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||
- pTempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||
- pTempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
- pTempSpell->Effect[j] == 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->Effect[j] == SPELL_EFFECT_HEAL ||
- pTempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||
- pTempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL ||
- (pTempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA && pTempSpell->EffectApplyAuraName[j] == 8))
- SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);
-
- //Make sure that this spell applies an aura
- if (pTempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA)
- SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
- }
- }
-}
-
void ScriptedAI::DoResetThreat()
{
if (!me->CanHaveThreatList() || me->getThreatManager().isThreatListEmpty())
@@ -702,25 +617,6 @@ void BossAI::SummonedCreatureDespawn(Creature *summon)
summons.Despawn(summon);
}
-#define GOBJECT(x) (const_cast<GameObjectInfo*>(GetGameObjectInfo(x)))
-
-void LoadOverridenSQLData()
-{
- GameObjectInfo *goInfo;
-
- // Sunwell Plateau : Kalecgos : Spectral Rift
- goInfo = GOBJECT(187055);
- if (goInfo)
- if (goInfo->type == GAMEOBJECT_TYPE_GOOBER)
- goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN
-
- // Naxxramas : Sapphiron Birth
- goInfo = GOBJECT(181356);
- if (goInfo)
- if (goInfo->type == GAMEOBJECT_TYPE_TRAP)
- goInfo->trap.radius = 50;
-}
-
// SD2 grid searchers.
Creature *GetClosestCreatureWithEntry(WorldObject *pSource, uint32 uiEntry, float fMaxSearchRange, bool bAlive)
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 9b27504c1b7..b4cd3f3eb9e 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -394,7 +394,7 @@ void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 Wait
void npc_escortAI::FillPointMovementListForCreature()
{
- std::vector<ScriptPointMove> const &pPointsEntries = pSystemMgr.GetPointMoveList(me->GetEntry());
+ std::vector<ScriptPointMove> const &pPointsEntries = sScriptSystemMgr.GetPointMoveList(me->GetEntry());
if (pPointsEntries.empty())
return;
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 112f1e25d3b..f50076554f1 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -24,9 +24,8 @@
#include "WorldSession.h"
#include "DatabaseEnv.h"
#include "SQLStorage.h"
-
#include "DBCStores.h"
-
+#include "ScriptMgr.h"
#include "AccountMgr.h"
#include "AuctionHouseMgr.h"
#include "Item.h"
@@ -231,7 +230,8 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
//does not clear ram
void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
-{ //return an item in auction to its owner by mail
+{
+ //return an item in auction to its owner by mail
Item *pItem = GetAItem(auction->item_guidlow);
if (!pItem)
return;
@@ -476,6 +476,7 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem
void AuctionHouseObject::AddAuction(AuctionEntry *ah)
{
ASSERT(ah);
+
AuctionsMap[ah->Id] = ah;
}
@@ -483,10 +484,12 @@ bool AuctionHouseObject::RemoveAuction(AuctionEntry *auction, uint32 item_templa
{
bool wasInMap = AuctionsMap.erase(auction->Id) ? true : false;
+ sScriptMgr.OnRemoveAuction(this, auction);
+
// we need to delete the entry, it is not referenced any more
delete auction;
return wasInMap;
- }
+}
void AuctionHouseObject::Update()
{
@@ -511,7 +514,8 @@ void AuctionHouseObject::Update()
{
uint32 tmpdata = result->Fetch()->GetUInt32();
expiredAuctions.push_back(tmpdata);
- } while (result->NextRow());
+ }
+ while (result->NextRow());
while (!expiredAuctions.empty())
{
@@ -528,7 +532,10 @@ void AuctionHouseObject::Update()
///- Either cancel the auction if there was no bidder
if (auction->bidder == 0)
+ {
auctionmgr.SendAuctionExpiredMail(auction);
+ sScriptMgr.OnAuctionExpire(this, auction);
+ }
///- Or perform the transaction
else
{
@@ -537,6 +544,7 @@ void AuctionHouseObject::Update()
//we send the money to the seller
auctionmgr.SendAuctionSuccessfulMail(auction);
auctionmgr.SendAuctionWonMail(auction);
+ sScriptMgr.OnAuctionSuccessful(this, auction);
}
///- In any case clear the auction
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index bce8644ffd8..26e07ab62c3 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -35,6 +35,7 @@
#include "Player.h"
#include "UpdateMask.h"
#include "SpellMgr.h"
+#include "ScriptMgr.h"
// Supported shift-links (client generated and server side)
// |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r
@@ -958,6 +959,15 @@ void ChatHandler::PSendSysMessage(const char *format, ...)
SendSysMessage(str);
}
+bool ChatHandler::ExecuteCommandInTables(std::vector<ChatCommand*>& tables, const char* text, const std::string& fullcmd)
+{
+ for (std::vector<ChatCommand*>::iterator it = tables.begin(); it != tables.end(); ++it)
+ if (ExecuteCommandInTable((*it), text, fullcmd))
+ return true;
+
+ return false;
+}
+
bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd)
{
char const* oldtext = text;
@@ -1091,10 +1101,7 @@ int ChatHandler::ParseCommands(const char* text)
std::string fullcmd = text;
if (m_session && m_session->GetSecurity() <= SEC_PLAYER && sWorld.getConfig(CONFIG_ALLOW_PLAYER_COMMANDS) == 0)
- return 0;
-
- if (m_session && !m_session->HandleOnPlayerChat(text))
- return 0;
+ return 0;
/// chat case (.command or !command format)
if (m_session)
@@ -1118,9 +1125,13 @@ int ChatHandler::ParseCommands(const char* text)
if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd))
{
- if (m_session && m_session->GetSecurity() == SEC_PLAYER)
- return 0;
- SendSysMessage(LANG_NO_CMD);
+ if (!ExecuteCommandInTables(sScriptMgr.GetChatCommands(), text, fullcmd))
+ {
+ if (m_session && m_session->GetSecurity() == SEC_PLAYER)
+ return 0;
+
+ SendSysMessage(LANG_NO_CMD);
+ }
}
return 1;
}
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 39f3eb416c1..cf3ef686f3e 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -23,6 +23,8 @@
#include "SharedDefines.h"
+#include <vector>
+
class ChatHandler;
class WorldSession;
class Creature;
@@ -96,7 +98,8 @@ class ChatHandler
void SendGlobalGMSysMessage(const char *str);
static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand);
- bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcommand);
+ bool ExecuteCommandInTables(std::vector<ChatCommand*>& tables, const char* text, const std::string& fullcmd);
+ bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd);
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
diff --git a/src/server/game/Chat/Commands/Debugcmds.cpp b/src/server/game/Chat/Commands/Debugcmds.cpp
index 64fa3efdcba..97a3777d73d 100644
--- a/src/server/game/Chat/Commands/Debugcmds.cpp
+++ b/src/server/game/Chat/Commands/Debugcmds.cpp
@@ -896,8 +896,8 @@ bool ChatHandler::HandleDebugItemExpireCommand(const char* args)
if (!i)
return false;
- m_session->GetPlayer()->DestroyItem(i->GetBagSlot(),i->GetSlot(), true);
- sScriptMgr.ItemExpire(m_session->GetPlayer(),i->GetProto());
+ m_session->GetPlayer()->DestroyItem(i->GetBagSlot(), i->GetSlot(), true);
+ sScriptMgr.OnItemExpire(m_session->GetPlayer(), i->GetProto());
return true;
}
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 2ce666bede5..30dedf793de 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -28,6 +28,7 @@
#include "ProgressBar.h"
#include "InstanceData.h"
#include "ConditionMgr.h"
+#include "ScriptMgr.h"
// Checks if player meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
@@ -38,10 +39,9 @@ bool Condition::Meets(Player * player, Unit* targetOverride)
sLog.outDebug("Condition player not found");
return false; // player not present, return false
}
- uint32 refId = 0;
+ uint32 refId = mConditionValue3;//value 3 can be a 'quick' reference
bool condMeets = false;
bool sendErrorMsg = false;
- refId = mConditionValue3;//value 3 can be a 'quick' reference
switch (mConditionType)
{
case CONDITION_NONE:
@@ -185,12 +185,15 @@ bool Condition::Meets(Player * player, Unit* targetOverride)
{
ConditionList ref = sConditionMgr.GetConditionReferences(refId);
refMeets = sConditionMgr.IsPlayerMeetToConditions(player, ref);
- }else refMeets = true;
+ }
+ else
+ refMeets = true;
if (sendErrorMsg && ErrorTextd && (!condMeets || !refMeets))//send special error from DB
player->m_ConditionErrorMsgId = ErrorTextd;
- return condMeets && refMeets;
+ bool script = sScriptMgr.OnConditionCheck(this, player, targetOverride); // Returns true by default.
+ return condMeets && refMeets && script;
}
ConditionMgr::ConditionMgr()
@@ -232,11 +235,15 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player,const ConditionLis
{
if(!IsPlayerMeetToConditionList(player, (*ref).second, targetOverride))
ElseGroupMap[(*i)->mElseGroup] = false;
- }else{
- sLog.outDebug("IsPlayerMeetToConditionList: Reference template -%u not found", (*i)->mReferenceId);//checked at loading, should never happen
+ }
+ else
+ {
+ sLog.outDebug("IsPlayerMeetToConditionList: Reference template -%u not found",
+ (*i)->mReferenceId);//checked at loading, should never happen
}
- } else//handle normal condition
+ }
+ else //handle normal condition
{
if (!(*i)->Meets(player, targetOverride))
ElseGroupMap[(*i)->mElseGroup] = false;
@@ -246,6 +253,7 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player,const ConditionLis
for (std::map<uint32, bool>::const_iterator i = ElseGroupMap.begin(); i != ElseGroupMap.end(); ++i)
if (i->second)
return true;
+
return false;
}
@@ -253,6 +261,7 @@ bool ConditionMgr::IsPlayerMeetToConditions(Player* player, ConditionList condit
{
if (conditions.empty())
return true;
+
if(player)
player->m_ConditionErrorMsgId = 0;
@@ -373,7 +382,8 @@ void ConditionMgr::LoadConditions(bool isReload)
sLog.outErrorDb("Condition %s %i has useless data in SourceGroup (%u)!", rowType, iSourceTypeOrReferenceId, cond->mSourceGroup);
if (cond->mSourceEntry && iSourceTypeOrReferenceId < 0)
sLog.outErrorDb("Condition %s %i has useless data in SourceEntry (%u)!", rowType, iSourceTypeOrReferenceId, cond->mSourceEntry);
- }else if (!isConditionTypeValid(cond))//doesn't have reference, validate ConditionType
+ }
+ else if (!isConditionTypeValid(cond))//doesn't have reference, validate ConditionType
{
delete cond;
continue;
@@ -407,7 +417,8 @@ void ConditionMgr::LoadConditions(bool isReload)
sLog.outErrorDb("Condition type %u has not allowed grouping %u!", uint32(cond->mSourceType), cond->mSourceGroup);
delete cond;
continue;
- }else if (cond->mSourceGroup)
+ }
+ else if (cond->mSourceGroup)
{
bool bIsDone = false;
//handle grouped conditions
@@ -456,6 +467,7 @@ void ConditionMgr::LoadConditions(bool isReload)
bIsDone = addToGossipMenuItems(cond);
break;
}
+
if (!bIsDone)
{
sLog.outErrorDb("Not handled grouped condition, SourceGroup %u", cond->mSourceGroup);
@@ -501,8 +513,10 @@ bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot)
sLog.outErrorDb("ConditionMgr: LootTemplate %u not found", cond->mSourceGroup);
return false;
}
+
if (loot->addConditionItem(cond))
return true;
+
sLog.outErrorDb("ConditionMgr: Item %u not found in LootTemplate %u", cond->mSourceEntry, cond->mSourceGroup);
return false;
}
@@ -522,6 +536,7 @@ bool ConditionMgr::addToGossipMenus(Condition* cond)
}
}
}
+
sLog.outErrorDb("addToGossipMenus: GossipMenu %u not found", cond->mSourceGroup);
return false;
}
@@ -540,6 +555,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond)
}
}
}
+
sLog.outErrorDb("addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->mSourceGroup, cond->mSourceEntry);
return false;
}
@@ -551,6 +567,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("Invalid ConditionSourceType %u in `condition` table, ignoring.", uint32(cond->mSourceType));
return false;
}
+
switch (cond->mSourceType)
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE:
@@ -560,6 +577,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Creature.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -576,6 +594,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Disenchant.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -592,6 +611,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Fishing.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -608,6 +628,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Gameobject.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -624,6 +645,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Item.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -640,6 +662,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Mail.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -656,6 +679,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Milling.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -672,6 +696,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Pickpocketing.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -688,6 +713,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Prospecting.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -704,6 +730,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Reference.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -720,6 +747,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Skinning.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -736,6 +764,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->mSourceGroup);
return false;
}
+
LootTemplate* loot = LootTemplates_Spell.GetLootForConditionFill(cond->mSourceGroup);
ItemPrototype const* pItemProto = sItemStorage.LookupEntry<ItemPrototype>(cond->mSourceEntry);
if (!pItemProto && !loot->isReference(cond->mSourceEntry))
@@ -752,8 +781,8 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceEntry %u in `condition` table, has ConditionType %u. Only CONDITION_SPELL_SCRIPT_TARGET(18) is valid for CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET(14), ignoring.", cond->mSourceEntry, uint32(cond->mConditionType));
return false;
}
- SpellEntry const* spellProto = sSpellStore.LookupEntry(cond->mSourceEntry);
+ SpellEntry const* spellProto = sSpellStore.LookupEntry(cond->mSourceEntry);
if (!spellProto)
{
sLog.outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
@@ -819,12 +848,14 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
sLog.outErrorDb("SourceEntry %u in `condition` table, has ConditionType %u. Only CONDITION_ITEM_TARGET(24) is valid for CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET(18), ignoring.", cond->mSourceEntry, uint32(cond->mConditionType));
return false;
}
+
ItemPrototype const *pItemProto = objmgr.GetItemPrototype(cond->mSourceEntry);
if (!pItemProto)
{
sLog.outErrorDb("SourceEntry %u in `condition` table, does not exist in `item_tamplate`, ignoring.", cond->mSourceEntry);
return false;
}
+
bool bIsItemSpellValid = false;
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
@@ -848,6 +879,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
break;
}
}
+
if (bIsItemSpellValid)
break;
}
@@ -867,6 +899,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
case CONDITION_SOURCE_TYPE_NONE:
break;
}
+
return true;
}
bool ConditionMgr::isConditionTypeValid(Condition* cond)
@@ -876,6 +909,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring.", uint32(cond->mConditionType),cond->mSourceEntry);
return false;
}
+
switch (cond->mConditionType)
{
case CONDITION_AURA:
@@ -885,6 +919,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Aura condition has non existing spell (Id: %d), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2 > 2)
{
sLog.outErrorDb("Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->mConditionValue2);
@@ -900,6 +935,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Item condition has non existing item (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (!cond->mConditionValue2)
{
sLog.outErrorDb("Item condition has 0 set for item count in value2 (%u), skipped", cond->mConditionValue2);
@@ -915,6 +951,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("ItemEquipped condition has non existing item (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("ItemEquipped condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -927,11 +964,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Zone condition has non existing area (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (areaEntry->zone != 0)
{
sLog.outErrorDb("Zone condition requires to be in area (%u) which is a subzone but zone expected, skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Zone condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -953,6 +992,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Team condition specifies unknown team (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Team condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -965,6 +1005,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Skill condition specifies non-existing skill (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2 < 1 || cond->mConditionValue2 > sWorld.GetConfigMaxSkillValue())
{
sLog.outErrorDb("Skill condition specifies invalid skill value (%u), skipped", cond->mConditionValue2);
@@ -982,6 +1023,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Quest condition specifies non-existing quest (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -990,6 +1032,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->mConditionValue1)
sLog.outErrorDb("Quest condition has useless data in value1 (%u)!", cond->mConditionValue1);
+
if (cond->mConditionValue2)
sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1001,6 +1044,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Aura condition has non existing spell (Id: %d), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2 > 2)
{
sLog.outErrorDb("Aura condition has non existing effect index (%u) in value2 (must be 0..2), skipped", cond->mConditionValue2);
@@ -1016,6 +1060,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Active event condition has non existing event id (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Active event condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1028,6 +1073,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Achivemen condition has non existing achivement id (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Achivemen condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1039,6 +1085,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Class condition has non existing class (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Class condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1050,6 +1097,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Race condition has non existing race (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Race condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1061,6 +1109,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("SpellTarget condition has non existing spell target type (%u), skipped", cond->mConditionValue1);
return false;
}
+
switch(cond->mConditionValue1)
{
case SPELL_TARGET_TYPE_GAMEOBJECT:
@@ -1081,8 +1130,8 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("SpellTarget condition has non existing creature template entry (%u) as target, skipped", cond->mConditionValue2);
return false;
}
- const CreatureInfo* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(cond->mConditionValue2);
+ const CreatureInfo* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(cond->mConditionValue2);
if (cond->mSourceEntry == 30427 && !cInfo->SkinLootId)
{
sLog.outErrorDb("SpellTarget condition has creature entry %u as a target of spellid 30427, but this creature has no skinlootid. Gas extraction will not work!, skipped", cond->mConditionValue2);
@@ -1091,6 +1140,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
break;
}
}
+
if (cond->mConditionValue3)
sLog.outErrorDb("SpellTarget condition has useless data in value3 (%u)!", cond->mConditionValue3);
break;
@@ -1102,6 +1152,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("CreatureTarget condition has non existing creature template entry (%u) as target, skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("CreatureTarget condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1113,6 +1164,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("TargetHealthBelowPct condition has invalid data in value1 (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("TargetHealthBelowPct condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1134,6 +1186,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("Map condition has non existing map (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (cond->mConditionValue2)
sLog.outErrorDb("Map condition has useless data in value2 (%u)!", cond->mConditionValue2);
break;
@@ -1145,11 +1198,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog.outErrorDb("ItemTarget condition has incorrect target type (%u), skipped", cond->mConditionValue1);
return false;
}
+
if (!cond->mConditionValue2 && !sCreatureStorage.LookupEntry<CreatureInfo>(cond->mConditionValue2))
{
sLog.outErrorDb("ItemTarget condition has non existing creature template entry (%u) as target, skipped", cond->mConditionValue2);
return false;
}
+
if (cond->mConditionValue3)
sLog.outErrorDb("ItemTarget condition has useless data in value3 (%u)!", cond->mConditionValue3);
break;
@@ -1169,6 +1224,7 @@ void ConditionMgr::Clean()
delete *it;
itr->second.clear();
}
+
m_ConditionReferenceMap.clear();
for (ConditionMap::iterator itr = m_ConditionMap.begin(); itr != m_ConditionMap.end(); ++itr)
@@ -1181,10 +1237,12 @@ void ConditionMgr::Clean()
}
itr->second.clear();
}
+
m_ConditionMap.clear();
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
for (std::list<Condition*>::const_iterator itr = m_AllocatedMemory.begin(); itr != m_AllocatedMemory.end(); ++itr)
delete *itr;
+
m_AllocatedMemory.clear();
}
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 11c148783ea..aec59b32da1 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -111,6 +111,7 @@ struct Condition
ErrorTextd = 0;
mScriptId = 0;
}
+
bool Meets(Player * player, Unit* targetOverride = NULL);
bool isLoaded() { return mConditionType > CONDITION_NONE || mReferenceId; }
};
@@ -125,9 +126,9 @@ class ConditionMgr
{
friend class ACE_Singleton<ConditionMgr, ACE_Null_Mutex>;
ConditionMgr();
+ ~ConditionMgr();
public:
- ~ConditionMgr();
void LoadConditions(bool isReload = false);
bool isConditionTypeValid(Condition* cond);
@@ -137,10 +138,12 @@ class ConditionMgr
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sType, uint32 uEntry);
protected:
+
ConditionMap m_ConditionMap;
ConditionReferenceMap m_ConditionReferenceMap;
private:
+
bool isSourceTypeValid(Condition* cond);
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
bool addToGossipMenus(Condition* cond);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 57802f058c4..0d0542b37aa 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -588,6 +588,8 @@ void Creature::Update(uint32 diff)
default:
break;
}
+
+ sScriptMgr.OnCreatureUpdate(this, diff);
}
void Creature::RegenerateMana()
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index 529710eda90..f83b3e5ecc7 100644
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -27,6 +27,7 @@
#include "GridNotifiers.h"
#include "CellImpl.h"
#include "GridNotifiersImpl.h"
+#include "ScriptMgr.h"
DynamicObject::DynamicObject() : WorldObject()
{
@@ -143,6 +144,8 @@ void DynamicObject::Update(uint32 p_time)
caster->RemoveDynObjectWithGUID(GetGUID());
Delete();
}
+ else
+ sScriptMgr.OnDynamicObjectUpdate(this, p_time);
}
void DynamicObject::Delete()
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 026dd8b1a32..32f26a3dc52 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -526,6 +526,8 @@ void GameObject::Update(uint32 diff)
break;
}
}
+
+ sScriptMgr.OnGameObjectUpdate(this, diff);
}
void GameObject::Refresh()
@@ -1602,7 +1604,7 @@ void GameObject::TakenDamage(uint32 damage, Unit *who)
if (BattleGround* bg = pwho->GetBattleGround())
bg->DestroyGate(pwho, this, m_goInfo->building.destroyedEvent);
hitType = BG_OBJECT_DMG_HIT_TYPE_JUST_DESTROYED;
- sScriptMgr.GODestroyed(pwho, this, m_goInfo->building.destroyedEvent);
+ sScriptMgr.OnGameObjectDestroyed(pwho, this, m_goInfo->building.destroyedEvent);
}
if (pwho)
if (BattleGround* bg = pwho->GetBattleGround())
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 6efc320d3d2..2b4e751b80a 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -292,7 +292,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
if (GetUInt32Value(ITEM_FIELD_DURATION) <= diff)
{
- sScriptMgr.ItemExpire(owner, GetProto());
+ sScriptMgr.OnItemExpire(owner, GetProto());
owner->DestroyItem(GetBagSlot(), GetSlot(), true);
return;
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d4e7196a16e..7abb307bd33 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2642,7 +2642,7 @@ void Player::GiveXP(uint32 xp, Unit* victim)
level = getLevel();
nextLvlXP = GetUInt32Value(PLAYER_NEXT_LEVEL_XP);
}
- newXP = GetSession()->HandleOnGetXP(newXP);
+
SetUInt32Value(PLAYER_XP, newXP);
}
@@ -6363,10 +6363,7 @@ void Player::CheckAreaExploreAndOutdoor()
if (!m_AreaID)
m_AreaID = GetAreaId();
if (m_AreaID != GetAreaId())
- {
m_AreaID = GetAreaId();
- GetSession()->HandleOnAreaChange(GetAreaEntryByAreaID(m_AreaID));
- }
bool isOutdoor;
uint16 areaFlag = GetBaseMap()->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ(), &isOutdoor);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 2d6690bd817..e8dd8f8fc0c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1443,7 +1443,6 @@ class Player : public Unit, public GridObject<Player>
uint32 GetMoney() { return GetUInt32Value (PLAYER_FIELD_COINAGE); }
void ModifyMoney(int32 d)
{
- d = GetSession()->HandleOnGetMoney(d);
if (d < 0)
SetMoney (GetMoney() > uint32(-d) ? GetMoney() + d : 0);
else
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index d4bccbc2979..5e5eecea068 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -19,16 +19,14 @@
*/
#include "Common.h"
-
#include "Transport.h"
#include "MapManager.h"
#include "ObjectMgr.h"
#include "Path.h"
-
+#include "ScriptMgr.h"
#include "WorldPacket.h"
#include "DBCStores.h"
#include "ProgressBar.h"
-
#include "World.h"
void MapManager::LoadTransports()
@@ -115,7 +113,8 @@ void MapManager::LoadTransports()
}
++count;
- } while (result->NextRow());
+ }
+ while (result->NextRow());
sLog.outString();
sLog.outString(">> Loaded %u transports", count);
@@ -529,6 +528,8 @@ bool Transport::AddPassenger(Player* passenger)
{
if (m_passengers.insert(passenger).second)
sLog.outDetail("Player %s boarded transport %s.", passenger->GetName(), GetName());
+
+ sScriptMgr.OnAddPassenger(this, passenger);
return true;
}
@@ -536,10 +537,12 @@ bool Transport::RemovePassenger(Player* passenger)
{
if (m_passengers.erase(passenger))
sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), GetName());
+
+ sScriptMgr.OnRemovePassenger(this, passenger);
return true;
}
-void Transport::Update(uint32 /*p_time*/)
+void Transport::Update(uint32 p_diff)
{
if (m_WayPoints.size() <= 1)
return;
@@ -572,6 +575,8 @@ void Transport::Update(uint32 /*p_time*/)
if ((sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES) == 0)
sLog.outDetail("%s moved to %d %f %f %f %d", this->m_name.c_str(), m_curr->second.id, m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid);
+
+ sScriptMgr.OnTransportUpdate(this, p_diff);
}
}
@@ -676,6 +681,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
currenttguid = std::max(tguid,currenttguid);
pCreature->SetGUIDTransport(tguid);
+ sScriptMgr.OnAddCreaturePassenger(this, pCreature);
return tguid;
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index f361d1ba95a..002f456bb77 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -724,13 +724,11 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
{
Player *killer = this->ToPlayer();
Player *killed = pVictim->ToPlayer();
- killer->GetSession()->HandleOnPVPKill(killed);
}
if (pVictim->GetTypeId() == TYPEID_UNIT && this->GetTypeId() == TYPEID_PLAYER)
{
Player *killer = this->ToPlayer();
Creature *pCreature = (pVictim->ToCreature());
- killer->GetSession()->HandleOnCreatureKill(pCreature);
}
}
else // if (health <= damage)
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 818cbd67904..e92e488de3d 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -23,7 +23,7 @@
#include "Unit.h"
#include "Util.h"
#include "WorldPacket.h"
-
+#include "ScriptMgr.h"
#include "CreatureAI.h"
#include "ZoneScript.h"
@@ -108,6 +108,8 @@ void Vehicle::Install()
}
Reset();
+
+ sScriptMgr.OnInstall(this);
}
void Vehicle::InstallAllAccessories()
@@ -127,7 +129,10 @@ void Vehicle::Uninstall()
if (Unit *passenger = itr->second.passenger)
if (passenger->HasUnitTypeMask(UNIT_MASK_ACCESSORY))
passenger->ToTempSummon()->UnSummon();
+
RemoveAllPassengers();
+
+ sScriptMgr.OnUninstall(this);
}
void Vehicle::Die()
@@ -137,7 +142,10 @@ void Vehicle::Die()
if (Unit *passenger = itr->second.passenger)
if (passenger->HasUnitTypeMask(UNIT_MASK_ACCESSORY))
passenger->setDeathState(JUST_DIED);
+
RemoveAllPassengers();
+
+ sScriptMgr.OnDie(this);
}
void Vehicle::Reset()
@@ -154,6 +162,8 @@ void Vehicle::Reset()
if (m_usableSeatNum)
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
}
+
+ sScriptMgr.OnReset(this);
}
void Vehicle::RemoveAllPassengers()
@@ -237,6 +247,8 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion)
accessory->EnterVehicle(this, seatId);
// This is not good, we have to send update twice
accessory->SendMovementFlagUpdate();
+
+ sScriptMgr.OnInstallAccessory(this, accessory);
}
}
@@ -317,9 +329,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
}
}
- //if (unit->GetTypeId() == TYPEID_PLAYER)
- // unit->ToPlayer()->SendTeleportAckPacket();
- //unit->SendMovementFlagUpdate();
+ sScriptMgr.OnAddPassenger(this, unit, seatId);
return true;
}
@@ -366,6 +376,8 @@ void Vehicle::RemovePassenger(Unit *unit)
// only for flyable vehicles
if (unit->HasUnitMovementFlag(MOVEMENTFLAG_FLYING))
me->CastSpell(unit, 45472, true); // Parachute
+
+ sScriptMgr.OnRemovePassenger(this, unit);
}
void Vehicle::RelocatePassengers(float x, float y, float z, float ang)
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 5b811d54fe2..5bc83ee4e5f 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -8765,8 +8765,6 @@ void ObjectMgr::LoadScriptNames()
barGoLink bar(result->GetRowCount());
- //OnEvent Changes
- m_scriptNames.push_back("scripted_on_events");
uint32 count = 1;
do
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index eed56efd026..6a4e02a9d1b 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -41,7 +41,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "GossipDef.h"
-
+#include "ScriptMgr.h"
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
#include "VMapFactory.h"
@@ -62,6 +62,9 @@ struct ScriptAction
Map::~Map()
{
+ if (!Instanceable())
+ sScriptMgr.OnDestroyMap(this);
+
UnloadAll();
while (!i_worldObjects.empty())
@@ -169,6 +172,8 @@ void Map::LoadMap(int gx,int gy, bool reload)
sLog.outDetail("Unloading previously loaded map %u before reloading.",GetId());
delete (GridMaps[gx][gy]);
GridMaps[gx][gy]=NULL;
+
+ sScriptMgr.OnUnloadGridMap(this, gx, gy);
}
// map file name
@@ -184,6 +189,8 @@ void Map::LoadMap(int gx,int gy, bool reload)
sLog.outError("Error loading map file: \n %s\n", tmp);
}
delete [] tmp;
+
+ sScriptMgr.OnLoadGridMap(this, gx, gy);
}
void Map::LoadMapAndVMap(int gx,int gy)
@@ -229,6 +236,9 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
+
+ if (!Instanceable())
+ sScriptMgr.OnCreateMap(this);
}
void Map::InitVisibilityDistance()
@@ -437,6 +447,7 @@ bool Map::Add(Player *player)
player->m_clientGUIDs.clear();
player->UpdateObjectVisibility(true);
+ sScriptMgr.OnPlayerEnter(this, player);
return true;
}
@@ -480,102 +491,6 @@ Map::Add(T *obj)
obj->UpdateObjectVisibility(true);
}
-/*
-void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self)
-{
- CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
-
- if (p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
- {
- sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- if (!loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)))
- return;
-
- Trinity::MessageDeliverer post_man(*player, msg, to_self);
- TypeContainerVisitor<Trinity::MessageDeliverer, WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this, *player, GetVisibilityDistance());
-}
-
-void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg)
-{
- CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
-
- if (p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
- {
- sLog.outError("Map::MessageBroadcast: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- if (!loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)))
- return;
-
- //TODO: currently on continents when Visibility.Distance.InFlight > Visibility.Distance.Continents
- //we have alot of blinking mobs because monster move packet send is broken...
- Trinity::ObjectMessageDeliverer post_man(*obj,msg);
- TypeContainerVisitor<Trinity::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this, *obj, GetVisibilityDistance());
-}
-
-void Map::MessageDistBroadcast(Player *player, WorldPacket *msg, float dist, bool to_self, bool own_team_only)
-{
- CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY());
-
- if (p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
- {
- sLog.outError("Map::MessageBroadcast: Player (GUID: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- if (!loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)))
- return;
-
- Trinity::MessageDistDeliverer post_man(*player, msg, dist, to_self, own_team_only);
- TypeContainerVisitor<Trinity::MessageDistDeliverer , WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this, *player, dist);
-}
-
-void Map::MessageDistBroadcast(WorldObject *obj, WorldPacket *msg, float dist)
-{
- CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY());
-
- if (p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
- {
- sLog.outError("Map::MessageBroadcast: Object (GUID: %u TypeId: %u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
- return;
- }
-
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- if (!loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)))
- return;
-
- Trinity::ObjectMessageDistDeliverer post_man(*obj, msg, dist);
- TypeContainerVisitor<Trinity::ObjectMessageDistDeliverer, WorldTypeMapContainer > message(post_man);
- CellLock<ReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, message, *this, *obj, dist);
-}
-*/
-
bool Map::loaded(const GridPair &p) const
{
return (getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord));
@@ -704,6 +619,8 @@ void Map::Update(const uint32 &t_diff)
if (!m_mapRefManager.isEmpty() || !m_activeNonPlayers.empty())
ProcessRelocationNotifies(t_diff);
+
+ sScriptMgr.OnMapUpdate(this, t_diff);
}
struct ResetNotifier
@@ -821,6 +738,8 @@ void Map::Remove(Player *player, bool remove)
if (remove)
DeleteFromWorld(player);
+
+ sScriptMgr.OnPlayerLeave(this, player);
}
template<class T>
@@ -1993,32 +1912,6 @@ void Map::UpdateObjectsVisibilityFor(Player* player, Cell cell, CellPair cellpai
// send data
notifier.SendToSelf();
}
-/*
-void Map::PlayerRelocationNotify(Player* player, Cell cell, CellPair cellpair)
-{
- Trinity::PlayerRelocationNotifier relocationNotifier(*player);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- TypeContainerVisitor<Trinity::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier);
- TypeContainerVisitor<Trinity::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
-
- cell.Visit(cellpair, p2grid_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
- cell.Visit(cellpair, p2world_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
-}
-
-void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair)
-{
- Trinity::CreatureRelocationNotifier relocationNotifier(*creature);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate(); // not trigger load unloaded grids at notifier call
-
- TypeContainerVisitor<Trinity::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
- TypeContainerVisitor<Trinity::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
-
- cell.Visit(cellpair, c2world_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
- cell.Visit(cellpair, c2grid_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
-}
-*/
void Map::SendInitSelf(Player * player)
{
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 0d34244ad5f..251415b2d97 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -248,6 +248,8 @@ class Map : public GridRefManager<NGridType>
Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
virtual ~Map();
+ MapEntry const* GetEntry() const { return i_mapEntry; }
+
// currently unused for normal maps
bool CanUnload(uint32 diff)
{
@@ -264,13 +266,6 @@ class Map : public GridRefManager<NGridType>
virtual void Update(const uint32&);
- /*
- void MessageBroadcast(Player *, WorldPacket *, bool to_self);
- void MessageBroadcast(WorldObject *, WorldPacket *);
- void MessageDistBroadcast(Player *, WorldPacket *, float dist, bool to_self, bool own_team_only = false);
- void MessageDistBroadcast(WorldObject *, WorldPacket *, float dist);
- */
-
float GetVisibilityDistance() const { return m_VisibleDistance; }
//function for setting up visibility distance for maps on per-type/per-Id basis
virtual void InitVisibilityDistance();
@@ -369,7 +364,6 @@ class Map : public GridRefManager<NGridType>
MapDifficulty const* GetMapDifficulty() const;
bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); }
- // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable
bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); }
bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h
index 8244e344275..bd73326852e 100644
--- a/src/server/game/Miscellaneous/Formulas.h
+++ b/src/server/game/Miscellaneous/Formulas.h
@@ -22,6 +22,8 @@
#define TRINITY_FORMULAS_H
#include "World.h"
+#include "SharedDefines.h"
+#include "ScriptMgr.h"
namespace Trinity
{
@@ -29,71 +31,108 @@ namespace Trinity
{
inline float hk_honor_at_level_f(uint8 level, uint32 count = 1)
{
- return count * level * 1.55f;
+ float honor = count * level * 1.55f;
+ sScriptMgr.OnHonorCalculation(honor, level, count);
+ return honor;
}
inline uint32 hk_honor_at_level(uint8 level, uint32 count = 1)
{
- return ceil(hk_honor_at_level_f(level, count));
+ uint32 honor = ceil(hk_honor_at_level_f(level, count));
+ sScriptMgr.OnHonorCalculation(honor, level, count);
+ return honor;
}
}
namespace XP
{
- enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
-
inline uint8 GetGrayLevel(uint8 pl_level)
{
+ uint8 level;
+
if (pl_level <= 5)
- return 0;
+ level = 0;
else if (pl_level <= 39)
- return pl_level - 5 - pl_level/10;
+ level = pl_level - 5 - pl_level / 10;
else if (pl_level <= 59)
- return pl_level - 1 - pl_level/5;
+ level = pl_level - 1 - pl_level / 5;
else
- return pl_level - 9;
+ level = pl_level - 9;
+
+ sScriptMgr.OnGetGrayLevel(level, pl_level);
+ return level;
}
inline XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
{
+ XPColorChar color;
+
if (mob_level >= pl_level + 5)
- return RED;
+ color = XP_RED;
else if (mob_level >= pl_level + 3)
- return ORANGE;
+ color = XP_ORANGE;
else if (mob_level >= pl_level - 2)
- return YELLOW;
+ color = XP_YELLOW;
else if (mob_level > GetGrayLevel(pl_level))
- return GREEN;
+ color = XP_GREEN;
else
- return GRAY;
+ color = XP_GRAY;
+
+ sScriptMgr.OnGetColorCode(color, pl_level, mob_level);
+ return color;
}
inline uint8 GetZeroDifference(uint8 pl_level)
{
- if (pl_level < 8) return 5;
- if (pl_level < 10) return 6;
- if (pl_level < 12) return 7;
- if (pl_level < 16) return 8;
- if (pl_level < 20) return 9;
- if (pl_level < 30) return 11;
- if (pl_level < 40) return 12;
- if (pl_level < 45) return 13;
- if (pl_level < 50) return 14;
- if (pl_level < 55) return 15;
- if (pl_level < 60) return 16;
- return 17;
+ uint8 diff;
+
+ if (pl_level < 8)
+ diff = 5;
+ else if (pl_level < 10)
+ diff = 6;
+ else if (pl_level < 12)
+ diff = 7;
+ else if (pl_level < 16)
+ diff = 8;
+ else if (pl_level < 20)
+ diff = 9;
+ else if (pl_level < 30)
+ diff = 11;
+ else if (pl_level < 40)
+ diff = 12;
+ else if (pl_level < 45)
+ diff = 13;
+ else if (pl_level < 50)
+ diff = 14;
+ else if (pl_level < 55)
+ diff = 15;
+ else if (pl_level < 60)
+ diff = 16;
+ else
+ diff = 17;
+
+ return diff;
}
inline uint32 BaseGain(uint8 pl_level, uint8 mob_level, ContentLevels content)
{
+ uint32 baseGain;
uint32 nBaseExp;
+
switch (content)
{
- case CONTENT_1_60: nBaseExp = 45; break;
- case CONTENT_61_70: nBaseExp = 235; break;
- case CONTENT_71_80: nBaseExp = 580; break;
+ case CONTENT_1_60:
+ nBaseExp = 45;
+ break;
+ case CONTENT_61_70:
+ nBaseExp = 235;
+ break;
+ case CONTENT_71_80:
+ nBaseExp = 580;
+ break;
default:
sLog.outError("BaseGain: Unsupported content level %u",content);
- nBaseExp = 45; break;
+ nBaseExp = 45;
+ break;
}
if (mob_level >= pl_level)
@@ -101,7 +140,8 @@ namespace Trinity
uint8 nLevelDiff = mob_level - pl_level;
if (nLevelDiff > 4)
nLevelDiff = 4;
- return ((pl_level*5 + nBaseExp) * (20 + nLevelDiff)/10 + 1)/2;
+
+ baseGain = ((pl_level * 5 + nBaseExp) * (20 + nLevelDiff) / 10 + 1) / 2;
}
else
{
@@ -109,41 +149,51 @@ namespace Trinity
if (mob_level > gray_level)
{
uint8 ZD = GetZeroDifference(pl_level);
- return (pl_level*5 + nBaseExp) * (ZD + mob_level - pl_level)/ZD;
+ baseGain = (pl_level * 5 + nBaseExp) * (ZD + mob_level - pl_level) / ZD;
}
- return 0;
+ else
+ baseGain = 0;
}
+
+ sScriptMgr.OnGetBaseGain(baseGain, pl_level, mob_level, content);
+ return baseGain;
}
inline uint32 Gain(Player *pl, Unit *u)
{
- if (u->GetTypeId() == TYPEID_UNIT && (
- ((Creature*)u)->isTotem() || ((Creature*)u)->isPet() ||
- (((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)))
- return 0;
-
- uint32 xp_gain = BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(),u->GetZoneId()));
- if (xp_gain == 0)
- return 0;
+ uint32 gain;
- //elites in instances have a 2.75x xp bonus instead of the regular 2x world bonus
- if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isElite())
+ if (u->GetTypeId() == TYPEID_UNIT &&
+ (((Creature*)u)->isTotem() || ((Creature*)u)->isPet() ||
+ (((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)))
+ gain = 0;
+ else
{
- if(u->GetMap() && u->GetMap()->IsDungeon())
- xp_gain *= 2.75;
- else
- xp_gain *= 2;
+ gain = BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(), u->GetZoneId()));
+
+ if (gain != 0 && u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isElite())
+ {
+ // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus.
+ if (u->GetMap() && u->GetMap()->IsDungeon())
+ gain *= 2.75;
+ else
+ gain *= 2;
+ }
}
- return uint32(xp_gain*sWorld.getRate(RATE_XP_KILL));
+ gain *= sWorld.getRate(RATE_XP_KILL);
+ sScriptMgr.OnGetGain(gain, pl, u);
+ return gain;
}
inline float xp_in_group_rate(uint32 count, bool isRaid)
{
+ float rate;
+
if (isRaid)
{
- // FIX ME: must apply decrease modifiers dependent from raid size
- return 1.0f;
+ // FIXME: Must apply decrease modifiers depending on raid size.
+ rate = 1.0f;
}
else
{
@@ -152,18 +202,21 @@ namespace Trinity
case 0:
case 1:
case 2:
- return 1.0f;
+ rate = 1.0f;
case 3:
- return 1.166f;
+ rate = 1.166f;
case 4:
- return 1.3f;
+ rate = 1.3f;
case 5:
default:
- return 1.4f;
+ rate = 1.4f;
}
}
+
+ sScriptMgr.OnGetGroupRate(rate, count, isRaid);
+ return rate;
}
}
}
-#endif
+#endif
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 07694a57577..c5e3594ed4c 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -2812,4 +2812,13 @@ enum TradeStatus
TRADE_STATUS_ONLY_CONJURED = 22 // You can only trade conjured items... (cross realm BG related).
};
+enum XPColorChar
+{
+ XP_RED,
+ XP_ORANGE,
+ XP_YELLOW,
+ XP_GREEN,
+ XP_GRAY
+};
+
#endif
diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h
index 530bb647903..e15880176f9 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvP.h
+++ b/src/server/game/OutdoorPvP/OutdoorPvP.h
@@ -33,10 +33,9 @@ enum OutdoorPvPTypes
OUTDOOR_PVP_ZM = 4,
OUTDOOR_PVP_SI = 5,
OUTDOOR_PVP_EP = 6,
- OUTDOOR_PVP_NR = 7,
};
-#define MAX_OUTDOORPVP_TYPES 8
+#define MAX_OUTDOORPVP_TYPES 7
const uint8 CapturePointArtKit[3] = {2, 1, 21};
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
index ba2df92bed9..89f2ce0c754 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
@@ -27,6 +27,7 @@
#include "Player.h"
#include "ProgressBar.h"
#include "DisableMgr.h"
+#include "ScriptMgr.h"
OutdoorPvPMgr::OutdoorPvPMgr()
{
@@ -40,91 +41,39 @@ OutdoorPvPMgr::~OutdoorPvPMgr()
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
delete *itr;
- for (OutdoorPvPDataSet::iterator itr = m_OutdoorPvPDatas.begin(); itr != m_OutdoorPvPDatas.end(); ++itr)
- delete *itr;
+ for (OutdoorPvPDataMap::iterator itr = m_OutdoorPvPDatas.begin(); itr != m_OutdoorPvPDatas.end(); ++itr)
+ delete itr->second;
}
void OutdoorPvPMgr::InitOutdoorPvP()
{
LoadTemplates();
- // create new opvp
- OutdoorPvP * pOP = new OutdoorPvPHP;
- // respawn, init variables
- if (!pOP->SetupOutdoorPvP())
- {
- sLog.outDebug("OutdoorPvP : HP init failed.");
- delete pOP;
- }
- else
- {
- m_OutdoorPvPSet.push_back(pOP);
- sLog.outDebug("OutdoorPvP : HP successfully initiated.");
- }
-
- pOP = new OutdoorPvPNA;
- // respawn, init variables
- if (!pOP->SetupOutdoorPvP())
- {
- sLog.outDebug("OutdoorPvP : NA init failed.");
- delete pOP;
- }
- else
- {
- m_OutdoorPvPSet.push_back(pOP);
- sLog.outDebug("OutdoorPvP : NA successfully initiated.");
- }
-
- pOP = new OutdoorPvPTF;
- // respawn, init variables
- if (!pOP->SetupOutdoorPvP())
- {
- sLog.outDebug("OutdoorPvP : TF init failed.");
- delete pOP;
- }
- else
+ OutdoorPvP* pvp;
+ for (uint8 i = 0; i < MAX_OUTDOORPVP_TYPES; ++i)
{
- m_OutdoorPvPSet.push_back(pOP);
- sLog.outDebug("OutdoorPvP : TF successfully initiated.");
- }
+ OutdoorPvPDataMap::iterator iter = m_OutdoorPvPDatas.find(OutdoorPvPTypes(i));
+ if (iter == m_OutdoorPvPDatas.end())
+ {
+ sLog.outErrorDb("Could not initialize OutdoorPvP object for type ID %u; no entry in database.", uint32(iter->first));
+ continue;
+ }
- pOP = new OutdoorPvPZM;
- // respawn, init variables
- if (!pOP->SetupOutdoorPvP())
- {
- sLog.outDebug("OutdoorPvP : ZM init failed.");
- delete pOP;
- }
- else
- {
- m_OutdoorPvPSet.push_back(pOP);
- sLog.outDebug("OutdoorPvP : ZM successfully initiated.");
- }
+ pvp = sScriptMgr.CreateOutdoorPvP(iter->second);
+ if (!pvp)
+ {
+ sLog.outError("Could not initialize OutdoorPvP object for type ID %u; got NULL pointer from script.", uint32(iter->first));
+ continue;
+ }
- pOP = new OutdoorPvPSI;
- // respawn, init variables
- if (!pOP->SetupOutdoorPvP())
- {
- sLog.outDebug("OutdoorPvP : SI init failed.");
- delete pOP;
- }
- else
- {
- m_OutdoorPvPSet.push_back(pOP);
- sLog.outDebug("OutdoorPvP : SI successfully initiated.");
- }
+ if (!pvp->SetupOutdoorPvP())
+ {
+ sLog.outError("Could not initialize OutdoorPvP object for type ID %u; SetupOutdoorPvP failed.", uint32(iter->first));
+ delete pvp;
+ continue;
+ }
- pOP = new OutdoorPvPEP;
- // respawn, init variables
- if (!pOP->SetupOutdoorPvP())
- {
- sLog.outDebug("OutdoorPvP : EP init failed.");
- delete pOP;
- }
- else
- {
- m_OutdoorPvPSet.push_back(pOP);
- sLog.outDebug("OutdoorPvP : EP successfully initiated.");
+ m_OutdoorPvPSet.push_back(pvp);
}
}
@@ -161,14 +110,15 @@ void OutdoorPvPMgr::LoadTemplates()
if (typeId >= MAX_OUTDOORPVP_TYPES)
{
- sLog.outError("Invalid OutdoorPvPTypes value %u in outdoorpvp_template; skipped.", typeId);
+ sLog.outErrorDb("Invalid OutdoorPvPTypes value %u in outdoorpvp_template; skipped.", typeId);
continue;
}
OutdoorPvPData data;
- data.TypeId = OutdoorPvPTypes(typeId);
+ OutdoorPvPTypes realTypeId = OutdoorPvPTypes(typeId);
+ data.TypeId = realTypeId;
data.ScriptId = objmgr.GetScriptId(fields[1].GetString());
- m_OutdoorPvPDatas.push_back(&data);
+ m_OutdoorPvPDatas[realTypeId] = &data;
++count;
}
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
index a1e8e3c9a6b..f140cbe421a 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h
@@ -85,7 +85,7 @@ class OutdoorPvPMgr
typedef std::vector<OutdoorPvP*> OutdoorPvPSet;
typedef std::map<uint32 /* zoneid */, OutdoorPvP*> OutdoorPvPMap;
- typedef std::vector<OutdoorPvPData*> OutdoorPvPDataSet;
+ typedef std::map<OutdoorPvPTypes, OutdoorPvPData*> OutdoorPvPDataMap;
private:
@@ -98,7 +98,7 @@ class OutdoorPvPMgr
OutdoorPvPMap m_OutdoorPvPMap;
// Holds the outdoor PvP templates
- OutdoorPvPDataSet m_OutdoorPvPDatas;
+ OutdoorPvPDataMap m_OutdoorPvPDatas;
// update interval
uint32 m_UpdateTimer;
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 5f6cce4917d..8e660f7116e 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -11,69 +11,34 @@
#include "ScriptLoader.h"
#include "ScriptSystem.h"
-int num_sc_scripts;
-Script *m_scripts[MAX_SCRIPTS];
-
-void FillSpellSummary();
-void LoadOverridenSQLData();
-
-void ScriptMgr::LoadDatabase()
-{
- pSystemMgr.LoadVersion();
- pSystemMgr.LoadScriptTexts();
- pSystemMgr.LoadScriptTextsCustom();
- pSystemMgr.LoadScriptWaypoints();
-}
-
-struct TSpellSummary {
- uint8 Targets; // set of enum SelectTarget
- uint8 Effects; // set of enum SelectEffect
-}extern *SpellSummary;
-
-ScriptMgr::ScriptMgr()
-{
-
-}
-ScriptMgr::~ScriptMgr()
-{
-
-}
-
-void ScriptMgr::ScriptsInit()
-{
- //Trinity Script startup
- /*sLog.outString(" _____ _ _ _ ____ _ _");
- sLog.outString("|_ _| __(_)_ __ (_) |_ _ _/ ___| ___ _ __(_)_ __ | |_ ");
- sLog.outString(" | || '__| | '_ \\| | __| | | \\___ \\ / __| \'__| | \'_ \\| __|");
- sLog.outString(" | || | | | | | | | |_| |_| |___) | (__| | | | |_) | |_ ");
- sLog.outString(" |_||_| |_|_| |_|_|\\__|\\__, |____/ \\___|_| |_| .__/ \\__|");
- sLog.outString(" |___/ |_| ");
- sLog.outString("");
- sLog.outString("");*/
-
- //Load database (must be called after SD2Config.SetSource).
- LoadDatabase();
-
- sLog.outString("Loading C++ scripts");
- barGoLink bar(1);
- bar.step();
- sLog.outString("");
-
- for (uint16 i =0; i<MAX_SCRIPTS; ++i)
- m_scripts[i]=NULL;
-
- FillSpellSummary();
-
- AddScripts();
-
- sLog.outString(">> Loaded %i C++ Scripts.", num_sc_scripts);
-
- sLog.outString(">> Load Overriden SQL Data.");
- LoadOverridenSQLData();
-}
-
-//*********************************
-//*** Functions used globally ***
+// Utility macros to refer to the script registry.
+#define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptMap
+#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_MAP(T)::iterator 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_MAP(T)::iterator 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;
void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget)
{
@@ -89,7 +54,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget)
return;
}
- const StringTextData* pData = pSystemMgr.GetTextData(iTextEntry);
+ const StringTextData* pData = sScriptSystemMgr.GetTextData(iTextEntry);
if (!pData)
{
@@ -102,9 +67,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget)
if (pData->uiSoundId)
{
if (GetSoundEntriesStore()->LookupEntry(pData->uiSoundId))
- {
pSource->SendPlaySound(pData->uiSoundId, false);
- }
else
sLog.outError("TSCR: DoScriptText entry %i tried to process invalid sound id %u.", iTextEntry, pData->uiSoundId);
}
@@ -117,7 +80,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget)
sLog.outError("TSCR: DoScriptText entry %i tried to process emote for invalid TypeId (%u).", iTextEntry, pSource->GetTypeId());
}
- switch(pData->uiType)
+ switch (pData->uiType)
{
case CHAT_TYPE_SAY:
pSource->MonsterSay(iTextEntry, pData->uiLanguage, pTarget ? pTarget->GetGUID() : 0);
@@ -132,437 +95,1122 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget)
pSource->MonsterTextEmote(iTextEntry, pTarget ? pTarget->GetGUID() : 0, true);
break;
case CHAT_TYPE_WHISPER:
- {
- if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
- pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID());
- else
- sLog.outError("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry);
- }
+ {
+ if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
+ pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID());
+ else
+ sLog.outError("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry);
+
break;
+ }
case CHAT_TYPE_BOSS_WHISPER:
- {
- if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
- pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID(), true);
- else
- sLog.outError("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry);
- }
+ {
+ if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
+ pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID(), true);
+ else
+ sLog.outError("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry);
+
break;
+ }
case CHAT_TYPE_ZONE_YELL:
pSource->MonsterYellToZone(iTextEntry, pData->uiLanguage, pTarget ? pTarget->GetGUID() : 0);
break;
}
}
-void Script::RegisterSelf()
+ScriptMgr::ScriptMgr()
+{
+}
+
+ScriptMgr::~ScriptMgr()
+{
+ #define SCR_CLEAR(T) \
+ FOR_SCRIPTS(T, itr, end) \
+ delete itr->second; \
+ SCR_REG_LST(T).clear();
+
+ // Clear scripts for every script type.
+ SCR_CLEAR(SpellHandlerScript);
+ SCR_CLEAR(AuraHandlerScript);
+ 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);
+
+ #undef SCR_CLEAR
+}
+
+void ScriptMgr::Initialize()
{
- // try to find scripts which try to use another script's allocated memory
- // that means didn't allocate memory for script
- for (uint16 i = 0; i < MAX_SCRIPTS; ++i)
+ LoadDatabase();
+
+ sLog.outString("Loading C++ scripts");
+ barGoLink bar(1);
+ bar.step();
+ sLog.outString("");
+
+ FillSpellSummary();
+ AddScripts();
+
+ sLog.outString(">> Loaded %u C++ scripts", GetScriptCount());
+}
+
+void ScriptMgr::LoadDatabase()
+{
+ sScriptSystemMgr.LoadVersion();
+ sScriptSystemMgr.LoadScriptTexts();
+ sScriptSystemMgr.LoadScriptTextsCustom();
+ sScriptSystemMgr.LoadScriptWaypoints();
+}
+
+struct TSpellSummary
+{
+ uint8 Targets; // set of enum SelectTarget
+ uint8 Effects; // set of enum SelectEffect
+} *SpellSummary;
+
+void ScriptMgr::FillSpellSummary()
+{
+ SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];
+
+ SpellEntry const* pTempSpell;
+
+ for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
{
- // somebody forgot to allocate memory for a script by a method like this: newscript = new Script
- if (m_scripts[i] == this)
+ SpellSummary[i].Effects = 0;
+ SpellSummary[i].Targets = 0;
+
+ pTempSpell = GetSpellStore()->LookupEntry(i);
+ //This spell doesn't exist
+ if (!pTempSpell)
+ continue;
+
+ for (uint32 j = 0; j < 3; ++j)
{
- sLog.outError("ScriptName: '%s' - Forgot to allocate memory, so this script and/or the script before that can't work.", Name.c_str());
- // don't register it
- // and don't delete it because its memory is used for another script
- return;
+ //Spell targets self
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);
+
+ //Spell targets a single enemy
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
+
+ //Spell targets AoE at enemy
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
+
+ //Spell targets an enemy
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ENEMY ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_DST_TARGET_ENEMY ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_SRC ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_AREA_ENEMY_DST ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_DEST_DYNOBJ_ENEMY)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
+
+ //Spell targets a single friend(or self)
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
+
+ //Spell targets aoe friends
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
+
+ //Spell targets any friend(or self)
+ if (pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_ALLY ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_TARGET_PARTY ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_CASTER ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_UNIT_PARTY_TARGET ||
+ pTempSpell->EffectImplicitTargetA[j] == TARGET_SRC_CASTER)
+ SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
+
+ //Make sure that this spell includes a damage effect
+ if (pTempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||
+ pTempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||
+ pTempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
+ pTempSpell->Effect[j] == 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->Effect[j] == SPELL_EFFECT_HEAL ||
+ pTempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||
+ pTempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL ||
+ (pTempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA && pTempSpell->EffectApplyAuraName[j] == 8))
+ SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);
+
+ //Make sure that this spell applies an aura
+ if (pTempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA)
+ SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
}
}
+}
- int id = GetScriptId(Name.c_str());
- if (id)
+void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::list<SpellScript *> & script_vector)
+{
+ SpellScriptsBounds bounds = objmgr.GetSpellScriptsBounds(spell_id);
+
+ for (SpellScriptsMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
{
- // try to find the script in assigned scripts
- bool IsExist = false;
- for (uint16 i = 0; i < MAX_SCRIPTS; ++i)
- {
- if (m_scripts[i])
- {
- // if the assigned script's name and the new script's name is the same
- if (m_scripts[i]->Name == Name)
- {
- IsExist = true;
- break;
- }
- }
- }
+ SpellHandlerScript* tmpscript = ScriptRegistry<SpellHandlerScript>::GetScriptById(itr->second);
+ if (!tmpscript)
+ continue;
- // if the script doesn't assigned -> assign it!
- if (!IsExist)
+ SpellScript* script = tmpscript->GetSpellScript();
+
+ if (!script)
{
- m_scripts[id] = this;
- ++num_sc_scripts;
+ sLog.outError("Spell script %s for spell %u returned a NULL SpellScript pointer!", tmpscript->ToString(), spell_id);
+ continue;
}
- // if the script is already assigned -> delete it!
- else
+
+ script_vector.push_back(script);
+ }
+}
+
+void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> > & script_vector)
+{
+ SpellScriptsBounds bounds = objmgr.GetSpellScriptsBounds(spell_id);
+ script_vector.reserve(std::distance(bounds.first, bounds.second));
+
+ for (SpellScriptsMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
+ {
+ SpellHandlerScript* tmpscript = ScriptRegistry<SpellHandlerScript>::GetScriptById(itr->second);
+ if (!tmpscript)
+ continue;
+
+ SpellScript* script = tmpscript->GetSpellScript();
+
+ if (!script)
{
- // TODO: write a better error message than this one :)
- sLog.outError("ScriptName: '%s' already assigned with the same ScriptName, so the script can't work.", Name.c_str());
- delete this;
+ sLog.outError("Spell script %s for spell %u returned a NULL SpellScript pointer!", tmpscript->ToString(), spell_id);
+ continue;
}
+
+ script_vector.push_back(std::make_pair(script, itr));
}
- else
- {
- if (Name.find("example") == std::string::npos)
- sLog.outErrorDb("TrinityScript: RegisterSelf, but script named %s does not have ScriptName assigned in database.",(this)->Name.c_str());
- delete this;
+}
+
+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::OnPacketReceive(WorldSocket* socket, WorldPacket& packet)
+{
+ ASSERT(socket);
+
+ FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, packet);
+}
+
+void ScriptMgr::OnPacketSend(WorldSocket* socket, WorldPacket& packet)
+{
+ ASSERT(socket);
+
+ FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, packet);
+}
+
+void ScriptMgr::OnUnknownPacketReceive(WorldSocket* socket, WorldPacket& packet)
+{
+ ASSERT(socket);
+
+ FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(socket, packet);
+}
+
+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::OnShutdown(ShutdownExitCode code, ShutdownMask mask)
+{
+ FOREACH_SCRIPT(WorldScript)->OnShutdown(code, mask);
+}
+
+void ScriptMgr::OnShutdownCancel()
+{
+ FOREACH_SCRIPT(WorldScript)->OnShutdownCancel();
+}
+
+void ScriptMgr::OnWorldUpdate(uint32 diff)
+{
+ FOREACH_SCRIPT(WorldScript)->OnUpdate(NULL, diff);
+}
+
+void ScriptMgr::OnHonorCalculation(float& honor, uint8 level, uint32 count)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnHonorCalculation(honor, level, count);
+}
+
+void ScriptMgr::OnHonorCalculation(uint32& honor, uint8 level, uint32 count)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnHonorCalculation(honor, level, count);
+}
+
+void ScriptMgr::OnGetGrayLevel(uint8& grayLevel, uint8 playerLevel)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnGetGrayLevel(grayLevel, playerLevel);
+}
+
+void ScriptMgr::OnGetColorCode(XPColorChar& color, uint8 playerLevel, uint8 mobLevel)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnGetColorCode(color, playerLevel, mobLevel);
+}
+
+void ScriptMgr::OnGetZeroDifference(uint8& diff, uint8 playerLevel)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnGetZeroDifference(diff, playerLevel);
+}
+
+void ScriptMgr::OnGetBaseGain(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnGetBaseGain(gain, playerLevel, mobLevel, content);
+}
+
+void ScriptMgr::OnGetGain(uint32& gain, Player* player, Unit* unit)
+{
+ ASSERT(player);
+ ASSERT(unit);
+
+ FOREACH_SCRIPT(FormulaScript)->OnGetGain(gain, player, unit);
+}
+
+void ScriptMgr::OnGetGroupRate(float& rate, uint32 count, bool isRaid)
+{
+ FOREACH_SCRIPT(FormulaScript)->OnGetGroupRate(rate, count, isRaid);
+}
+
+#define SCR_MAP_BGN(M,V,I,E,C,T) \
+ if (V->GetEntry()->T()) \
+ { \
+ FOR_SCRIPTS(M, I, E) \
+ { \
+ MapEntry const* C = I->second->GetEntry(); \
+ if (!C) \
+ continue; \
+ if (entry->MapID == V->GetId()) \
+ {
+
+#define SCR_MAP_END \
+ break; \
+ } \
+ } \
}
+
+void ScriptMgr::OnCreateMap(Map* map)
+{
+ ASSERT(map);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ 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::OnLogin(Player *pPlayer)
+void ScriptMgr::OnDestroyMap(Map* map)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnLogin) return;
- tmpscript->pOnLogin(pPlayer);
+ ASSERT(map);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ 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::OnLogout(Player *pPlayer)
+void ScriptMgr::OnLoadGridMap(Map* map, uint32 gx, uint32 gy)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnLogout) return;
- tmpscript->pOnLogout(pPlayer);
+ ASSERT(map);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ itr->second->OnLoadGridMap(map, gx, gy);
+ SCR_MAP_END;
+
+ SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
+ itr->second->OnLoadGridMap((InstanceMap*)map, gx, gy);
+ SCR_MAP_END;
+
+ SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleGround);
+ itr->second->OnLoadGridMap((BattleGroundMap*)map, gx, gy);
+ SCR_MAP_END;
}
-void ScriptMgr::OnPVPKill(Player *killer, Player *killed)
+void ScriptMgr::OnUnloadGridMap(Map* map, uint32 gx, uint32 gy)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnPVPKill) return;
- tmpscript->pOnPVPKill(killer, killed);
+ ASSERT(map);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ itr->second->OnUnloadGridMap(map, gx, gy);
+ SCR_MAP_END;
+
+ SCR_MAP_BGN(InstanceMapScript, map, itr, end, entry, IsDungeon);
+ itr->second->OnUnloadGridMap((InstanceMap*)map, gx, gy);
+ SCR_MAP_END;
+
+ SCR_MAP_BGN(BattlegroundMapScript, map, itr, end, entry, IsBattleGround);
+ itr->second->OnUnloadGridMap((BattleGroundMap*)map, gx, gy);
+ SCR_MAP_END;
}
-bool ScriptMgr::OnSpellCast (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGoTarget, uint32 i, SpellEntry const *spell)
+void ScriptMgr::OnPlayerEnter(Map* map, Player* player)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnSpellCast) return true;
- return tmpscript->pOnSpellCast(pUnitTarget,pItemTarget,pGoTarget,i,spell);
+ ASSERT(map);
+ ASSERT(player);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ 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;
}
-uint32 ScriptMgr::OnGetXP(Player *pPlayer, uint32 amount)
+void ScriptMgr::OnPlayerLeave(Map* map, Player* player)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnGetXP) return amount;
- return tmpscript->pOnGetXP(pPlayer,amount);
+ ASSERT(map);
+ ASSERT(player);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ 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;
}
-uint32 ScriptMgr::OnGetMoney(Player *pPlayer, int32 amount)
+void ScriptMgr::OnMapUpdate(Map* map, uint32 diff)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnGetMoney) return amount;
- return tmpscript->pOnGetMoney(pPlayer,amount);
+ ASSERT(map);
+
+ SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsContinent);
+ 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;
}
-bool ScriptMgr::OnPlayerChat(Player *pPlayer, const char *text)
+#undef SCR_MAP_BGN
+#undef SCR_MAP_END
+
+InstanceData* ScriptMgr::CreateInstanceData(InstanceMap* map)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnPlayerChat) return true;
- return tmpscript->pOnPlayerChat(pPlayer,text);
+ ASSERT(map);
+
+ GET_SCRIPT_RET(InstanceMapScript, map->GetScriptId(), tmpscript, NULL);
+ return tmpscript->OnGetInstanceData(map);
}
-void ScriptMgr::OnServerStartup()
+bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Item* target)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnServerStartup) return;
- tmpscript->pOnServerStartup();
+ ASSERT(caster);
+ ASSERT(target);
+
+ GET_SCRIPT_RET(ItemScript, target->GetProto()->ScriptId, tmpscript, false);
+ return tmpscript->OnDummyEffect(caster, spellId, effIndex, target);
}
-void ScriptMgr::OnServerShutdown()
+bool ScriptMgr::OnQuestAccept(Player* player, Item* item, Quest const* quest)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnServerShutdown) return;
- tmpscript->pOnServerShutdown();
+ ASSERT(player);
+ ASSERT(item);
+ ASSERT(quest);
+
+ GET_SCRIPT_RET(ItemScript, item->GetProto()->ScriptId, tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestAccept(player, item, quest);
}
-void ScriptMgr::OnAreaChange(Player *pPlayer, AreaTableEntry const *pArea)
+bool ScriptMgr::OnItemUse(Player* player, Item* item, SpellCastTargets const& targets)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnAreaChange) return;
- tmpscript->pOnAreaChange(pPlayer, pArea);
+ ASSERT(player);
+ ASSERT(item);
+
+ GET_SCRIPT_RET(ItemScript, item->GetProto()->ScriptId, tmpscript, false);
+ return tmpscript->OnUse(player, item, targets);
}
-bool ScriptMgr::OnItemClick (Player *pPlayer, Item *pItem)
+bool ScriptMgr::OnItemExpire(Player* player, ItemPrototype const* proto)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnItemClick) return true;
- return tmpscript->pOnItemClick(pPlayer,pItem);
+ ASSERT(player);
+ ASSERT(proto);
+
+ GET_SCRIPT_RET(ItemScript, proto->ScriptId, tmpscript, false);
+ return tmpscript->OnExpire(player, proto);
}
-bool ScriptMgr::OnItemOpen (Player *pPlayer, Item *pItem)
+bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Creature* target)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnItemOpen) return true;
- return tmpscript->pOnItemOpen(pPlayer,pItem);
+ ASSERT(caster);
+ ASSERT(target);
+
+ GET_SCRIPT_RET(CreatureScript, target->GetScriptId(), tmpscript, false);
+ return tmpscript->OnDummyEffect(caster, spellId, effIndex, target);
}
-bool ScriptMgr::OnGoClick (Player *pPlayer, GameObject *pGameObject)
+bool ScriptMgr::OnGossipHello(Player* player, Creature* creature)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnGoClick) return true;
- return tmpscript->pOnGoClick(pPlayer,pGameObject);
+ ASSERT(player);
+ ASSERT(creature);
+
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnGossipHello(player, creature);
}
-void ScriptMgr::OnCreatureKill (Player *pPlayer, Creature *pCreature)
+bool ScriptMgr::OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
{
- Script *tmpscript = m_scripts[GetScriptId("scripted_on_events")];
- if (!tmpscript || !tmpscript->pOnCreatureKill) return;
- tmpscript->pOnCreatureKill(pPlayer,pCreature);
+ ASSERT(player);
+ ASSERT(creature);
+
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnGossipSelect(player, creature, sender, action);
}
-char const* ScriptMgr::ScriptsVersion()
+bool ScriptMgr::OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code)
{
- return "Integrated Trinity Scripts";
+ ASSERT(player);
+ ASSERT(creature);
+ ASSERT(code);
+
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnGossipSelectCode(player, creature, sender, action, code);
}
-bool ScriptMgr::GossipHello (Player * pPlayer, Creature* pCreature)
+bool ScriptMgr::OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pGossipHello) return false;
+ ASSERT(player);
+ ASSERT(creature);
+ ASSERT(quest);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGossipHello(pPlayer, pCreature);
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestAccept(player, creature, quest);
}
-bool ScriptMgr::GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+bool ScriptMgr::OnQuestSelect(Player* player, Creature* creature, Quest const* quest)
{
- sLog.outDebug("TSCR: Gossip selection, sender: %d, action: %d", uiSender, uiAction);
+ ASSERT(player);
+ ASSERT(creature);
+ ASSERT(quest);
+
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestSelect(player, creature, quest);
+}
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pGossipSelect) return false;
+bool ScriptMgr::OnQuestComplete(Player* player, Creature* creature, Quest const* quest)
+{
+ ASSERT(player);
+ ASSERT(creature);
+ ASSERT(quest);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGossipSelect(pPlayer, pCreature, uiSender, uiAction);
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestComplete(player, creature, quest);
}
-bool ScriptMgr::GossipSelectWithCode(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction, const char* sCode)
+bool ScriptMgr::OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt)
{
- sLog.outDebug("TSCR: Gossip selection with code, sender: %d, action: %d", uiSender, uiAction);
+ ASSERT(player);
+ ASSERT(creature);
+ ASSERT(quest);
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pGossipSelectWithCode) return false;
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestReward(player, creature, quest, opt);
+}
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGossipSelectWithCode(pPlayer, pCreature, uiSender, uiAction, sCode);
+uint32 ScriptMgr::GetDialogStatus(Player* player, Creature* creature)
+{
+ ASSERT(player);
+ ASSERT(creature);
+
+ // TODO: 100 is a funny magic number to have hanging around here...
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, 100);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnDialogStatus(player, creature);
}
-bool ScriptMgr::GOSelect(Player* pPlayer, GameObject* pGO, uint32 uiSender, uint32 uiAction)
+CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature)
{
- if (!pGO)
- return false;
- sLog.outDebug("TSCR: Gossip selection, sender: %d, action: %d", uiSender, uiAction);
+ ASSERT(creature);
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript || !tmpscript->pGOSelect) return false;
+ GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, NULL);
+ return tmpscript->OnGetAI();
+}
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGOSelect(pPlayer, pGO, uiSender, uiAction);
+void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff)
+{
+ ASSERT(creature);
+
+ GET_SCRIPT(CreatureScript, creature->GetScriptId(), tmpscript);
+ tmpscript->OnUpdate(creature, diff);
}
-bool ScriptMgr::GOSelectWithCode(Player* pPlayer, GameObject* pGO, uint32 uiSender, uint32 uiAction, const char* sCode)
+bool ScriptMgr::OnGossipHello(Player* player, GameObject* go)
{
- if (!pGO)
- return false;
- sLog.outDebug("TSCR: Gossip selection, sender: %d, action: %d",uiSender, uiAction);
+ ASSERT(player);
+ ASSERT(go);
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript || !tmpscript->pGOSelectWithCode) return false;
+ GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnGossipHello(player, go);
+}
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGOSelectWithCode(pPlayer, pGO, uiSender ,uiAction, sCode);
+bool ScriptMgr::OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action)
+{
+ ASSERT(player);
+ ASSERT(go);
+
+ GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnGossipSelect(player, go, sender, action);
}
-bool ScriptMgr::QuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
+bool ScriptMgr::OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pQuestAccept) return false;
+ ASSERT(player);
+ ASSERT(go);
+ ASSERT(code);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pQuestAccept(pPlayer, pCreature, pQuest);
+ GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnGossipSelectCode(player, go, sender, action, code);
}
-bool ScriptMgr::QuestSelect(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
+bool ScriptMgr::OnQuestAccept(Player* player, GameObject* go, Quest const* quest)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pQuestSelect) return false;
+ ASSERT(player);
+ ASSERT(go);
+ ASSERT(quest);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pQuestSelect(pPlayer, pCreature, pQuest);
+ GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestAccept(player, go, quest);
}
-bool ScriptMgr::QuestComplete(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
+bool ScriptMgr::OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pQuestComplete) return false;
+ ASSERT(player);
+ ASSERT(go);
+ ASSERT(quest);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pQuestComplete(pPlayer, pCreature, pQuest);
+ GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnQuestReward(player, go, quest, opt);
}
-bool ScriptMgr::ChooseReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt)
+uint32 ScriptMgr::GetDialogStatus(Player* player, GameObject* go)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pChooseReward) return false;
+ ASSERT(player);
+ ASSERT(go);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pChooseReward(pPlayer, pCreature, pQuest, opt);
+ // TODO: 100 is a funny magic number to have hanging around here...
+ GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, 100);
+ player->PlayerTalkClass->ClearMenus();
+ return tmpscript->OnDialogStatus(player, go);
}
-uint32 ScriptMgr::NPCDialogStatus(Player* pPlayer, Creature* pCreature)
+void ScriptMgr::OnGameObjectDestroyed(Player* player, GameObject* go, uint32 eventId)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->pNPCDialogStatus) return 100;
+ ASSERT(player);
+ ASSERT(go);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pNPCDialogStatus(pPlayer, pCreature);
+ GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
+ tmpscript->OnDestroyed(player, go, eventId);
}
-uint32 ScriptMgr::GODialogStatus(Player* pPlayer, GameObject* pGO)
+void ScriptMgr::OnGameObjectUpdate(GameObject* go, uint32 diff)
{
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript || !tmpscript->pGODialogStatus) return 100;
+ ASSERT(go);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGODialogStatus(pPlayer, pGO);
+ GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript);
+ tmpscript->OnUpdate(go, diff);
}
-bool ScriptMgr::ItemHello(Player* pPlayer, Item* pItem, Quest const* pQuest)
+bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, GameObject* target)
{
- Script *tmpscript = m_scripts[pItem->GetProto()->ScriptId];
- if (!tmpscript || !tmpscript->pItemHello) return false;
+ ASSERT(caster);
+ ASSERT(target);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pItemHello(pPlayer, pItem, pQuest);
+ GET_SCRIPT_RET(GameObjectScript, target->GetScriptId(), tmpscript, false);
+ return tmpscript->OnDummyEffect(caster, spellId, effIndex, target);
}
-bool ScriptMgr::ItemQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest)
+bool ScriptMgr::OnTrigger(Player* player, AreaTriggerEntry const* trigger)
{
- Script *tmpscript = m_scripts[pItem->GetProto()->ScriptId];
- if (!tmpscript || !tmpscript->pItemQuestAccept) return false;
+ ASSERT(player);
+ ASSERT(trigger);
+
+ GET_SCRIPT_RET(AreaTriggerScript, trigger->id, tmpscript, false);
+ return tmpscript->OnTrigger(player, trigger);
+}
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pItemQuestAccept(pPlayer, pItem, pQuest);
+BattleGround* ScriptMgr::CreateBattleground(BattleGroundTypeId typeId)
+{
+ // TODO: Implement script-side battlegrounds.
+ ASSERT(false);
+ return NULL;
}
-bool ScriptMgr::GOHello(Player* pPlayer, GameObject* pGO)
+OutdoorPvP* ScriptMgr::CreateOutdoorPvP(OutdoorPvPData const* data)
{
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript || !tmpscript->pGOHello) return false;
+ ASSERT(data);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGOHello(pPlayer, pGO);
+ GET_SCRIPT_RET(OutdoorPvPScript, data->ScriptId, tmpscript, NULL);
+ return tmpscript->OnGetOutdoorPvP();
}
-bool ScriptMgr::GOQuestAccept(Player* pPlayer, GameObject* pGO, Quest const* pQuest)
+std::vector<ChatCommand*> ScriptMgr::GetChatCommands()
{
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript || !tmpscript->pGOQuestAccept) return false;
+ std::vector<ChatCommand*> table;
+
+ FOR_SCRIPTS_RET(CommandScript, itr, end, table)
+ table.push_back(itr->second->OnGetCommands());
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGOQuestAccept(pPlayer, pGO, pQuest);
+ return table;
}
-bool ScriptMgr::GOChooseReward(Player* pPlayer, GameObject* pGO, Quest const* pQuest, uint32 opt)
+void ScriptMgr::OnWeatherChange(Weather* weather, WeatherState state, float grade)
{
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript || !tmpscript->pGOChooseReward) return false;
+ ASSERT(weather);
- pPlayer->PlayerTalkClass->ClearMenus();
- return tmpscript->pGOChooseReward(pPlayer, pGO, pQuest, opt);
+ GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript);
+ tmpscript->OnChange(weather, state, grade);
}
-void ScriptMgr::GODestroyed(Player* pPlayer, GameObject* pGO, uint32 destroyedEvent)
+void ScriptMgr::OnWeatherUpdate(Weather* weather, uint32 diff)
{
- Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId];
- if (!tmpscript) return;
- tmpscript->pGODestroyed(pPlayer, pGO, destroyedEvent);
+ ASSERT(weather);
+
+ GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript);
+ tmpscript->OnUpdate(weather, diff);
}
-bool ScriptMgr::AreaTrigger(Player* pPlayer, AreaTriggerEntry const* atEntry)
+void ScriptMgr::OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry)
{
- Script *tmpscript = m_scripts[GetAreaTriggerScriptId(atEntry->id)];
- if (!tmpscript || !tmpscript->pAreaTrigger) return false;
+ ASSERT(ah);
+ ASSERT(entry);
- return tmpscript->pAreaTrigger(pPlayer, atEntry);
+ FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionAdd(ah, entry);
}
-CreatureAI* ScriptMgr::GetAI(Creature* pCreature)
+void ScriptMgr::OnRemoveAuction(AuctionHouseObject* ah, AuctionEntry* entry)
{
- Script *tmpscript = m_scripts[pCreature->GetScriptId()];
- if (!tmpscript || !tmpscript->GetAI) return NULL;
+ ASSERT(ah);
+ ASSERT(entry);
- return tmpscript->GetAI(pCreature);
+ FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionRemove(ah, entry);
}
-bool ScriptMgr::ItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
+void ScriptMgr::OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry)
{
- Script *tmpscript = m_scripts[pItem->GetProto()->ScriptId];
- if (!tmpscript || !tmpscript->pItemUse) return false;
+ ASSERT(ah);
+ ASSERT(entry);
- return tmpscript->pItemUse(pPlayer, pItem, targets);
+ FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionSuccessful(ah, entry);
}
-bool ScriptMgr::ItemExpire(Player* pPlayer, ItemPrototype const * pItemProto)
+void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry)
{
- Script *tmpscript = m_scripts[pItemProto->ScriptId];
- if (!tmpscript || !tmpscript->pItemExpire) return true;
+ ASSERT(ah);
+ ASSERT(entry);
- return tmpscript->pItemExpire(pPlayer, pItemProto);
+ FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry);
}
-bool ScriptMgr::EffectDummyCreature(Unit *caster, uint32 spellId, uint32 effIndex, Creature *crTarget)
+bool ScriptMgr::OnConditionCheck(Condition* condition, Player* player, Unit* targetOverride)
{
- Script *tmpscript = m_scripts[crTarget->GetScriptId()];
+ ASSERT(condition);
+ ASSERT(player);
+
+ GET_SCRIPT_RET(ConditionScript, condition->mScriptId, tmpscript, true);
+ return tmpscript->OnConditionCheck(condition, player, targetOverride);
+}
- if (!tmpscript || !tmpscript->pEffectDummyCreature) return false;
+void ScriptMgr::OnInstall(Vehicle* veh)
+{
+ ASSERT(veh);
- return tmpscript->pEffectDummyCreature(caster, spellId, effIndex, crTarget);
+ FOREACH_SCRIPT(VehicleScript)->OnInstall(veh);
}
-bool ScriptMgr::EffectDummyGameObj(Unit *caster, uint32 spellId, uint32 effIndex, GameObject *gameObjTarget)
+void ScriptMgr::OnUninstall(Vehicle* veh)
{
- Script *tmpscript = m_scripts[gameObjTarget->GetGOInfo()->ScriptId];
+ ASSERT(veh);
- if (!tmpscript || !tmpscript->pEffectDummyGameObj) return false;
+ FOREACH_SCRIPT(VehicleScript)->OnUninstall(veh);
+}
- return tmpscript->pEffectDummyGameObj(caster, spellId, effIndex, gameObjTarget);
+void ScriptMgr::OnDie(Vehicle* veh)
+{
+ ASSERT(veh);
+
+ FOREACH_SCRIPT(VehicleScript)->OnDie(veh);
}
-bool ScriptMgr::EffectDummyItem(Unit *caster, uint32 spellId, uint32 effIndex, Item *itemTarget)
+void ScriptMgr::OnReset(Vehicle* veh)
{
- Script *tmpscript = m_scripts[itemTarget->GetProto()->ScriptId];
+ ASSERT(veh);
+
+ FOREACH_SCRIPT(VehicleScript)->OnReset(veh);
+}
- if (!tmpscript || !tmpscript->pEffectDummyItem) return false;
+void ScriptMgr::OnInstallAccessory(Vehicle* veh, Creature* accessory)
+{
+ ASSERT(veh);
+ ASSERT(accessory);
- return tmpscript->pEffectDummyItem(caster, spellId, effIndex, itemTarget);
+ FOREACH_SCRIPT(VehicleScript)->OnInstallAccessory(veh, accessory);
}
-InstanceData* ScriptMgr::CreateInstanceData(Map *map)
+void ScriptMgr::OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId)
{
- if (!map->IsDungeon()) return NULL;
+ ASSERT(veh);
+ ASSERT(passenger);
- Script *tmpscript = m_scripts[((InstanceMap*)map)->GetScriptId()];
- if (!tmpscript || !tmpscript->GetInstanceData) return NULL;
+ FOREACH_SCRIPT(VehicleScript)->OnAddPassenger(veh, passenger, seatId);
+}
- return tmpscript->GetInstanceData(map);
+void ScriptMgr::OnRemovePassenger(Vehicle* veh, Unit* passenger)
+{
+ ASSERT(veh);
+ ASSERT(passenger);
+
+ FOREACH_SCRIPT(VehicleScript)->OnRemovePassenger(veh, passenger);
}
-void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::list<SpellScript *> & script_vector)
+void ScriptMgr::OnDynamicObjectUpdate(DynamicObject* dynobj, uint32 diff)
{
- SpellScriptsBounds bounds = objmgr.GetSpellScriptsBounds(spell_id);
- for (SpellScriptsMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
- {
- Script *tmpscript = m_scripts[itr->second];
- if (!tmpscript || !tmpscript->GetSpellScript) continue;
- script_vector.push_back(tmpscript->GetSpellScript());
- }
+ ASSERT(dynobj);
+
+ FOR_SCRIPTS(DynamicObjectScript, itr, end)
+ itr->second->OnUpdate(dynobj, diff);
}
-void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> > & script_vector)
+void ScriptMgr::OnAddPassenger(Transport* transport, Player* player)
{
- SpellScriptsBounds bounds = objmgr.GetSpellScriptsBounds(spell_id);
- script_vector.reserve(std::distance(bounds.first, bounds.second));
- for (SpellScriptsMap::iterator itr = bounds.first; itr != bounds.second; ++itr)
+ 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 SpellHandlerScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<SpellHandlerScript>::AddScript(this);
+}
+
+void AuraHandlerScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<AuraHandlerScript>::AddScript(this);
+}
+
+void ServerScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<ServerScript>::AddScript(this);
+}
+
+void WorldScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<WorldScript>::AddScript(this);
+}
+
+void FormulaScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<FormulaScript>::AddScript(this);
+}
+
+void WorldMapScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<WorldMapScript>::AddScript(this);
+}
+
+void InstanceMapScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<InstanceMapScript>::AddScript(this);
+}
+
+void BattlegroundMapScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<BattlegroundMapScript>::AddScript(this);
+}
+
+void AreaTriggerScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<AreaTriggerScript>::AddScript(this);
+}
+
+void ItemScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<ItemScript>::AddScript(this);
+}
+
+void CreatureScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<CreatureScript>::AddScript(this);
+}
+
+void GameObjectScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<GameObjectScript>::AddScript(this);
+}
+
+void BattlegroundScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<BattlegroundScript>::AddScript(this);
+}
+
+void OutdoorPvPScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<OutdoorPvPScript>::AddScript(this);
+}
+
+void CommandScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<CommandScript>::AddScript(this);
+}
+
+void WeatherScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<WeatherScript>::AddScript(this);
+}
+
+void AuctionHouseScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<AuctionHouseScript>::AddScript(this);
+}
+
+void ConditionScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<ConditionScript>::AddScript(this);
+}
+
+void VehicleScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<VehicleScript>::AddScript(this);
+}
+
+void DynamicObjectScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<DynamicObjectScript>::AddScript(this);
+}
+
+void TransportScript::RegisterSelf()
+{
+ ScriptMgr::ScriptRegistry<TransportScript>::AddScript(this);
+}
+
+template<class TScript>
+void ScriptMgr::ScriptRegistry<TScript>::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 (ScriptMap::iterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
{
- Script *tmpscript = m_scripts[itr->second];
- if (!tmpscript || !tmpscript->GetSpellScript) continue;
- script_vector.push_back(std::make_pair(tmpscript->GetSpellScript(), itr));
+ if (it->second == script)
+ {
+ sLog.outError("Script '%s' forgot to allocate memory, so this script and/or the script before that can't work.",
+ script->ToString());
+
+ return;
+ }
+ }
+
+ // 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 = GetScriptId(script->ToString());
+ if (id)
+ {
+ // Try to find an existing script.
+ bool existing = false;
+ for (ScriptMap::iterator 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->ToString());
+
+ delete script;
+ }
+ }
+ else if (script->IsDatabaseBound())
+ {
+ // The script uses a script name from database, but isn't assigned to anything.
+ if (script->GetName().find("example") == std::string::npos)
+ sLog.outErrorDb("Script named '%s' does not have a script name assigned in database.",
+ script->ToString());
+
+ delete script;
+ }
+ else
+ {
+ // We're dealing with a code-only script; just add it.
+ ScriptPointerList[_scriptIdCounter++] = script;
+ sScriptMgr.IncrementScriptCount();
}
}
+
+// Instantiate static members of ScriptMgr::ScriptRegistry.
+template<class TScript> std::map<uint32, TScript*> ScriptMgr::ScriptRegistry<TScript>::ScriptPointerList;
+template<class TScript> uint32 ScriptMgr::ScriptRegistry<TScript>::_scriptIdCounter;
+
+// Specialize for each script type class like so:
+template class ScriptMgr::ScriptRegistry<SpellHandlerScript>;
+template class ScriptMgr::ScriptRegistry<AuraHandlerScript>;
+template class ScriptMgr::ScriptRegistry<ServerScript>;
+template class ScriptMgr::ScriptRegistry<WorldScript>;
+template class ScriptMgr::ScriptRegistry<FormulaScript>;
+template class ScriptMgr::ScriptRegistry<WorldMapScript>;
+template class ScriptMgr::ScriptRegistry<InstanceMapScript>;
+template class ScriptMgr::ScriptRegistry<BattlegroundMapScript>;
+template class ScriptMgr::ScriptRegistry<ItemScript>;
+template class ScriptMgr::ScriptRegistry<CreatureScript>;
+template class ScriptMgr::ScriptRegistry<GameObjectScript>;
+template class ScriptMgr::ScriptRegistry<AreaTriggerScript>;
+template class ScriptMgr::ScriptRegistry<BattlegroundScript>;
+template class ScriptMgr::ScriptRegistry<OutdoorPvPScript>;
+template class ScriptMgr::ScriptRegistry<CommandScript>;
+template class ScriptMgr::ScriptRegistry<WeatherScript>;
+template class ScriptMgr::ScriptRegistry<AuctionHouseScript>;
+template class ScriptMgr::ScriptRegistry<ConditionScript>;
+template class ScriptMgr::ScriptRegistry<VehicleScript>;
+template class ScriptMgr::ScriptRegistry<DynamicObjectScript>;
+template class ScriptMgr::ScriptRegistry<TransportScript>;
+
+// 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_MAP
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 4ce6b403cea..64d8e92abea 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -13,6 +13,15 @@
#include "DBCStructure.h"
#include "Config.h"
#include "ObjectMgr.h"
+#include "BattleGround.h"
+#include "OutdoorPvPMgr.h"
+#include "SharedDefines.h"
+#include "Chat.h"
+#include "Weather.h"
+#include "AuctionHouseMgr.h"
+#include "ConditionMgr.h"
+#include "Vehicle.h"
+#include "Transport.h"
class Player;
class Creature;
@@ -28,134 +37,893 @@ class Unit;
class WorldObject;
struct ItemPrototype;
class Spell;
+class ScriptMgr;
+class WorldSocket;
-#define MAX_SCRIPTS 5000 //72 bytes each (approx 351kb)
#define VISIBLE_RANGE (166.0f) //MAX visible range (size of grid)
#define DEFAULT_TEXT "<Trinity Script Text Entry Missing!>"
-struct Script
-{
- Script() :
- pOnLogin(NULL), pOnLogout(NULL), pOnPVPKill(NULL), pOnSpellCast(NULL), pOnGetXP(NULL),
- pOnGetMoney(NULL), pOnPlayerChat(NULL), pOnServerStartup(NULL), pOnServerShutdown(NULL),
- pOnAreaChange(NULL), pOnItemClick(NULL), pOnItemOpen(NULL), pOnGoClick(NULL), pOnCreatureKill(NULL),
- pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
- pGOSelect(NULL), pGOSelectWithCode(NULL),
- pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL),
- pChooseReward(NULL), pGODestroyed(NULL), pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL),
- pGOQuestAccept(NULL), pGOChooseReward(NULL),pItemUse(NULL), pItemExpire(NULL),
- pEffectDummyCreature(NULL), pEffectDummyGameObj(NULL), pEffectDummyItem(NULL),
- GetAI(NULL), GetInstanceData(NULL), GetSpellScript(NULL)
- {}
-
- std::string Name;
-
- //Methods to be scripted
- void (*pOnLogin)(Player*);
- void (*pOnLogout)(Player*);
- void (*pOnPVPKill)(Player*, Player*);
- bool (*pOnSpellCast)(Unit*, Item*, GameObject*, uint32, SpellEntry const*);
- uint32 (*pOnGetXP)(Player*, uint32);
- int32 (*pOnGetMoney)(Player*, int32);
- bool (*pOnPlayerChat)(Player*, const char*);
- void (*pOnServerStartup)();
- void (*pOnServerShutdown)();
- void (*pOnAreaChange)(Player*, AreaTableEntry const*);
- bool (*pOnItemClick)(Player*, Item*);
- bool (*pOnItemOpen)(Player*, Item*);
- bool (*pOnGoClick)(Player*, GameObject*);
- void (*pOnCreatureKill)(Player*, Creature*);
- bool (*pGossipHello)(Player*, Creature*);
- bool (*pQuestAccept)(Player*, Creature*, Quest const*);
- bool (*pGossipSelect)(Player*, Creature*, uint32 , uint32);
- bool (*pGossipSelectWithCode)(Player*, Creature*, uint32 , uint32 , const char*);
- bool (*pGOSelect)(Player*, GameObject*, uint32 , uint32);
- bool (*pGOSelectWithCode)(Player*, GameObject*, uint32 , uint32 , const char*);
- bool (*pQuestSelect)(Player*, Creature*, Quest const*);
- bool (*pQuestComplete)(Player*, Creature*, Quest const*);
- uint32 (*pNPCDialogStatus)(Player*, Creature*);
- uint32 (*pGODialogStatus)(Player*, GameObject * _GO);
- bool (*pChooseReward)(Player*, Creature*, Quest const*, uint32);
- bool (*pItemHello)(Player*, Item*, Quest const*);
- bool (*pGOHello)(Player*, GameObject*);
- bool (*pAreaTrigger)(Player*, AreaTriggerEntry const*);
- bool (*pItemQuestAccept)(Player*, Item *, Quest const*);
- bool (*pGOQuestAccept)(Player*, GameObject*, Quest const*);
- bool (*pGOChooseReward)(Player*, GameObject*, Quest const*, uint32);
- void (*pGODestroyed)(Player*, GameObject*, uint32);
- bool (*pItemUse)(Player*, Item*, SpellCastTargets const&);
- bool (*pItemExpire)(Player*, ItemPrototype const *);
- bool (*pEffectDummyCreature)(Unit*, uint32, uint32, Creature*);
- bool (*pEffectDummyGameObj)(Unit*, uint32, uint32, GameObject*);
- bool (*pEffectDummyItem)(Unit*, uint32, uint32, Item*);
-
- CreatureAI* (*GetAI)(Creature*);
- InstanceData* (*GetInstanceData)(Map*);
-
- SpellScript*(*GetSpellScript)();
- //AuraScript*(*GetAuraScript)();
-
- void RegisterSelf();
+// Generic scripting text function.
+void DoScriptText(int32 textEntry, WorldObject* pSource, Unit *pTarget = NULL);
+
+/*
+ TODO: Add more script type classes.
+
+ ChatScript
+ MailScript
+ SessionScript
+ CollisionScript
+ GroupScript
+ ArenaTeamScript
+ GuildScript
+
+*/
+
+/*
+ Standard procedure when adding new script type classes:
+
+ First of all, define the actual class, and have it inherit from ScriptObject, like so:
+
+ class MyScriptType : public ScriptObject
+ {
+ uint32 _someId;
+
+ protected:
+
+ MyScriptType(const char* name, uint32 someId)
+ : ScriptObject(name), _someId(someId)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // If a virtual function in your script type class is not necessarily
+ // required to be overridden, just declare it virtual with an empty
+ // body. If, on the other hand, it's logical only to override it (i.e.
+ // if it's the only method in the class), make it pure virtual, by adding
+ // = 0 to it.
+ virtual void OnSomeEvent(uint32 someArg1, std::string& someArg2) { }
+
+ // This is a pure virtual function:
+ virtual void OnAnotherEvent(uint32 someArg) = 0;
+ }
+
+ RegisterSelf() should be defined in ScriptMgr.cpp, and simply registers the script
+ with ScriptRegistry:
+
+ void MyScriptType::RegisterSelf()
+ {
+ ScriptMgr::ScriptRegistry<MyScriptType>::AddScript(this);
+ }
+
+ Next, you need to add a specialization for ScriptRegistry. Put this in the bottom of
+ ScriptMgr.cpp:
+
+ template class ScriptMgr::ScriptRegistry<MyScriptType>;
+
+ Now, add a cleanup routine in ScriptMgr::~ScriptMgr:
+
+ SCR_CLEAR(MyScriptType);
+
+ Now your script type is good to go with the script system. What you need to do now
+ is add functions to ScriptMgr that can be called from the core to actually trigger
+ certain events. For example, in ScriptMgr.h:
+
+ void OnSomeEvent(uint32 someArg1, std::string& someArg2);
+ void OnAnotherEvent(uint32 someArg);
+
+ In ScriptMgr.cpp:
+
+ void ScriptMgr::OnSomeEvent(uint32 someArg1, std::string& someArg2)
+ {
+ FOREACH_SCRIPT(MyScriptType)->OnSomeEvent(someArg1, someArg2);
+ }
+
+ void ScriptMgr::OnAnotherEvent(uint32 someArg)
+ {
+ FOREACH_SCRIPT(MyScriptType)->OnAnotherEvent(someArg1, someArg2);
+ }
+
+ Now you simply call these two functions from anywhere in the core to trigger the
+ event on all registered scripts of that type.
+*/
+
+class ScriptObject
+{
+ friend class ScriptMgr;
+
+ public:
+
+ // Called when the script is initialized. Use it to initialize any properties of the script.
+ virtual void OnInitialize() { }
+
+ // Called when the script is deleted. Use it to free memory, etc.
+ virtual void OnTeardown() { }
+
+ // Do not override this in scripts; it should be overridden by the various script type classes. It indicates
+ // whether or not this script type must be assigned in the database.
+ virtual bool IsDatabaseBound() const { return false; }
+
+ const std::string& GetName() const { return _name; }
+
+ const char* ToString() const { return _name.c_str(); }
+
+ protected:
+
+ // Call this to register the script with ScriptMgr.
+ virtual void RegisterSelf() = 0;
+
+ ScriptObject(const char* name)
+ : _name(std::string(name))
+ {
+ // Allow the script to do startup routines.
+ OnInitialize();
+
+ // Register with ScriptMgr.
+ RegisterSelf();
+ }
+
+ virtual ~ScriptObject()
+ {
+ // Allow the script to do cleanup routines.
+ OnTeardown();
+ }
+
+ private:
+
+ const std::string _name;
+};
+
+template<class TObject> class UpdatableScript
+{
+ protected:
+
+ UpdatableScript()
+ {
+ }
+
+ public:
+
+ virtual void OnUpdate(TObject* obj, uint32 diff) { }
+};
+
+class SpellHandlerScript : public ScriptObject
+{
+ protected:
+
+ SpellHandlerScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Should return a fully valid SpellScript pointer.
+ virtual SpellScript* GetSpellScript() const = 0;
+};
+
+class AuraHandlerScript : public ScriptObject
+{
+ protected:
+
+ AuraHandlerScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Should return a fully valid AuraScript pointer.
+ // virtual AuraScript* GetAuraScript() const = 0;
+};
+
+class ServerScript : public ScriptObject
+{
+ protected:
+
+ ServerScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // Called when reactive socket I/O is started (WorldSocketMgr).
+ virtual void OnNetworkStart() { }
+
+ // Called when reactive I/O is stopped.
+ virtual void OnNetworkStop() { }
+
+ // Called when a remote socket establishes a connection to the server. Do not store the socket object.
+ virtual void OnSocketOpen(WorldSocket* socket) { }
+
+ // Called when a socket is closed. Do not store the socket object, and do not rely on the connection
+ // being open; it is not.
+ virtual void OnSocketClose(WorldSocket* socket, bool wasNew) { }
+
+ // Called when a packet is sent to a client. The packet object is a copy of the original packet, so reading
+ // and modifying it is safe.
+ virtual void OnPacketSend(WorldSocket* socket, WorldPacket& packet) { }
+
+ // Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so
+ // reading and modifying it is safe.
+ virtual void OnPacketReceive(WorldSocket* socket, WorldPacket& packet) { }
+
+ // Called when an invalid (unknown opcode) packet is received by a client. The packet is a reference to the orignal
+ // packet; not a copy. This allows you to actually handle unknown packets (for whatever purpose).
+ virtual void OnUnknownPacketReceive(WorldSocket* socket, WorldPacket& packet) { }
+};
+
+class WorldScript : public ScriptObject, public UpdatableScript<void>
+{
+ protected:
+
+ WorldScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // Called when the open/closed state of the world changes.
+ virtual void OnOpenStateChange(bool open) { }
+
+ // Called after the world configuration is (re)loaded.
+ virtual void OnConfigLoad(bool reload) { }
+
+ // Called before the message of the day is changed.
+ virtual void OnMotdChange(std::string& newMotd) { }
+
+ // Called when a world shutdown is initiated.
+ virtual void OnShutdown(ShutdownExitCode code, ShutdownMask mask) { }
+
+ // Called when a world shutdown is cancelled.
+ virtual void OnShutdownCancel() { }
+
+ // Called on every world tick (don't execute too heavy code here).
+ virtual void OnUpdate(void* null, uint32 diff) { }
+};
+
+class FormulaScript : public ScriptObject
+{
+ protected:
+
+ FormulaScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // Called after calculating honor.
+ virtual void OnHonorCalculation(float& honor, uint8 level, uint32 count) { }
+
+ // Called after calculating honor.
+ virtual void OnHonorCalculation(uint32& honor, uint8 level, uint32 count) { }
+
+ // Called after gray level calculation.
+ virtual void OnGetGrayLevel(uint8& grayLevel, uint8 playerLevel) { }
+
+ // Called after calculating experience color.
+ virtual void OnGetColorCode(XPColorChar& color, uint8 playerLevel, uint8 mobLevel) { }
+
+ // Called after calculating zero difference.
+ virtual void OnGetZeroDifference(uint8& diff, uint8 playerLevel) { }
+
+ // Called after calculating base experience gain.
+ virtual void OnGetBaseGain(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content) { }
+
+ // Called after calculating experience gain.
+ virtual void OnGetGain(uint32& gain, Player* player, Unit* unit) { }
+
+ virtual void OnGetGroupRate(float& rate, uint32 count, bool isRaid) { }
+};
+
+template<class TMap> class MapScript : public UpdatableScript<TMap>
+{
+ MapEntry const* _mapEntry;
+
+ protected:
+
+ MapScript(uint32 mapId)
+ : _mapEntry(sMapStore.LookupEntry(mapId))
+ {
+ if (!_mapEntry)
+ sLog.outError("Invalid MapScript for %u; no such map ID.", mapId);
+ }
+
+ public:
+
+ // Gets the MapEntry structure associated with this script. Can return NULL.
+ MapEntry const* GetEntry() { return _mapEntry; }
+
+ // Called when the map is created.
+ virtual void OnCreate(TMap* map) { }
+
+ // Called just before the map is destroyed.
+ virtual void OnDestroy(TMap* map) { }
+
+ // Called when a grid map is loaded.
+ virtual void OnLoadGridMap(TMap* map, uint32 gx, uint32 gy) { }
+
+ // Called when a grid map is unloaded.
+ virtual void OnUnloadGridMap(TMap* map, uint32 gx, uint32 gy) { }
+
+ // Called when a player enters the map.
+ virtual void OnPlayerEnter(TMap* map, Player* player) { }
+
+ // Called when a player leaves the map.
+ virtual void OnPlayerLeave(TMap* map, Player* player) { }
+
+ // Called on every map update tick.
+ virtual void OnUpdate(TMap* map, uint32 diff) { }
+};
+
+class WorldMapScript : public ScriptObject, public MapScript<Map>
+{
+ protected:
+
+ WorldMapScript(const char* name, uint32 mapId)
+ : ScriptObject(name), MapScript(mapId)
+ {
+ if (GetEntry() && !GetEntry()->IsContinent())
+ sLog.outError("WorldMapScript for map %u is invalid.", mapId);
+ }
+
+ void RegisterSelf();
+};
+
+class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
+{
+ protected:
+
+ InstanceMapScript(const char* name, uint32 mapId = 0)
+ : ScriptObject(name), MapScript(mapId)
+ {
+ if (GetEntry() && !GetEntry()->IsDungeon())
+ sLog.outError("InstanceMapScript for map %u is invalid.", mapId);
+ }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Gets an InstanceData object for this instance.
+ virtual InstanceData* OnGetInstanceData(InstanceMap* map) { return NULL; }
+};
+
+class BattlegroundMapScript : public ScriptObject, public MapScript<BattleGroundMap>
+{
+ protected:
+
+ BattlegroundMapScript(const char* name, uint32 mapId)
+ : ScriptObject(name), MapScript(mapId)
+ {
+ if (GetEntry() && !GetEntry()->IsBattleGround())
+ sLog.outError("BattlegroundMapScript for map %u is invalid.", mapId);
+ }
+
+ void RegisterSelf();
+};
+
+class ItemScript : public ScriptObject
+{
+ protected:
+
+ ItemScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when a dummy spell effect is triggered on the item.
+ virtual bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Item* target) { return false; }
+
+ // Called when a player accepts a quest from the item.
+ virtual bool OnQuestAccept(Player* player, Item* item, Quest const* quest) { return false; }
+
+ // Called when a player uses the item.
+ virtual bool OnUse(Player* player, Item* item, SpellCastTargets const& targets) { return false; }
+
+ // Called when the item expires (is destroyed).
+ virtual bool OnExpire(Player* player, ItemPrototype const* proto) { return false; }
+};
+
+class CreatureScript : public ScriptObject, public UpdatableScript<Creature>
+{
+ protected:
+
+ CreatureScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when a dummy spell effect is triggered on the creature.
+ virtual bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Creature* target) { return false; }
+
+ // Called when a player opens a gossip dialog with the creature.
+ virtual bool OnGossipHello(Player* player, Creature* creature) { return false; }
+
+ // Called when a player selects a gossip item in the creature's gossip menu.
+ virtual bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) { return false; }
+
+ // Called when a player selects a gossip with a code in the creature's gossip menu.
+ virtual bool OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code) { return false; }
+
+ // Called when a player accepts a quest from the creature.
+ virtual bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) { return false; }
+
+ // Called when a player selects a quest in the creature's quest menu.
+ virtual bool OnQuestSelect(Player* player, Creature* creature, Quest const* quest) { return false; }
+
+ // Called when a player completes a quest with the creature.
+ virtual bool OnQuestComplete(Player* player, Creature* creature, Quest const* quest) { return false; }
+
+ // Called when a player selects a quest reward.
+ virtual bool OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt) { return false; }
+
+ // Called when the dialog status between a player and the creature is requested.
+ virtual uint32 OnDialogStatus(Player* player, Creature* creature) { return 0; }
+
+ // Called when a CreatureAI object is needed for the creature.
+ virtual CreatureAI* OnGetAI() { return NULL; }
+};
+
+class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
+{
+ protected:
+
+ GameObjectScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when a dummy spell effect is triggered on the gameobject.
+ virtual bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, GameObject* target) { return false; }
+
+ // Called when a player opens a gossip dialog with the gameobject.
+ virtual bool OnGossipHello(Player* player, GameObject* go) { return false; }
+
+ // Called when a player selects a gossip item in the gameobject's gossip menu.
+ virtual bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action) { return false; }
+
+ // Called when a player selects a gossip with a code in the gameobject's gossip menu.
+ virtual bool OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code) { return false; }
+
+ // Called when a player accepts a quest from the gameobject.
+ virtual bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest) { return false; }
+
+ // Called when a player selects a quest reward.
+ virtual bool OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt) { return false; }
+
+ // Called when the dialog status between a player and the gameobject is requested.
+ virtual uint32 OnDialogStatus(Player* player, GameObject* go) { return 0; }
+
+ // Called when the gameobject is destroyed (destructible buildings only).
+ virtual void OnDestroyed(Player* player, GameObject* go, uint32 eventId) { }
+};
+
+class AreaTriggerScript : public ScriptObject
+{
+ protected:
+
+ AreaTriggerScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when the area trigger is activated by a player.
+ bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) { return false; }
+};
+
+class BattlegroundScript : public ScriptObject
+{
+ protected:
+
+ BattlegroundScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Should return a fully valid BattleGround object for the type ID.
+ virtual BattleGround* OnGetBattleground() = 0;
+};
+
+class OutdoorPvPScript : public ScriptObject
+{
+ protected:
+
+ OutdoorPvPScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Should return a fully valid OutdoorPvP object for the type ID.
+ virtual OutdoorPvP* OnGetOutdoorPvP() = 0;
+};
+
+class CommandScript : public ScriptObject
+{
+ protected:
+
+ CommandScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // Should return a pointer to a valid command table (ChatCommand array) to be used by ChatHandler.
+ virtual ChatCommand* OnGetCommands() = 0;
+};
+
+class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
+{
+ protected:
+
+ WeatherScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when the weather changes in the zone this script is associated with.
+ virtual void OnChange(Weather* weather, WeatherState state, float grade) { }
+};
+
+class AuctionHouseScript : public ScriptObject
+{
+ protected:
+
+ AuctionHouseScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // Called when an auction is added to an auction house.
+ void OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry) { }
+
+ // Called when an auction is removed from an auction house.
+ void OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry) { }
+
+ // Called when an auction was succesfully completed.
+ void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry) { }
+
+ // Called when an auction expires.
+ void OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry) { }
};
+class ConditionScript : public ScriptObject
+{
+ protected:
+
+ ConditionScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when a single condition is checked for a player.
+ bool OnConditionCheck(Condition* condition, Player* player, Unit* targetOverride) { return true; }
+};
+
+class VehicleScript : public ScriptObject
+{
+ protected:
+
+ VehicleScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+
+ public:
+
+ // Called after a vehicle is installed.
+ virtual void OnInstall(Vehicle* veh) { }
+
+ // Called after a vehicle is uninstalled.
+ virtual void OnUninstall(Vehicle* veh) { }
+
+ // Called after a vehicle dies.
+ virtual void OnDie(Vehicle* veh) { }
+
+ // Called when a vehicle resets.
+ virtual void OnReset(Vehicle* veh) { }
+
+ // Called after an accessory is installed in a vehicle.
+ virtual void OnInstallAccessory(Vehicle* veh, Creature* accessory) { }
+
+ // Called after a passenger is added to a vehicle.
+ virtual void OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId) { }
+
+ // Called after a passenger is removed from a vehicle.
+ virtual void OnRemovePassenger(Vehicle* veh, Unit* passenger) { }
+};
+
+class DynamicObjectScript : public ScriptObject, public UpdatableScript<DynamicObject>
+{
+ protected:
+
+ DynamicObjectScript(const char* name)
+ : ScriptObject(name)
+ { }
+
+ void RegisterSelf();
+};
+
+class TransportScript : public ScriptObject, public UpdatableScript<Transport>
+{
+ protected:
+
+ TransportScript(const char* name)
+ : ScriptObject(name)
+ {
+ }
+
+ void RegisterSelf();
+
+ public:
+
+ bool IsDatabaseBound() const { return true; }
+
+ // Called when a player boards the transport.
+ virtual void OnAddPassenger(Transport* transport, Player* player) { }
+
+ // Called when a creature boards the transport.
+ virtual void OnAddCreaturePassenger(Transport* transport, Creature* creature) { }
+
+ // Called when a player exits the transport.
+ virtual void OnRemovePassenger(Transport* transport, Player* player) { }
+};
+
+// Placed here due to ScriptRegistry::AddScript dependency.
+#define sScriptMgr (*ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance())
+
+// Manages registration, loading, and execution of scripts.
class ScriptMgr
{
friend class ACE_Singleton<ScriptMgr, ACE_Null_Mutex>;
+ friend class ScriptObject;
+
ScriptMgr();
- public:
- ~ScriptMgr();
-
- void ScriptsInit();
- void LoadDatabase();
- char const* ScriptsVersion();
-
- //event handlers
- void OnLogin(Player *pPlayer);
- void OnLogout(Player *pPlayer);
- void OnPVPKill(Player *killer, Player *killed);
- bool OnSpellCast (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGoTarget, uint32 i, SpellEntry const *spell);
- uint32 OnGetXP(Player *pPlayer, uint32 amount);
- uint32 OnGetMoney(Player *pPlayer, int32 amount);
- bool OnPlayerChat(Player *pPlayer, const char *text);
- void OnServerStartup();
- void OnServerShutdown();
- void OnAreaChange(Player *pPlayer, AreaTableEntry const *pArea);
- bool OnItemClick (Player *pPlayer, Item *pItem);
- bool OnItemOpen (Player *pPlayer, Item *pItem);
- bool OnGoClick (Player *pPlayer, GameObject *pGameObject);
- void OnCreatureKill (Player *pPlayer, Creature *pCreature);
- bool GossipHello (Player * pPlayer, Creature* pCreature);
- bool GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction);
- bool GossipSelectWithCode(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction, const char* sCode);
- bool GOSelect(Player* pPlayer, GameObject* pGO, uint32 uiSender, uint32 uiAction);
- bool GOSelectWithCode(Player* pPlayer, GameObject* pGO, uint32 uiSender, uint32 uiAction, const char* sCode);
- bool QuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest);
- bool QuestSelect(Player* pPlayer, Creature* pCreature, Quest const* pQuest);
- bool QuestComplete(Player* pPlayer, Creature* pCreature, Quest const* pQuest);
- bool ChooseReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt);
- uint32 NPCDialogStatus(Player* pPlayer, Creature* pCreature);
- uint32 GODialogStatus(Player* pPlayer, GameObject* pGO);
- bool ItemHello(Player* pPlayer, Item* pItem, Quest const* pQuest);
- bool ItemQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest);
- bool GOHello(Player* pPlayer, GameObject* pGO);
- bool GOQuestAccept(Player* pPlayer, GameObject* pGO, Quest const* pQuest);
- bool GOChooseReward(Player* pPlayer, GameObject* pGO, Quest const* pQuest, uint32 opt);
- void GODestroyed(Player* pPlayer, GameObject* pGO, uint32 destroyedEvent);
- bool AreaTrigger(Player* pPlayer,AreaTriggerEntry const* atEntry);
- CreatureAI* GetAI(Creature* pCreature);
- bool ItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets);
- bool ItemExpire(Player* pPlayer, ItemPrototype const * pItemProto);
- bool EffectDummyCreature(Unit *caster, uint32 spellId, uint32 effIndex, Creature *crTarget);
- bool EffectDummyGameObj(Unit *caster, uint32 spellId, uint32 effIndex, GameObject *gameObjTarget);
- bool EffectDummyItem(Unit *caster, uint32 spellId, uint32 effIndex, Item *itemTarget);
- InstanceData* CreateInstanceData(Map *map);
- void CreateSpellScripts(uint32 spell_id, std::list<SpellScript *> & script_vector);
- void CreateSpellScripts(uint32 spell_id, std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> > & script_vector);
-};
-
-//Generic scripting text function
-void DoScriptText(int32 textEntry, WorldObject* pSource, Unit *pTarget = NULL);
+ ~ScriptMgr();
-#define sScriptMgr (*ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance())
-#endif
+ uint32 _scriptCount;
+
+ void LoadDatabase();
+ void FillSpellSummary();
+
+ public: /* Initialization */
+
+ void Initialize();
+ const char* ScriptsVersion() const { return "Integrated Trinity Scripts"; }
+
+ void IncrementScriptCount() { ++_scriptCount; }
+ uint32 GetScriptCount() const { return _scriptCount; }
+
+ public: /* SpellHandlerScript */
+
+ void CreateSpellScripts(uint32 spell_id, std::list<SpellScript*>& script_vector);
+ void CreateSpellScripts(uint32 spell_id, std::vector<std::pair<SpellScript*, SpellScriptsMap::iterator> >& script_vector);
+
+ public: /* AuraHandlerScript */
+
+ // void CreateAuraScripts(uint32 spell_id, std::list<AuraScript*>& script_vector);
+ // void CreateAuraScripts(uint32 spell_id, std::vector<std::pair<AuraScript*, SpellScriptsMap::iterator> >& script_vector);
+
+ public: /* ServerScript */
+
+ void OnNetworkStart();
+ void OnNetworkStop();
+ void OnSocketOpen(WorldSocket* socket);
+ void OnSocketClose(WorldSocket* socket, bool wasNew);
+ void OnPacketReceive(WorldSocket* socket, WorldPacket& packet);
+ void OnPacketSend(WorldSocket* socket, WorldPacket& packet);
+ void OnUnknownPacketReceive(WorldSocket* socket, WorldPacket& packet);
+
+ public: /* WorldScript */
+
+ void OnOpenStateChange(bool open);
+ void OnConfigLoad(bool reload);
+ void OnMotdChange(std::string& newMotd);
+ void OnShutdown(ShutdownExitCode code, ShutdownMask mask);
+ void OnShutdownCancel();
+ void OnWorldUpdate(uint32 diff);
+
+ public: /* FormulaScript */
+ void OnHonorCalculation(float& honor, uint8 level, uint32 count);
+ void OnHonorCalculation(uint32& honor, uint8 level, uint32 count);
+ void OnGetGrayLevel(uint8& grayLevel, uint8 playerLevel);
+ void OnGetColorCode(XPColorChar& color, uint8 playerLevel, uint8 mobLevel);
+ void OnGetZeroDifference(uint8& diff, uint8 playerLevel);
+ void OnGetBaseGain(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content);
+ void OnGetGain(uint32& gain, Player* player, Unit* unit);
+ void OnGetGroupRate(float& rate, uint32 count, bool isRaid);
+
+ public: /* MapScript */
+
+ void OnCreateMap(Map* map);
+ void OnDestroyMap(Map* map);
+ void OnLoadGridMap(Map* map, uint32 gx, uint32 gy);
+ void OnUnloadGridMap(Map* map, uint32 gx, uint32 gy);
+ void OnPlayerEnter(Map* map, Player* player);
+ void OnPlayerLeave(Map* map, Player* player);
+ void OnMapUpdate(Map* map, uint32 diff);
+
+ public: /* InstanceMapScript */
+
+ InstanceData* CreateInstanceData(InstanceMap* map);
+
+ public: /* ItemScript */
+
+ bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Item* target);
+ bool OnQuestAccept(Player* player, Item* item, Quest const* quest);
+ bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets);
+ bool OnItemExpire(Player* player, ItemPrototype const* proto);
+
+ public: /* CreatureScript */
+
+ bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Creature* target);
+ bool OnGossipHello(Player* player, Creature* creature);
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action);
+ bool OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code);
+ bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest);
+ bool OnQuestSelect(Player* player, Creature* creature, Quest const* quest);
+ bool OnQuestComplete(Player* player, Creature* creature, Quest const* quest);
+ bool OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt);
+ uint32 GetDialogStatus(Player* player, Creature* creature);
+ CreatureAI* GetCreatureAI(Creature* creature);
+ void OnCreatureUpdate(Creature* creature, uint32 diff);
+
+ public: /* GameObjectScript */
+
+ bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, GameObject* target);
+ bool OnGossipHello(Player* player, GameObject* go);
+ bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action);
+ bool OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code);
+ bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest);
+ bool OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt);
+ uint32 GetDialogStatus(Player* player, GameObject* go);
+ void OnGameObjectDestroyed(Player* player, GameObject* go, uint32 eventId);
+ void OnGameObjectUpdate(GameObject* go, uint32 diff);
+
+ public: /* AreaTriggerScript */
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* trigger);
+
+ public: /* BattlegroundScript */
+
+ BattleGround* CreateBattleground(BattleGroundTypeId typeId);
+
+ public: /* OutdoorPvPScript */
+
+ OutdoorPvP* CreateOutdoorPvP(OutdoorPvPData const* data);
+
+ public: /* CommandScript */
+
+ std::vector<ChatCommand*> GetChatCommands();
+
+ public: /* WeatherScript */
+
+ void OnWeatherChange(Weather* weather, WeatherState state, float grade);
+ void OnWeatherUpdate(Weather* weather, uint32 diff);
+
+ public: /* AuctionHouseScript */
+
+ void OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry);
+ void OnRemoveAuction(AuctionHouseObject* ah, AuctionEntry* entry);
+ void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry);
+ void OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry);
+
+ public: /* ConditionScript */
+
+ bool OnConditionCheck(Condition* condition, Player* player, Unit* targetOverride);
+
+ public: /* VehicleScript */
+
+ void OnInstall(Vehicle* veh);
+ void OnUninstall(Vehicle* veh);
+ void OnDie(Vehicle* veh);
+ void OnReset(Vehicle* veh);
+ void OnInstallAccessory(Vehicle* veh, Creature* accessory);
+ void OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId);
+ void OnRemovePassenger(Vehicle* veh, Unit* passenger);
+
+ public: /* DynamicObjectScript */
+
+ void OnDynamicObjectUpdate(DynamicObject* dynobj, uint32 diff);
+
+ public: /* TransportScript */
+
+ void OnAddPassenger(Transport* transport, Player* player);
+ void OnAddCreaturePassenger(Transport* transport, Creature* creature);
+ void OnRemovePassenger(Transport* transport, Player* player);
+ void OnTransportUpdate(Transport* transport, uint32 diff);
+
+ public: /* ScriptRegistry */
+
+ // This is the global static registry of scripts.
+ template<class TScript> class ScriptRegistry
+ {
+ // Counter used for code-only scripts.
+ static uint32 _scriptIdCounter;
+
+ public:
+
+ typedef std::map<uint32, TScript*> ScriptMap;
+
+ // The actual list of scripts. This will be accessed concurrently, so it must not be modified
+ // after server startup.
+ static ScriptMap ScriptPointerList;
+
+ // Gets a script by its ID (assigned by ObjectMgr).
+ static TScript* GetScriptById(uint32 id)
+ {
+ for (ScriptMap::iterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
+ if (it->first == id)
+ return it->second;
+
+ return NULL;
+ }
+
+ // Attempts to add a new script to the list.
+ static void AddScript(TScript* const script);
+ };
+};
+
+#endif
diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h
index 7102e4a43e1..52401502c83 100644
--- a/src/server/game/Scripting/ScriptSystem.h
+++ b/src/server/game/Scripting/ScriptSystem.h
@@ -97,6 +97,6 @@ class SystemMgr
PointMoveMap m_mPointMoveMap; //coordinates for waypoints
};
-#define pSystemMgr SystemMgr::Instance()
+#define sScriptSystemMgr SystemMgr::Instance()
#endif
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 94afaee6f0f..45a41dc099d 100644
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -806,8 +806,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
m_playerLoading = false;
- //Hook for OnLogin Event
- sScriptMgr.OnLogin(pCurrChar);
delete holder;
}
@@ -1360,48 +1358,3 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data)
data << uint8(0); // 4 - equipment swap failed - inventory is full
SendPacket(&data);
}
-
-void WorldSession::HandleOnPVPKill(Player *killed)
-{
- sScriptMgr.OnPVPKill(GetPlayer(), killed);
-}
-
-bool WorldSession::HandleOnPlayerChat(const char *text)
-{
- return sScriptMgr.OnPlayerChat(GetPlayer(), text);
-}
-
-uint32 WorldSession::HandleOnGetXP(uint32 amount)
-{
- return sScriptMgr.OnGetXP(GetPlayer(), amount);
-}
-
-int32 WorldSession::HandleOnGetMoney(int32 amount)
-{
- return sScriptMgr.OnGetMoney(GetPlayer(), amount);
-}
-
-void WorldSession::HandleOnAreaChange(AreaTableEntry const *pArea)
-{
- sScriptMgr.OnAreaChange(GetPlayer(), pArea);
-}
-
-bool WorldSession::HandleOnItemClick(Item *pItem)
-{
- return sScriptMgr.OnItemClick(GetPlayer(), pItem);
-}
-
-bool WorldSession::HandleOnItemOpen(Item *pItem)
-{
- return sScriptMgr.OnItemOpen(GetPlayer(), pItem);
-}
-
-bool WorldSession::HandleOnGoClick(GameObject *pGameObject)
-{
- return sScriptMgr.OnGoClick(GetPlayer(), pGameObject);
-}
-
-void WorldSession::HandleOnCreatureKill(Creature *pCreature)
-{
- sScriptMgr.OnCreatureKill(GetPlayer(), pCreature);
-}
diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
index b7aa9b66979..264f48b7265 100644
--- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
@@ -140,21 +140,21 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
{
if (unit)
{
- if (!sScriptMgr.GossipSelectWithCode(_player, unit, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str()))
+ if (!sScriptMgr.OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str()))
_player->OnGossipSelect(unit, gossipListId, menuId);
}
else
- sScriptMgr.GOSelectWithCode(_player, go, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str());
+ sScriptMgr.OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str());
}
else
{
if (unit)
{
- if (!sScriptMgr.GossipSelect(_player, unit, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId)))
+ if (!sScriptMgr.OnGossipSelect(_player, unit, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId)))
_player->OnGossipSelect(unit, gossipListId, menuId);
}
else
- sScriptMgr.GOSelect(_player, go, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId));
+ sScriptMgr.OnGossipSelect(_player, go, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId));
}
}
@@ -884,7 +884,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
}
}
- if (sScriptMgr.AreaTrigger(GetPlayer(), atEntry))
+ if (sScriptMgr.OnTrigger(GetPlayer(), atEntry))
return;
uint32 quest_id = objmgr.GetQuestForAreaTrigger(Trigger_ID);
diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
index 935ccf02f96..3caf0db9dac 100644
--- a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
@@ -340,7 +340,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data)
}
}
- if (!sScriptMgr.GossipHello(_player, unit))
+ if (!sScriptMgr.OnGossipHello(_player, unit))
{
// _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
_player->PrepareGossipMenu(unit, unit->GetCreatureInfo()->GossipMenuId, true);
diff --git a/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp b/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp
index 8c7b87be79c..7344ad6d272 100644
--- a/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp
@@ -56,7 +56,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recv_data)
Creature* cr_questgiver=questgiver->ToCreature();
if (!cr_questgiver->IsHostileTo(_player)) // not show quest status to enemies
{
- questStatus = sScriptMgr.NPCDialogStatus(_player, cr_questgiver);
+ questStatus = sScriptMgr.GetDialogStatus(_player, cr_questgiver);
if (questStatus > 6)
questStatus = getDialogStatus(_player, cr_questgiver, defstatus);
}
@@ -66,7 +66,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recv_data)
{
sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u",uint32(GUID_LOPART(guid)));
GameObject* go_questgiver=(GameObject*)questgiver;
- questStatus = sScriptMgr.GODialogStatus(_player, go_questgiver);
+ questStatus = sScriptMgr.GetDialogStatus(_player, go_questgiver);
if (questStatus > 6)
questStatus = getDialogStatus(_player, go_questgiver, defstatus);
break;
@@ -101,7 +101,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data)
// Stop the npc if moving
pCreature->StopMoving();
- if (sScriptMgr.GossipHello(_player, pCreature))
+ if (sScriptMgr.OnGossipHello(_player, pCreature))
return;
_player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId, true);
@@ -188,12 +188,12 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data)
switch(pObject->GetTypeId())
{
case TYPEID_UNIT:
- sScriptMgr.QuestAccept(_player, (pObject->ToCreature()), qInfo);
+ sScriptMgr.OnQuestAccept(_player, (pObject->ToCreature()), qInfo);
break;
case TYPEID_ITEM:
case TYPEID_CONTAINER:
{
- sScriptMgr.ItemQuestAccept(_player, ((Item*)pObject), qInfo);
+ sScriptMgr.OnQuestAccept(_player, ((Item*)pObject), qInfo);
// destroy not required for quest finish quest starting item
bool destroyItem = true;
@@ -212,7 +212,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket & recv_data)
break;
}
case TYPEID_GAMEOBJECT:
- sScriptMgr.GOQuestAccept(_player, ((GameObject*)pObject), qInfo);
+ sScriptMgr.OnQuestAccept(_player, ((GameObject*)pObject), qInfo);
break;
}
_player->PlayerTalkClass->CloseGossip();
@@ -307,7 +307,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
switch(pObject->GetTypeId())
{
case TYPEID_UNIT:
- if (!(sScriptMgr.ChooseReward(_player, (pObject->ToCreature()), pQuest, reward)))
+ if (!(sScriptMgr.OnQuestReward(_player, (pObject->ToCreature()), pQuest, reward)))
{
// Send next quest
if (Quest const* nextquest = _player->GetNextQuest(guid ,pQuest))
@@ -315,7 +315,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
}
break;
case TYPEID_GAMEOBJECT:
- if (!sScriptMgr.GOChooseReward(_player, ((GameObject*)pObject), pQuest, reward))
+ if (!sScriptMgr.OnQuestReward(_player, ((GameObject*)pObject), pQuest, reward))
{
// Send next quest
if (Quest const* nextquest = _player->GetNextQuest(guid ,pQuest))
@@ -672,7 +672,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
continue;
if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
continue;
- questStatus = sScriptMgr.NPCDialogStatus(_player, questgiver);
+ questStatus = sScriptMgr.GetDialogStatus(_player, questgiver);
if (questStatus > 6)
questStatus = getDialogStatus(_player, questgiver, defstatus);
@@ -687,7 +687,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
continue;
if (questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
continue;
- questStatus = sScriptMgr.GODialogStatus(_player, questgiver);
+ questStatus = sScriptMgr.GetDialogStatus(_player, questgiver);
if (questStatus > 6)
questStatus = getDialogStatus(_player, questgiver, defstatus);
diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
index 4179474db47..a46d4e336d6 100644
--- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
@@ -156,7 +156,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
}
//Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
- if (!sScriptMgr.ItemUse(pUser,pItem,targets))
+ if (!sScriptMgr.OnItemUse(pUser,pItem,targets))
{
// no script or script not process request by self
pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex);
@@ -199,9 +199,6 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
return;
}
- if (!pUser->GetSession()->HandleOnItemOpen(pItem))
- return;
-
// locked item
uint32 lockId = proto->LockID;
if (lockId)
@@ -266,7 +263,7 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPacket & recv_data)
if (!obj)
return;
- if (sScriptMgr.GOHello(_player, obj))
+ if (sScriptMgr.OnGossipHello(_player, obj))
return;
obj->Use(_player);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index cc4644e0434..931e2e6519f 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -196,6 +196,8 @@ bool WorldSession::Update(uint32 diff)
sLog.outError("SESSION: received non-existed opcode %s (0x%.4X)",
LookupOpcodeName(packet->GetOpcode()),
packet->GetOpcode());
+
+ sScriptMgr.OnUnknownPacketReceive(m_Socket, WorldPacket(*packet));
}
else
{
@@ -213,6 +215,7 @@ bool WorldSession::Update(uint32 diff)
}
else if (_player->IsInWorld())
{
+ sScriptMgr.OnPacketReceive(m_Socket, WorldPacket(*packet));
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
@@ -227,6 +230,7 @@ bool WorldSession::Update(uint32 diff)
else
{
// not expected _player or must checked in packet hanlder
+ sScriptMgr.OnPacketReceive(m_Socket, WorldPacket(*packet));
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
@@ -239,6 +243,7 @@ bool WorldSession::Update(uint32 diff)
LogUnexpectedOpcode(packet, "the player is still in world");
else
{
+ sScriptMgr.OnPacketReceive(m_Socket, WorldPacket(*packet));
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
@@ -256,7 +261,8 @@ bool WorldSession::Update(uint32 diff)
// and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
m_playerRecentlyLogout = false;
-
+
+ sScriptMgr.OnPacketReceive(m_Socket, WorldPacket(*packet));
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
@@ -471,9 +477,6 @@ void WorldSession::LogoutPlayer(bool Save)
sLog.outDebug("SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
}
- //Hook for OnLogout Event
- sScriptMgr.OnLogout(_player);
-
m_playerLogout = false;
m_playerSave = false;
m_playerRecentlyLogout = true;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index f88b34d3127..9b5bca8b53f 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -785,15 +785,6 @@ class WorldSession
void HandleReadyForAccountDataTimes(WorldPacket& recv_data);
void HandleQueryQuestsCompleted(WorldPacket& recv_data);
void HandleQuestPOIQuery(WorldPacket& recv_data);
- void HandleOnPVPKill(Player *killed);
- bool HandleOnPlayerChat(const char *text);
- uint32 HandleOnGetXP(uint32 amount);
- int32 HandleOnGetMoney(int32 amount);
- void HandleOnAreaChange(AreaTableEntry const *pArea);
- bool HandleOnItemClick(Item *pItem);
- bool HandleOnItemOpen(Item *pItem);
- bool HandleOnGoClick(GameObject *pGameObject);
- void HandleOnCreatureKill(Creature *pCreature);
void HandleEjectPasenger(WorldPacket &data);
void HandleEnterPlayerVehicle(WorldPacket &data);
private:
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index f7b128fb761..dea11417e23 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -45,6 +45,7 @@
#include "WorldSocketMgr.h"
#include "Log.h"
#include "WorldLog.h"
+#include "ScriptMgr.h"
#if defined(__GNUC__)
#pragma pack(1)
@@ -186,6 +187,9 @@ int WorldSocket::SendPacket (const WorldPacket& pct)
sWorldLog.outLog("\n");
}
+ // Create a copy of the original packet; this is to avoid issues if a hook modifies it.
+ sScriptMgr.OnPacketSend(this, WorldPacket(pct));
+
ServerPktHeader header(pct.size()+2, pct.GetOpcode());
m_Crypt.EncryptSend ((uint8*)header.header, header.getHeaderLength());
@@ -705,7 +709,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
sWorldLog.outLog ("\n");
}
- try {
+ try
+ {
switch(opcode)
{
case CMSG_PING:
@@ -716,11 +721,12 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
sLog.outError ("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
return -1;
}
-
+
+ sScriptMgr.OnPacketReceive(this, WorldPacket(*new_pct));
return HandleAuthSession (*new_pct);
case CMSG_KEEP_ALIVE:
DEBUG_LOG ("CMSG_KEEP_ALIVE ,size: %d", new_pct->size());
-
+ sScriptMgr.OnPacketReceive(this, WorldPacket(*new_pct));
return 0;
default:
{
@@ -747,7 +753,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
}
}
}
- catch(ByteBufferException &)
+ catch (ByteBufferException &)
{
sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp
index 192105a5ba3..d4015c47e76 100644
--- a/src/server/game/Server/WorldSocketMgr.cpp
+++ b/src/server/game/Server/WorldSocketMgr.cpp
@@ -45,6 +45,7 @@
#include "Config.h"
#include "DatabaseEnv.h"
#include "WorldSocket.h"
+#include "ScriptMgr.h"
/**
* This is a helper class to WorldSocketMgr ,that manages
@@ -116,6 +117,8 @@ class ReactorRunnable : protected ACE_Task_Base
sock->reactor (m_Reactor);
m_NewSockets.insert (sock);
+ sScriptMgr.OnSocketOpen(sock);
+
return 0;
}
@@ -139,6 +142,8 @@ class ReactorRunnable : protected ACE_Task_Base
if (sock->IsClosed())
{
+ sScriptMgr.OnSocketClose(sock, true);
+
sock->RemoveReference();
--m_Connections;
}
@@ -176,7 +181,11 @@ class ReactorRunnable : protected ACE_Task_Base
{
t = i;
++i;
+
(*t)->CloseSocket();
+
+ sScriptMgr.OnSocketClose((*t), false);
+
(*t)->RemoveReference();
--m_Connections;
m_Sockets.erase (t);
@@ -279,6 +288,8 @@ WorldSocketMgr::StartNetwork (ACE_UINT16 port, const char* address)
if (StartReactiveIO(port, address) == -1)
return -1;
+ sScriptMgr.OnNetworkStart();
+
return 0;
}
@@ -300,6 +311,8 @@ WorldSocketMgr::StopNetwork()
}
Wait();
+
+ sScriptMgr.OnNetworkStop();
}
void
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 80b1aacd54d..0af5b043fd7 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2327,7 +2327,7 @@ void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this);
sLog.outDebug("AuraEffect::TriggerSpell: Spell %u Trigger %u",GetId(), triggeredSpellInfo->Id);
}
- else if (target->GetTypeId() != TYPEID_UNIT || !sScriptMgr.EffectDummyCreature(caster, GetId(), GetEffIndex(), triggerTarget->ToCreature()))
+ else if (target->GetTypeId() != TYPEID_UNIT || !sScriptMgr.OnDummyEffect(caster, GetId(), SpellEffIndex(GetEffIndex()), triggerTarget->ToCreature()))
sLog.outError("AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index cad47652544..ca7443fbbcf 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4553,9 +4553,6 @@ void Spell::HandleThreatSpells(uint32 spellId)
void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i)
{
- if (!sScriptMgr.OnSpellCast(pUnitTarget,pItemTarget,pGOTarget,i,m_spellInfo))
- return;
-
//effect has been handled, skip it
if (m_effectMask & (1<<i))
return;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index a42501a8ac5..f7c5b759334 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1936,11 +1936,11 @@ void Spell::EffectDummy(uint32 i)
// Script based implementation. Must be used only for not good for implementation in core spell effects
// So called only for not proccessed cases
if (gameObjTarget)
- sScriptMgr.EffectDummyGameObj(m_caster, m_spellInfo->Id, i, gameObjTarget);
+ sScriptMgr.OnDummyEffect(m_caster, m_spellInfo->Id, SpellEffIndex(i), gameObjTarget);
else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT)
- sScriptMgr.EffectDummyCreature(m_caster, m_spellInfo->Id, i, unitTarget->ToCreature());
+ sScriptMgr.OnDummyEffect(m_caster, m_spellInfo->Id, SpellEffIndex(i), unitTarget->ToCreature());
else if (itemTarget)
- sScriptMgr.EffectDummyItem(m_caster, m_spellInfo->Id, i, itemTarget);
+ sScriptMgr.OnDummyEffect(m_caster, m_spellInfo->Id, SpellEffIndex(i), itemTarget);
}
void Spell::EffectTriggerSpellWithValue(uint32 i)
@@ -3128,7 +3128,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if (gameObjTarget)
{
- if (sScriptMgr.GOHello(player, gameObjTarget))
+ if (sScriptMgr.OnGossipHello(player, gameObjTarget))
return;
switch (gameObjTarget->GetGoType())
diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp
index 5c5779a6506..8c3da68f538 100644
--- a/src/server/game/Weather/Weather.cpp
+++ b/src/server/game/Weather/Weather.cpp
@@ -29,6 +29,7 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "Util.h"
+#include "ScriptMgr.h"
/// Create the Weather object
Weather::Weather(uint32 zone, WeatherData const* weatherChances)
@@ -46,7 +47,8 @@ bool Weather::Update(uint32 diff)
{
if (m_timer.GetCurrent() >= 0)
m_timer.Update(diff);
- else m_timer.SetCurrent(0);
+ else
+ m_timer.SetCurrent(0);
///- If the timer has passed, ReGenerate the weather
if (m_timer.Passed())
@@ -60,6 +62,8 @@ bool Weather::Update(uint32 diff)
return false;
}
}
+
+ sScriptMgr.OnWeatherUpdate(this, diff);
return true;
}
@@ -266,6 +270,7 @@ bool Weather::UpdateWeather()
}
sLog.outDetail("Change the weather of zone %u to %s.", m_zone, wthstr);
+ sScriptMgr.OnWeatherChange(this, state, m_grade);
return true;
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 5a54f9f85da..0554bf5e5a7 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -70,6 +70,7 @@
#include "ConditionMgr.h"
#include "DisableMgr.h"
#include "CharacterDatabaseCleaner.h"
+#include "ScriptMgr.h"
volatile bool World::m_stopEvent = false;
uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
@@ -165,6 +166,31 @@ Player* World::FindPlayerInZone(uint32 zone)
return NULL;
}
+bool World::IsClosed() const
+{
+ return m_isClosed;
+}
+
+void World::SetClosed(bool val)
+{
+ m_isClosed = val;
+
+ // Invert the value, for simplicity for scripters.
+ sScriptMgr.OnOpenStateChange(!val);
+}
+
+void World::SetMotd(const std::string& motd)
+{
+ m_motd = motd;
+
+ sScriptMgr.OnMotdChange(m_motd);
+}
+
+const char* World::GetMotd() const
+{
+ return m_motd.c_str();
+}
+
/// Find a session by its id
WorldSession* World::FindSession(uint32 id) const
{
@@ -1223,7 +1249,6 @@ void World::LoadConfigSettings(bool reload)
if (m_configs[CONFIG_PVP_TOKEN_COUNT] < 1)
m_configs[CONFIG_PVP_TOKEN_COUNT] = 1;
-
m_configs[CONFIG_NO_RESET_TALENT_COST] = sConfig.GetBoolDefault("NoResetTalentsCost", false);
m_configs[CONFIG_SHOW_KICK_IN_WORLD] = sConfig.GetBoolDefault("ShowKickInWorld", false);
m_configs[CONFIG_INTERVAL_LOG_UPDATE] = sConfig.GetIntDefault("RecordUpdateTimeDiffInterval", 60000);
@@ -1240,6 +1265,8 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_CHATLOG_PUBLIC] = sConfig.GetBoolDefault("ChatLogs.Public", false);
m_configs[CONFIG_CHATLOG_ADDON] = sConfig.GetBoolDefault("ChatLogs.Addon", false);
m_configs[CONFIG_CHATLOG_BGROUND] = sConfig.GetBoolDefault("ChatLogs.BattleGround", false);
+
+ sScriptMgr.OnConfigLoad(reload);
}
/// Initialize the World
@@ -1624,7 +1651,7 @@ void World::SetInitialWorldSettings()
objmgr.LoadSpellScriptNames();
sLog.outString("Initializing Scripts...");
- sScriptMgr.ScriptsInit();
+ sScriptMgr.Initialize();
sLog.outString("Validating spell scripts...");
objmgr.ValidateSpellScripts();
@@ -1733,7 +1760,6 @@ void World::SetInitialWorldSettings()
else
sLog.SetLogDB(false);
- sScriptMgr.OnServerStartup();
sLog.outString("WORLD: World initialized");
}
@@ -1847,7 +1873,8 @@ void World::LoadAutobroadcasts()
/// Update the World !
void World::Update(uint32 diff)
{
- m_updateTime = uint32(diff);
+ m_updateTime = diff;
+
if (m_configs[CONFIG_INTERVAL_LOG_UPDATE])
{
if (m_updateTimeSum > m_configs[CONFIG_INTERVAL_LOG_UPDATE])
@@ -1867,7 +1894,8 @@ void World::Update(uint32 diff)
for (int i = 0; i < WUPDATE_COUNT; ++i)
if (m_timers[i].GetCurrent() >= 0)
m_timers[i].Update(diff);
- else m_timers[i].SetCurrent(0);
+ else
+ m_timers[i].SetCurrent(0);
///- Update the game time and check for shutdown time
_UpdateGameTime();
@@ -1928,6 +1956,7 @@ void World::Update(uint32 diff)
}
}
}
+
/// <li> Update uptime table
if (m_timers[WUPDATE_UPTIME].Passed())
{
@@ -1956,12 +1985,6 @@ void World::Update(uint32 diff)
///- Update objects when the timer has passed (maps, transport, creatures,...)
sMapMgr.Update(diff); // As interval = 0
- /*if (m_timers[WUPDATE_OBJECTS].Passed())
- {
- m_timers[WUPDATE_OBJECTS].Reset();
- sMapMgr.DoDelayedMovesAndRemoves();
- }*/
-
static uint32 autobroadcaston = 0;
autobroadcaston = sConfig.GetIntDefault("AutoBroadcast.On", 0);
if (autobroadcaston == 1)
@@ -2015,6 +2038,8 @@ void World::Update(uint32 diff)
// And last, but not least handle the issued cli commands
ProcessCliCommands();
+
+ sScriptMgr.OnWorldUpdate(diff);
}
void World::ForceGameEventUpdate()
@@ -2361,7 +2386,7 @@ void World::ShutdownServ(uint32 time, uint32 options, uint8 exitcode)
ShutdownMsg(true);
}
- sScriptMgr.OnServerShutdown();
+ sScriptMgr.OnShutdown(ShutdownExitCode(exitcode), ShutdownMask(options));
}
/// Display a shutdown message to the user(s)
@@ -2409,6 +2434,8 @@ void World::ShutdownCancel()
SendServerMessage(msgid);
DEBUG_LOG("Server %s cancelled.",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown"));
+
+ sScriptMgr.OnShutdownCancel();
}
/// Send a server message to the user(s)
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 29bb6f73fc3..5742741db07 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -525,10 +525,10 @@ class World
void RemoveWeather(uint32 zone_id);
/// Deny clients?
- bool IsClosed() { return m_isClosed; }
+ bool IsClosed() const;
/// Close world
- void SetClosed(bool val) { m_isClosed = val; }
+ void SetClosed(bool val);
/// Get the active session server limit (or security level limitations)
uint32 GetPlayerAmountLimit() const { return m_playerLimit >= 0 ? m_playerLimit : 0; }
@@ -553,9 +553,9 @@ class World
void SetAllowMovement(bool allow) { m_allowMovement = allow; }
/// Set a new Message of the Day
- void SetMotd(const std::string& motd) { m_motd = motd; }
+ void SetMotd(const std::string& motd);
/// Get the current Message of the Day
- const char* GetMotd() const { return m_motd.c_str(); }
+ const char* GetMotd() const;
/// Set the string for new characters (first login)
void SetNewCharString(std::string str) { m_newCharString = str; }
@@ -688,11 +688,11 @@ class World
void UpdateAreaDependentAuras();
- void ProcessStartEvent();
- void ProcessStopEvent();
- bool GetEventKill() { return isEventKillStart; }
+ void ProcessStartEvent();
+ void ProcessStopEvent();
+ bool GetEventKill() { return isEventKillStart; }
- bool isEventKillStart;
+ bool isEventKillStart;
protected:
void _UpdateGameTime();
// callback for UpdateRealmCharacters
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index eef7b7f65d3..b7cef4d8832 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -31,7 +31,6 @@ set(scripts_STAT_SRCS
${scripts_world}
${scripts_spells}
${scripts_examples}
- Custom/on_events.cpp
../game/AI/ScriptedAI/ScriptedEscortAI.cpp
../game/AI/ScriptedAI/ScriptedCreature.cpp
../game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -90,6 +89,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object/Updates
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Pet
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Player
+ ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Transport
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Unit
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Vehicle
${CMAKE_SOURCE_DIR}/src/server/game/Events
diff --git a/src/server/scripts/Custom/on_events.cpp b/src/server/scripts/Custom/on_events.cpp
deleted file mode 100644
index 58cc8275a3a..00000000000
--- a/src/server/scripts/Custom/on_events.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/>
- *
- * 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 "ScriptPCH.h"
-#include <cstring>
-
-//This function is called when the player logs in (every login)
-void OnLogin(Player * /*pPlayer*/)
-{
-
-}
-
-//This function is called when the player logs out
-void OnLogout(Player * /*pPlayer*/)
-{
-
-}
-
-//This function is called when the player kills another player
-void OnPVPKill(Player * /*killer*/, Player * /*killed*/)
-{
-
-}
-
-//This function is called when a players AreaID changes
-void OnAreaChange(Player * /*pPlayer*/, AreaTableEntry const * /*pArea*/)
-{
-
-}
-
-//This is called when a player kills a creature (non pvp)
-void OnCreatureKill(Player * /*pPlayer*/, Creature * /*pCreature*/)
-{
-
-}
-
-//This function is called when a player has a money exchange
-int32 OnGetMoney(Player * /*pPlayer*/, int32 amount)
-{
- return amount;
-}
-
-//This function is called whenever a player gets XP
-uint32 OnGetXP(Player * /*pPlayer*/, uint32 amount)
-{
- return amount;
-}
-
-//This function is called when a player clicks a GO Object
-bool OnGoClick(Player * /*pPlayer*/, GameObject * /*pGameObject*/)
-{
- return true;
-}
-
-//This function is called when a player clicks and item
-bool OnItemClick(Player * /*pPlayer*/, Item * /*pItem*/)
-{
- return true;
-}
-
-//This function is called when a player opens an item (like a clam)
-bool OnItemOpen(Player * /*pPlayer*/, Item * /*pItem*/)
-{
- return true;
-}
-
-//This function is called when a player sends a chat message
-bool OnPlayerChat(Player * /*pPlayer*/, const char * /*text*/)
-{
- return true;
-}
-
-//this function is called when the server starts
-void OnServerStartup()
-{
-
-}
-//this function is called when the server shuts down
-void OnServerShutdown()
-{
-
-}
-
-//this function is called when a player casts a spell
-bool OnSpellCast(Unit * /*pUnitTarget*/, Item * /*pItemTarget*/, GameObject * /*pGoTarget*/, uint32 /*i*/, SpellEntry const * /*spell*/)
-{
- return true;
-}
-
- void AddSC_onevents()
-{
- Script *newscript;
- newscript = new Script;
- newscript->Name = "scripted_on_events";
- newscript->pOnLogin = &OnLogin;
- newscript->pOnLogout = &OnLogout;
- newscript->pOnPVPKill = &OnPVPKill;
- newscript->pOnAreaChange = &OnAreaChange;
- newscript->pOnCreatureKill = &OnCreatureKill;
- newscript->pOnGetMoney = &OnGetMoney;
- newscript->pOnGetXP = &OnGetXP;
- newscript->pOnGoClick = &OnGoClick;
- newscript->pOnItemClick = &OnItemClick;
- newscript->pOnItemOpen = &OnItemOpen;
- newscript->pOnPlayerChat = &OnPlayerChat;
- newscript->pOnServerShutdown = &OnServerShutdown;
- newscript->pOnServerStartup = &OnServerStartup;
- newscript->pOnSpellCast = &OnSpellCast;
-
- newscript->RegisterSelf();
-}
diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.h b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.h
index 2fdd536b698..375e586f13b 100644
--- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.h
+++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.h
@@ -5,32 +5,32 @@
#ifndef DEF_ZF_H
#define DEF_ZF_H
- enum zfEntries
- {
- ENTRY_ZUMRAH = 7271,
- ENTRY_BLY = 7604,
- ENTRY_RAVEN = 7605,
- ENTRY_ORO = 7606,
- ENTRY_WEEGLI = 7607,
- ENTRY_MURTA = 7608,
+enum zfEntries
+{
+ ENTRY_ZUMRAH = 7271,
+ ENTRY_BLY = 7604,
+ ENTRY_RAVEN = 7605,
+ ENTRY_ORO = 7606,
+ ENTRY_WEEGLI = 7607,
+ ENTRY_MURTA = 7608,
- GO_END_DOOR = 146084,
+ GO_END_DOOR = 146084,
- EVENT_PYRAMID = 1,
- EVENT_GAHZRILLA
- };
+ EVENT_PYRAMID = 1,
+ EVENT_GAHZRILLA
+};
- enum zfPyramidPhases
- {
- PYRAMID_NOT_STARTED, //default
- PYRAMID_CAGES_OPEN, //happens in GO hello for cages
- PYRAMID_ARRIVED_AT_STAIR , //happens in Weegli's movementinform
- PYRAMID_WAVE_1,
- PYRAMID_PRE_WAVE_2,
- PYRAMID_WAVE_2,
- PYRAMID_PRE_WAVE_3,
- PYRAMID_WAVE_3,
- PYRAMID_KILLED_ALL_TROLLS,
- };
+enum zfPyramidPhases
+{
+ PYRAMID_NOT_STARTED, //default
+ PYRAMID_CAGES_OPEN, //happens in GO hello for cages
+ PYRAMID_ARRIVED_AT_STAIR , //happens in Weegli's movementinform
+ PYRAMID_WAVE_1,
+ PYRAMID_PRE_WAVE_2,
+ PYRAMID_WAVE_2,
+ PYRAMID_PRE_WAVE_3,
+ PYRAMID_WAVE_3,
+ PYRAMID_KILLED_ALL_TROLLS,
+};
#endif \ No newline at end of file
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index c158b9be3fb..3edf0c50c61 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -330,6 +330,10 @@ class HookList
m_list.remove(t);
return *this;
}
+ size_t size()
+ {
+ return m_list.size();
+ }
ListIterator begin()
{
return m_list.begin();