/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#ifndef SC_SCRIPTMGR_H
#define SC_SCRIPTMGR_H
#include "AchievementMgr.h"
#include "ArenaTeam.h"
#include "AuctionHouseMgr.h"
#include "Battleground.h"
#include "Common.h"
#include "DBCStores.h"
#include "DynamicObject.h"
#include "GameEventMgr.h"
#include "Group.h"
#include "LFGMgr.h"
#include "ObjectMgr.h"
#include "PetDefines.h"
#include "QuestDef.h"
#include "SharedDefines.h"
#include "Tuples.h"
#include "Types.h"
#include "Weather.h"
#include "World.h"
#include
class AuctionHouseObject;
class AuraScript;
class Battleground;
class BattlegroundMap;
class BattlegroundQueue;
class Channel;
class ChatHandler;
class Creature;
class CreatureAI;
class DynamicObject;
class GameObject;
class GameObjectAI;
class GridMap;
class Group;
class Guild;
class InstanceMap;
class InstanceScript;
class Item;
class Map;
class MotionTransport;
class OutdoorPvP;
class Player;
class Quest;
class ScriptMgr;
class Spell;
class SpellCastTargets;
class SpellInfo;
class SpellScript;
class StaticTransport;
class Transport;
class Unit;
class Vehicle;
class WorldObject;
class WorldPacket;
class WorldSocket;
class CharacterCreateInfo;
struct AchievementCriteriaData;
struct AuctionEntry;
struct Condition;
struct ConditionSourceInfo;
struct DungeonProgressionRequirements;
struct GroupQueueInfo;
struct ItemTemplate;
struct OutdoorPvPData;
struct TargetInfo;
struct SpellModifier;
namespace Acore::ChatCommands
{
struct ChatCommandBuilder;
}
#define VISIBLE_RANGE 166.0f //MAX visible range (size of grid)
// Check out our guide on how to create new hooks in our wiki! https://www.azerothcore.org/wiki/hooks-script
/*
TODO: Add more script type classes.
SessionScript
CollisionScript
ArenaTeamScript
*/
class ScriptObject
{
friend class ScriptMgr;
public:
// Do not override this in scripts; it should be overridden by the various script type classes. It indicates
// whether or not this script type must be assigned in the database.
[[nodiscard]] virtual bool IsDatabaseBound() const { return false; }
[[nodiscard]] virtual bool isAfterLoadScript() const { return IsDatabaseBound(); }
virtual void checkValidity() { }
[[nodiscard]] const std::string& GetName() const { return _name; }
protected:
ScriptObject(const char* name)
: _name(std::string(name))
{
}
virtual ~ScriptObject() = default;
private:
const std::string _name;
};
template class UpdatableScript
{
protected:
UpdatableScript() = default;
public:
virtual void OnUpdate(TObject* /*obj*/, uint32 /*diff*/) { }
};
class SpellScriptLoader : public ScriptObject
{
protected:
SpellScriptLoader(const char* name);
public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; }
// Should return a fully valid SpellScript pointer.
[[nodiscard]] virtual SpellScript* GetSpellScript() const { return nullptr; }
// Should return a fully valid AuraScript pointer.
[[nodiscard]] virtual AuraScript* GetAuraScript() const { return nullptr; }
};
class ServerScript : public ScriptObject
{
protected:
ServerScript(const char* name);
public:
// Called when reactive socket I/O is started (WorldSocketMgr).
virtual void OnNetworkStart() { }
// Called when reactive I/O is stopped.
virtual void OnNetworkStop() { }
// Called when a remote socket establishes a connection to the server. Do not store the socket object.
virtual void OnSocketOpen(std::shared_ptr /*socket*/) { }
// Called when a socket is closed. Do not store the socket object, and do not rely on the connection
// being open; it is not.
virtual void OnSocketClose(std::shared_ptr /*socket*/) { }
/**
* @brief This hook called when a packet is sent to a client. The packet object is a copy of the original packet, so reading and modifying it is safe.
*
* @param session Contains information about the WorldSession
* @param packet Contains information about the WorldPacket
* @return True if you want to continue sending the packet, false if you want to disallow sending the packet
*/
[[nodiscard]] virtual bool CanPacketSend(WorldSession* /*session*/, WorldPacket& /*packet*/) { return true; }
/**
* @brief Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so
* reading and modifying it is safe. Make sure to check WorldSession pointer before usage, it might be null in case of auth packets
*
* @param session Contains information about the WorldSession
* @param packet Contains information about the WorldPacket
* @return True if you want to continue receive the packet, false if you want to disallow receive the packet
*/
[[nodiscard]] virtual bool CanPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { return true; }
};
class WorldScript : public ScriptObject
{
protected:
WorldScript(const char* name);
public:
// Called when the open/closed state of the world changes.
virtual void OnOpenStateChange(bool /*open*/) { }
// Called after the world configuration is (re)loaded.
virtual void OnAfterConfigLoad(bool /*reload*/) { }
// Called when loading custom database tables
virtual void OnLoadCustomDatabaseTable() { }
// Called before the world configuration is (re)loaded.
virtual void OnBeforeConfigLoad(bool /*reload*/) { }
// Called before the message of the day is changed.
virtual void OnMotdChange(std::string& /*newMotd*/) { }
// Called when a world shutdown is initiated.
virtual void OnShutdownInitiate(ShutdownExitCode /*code*/, ShutdownMask /*mask*/) { }
// Called when a world shutdown is cancelled.
virtual void OnShutdownCancel() { }
// Called on every world tick (don't execute too heavy code here).
virtual void OnUpdate(uint32 /*diff*/) { }
// Called when the world is started.
virtual void OnStartup() { }
// Called when the world is actually shut down.
virtual void OnShutdown() { }
/**
* @brief Called after all maps are unloaded from core
*/
virtual void OnAfterUnloadAllMaps() { }
/**
* @brief This hook runs before finalizing the player world session. Can be also used to mutate the cache version of the Client.
*
* @param version The cache version that we will be sending to the Client.
*/
virtual void OnBeforeFinalizePlayerWorldSession(uint32& /*cacheVersion*/) { }
/**
* @brief This hook runs after all scripts loading and before itialized
*/
virtual void OnBeforeWorldInitialized() { }
};
class FormulaScript : public ScriptObject
{
protected:
FormulaScript(const char* name);
public:
// Called after calculating honor.
virtual void OnHonorCalculation(float& /*honor*/, uint8 /*level*/, float /*multiplier*/) { }
// Called after gray level calculation.
virtual void OnGrayLevelCalculation(uint8& /*grayLevel*/, uint8 /*playerLevel*/) { }
// Called after calculating experience color.
virtual void OnColorCodeCalculation(XPColorChar& /*color*/, uint8 /*playerLevel*/, uint8 /*mobLevel*/) { }
// Called after calculating zero difference.
virtual void OnZeroDifferenceCalculation(uint8& /*diff*/, uint8 /*playerLevel*/) { }
// Called after calculating base experience gain.
virtual void OnBaseGainCalculation(uint32& /*gain*/, uint8 /*playerLevel*/, uint8 /*mobLevel*/, ContentLevels /*content*/) { }
// Called after calculating experience gain.
virtual void OnGainCalculation(uint32& /*gain*/, Player* /*player*/, Unit* /*unit*/) { }
// Called when calculating the experience rate for group experience.
virtual void OnGroupRateCalculation(float& /*rate*/, uint32 /*count*/, bool /*isRaid*/) { }
// Called after calculating arena rating changes
virtual void OnAfterArenaRatingCalculation(Battleground* const /*bg*/, int32& /*winnerMatchmakerChange*/, int32& /*loserMatchmakerChange*/, int32& /*winnerChange*/, int32& /*loserChange*/) { };
// Called before modifying a player's personal rating
virtual void OnBeforeUpdatingPersonalRating(int32& /*mod*/, uint32 /*type*/) { }
};
template class MapScript : public UpdatableScript
{
MapEntry const* _mapEntry;
uint32 _mapId;
protected:
MapScript(uint32 mapId)
: _mapId(mapId)
{
}
public:
void checkMap()
{
_mapEntry = sMapStore.LookupEntry(_mapId);
if (!_mapEntry)
LOG_ERROR("maps.script", "Invalid MapScript for {}; no such map ID.", _mapId);
}
// Gets the MapEntry structure associated with this script. Can return nullptr.
MapEntry const* GetEntry() { return _mapEntry; }
// Called when the map is created.
virtual void OnCreate(TMap* /*map*/) { }
// Called just before the map is destroyed.
virtual void OnDestroy(TMap* /*map*/) { }
// Called when a grid map is loaded.
virtual void OnLoadGridMap(TMap* /*map*/, GridMap* /*gmap*/, uint32 /*gx*/, uint32 /*gy*/) { }
// Called when a grid map is unloaded.
virtual void OnUnloadGridMap(TMap* /*map*/, GridMap* /*gmap*/, uint32 /*gx*/, uint32 /*gy*/) { }
// Called when a player enters the map.
virtual void OnPlayerEnter(TMap* /*map*/, Player* /*player*/) { }
// Called when a player leaves the map.
virtual void OnPlayerLeave(TMap* /*map*/, Player* /*player*/) { }
// Called on every map update tick.
void OnUpdate(TMap* /*map*/, uint32 /*diff*/) override { }
};
class WorldMapScript : public ScriptObject, public MapScript