· 8 years ago · Dec 09, 2017, 10:06 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 *GetScript(const LuaVal &key);
1148
1149private:
1150 void OnHandle(Player *sender, const LuaVal &handlerKey, const LuaVal &args);
1151
1152 LuaVal _key;
1153
1154 typedef std::unordered_map<LuaVal, HandlerFunc, LuaVal::LuaValHasher> HandlerMapType;
1155 HandlerMapType _handlerMap;
1156
1157 typedef std::unordered_map<LuaVal, AIOScript*, LuaVal::LuaValHasher> AIOScriptByKeyMap;
1158 static AIOScriptByKeyMap _scriptByKeyMap;
1159
1160 friend class ScriptMgr;
1161
1162 template<>
1163 AIOScript *GetScript(const LuaVal &key);
1164};
1165
1166class AIOHandlers : public AIOScript
1167{
1168private:
1169 AIOHandlers();
1170 void HandleInit(Player *sender, const LuaVal &args);
1171 void HandleError(Player *sender, const LuaVal &args);
1172
1173 struct InitHookInfo
1174 {
1175 LuaVal scriptKey;
1176 LuaVal handlerKey;
1177 std::list<AIOScript::ArgFunc> argsList;
1178
1179 InitHookInfo(const LuaVal &scriptKey, const LuaVal &handlerKey)
1180 : scriptKey(scriptKey), handlerKey(handlerKey)
1181 { }
1182 };
1183
1184 typedef std::list<InitHookInfo> HookListType;
1185 HookListType _initHookList;
1186
1187 friend class ScriptMgr;
1188 friend class AIOScript;
1189};
1190
1191// Placed here due to ScriptRegistry::AddScript dependency.
1192#define sScriptMgr ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance()
1193
1194// Manages registration, loading, and execution of scripts.
1195class ScriptMgr
1196{
1197 friend class ACE_Singleton<ScriptMgr, ACE_Null_Mutex>;
1198 friend class ScriptObject;
1199 friend class AIOScript;
1200
1201 private:
1202
1203 ScriptMgr();
1204 virtual ~ScriptMgr();
1205
1206 public: /* Initialization */
1207
1208 void Initialize();
1209 void LoadDatabase();
1210 void FillSpellSummary();
1211 void CheckIfScriptsInDatabaseExist();
1212
1213 const char* ScriptsVersion() const { return "Integrated Trinity Scripts"; }
1214
1215 void IncrementScriptCount() { ++_scriptCount; }
1216 uint32 GetScriptCount() const { return _scriptCount; }
1217
1218 public: /* Unloading */
1219
1220 void Unload();
1221
1222 public: /* SpellScriptLoader */
1223
1224 void CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector);
1225 void CreateAuraScripts(uint32 spellId, std::list<AuraScript*>& scriptVector);
1226 void CreateSpellScriptLoaders(uint32 spellId, std::vector<std::pair<SpellScriptLoader*, std::multimap<uint32, uint32>::iterator> >& scriptVector);
1227
1228 public: /* ServerScript */
1229
1230 void OnNetworkStart();
1231 void OnNetworkStop();
1232 void OnSocketOpen(WorldSocket* socket);
1233 void OnSocketClose(WorldSocket* socket, bool wasNew);
1234
1235 public: /* WorldScript */
1236
1237 void OnOpenStateChange(bool open);
1238 void OnBeforeConfigLoad(bool reload);
1239 void OnAfterConfigLoad(bool reload);
1240 void OnMotdChange(std::string& newMotd);
1241 void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask);
1242 void OnShutdownCancel();
1243 void OnWorldUpdate(uint32 diff);
1244 void OnStartup();
1245 void OnShutdown();
1246
1247 public: /* FormulaScript */
1248
1249 void OnHonorCalculation(float& honor, uint8 level, float multiplier);
1250 void OnGrayLevelCalculation(uint8& grayLevel, uint8 playerLevel);
1251 void OnColorCodeCalculation(XPColorChar& color, uint8 playerLevel, uint8 mobLevel);
1252 void OnZeroDifferenceCalculation(uint8& diff, uint8 playerLevel);
1253 void OnBaseGainCalculation(uint32& gain, uint8 playerLevel, uint8 mobLevel, ContentLevels content);
1254 void OnGainCalculation(uint32& gain, Player* player, Unit* unit);
1255 void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid);
1256 void OnAfterArenaRatingCalculation(Battleground *const bg, int32 &winnerMatchmakerChange, int32 &loserMatchmakerChange, int32 &winnerChange, int32 &loserChange);
1257
1258 public: /* MapScript */
1259
1260 void OnCreateMap(Map* map);
1261 void OnDestroyMap(Map* map);
1262 void OnLoadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy);
1263 void OnUnloadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy);
1264 void OnPlayerEnterMap(Map* map, Player* player);
1265 void OnPlayerLeaveMap(Map* map, Player* player);
1266 void OnMapUpdate(Map* map, uint32 diff);
1267
1268 public: /* InstanceMapScript */
1269
1270 InstanceScript* CreateInstanceScript(InstanceMap* map);
1271
1272 public: /* ItemScript */
1273
1274 bool OnQuestAccept(Player* player, Item* item, Quest const* quest);
1275 bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets);
1276 bool OnItemExpire(Player* player, ItemTemplate const* proto);
1277 void OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action);
1278 void OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code);
1279
1280
1281 public: /* CreatureScript */
1282
1283 bool OnGossipHello(Player* player, Creature* creature);
1284 bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action);
1285 bool OnGossipSelectCode(Player* player, Creature* creature, uint32 sender, uint32 action, const char* code);
1286 bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest);
1287 bool OnQuestSelect(Player* player, Creature* creature, Quest const* quest);
1288 bool OnQuestComplete(Player* player, Creature* creature, Quest const* quest);
1289 bool OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 opt);
1290 uint32 GetDialogStatus(Player* player, Creature* creature);
1291 CreatureAI* GetCreatureAI(Creature* creature);
1292 void OnCreatureUpdate(Creature* creature, uint32 diff);
1293
1294 public: /* GameObjectScript */
1295
1296 bool OnGossipHello(Player* player, GameObject* go);
1297 bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action);
1298 bool OnGossipSelectCode(Player* player, GameObject* go, uint32 sender, uint32 action, const char* code);
1299 bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest);
1300 bool OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 opt);
1301 uint32 GetDialogStatus(Player* player, GameObject* go);
1302 void OnGameObjectDestroyed(GameObject* go, Player* player);
1303 void OnGameObjectDamaged(GameObject* go, Player* player);
1304 void OnGameObjectLootStateChanged(GameObject* go, uint32 state, Unit* unit);
1305 void OnGameObjectStateChanged(GameObject* go, uint32 state);
1306 void OnGameObjectUpdate(GameObject* go, uint32 diff);
1307 GameObjectAI* GetGameObjectAI(GameObject* go);
1308
1309 public: /* AreaTriggerScript */
1310
1311 bool OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger);
1312
1313 public: /* BattlegroundScript */
1314
1315 Battleground* CreateBattleground(BattlegroundTypeId typeId);
1316
1317 public: /* OutdoorPvPScript */
1318
1319 OutdoorPvP* CreateOutdoorPvP(OutdoorPvPData const* data);
1320
1321 public: /* CommandScript */
1322
1323 std::vector<ChatCommand> GetChatCommands();
1324
1325 public: /* WeatherScript */
1326
1327 void OnWeatherChange(Weather* weather, WeatherState state, float grade);
1328 void OnWeatherUpdate(Weather* weather, uint32 diff);
1329
1330 public: /* AuctionHouseScript */
1331
1332 void OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry);
1333 void OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry);
1334 void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry);
1335 void OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry);
1336
1337 public: /* ConditionScript */
1338
1339 bool OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo);
1340
1341 public: /* VehicleScript */
1342
1343 void OnInstall(Vehicle* veh);
1344 void OnUninstall(Vehicle* veh);
1345 void OnReset(Vehicle* veh);
1346 void OnInstallAccessory(Vehicle* veh, Creature* accessory);
1347 void OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId);
1348 void OnRemovePassenger(Vehicle* veh, Unit* passenger);
1349
1350 public: /* DynamicObjectScript */
1351
1352 void OnDynamicObjectUpdate(DynamicObject* dynobj, uint32 diff);
1353
1354 public: /* TransportScript */
1355
1356 void OnAddPassenger(Transport* transport, Player* player);
1357 void OnAddCreaturePassenger(Transport* transport, Creature* creature);
1358 void OnRemovePassenger(Transport* transport, Player* player);
1359 void OnTransportUpdate(Transport* transport, uint32 diff);
1360 void OnRelocate(Transport* transport, uint32 waypointId, uint32 mapId, float x, float y, float z);
1361
1362 public: /* AchievementCriteriaScript */
1363
1364 bool OnCriteriaCheck(uint32 scriptId, Player* source, Unit* target, uint32 criteria_id);
1365
1366 public: /* PlayerScript */
1367
1368
1369 void OnBeforePlayerUpdate(Player* player, uint32 p_time);
1370 void OnPlayerReleasedGhost(Player* player);
1371 void OnPVPKill(Player* killer, Player* killed);
1372 void OnCreatureKill(Player* killer, Creature* killed);
1373 void OnPlayerKilledByCreature(Creature* killer, Player* killed);
1374 void OnPlayerLevelChanged(Player* player, uint8 oldLevel);
1375 void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints);
1376 void OnPlayerTalentsReset(Player* player, bool noCost);
1377 void OnPlayerMoneyChanged(Player* player, int32& amount);
1378 void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim);
1379 void OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
1380 void OnPlayerDuelRequest(Player* target, Player* challenger);
1381 void OnPlayerDuelStart(Player* player1, Player* player2);
1382 void OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type);
1383 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg);
1384 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Player* receiver);
1385 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Group* group);
1386 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Guild* guild);
1387 void OnPlayerChat(Player* player, uint32 type, uint32 lang, std::string& msg, Channel* channel);
1388 void OnPlayerEmote(Player* player, uint32 emote);
1389 void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, uint64 guid);
1390 void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck);
1391 void OnPlayerLogin(Player* player);
1392 void OnPlayerLoadFromDB(Player* player);
1393 void OnPlayerLogout(Player* player);
1394 void OnPlayerCreate(Player* player);
1395 void OnPlayerDelete(uint64 guid);
1396 void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent);
1397 void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea);
1398 void OnPlayerUpdateArea(Player* player, uint32 oldArea, uint32 newArea);
1399 bool OnBeforePlayerTeleport(Player* player, uint32 mapid, float x, float y, float z, float orientation, uint32 options, Unit *target);
1400 void OnPlayerUpdateFaction(Player* player);
1401 void OnPlayerAddToBattleground(Player* player, Battleground* bg);
1402 void OnPlayerRemoveFromBattleground(Player* player, Battleground* bg);
1403 void OnAchievementComplete(Player *player, AchievementEntry const* achievement);
1404 void OnCriteriaProgress(Player *player, AchievementCriteriaEntry const* criteria);
1405 void OnAchievementSave(SQLTransaction& trans, Player* player, uint16 achiId, CompletedAchievementData achiData);
1406 void OnCriteriaSave(SQLTransaction& trans, Player* player, uint16 critId, CriteriaProgress criteriaData);
1407 void OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action);
1408 void OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code);
1409 void OnPlayerBeingCharmed(Player* player, Unit* charmer, uint32 oldFactionId, uint32 newFactionId);
1410 void OnAfterPlayerSetVisibleItemSlot(Player* player, uint8 slot, Item *item);
1411 void OnAfterPlayerMoveItemFromInventory(Player* player, Item* it, uint8 bag, uint8 slot, bool update);
1412 void OnEquip(Player* player, Item* it, uint8 bag, uint8 slot, bool update);
1413 void OnPlayerJoinBG(Player* player);
1414 void OnPlayerJoinArena(Player* player);
1415 void OnLootItem(Player* player, Item* item, uint32 count, uint64 lootguid);
1416 void OnCreateItem(Player* player, Item* item, uint32 count);
1417 void OnQuestRewardItem(Player* player, Item* item, uint32 count);
1418 void OnBeforeBuyItemFromVendor(Player * player, uint64 vendorguid, uint32 vendorslot, uint32 &item, uint8 count, uint8 bag, uint8 slot);
1419 void OnAfterStoreOrEquipNewItem(Player* player, uint32 vendorslot, uint32 &item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
1420 void OnAfterUpdateMaxPower(Player* player, Powers& power, float& value);
1421 void OnAfterUpdateMaxHealth(Player* player, float& value);
1422 void OnBeforeUpdateAttackPowerAndDamage(Player* player, float& level, float& val2, bool ranged);
1423 void OnAfterUpdateAttackPowerAndDamage(Player* player, float& level, float& base_attPower, float& attPowerMod, float& attPowerMultiplier, bool ranged);
1424 void OnBeforeInitTalentForLevel(Player* player, uint8& level, uint32& talentPointsForLevel);
1425 void OnFirstLogin(Player* player);
1426
1427 public: /* GuildScript */
1428
1429 void OnGuildAddMember(Guild* guild, Player* player, uint8& plRank);
1430 void OnGuildRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool isKicked);
1431 void OnGuildMOTDChanged(Guild* guild, const std::string& newMotd);
1432 void OnGuildInfoChanged(Guild* guild, const std::string& newInfo);
1433 void OnGuildCreate(Guild* guild, Player* leader, const std::string& name);
1434 void OnGuildDisband(Guild* guild);
1435 void OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair);
1436 void OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount);
1437 void OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId,
1438 bool isDestBank, uint8 destContainer, uint8 destSlotId);
1439 void OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank);
1440 void OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId);
1441
1442 public: /* GroupScript */
1443
1444 void OnGroupAddMember(Group* group, uint64 guid);
1445 void OnGroupInviteMember(Group* group, uint64 guid);
1446 void OnGroupRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason);
1447 void OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid);
1448 void OnGroupDisband(Group* group);
1449
1450 public: /* GlobalScript */
1451 void OnGlobalItemDelFromDB(SQLTransaction& trans, uint32 itemGuid);
1452 void OnGlobalMirrorImageDisplayItem(const Item *item, uint32 &display);
1453 void OnBeforeUpdateArenaPoints(ArenaTeam* at, std::map<uint32, uint32> &ap);
1454 void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32 &maxcount, LootStore const& store);
1455 void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store);
1456 void OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float &chance, Loot& loot, LootStore const& store);
1457 void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData);
1458 void OnAfterInitializeLockedDungeons(Player* player);
1459
1460
1461 public: /* Scheduled scripts */
1462
1463 uint32 IncreaseScheduledScriptsCount() { return ++_scheduledScripts; }
1464 uint32 DecreaseScheduledScriptCount() { return --_scheduledScripts; }
1465 uint32 DecreaseScheduledScriptCount(size_t count) { return _scheduledScripts -= count; }
1466 bool IsScriptScheduled() const { return _scheduledScripts > 0; }
1467
1468
1469 public: /* AIOScript */
1470
1471 void OnAddonMessage(Player *sender, const std::string &message);
1472
1473 public: /* UnitScript */
1474
1475 void OnHeal(Unit* healer, Unit* reciever, uint32& gain);
1476 void OnDamage(Unit* attacker, Unit* victim, uint32& damage);
1477 void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage);
1478 void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage);
1479 void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage);
1480 void ModifyHealRecieved(Unit* target, Unit* attacker, uint32& addHealth);
1481 uint32 DealDamage(Unit* AttackerUnit, Unit *pVictim, uint32 damage, DamageEffectType damagetype);
1482 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);
1483
1484
1485 public: /* MovementHandlerScript */
1486
1487 void OnPlayerMove(Player* player, MovementInfo movementInfo, uint32 opcode);
1488
1489 public: /* AllCreatureScript */
1490
1491 //listener function (OnAllCreatureUpdate) is called by OnCreatureUpdate
1492 //void OnAllCreatureUpdate(Creature* creature, uint32 diff);
1493 void Creature_SelectLevel(const CreatureTemplate *cinfo, Creature* creature);
1494
1495 public: /* AllMapScript */
1496
1497 //listener functions are called by OnPlayerEnterMap and OnPlayerLeaveMap
1498 //void OnPlayerEnterAll(Map* map, Player* player);
1499 //void OnPlayerLeaveAll(Map* map, Player* player);
1500
1501 private:
1502
1503 uint32 _scriptCount;
1504 AIOHandlers *_aioHandlers;
1505
1506 //atomic op counter for active scripts amount
1507 std::atomic<long> _scheduledScripts;
1508};
1509
1510template<class ScriptClass>
1511ScriptClass *AIOScript::GetScript(const LuaVal &scriptKey)
1512{
1513 AIOScriptByKeyMap::const_iterator itr = AIOScript::_scriptByKeyMap.find(scriptKey);
1514 if (itr == AIOScript::_scriptByKeyMap.end())
1515 return 0;
1516
1517 return dynamic_cast<ScriptClass*>(itr->second);
1518}
1519
1520template<class TScript>
1521class ScriptRegistry
1522{
1523 public:
1524
1525 typedef std::map<uint32, TScript*> ScriptMap;
1526 typedef typename ScriptMap::iterator ScriptMapIterator;
1527
1528 typedef std::vector<TScript*> ScriptVector;
1529 typedef typename ScriptVector::iterator ScriptVectorIterator;
1530
1531 // The actual list of scripts. This will be accessed concurrently, so it must not be modified
1532 // after server startup.
1533 static ScriptMap ScriptPointerList;
1534 // After database load scripts
1535 static ScriptVector ALScripts;
1536
1537 static void AddScript(TScript* const script)
1538 {
1539 ASSERT(script);
1540
1541 if (!_checkMemory(script))
1542 return;
1543
1544 if (script->isAfterLoadScript())
1545 {
1546 ALScripts.push_back(script);
1547 }
1548 else
1549 {
1550 script->checkValidity();
1551
1552 // We're dealing with a code-only script; just add it.
1553 ScriptPointerList[_scriptIdCounter++] = script;
1554 sScriptMgr->IncrementScriptCount();
1555 }
1556 }
1557
1558 static void AddALScripts() {
1559 for(ScriptVectorIterator it = ALScripts.begin(); it != ALScripts.end(); ++it) {
1560 TScript* const script = *it;
1561
1562 script->checkValidity();
1563
1564 if (script->IsDatabaseBound()) {
1565
1566 if (!_checkMemory(script))
1567 return;
1568
1569 // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
1570 // through a script name (or similar).
1571 uint32 id = sObjectMgr->GetScriptId(script->GetName().c_str());
1572 if (id)
1573 {
1574 // Try to find an existing script.
1575 bool existing = false;
1576 for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
1577 {
1578 // If the script names match...
1579 if (it->second->GetName() == script->GetName())
1580 {
1581 // ... It exists.
1582 existing = true;
1583 break;
1584 }
1585 }
1586
1587 // If the script isn't assigned -> assign it!
1588 if (!existing)
1589 {
1590 ScriptPointerList[id] = script;
1591 sScriptMgr->IncrementScriptCount();
1592 }
1593 else
1594 {
1595 // If the script is already assigned -> delete it!
1596 sLog->outError("Script '%s' already assigned with the same script name, so the script can't work.",
1597 script->GetName().c_str());
1598
1599 //ASSERT(false); // Error that should be fixed ASAP.
1600 }
1601 }
1602 else
1603 {
1604 // The script uses a script name from database, but isn't assigned to anything.
1605 if (script->GetName().find("Smart") == std::string::npos)
1606 sLog->outErrorDb("Script named '%s' does not have a script name assigned in database.",
1607 script->GetName().c_str());
1608 }
1609 } else {
1610 // We're dealing with a code-only script; just add it.
1611 ScriptPointerList[_scriptIdCounter++] = script;
1612 sScriptMgr->IncrementScriptCount();
1613 }
1614 }
1615 }
1616
1617 // Gets a script by its ID (assigned by ObjectMgr).
1618 static TScript* GetScriptById(uint32 id)
1619 {
1620 ScriptMapIterator it = ScriptPointerList.find(id);
1621 if (it != ScriptPointerList.end())
1622 return it->second;
1623
1624 return NULL;
1625 }
1626
1627 private:
1628 // See if the script is using the same memory as another script. If this happens, it means that
1629 // someone forgot to allocate new memory for a script.
1630 static bool _checkMemory(TScript* const script) {
1631 // See if the script is using the same memory as another script. If this happens, it means that
1632 // someone forgot to allocate new memory for a script.
1633 for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
1634 {
1635 if (it->second == script)
1636 {
1637 sLog->outError("Script '%s' has same memory pointer as '%s'.",
1638 script->GetName().c_str(), it->second->GetName().c_str());
1639
1640 return false;
1641 }
1642 }
1643
1644 return true;
1645 }
1646
1647 // Counter used for code-only scripts.
1648 static uint32 _scriptIdCounter;
1649};
1650
1651#endif