· 8 years ago · Dec 09, 2017, 10:14 PM
1/*
2 * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2
3 * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
4 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
5 */
6
7#ifndef SC_SCRIPTMGR_H
8#define SC_SCRIPTMGR_H
9
10#include "Common.h"
11#include <ace/Singleton.h>
12#include <atomic>
13
14#include "ObjectMgr.h"
15#include "DBCStores.h"
16#include "QuestDef.h"
17#include "SharedDefines.h"
18#include "World.h"
19#include "Weather.h"
20#include "AchievementMgr.h"
21#include "DynamicObject.h"
22#include "ArenaTeam.h"
23#include "smallfolk.h"
24
25class AuctionHouseObject;
26class AuraScript;
27class Battleground;
28class BattlegroundMap;
29class Channel;
30class ChatCommand;
31class Creature;
32class CreatureAI;
33class DynamicObject;
34class GameObject;
35class GameObjectAI;
36class Guild;
37class GridMap;
38class Group;
39class InstanceMap;
40class InstanceScript;
41class Item;
42class Map;
43class OutdoorPvP;
44class Player;
45class Quest;
46class ScriptMgr;
47class Spell;
48class SpellScript;
49class SpellCastTargets;
50class Transport;
51class StaticTransport;
52class MotionTransport;
53class Unit;
54class Vehicle;
55class WorldPacket;
56class WorldSocket;
57class WorldObject;
58
59struct AchievementCriteriaData;
60struct AuctionEntry;
61struct ConditionSourceInfo;
62struct Condition;
63struct ItemTemplate;
64struct OutdoorPvPData;
65
66#define VISIBLE_RANGE 166.0f //MAX visible range (size of grid)
67
68
69/*
70 TODO: Add more script type classes.
71
72 MailScript
73 SessionScript
74 CollisionScript
75 ArenaTeamScript
76
77*/
78
79/*
80 Standard procedure when adding new script type classes:
81
82 First of all, define the actual class, and have it inherit from ScriptObject, like so:
83
84 class MyScriptType : public ScriptObject
85 {
86 uint32 _someId;
87
88 private:
89
90 void RegisterSelf();
91
92 protected:
93
94 MyScriptType(const char* name, uint32 someId)
95 : ScriptObject(name), _someId(someId)
96 {
97 ScriptRegistry<MyScriptType>::AddScript(this);
98 }
99
100 public:
101
102 // If a virtual function in your script type class is not necessarily
103 // required to be overridden, just declare it virtual with an empty
104 // body. If, on the other hand, it's logical only to override it (i.e.
105 // if it's the only method in the class), make it pure virtual, by adding
106 // = 0 to it.
107 virtual void OnSomeEvent(uint32 someArg1, std::string& someArg2) { }
108
109 // This is a pure virtual function:
110 virtual void OnAnotherEvent(uint32 someArg) = 0;
111 }
112
113 Next, you need to add a specialization for ScriptRegistry. Put this in the bottom of
114 ScriptMgr.cpp:
115
116 template class ScriptRegistry<MyScriptType>;
117
118 Now, add a cleanup routine in ScriptMgr::~ScriptMgr:
119
120 SCR_CLEAR(MyScriptType);
121
122 Now your script type is good to go with the script system. What you need to do now
123 is add functions to ScriptMgr that can be called from the core to actually trigger
124 certain events. For example, in ScriptMgr.h:
125
126 void OnSomeEvent(uint32 someArg1, std::string& someArg2);
127 void OnAnotherEvent(uint32 someArg);
128
129 In ScriptMgr.cpp:
130
131 void ScriptMgr::OnSomeEvent(uint32 someArg1, std::string& someArg2)
132 {
133 FOREACH_SCRIPT(MyScriptType)->OnSomeEvent(someArg1, someArg2);
134 }
135
136 void ScriptMgr::OnAnotherEvent(uint32 someArg)
137 {
138 FOREACH_SCRIPT(MyScriptType)->OnAnotherEvent(someArg1, someArg2);
139 }
140
141 Now you simply call these two functions from anywhere in the core to trigger the
142 event on all registered scripts of that type.
143*/
144
145class ScriptObject
146{
147 friend class ScriptMgr;
148
149 public:
150
151 // Do not override this in scripts; it should be overridden by the various script type classes. It indicates
152 // whether or not this script type must be assigned in the database.
153 virtual bool IsDatabaseBound() const { return false; }
154 virtual bool isAfterLoadScript() const { return IsDatabaseBound(); }
155 virtual void checkValidity() { }
156
157 const std::string& GetName() const { return _name; }
158
159 protected:
160
161 ScriptObject(const char* name)
162 : _name(std::string(name))
163 {
164 }
165
166 virtual ~ScriptObject()
167 {
168 }
169
170 private:
171
172 const std::string _name;
173};
174
175template<class TObject> class UpdatableScript
176{
177 protected:
178
179 UpdatableScript()
180 {
181 }
182
183 public:
184
185 virtual void OnUpdate(TObject* /*obj*/, uint32 /*diff*/) { }
186};
187
188class SpellScriptLoader : public ScriptObject
189{
190 protected:
191
192 SpellScriptLoader(const char* name);
193
194 public:
195
196 bool IsDatabaseBound() const { return true; }
197
198 // Should return a fully valid SpellScript pointer.
199 virtual SpellScript* GetSpellScript() const { return NULL; }
200
201 // Should return a fully valid AuraScript pointer.
202 virtual AuraScript* GetAuraScript() const { return NULL; }
203};
204
205class ServerScript : public ScriptObject
206{
207 protected:
208
209 ServerScript(const char* name);
210
211 public:
212
213 // Called when reactive socket I/O is started (WorldSocketMgr).
214 virtual void OnNetworkStart() { }
215
216 // Called when reactive I/O is stopped.
217 virtual void OnNetworkStop() { }
218
219 // Called when a remote socket establishes a connection to the server. Do not store the socket object.
220 virtual void OnSocketOpen(WorldSocket* /*socket*/) { }
221
222 // Called when a socket is closed. Do not store the socket object, and do not rely on the connection
223 // being open; it is not.
224 virtual void OnSocketClose(WorldSocket* /*socket*/, bool /*wasNew*/) { }
225};
226
227class WorldScript : public ScriptObject
228{
229 protected:
230
231 WorldScript(const char* name);
232
233 public:
234
235 // Called when the open/closed state of the world changes.
236 virtual void OnOpenStateChange(bool /*open*/) { }
237
238 // Called after the world configuration is (re)loaded.
239 virtual void OnAfterConfigLoad(bool /*reload*/) { }
240
241 // Called before the world configuration is (re)loaded.
242 virtual void OnBeforeConfigLoad(bool /*reload*/) { }
243
244 // Called before the message of the day is changed.
245 virtual void OnMotdChange(std::string& /*newMotd*/) { }
246
247 // Called when a world shutdown is initiated.
248 virtual void OnShutdownInitiate(ShutdownExitCode /*code*/, ShutdownMask /*mask*/) { }
249
250 // Called when a world shutdown is cancelled.
251 virtual void OnShutdownCancel() { }
252
253 // Called on every world tick (don't execute too heavy code here).
254 virtual void OnUpdate(uint32 /*diff*/) { }
255
256 // Called when the world is started.
257 virtual void OnStartup() { }
258
259 // Called when the world is actually shut down.
260 virtual void OnShutdown() { }
261};
262
263class FormulaScript : public ScriptObject
264{
265 protected:
266
267 FormulaScript(const char* name);
268
269 public:
270
271 // Called after calculating honor.
272 virtual void OnHonorCalculation(float& /*honor*/, uint8 /*level*/, float /*multiplier*/) { }
273
274 // Called after gray level calculation.
275 virtual void OnGrayLevelCalculation(uint8& /*grayLevel*/, uint8 /*playerLevel*/) { }
276
277 // Called after calculating experience color.
278 virtual void OnColorCodeCalculation(XPColorChar& /*color*/, uint8 /*playerLevel*/, uint8 /*mobLevel*/) { }
279
280 // Called after calculating zero difference.
281 virtual void OnZeroDifferenceCalculation(uint8& /*diff*/, uint8 /*playerLevel*/) { }
282
283 // Called after calculating base experience gain.
284 virtual void OnBaseGainCalculation(uint32& /*gain*/, uint8 /*playerLevel*/, uint8 /*mobLevel*/, ContentLevels /*content*/) { }
285
286 // Called after calculating experience gain.
287 virtual void OnGainCalculation(uint32& /*gain*/, Player* /*player*/, Unit* /*unit*/) { }
288
289 // Called when calculating the experience rate for group experience.
290 virtual void OnGroupRateCalculation(float& /*rate*/, uint32 /*count*/, bool /*isRaid*/) { }
291
292 // Called after calculating arena rating changes
293 virtual void OnAfterArenaRatingCalculation(Battleground *const /*bg*/, int32& /*winnerMatchmakerChange*/, int32& /*loserMatchmakerChange*/, int32& /*winnerChange*/, int32& /*loserChange*/) { };
294};
295
296template<class TMap> class MapScript : public UpdatableScript<TMap>
297{
298 MapEntry const* _mapEntry;
299 uint32 _mapId;
300
301 protected:
302
303 MapScript(uint32 mapId)
304 : _mapId(mapId)
305 {
306 }
307
308 public:
309 void checkMap() {
310 _mapEntry = sMapStore.LookupEntry(_mapId);
311
312 if (!_mapEntry)
313 sLog->outError("Invalid MapScript for %u; no such map ID.", _mapId);
314 }
315
316 // Gets the MapEntry structure associated with this script. Can return NULL.
317 MapEntry const* GetEntry() { return _mapEntry; }
318
319 // Called when the map is created.
320 virtual void OnCreate(TMap* /*map*/) { }
321
322 // Called just before the map is destroyed.
323 virtual void OnDestroy(TMap* /*map*/) { }
324
325 // Called when a grid map is loaded.
326 virtual void OnLoadGridMap(TMap* /*map*/, GridMap* /*gmap*/, uint32 /*gx*/, uint32 /*gy*/) { }
327
328 // Called when a grid map is unloaded.
329 virtual void OnUnloadGridMap(TMap* /*map*/, GridMap* /*gmap*/, uint32 /*gx*/, uint32 /*gy*/) { }
330
331 // Called when a player enters the map.
332 virtual void OnPlayerEnter(TMap* /*map*/, Player* /*player*/) { }
333
334 // Called when a player leaves the map.
335 virtual void OnPlayerLeave(TMap* /*map*/, Player* /*player*/) { }
336
337 // Called on every map update tick.
338 virtual void OnUpdate(TMap* /*map*/, uint32 /*diff*/) { }
339};
340
341class WorldMapScript : public ScriptObject, public MapScript<Map>
342{
343 protected:
344
345 WorldMapScript(const char* name, uint32 mapId);
346
347 public:
348
349 bool isAfterLoadScript() const { return true; }
350
351 void checkValidity() {
352 checkMap();
353
354 if (GetEntry() && !GetEntry()->IsWorldMap())
355 sLog->outError("WorldMapScript for map %u is invalid.", GetEntry()->MapID);
356 }
357};
358
359class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
360{
361 protected:
362
363 InstanceMapScript(const char* name, uint32 mapId);
364
365 public:
366
367 bool IsDatabaseBound() const { return true; }
368
369 void checkValidity() {
370 checkMap();
371
372 if (GetEntry() && !GetEntry()->IsDungeon())
373 sLog->outError("InstanceMapScript for map %u is invalid.", GetEntry()->MapID);
374 }
375
376 // Gets an InstanceScript object for this instance.
377 virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; }
378};
379
380class BattlegroundMapScript : public ScriptObject, public MapScript<BattlegroundMap>
381{
382 protected:
383
384 BattlegroundMapScript(const char* name, uint32 mapId);
385
386 public:
387
388 bool isAfterLoadScript() const { return true; }
389
390 void checkValidity() {
391 checkMap();
392
393 if (GetEntry() && !GetEntry()->IsBattleground())
394 sLog->outError("BattlegroundMapScript for map %u is invalid.", GetEntry()->MapID);
395 }
396};
397
398class ItemScript : public ScriptObject
399{
400 protected:
401
402 ItemScript(const char* name);
403
404 public:
405
406 bool IsDatabaseBound() const { return true; }
407
408 // Called when a player accepts a quest from the item.
409 virtual bool OnQuestAccept(Player* /*player*/, Item* /*item*/, Quest const* /*quest*/) { return false; }
410
411 // Called when a player uses the item.
412 virtual bool OnUse(Player* /*player*/, Item* /*item*/, SpellCastTargets const& /*targets*/) { return false; }
413
414 // Called when the item expires (is destroyed).
415 virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; }
416
417 // Called when a player selects an option in an item gossip window
418 virtual void OnGossipSelect(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/) { }
419
420 // Called when a player selects an option in an item gossip window
421 virtual void OnGossipSelectCode(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { }
422};
423
424class UnitScript : public ScriptObject
425{
426protected:
427
428 UnitScript(const char* name, bool addToScripts = true);
429
430public:
431 // Called when a unit deals healing to another unit
432 virtual void OnHeal(Unit* /*healer*/, Unit* /*reciever*/, uint32& /*gain*/) { }
433
434 // Called when a unit deals damage to another unit
435 virtual void OnDamage(Unit* /*attacker*/, Unit* /*victim*/, uint32& /*damage*/) { }
436
437 // Called when DoT's Tick Damage is being Dealt
438 virtual void ModifyPeriodicDamageAurasTick(Unit* /*target*/, Unit* /*attacker*/, uint32& /*damage*/) { }
439
440 // Called when Melee Damage is being Dealt
441 virtual void ModifyMeleeDamage(Unit* /*target*/, Unit* /*attacker*/, uint32& /*damage*/) { }
442
443 // Called when Spell Damage is being Dealt
444 virtual void ModifySpellDamageTaken(Unit* /*target*/, Unit* /*attacker*/, int32& /*damage*/) { }
445
446 // Called when Heal is Recieved
447 virtual void ModifyHealRecieved(Unit* /*target*/, Unit* /*attacker*/, uint32& /*damage*/) { }
448
449 //Called when Damage is Dealt
450 virtual uint32 DealDamage(Unit* /*AttackerUnit*/, Unit* /*pVictim*/, uint32 damage, DamageEffectType /*damagetype*/) { return damage; }
451
452 virtual void OnBeforeRollMeleeOutcomeAgainst(const Unit* /*attacker*/, const Unit* /*victim*/, WeaponAttackType /*attType*/, int32 &/*attackerMaxSkillValueForLevel*/, int32 &/*victimMaxSkillValueForLevel*/, int32 &/*attackerWeaponSkill*/, int32 &/*victimDefenseSkill*/, int32& /*crit_chance*/, int32& /*miss_chance*/ , int32& /*dodge_chance*/ , int32& /*parry_chance*/ , int32& /*block_chance*/ ) { };
453};
454
455class MovementHandlerScript : public ScriptObject
456{
457protected:
458
459 MovementHandlerScript(const char* name);
460
461public:
462
463 //Called whenever a player moves
464 virtual void OnPlayerMove(Player* /*player*/, MovementInfo /*movementInfo*/, uint32 /*opcode*/) { }
465};
466
467class AllMapScript : public ScriptObject
468{
469protected:
470
471 AllMapScript(const char* name);
472
473public:
474
475 // Called when a player enters any Map
476 virtual void OnPlayerEnterAll(Map* /*map*/, Player* /*player*/) { }
477
478 // Called when a player leave any Map
479 virtual void OnPlayerLeaveAll(Map* /*map*/, Player* /*player*/) { }
480};
481
482class AllCreatureScript : public ScriptObject
483{
484protected:
485
486 AllCreatureScript(const char* name);
487
488public:
489
490 // Called from End of Creature Update.
491 virtual void OnAllCreatureUpdate(Creature* /*creature*/, uint32 /*diff*/) { }
492
493 // Called from End of Creature SelectLevel.
494 virtual void Creature_SelectLevel(const CreatureTemplate* /*cinfo*/, Creature* /*creature*/) { }
495};
496
497class CreatureScript : public ScriptObject, public UpdatableScript<Creature>
498{
499 protected:
500
501 CreatureScript(const char* name);
502
503 public:
504
505 bool IsDatabaseBound() const { return true; }
506
507 // Called when a player opens a gossip dialog with the creature.
508 virtual bool OnGossipHello(Player* /*player*/, Creature* /*creature*/) { return false; }
509
510 // Called when a player selects a gossip item in the creature's gossip menu.
511 virtual bool OnGossipSelect(Player* /*player*/, Creature* /*creature*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
512
513 // Called when a player selects a gossip with a code in the creature's gossip menu.
514 virtual bool OnGossipSelectCode(Player* /*player*/, Creature* /*creature*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { return false; }
515
516 // Called when a player accepts a quest from the creature.
517 virtual bool OnQuestAccept(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; }
518
519 // Called when a player selects a quest in the creature's quest menu.
520 virtual bool OnQuestSelect(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; }
521
522 // Called when a player completes a quest with the creature.
523 virtual bool OnQuestComplete(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; }
524
525 // Called when a player selects a quest reward.
526 virtual bool OnQuestReward(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; }
527
528 // Called when the dialog status between a player and the creature is requested.
529 virtual uint32 GetDialogStatus(Player* /*player*/, Creature* /*creature*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; }
530
531 // Called when a CreatureAI object is needed for the creature.
532 virtual CreatureAI* GetAI(Creature* /*creature*/) const { return NULL; }
533};
534
535class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
536{
537 protected:
538
539 GameObjectScript(const char* name);
540
541 public:
542
543 bool IsDatabaseBound() const { return true; }
544
545 // Called when a player opens a gossip dialog with the gameobject.
546 virtual bool OnGossipHello(Player* /*player*/, GameObject* /*go*/) { return false; }
547
548 // Called when a player selects a gossip item in the gameobject's gossip menu.
549 virtual bool OnGossipSelect(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
550
551 // Called when a player selects a gossip with a code in the gameobject's gossip menu.
552 virtual bool OnGossipSelectCode(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { return false; }
553
554 // Called when a player accepts a quest from the gameobject.
555 virtual bool OnQuestAccept(Player* /*player*/, GameObject* /*go*/, Quest const* /*quest*/) { return false; }
556
557 // Called when a player selects a quest reward.
558 virtual bool OnQuestReward(Player* /*player*/, GameObject* /*go*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; }
559
560 // Called when the dialog status between a player and the gameobject is requested.
561 virtual uint32 GetDialogStatus(Player* /*player*/, GameObject* /*go*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; }
562
563 // Called when the game object is destroyed (destructible buildings only).
564 virtual void OnDestroyed(GameObject* /*go*/, Player* /*player*/) { }
565
566 // Called when the game object is damaged (destructible buildings only).
567 virtual void OnDamaged(GameObject* /*go*/, Player* /*player*/) { }
568
569 // Called when the game object loot state is changed.
570 virtual void OnLootStateChanged(GameObject* /*go*/, uint32 /*state*/, Unit* /*unit*/) { }
571
572 // Called when the game object state is changed.
573 virtual void OnGameObjectStateChanged(GameObject* /*go*/, uint32 /*state*/) { }
574
575 // Called when a GameObjectAI object is needed for the gameobject.
576 virtual GameObjectAI* GetAI(GameObject* /*go*/) const { return NULL; }
577};
578
579class AreaTriggerScript : public ScriptObject
580{
581 protected:
582
583 AreaTriggerScript(const char* name);
584
585 public:
586
587 bool IsDatabaseBound() const { return true; }
588
589 // Called when the area trigger is activated by a player.
590 virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/) { return false; }
591};
592
593class BattlegroundScript : public ScriptObject
594{
595 protected:
596
597 BattlegroundScript(const char* name);
598
599 public:
600
601 bool IsDatabaseBound() const { return true; }
602
603 // Should return a fully valid Battleground object for the type ID.
604 virtual Battleground* GetBattleground() const = 0;
605
606};
607
608class OutdoorPvPScript : public ScriptObject
609{
610 protected:
611
612 OutdoorPvPScript(const char* name);
613
614 public:
615
616 bool IsDatabaseBound() const { return true; }
617
618 // Should return a fully valid OutdoorPvP object for the type ID.
619 virtual OutdoorPvP* GetOutdoorPvP() const = 0;
620};
621
622class CommandScript : public ScriptObject
623{
624 protected:
625
626 CommandScript(const char* name);
627
628 public:
629
630 // Should return a pointer to a valid command table (ChatCommand array) to be used by ChatHandler.
631 virtual std::vector<ChatCommand> GetCommands() const = 0;
632};
633
634class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
635{
636 protected:
637
638 WeatherScript(const char* name);
639
640 public:
641
642 bool IsDatabaseBound() const { return true; }
643
644 // Called when the weather changes in the zone this script is associated with.
645 virtual void OnChange(Weather* /*weather*/, WeatherState /*state*/, float /*grade*/) { }
646};
647
648class AuctionHouseScript : public ScriptObject
649{
650 protected:
651
652 AuctionHouseScript(const char* name);
653
654 public:
655
656 // Called when an auction is added to an auction house.
657 virtual void OnAuctionAdd(AuctionHouseObject* /*ah*/, AuctionEntry* /*entry*/) { }
658
659 // Called when an auction is removed from an auction house.
660 virtual void OnAuctionRemove(AuctionHouseObject* /*ah*/, AuctionEntry* /*entry*/) { }
661
662 // Called when an auction was succesfully completed.
663 virtual void OnAuctionSuccessful(AuctionHouseObject* /*ah*/, AuctionEntry* /*entry*/) { }
664
665 // Called when an auction expires.
666 virtual void OnAuctionExpire(AuctionHouseObject* /*ah*/, AuctionEntry* /*entry*/) { }
667};
668
669class ConditionScript : public ScriptObject
670{
671 protected:
672
673 ConditionScript(const char* name);
674
675 public:
676
677 bool IsDatabaseBound() const { return true; }
678
679 // Called when a single condition is checked for a player.
680 virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
681};
682
683class VehicleScript : public ScriptObject
684{
685 protected:
686
687 VehicleScript(const char* name);
688
689 public:
690
691 // Called after a vehicle is installed.
692 virtual void OnInstall(Vehicle* /*veh*/) { }
693
694 // Called after a vehicle is uninstalled.
695 virtual void OnUninstall(Vehicle* /*veh*/) { }
696
697 // Called when a vehicle resets.
698 virtual void OnReset(Vehicle* /*veh*/) { }
699
700 // Called after an accessory is installed in a vehicle.
701 virtual void OnInstallAccessory(Vehicle* /*veh*/, Creature* /*accessory*/) { }
702
703 // Called after a passenger is added to a vehicle.
704 virtual void OnAddPassenger(Vehicle* /*veh*/, Unit* /*passenger*/, int8 /*seatId*/) { }
705
706 // Called after a passenger is removed from a vehicle.
707 virtual void OnRemovePassenger(Vehicle* /*veh*/, Unit* /*passenger*/) { }
708};
709
710class DynamicObjectScript : public ScriptObject, public UpdatableScript<DynamicObject>
711{
712 protected:
713
714 DynamicObjectScript(const char* name);
715};
716
717class TransportScript : public ScriptObject, public UpdatableScript<Transport>
718{
719 protected:
720
721 TransportScript(const char* name);
722
723 public:
724
725 bool IsDatabaseBound() const { return true; }
726
727 // Called when a player boards the transport.
728 virtual void OnAddPassenger(Transport* /*transport*/, Player* /*player*/) { }
729
730 // Called when a creature boards the transport.
731 virtual void OnAddCreaturePassenger(Transport* /*transport*/, Creature* /*creature*/) { }
732
733 // Called when a player exits the transport.
734 virtual void OnRemovePassenger(Transport* /*transport*/, Player* /*player*/) { }
735
736 // Called when a transport moves.
737 virtual void OnRelocate(Transport* /*transport*/, uint32 /*waypointId*/, uint32 /*mapId*/, float /*x*/, float /*y*/, float /*z*/) { }
738};
739
740class AchievementCriteriaScript : public ScriptObject
741{
742 protected:
743
744 AchievementCriteriaScript(const char* name);
745
746 public:
747
748 bool IsDatabaseBound() const { return true; }
749
750 // Called when an additional criteria is checked.
751 virtual bool OnCheck(Player* source, Unit* target, uint32 /*criteria_id*/) {
752 return OnCheck(source, target);
753 }
754 // deprecated/legacy
755 virtual bool OnCheck(Player* /*source*/, Unit* /*target*/) { return true; };
756};
757
758class PlayerScript : public ScriptObject
759{
760 protected:
761
762 PlayerScript(const char* name);
763
764 public:
765 virtual void OnPlayerReleasedGhost(Player* /*player*/) { }
766
767 // Called when a player kills another player
768 virtual void OnPVPKill(Player* /*killer*/, Player* /*killed*/) { }
769
770 // Called when a player kills a creature
771 virtual void OnCreatureKill(Player* /*killer*/, Creature* /*killed*/) { }
772
773 // Called when a player is killed by a creature
774 virtual void OnPlayerKilledByCreature(Creature* /*killer*/, Player* /*killed*/) { }
775
776 // Called when a player's level changes (right before the level is applied)
777 virtual void OnLevelChanged(Player* /*player*/, uint8 /*newLevel*/) { }
778
779 // Called when a player's free talent points change (right before the change is applied)
780 virtual void OnFreeTalentPointsChanged(Player* /*player*/, uint32 /*points*/) { }
781
782 // Called when a player's talent points are reset (right before the reset is done)
783 virtual void OnTalentsReset(Player* /*player*/, bool /*noCost*/) { }
784
785 // Called for player::update
786 virtual void OnBeforeUpdate(Player* /*player*/, uint32 /*p_time*/){ }
787
788 // Called when a player's money is modified (before the modification is done)
789 virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { }
790
791 // Called when a player gains XP (before anything is given)
792 virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { }
793
794 // Called when a player's reputation changes (before it is actually changed)
795 virtual void OnReputationChange(Player* /*player*/, uint32 /*factionId*/, int32& /*standing*/, bool /*incremental*/) { }
796
797 // Called when a duel is requested
798 virtual void OnDuelRequest(Player* /*target*/, Player* /*challenger*/) { }
799
800 // Called when a duel starts (after 3s countdown)
801 virtual void OnDuelStart(Player* /*player1*/, Player* /*player2*/) { }
802
803 // Called when a duel ends
804 virtual void OnDuelEnd(Player* /*winner*/, Player* /*loser*/, DuelCompleteType /*type*/) { }
805
806 // The following methods are called when a player sends a chat message.
807 virtual void OnChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/) { }
808
809 virtual void OnChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Player* /*receiver*/) { }
810
811 virtual void OnChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Group* /*group*/) { }
812
813 virtual void OnChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Guild* /*guild*/) { }
814
815 virtual void OnChat(Player* /*player*/, uint32 /*type*/, uint32 /*lang*/, std::string& /*msg*/, Channel* /*channel*/) { }
816
817 // Both of the below are called on emote opcodes.
818 virtual void OnEmote(Player* /*player*/, uint32 /*emote*/) { }
819
820 virtual void OnTextEmote(Player* /*player*/, uint32 /*textEmote*/, uint32 /*emoteNum*/, uint64 /*guid*/) { }
821
822 // Called in Spell::Cast.
823 virtual void OnSpellCast(Player* /*player*/, Spell* /*spell*/, bool /*skipCheck*/) { }
824
825 // Called during data loading
826 virtual void OnLoadFromDB(Player* /*player*/) { };
827
828 // Called when a player logs in.
829 virtual void OnLogin(Player* /*player*/) { }
830
831 // Called when a player logs out.
832 virtual void OnLogout(Player* /*player*/) { }
833
834 // Called when a player is created.
835 virtual void OnCreate(Player* /*player*/) { }
836
837 // Called when a player is deleted.
838 virtual void OnDelete(uint64 /*guid*/) { }
839
840 // Called when a player is bound to an instance
841 virtual void OnBindToInstance(Player* /*player*/, Difficulty /*difficulty*/, uint32 /*mapId*/, bool /*permanent*/) { }
842
843 // Called when a player switches to a new zone
844 virtual void OnUpdateZone(Player* /*player*/, uint32 /*newZone*/, uint32 /*newArea*/) { }
845
846 // Called when a player switches to a new area (more accurate than UpdateZone)
847 virtual void OnUpdateArea(Player* /*player*/, uint32 /*oldArea*/, uint32 /*newArea*/) { }
848
849 // Called when a player changes to a new map (after moving to new map)
850 virtual void OnMapChanged(Player* /*player*/) { }
851
852 // Called before a player is being teleported to new coords
853 virtual bool OnBeforeTeleport(Player* /*player*/, uint32 /*mapid*/, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) { return true; }
854
855 // Called when team/faction is set on player
856 virtual void OnUpdateFaction(Player* /*player*/) { }
857
858 // Called when a player is added to battleground
859 virtual void OnAddToBattleground(Player* /*player*/, Battleground* /*bg*/) { }
860
861 // Called when a player is removed from battleground
862 virtual void OnRemoveFromBattleground(Player* /*player*/, Battleground* /*bg*/) { }
863
864 // Called when a player complete an achievement
865 virtual void OnAchiComplete(Player* /*player*/, AchievementEntry const* /*achievement*/) { }
866
867 // Called when a player complete an achievement criteria
868 virtual void OnCriteriaProgress(Player* /*player*/, AchievementCriteriaEntry const* /*criteria*/) { }
869
870 // Called when an Achievement is saved to DB
871 virtual void OnAchiSave(SQLTransaction& /*trans*/, Player* /*player*/, uint16 /*achId*/, CompletedAchievementData /*achiData*/) { }
872
873 // Called when an Criteria is saved to DB
874 virtual void OnCriteriaSave(SQLTransaction& /*trans*/, Player* /*player*/, uint16 /*achId*/, CriteriaProgress /*criteriaData*/) { }
875
876 // Called when a player selects an option in a player gossip window
877 virtual void OnGossipSelect(Player* /*player*/, uint32 /*menu_id*/, uint32 /*sender*/, uint32 /*action*/) { }
878
879 // Called when a player selects an option in a player gossip window
880 virtual void OnGossipSelectCode(Player* /*player*/, uint32 /*menu_id*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { }
881
882 // On player getting charmed
883 virtual void OnBeingCharmed(Player* /*player*/, Unit* /*charmer*/, uint32 /*oldFactionId*/, uint32 /*newFactionId*/) { }
884
885 // To change behaviour of set visible item slot
886 virtual void OnAfterSetVisibleItemSlot(Player* /*player*/, uint8 /*slot*/, Item* /*item*/) { }
887
888 // After an item has been moved from inventory
889 virtual void OnAfterMoveItemFromInventory(Player* /*player*/, Item* /*it*/, uint8 /*bag*/, uint8 /*slot*/, bool /*update*/) { }
890
891 // After an item has been equipped
892 virtual void OnEquip(Player* /*player*/, Item* /*it*/, uint8 /*bag*/, uint8 /*slot*/, bool /*update*/) { }
893
894 // After player enters queue for BG
895 virtual void OnPlayerJoinBG(Player* /*player*/) { }
896
897 // After player enters queue for Arena
898 virtual void OnPlayerJoinArena(Player* /*player*/) { }
899
900 //After looting item
901 virtual void OnLootItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/, uint64 /*lootguid*/) { }
902
903 //After creating item (eg profession item creation)
904 virtual void OnCreateItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { }
905
906 //After receiving item as a quest reward
907 virtual void OnQuestRewardItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { }
908
909 //Before buying something from any vendor
910 virtual void OnBeforeBuyItemFromVendor(Player* /*player*/, uint64 /*vendorguid*/, uint32 /*vendorslot*/, uint32 &/*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/) { };
911
912 //Before buying something from any vendor
913 virtual void OnAfterStoreOrEquipNewItem(Player* /*player*/, uint32 /*vendorslot*/, uint32& /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/, ItemTemplate const* /*pProto*/, Creature* /*pVendor*/, VendorItem const* /*crItem*/, bool /*bStore*/) { };
914
915 virtual void OnAfterUpdateMaxPower(Player* /*player*/, Powers& /*power*/, float& /*value*/) { }
916
917 virtual void OnAfterUpdateMaxHealth(Player* /*player*/, float& /*value*/) { }
918
919 virtual void OnBeforeUpdateAttackPowerAndDamage(Player* /*player*/, float& /*level*/, float& /*val2*/, bool /*ranged*/) { }
920 virtual void OnAfterUpdateAttackPowerAndDamage(Player* /*player*/, float& /*level*/, float& /*base_attPower*/, float& /*attPowerMod*/, float& /*attPowerMultiplier*/, bool /*ranged*/) { }
921
922 virtual void OnBeforeInitTalentForLevel(Player* /*player*/, uint8& /*level*/, uint32& /*talentPointsForLevel*/) { }
923
924 virtual void OnFirstLogin(Player* /*player*/) { }
925};
926
927class GuildScript : public ScriptObject
928{
929 protected:
930
931 GuildScript(const char* name);
932
933 public:
934
935 bool IsDatabaseBound() const { return false; }
936
937 // Called when a member is added to the guild.
938 virtual void OnAddMember(Guild* /*guild*/, Player* /*player*/, uint8& /*plRank*/) { }
939
940 // Called when a member is removed from the guild.
941 virtual void OnRemoveMember(Guild* /*guild*/, Player* /*player*/, bool /*isDisbanding*/, bool /*isKicked*/) { }
942
943 // Called when the guild MOTD (message of the day) changes.
944 virtual void OnMOTDChanged(Guild* /*guild*/, const std::string& /*newMotd*/) { }
945
946 // Called when the guild info is altered.
947 virtual void OnInfoChanged(Guild* /*guild*/, const std::string& /*newInfo*/) { }
948
949 // Called when a guild is created.
950 virtual void OnCreate(Guild* /*guild*/, Player* /*leader*/, const std::string& /*name*/) { }
951
952 // Called when a guild is disbanded.
953 virtual void OnDisband(Guild* /*guild*/) { }
954
955 // Called when a guild member withdraws money from a guild bank.
956 virtual void OnMemberWitdrawMoney(Guild* /*guild*/, Player* /*player*/, uint32& /*amount*/, bool /*isRepair*/) { }
957
958 // Called when a guild member deposits money in a guild bank.
959 virtual void OnMemberDepositMoney(Guild* /*guild*/, Player* /*player*/, uint32& /*amount*/) { }
960
961 // Called when a guild member moves an item in a guild bank.
962 virtual void OnItemMove(Guild* /*guild*/, Player* /*player*/, Item* /*pItem*/, bool /*isSrcBank*/, uint8 /*srcContainer*/, uint8 /*srcSlotId*/,
963 bool /*isDestBank*/, uint8 /*destContainer*/, uint8 /*destSlotId*/) { }
964
965 virtual void OnEvent(Guild* /*guild*/, uint8 /*eventType*/, uint32 /*playerGuid1*/, uint32 /*playerGuid2*/, uint8 /*newRank*/) { }
966
967 virtual void OnBankEvent(Guild* /*guild*/, uint8 /*eventType*/, uint8 /*tabId*/, uint32 /*playerGuid*/, uint32 /*itemOrMoney*/, uint16 /*itemStackCount*/, uint8 /*destTabId*/) { }
968};
969
970class GroupScript : public ScriptObject
971{
972 protected:
973
974 GroupScript(const char* name);
975
976 public:
977
978 bool IsDatabaseBound() const { return false; }
979
980 // Called when a member is added to a group.
981 virtual void OnAddMember(Group* /*group*/, uint64 /*guid*/) { }
982
983 // Called when a member is invited to join a group.
984 virtual void OnInviteMember(Group* /*group*/, uint64 /*guid*/) { }
985
986 // Called when a member is removed from a group.
987 virtual void OnRemoveMember(Group* /*group*/, uint64 /*guid*/, RemoveMethod /*method*/, uint64 /*kicker*/, const char* /*reason*/) { }
988
989 // Called when the leader of a group is changed.
990 virtual void OnChangeLeader(Group* /*group*/, uint64 /*newLeaderGuid*/, uint64 /*oldLeaderGuid*/) { }
991
992 // Called when a group is disbanded.
993 virtual void OnDisband(Group* /*group*/) { }
994};
995
996// following hooks can be used anywhere and are not db bounded
997class GlobalScript : public ScriptObject
998{
999 protected:
1000
1001 GlobalScript(const char* name);
1002
1003 public:
1004
1005 // items
1006 virtual void OnItemDelFromDB(SQLTransaction& /*trans*/, uint32 /*itemGuid*/) { }
1007 virtual void OnMirrorImageDisplayItem(const Item* /*item*/, uint32& /*display*/) { }
1008
1009 // loot
1010 virtual void OnAfterRefCount(Player const* /*player*/, LootStoreItem* /*LootStoreItem*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, uint32& /*maxcount*/, LootStore const& /*store*/) { }
1011 virtual void OnBeforeDropAddItem(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { }
1012 virtual void OnItemRoll(Player const* /*player*/, LootStoreItem const* /*LootStoreItem*/, float& /*chance*/, Loot& /*loot*/, LootStore const& /*store*/) { };
1013
1014 virtual void OnInitializeLockedDungeons(Player* /*player*/, uint8& /*level*/, uint32& /*lockData*/) { }
1015 virtual void OnAfterInitializeLockedDungeons(Player* /*player*/) { }
1016
1017 // On Before arena points distribution
1018 virtual void OnBeforeUpdateArenaPoints(ArenaTeam* /*at*/, std::map<uint32, uint32> & /*ap*/) { }
1019};
1020
1021// ##################### Abstract AIO handler script #####################
1022// Inherit AIOScript to make an AIO handler script
1023//
1024// See smallfork_cpp at https://github.com/Rochet2/smallfolk_cpp for
1025// reference on how to use LuaVal
1026//
1027// Example of use:
1028//
1029// class ExampleAIOScript : public AIOScript
1030// {
1031// public:
1032// ExampleAIOScript()
1033// : AIOScript("ExampleScriptName")
1034// {
1035// using namespace std::placeholders;
1036//
1037// // Loads addon files to addons list and sends them on AIO client initialization
1038// // Looks for the file in path config AIO.ClientScriptPath
1039// AddAddon(World::AIOAddon("ExampleAddon", "example_addon.lua"));
1040//
1041// // You can also add addons to be sent to players with specific permission
1042// AddAddon(World::AIOAddon("AnotherAddon", "example_addon.lua", 192)); //192 refers to admin RBAC permission
1043//
1044// // Handler function signature: void HandlerFunction(Player *sender, const LuaVal &args)
1045// AddHandler("Print", std::bind(&ExampleAIOScript::HandlePrint, this, _1, _2));
1046// AddHandler("Save", std::bind(&ExampleAIOScript::HandleSave, this, _1, _2));
1047//
1048// // Initialization handler and arguments
1049// AddInitArgs("ExampleScriptName", "Init", std::bind(&ExampleAIOScript::InitArg, this, _1), std::bind(&ExampleAIOScript::InitArg, this, _1));
1050// //Adds additional argument to send to handler
1051// AddInitArgs("ExampleScriptName", "Init", std::bind(&ExampleAIOScript::InitArg2, this, _1));
1052// AddInitArgs("AnotherScript", "InitB"); //Arguments are not necessary
1053// }
1054//
1055// void HandlePrint(Player *sender, const LuaVal &args)
1056// {
1057// //LuaVal args in a handler function is always a table
1058// //Handler arguments index starts from 4
1059// LuaVal &InputVal = args[4];
1060// LuaVal &SliderVal = args[5];
1061//
1062// //MUST check if the value type is valid or else smallfolk_cpp will
1063// //throw on obtaining that type
1064// if(!InputVal.isstring() || !SliderVal.isnumber())
1065// {
1066// return;
1067// }
1068//
1069// sender->GetSession()->SendNotification("HandlePrint -> Stored String: %s, Input: %s, Slider Value: %f",
1070// storedString.c_str(), InputVal.str().c_str(), SliderVal.num());
1071// }
1072//
1073// void HandleSave(Player *sender, const LuaVal &args)
1074// {
1075// //LuaVal args in a handler function is always a table
1076// //Handler arguments index starts from 4
1077// LuaVal &SaveVal = args.get[4];
1078//
1079// //MUST check if the value type is valid
1080// if(!SaveVal.isstring())
1081// {
1082// return;
1083// }
1084//
1085// storedString = SaveVal.str();
1086// sender->GetSession()->SendNotification("Saved");
1087// }
1088//
1089// LuaVal InitArg(Player *sender)
1090// {
1091// LuaVal arg = LuaVal(TTABLE);
1092// arg.set("key", 12.3);
1093// arg["key2"] = false;
1094//
1095// return arg;
1096// }
1097//
1098// LuaVal InitArg2(Player *sender)
1099// {
1100// return "LuaVal will implicitly create a string LuaVal for this arg";
1101// }
1102//
1103// private:
1104// std::string storedString;
1105// };
1106class AIOScript : public ScriptObject
1107{
1108public:
1109 virtual ~AIOScript() { AIOScript::_scriptByKeyMap.erase(GetKey()); }
1110
1111 // Returns the key of this CAIO script
1112 LuaVal GetKey() const { return _key; }
1113 bool IsDatabaseBound() const { return false; }
1114
1115 typedef std::function<void(Player*, const LuaVal&)> HandlerFunc;
1116 typedef std::function<LuaVal(Player*)> ArgFunc;
1117
1118protected:
1119 // Registers an AIO Handler script of scriptName
1120 AIOScript(const LuaVal &scriptKey);
1121
1122 // Registers a handler function to call when handling
1123 // handleKey of this script.
1124 void AddHandler(const LuaVal &handlerKey, HandlerFunc function) { _handlerMap[handlerKey] = function; }
1125
1126 // Adds a client side handler to call and adds arguments
1127 // to sends with it for AIO client initialization.
1128 //
1129 // You can add additional arguments to the handler by
1130 // calling this function again
1131 void AddInitArgs(const LuaVal &scriptKey, const LuaVal &handlerKey,
1132 ArgFunc a1 = ArgFunc(), ArgFunc a2 = ArgFunc(), ArgFunc a3 = ArgFunc(),
1133 ArgFunc a4 = ArgFunc(), ArgFunc a5 = ArgFunc(), ArgFunc a6 = ArgFunc());
1134
1135 // Adds a WoW addon file to the list of addons with a unique
1136 // addon key to send on AIO client initialization.
1137 // Returns true if addon was added, false if addon key is taken.
1138 //
1139 // It is required to call World::ForceReloadPlayerAddons()
1140 // if addons are added after server is fully initialized
1141 // for online players to load the added addons.
1142 bool AddAddon(const World::AIOAddon &addon) { return sWorld->AddAddon(addon); }
1143
1144 // Returns pointer to an AIO script by its key and typename.
1145 // Returns null if scriptName doesn't exist or typename was incorrect.
1146 template<class ScriptClass>
1147 ScriptClass *AIOScript::GetScript(const LuaVal &scriptKey)
1148 {
1149 AIOScriptByKeyMap::const_iterator itr = AIOScript::_scriptByKeyMap.find(scriptKey);
1150 if (itr == AIOScript::_scriptByKeyMap.end())
1151 return 0;
1152
1153 return dynamic_cast<ScriptClass*>(itr->second);
1154 }
1155
1156private:
1157 void OnHandle(Player *sender, const LuaVal &handlerKey, const LuaVal &args);
1158
1159 LuaVal _key;
1160
1161 typedef std::unordered_map<LuaVal, HandlerFunc, LuaVal::LuaValHasher> HandlerMapType;
1162 HandlerMapType _handlerMap;
1163
1164 typedef std::unordered_map<LuaVal, AIOScript*, LuaVal::LuaValHasher> AIOScriptByKeyMap;
1165 static AIOScriptByKeyMap _scriptByKeyMap;
1166
1167 friend class ScriptMgr;
1168
1169};
1170
1171template<> AIOScript* AIOScript::GetScript<AIOScript>(const LuaVal &key);
1172
1173class AIOHandlers : public AIOScript
1174{
1175private:
1176 AIOHandlers();
1177 void HandleInit(Player *sender, const LuaVal &args);
1178 void HandleError(Player *sender, const LuaVal &args);
1179
1180 struct InitHookInfo
1181 {
1182 LuaVal scriptKey;
1183 LuaVal handlerKey;
1184 std::list<AIOScript::ArgFunc> argsList;
1185
1186 InitHookInfo(const LuaVal &scriptKey, const LuaVal &handlerKey)
1187 : scriptKey(scriptKey), handlerKey(handlerKey)
1188 { }
1189 };
1190
1191 typedef std::list<InitHookInfo> HookListType;
1192 HookListType _initHookList;
1193
1194 friend class ScriptMgr;
1195 friend class AIOScript;
1196};
1197
1198// Placed here due to ScriptRegistry::AddScript dependency.
1199#define sScriptMgr ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance()
1200
1201// Manages registration, loading, and execution of scripts.
1202class ScriptMgr
1203{
1204 friend class ACE_Singleton<ScriptMgr, ACE_Null_Mutex>;
1205 friend class ScriptObject;
1206 friend class AIOScript;
1207
1208 private:
1209
1210 ScriptMgr();
1211 virtual ~ScriptMgr();
1212
1213 public: /* Initialization */
1214
1215 void Initialize();
1216 void LoadDatabase();
1217 void FillSpellSummary();
1218 void CheckIfScriptsInDatabaseExist();
1219
1220 const char* ScriptsVersion() const { return "Integrated Trinity Scripts"; }
1221
1222 void IncrementScriptCount() { ++_scriptCount; }
1223 uint32 GetScriptCount() const { return _scriptCount; }
1224
1225 public: /* Unloading */
1226
1227 void Unload();
1228
1229 public: /* SpellScriptLoader */
1230
1231 void CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector);
1232 void CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector);
1233 void CreateSpellScriptLoaders(uint32 spellId, std::vector<std::pair<SpellScriptLoader*, std::multimap<uint32, uint32>::iterator> >& scriptVector);
1234
1235 public: /* ServerScript */
1236
1237 void OnNetworkStart();
1238 void OnNetworkStop();
1239 void OnSocketOpen(WorldSocket* socket);
1240 void OnSocketClose(WorldSocket* socket, bool wasNew);
1241
1242 public: /* WorldScript */
1243
1244 void OnOpenStateChange(bool open);
1245 void OnBeforeConfigLoad(bool reload);
1246 void OnAfterConfigLoad(bool reload);
1247 void OnMotdChange(std::string& newMotd);
1248 void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask);
1249 void OnShutdownCancel();
1250 void OnWorldUpdate(uint32 diff);
1251 void OnStartup();
1252 void OnShutdown();
1253
1254 public: /* FormulaScript */
1255
1256 void OnHonorCalculation(float& honor, uint8 level, float multiplier);
1257 void OnGrayLevelCalculation(uint8& grayLevel, uint8 playerLevel);
1258 void OnColorCodeCalculation(XPColorChar& color, uint8 playerLevel, uint8 mobLevel);
1259 void OnZeroDifferenceCalculation(uint8& diff, uint8 playerLevel);
1260 void OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content);
1261 void OnGainCalculation(uint32& gain, Player* player, Unit* unit);
1262 void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid);
1263 void OnAfterArenaRatingCalculation(Battleground *const bg, int32 &winnerMatchmakerChange, int32 &loserMatchmakerChange, int32 &winnerChange, int32 &loserChange);
1264
1265 public: /* MapScript */
1266
1267 void OnCreateMap(Map* map);
1268 void OnDestroyMap(Map* map);
1269 void OnLoadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy);
1270 void OnUnloadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy);
1271 void OnPlayerEnterMap(Map* map, Player* player);
1272 void OnPlayerLeaveMap(Map* map, Player* player);
1273 void OnMapUpdate(Map* map, uint32 diff);
1274
1275 public: /* InstanceMapScript */
1276
1277 InstanceScript* CreateInstanceScript(InstanceMap* map);
1278
1279 public: /* ItemScript */
1280
1281 bool OnQuestAccept(Player* player, Item* item, Quest const* quest);
1282 bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets);
1283 bool OnItemExpire(Player* player, ItemTemplate const* proto);
1284 void OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action);
1285 void OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code);
1286
1287
1288 public: /* CreatureScript */
1289
1290 bool OnGossipHello(Player* player, Creature* creature);
1291 bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action);
1292 bool OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code);
1293 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest);
1294 bool OnQuestSelect(Player* player, Creature* creature, Quest const* quest);
1295 bool OnQuestComplete(Player* player, Creature* creature, Quest const* quest);
1296 bool OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt);
1297 uint32 GetDialogStatus(Player* player, Creature* creature);
1298 CreatureAI* GetCreatureAI(Creature* creature);
1299 void OnCreatureUpdate(Creature* creature, uint32 diff);
1300
1301 public: /* GameObjectScript */
1302
1303 bool OnGossipHello(Player* player, GameObject* go);
1304 bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action);
1305 bool OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code);
1306 bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest);
1307 bool OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt);
1308 uint32 GetDialogStatus(Player* player, GameObject* go);
1309 void OnGameObjectDestroyed(GameObject* go, Player* player);
1310 void OnGameObjectDamaged(GameObject* go, Player* player);
1311 void OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit);
1312 void OnGameObjectStateChanged(GameObject* go, uint32 state);
1313 void OnGameObjectUpdate(GameObject* go, uint32 diff);
1314 GameObjectAI* GetGameObjectAI(GameObject* go);
1315
1316 public: /* AreaTriggerScript */
1317
1318 bool OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger);
1319
1320 public: /* BattlegroundScript */
1321
1322 Battleground* CreateBattleground(BattlegroundTypeId typeId);
1323
1324 public: /* OutdoorPvPScript */
1325
1326 OutdoorPvP* CreateOutdoorPvP(OutdoorPvPData const* data);
1327
1328 public: /* CommandScript */
1329
1330 std::vector<ChatCommand> GetChatCommands();
1331
1332 public: /* WeatherScript */
1333
1334 void OnWeatherChange(Weather* weather, WeatherState state, float grade);
1335 void OnWeatherUpdate(Weather* weather, uint32 diff);
1336
1337 public: /* AuctionHouseScript */
1338
1339 void OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry);
1340 void OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry);
1341 void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry);
1342 void OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry);
1343
1344 public: /* ConditionScript */
1345
1346 bool OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo);
1347
1348 public: /* VehicleScript */
1349
1350 void OnInstall(Vehicle* veh);
1351 void OnUninstall(Vehicle* veh);
1352 void OnReset(Vehicle* veh);
1353 void OnInstallAccessory(Vehicle* veh, Creature* accessory);
1354 void OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId);
1355 void OnRemovePassenger(Vehicle* veh, Unit* passenger);
1356
1357 public: /* DynamicObjectScript */
1358
1359 void OnDynamicObjectUpdate(DynamicObject* dynobj, uint32 diff);
1360
1361 public: /* TransportScript */
1362
1363 void OnAddPassenger(Transport* transport, Player* player);
1364 void OnAddCreaturePassenger(Transport* transport, Creature* creature);
1365 void OnRemovePassenger(Transport* transport, Player* player);
1366 void OnTransportUpdate(Transport* transport, uint32 diff);
1367 void OnRelocate(Transport* transport, uint32 waypointId, uint32 mapId, float x, float y, float z);
1368
1369 public: /* AchievementCriteriaScript */
1370
1371 bool OnCriteriaCheck(uint32 scriptId, Player* source, Unit* target, uint32 criteria_id);
1372
1373 public: /* PlayerScript */
1374
1375
1376 void OnBeforePlayerUpdate(Player* player, uint32 p_time);
1377 void OnPlayerReleasedGhost(Player* player);
1378 void OnPVPKill(Player* killer, Player* killed);
1379 void OnCreatureKill(Player* killer, Creature* killed);
1380 void OnPlayerKilledByCreature(Creature* killer, Player* killed);
1381 void OnPlayerLevelChanged(Player* player, uint8 oldLevel);
1382 void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints);
1383 void OnPlayerTalentsReset(Player* player, bool noCost);
1384 void OnPlayerMoneyChanged(Player* player, int32& amount);
1385 void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim);
1386 void OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
1387 void OnPlayerDuelRequest(Player* target, Player* challenger);
1388 void OnPlayerDuelStart(Player* player1, Player* player2);
1389 void OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type);
1390 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg);
1391 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver);
1392 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group);
1393 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild);
1394 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel);
1395 void OnPlayerEmote(Player* player, uint32 emote);
1396 void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, uint64 guid);
1397 void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck);
1398 void OnPlayerLogin(Player* player);
1399 void OnPlayerLoadFromDB(Player* player);
1400 void OnPlayerLogout(Player* player);
1401 void OnPlayerCreate(Player* player);
1402 void OnPlayerDelete(uint64 guid);
1403 void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent);
1404 void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea);
1405 void OnPlayerUpdateArea(Player* player, uint32 oldArea, uint32 newArea);
1406 bool OnBeforePlayerTeleport(Player* player, uint32 mapid, float x, float y, float z, float orientation, uint32 options, Unit *target);
1407 void OnPlayerUpdateFaction(Player* player);
1408 void OnPlayerAddToBattleground(Player* player, Battleground* bg);
1409 void OnPlayerRemoveFromBattleground(Player* player, Battleground* bg);
1410 void OnAchievementComplete(Player *player, AchievementEntry const* achievement);
1411 void OnCriteriaProgress(Player *player, AchievementCriteriaEntry const* criteria);
1412 void OnAchievementSave(SQLTransaction& trans, Player* player, uint16 achiId, CompletedAchievementData achiData);
1413 void OnCriteriaSave(SQLTransaction& trans, Player* player, uint16 critId, CriteriaProgress criteriaData);
1414 void OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action);
1415 void OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code);
1416 void OnPlayerBeingCharmed(Player* player, Unit* charmer, uint32 oldFactionId, uint32 newFactionId);
1417 void OnAfterPlayerSetVisibleItemSlot(Player* player, uint8 slot, Item *item);
1418 void OnAfterPlayerMoveItemFromInventory(Player* player, Item* it, uint8 bag, uint8 slot, bool update);
1419 void OnEquip(Player* player, Item* it, uint8 bag, uint8 slot, bool update);
1420 void OnPlayerJoinBG(Player* player);
1421 void OnPlayerJoinArena(Player* player);
1422 void OnLootItem(Player* player, Item* item, uint32 count, uint64 lootguid);
1423 void OnCreateItem(Player* player, Item* item, uint32 count);
1424 void OnQuestRewardItem(Player* player, Item* item, uint32 count);
1425 void OnBeforeBuyItemFromVendor(Player * player, uint64 vendorguid, uint32 vendorslot, uint32 &item, uint8 count, uint8 bag, uint8 slot);
1426 void OnAfterStoreOrEquipNewItem(Player* player, uint32 vendorslot, uint32 &item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
1427 void OnAfterUpdateMaxPower(Player* player, Powers& power, float& value);
1428 void OnAfterUpdateMaxHealth(Player* player, float& value);
1429 void OnBeforeUpdateAttackPowerAndDamage(Player* player, float& level, float& val2, bool ranged);
1430 void OnAfterUpdateAttackPowerAndDamage(Player* player, float& level, float& base_attPower, float& attPowerMod, float& attPowerMultiplier, bool ranged);
1431 void OnBeforeInitTalentForLevel(Player* player, uint8& level, uint32& talentPointsForLevel);
1432 void OnFirstLogin(Player* player);
1433
1434 public: /* GuildScript */
1435
1436 void OnGuildAddMember(Guild* guild, Player* player, uint8& plRank);
1437 void OnGuildRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool isKicked);
1438 void OnGuildMOTDChanged(Guild* guild, const std::string& newMotd);
1439 void OnGuildInfoChanged(Guild* guild, const std::string& newInfo);
1440 void OnGuildCreate(Guild* guild, Player* leader, const std::string& name);
1441 void OnGuildDisband(Guild* guild);
1442 void OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair);
1443 void OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount);
1444 void OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId,
1445 bool isDestBank, uint8 destContainer, uint8 destSlotId);
1446 void OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank);
1447 void OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId);
1448
1449 public: /* GroupScript */
1450
1451 void OnGroupAddMember(Group* group, uint64 guid);
1452 void OnGroupInviteMember(Group* group, uint64 guid);
1453 void OnGroupRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason);
1454 void OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid);
1455 void OnGroupDisband(Group* group);
1456
1457 public: /* GlobalScript */
1458 void OnGlobalItemDelFromDB(SQLTransaction& trans, uint32 itemGuid);
1459 void OnGlobalMirrorImageDisplayItem(const Item *item, uint32 &display);
1460 void OnBeforeUpdateArenaPoints(ArenaTeam* at, std::map<uint32, uint32> &ap);
1461 void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32 &maxcount, LootStore const& store);
1462 void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store);
1463 void OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float &chance, Loot& loot, LootStore const& store);
1464 void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData);
1465 void OnAfterInitializeLockedDungeons(Player* player);
1466
1467
1468 public: /* Scheduled scripts */
1469
1470 uint32 IncreaseScheduledScriptsCount() { return ++_scheduledScripts; }
1471 uint32 DecreaseScheduledScriptCount() { return --_scheduledScripts; }
1472 uint32 DecreaseScheduledScriptCount(size_t count) { return _scheduledScripts -= count; }
1473 bool IsScriptScheduled() const { return _scheduledScripts > 0; }
1474
1475
1476 public: /* AIOScript */
1477
1478 void OnAddonMessage(Player *sender, const std::string &message);
1479
1480 public: /* UnitScript */
1481
1482 void OnHeal(Unit* healer, Unit* reciever, uint32& gain);
1483 void OnDamage(Unit* attacker, Unit* victim, uint32& damage);
1484 void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage);
1485 void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage);
1486 void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage);
1487 void ModifyHealRecieved(Unit* target, Unit* attacker, uint32& addHealth);
1488 uint32 DealDamage(Unit* AttackerUnit, Unit *pVictim, uint32 damage, DamageEffectType damagetype);
1489 void OnBeforeRollMeleeOutcomeAgainst(const Unit* attacker, const Unit* victim, WeaponAttackType attType, int32 &attackerMaxSkillValueForLevel, int32 &victimMaxSkillValueForLevel, int32 &attackerWeaponSkill, int32 &victimDefenseSkill, int32 &crit_chance, int32 &miss_chance, int32 &dodge_chance, int32 &parry_chance, int32 &block_chance);
1490
1491
1492 public: /* MovementHandlerScript */
1493
1494 void OnPlayerMove(Player* player, MovementInfo movementInfo, uint32 opcode);
1495
1496 public: /* AllCreatureScript */
1497
1498 //listener function (OnAllCreatureUpdate) is called by OnCreatureUpdate
1499 //void OnAllCreatureUpdate(Creature* creature, uint32 diff);
1500 void Creature_SelectLevel(const CreatureTemplate *cinfo, Creature* creature);
1501
1502 public: /* AllMapScript */
1503
1504 //listener functions are called by OnPlayerEnterMap and OnPlayerLeaveMap
1505 //void OnPlayerEnterAll(Map* map, Player* player);
1506 //void OnPlayerLeaveAll(Map* map, Player* player);
1507
1508 private:
1509
1510 uint32 _scriptCount;
1511 AIOHandlers *_aioHandlers;
1512
1513 //atomic op counter for active scripts amount
1514 std::atomic<long> _scheduledScripts;
1515};
1516
1517template<class ScriptClass>
1518ScriptClass *AIOScript::GetScript(const LuaVal &scriptKey)
1519{
1520 AIOScriptByKeyMap::const_iterator itr = AIOScript::_scriptByKeyMap.find(scriptKey);
1521 if (itr == AIOScript::_scriptByKeyMap.end())
1522 return 0;
1523
1524 return dynamic_cast<ScriptClass*>(itr->second);
1525}
1526
1527template<class TScript>
1528class ScriptRegistry
1529{
1530 public:
1531
1532 typedef std::map<uint32, TScript*> ScriptMap;
1533 typedef typename ScriptMap::iterator ScriptMapIterator;
1534
1535 typedef std::vector<TScript*> ScriptVector;
1536 typedef typename ScriptVector::iterator ScriptVectorIterator;
1537
1538 // The actual list of scripts. This will be accessed concurrently, so it must not be modified
1539 // after server startup.
1540 static ScriptMap ScriptPointerList;
1541 // After database load scripts
1542 static ScriptVector ALScripts;
1543
1544 static void AddScript(TScript* const script)
1545 {
1546 ASSERT(script);
1547
1548 if (!_checkMemory(script))
1549 return;
1550
1551 if (script->isAfterLoadScript())
1552 {
1553 ALScripts.push_back(script);
1554 }
1555 else
1556 {
1557 script->checkValidity();
1558
1559 // We're dealing with a code-only script; just add it.
1560 ScriptPointerList[_scriptIdCounter++] = script;
1561 sScriptMgr->IncrementScriptCount();
1562 }
1563 }
1564
1565 static void AddALScripts() {
1566 for(ScriptVectorIterator it = ALScripts.begin(); it != ALScripts.end(); ++it) {
1567 TScript* const script = *it;
1568
1569 script->checkValidity();
1570
1571 if (script->IsDatabaseBound()) {
1572
1573 if (!_checkMemory(script))
1574 return;
1575
1576 // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
1577 // through a script name (or similar).
1578 uint32 id = sObjectMgr->GetScriptId(script->GetName().c_str());
1579 if (id)
1580 {
1581 // Try to find an existing script.
1582 bool existing = false;
1583 for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
1584 {
1585 // If the script names match...
1586 if (it->second->GetName() == script->GetName())
1587 {
1588 // ... It exists.
1589 existing = true;
1590 break;
1591 }
1592 }
1593
1594 // If the script isn't assigned -> assign it!
1595 if (!existing)
1596 {
1597 ScriptPointerList[id] = script;
1598 sScriptMgr->IncrementScriptCount();
1599 }
1600 else
1601 {
1602 // If the script is already assigned -> delete it!
1603 sLog->outError("Script '%s' already assigned with the same script name, so the script can't work.",
1604 script->GetName().c_str());
1605
1606 //ASSERT(false); // Error that should be fixed ASAP.
1607 }
1608 }
1609 else
1610 {
1611 // The script uses a script name from database, but isn't assigned to anything.
1612 if (script->GetName().find("Smart") == std::string::npos)
1613 sLog->outErrorDb("Script named '%s' does not have a script name assigned in database.",
1614 script->GetName().c_str());
1615 }
1616 } else {
1617 // We're dealing with a code-only script; just add it.
1618 ScriptPointerList[_scriptIdCounter++] = script;
1619 sScriptMgr->IncrementScriptCount();
1620 }
1621 }
1622 }
1623
1624 // Gets a script by its ID (assigned by ObjectMgr).
1625 static TScript* GetScriptById(uint32 id)
1626 {
1627 ScriptMapIterator it = ScriptPointerList.find(id);
1628 if (it != ScriptPointerList.end())
1629 return it->second;
1630
1631 return NULL;
1632 }
1633
1634 private:
1635 // See if the script is using the same memory as another script. If this happens, it means that
1636 // someone forgot to allocate new memory for a script.
1637 static bool _checkMemory(TScript* const script) {
1638 // See if the script is using the same memory as another script. If this happens, it means that
1639 // someone forgot to allocate new memory for a script.
1640 for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
1641 {
1642 if (it->second == script)
1643 {
1644 sLog->outError("Script '%s' has same memory pointer as '%s'.",
1645 script->GetName().c_str(), it->second->GetName().c_str());
1646
1647 return false;
1648 }
1649 }
1650
1651 return true;
1652 }
1653
1654 // Counter used for code-only scripts.
1655 static uint32 _scriptIdCounter;
1656};
1657
1658#endif