aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Scripting/ScriptMgr.h
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/server/game/Scripting/ScriptMgr.h
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/server/game/Scripting/ScriptMgr.h')
-rw-r--r--src/server/game/Scripting/ScriptMgr.h1006
1 files changed, 887 insertions, 119 deletions
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