Allow binding event handlers to individual Creatures.

Because GUIDs are, in fact, not globally unique on mangos, the actual
unique identifier is the GUID/instance ID pair of the Creature.

On Trinity Creatures in instances are assigned new GUIDs. This means that
the instance ID part is redundant but must be used anyway for consistency.
This commit is contained in:
Patman64
2015-01-11 18:48:38 -05:00
parent 882eb40acb
commit dd39592ddd
6 changed files with 367 additions and 89 deletions

View File

@@ -94,7 +94,7 @@ using namespace HookMgr;
* 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, T event_id, uint32 entry, int number_of_arguments)
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));
@@ -118,6 +118,9 @@ int Eluna::SetupStack(EventBind<T>* event_bindings, EntryBind<T>* entry_bindings
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;
@@ -188,12 +191,12 @@ void Eluna::CleanUpStack(int number_of_arguments)
* 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, T event_id, uint32 entry)
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, event_id, entry, number_of_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)
@@ -214,14 +217,14 @@ void Eluna::CallAllFunctions(EventBind<T>* event_bindings, EntryBind<T>* entry_b
* otherwise returns the opposite of `default_value`.
*/
template<typename T>
bool Eluna::CallAllFunctionsBool(EventBind<T>* event_bindings, EntryBind<T>* entry_bindings, T event_id, uint32 entry, bool default_value)
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, event_id, entry, number_of_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)
@@ -1734,14 +1737,15 @@ void Eluna::OnRemove(Creature* creature)
bool Eluna::OnDummyEffect(Unit* pCaster, uint32 spellId, SpellEffIndex effIndex, Creature* pTarget)
{
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()))
return false;
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, CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry());
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry(), pTarget->GET_GUID(), pTarget->GetInstanceId());
}
bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature)
@@ -1788,80 +1792,87 @@ bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 send
bool Eluna::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
{
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GetEntry()))
return false;
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, CREATURE_EVENT_ON_QUEST_ACCEPT, pCreature->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_QUEST_REWARD, pCreature->GetEntry());
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()))
return DIALOG_STATUS_SCRIPTED_NO_STATUS;
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, CREATURE_EVENT_ON_DIALOG_STATUS, pCreature->GetEntry());
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()))
return;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_ADD, creature->GET_GUID(), creature->GetInstanceId()))
return;
LOCK_ELUNA;
Push(creature);
CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_ADD, creature->GetEntry());
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()))
return;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_REMOVE, creature->GET_GUID(), creature->GetInstanceId()))
return;
LOCK_ELUNA;
Push(creature);
CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_REMOVE, creature->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED, pCreature->GET_GUID(), pCreature->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(pCreature);
Push(pSummoner);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SUMMONED, pCreature->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_AIUPDATE, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(diff);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_AIUPDATE, me->GetEntry());
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)
@@ -1869,19 +1880,21 @@ bool Eluna::UpdateAI(Creature* me, const uint32 diff)
bool Eluna::EnterCombat(Creature* me, Unit* target)
{
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_ENTER_COMBAT, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(target);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_ENTER_COMBAT, me->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
bool result = false;
@@ -1889,7 +1902,7 @@ bool Eluna::DamageTaken(Creature* me, Unit* attacker, uint32& damage)
Push(attacker);
Push(damage);
int damageIndex = lua_gettop(L);
int n = SetupStack(CreatureEventBindings, CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry(), 3);
int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_DAMAGE_TAKEN, me->GetEntry(), me->GET_GUID(), me->GetInstanceId(), 3);
while (n > 0)
{
@@ -1918,73 +1931,79 @@ bool Eluna::JustDied(Creature* me, Unit* killer)
On_Reset(me);
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_DIED, me->GetEntry()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_DIED, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(killer);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_DIED, me->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_TARGET_DIED, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(victim);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_TARGET_DIED, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_REACH_WP, me->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_PRE_COMBAT, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(target);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_PRE_COMBAT, me->GetEntry());
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
@@ -1993,23 +2012,25 @@ bool Eluna::EnterEvadeMode(Creature* me)
On_Reset(me);
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_LEAVE_COMBAT, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_LEAVE_COMBAT, me->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_ATTACKED_AT, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(attacker);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_ATTACKED_AT, me->GetEntry());
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)
@@ -2018,49 +2039,53 @@ bool Eluna::JustRespawned(Creature* me)
On_Reset(me);
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SPAWN, me->GetEntry()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_SPAWN, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_SPAWN, me->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_REACH_HOME, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_REACH_HOME, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_RECEIVE_EMOTE, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry(), 2);
int n = SetupStack(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_CORPSE_REMOVED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId(), 2);
while (n > 0)
{
@@ -2086,49 +2111,53 @@ bool Eluna::CorpseRemoved(Creature* me, uint32& respawnDelay)
bool Eluna::MoveInLineOfSight(Creature* me, Unit* who)
{
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry()))
return false;
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, CREATURE_EVENT_ON_MOVE_IN_LOS, me->GetEntry());
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()))
return;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_RESET, me->GET_GUID(), me->GetInstanceId()))
return;
LOCK_ELUNA;
Push(me);
CallAllFunctions(CreatureEventBindings, CREATURE_EVENT_ON_RESET, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_HIT_BY_SPELL, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GetEntry());
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_SPELL_HIT_TARGET, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
}
#ifdef TRINITY
@@ -2136,37 +2165,40 @@ bool Eluna::SpellHitTarget(Creature* me, Unit* target, SpellInfo const* spell)
bool Eluna::SummonedCreatureDies(Creature* me, Creature* summon, Unit* killer)
{
if (!CreatureEventBindings->HasEvents(CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GetEntry()))
return false;
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, CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, me->GetEntry());
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()))
return false;
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, CREATURE_EVENT_ON_OWNER_ATTACKED_AT, me->GetEntry());
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()))
return false;
if (!CreatureUniqueBindings->HasEvents(CREATURE_EVENT_ON_OWNER_ATTACKED, me->GET_GUID(), me->GetInstanceId()))
return false;
LOCK_ELUNA;
Push(me);
Push(target);
return CallAllFunctionsBool(CreatureEventBindings, CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry());
return CallAllFunctionsBool(CreatureEventBindings, CreatureUniqueBindings, CREATURE_EVENT_ON_OWNER_ATTACKED, me->GetEntry(), me->GET_GUID(), me->GetInstanceId());
}
#endif
@@ -2547,7 +2579,7 @@ void Eluna::OnRemoveFromWorld(GameObject* gameobject)
CreatureAI* Eluna::GetAI(Creature* creature)
{
if (!CreatureEventBindings->HasEvents(creature->GetEntry()))
if (!CreatureEventBindings->HasEvents(creature->GetEntry()) && !CreatureUniqueBindings->HasEvents(creature->GET_GUID(), creature->GetInstanceId()))
return NULL;
return new ElunaCreatureAI(creature);
}