aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXTZGZoReX <none@none>2010-08-06 19:23:43 +0200
committerXTZGZoReX <none@none>2010-08-06 19:23:43 +0200
commit946adf469c14deeaf202cba5378fb5edfd792bd6 (patch)
treece27f0aaa34c6cd06fbdf234ec31ff6abc9ce80c /src
parent2562a4651f94e2dc40ccce108a2497c2c26bfff6 (diff)
*** New core <-> script library interface - complete rewrite of the old one.
* Removed the misdesigned on_events script/hooks. * Lots of related cleanups and assertions. * The interface is now fully object-oriented. ** Scripts no longer use function pointers. ** Scripts no longer use the general-purpose Script struct for everything. ** Script types are split into separate classes which must be inherited depending on what functionality is desired. * Several script types have been added to allow extending functionality in a code-only manner (some script types require assignment in the recently added ScriptName columns in the database, though). ** SpellHandlerScript: Wrapper around spell scripts (returns new SpellScript objects (`spell_script_names`.`ScriptName`)). ** ServerScript: Allows scripting events that occur in the network layer. ** WorldScript: Allows scripting certain world-global events. ** FormulaScript: Allows hooking and interfering with core formulas. ** *MapScript: Allows hooking different map types (including world, instance, and battleground maps (`instance_template`.`ScriptName`)). ** ItemScript: Allows scripting of items (like the old interface (`item_template`.`ScriptName`)). ** CreatureScript: Allows scripting of creatures/AI (like the old interface (`creature_template`.`ScriptName`)). ** GameObjectScript: Allows scripting of gameobjects (like the old interface (`gameobject_template`.`ScriptName`)). ** AreaTriggerScript: Allows scripting triggered area triggers (like the old interface (`areatrigger_scripts`.`ScriptName`)). ** OutdoorPvPScript: Script which should return OutdoorPvP objects for use by OutdoorPvPMgr (`outdoorpvp_template`.`ScriptName`). ** CommandScript: Allows extending the in-core command table. ** WeatherScript: Allows scripting of weather changes (`game_weather`.`ScriptName`). ** AuctionHouseScript: Allows scripting of auction events. ** ConditionScript: Allows scripting of conditions (`conditions`.`ScriptName`). ** DynamicObjectScript: Allows scripting of dynamicobjects. ** TransportScript: Allows scripting of transport events (`transports`.`ScriptName`). * OutdoorPvP objects are now created through scripts. This effectively means that they'll need to be moved to scripts before the they're functional again. * The whole idea with this new interface is to allow expanding core functionality without touching core code. If further hooks are needed to expand functionality of the core, let us know; we'll add them, if we agree that it is appropriate to do so. *** NOTE: The scripts project will _not_ build before it has been adapted to the new interface. *** Thanks to everyone who helped out with related preparations and suggestions! --HG-- branch : trunk
Diffstat (limited to 'src')
-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();