Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ElunaIncludes.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "ScriptMgr.h"
#include "Spell.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
#include "WorldPacket.h"
Expand Down
7 changes: 7 additions & 0 deletions ElunaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ ElunaConstrainedObjectRef<Aura> GetWeakPtrFor(Aura const* obj)
#endif
return { obj->GetWeakPtr(), map };
}

ElunaConstrainedObjectRef<AuraEffect> GetWeakPtrFor(AuraEffect const* obj)
{
Map* map = obj->GetBase()->GetOwner()->GetMap();
return { obj->GetWeakPtr(), map };
}

ElunaConstrainedObjectRef<BattleGround> GetWeakPtrFor(BattleGround const* obj) { return { obj->GetWeakPtr(), obj->GetBgMap() }; }
ElunaConstrainedObjectRef<Group> GetWeakPtrFor(Group const* obj) { return { obj->GetWeakPtr(), nullptr }; }
ElunaConstrainedObjectRef<Guild> GetWeakPtrFor(Guild const* obj) { return { obj->GetWeakPtr(), nullptr }; }
Expand Down
1 change: 1 addition & 0 deletions ElunaTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct ElunaConstrainedObjectRef
};

ElunaConstrainedObjectRef<Aura> GetWeakPtrFor(Aura const* obj);
ElunaConstrainedObjectRef<AuraEffect> GetWeakPtrFor(AuraEffect const* obj);
ElunaConstrainedObjectRef<BattleGround> GetWeakPtrFor(BattleGround const* obj);
ElunaConstrainedObjectRef<Group> GetWeakPtrFor(Group const* obj);
ElunaConstrainedObjectRef<Guild> GetWeakPtrFor(Guild const* obj);
Expand Down
6 changes: 6 additions & 0 deletions LuaEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,12 @@ class ELUNA_GAME_API Eluna

/* Spell */
void OnSpellCast(Spell* pSpell, bool skipCheck);
bool OnAuraApplication(Aura* aura, AuraEffect const* auraEff, Unit* target, uint8 mode, bool apply);
void OnAuraDispel(Aura* aura, DispelInfo* dispelInfo);
bool OnPerodicTick(Aura* aura, AuraEffect const* auraEff, Unit* target);
void OnPerodicUpdate(Aura* aura, AuraEffect const* auraEff);
void OnAuraCalcAmount(Aura* aura, AuraEffect const* auraEff, int32& amount, bool& canBeRecalculated);
void OnCalcPerodic(Aura* aura, AuraEffect const* auraEff, bool& isPeriodic, int32& amplitude);
};
template<> Unit* Eluna::CHECKOBJ<Unit>(int narg, bool error);
template<> Object* Eluna::CHECKOBJ<Object>(int narg, bool error);
Expand Down
16 changes: 14 additions & 2 deletions hooks/Hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,13 @@ namespace Hooks

enum SpellEvents
{
SPELL_EVENT_ON_CAST = 1, // (event, spell, skipCheck)
SPELL_EVENT_ON_CAST = 1, // (event, spell, skipCheck)
SPELL_EVENT_ON_AURA_APPLICATION = 2, // (event, aura, auraEffect, target, mode, apply) - Can return true to stop normal action
SPELL_EVENT_ON_DISPEL = 3, // (event, aura, dispeler, dispelSpellId, removedCharges)
SPELL_EVENT_ON_PERODIC_TICK = 4, // (event, aura, auraEffect, target) Can return true to stop normal action
SPELL_EVENT_ON_PERODIC_UPDATE = 5, // (event, aura, auraEffect)
SPELL_EVENT_ON_AURA_CALC_AMOUNT = 6, // (event, aura, auraEffect, amount, canBeRecalculated) - can return new amount as first return value, can return new canBeRecalculated as second return value
SPELL_EVENT_ON_CALC_PERODIC = 7, // (event, aura, auraEffect, isPeriodic, amplitude) - can return new isPeriodic as first return value, can return new amplitude as second return value
SPELL_EVENT_COUNT
};

Expand Down Expand Up @@ -520,7 +526,13 @@ class HookToReadableString
};

static constexpr EventEntry SpellEventsTable[] = {
{Hooks::SPELL_EVENT_ON_CAST, "on_cast"}
{Hooks::SPELL_EVENT_ON_CAST, "on_cast"},
{Hooks::SPELL_EVENT_ON_AURA_APPLICATION, "on_aura_application" },
{Hooks::SPELL_EVENT_ON_DISPEL, "on_aura_dispel" },
{Hooks::SPELL_EVENT_ON_PERODIC_TICK, "on_perodic_tick" },
{Hooks::SPELL_EVENT_ON_PERODIC_UPDATE, "on_perodic_update" },
{Hooks::SPELL_EVENT_ON_AURA_CALC_AMOUNT, "on_aura_calc_amount" },
{Hooks::SPELL_EVENT_ON_CALC_PERODIC, "on_calc_perodic" }
};

static constexpr EventEntry ItemEventsTable[] = {
Expand Down
113 changes: 111 additions & 2 deletions hooks/SpellHooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ using namespace Hooks;

#define START_HOOK(EVENT, SPELL) \
auto binding = GetBinding<EntryKey<SpellEvents>>(REGTYPE_SPELL);\
auto key = EntryKey<SpellEvents>(EVENT, SPELL->m_spellInfo->Id);\
auto key = EntryKey<SpellEvents>(EVENT, SPELL->GetSpellInfo()->Id);\
if (!binding->HasBindingsFor(key))\
return;

#define START_HOOK_WITH_RETVAL(EVENT, SPELL, RETVAL) \
auto binding = GetBinding<EntryKey<SpellEvents>>(REGTYPE_SPELL);\
auto key = EntryKey<SpellEvents>(EVENT, SPELL->m_spellInfo->Id);\
auto key = EntryKey<SpellEvents>(EVENT, SPELL->GetSpellInfo()->Id);\
if (!binding->HasBindingsFor(key))\
return RETVAL;

Expand All @@ -32,3 +32,112 @@ void Eluna::OnSpellCast(Spell* pSpell, bool skipCheck)
HookPush(skipCheck);
CallAllFunctions(binding, key);
}

bool Eluna::OnAuraApplication(Aura* aura, AuraEffect const* auraEff, Unit* target, uint8 mode, bool apply)
{
START_HOOK_WITH_RETVAL(SPELL_EVENT_ON_AURA_APPLICATION, aura, false);
HookPush(aura);
HookPush(auraEff);
HookPush(target);
HookPush(mode);
HookPush(apply);
return CallAllFunctionsBool(binding, key, false);
}

void Eluna::OnAuraDispel(Aura* aura, DispelInfo* dispelInfo)
{
START_HOOK(SPELL_EVENT_ON_DISPEL, aura);
HookPush(aura);
HookPush(dispelInfo->GetDispeller());
HookPush(dispelInfo->GetDispellerSpellId());
HookPush(dispelInfo->GetRemovedCharges());
CallAllFunctions(binding, key);
}

bool Eluna::OnPerodicTick(Aura* aura, AuraEffect const* auraEff, Unit* target)
{
START_HOOK_WITH_RETVAL(SPELL_EVENT_ON_PERODIC_TICK, aura, false);
HookPush(aura);
HookPush(auraEff);
HookPush(target);
return CallAllFunctionsBool(binding, key, false);
}

void Eluna::OnPerodicUpdate(Aura* aura, AuraEffect const* auraEff)
{
START_HOOK(SPELL_EVENT_ON_PERODIC_UPDATE, aura);
HookPush(aura);
HookPush(auraEff);
CallAllFunctions(binding, key);
}

void Eluna::OnAuraCalcAmount(Aura* aura, AuraEffect const* auraEff, int32& amount, bool& canBeRecalculated)
{
START_HOOK(SPELL_EVENT_ON_AURA_CALC_AMOUNT, aura);
HookPush(aura);
HookPush(auraEff);
HookPush(amount);
int amountIndex = lua_gettop(L);
HookPush(canBeRecalculated);
int canBeRecalculatedIndex = lua_gettop(L);
int n = SetupStack(binding, key, 4);

while (n > 0)
{
int r = CallOneFunction(n--, 4, 2);

if (lua_isnumber(L, r + 0))
{
amount = CHECKVAL<uint32>(r + 0);
// Update the stack for subsequent calls.
ReplaceArgument(amount, amountIndex);
}


if (lua_isboolean(L, r + 1))
{
canBeRecalculated = lua_toboolean(L, r + 1);
// Update the stack for subsequent calls.
ReplaceArgument(amount, canBeRecalculatedIndex);
}

lua_pop(L, 2);
}

CleanUpStack(2);
}

void Eluna::OnCalcPerodic(Aura* aura, AuraEffect const* auraEff, bool& isPeriodic, int32& amplitude)
{
START_HOOK(SPELL_EVENT_ON_AURA_CALC_AMOUNT, aura);
HookPush(aura);
HookPush(auraEff);
HookPush(isPeriodic);
int isPeriodicIndex = lua_gettop(L);
HookPush(amplitude);
int amplitudeIndex = lua_gettop(L);
int n = SetupStack(binding, key, 4);

while (n > 0)
{
int r = CallOneFunction(n--, 4, 2);

if (lua_isboolean(L, r + 0))
{
isPeriodic = lua_toboolean(L, r + 0);
// Update the stack for subsequent calls.
ReplaceArgument(isPeriodic, isPeriodicIndex);
}

if (lua_isnumber(L, r + 1))
{
amplitude = CHECKVAL<int32>(r + 1);
// Update the stack for subsequent calls.
ReplaceArgument(amplitude, amplitudeIndex);
}

lua_pop(L, 2);
}

CleanUpStack(2);
}
4 changes: 4 additions & 0 deletions methods/Methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "GameObjectMethods.h"
#include "ElunaQueryMethods.h"
#include "AuraMethods.h"
#include "AuraEffectMethods.h"
#include "ItemMethods.h"
#include "WorldPacketMethods.h"
#include "SpellMethods.h"
Expand Down Expand Up @@ -90,6 +91,9 @@ void RegisterMethods(Eluna* E)
ElunaTemplate<Aura>::Register(E, "Aura");
ElunaTemplate<Aura>::SetMethods(E, LuaAura::AuraMethods);

ElunaTemplate<AuraEffect>::Register(E, "AuraEffect");
ElunaTemplate<AuraEffect>::SetMethods(E, LuaAuraEffects::AuraEffectMethods);

ElunaTemplate<Spell>::Register(E, "Spell");
ElunaTemplate<Spell>::SetMethods(E, LuaSpell::SpellMethods);

Expand Down
159 changes: 159 additions & 0 deletions methods/TrinityCore/AuraEffectMethods.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* Copyright (C) 2010 - 2024 Eluna Lua Engine <https://elunaluaengine.github.io/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/

#ifndef AURAEFFECTMETHODS_H
#define AURAEFFECTMETHODS_H


namespace LuaAuraEffects
{
int GetBase(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetBase());
return 1;
}

int GetBaseAmount(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetBaseAmount());
return 1;
}

int GetAmplitude(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetAmplitude());
return 1;
}

int GetAmount(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetAmount());
return 1;
}

int SetAmount(Eluna* E, AuraEffect* aurEff)
{
int32 amount = E->CHECKVAL<int32>(2);
aurEff->SetAmount(amount);
return 0;
}

int GetPeriodicTimer(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetPeriodicTimer());
return 1;
}

int SetPeriodicTimer(Eluna* E, AuraEffect* aurEff)
{
int32 timer = E->CHECKVAL<int32>(2);
aurEff->SetPeriodicTimer(timer);
return 0;
}

int CalculateAmount(Eluna* E, AuraEffect* aurEff)
{
Unit* caster = E->CHECKOBJ<Unit>(2);
E->Push(aurEff->CalculateAmount(caster));
return 1;
}

int CalculatePeriodic(Eluna* E, AuraEffect* aurEff)
{
Unit* caster = E->CHECKOBJ<Unit>(2);
bool resetPeriodicTimer = E->CHECKVAL<bool>(3, false);
bool load = E->CHECKVAL<bool>(4, false);
aurEff->CalculatePeriodic(caster, resetPeriodicTimer, load);
return 0;
}

int ChangeAmount(Eluna* E, AuraEffect* aurEff)
{
int32 newAmount = E->CHECKVAL<int32>(2);
bool mark = E->CHECKVAL<bool>(3, true);
bool onStackOrReapply = E->CHECKVAL<bool>(4, false);
aurEff->ChangeAmount(newAmount, mark, onStackOrReapply);
return 0;
}

int RecalculateAmount(Eluna* /*E*/, AuraEffect* aurEff)
{
aurEff->RecalculateAmount();
return 0;
}

int CanBeRecalculated(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->CanBeRecalculated());
return 1;
}

int SetCanBeRecalculated(Eluna* E, AuraEffect* aurEff)
{
bool val = E->CHECKVAL<bool>(2, true);
aurEff->SetCanBeRecalculated(val);
return 0;
}

int GetTickNumber(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetTickNumber());
return 1;
}

int GetRemainingTicks(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetRemainingTicks());
return 1;
}

int GetTotalTicks(Eluna* E, AuraEffect* aurEff)
{
E->Push(aurEff->GetTotalTicks());
return 1;
}

int GetTargetList(Eluna* E, AuraEffect* aurEff)
{
std::list<Unit*> list;
aurEff->GetTargetList(list);
lua_createtable(E->L, list.size(), 0);
int tbl = lua_gettop(E->L);
uint32 i = 0;

for (std::list<Unit*>::const_iterator it = list.begin(); it != list.end(); ++it)
{
E->Push(*it);
lua_rawseti(E->L, tbl, ++i);
}

lua_settop(E->L, tbl);
return 1;
}

ElunaRegister<AuraEffect> AuraEffectMethods[] =
{
{"GetBase", &LuaAuraEffects::GetBase},
{"GetBaseAmount", &LuaAuraEffects::GetBaseAmount},
{"GetAmplitude", &LuaAuraEffects::GetAmplitude},
{"GetAmount", &LuaAuraEffects::GetAmount},
{"SetAmount", &LuaAuraEffects::SetAmount},
{"GetPeriodicTimer", &LuaAuraEffects::GetPeriodicTimer},
{"SetPeriodicTimer", &LuaAuraEffects::SetPeriodicTimer},
{"CalculateAmount", &LuaAuraEffects::CalculateAmount},
{"CalculatePeriodic", &LuaAuraEffects::CalculatePeriodic},
{"ChangeAmount", &LuaAuraEffects::ChangeAmount},
{"RecalculateAmount", &LuaAuraEffects::RecalculateAmount},
{"CanBeRecalculated", &LuaAuraEffects::CanBeRecalculated},
{"SetCanBeRecalculated", &LuaAuraEffects::SetCanBeRecalculated},
{"GetTickNumber", &LuaAuraEffects::GetTickNumber},
{"GetRemainingTicks", &LuaAuraEffects::GetRemainingTicks},
{"GetTotalTicks", &LuaAuraEffects::GetTotalTicks},
{"GetTargetList", &LuaAuraEffects::GetTargetList}
};
};
#endif

Loading