Files
mod-ale/LuaEngine.h
2015-03-15 01:37:17 +02:00

508 lines
22 KiB
C++

/*
* Copyright (C) 2010 - 2015 Eluna Lua Engine <http://emudevs.com/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/
#ifndef _LUA_ENGINE_H
#define _LUA_ENGINE_H
#include "Common.h"
#include "SharedDefines.h"
#include "DBCEnums.h"
#include "Group.h"
#include "Item.h"
#ifndef TRINITY
#include "Player.h"
#endif
#include "Weather.h"
#include "World.h"
#include "Hooks.h"
extern "C"
{
#include "lua.h"
};
#ifdef TRINITY
struct ItemTemplate;
typedef BattlegroundTypeId BattleGroundTypeId;
#else
struct ItemPrototype;
typedef ItemPrototype ItemTemplate;
typedef SpellEffectIndex SpellEffIndex;
struct SpellEntry;
typedef SpellEntry SpellInfo;
#ifdef CLASSIC
typedef int Difficulty;
#endif
#endif
struct AreaTriggerEntry;
class AuctionHouseObject;
struct AuctionEntry;
#ifdef TRINITY
class Battleground;
typedef Battleground BattleGround;
#endif
class Channel;
class Corpse;
class Creature;
class CreatureAI;
class GameObject;
#ifdef TRINITY
class GameObjectAI;
#endif
class Guild;
class Group;
class Item;
class Pet;
class Player;
class Quest;
class Spell;
class SpellCastTargets;
#ifdef TRINITY
class TempSummon;
#else
class TemporarySummon;
typedef TemporarySummon TempSummon;
#endif
// class Transport;
class Unit;
class Weather;
class WorldPacket;
#ifndef CLASSIC
#ifndef TBC
#ifdef TRINITY
class Vehicle;
#else
class VehicleInfo;
typedef VehicleInfo Vehicle;
#endif
#endif
#endif
struct lua_State;
class EventMgr;
class ElunaObject;
template<typename T>
class ElunaTemplate;
template<typename T>
class EventBind;
template<typename T>
class EntryBind;
template<typename T>
class UniqueBind;
struct LuaScript
{
std::string fileext;
std::string filename;
std::string filepath;
std::string modulepath;
};
#define ELUNA_OBJECT_STORE "Eluna Object Store"
#define LOCK_ELUNA Eluna::Guard __guard(Eluna::GetLock())
class Eluna
{
public:
typedef std::list<LuaScript> ScriptList;
#ifdef TRINITY
typedef std::recursive_mutex LockType;
typedef std::lock_guard<LockType> Guard;
#else
typedef ACE_Recursive_Thread_Mutex LockType;
typedef ACE_Guard<LockType> Guard;
#endif
private:
static bool reload;
static bool initialized;
static LockType lock;
// Lua script locations
static ScriptList lua_scripts;
static ScriptList lua_extensions;
// Lua script folder path
static std::string lua_folderpath;
// lua path variable for require() function
static std::string lua_requirepath;
uint32 event_level;
// When a hook pushes arguments to be passed to event handlers
// this is used to keep track of how many arguments were pushed.
uint8 push_counter;
bool enabled;
Eluna();
~Eluna();
// Prevent copy
Eluna(Eluna const&);
Eluna& operator=(const Eluna&);
void OpenLua();
void CloseLua();
void DestroyBindStores();
void CreateBindStores();
bool ExecuteCall(int params, int res);
void InvalidateObjects();
// Use ReloadEluna() to make eluna reload
// This is called on world update to reload eluna
static void _ReloadEluna();
static void LoadScriptPaths();
static void GetScripts(std::string path);
static void AddScriptPath(std::string filename, const std::string& fullpath);
static int StackTrace(lua_State *_L);
static void Report(lua_State* _L);
// Some helpers for hooks to call event handlers.
// The bodies of the templates are in HookHelpers.h, so if you want to use them you need to #include "HookHelpers.h".
template<typename T> int SetupStack(EventBind<T>* event_bindings, EntryBind<T>* entry_bindings, UniqueBind<T>* guid_bindings, T event_id, uint32 entry, uint64 guid, uint32 instanceId, int number_of_arguments);
int CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results);
void CleanUpStack(int number_of_arguments);
template<typename T> void ReplaceArgument(T value, uint8 index);
template<typename T> void CallAllFunctions(EventBind<T>* event_bindings, EntryBind<T>* entry_bindings, UniqueBind<T>* guid_bindings, T event_id, uint32 entry, uint64 guid, uint32 instanceId);
template<typename T> bool CallAllFunctionsBool(EventBind<T>* event_bindings, EntryBind<T>* entry_bindings, UniqueBind<T>* guid_bindings, T event_id, uint32 entry, uint64 guid, uint32 instanceId, bool default_value);
// Convenient overloads for Setup. Use these in hooks instead of original.
template<typename T> int SetupStack(EventBind<T>* event_bindings, T event_id, int number_of_arguments)
{
return SetupStack(event_bindings, (EntryBind<T>*)NULL, (UniqueBind<T>*)NULL, event_id, 0, 0, 0, number_of_arguments);
}
template<typename T> int SetupStack(EntryBind<T>* entry_bindings, T event_id, uint32 entry, int number_of_arguments)
{
return SetupStack((EventBind<T>*)NULL, entry_bindings, (UniqueBind<T>*)NULL, event_id, entry, 0, 0, number_of_arguments);
}
template<typename T> int SetupStack(EntryBind<T>* entry_bindings, UniqueBind<T>* guid_bindings, T event_id, uint32 entry, uint64 guid, uint32 instanceId, int number_of_arguments)
{
return SetupStack((EventBind<T>*)NULL, entry_bindings, guid_bindings, event_id, entry, guid, instanceId, number_of_arguments);
}
// Convenient overloads for CallAllFunctions. Use these in hooks instead of original.
template<typename T> void CallAllFunctions(EventBind<T>* event_bindings, T event_id)
{
CallAllFunctions(event_bindings, (EntryBind<T>*)NULL, (UniqueBind<T>*)NULL, event_id, 0, 0, 0);
}
template<typename T> void CallAllFunctions(EntryBind<T>* entry_bindings, T event_id, uint32 entry)
{
CallAllFunctions((EventBind<T>*)NULL, entry_bindings, (UniqueBind<T>*)NULL, event_id, entry, 0, 0);
}
template<typename T> void CallAllFunctions(EntryBind<T>* entry_bindings, UniqueBind<T>* guid_bindings, T event_id, uint32 entry, uint64 guid, uint32 instanceId)
{
CallAllFunctions((EventBind<T>*)NULL, entry_bindings, guid_bindings, event_id, entry, guid, instanceId);
}
// Convenient overloads for CallAllFunctionsBool. Use these in hooks instead of original.
template<typename T> bool CallAllFunctionsBool(EventBind<T>* event_bindings, T event_id, bool default_value = false)
{
return CallAllFunctionsBool(event_bindings, (EntryBind<T>*)NULL, (UniqueBind<T>*)NULL, event_id, 0, 0, 0, default_value);
}
template<typename T> bool CallAllFunctionsBool(EntryBind<T>* entry_bindings, T event_id, uint32 entry, bool default_value = false)
{
return CallAllFunctionsBool((EventBind<T>*)NULL, entry_bindings, (UniqueBind<T>*)NULL, event_id, entry, 0, 0, default_value);
}
template<typename T> bool CallAllFunctionsBool(EntryBind<T>* entry_bindings, UniqueBind<T>* guid_bindings, T event_id, uint32 entry, uint64 guid, uint32 instanceId, bool default_value = false)
{
return CallAllFunctionsBool((EventBind<T>*)NULL, entry_bindings, guid_bindings, event_id, entry, guid, instanceId, default_value);
}
public:
static Eluna* GEluna;
lua_State* L;
EventMgr* eventMgr;
EventBind<Hooks::ServerEvents>* ServerEventBindings;
EventBind<Hooks::PlayerEvents>* PlayerEventBindings;
EventBind<Hooks::GuildEvents>* GuildEventBindings;
EventBind<Hooks::GroupEvents>* GroupEventBindings;
EventBind<Hooks::VehicleEvents>* VehicleEventBindings;
EventBind<Hooks::BGEvents>* BGEventBindings;
EntryBind<Hooks::PacketEvents>* PacketEventBindings;
EntryBind<Hooks::CreatureEvents>* CreatureEventBindings;
EntryBind<Hooks::GossipEvents>* CreatureGossipBindings;
EntryBind<Hooks::GameObjectEvents>* GameObjectEventBindings;
EntryBind<Hooks::GossipEvents>* GameObjectGossipBindings;
EntryBind<Hooks::ItemEvents>* ItemEventBindings;
EntryBind<Hooks::GossipEvents>* ItemGossipBindings;
EntryBind<Hooks::GossipEvents>* playerGossipBindings;
UniqueBind<Hooks::CreatureEvents>* CreatureUniqueBindings;
static void Initialize();
static void Uninitialize();
// This function is used to make eluna reload
static void ReloadEluna() { LOCK_ELUNA; reload = true; }
static LockType& GetLock() { return lock; };
static bool IsInitialized() { return initialized; }
// Static pushes, can be used by anything, including methods.
static void Push(lua_State* luastate); // nil
static void Push(lua_State* luastate, const long long);
static void Push(lua_State* luastate, const unsigned long long);
static void Push(lua_State* luastate, const long);
static void Push(lua_State* luastate, const unsigned long);
static void Push(lua_State* luastate, const int);
static void Push(lua_State* luastate, const unsigned int);
static void Push(lua_State* luastate, const bool);
static void Push(lua_State* luastate, const float);
static void Push(lua_State* luastate, const double);
static void Push(lua_State* luastate, const std::string&);
static void Push(lua_State* luastate, const char*);
static void Push(lua_State* luastate, Object const* obj);
static void Push(lua_State* luastate, WorldObject const* obj);
static void Push(lua_State* luastate, Unit const* unit);
static void Push(lua_State* luastate, Pet const* pet);
static void Push(lua_State* luastate, TempSummon const* summon);
template<typename T>
static void Push(lua_State* luastate, T const* ptr)
{
ElunaTemplate<T>::Push(luastate, ptr);
}
void RunScripts();
bool ShouldReload() const { return reload; }
bool IsEnabled() const { return enabled && IsInitialized(); }
bool HasLuaState() const { return L != NULL; }
void Register(uint8 reg, uint32 id, uint64 guid, uint32 instanceId, uint32 evt, int func, uint32 shots);
// Non-static pushes, to be used in hooks.
// These just call the correct static version with the main thread's Lua state.
void Push() { Push(L); ++push_counter; }
void Push(const long long value) { Push(L, value); ++push_counter; }
void Push(const unsigned long long value) { Push(L, value); ++push_counter; }
void Push(const long value) { Push(L, value); ++push_counter; }
void Push(const unsigned long value) { Push(L, value); ++push_counter; }
void Push(const int value) { Push(L, value); ++push_counter; }
void Push(const unsigned int value) { Push(L, value); ++push_counter; }
void Push(const bool value) { Push(L, value); ++push_counter; }
void Push(const float value) { Push(L, value); ++push_counter; }
void Push(const double value) { Push(L, value); ++push_counter; }
void Push(const std::string& value) { Push(L, value); ++push_counter; }
void Push(const char* value) { Push(L, value); ++push_counter; }
template<typename T>
void Push(T const* ptr) { Push(L, ptr); ++push_counter; }
// Checks
template<typename T> static T CHECKVAL(lua_State* luastate, int narg);
template<typename T> static T CHECKVAL(lua_State* luastate, int narg, T def)
{
return lua_isnoneornil(luastate, narg) ? def : CHECKVAL<T>(luastate, narg);
}
template<typename T> static T* CHECKOBJ(lua_State* luastate, int narg, bool error = true)
{
return ElunaTemplate<T>::Check(luastate, narg, error);
}
static ElunaObject* CHECKTYPE(lua_State* luastate, int narg, const char *tname, bool error = true);
CreatureAI* GetAI(Creature* creature);
/* Custom */
void OnTimedEvent(int funcRef, uint32 delay, uint32 calls, WorldObject* obj);
bool OnCommand(Player* player, const char* text);
void OnWorldUpdate(uint32 diff);
void OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid);
void OnLootMoney(Player* pPlayer, uint32 amount);
void OnFirstLogin(Player* pPlayer);
void OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot);
void OnRepop(Player* pPlayer);
void OnResurrect(Player* pPlayer);
void OnQuestAbandon(Player* pPlayer, uint32 questId);
void OnLearnTalents(Player* pPlayer, uint32 talentId, uint32 talentRank, uint32 spellid);
InventoryResult OnCanUseItem(const Player* pPlayer, uint32 itemEntry);
void OnLuaStateClose();
void OnLuaStateOpen();
bool OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel);
/* Item */
bool OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget);
bool OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest);
bool OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets);
bool OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets);
bool OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& targets);
bool OnExpire(Player* pPlayer, ItemTemplate const* pProto);
bool OnRemove(Player* pPlayer, Item* item);
void HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, uint32 action, const std::string& code);
/* Creature */
bool OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget);
bool OnGossipHello(Player* pPlayer, Creature* pCreature);
bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action);
bool OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code);
bool OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest);
bool OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt);
uint32 GetDialogStatus(Player* pPlayer, Creature* pCreature);
bool OnSummoned(Creature* creature, Unit* summoner);
bool UpdateAI(Creature* me, const uint32 diff);
bool EnterCombat(Creature* me, Unit* target);
bool DamageTaken(Creature* me, Unit* attacker, uint32& damage);
bool JustDied(Creature* me, Unit* killer);
bool KilledUnit(Creature* me, Unit* victim);
bool JustSummoned(Creature* me, Creature* summon);
bool SummonedCreatureDespawn(Creature* me, Creature* summon);
bool MovementInform(Creature* me, uint32 type, uint32 id);
bool AttackStart(Creature* me, Unit* target);
bool EnterEvadeMode(Creature* me);
bool AttackedBy(Creature* me, Unit* attacker);
bool JustRespawned(Creature* me);
bool JustReachedHome(Creature* me);
bool ReceiveEmote(Creature* me, Player* player, uint32 emoteId);
bool CorpseRemoved(Creature* me, uint32& respawnDelay);
bool MoveInLineOfSight(Creature* me, Unit* who);
bool SpellHit(Creature* me, Unit* caster, SpellInfo const* spell);
bool SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell);
bool SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer);
bool OwnerAttackedBy(Creature* me, Unit* attacker);
bool OwnerAttacked(Creature* me, Unit* target);
void On_Reset(Creature* me);
/* GameObject */
bool OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget);
bool OnGameObjectUse(Player* pPlayer, GameObject* pGameObject);
bool OnGossipHello(Player* pPlayer, GameObject* pGameObject);
bool OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action);
bool OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code);
bool OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest);
bool OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt);
uint32 GetDialogStatus(Player* pPlayer, GameObject* pGameObject);
#ifndef CLASSIC
#ifndef TBC
void OnDestroyed(GameObject* pGameObject, Player* pPlayer);
void OnDamaged(GameObject* pGameObject, Player* pPlayer);
#endif
#endif
void OnLootStateChanged(GameObject* pGameObject, uint32 state);
void OnGameObjectStateChanged(GameObject* pGameObject, uint32 state);
void UpdateAI(GameObject* pGameObject, uint32 diff);
void OnSpawn(GameObject* gameobject);
/* Packet */
bool OnPacketSend(WorldSession* session, WorldPacket& packet);
void OnPacketSendAny(Player* player, WorldPacket& packet, bool& result);
void OnPacketSendOne(Player* player, WorldPacket& packet, bool& result);
bool OnPacketReceive(WorldSession* session, WorldPacket& packet);
void OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result);
void OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result);
/* Player */
void OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy);
void OnPlayerLeaveCombat(Player* pPlayer);
void OnPVPKill(Player* pKiller, Player* pKilled);
void OnCreatureKill(Player* pKiller, Creature* pKilled);
void OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled);
void OnLevelChanged(Player* pPlayer, uint8 oldLevel);
void OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints);
void OnTalentsReset(Player* pPlayer, bool noCost);
void OnMoneyChanged(Player* pPlayer, int32& amount);
void OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim);
void OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental);
void OnDuelRequest(Player* pTarget, Player* pChallenger);
void OnDuelStart(Player* pStarter, Player* pChallenger);
void OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type);
bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg);
bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup);
bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild);
bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel);
bool OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver);
void OnEmote(Player* pPlayer, uint32 emote);
void OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint64 guid);
void OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck);
void OnLogin(Player* pPlayer);
void OnLogout(Player* pPlayer);
void OnCreate(Player* pPlayer);
void OnDelete(uint32 guid);
void OnSave(Player* pPlayer);
void OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent);
void OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea);
void OnMapChanged(Player* pPlayer);
void HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code);
#ifndef CLASSIC
#ifndef TBC
/* Vehicle */
void OnInstall(Vehicle* vehicle);
void OnUninstall(Vehicle* vehicle);
void OnInstallAccessory(Vehicle* vehicle, Creature* accessory);
void OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId);
void OnRemovePassenger(Vehicle* vehicle, Unit* passenger);
#endif
#endif
/* AreaTrigger */
bool OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger);
/* Weather */
void OnChange(Weather* weather, uint32 zone, WeatherState state, float grade);
/* Auction House */
void OnAdd(AuctionHouseObject* ah, AuctionEntry* entry);
void OnRemove(AuctionHouseObject* ah, AuctionEntry* entry);
void OnSuccessful(AuctionHouseObject* ah, AuctionEntry* entry);
void OnExpire(AuctionHouseObject* ah, AuctionEntry* entry);
/* Guild */
void OnAddMember(Guild* guild, Player* player, uint32 plRank);
void OnRemoveMember(Guild* guild, Player* player, bool isDisbanding);
void OnMOTDChanged(Guild* guild, const std::string& newMotd);
void OnInfoChanged(Guild* guild, const std::string& newInfo);
void OnCreate(Guild* guild, Player* leader, const std::string& name);
void OnDisband(Guild* guild);
void OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair);
void OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount);
void OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId);
void OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank);
void OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId);
/* Group */
void OnAddMember(Group* group, uint64 guid);
void OnInviteMember(Group* group, uint64 guid);
void OnRemoveMember(Group* group, uint64 guid, uint8 method);
void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid);
void OnDisband(Group* group);
void OnCreate(Group* group, uint64 leaderGuid, GroupType groupType);
/* Map */
void OnCreate(Map* map);
void OnDestroy(Map* map);
void OnPlayerEnter(Map* map, Player* player);
void OnPlayerLeave(Map* map, Player* player);
void OnUpdate(Map* map, uint32 diff);
void OnAddToWorld(Creature* creature);
void OnRemoveFromWorld(Creature* creature);
void OnAddToWorld(GameObject* gameobject);
void OnRemoveFromWorld(GameObject* gameobject);
void OnRemove(Creature* creature);
void OnRemove(GameObject* gameobject);
/* World */
void OnOpenStateChange(bool open);
void OnConfigLoad(bool reload);
void OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask);
void OnShutdownCancel();
void OnUpdate(uint32 diff);
void OnStartup();
void OnShutdown();
/* Battle Ground */
void OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId);
void OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner);
void OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId);
void OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId);
};
template<> Unit* Eluna::CHECKOBJ<Unit>(lua_State* L, int narg, bool error);
template<> Object* Eluna::CHECKOBJ<Object>(lua_State* L, int narg, bool error);
template<> WorldObject* Eluna::CHECKOBJ<WorldObject>(lua_State* L, int narg, bool error);
template<> ElunaObject* Eluna::CHECKOBJ<ElunaObject>(lua_State* L, int narg, bool error);
#define sEluna Eluna::GEluna
#endif