mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
Move hooks to separate files.
This commit is contained in:
67
BattleGroundHooks.cpp
Normal file
67
BattleGroundHooks.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 _BATTLEGROUND_HOOKS_H
|
||||
#define _BATTLEGROUND_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaTemplate.h" // Needed to be able to push BattleGround objects.
|
||||
#include "ElunaBinding.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId)
|
||||
{
|
||||
if (!BGEventBindings->HasEvents(BG_EVENT_ON_START))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(bg);
|
||||
Push(bgId);
|
||||
Push(instanceId);
|
||||
CallAllFunctions(BGEventBindings, BG_EVENT_ON_START);
|
||||
}
|
||||
|
||||
void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, Team winner)
|
||||
{
|
||||
if (!BGEventBindings->HasEvents(BG_EVENT_ON_END))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(bg);
|
||||
Push(bgId);
|
||||
Push(instanceId);
|
||||
Push(winner);
|
||||
CallAllFunctions(BGEventBindings, BG_EVENT_ON_END);
|
||||
}
|
||||
|
||||
void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId)
|
||||
{
|
||||
if (!BGEventBindings->HasEvents(BG_EVENT_ON_CREATE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(bg);
|
||||
Push(bgId);
|
||||
Push(instanceId);
|
||||
CallAllFunctions(BGEventBindings, BG_EVENT_ON_CREATE);
|
||||
}
|
||||
|
||||
void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId)
|
||||
{
|
||||
if (!BGEventBindings->HasEvents(BG_EVENT_ON_PRE_DESTROY))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(bg);
|
||||
Push(bgId);
|
||||
Push(instanceId);
|
||||
CallAllFunctions(BGEventBindings, BG_EVENT_ON_PRE_DESTROY);
|
||||
}
|
||||
|
||||
#endif // _BATTLEGROUND_HOOKS_H
|
||||
486
CreatureHooks.cpp
Normal file
486
CreatureHooks.cpp
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* 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 _CREATURE_HOOKS_H
|
||||
#define _CREATURE_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaIncludes.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GET_GUID(), pTarget->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pCaster);
|
||||
Push(spellId);
|
||||
Push(effIndex);
|
||||
Push(pTarget);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry(), pTarget->GET_GUID(), pTarget->GetInstanceId());
|
||||
}
|
||||
|
||||
bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (!CreatureGossipBindings->HasEvents(GOSSIP_EVENT_ON_HELLO, pCreature->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pCreature);
|
||||
return CallAllFunctionsBool(CreatureGossipBindings, GOSSIP_EVENT_ON_HELLO, pCreature->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action)
|
||||
{
|
||||
if (!CreatureGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pCreature);
|
||||
Push(sender);
|
||||
Push(action);
|
||||
return CallAllFunctionsBool(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code)
|
||||
{
|
||||
if (!CreatureGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pCreature);
|
||||
Push(sender);
|
||||
Push(action);
|
||||
Push(code);
|
||||
return CallAllFunctionsBool(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GET_GUID(), pCreature->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pCreature);
|
||||
Push(pQuest);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GetEntry(), pCreature->GET_GUID(), pCreature->GetInstanceId());
|
||||
}
|
||||
|
||||
bool Eluna::OnQuestReward(Player* pPlayer, Creature* pCreature, Quest const* pQuest, uint32 opt)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_QUEST_REWARD, pCreature->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_QUEST_REWARD, pCreature->GET_GUID(), pCreature->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pCreature);
|
||||
Push(pQuest);
|
||||
Push(opt);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_QUEST_REWARD, pCreature->GetEntry(), pCreature->GET_GUID(), pCreature->GetInstanceId());
|
||||
}
|
||||
|
||||
uint32 Eluna::GetDialogStatus(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GET_GUID(), pCreature->GetInstanceId()))
|
||||
return DIALOG_STATUS_SCRIPTED_NO_STATUS;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pCreature);
|
||||
CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GetEntry(), pCreature->GET_GUID(), pCreature->GetInstanceId());
|
||||
return DIALOG_STATUS_SCRIPTED_NO_STATUS;
|
||||
}
|
||||
|
||||
void Eluna::OnAddToWorld(Creature* creature)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ADD, creature->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_ADD, creature->GET_GUID(), creature->GetInstanceId()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(creature);
|
||||
CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_ADD, creature->GetEntry(), creature->GET_GUID(), creature->GetInstanceId());
|
||||
}
|
||||
|
||||
void Eluna::OnRemoveFromWorld(Creature* creature)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_REMOVE, creature->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_REMOVE, creature->GET_GUID(), creature->GetInstanceId()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(creature);
|
||||
CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_REMOVE, creature->GetEntry(), creature->GET_GUID(), creature->GetInstanceId());
|
||||
}
|
||||
|
||||
bool Eluna::OnSummoned(Creature* pCreature, Unit* pSummoner)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED, pCreature->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED, pCreature->GET_GUID(), pCreature->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pCreature);
|
||||
Push(pSummoner);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_SUMMONED, pCreature->GetEntry(), pCreature->GET_GUID(), pCreature->GetInstanceId());
|
||||
}
|
||||
|
||||
bool Eluna::UpdateAI(Creature* me, const uint32 diff)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_AIUPDATE, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_AIUPDATE, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(diff);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_AIUPDATE, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
//Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
|
||||
//Called at creature aggro either by MoveInLOS or Attack Start
|
||||
bool Eluna::EnterCombat(Creature* me, Unit* target)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_ENTER_COMBAT, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(target);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called at any Damage from any attacker (before damage apply)
|
||||
bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = false;
|
||||
Push(me);
|
||||
Push(attacker);
|
||||
Push(damage);
|
||||
int damageIndex = lua_gettop(L);
|
||||
int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry(), me->GET_GUID(), me->GetInstanceId(), 3);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 3, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0))
|
||||
result = true;
|
||||
|
||||
if (lua_isnumber(L, r + 1))
|
||||
{
|
||||
damage = Eluna::CHECKVAL<uint32>(L, r + 1);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(damage, damageIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(3);
|
||||
return result;
|
||||
}
|
||||
|
||||
//Called at creature death
|
||||
bool Eluna::JustDied(Creature* me, Unit* killer)
|
||||
{
|
||||
On_Reset(me);
|
||||
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DIED, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_DIED, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(killer);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_DIED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
//Called at creature killing another unit
|
||||
bool Eluna::KilledUnit(Creature* me, Unit* victim)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_TARGET_DIED, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_TARGET_DIED, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(victim);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_TARGET_DIED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when the creature summon successfully other creature
|
||||
bool Eluna::JustSummoned(Creature* me, Creature* summon)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(summon);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when a summoned creature is despawned
|
||||
bool Eluna::SummonedCreatureDespawn(Creature* me, Creature* summon)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(summon);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
//Called at waypoint reached or PointMovement end
|
||||
bool Eluna::MovementInform(Creature* me, uint32 type, uint32 id)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_REACH_WP, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_REACH_WP, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(type);
|
||||
Push(id);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_REACH_WP, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called before EnterCombat even before the creature is in combat.
|
||||
bool Eluna::AttackStart(Creature* me, Unit* target)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_PRE_COMBAT, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_PRE_COMBAT, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(target);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_PRE_COMBAT, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called for reaction at stopping attack at no attackers or targets
|
||||
bool Eluna::EnterEvadeMode(Creature* me)
|
||||
{
|
||||
On_Reset(me);
|
||||
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_LEAVE_COMBAT, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
|
||||
bool Eluna::AttackedBy(Creature* me, Unit* attacker)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ATTACKED_AT, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_ATTACKED_AT, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(attacker);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_ATTACKED_AT, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when creature is spawned or respawned (for reseting variables)
|
||||
bool Eluna::JustRespawned(Creature* me)
|
||||
{
|
||||
On_Reset(me);
|
||||
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SPAWN, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SPAWN, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_SPAWN, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called at reaching home after evade
|
||||
bool Eluna::JustReachedHome(Creature* me)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_REACH_HOME, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_REACH_HOME, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_REACH_HOME, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called at text emote receive from player
|
||||
bool Eluna::ReceiveEmote(Creature* me, Player* player, uint32 emoteId)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_RECEIVE_EMOTE, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_RECEIVE_EMOTE, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(player);
|
||||
Push(emoteId);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_RECEIVE_EMOTE, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// called when the corpse of this creature gets removed
|
||||
bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_CORPSE_REMOVED, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = false;
|
||||
Push(me);
|
||||
Push(respawnDelay);
|
||||
int respawnDelayIndex = lua_gettop(L);
|
||||
int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId(), 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && lua_toboolean(L, r + 0))
|
||||
result = true;
|
||||
|
||||
if (lua_isnumber(L, r + 1))
|
||||
{
|
||||
respawnDelay = Eluna::CHECKVAL<uint32>(L, r + 1);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(respawnDelay, respawnDelayIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::MoveInLineOfSight(Creature* me, Unit* who)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_MOVE_IN_LOS, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(who);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called on creature initial spawn, respawn, death, evade (leave combat)
|
||||
void Eluna::On_Reset(Creature* me) // Not an override, custom
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_RESET, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_RESET, me->GET_GUID(), me->GetInstanceId()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
CallAllFunctions(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_RESET, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when hit by a spell
|
||||
bool Eluna::SpellHit(Creature* me, Unit* caster, SpellInfo const* spell)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_HIT_BY_SPELL, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_HIT_BY_SPELL, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(caster);
|
||||
Push(spell->Id); // Pass spell object?
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_HIT_BY_SPELL, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when spell hits a target
|
||||
bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(target);
|
||||
Push(spell->Id); // Pass spell object?
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
#ifdef TRINITY
|
||||
|
||||
bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(summon);
|
||||
Push(killer);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when owner takes damage
|
||||
bool Eluna::OwnerAttackedBy(Creature* me, Unit* attacker)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(attacker);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
// Called when owner attacks something
|
||||
bool Eluna::OwnerAttacked(Creature* me, Unit* target)
|
||||
{
|
||||
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry()))
|
||||
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED, me->GET_GUID(), me->GetInstanceId()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(me);
|
||||
Push(target);
|
||||
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
|
||||
}
|
||||
|
||||
#endif // TRINITY
|
||||
#endif // _CREATURE_HOOKS_H
|
||||
211
GameObjectHooks.cpp
Normal file
211
GameObjectHooks.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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 _GAMEOBJECT_HOOKS_H
|
||||
#define _GAMEOBJECT_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaIncludes.h"
|
||||
#include "ElunaEventMgr.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pCaster);
|
||||
Push(spellId);
|
||||
Push(effIndex);
|
||||
Push(pTarget);
|
||||
return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry());
|
||||
}
|
||||
|
||||
bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject)
|
||||
{
|
||||
if (!GameObjectGossipBindings->HasEvents(GOSSIP_EVENT_ON_HELLO, pGameObject->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pGameObject);
|
||||
return CallAllFunctionsBool(GameObjectGossipBindings, GOSSIP_EVENT_ON_HELLO, pGameObject->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action)
|
||||
{
|
||||
if (!GameObjectGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pGameObject);
|
||||
Push(sender);
|
||||
Push(action);
|
||||
return CallAllFunctionsBool(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code)
|
||||
{
|
||||
if (!GameObjectGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pGameObject);
|
||||
Push(sender);
|
||||
Push(action);
|
||||
Push(code);
|
||||
return CallAllFunctionsBool(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pGameObject);
|
||||
Push(pQuest);
|
||||
return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pGameObject->elunaEvents->Update(diff);
|
||||
Push(pGameObject);
|
||||
Push(diff);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pGameObject);
|
||||
Push(pQuest);
|
||||
Push(opt);
|
||||
return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
uint32 Eluna::GetDialogStatus(Player* pPlayer, GameObject* pGameObject)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry()))
|
||||
return DIALOG_STATUS_SCRIPTED_NO_STATUS;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pGameObject);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry());
|
||||
return DIALOG_STATUS_SCRIPTED_NO_STATUS; // DIALOG_STATUS_UNDEFINED
|
||||
}
|
||||
|
||||
#ifndef CLASSIC
|
||||
#ifndef TBC
|
||||
void Eluna::OnDestroyed(GameObject* pGameObject, Player* pPlayer)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pGameObject);
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::OnDamaged(GameObject* pGameObject, Player* pPlayer)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pGameObject);
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pGameObject);
|
||||
Push(state);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pGameObject);
|
||||
Push(state);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::OnSpawn(GameObject* gameobject)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_SPAWN, gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(gameobject);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_SPAWN, gameobject->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::OnAddToWorld(GameObject* gameobject)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_ADD, gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(gameobject);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_ADD, gameobject->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::OnRemoveFromWorld(GameObject* gameobject)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_REMOVE, gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(gameobject);
|
||||
CallAllFunctions(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_REMOVE, gameobject->GetEntry());
|
||||
}
|
||||
|
||||
bool Eluna::OnGameObjectUse(Player* pPlayer, GameObject* pGameObject)
|
||||
{
|
||||
if (!GameObjectEventBindings->HasEvents(GAMEOBJECT_EVENT_ON_USE, pGameObject->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pGameObject);
|
||||
Push(pPlayer);
|
||||
return CallAllFunctionsBool(GameObjectEventBindings, GAMEOBJECT_EVENT_ON_USE, pGameObject->GetEntry());
|
||||
}
|
||||
|
||||
#endif // _GAMEOBJECT_HOOKS_H
|
||||
@@ -593,7 +593,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterServerEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEventHelper(E, L, HookMgr::REGTYPE_SERVER);
|
||||
RegisterEventHelper(E, L, Hooks::REGTYPE_SERVER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -658,7 +658,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterPlayerEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEventHelper(E, L, HookMgr::REGTYPE_PLAYER);
|
||||
RegisterEventHelper(E, L, Hooks::REGTYPE_PLAYER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -691,7 +691,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterGuildEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEventHelper(E, L, HookMgr::REGTYPE_GUILD);
|
||||
RegisterEventHelper(E, L, Hooks::REGTYPE_GUILD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -719,7 +719,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterGroupEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEventHelper(E, L, HookMgr::REGTYPE_GROUP);
|
||||
RegisterEventHelper(E, L, Hooks::REGTYPE_GROUP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -743,7 +743,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterBGEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEventHelper(E, L, HookMgr::REGTYPE_BG);
|
||||
RegisterEventHelper(E, L, Hooks::REGTYPE_BG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -768,7 +768,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterPacketEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_PACKET);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_PACKET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -791,7 +791,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterCreatureGossipEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_CREATURE_GOSSIP);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_CREATURE_GOSSIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterGameObjectGossipEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_GAMEOBJECT_GOSSIP);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_GAMEOBJECT_GOSSIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -840,7 +840,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterItemEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_ITEM);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_ITEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -863,7 +863,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterItemGossipEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_ITEM_GOSSIP);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_ITEM_GOSSIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -886,7 +886,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterPlayerGossipEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_PLAYER_GOSSIP);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_PLAYER_GOSSIP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -944,7 +944,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterCreatureEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_CREATURE);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_CREATURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1003,7 +1003,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterUniqueCreatureEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterUniqueHelper(E, L, HookMgr::REGTYPE_CREATURE);
|
||||
RegisterUniqueHelper(E, L, Hooks::REGTYPE_CREATURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1037,7 +1037,7 @@ namespace LuaGlobalFunctions
|
||||
*/
|
||||
int RegisterGameObjectEvent(Eluna* E, lua_State* L)
|
||||
{
|
||||
RegisterEntryHelper(E, L, HookMgr::REGTYPE_GAMEOBJECT);
|
||||
RegisterEntryHelper(E, L, Hooks::REGTYPE_GAMEOBJECT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
85
GroupHooks.cpp
Normal file
85
GroupHooks.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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 _GROUP_HOOKS_H
|
||||
#define _GROUP_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
void Eluna::OnAddMember(Group* group, uint64 guid)
|
||||
{
|
||||
if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_MEMBER_ADD))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(group);
|
||||
Push(guid);
|
||||
CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_ADD);
|
||||
}
|
||||
|
||||
void Eluna::OnInviteMember(Group* group, uint64 guid)
|
||||
{
|
||||
if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_MEMBER_INVITE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(group);
|
||||
Push(guid);
|
||||
CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_INVITE);
|
||||
}
|
||||
|
||||
void Eluna::OnRemoveMember(Group* group, uint64 guid, uint8 method)
|
||||
{
|
||||
if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_MEMBER_REMOVE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(group);
|
||||
Push(guid);
|
||||
Push(method);
|
||||
CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_MEMBER_REMOVE);
|
||||
}
|
||||
|
||||
void Eluna::OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid)
|
||||
{
|
||||
if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_LEADER_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(group);
|
||||
Push(newLeaderGuid);
|
||||
Push(oldLeaderGuid);
|
||||
CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_LEADER_CHANGE);
|
||||
}
|
||||
|
||||
void Eluna::OnDisband(Group* group)
|
||||
{
|
||||
if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_DISBAND))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(group);
|
||||
CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_DISBAND);
|
||||
}
|
||||
|
||||
void Eluna::OnCreate(Group* group, uint64 leaderGuid, GroupType groupType)
|
||||
{
|
||||
if (!GroupEventBindings->HasEvents(GROUP_EVENT_ON_CREATE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(group);
|
||||
Push(leaderGuid);
|
||||
Push(groupType);
|
||||
CallAllFunctions(GroupEventBindings, GROUP_EVENT_ON_CREATE);
|
||||
}
|
||||
|
||||
#endif // _GROUP_HOOKS_H
|
||||
193
GuildHooks.cpp
Normal file
193
GuildHooks.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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 _GUILD_HOOKS_H
|
||||
#define _GUILD_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_ADD_MEMBER))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(player);
|
||||
Push(plRank);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_ADD_MEMBER);
|
||||
}
|
||||
|
||||
void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_REMOVE_MEMBER))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(player);
|
||||
Push(isDisbanding);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_REMOVE_MEMBER);
|
||||
}
|
||||
|
||||
void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_MOTD_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(newMotd);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_MOTD_CHANGE);
|
||||
}
|
||||
|
||||
void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_INFO_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(newInfo);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_INFO_CHANGE);
|
||||
}
|
||||
|
||||
void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_CREATE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(leader);
|
||||
Push(name);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_CREATE);
|
||||
}
|
||||
|
||||
void Eluna::OnDisband(Guild* guild)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_DISBAND))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_DISBAND);
|
||||
}
|
||||
|
||||
void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) // isRepair not a part of Mangos, implement?
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_MONEY_WITHDRAW))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(player);
|
||||
Push(amount);
|
||||
Push(isRepair); // isRepair not a part of Mangos, implement?
|
||||
int amountIndex = lua_gettop(L) - 1;
|
||||
int n = SetupStack(GuildEventBindings, GUILD_EVENT_ON_MONEY_WITHDRAW, 4);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 4, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
{
|
||||
amount = CHECKVAL<uint32>(L, r);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(amount, amountIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(4);
|
||||
}
|
||||
|
||||
void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_MONEY_DEPOSIT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(player);
|
||||
Push(amount);
|
||||
int amountIndex = lua_gettop(L);
|
||||
int n = SetupStack(GuildEventBindings, GUILD_EVENT_ON_MONEY_DEPOSIT, 3);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 3, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
{
|
||||
amount = CHECKVAL<uint32>(L, r);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(amount, amountIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(3);
|
||||
}
|
||||
|
||||
void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId,
|
||||
bool isDestBank, uint8 destContainer, uint8 destSlotId)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_ITEM_MOVE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(player);
|
||||
Push(pItem);
|
||||
Push(isSrcBank);
|
||||
Push(srcContainer);
|
||||
Push(srcSlotId);
|
||||
Push(isDestBank);
|
||||
Push(destContainer);
|
||||
Push(destSlotId);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_ITEM_MOVE);
|
||||
}
|
||||
|
||||
void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_EVENT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(eventType);
|
||||
Push(playerGuid1);
|
||||
Push(playerGuid2);
|
||||
Push(newRank);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_EVENT);
|
||||
}
|
||||
|
||||
void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId)
|
||||
{
|
||||
if (!GuildEventBindings->HasEvents(GUILD_EVENT_ON_BANK_EVENT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guild);
|
||||
Push(eventType);
|
||||
Push(tabId);
|
||||
Push(playerGuid);
|
||||
Push(itemOrMoney);
|
||||
Push(itemStackCount);
|
||||
Push(destTabId);
|
||||
CallAllFunctions(GuildEventBindings, GUILD_EVENT_ON_BANK_EVENT);
|
||||
}
|
||||
|
||||
#endif // _GUILD_HOOKS_H
|
||||
129
HookHelpers.h
Normal file
129
HookHelpers.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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 _HOOK_HELPERS_H
|
||||
#define _HOOK_HELPERS_H
|
||||
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaUtility.h"
|
||||
|
||||
/*
|
||||
* Sets up the stack so that event handlers can be called.
|
||||
*
|
||||
* Returns the number of functions that were pushed onto the stack.
|
||||
*
|
||||
* Use the simpler overloads for just EventBind or EntryBind instead of this overload in hooks.
|
||||
*/
|
||||
template<typename T>
|
||||
int Eluna::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)
|
||||
{
|
||||
// Ensure that if `entry_bindings` is not NULL, a valid entry is supplied.
|
||||
ASSERT(!entry_bindings || (entry_bindings && entry > 0));
|
||||
ASSERT(number_of_arguments == this->push_counter);
|
||||
// Stack: [arguments]
|
||||
|
||||
Push(event_id);
|
||||
this->push_counter = 0;
|
||||
++number_of_arguments;
|
||||
// Stack: [arguments], event_id
|
||||
|
||||
int arguments_top = lua_gettop(L);
|
||||
int first_argument_index = arguments_top - number_of_arguments + 1;
|
||||
ASSERT(arguments_top >= number_of_arguments);
|
||||
|
||||
lua_insert(L, first_argument_index);
|
||||
// Stack: event_id, [arguments]
|
||||
|
||||
if (event_bindings)
|
||||
event_bindings->PushFuncRefs(L, (int)event_id);
|
||||
|
||||
if (entry_bindings)
|
||||
entry_bindings->PushFuncRefs(L, (int)event_id, entry);
|
||||
|
||||
if (guid_bindings)
|
||||
guid_bindings->PushFuncRefs(L, (int)event_id, guid, instanceId);
|
||||
// Stack: event_id, [arguments], [functions]
|
||||
|
||||
int number_of_functions = lua_gettop(L) - arguments_top;
|
||||
return number_of_functions;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace one of the arguments pushed before `SetupStack` with a new value.
|
||||
*/
|
||||
template<typename T>
|
||||
void Eluna::ReplaceArgument(T value, uint8 index)
|
||||
{
|
||||
ASSERT(index < lua_gettop(L) && index > 0);
|
||||
// Stack: event_id, [arguments], [functions], [results]
|
||||
|
||||
Eluna::Push(L, value);
|
||||
// Stack: event_id, [arguments], [functions], [results], value
|
||||
|
||||
lua_replace(L, index + 1);
|
||||
// Stack: event_id, [arguments and value], [functions], [results]
|
||||
}
|
||||
|
||||
/*
|
||||
* Call all event handlers registered to the event ID/entry combination and ignore any results.
|
||||
*/
|
||||
template<typename T>
|
||||
void Eluna::CallAllFunctions(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 = this->push_counter;
|
||||
// Stack: [arguments]
|
||||
|
||||
int number_of_functions = SetupStack(event_bindings, entry_bindings, guid_bindings, event_id, entry, guid, instanceId, number_of_arguments);
|
||||
// Stack: event_id, [arguments], [functions]
|
||||
|
||||
while (number_of_functions > 0)
|
||||
{
|
||||
CallOneFunction(number_of_functions, number_of_arguments, 0);
|
||||
--number_of_functions;
|
||||
// Stack: event_id, [arguments], [functions - 1]
|
||||
}
|
||||
// Stack: event_id, [arguments]
|
||||
|
||||
CleanUpStack(number_of_arguments);
|
||||
// Stack: (empty)
|
||||
}
|
||||
|
||||
/*
|
||||
* Call all event handlers registered to the event ID/entry combination,
|
||||
* and returns `default_value` if ALL event handlers returned `default_value`,
|
||||
* otherwise returns the opposite of `default_value`.
|
||||
*/
|
||||
template<typename T>
|
||||
bool Eluna::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)
|
||||
{
|
||||
bool result = default_value;
|
||||
// Note: number_of_arguments here does not count in eventID, which is pushed in SetupStack
|
||||
int number_of_arguments = this->push_counter;
|
||||
// Stack: [arguments]
|
||||
|
||||
int number_of_functions = SetupStack(event_bindings, entry_bindings, guid_bindings, event_id, entry, guid, instanceId, number_of_arguments);
|
||||
// Stack: event_id, [arguments], [functions]
|
||||
|
||||
while (number_of_functions > 0)
|
||||
{
|
||||
int r = CallOneFunction(number_of_functions, number_of_arguments, 1);
|
||||
--number_of_functions;
|
||||
// Stack: event_id, [arguments], [functions - 1], result
|
||||
|
||||
if (lua_isboolean(L, r) && (lua_toboolean(L, r) == 1) != default_value)
|
||||
result = !default_value;
|
||||
|
||||
lua_pop(L, 1);
|
||||
// Stack: event_id, [arguments], [functions - 1]
|
||||
}
|
||||
// Stack: event_id, [arguments]
|
||||
|
||||
CleanUpStack(number_of_arguments);
|
||||
// Stack: (empty)
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // _HOOK_HELPERS_H
|
||||
2446
HookMgr.cpp
2446
HookMgr.cpp
File diff suppressed because it is too large
Load Diff
19
Hooks.cpp
Normal file
19
Hooks.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaEventMgr.h"
|
||||
#include "ElunaIncludes.h"
|
||||
#include "ElunaTemplate.h"
|
||||
#include "ElunaCreatureAI.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
};
|
||||
|
||||
@@ -1,13 +1,72 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
* 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 LUAHOOKS_H
|
||||
#define LUAHOOKS_H
|
||||
#ifndef _HOOKS_H
|
||||
#define _HOOKS_H
|
||||
|
||||
namespace HookMgr
|
||||
/*
|
||||
* A hook should be written in one of the following forms:
|
||||
*
|
||||
* A. If results will be IGNORED:
|
||||
*
|
||||
* // Return early if there are no bindings.
|
||||
* if (!WhateverBindings->HasEvents(SOME_EVENT_TYPE))
|
||||
* return;
|
||||
*
|
||||
* // Lock out any other threads.
|
||||
* LOCK_ELUNA;
|
||||
*
|
||||
* // Push extra arguments, if any.
|
||||
* Push(a);
|
||||
* Push(b);
|
||||
* Push(c);
|
||||
*
|
||||
* // Call all event handlers.
|
||||
* CallAllFunctions(WhateverBindings, SOME_EVENT_TYPE);
|
||||
*
|
||||
*
|
||||
* B. If results will be USED:
|
||||
*
|
||||
* // Return early if there are no bindings.
|
||||
* if (!WhateverBindings->HasEvents(SOME_EVENT_TYPE))
|
||||
* return;
|
||||
*
|
||||
* // Lock out any other threads.
|
||||
* LOCK_ELUNA;
|
||||
*
|
||||
* // Push extra arguments, if any.
|
||||
* Push(a);
|
||||
* Push(b);
|
||||
* Push(c);
|
||||
*
|
||||
* // Setup the stack and get the number of functions pushed.
|
||||
* // Last argument is 3 because we did 3 Pushes.
|
||||
* int n = SetupStack(WhateverBindings, SOME_EVENT_TYPE, 3);
|
||||
*
|
||||
* // Call each event handler in order and check results.
|
||||
* while (n > 0)
|
||||
* {
|
||||
* // Call an event handler and decrement the function counter afterward.
|
||||
* // Second-last argument is 3 because we did 3 Pushes.
|
||||
* // Last argument is 2 because we want 2 results.
|
||||
* int r = CallOneFunction(n--, 3, 2);
|
||||
*
|
||||
* // Results can be popped using `r`.
|
||||
* int first = CHECKVAL<int>(L, r + 0);
|
||||
* int second = CHECKVAL<int>(L, r + 1);
|
||||
*
|
||||
* // Pop the results off the stack.
|
||||
* lua_pop(L, 2);
|
||||
* }
|
||||
*
|
||||
* // Clean-up the stack. Argument is 3 because we did 3 Pushes.
|
||||
* CleanUpStack(3);
|
||||
*/
|
||||
|
||||
namespace Hooks
|
||||
{
|
||||
enum RegisterTypes
|
||||
{
|
||||
@@ -28,7 +87,6 @@ namespace HookMgr
|
||||
REGTYPE_COUNT
|
||||
};
|
||||
|
||||
// RegisterPacketEvent(Opcode, event, function)
|
||||
enum PacketEvents
|
||||
{
|
||||
PACKET_EVENT_ON_PACKET_RECEIVE = 5, // (event, packet, player) - Player only if accessible. Can return false, newPacket
|
||||
@@ -38,7 +96,6 @@ namespace HookMgr
|
||||
PACKET_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterServerEvent(EventId, function)
|
||||
enum ServerEvents
|
||||
{
|
||||
// Server
|
||||
@@ -96,7 +153,6 @@ namespace HookMgr
|
||||
SERVER_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterPlayerEvent(eventId, function)
|
||||
enum PlayerEvents
|
||||
{
|
||||
PLAYER_EVENT_ON_CHARACTER_CREATE = 1, // (event, player)
|
||||
@@ -147,7 +203,6 @@ namespace HookMgr
|
||||
PLAYER_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterGuildEvent(eventId, function)
|
||||
enum GuildEvents
|
||||
{
|
||||
// Guild
|
||||
@@ -166,7 +221,6 @@ namespace HookMgr
|
||||
GUILD_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterGroupEvent(eventId, function)
|
||||
enum GroupEvents
|
||||
{
|
||||
// Group
|
||||
@@ -180,7 +234,6 @@ namespace HookMgr
|
||||
GROUP_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterVehicleEvent(eventId, function)
|
||||
enum VehicleEvents
|
||||
{
|
||||
VEHICLE_EVENT_ON_INSTALL = 1, // (event, vehicle)
|
||||
@@ -193,7 +246,6 @@ namespace HookMgr
|
||||
VEHICLE_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterCreatureEvent(entry, EventId, function)
|
||||
enum CreatureEvents
|
||||
{
|
||||
CREATURE_EVENT_ON_ENTER_COMBAT = 1, // (event, creature, target) - Can return true to stop normal action
|
||||
@@ -236,7 +288,6 @@ namespace HookMgr
|
||||
CREATURE_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterGameObjectEvent(entry, EventId, function)
|
||||
enum GameObjectEvents
|
||||
{
|
||||
GAMEOBJECT_EVENT_ON_AIUPDATE = 1, // (event, go, diff)
|
||||
@@ -256,7 +307,6 @@ namespace HookMgr
|
||||
GAMEOBJECT_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterItemEvent(entry, EventId, function)
|
||||
enum ItemEvents
|
||||
{
|
||||
ITEM_EVENT_ON_DUMMY_EFFECT = 1, // (event, caster, spellid, effindex, item) - Can return true
|
||||
@@ -267,10 +317,6 @@ namespace HookMgr
|
||||
ITEM_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterCreatureGossipEvent(entry, EventId, function)
|
||||
// RegisterGameObjectGossipEvent(entry, EventId, function)
|
||||
// RegisterItemGossipEvent(entry, EventId, function)
|
||||
// RegisterPlayerGossipEvent(menu_id, EventId, function)
|
||||
enum GossipEvents
|
||||
{
|
||||
GOSSIP_EVENT_ON_HELLO = 1, // (event, player, object) - Object is the Creature/GameObject/Item. Can return false to do default action. For item gossip can return false to stop spell casting.
|
||||
@@ -278,7 +324,6 @@ namespace HookMgr
|
||||
GOSSIP_EVENT_COUNT
|
||||
};
|
||||
|
||||
// RegisterBGEvent(EventId, function)
|
||||
enum BGEvents
|
||||
{
|
||||
BG_EVENT_ON_START = 1, // (event, bg, bgId, instanceId) - Needs to be added to TC
|
||||
@@ -288,4 +333,5 @@ namespace HookMgr
|
||||
BG_EVENT_COUNT
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // _HOOKS_H
|
||||
144
ItemHooks.cpp
Normal file
144
ItemHooks.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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 _ITEM_HOOKS_H
|
||||
#define _ITEM_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaIncludes.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget)
|
||||
{
|
||||
if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pCaster);
|
||||
Push(spellId);
|
||||
Push(effIndex);
|
||||
Push(pTarget);
|
||||
return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry());
|
||||
}
|
||||
|
||||
bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest)
|
||||
{
|
||||
if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pItem);
|
||||
Push(pQuest);
|
||||
return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry());
|
||||
}
|
||||
|
||||
bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
|
||||
{
|
||||
ObjectGuid guid = pItem->GET_GUID();
|
||||
bool castSpell = true;
|
||||
|
||||
if (!OnItemUse(pPlayer, pItem, targets))
|
||||
castSpell = false;
|
||||
|
||||
pItem = pPlayer->GetItemByGuid(guid);
|
||||
if (pItem)
|
||||
{
|
||||
if (!OnItemGossip(pPlayer, pItem, targets))
|
||||
castSpell = false;
|
||||
pItem = pPlayer->GetItemByGuid(guid);
|
||||
}
|
||||
|
||||
if (pItem && castSpell)
|
||||
return true;
|
||||
|
||||
// Send equip error that shows no message
|
||||
// This is a hack fix to stop spell casting visual bug when a spell is not cast on use
|
||||
WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, 18);
|
||||
data << uint8(59); // EQUIP_ERR_NONE / EQUIP_ERR_CANT_BE_DISENCHANTED
|
||||
data << ObjectGuid(guid);
|
||||
data << ObjectGuid(uint64(0));
|
||||
data << uint8(0);
|
||||
pPlayer->GetSession()->SendPacket(&data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
|
||||
{
|
||||
if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_USE, pItem->GetEntry()))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pItem);
|
||||
#ifndef TRINITY
|
||||
if (GameObject* target = targets.getGOTarget())
|
||||
Push(target);
|
||||
else if (Item* target = targets.getItemTarget())
|
||||
Push(target);
|
||||
else if (Corpse* target = pPlayer->GetMap()->GetCorpse(targets.getCorpseTargetGuid()))
|
||||
Push(target);
|
||||
else if (Unit* target = targets.getUnitTarget())
|
||||
Push(target);
|
||||
else
|
||||
Push();
|
||||
#else
|
||||
if (GameObject* target = targets.GetGOTarget())
|
||||
Push(target);
|
||||
else if (Item* target = targets.GetItemTarget())
|
||||
Push(target);
|
||||
else if (Corpse* target = targets.GetCorpseTarget())
|
||||
Push(target);
|
||||
else if (Unit* target = targets.GetUnitTarget())
|
||||
Push(target);
|
||||
else if (WorldObject* target = targets.GetObjectTarget())
|
||||
Push(target);
|
||||
else
|
||||
Push();
|
||||
#endif
|
||||
|
||||
return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_USE, pItem->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/)
|
||||
{
|
||||
if (!ItemGossipBindings->HasEvents(GOSSIP_EVENT_ON_HELLO, pItem->GetEntry()))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(pPlayer);
|
||||
Push(pItem);
|
||||
return CallAllFunctionsBool(ItemGossipBindings, GOSSIP_EVENT_ON_HELLO, pItem->GetEntry(), true);
|
||||
}
|
||||
|
||||
bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto)
|
||||
{
|
||||
if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_EXPIRE, pProto->ItemId))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pProto->ItemId);
|
||||
return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_EXPIRE, pProto->ItemId);
|
||||
}
|
||||
|
||||
bool Eluna::OnRemove(Player* pPlayer, Item* item)
|
||||
{
|
||||
if (!ItemEventBindings->HasEvents(ITEM_EVENT_ON_REMOVE, item->GetEntry()))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(item);
|
||||
return CallAllFunctionsBool(ItemEventBindings, ITEM_EVENT_ON_REMOVE, item->GetEntry());
|
||||
}
|
||||
|
||||
#endif // _ITEM_HOOKS_H
|
||||
142
LuaEngine.cpp
142
LuaEngine.cpp
@@ -4,13 +4,14 @@
|
||||
* Please see the included DOCS/LICENSE.md for more information
|
||||
*/
|
||||
|
||||
#include "HookMgr.h"
|
||||
#include "Hooks.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaEventMgr.h"
|
||||
#include "ElunaIncludes.h"
|
||||
#include "ElunaTemplate.h"
|
||||
#include "ElunaUtility.h"
|
||||
#include "ElunaCreatureAI.h"
|
||||
|
||||
#ifdef USING_BOOST
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -123,23 +124,23 @@ push_counter(0),
|
||||
|
||||
eventMgr(NULL),
|
||||
|
||||
ServerEventBindings(new EventBind<HookMgr::ServerEvents>("ServerEvents", *this)),
|
||||
PlayerEventBindings(new EventBind<HookMgr::PlayerEvents>("PlayerEvents", *this)),
|
||||
GuildEventBindings(new EventBind<HookMgr::GuildEvents>("GuildEvents", *this)),
|
||||
GroupEventBindings(new EventBind<HookMgr::GroupEvents>("GroupEvents", *this)),
|
||||
VehicleEventBindings(new EventBind<HookMgr::VehicleEvents>("VehicleEvents", *this)),
|
||||
BGEventBindings(new EventBind<HookMgr::BGEvents>("BGEvents", *this)),
|
||||
ServerEventBindings(new EventBind<Hooks::ServerEvents>("ServerEvents", *this)),
|
||||
PlayerEventBindings(new EventBind<Hooks::PlayerEvents>("PlayerEvents", *this)),
|
||||
GuildEventBindings(new EventBind<Hooks::GuildEvents>("GuildEvents", *this)),
|
||||
GroupEventBindings(new EventBind<Hooks::GroupEvents>("GroupEvents", *this)),
|
||||
VehicleEventBindings(new EventBind<Hooks::VehicleEvents>("VehicleEvents", *this)),
|
||||
BGEventBindings(new EventBind<Hooks::BGEvents>("BGEvents", *this)),
|
||||
|
||||
PacketEventBindings(new EntryBind<HookMgr::PacketEvents>("PacketEvents", *this)),
|
||||
CreatureEventBindings(new EntryBind<HookMgr::CreatureEvents>("CreatureEvents", *this)),
|
||||
CreatureGossipBindings(new EntryBind<HookMgr::GossipEvents>("GossipEvents (creature)", *this)),
|
||||
GameObjectEventBindings(new EntryBind<HookMgr::GameObjectEvents>("GameObjectEvents", *this)),
|
||||
GameObjectGossipBindings(new EntryBind<HookMgr::GossipEvents>("GossipEvents (gameobject)", *this)),
|
||||
ItemEventBindings(new EntryBind<HookMgr::ItemEvents>("ItemEvents", *this)),
|
||||
ItemGossipBindings(new EntryBind<HookMgr::GossipEvents>("GossipEvents (item)", *this)),
|
||||
playerGossipBindings(new EntryBind<HookMgr::GossipEvents>("GossipEvents (player)", *this)),
|
||||
PacketEventBindings(new EntryBind<Hooks::PacketEvents>("PacketEvents", *this)),
|
||||
CreatureEventBindings(new EntryBind<Hooks::CreatureEvents>("CreatureEvents", *this)),
|
||||
CreatureGossipBindings(new EntryBind<Hooks::GossipEvents>("GossipEvents (creature)", *this)),
|
||||
GameObjectEventBindings(new EntryBind<Hooks::GameObjectEvents>("GameObjectEvents", *this)),
|
||||
GameObjectGossipBindings(new EntryBind<Hooks::GossipEvents>("GossipEvents (gameobject)", *this)),
|
||||
ItemEventBindings(new EntryBind<Hooks::ItemEvents>("ItemEvents", *this)),
|
||||
ItemGossipBindings(new EntryBind<Hooks::GossipEvents>("GossipEvents (item)", *this)),
|
||||
playerGossipBindings(new EntryBind<Hooks::GossipEvents>("GossipEvents (player)", *this)),
|
||||
|
||||
CreatureUniqueBindings(new UniqueBind<HookMgr::CreatureEvents>("CreatureEvents", *this))
|
||||
CreatureUniqueBindings(new UniqueBind<Hooks::CreatureEvents>("CreatureEvents", *this))
|
||||
{
|
||||
// open base lua libraries
|
||||
luaL_openlibs(L);
|
||||
@@ -767,56 +768,56 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
{
|
||||
switch (regtype)
|
||||
{
|
||||
case HookMgr::REGTYPE_SERVER:
|
||||
if (evt < HookMgr::SERVER_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_SERVER:
|
||||
if (evt < Hooks::SERVER_EVENT_COUNT)
|
||||
{
|
||||
ServerEventBindings->Insert(evt, functionRef, shots);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_PLAYER:
|
||||
if (evt < HookMgr::PLAYER_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_PLAYER:
|
||||
if (evt < Hooks::PLAYER_EVENT_COUNT)
|
||||
{
|
||||
PlayerEventBindings->Insert(evt, functionRef, shots);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_GUILD:
|
||||
if (evt < HookMgr::GUILD_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_GUILD:
|
||||
if (evt < Hooks::GUILD_EVENT_COUNT)
|
||||
{
|
||||
GuildEventBindings->Insert(evt, functionRef, shots);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_GROUP:
|
||||
if (evt < HookMgr::GROUP_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_GROUP:
|
||||
if (evt < Hooks::GROUP_EVENT_COUNT)
|
||||
{
|
||||
GroupEventBindings->Insert(evt, functionRef, shots);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_VEHICLE:
|
||||
if (evt < HookMgr::VEHICLE_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_VEHICLE:
|
||||
if (evt < Hooks::VEHICLE_EVENT_COUNT)
|
||||
{
|
||||
VehicleEventBindings->Insert(evt, functionRef, shots);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_BG:
|
||||
if (evt < HookMgr::BG_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_BG:
|
||||
if (evt < Hooks::BG_EVENT_COUNT)
|
||||
{
|
||||
BGEventBindings->Insert(evt, functionRef, shots);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_PACKET:
|
||||
if (evt < HookMgr::PACKET_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_PACKET:
|
||||
if (evt < Hooks::PACKET_EVENT_COUNT)
|
||||
{
|
||||
if (id >= NUM_MSG_TYPES)
|
||||
{
|
||||
@@ -830,8 +831,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_CREATURE:
|
||||
if (evt < HookMgr::CREATURE_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_CREATURE:
|
||||
if (evt < Hooks::CREATURE_EVENT_COUNT)
|
||||
{
|
||||
if (id != 0)
|
||||
{
|
||||
@@ -853,8 +854,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_CREATURE_GOSSIP:
|
||||
if (evt < HookMgr::GOSSIP_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_CREATURE_GOSSIP:
|
||||
if (evt < Hooks::GOSSIP_EVENT_COUNT)
|
||||
{
|
||||
if (!eObjectMgr->GetCreatureTemplate(id))
|
||||
{
|
||||
@@ -868,8 +869,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_GAMEOBJECT:
|
||||
if (evt < HookMgr::GAMEOBJECT_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_GAMEOBJECT:
|
||||
if (evt < Hooks::GAMEOBJECT_EVENT_COUNT)
|
||||
{
|
||||
if (!eObjectMgr->GetGameObjectTemplate(id))
|
||||
{
|
||||
@@ -883,8 +884,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_GAMEOBJECT_GOSSIP:
|
||||
if (evt < HookMgr::GOSSIP_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_GAMEOBJECT_GOSSIP:
|
||||
if (evt < Hooks::GOSSIP_EVENT_COUNT)
|
||||
{
|
||||
if (!eObjectMgr->GetGameObjectTemplate(id))
|
||||
{
|
||||
@@ -898,8 +899,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_ITEM:
|
||||
if (evt < HookMgr::ITEM_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_ITEM:
|
||||
if (evt < Hooks::ITEM_EVENT_COUNT)
|
||||
{
|
||||
if (!eObjectMgr->GetItemTemplate(id))
|
||||
{
|
||||
@@ -913,8 +914,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_ITEM_GOSSIP:
|
||||
if (evt < HookMgr::GOSSIP_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_ITEM_GOSSIP:
|
||||
if (evt < Hooks::GOSSIP_EVENT_COUNT)
|
||||
{
|
||||
if (!eObjectMgr->GetItemTemplate(id))
|
||||
{
|
||||
@@ -928,8 +929,8 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
}
|
||||
break;
|
||||
|
||||
case HookMgr::REGTYPE_PLAYER_GOSSIP:
|
||||
if (evt < HookMgr::GOSSIP_EVENT_COUNT)
|
||||
case Hooks::REGTYPE_PLAYER_GOSSIP:
|
||||
if (evt < Hooks::GOSSIP_EVENT_COUNT)
|
||||
{
|
||||
playerGossipBindings->Insert(id, evt, functionRef, shots);
|
||||
return;
|
||||
@@ -939,3 +940,56 @@ void Eluna::Register(uint8 regtype, uint32 id, uint64 guid, uint32 instanceId, u
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, functionRef);
|
||||
luaL_error(L, "Unknown event type (regtype %d, id %d, event %d)", regtype, id, evt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleans up the stack, effectively undoing all Push calls and the Setup call.
|
||||
*/
|
||||
void Eluna::CleanUpStack(int number_of_arguments)
|
||||
{
|
||||
// Stack: event_id, [arguments]
|
||||
|
||||
lua_pop(L, number_of_arguments + 1); // Add 1 because the caller doesn't know about `event_id`.
|
||||
// Stack: (empty)
|
||||
|
||||
if (event_level == 0)
|
||||
InvalidateObjects();
|
||||
}
|
||||
|
||||
/*
|
||||
* Call a single event handler that was put on the stack with `Setup` and removes it from the stack.
|
||||
*
|
||||
* The caller is responsible for keeping track of how many times this should be called.
|
||||
*/
|
||||
int Eluna::CallOneFunction(int number_of_functions, int number_of_arguments, int number_of_results)
|
||||
{
|
||||
++number_of_arguments; // Caller doesn't know about `event_id`.
|
||||
ASSERT(number_of_functions > 0 && number_of_arguments > 0 && number_of_results >= 0);
|
||||
// Stack: event_id, [arguments], [functions]
|
||||
|
||||
int functions_top = lua_gettop(L);
|
||||
int first_function_index = functions_top - number_of_functions + 1;
|
||||
int arguments_top = first_function_index - 1;
|
||||
int first_argument_index = arguments_top - number_of_arguments + 1;
|
||||
|
||||
// Copy the arguments from the bottom of the stack to the top.
|
||||
for (int argument_index = first_argument_index; argument_index <= arguments_top; ++argument_index)
|
||||
{
|
||||
lua_pushvalue(L, argument_index);
|
||||
}
|
||||
// Stack: event_id, [arguments], [functions], event_id, [arguments]
|
||||
|
||||
ExecuteCall(number_of_arguments, number_of_results);
|
||||
--functions_top;
|
||||
// Stack: event_id, [arguments], [functions - 1], [results]
|
||||
|
||||
return functions_top + 1; // Return the location of the first result (if any exist).
|
||||
}
|
||||
|
||||
CreatureAI* Eluna::GetAI(Creature* creature)
|
||||
{
|
||||
if (CreatureEventBindings->HasEvents(creature->GetEntry()) ||
|
||||
CreatureUniqueBindings->HasEvents(creature->GET_GUID(), creature->GetInstanceId()))
|
||||
return new ElunaCreatureAI(creature);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
46
LuaEngine.h
46
LuaEngine.h
@@ -18,7 +18,7 @@
|
||||
#endif
|
||||
#include "Weather.h"
|
||||
#include "World.h"
|
||||
#include "HookMgr.h"
|
||||
#include "Hooks.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -112,6 +112,7 @@ private:
|
||||
Eluna& operator=(const Eluna&);
|
||||
|
||||
// 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);
|
||||
@@ -183,23 +184,23 @@ public:
|
||||
|
||||
EventMgr* eventMgr;
|
||||
|
||||
EventBind<HookMgr::ServerEvents>* ServerEventBindings;
|
||||
EventBind<HookMgr::PlayerEvents>* PlayerEventBindings;
|
||||
EventBind<HookMgr::GuildEvents>* GuildEventBindings;
|
||||
EventBind<HookMgr::GroupEvents>* GroupEventBindings;
|
||||
EventBind<HookMgr::VehicleEvents>* VehicleEventBindings;
|
||||
EventBind<HookMgr::BGEvents>* BGEventBindings;
|
||||
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<HookMgr::PacketEvents>* PacketEventBindings;
|
||||
EntryBind<HookMgr::CreatureEvents>* CreatureEventBindings;
|
||||
EntryBind<HookMgr::GossipEvents>* CreatureGossipBindings;
|
||||
EntryBind<HookMgr::GameObjectEvents>* GameObjectEventBindings;
|
||||
EntryBind<HookMgr::GossipEvents>* GameObjectGossipBindings;
|
||||
EntryBind<HookMgr::ItemEvents>* ItemEventBindings;
|
||||
EntryBind<HookMgr::GossipEvents>* ItemGossipBindings;
|
||||
EntryBind<HookMgr::GossipEvents>* playerGossipBindings;
|
||||
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<HookMgr::CreatureEvents>* CreatureUniqueBindings;
|
||||
UniqueBind<Hooks::CreatureEvents>* CreatureUniqueBindings;
|
||||
|
||||
Eluna();
|
||||
~Eluna();
|
||||
@@ -235,16 +236,18 @@ public:
|
||||
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*);
|
||||
template<typename T> static void Push(lua_State* luastate, T const* ptr)
|
||||
{
|
||||
ElunaTemplate<T>::Push(luastate, ptr);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -263,7 +266,8 @@ public:
|
||||
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; }
|
||||
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);
|
||||
|
||||
719
PlayerHooks.cpp
Normal file
719
PlayerHooks.cpp
Normal file
@@ -0,0 +1,719 @@
|
||||
/*
|
||||
* 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 _PLAYER_HOOKS_H
|
||||
#define _PLAYER_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaIncludes.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* item, uint32 sender, uint32 action, const std::string& code)
|
||||
{
|
||||
if (!ItemGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, item->GetEntry()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
Push(pPlayer);
|
||||
Push(item);
|
||||
Push(sender);
|
||||
Push(action);
|
||||
if (code.empty())
|
||||
Push();
|
||||
else
|
||||
Push(code);
|
||||
|
||||
CallAllFunctions(ItemGossipBindings, GOSSIP_EVENT_ON_SELECT, item->GetEntry());
|
||||
}
|
||||
|
||||
void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code)
|
||||
{
|
||||
if (!playerGossipBindings->HasEvents(GOSSIP_EVENT_ON_SELECT, menuId))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
|
||||
Push(pPlayer); // receiver
|
||||
Push(pPlayer); // sender, just not to mess up the amount of args.
|
||||
Push(sender);
|
||||
Push(action);
|
||||
if (code.empty())
|
||||
Push();
|
||||
else
|
||||
Push(code);
|
||||
|
||||
CallAllFunctions(playerGossipBindings, GOSSIP_EVENT_ON_SELECT, menuId);
|
||||
}
|
||||
|
||||
// Player
|
||||
bool Eluna::OnCommand(Player* player, const char* text)
|
||||
{
|
||||
// If from console, player is NULL
|
||||
std::string fullcmd(text);
|
||||
if (!player || player->GetSession()->GetSecurity() >= SEC_ADMINISTRATOR)
|
||||
{
|
||||
char* creload = strtok((char*)text, " ");
|
||||
char* celuna = strtok(NULL, "");
|
||||
if (creload && celuna)
|
||||
{
|
||||
std::string reload(creload);
|
||||
std::string eluna(celuna);
|
||||
std::transform(reload.begin(), reload.end(), reload.begin(), ::tolower);
|
||||
if (reload == "reload")
|
||||
{
|
||||
std::transform(eluna.begin(), eluna.end(), eluna.begin(), ::tolower);
|
||||
if (std::string("eluna").find(eluna) == 0)
|
||||
{
|
||||
Eluna::reload = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_COMMAND))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(player);
|
||||
Push(fullcmd);
|
||||
return CallAllFunctionsBool(PlayerEventBindings, PLAYER_EVENT_ON_COMMAND, true);
|
||||
}
|
||||
|
||||
void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, uint64 guid)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOOT_ITEM))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pItem);
|
||||
Push(count);
|
||||
Push(guid);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_ITEM);
|
||||
}
|
||||
|
||||
void Eluna::OnLootMoney(Player* pPlayer, uint32 amount)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOOT_MONEY))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(amount);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOOT_MONEY);
|
||||
}
|
||||
|
||||
void Eluna::OnFirstLogin(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_FIRST_LOGIN))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_FIRST_LOGIN);
|
||||
}
|
||||
|
||||
void Eluna::OnRepop(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_REPOP))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_REPOP);
|
||||
}
|
||||
|
||||
void Eluna::OnResurrect(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_RESURRECT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_RESURRECT);
|
||||
}
|
||||
|
||||
void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_QUEST_ABANDON))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(questId);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_QUEST_ABANDON);
|
||||
}
|
||||
|
||||
void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_EQUIP))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pItem);
|
||||
Push(bag);
|
||||
Push(slot);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_EQUIP);
|
||||
}
|
||||
|
||||
InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CAN_USE_ITEM))
|
||||
return EQUIP_ERR_OK;
|
||||
|
||||
LOCK_ELUNA;
|
||||
InventoryResult result = EQUIP_ERR_OK;
|
||||
Push(pPlayer);
|
||||
Push(itemEntry);
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_CAN_USE_ITEM, 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
result = (InventoryResult)CHECKVAL<uint32>(L, r);
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
return result;
|
||||
}
|
||||
void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_ENTER_COMBAT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pEnemy);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_ENTER_COMBAT);
|
||||
}
|
||||
|
||||
void Eluna::OnPlayerLeaveCombat(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LEAVE_COMBAT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEAVE_COMBAT);
|
||||
}
|
||||
|
||||
void Eluna::OnPVPKill(Player* pKiller, Player* pKilled)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_KILL_PLAYER))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pKiller);
|
||||
Push(pKilled);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILL_PLAYER);
|
||||
}
|
||||
|
||||
void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_KILL_CREATURE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pKiller);
|
||||
Push(pKilled);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILL_CREATURE);
|
||||
}
|
||||
|
||||
void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_KILLED_BY_CREATURE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pKiller);
|
||||
Push(pKilled);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_KILLED_BY_CREATURE);
|
||||
}
|
||||
|
||||
void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LEVEL_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(oldLevel);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LEVEL_CHANGE);
|
||||
}
|
||||
|
||||
void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_TALENTS_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(newPoints);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_CHANGE);
|
||||
}
|
||||
|
||||
void Eluna::OnTalentsReset(Player* pPlayer, bool noCost)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_TALENTS_RESET))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(noCost);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TALENTS_RESET);
|
||||
}
|
||||
|
||||
void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_MONEY_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(amount);
|
||||
int amountIndex = lua_gettop(L);
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_MONEY_CHANGE, 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
{
|
||||
amount = CHECKVAL<int32>(L, r);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(amount, amountIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
}
|
||||
|
||||
void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GIVE_XP))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(amount);
|
||||
Push(pVictim);
|
||||
int amountIndex = lua_gettop(L) - 1;
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GIVE_XP, 3);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 3, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
{
|
||||
amount = CHECKVAL<uint32>(L, r);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(amount, amountIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(3);
|
||||
}
|
||||
|
||||
void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_REPUTATION_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(factionID);
|
||||
Push(standing);
|
||||
Push(incremental);
|
||||
int standingIndex = lua_gettop(L) - 1;
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_REPUTATION_CHANGE, 4);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 4, 1);
|
||||
|
||||
if (lua_isnumber(L, r))
|
||||
{
|
||||
standing = CHECKVAL<int32>(L, r);
|
||||
// Update the stack for subsequent calls.
|
||||
ReplaceArgument(standing, standingIndex);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
CleanUpStack(4);
|
||||
}
|
||||
|
||||
void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_DUEL_REQUEST))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pTarget);
|
||||
Push(pChallenger);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_REQUEST);
|
||||
}
|
||||
|
||||
void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_DUEL_START))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pStarter);
|
||||
Push(pChallenger);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_START);
|
||||
}
|
||||
|
||||
void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_DUEL_END))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pWinner);
|
||||
Push(pLoser);
|
||||
Push(type);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_DUEL_END);
|
||||
}
|
||||
|
||||
void Eluna::OnEmote(Player* pPlayer, uint32 emote)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_EMOTE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(emote);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_EMOTE);
|
||||
}
|
||||
|
||||
void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, uint64 guid)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_TEXT_EMOTE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(textEmote);
|
||||
Push(emoteNum);
|
||||
Push(guid);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_TEXT_EMOTE);
|
||||
}
|
||||
|
||||
void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_SPELL_CAST))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pSpell);
|
||||
Push(skipCheck);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_SPELL_CAST);
|
||||
}
|
||||
|
||||
void Eluna::OnLogin(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOGIN))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGIN);
|
||||
}
|
||||
|
||||
void Eluna::OnLogout(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_LOGOUT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_LOGOUT);
|
||||
}
|
||||
|
||||
void Eluna::OnCreate(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHARACTER_CREATE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_CREATE);
|
||||
}
|
||||
|
||||
void Eluna::OnDelete(uint32 guidlow)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHARACTER_DELETE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(guidlow);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_CHARACTER_DELETE);
|
||||
}
|
||||
|
||||
void Eluna::OnSave(Player* pPlayer)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_SAVE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_SAVE);
|
||||
}
|
||||
|
||||
void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_BIND_TO_INSTANCE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(difficulty);
|
||||
Push(mapid);
|
||||
Push(permanent);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_BIND_TO_INSTANCE);
|
||||
}
|
||||
|
||||
void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_UPDATE_ZONE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(newZone);
|
||||
Push(newArea);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_UPDATE_ZONE);
|
||||
}
|
||||
|
||||
void Eluna::OnMapChanged(Player* player)
|
||||
{
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_MAP_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(player);
|
||||
CallAllFunctions(PlayerEventBindings, PLAYER_EVENT_ON_MAP_CHANGE);
|
||||
}
|
||||
|
||||
// AddOns
|
||||
bool Eluna::OnAddonMessage(Player* sender, uint32 type, std::string& msg, Player* receiver, Guild* guild, Group* group, Channel* channel)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(ADDON_EVENT_ON_MESSAGE))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(sender);
|
||||
Push(type);
|
||||
const char* c_msg = msg.c_str();
|
||||
Push(strtok((char*)c_msg, "\t")); // prefix
|
||||
Push(strtok(NULL, "")); // msg
|
||||
if (receiver)
|
||||
Push(receiver);
|
||||
else if (guild)
|
||||
Push(guild);
|
||||
else if (group)
|
||||
Push(group);
|
||||
else if (channel)
|
||||
Push(channel->GetChannelId());
|
||||
else
|
||||
Push();
|
||||
|
||||
return CallAllFunctionsBool(ServerEventBindings, ADDON_EVENT_ON_MESSAGE, true);
|
||||
}
|
||||
|
||||
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg)
|
||||
{
|
||||
if (lang == LANG_ADDON)
|
||||
return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHAT))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = true;
|
||||
Push(pPlayer);
|
||||
Push(msg);
|
||||
Push(type);
|
||||
Push(lang);
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_CHAT, 4);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 4, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isstring(L, r + 1))
|
||||
msg = std::string(lua_tostring(L, r + 1));
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(4);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup)
|
||||
{
|
||||
if (lang == LANG_ADDON)
|
||||
return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL);
|
||||
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GROUP_CHAT))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = true;
|
||||
Push(pPlayer);
|
||||
Push(msg);
|
||||
Push(type);
|
||||
Push(lang);
|
||||
Push(pGroup);
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GROUP_CHAT, 5);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 5, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isstring(L, r + 1))
|
||||
msg = std::string(lua_tostring(L, r + 1));
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(5);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild)
|
||||
{
|
||||
if (lang == LANG_ADDON)
|
||||
return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL);
|
||||
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_GUILD_CHAT))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = true;
|
||||
Push(pPlayer);
|
||||
Push(msg);
|
||||
Push(type);
|
||||
Push(lang);
|
||||
Push(pGuild);
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_GUILD_CHAT, 5);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 5, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isstring(L, r + 1))
|
||||
msg = std::string(lua_tostring(L, r + 1));
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(5);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel)
|
||||
{
|
||||
if (lang == LANG_ADDON)
|
||||
return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel);
|
||||
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_CHANNEL_CHAT))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = true;
|
||||
Push(pPlayer);
|
||||
Push(msg);
|
||||
Push(type);
|
||||
Push(lang);
|
||||
Push(pChannel->GetChannelId());
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_CHANNEL_CHAT, 5);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 5, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isstring(L, r + 1))
|
||||
msg = std::string(lua_tostring(L, r + 1));
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(5);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver)
|
||||
{
|
||||
if (lang == LANG_ADDON)
|
||||
return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL);
|
||||
|
||||
if (!PlayerEventBindings->HasEvents(PLAYER_EVENT_ON_WHISPER))
|
||||
return true;
|
||||
|
||||
LOCK_ELUNA;
|
||||
bool result = true;
|
||||
Push(pPlayer);
|
||||
Push(msg);
|
||||
Push(type);
|
||||
Push(lang);
|
||||
Push(pReceiver);
|
||||
int n = SetupStack(PlayerEventBindings, PLAYER_EVENT_ON_WHISPER, 5);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 5, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isstring(L, r + 1))
|
||||
msg = std::string(lua_tostring(L, r + 1));
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(5);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // _PLAYER_HOOKS_H
|
||||
386
ServerHooks.cpp
Normal file
386
ServerHooks.cpp
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* 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 _SERVER_HOOKS_H
|
||||
#define _SERVER_HOOKS_H
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
#include "ElunaTemplate.h" // Needed to be able to push AuctionHouseObjects.
|
||||
#include "ElunaEventMgr.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
void Eluna::OnLuaStateClose()
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(ELUNA_EVENT_ON_LUA_STATE_CLOSE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_CLOSE);
|
||||
}
|
||||
|
||||
void Eluna::OnLuaStateOpen()
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(ELUNA_EVENT_ON_LUA_STATE_OPEN))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
CallAllFunctions(ServerEventBindings, ELUNA_EVENT_ON_LUA_STATE_OPEN);
|
||||
}
|
||||
|
||||
// areatrigger
|
||||
bool Eluna::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* pTrigger)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(TRIGGER_EVENT_ON_TRIGGER))
|
||||
return false;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(pPlayer);
|
||||
Push(pTrigger->id);
|
||||
return CallAllFunctionsBool(ServerEventBindings, TRIGGER_EVENT_ON_TRIGGER);
|
||||
}
|
||||
|
||||
// weather
|
||||
void Eluna::OnChange(Weather* weather, uint32 zone, WeatherState state, float grade)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WEATHER_EVENT_ON_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(zone);
|
||||
Push(state);
|
||||
Push(grade);
|
||||
CallAllFunctions(ServerEventBindings, WEATHER_EVENT_ON_CHANGE);
|
||||
}
|
||||
|
||||
// Auction House
|
||||
void Eluna::OnAdd(AuctionHouseObject* ah)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_ADD))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(ah);
|
||||
CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_ADD);
|
||||
}
|
||||
|
||||
void Eluna::OnRemove(AuctionHouseObject* ah)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_REMOVE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(ah);
|
||||
CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_REMOVE);
|
||||
}
|
||||
|
||||
void Eluna::OnSuccessful(AuctionHouseObject* ah)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_SUCCESSFUL))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(ah);
|
||||
CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_SUCCESSFUL);
|
||||
}
|
||||
|
||||
void Eluna::OnExpire(AuctionHouseObject* ah)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(AUCTION_EVENT_ON_EXPIRE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(ah);
|
||||
CallAllFunctions(ServerEventBindings, AUCTION_EVENT_ON_EXPIRE);
|
||||
}
|
||||
|
||||
// Packet
|
||||
bool Eluna::OnPacketSend(WorldSession* session, WorldPacket& packet)
|
||||
{
|
||||
bool result = true;
|
||||
Player* player = NULL;
|
||||
if (session)
|
||||
player = session->GetPlayer();
|
||||
OnPacketSendAny(player, packet, result);
|
||||
OnPacketSendOne(player, packet, result);
|
||||
return result;
|
||||
}
|
||||
void Eluna::OnPacketSendAny(Player* player, WorldPacket& packet, bool& result)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(SERVER_EVENT_ON_PACKET_SEND))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(new WorldPacket(packet));
|
||||
Push(player);
|
||||
int n = SetupStack(ServerEventBindings, SERVER_EVENT_ON_PACKET_SEND, 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isuserdata(L, r + 1))
|
||||
if (WorldPacket* data = CHECKOBJ<WorldPacket>(L, r + 1, false))
|
||||
packet = *data;
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
}
|
||||
|
||||
void Eluna::OnPacketSendOne(Player* player, WorldPacket& packet, bool& result)
|
||||
{
|
||||
if (!PacketEventBindings->HasEvents(PACKET_EVENT_ON_PACKET_SEND, packet.GetOpcode()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(new WorldPacket(packet));
|
||||
Push(player);
|
||||
int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_SEND, OpcodesList(packet.GetOpcode()), 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isuserdata(L, r + 1))
|
||||
if (WorldPacket* data = CHECKOBJ<WorldPacket>(L, r + 1, false))
|
||||
packet = *data;
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
}
|
||||
|
||||
bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet)
|
||||
{
|
||||
bool result = true;
|
||||
Player* player = NULL;
|
||||
if (session)
|
||||
player = session->GetPlayer();
|
||||
OnPacketReceiveAny(player, packet, result);
|
||||
OnPacketReceiveOne(player, packet, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(SERVER_EVENT_ON_PACKET_RECEIVE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(new WorldPacket(packet));
|
||||
Push(player);
|
||||
int n = SetupStack(ServerEventBindings, SERVER_EVENT_ON_PACKET_RECEIVE, 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isuserdata(L, r + 1))
|
||||
if (WorldPacket* data = CHECKOBJ<WorldPacket>(L, r + 1, false))
|
||||
packet = *data;
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
}
|
||||
|
||||
void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result)
|
||||
{
|
||||
if (!PacketEventBindings->HasEvents(PACKET_EVENT_ON_PACKET_RECEIVE, packet.GetOpcode()))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(new WorldPacket(packet));
|
||||
Push(player);
|
||||
int n = SetupStack(PacketEventBindings, PACKET_EVENT_ON_PACKET_RECEIVE, OpcodesList(), 2);
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
int r = CallOneFunction(n--, 2, 2);
|
||||
|
||||
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
|
||||
result = false;
|
||||
|
||||
if (lua_isuserdata(L, r + 1))
|
||||
if (WorldPacket* data = CHECKOBJ<WorldPacket>(L, r + 1, false))
|
||||
packet = *data;
|
||||
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
CleanUpStack(2);
|
||||
}
|
||||
|
||||
void Eluna::OnOpenStateChange(bool open)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_OPEN_STATE_CHANGE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(open);
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_OPEN_STATE_CHANGE);
|
||||
}
|
||||
|
||||
void Eluna::OnConfigLoad(bool reload)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_CONFIG_LOAD))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(reload);
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_CONFIG_LOAD);
|
||||
}
|
||||
|
||||
void Eluna::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_SHUTDOWN_INIT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(code);
|
||||
Push(mask);
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_INIT);
|
||||
}
|
||||
|
||||
void Eluna::OnShutdownCancel()
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_SHUTDOWN_CANCEL))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN_CANCEL);
|
||||
}
|
||||
|
||||
void Eluna::OnWorldUpdate(uint32 diff)
|
||||
{
|
||||
LOCK_ELUNA;
|
||||
|
||||
if (reload)
|
||||
{
|
||||
ReloadEluna();
|
||||
return;
|
||||
}
|
||||
|
||||
eventMgr->globalProcessor->Update(diff);
|
||||
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_UPDATE))
|
||||
return;
|
||||
|
||||
Push(diff);
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_UPDATE);
|
||||
}
|
||||
|
||||
void Eluna::OnStartup()
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_STARTUP))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_STARTUP);
|
||||
}
|
||||
|
||||
void Eluna::OnShutdown()
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_SHUTDOWN))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_SHUTDOWN);
|
||||
}
|
||||
|
||||
/* Map */
|
||||
void Eluna::OnCreate(Map* map)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_CREATE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(map);
|
||||
CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_CREATE);
|
||||
}
|
||||
|
||||
void Eluna::OnDestroy(Map* map)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_DESTROY))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(map);
|
||||
CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_DESTROY);
|
||||
}
|
||||
|
||||
void Eluna::OnPlayerEnter(Map* map, Player* player)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_PLAYER_ENTER))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(map);
|
||||
Push(player);
|
||||
CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_PLAYER_ENTER);
|
||||
}
|
||||
|
||||
void Eluna::OnPlayerLeave(Map* map, Player* player)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_PLAYER_LEAVE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(map);
|
||||
Push(player);
|
||||
CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_PLAYER_LEAVE);
|
||||
}
|
||||
|
||||
void Eluna::OnUpdate(Map* map, uint32 diff)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(MAP_EVENT_ON_UPDATE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
// enable this for multithread
|
||||
// eventMgr->globalProcessor->Update(diff);
|
||||
Push(map);
|
||||
Push(diff);
|
||||
CallAllFunctions(ServerEventBindings, MAP_EVENT_ON_UPDATE);
|
||||
}
|
||||
|
||||
void Eluna::OnRemove(GameObject* gameobject)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_DELETE_GAMEOBJECT))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(gameobject);
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_GAMEOBJECT);
|
||||
}
|
||||
|
||||
void Eluna::OnRemove(Creature* creature)
|
||||
{
|
||||
if (!ServerEventBindings->HasEvents(WORLD_EVENT_ON_DELETE_CREATURE))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(creature);
|
||||
CallAllFunctions(ServerEventBindings, WORLD_EVENT_ON_DELETE_CREATURE);
|
||||
}
|
||||
|
||||
#endif // _SERVER_HOOKS_H
|
||||
77
VehicleHooks.cpp
Normal file
77
VehicleHooks.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 _VEHICLE_HOOKS_H
|
||||
#define _VEHICLE_HOOKS_H
|
||||
|
||||
#ifndef CLASSIC
|
||||
#ifndef TBC
|
||||
|
||||
#include "Hooks.h"
|
||||
#include "HookHelpers.h"
|
||||
#include "LuaEngine.h"
|
||||
#include "ElunaBinding.h"
|
||||
|
||||
using namespace Hooks;
|
||||
|
||||
// Vehicle
|
||||
void Eluna::OnInstall(Vehicle* vehicle)
|
||||
{
|
||||
if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_INSTALL))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(vehicle);
|
||||
CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL);
|
||||
}
|
||||
|
||||
void Eluna::OnUninstall(Vehicle* vehicle)
|
||||
{
|
||||
if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_UNINSTALL))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(vehicle);
|
||||
CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_UNINSTALL);
|
||||
}
|
||||
|
||||
void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory)
|
||||
{
|
||||
if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_INSTALL_ACCESSORY))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(vehicle);
|
||||
Push(accessory);
|
||||
CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_INSTALL_ACCESSORY);
|
||||
}
|
||||
|
||||
void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId)
|
||||
{
|
||||
if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_ADD_PASSENGER))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(vehicle);
|
||||
Push(passenger);
|
||||
Push(seatId);
|
||||
CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_ADD_PASSENGER);
|
||||
}
|
||||
|
||||
void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger)
|
||||
{
|
||||
if (!VehicleEventBindings->HasEvents(VEHICLE_EVENT_ON_REMOVE_PASSENGER))
|
||||
return;
|
||||
|
||||
LOCK_ELUNA;
|
||||
Push(vehicle);
|
||||
Push(passenger);
|
||||
CallAllFunctions(VehicleEventBindings, VEHICLE_EVENT_ON_REMOVE_PASSENGER);
|
||||
}
|
||||
|
||||
#endif // CLASSIC
|
||||
#endif // TBC
|
||||
#endif // _VEHICLE_HOOKS_H
|
||||
Reference in New Issue
Block a user