diff --git a/src/ScriptResolving/AngelScript/AngelScripResolver.cpp b/src/ScriptResolving/AngelScript/AngelScripResolver.cpp
index e4280fb..2e63a5f 100644
--- a/src/ScriptResolving/AngelScript/AngelScripResolver.cpp
+++ b/src/ScriptResolving/AngelScript/AngelScripResolver.cpp
@@ -139,7 +139,7 @@ CreatureLib::Battling::Script* AngelScripResolver::LoadScript(ScriptCategory cat
     auto ctx = _contextPool->RequestContext();
     auto obj = t->Instantiate(ctx);
     _contextPool->ReturnContextToPool(ctx);
-    return new AngelScriptScript(t, obj, _contextPool);
+    return new AngelScriptScript(this, t, obj, _contextPool);
 }
 void AngelScripResolver::FinalizeModule() {
     int r = _builder.BuildModule();
diff --git a/src/ScriptResolving/AngelScript/AngelScripResolver.hpp b/src/ScriptResolving/AngelScript/AngelScripResolver.hpp
index 9ac1fcf..858e773 100644
--- a/src/ScriptResolving/AngelScript/AngelScripResolver.hpp
+++ b/src/ScriptResolving/AngelScript/AngelScripResolver.hpp
@@ -22,6 +22,7 @@ private:
     static void MessageCallback(const asSMessageInfo* msg, void* param);
     static void Print(const std::string& str) { std::cout << str << std::endl; }
     Dictionary<ScriptCategory, Dictionary<ConstString, AngelScriptTypeInfo*>> _typeDatabase;
+    Dictionary<ConstString, asITypeInfo*> _baseTypes;
 
     void RegisterTypes();
     void InitializeByteCode(asIBinaryStream* stream,
@@ -55,5 +56,14 @@ public:
     const Dictionary<ScriptCategory, Dictionary<ConstString, AngelScriptTypeInfo*>>& GetTypeDatabase() const noexcept {
         return _typeDatabase;
     }
+
+    asITypeInfo* GetBaseType(const ConstString& name){
+        asITypeInfo* t = nullptr;
+        if (!_baseTypes.TryGet(name, t)){
+            t = this->_engine->GetTypeInfoByDecl(name.c_str());
+            _baseTypes.Insert(name, t);
+        }
+        return t;
+    }
 };
 #endif // PKMNLIB_ANGELSCRIPRESOLVER_HPP
diff --git a/src/ScriptResolving/AngelScript/AngelScriptScript.cpp b/src/ScriptResolving/AngelScript/AngelScriptScript.cpp
index 97d92e6..f80129b 100644
--- a/src/ScriptResolving/AngelScript/AngelScriptScript.cpp
+++ b/src/ScriptResolving/AngelScript/AngelScriptScript.cpp
@@ -1 +1,260 @@
 #include "AngelScriptScript.hpp"
+#include "AngelScripResolver.hpp"
+
+#define CALL_HOOK(name, setup)                                                                                         \
+    auto s = _type->Get##name();                                                                                       \
+    if (!s.Exists)                                                                                                     \
+        return;                                                                                                        \
+    auto ctx = asGetActiveContext();                                                                                   \
+    bool newContext = false;                                                                                           \
+    if (ctx == nullptr) {                                                                                              \
+        ctx = _ctxPool->RequestContext();                                                                              \
+        newContext = true;                                                                                             \
+    } else {                                                                                                           \
+        ctx->PushState();                                                                                              \
+    }                                                                                                                  \
+    ctx->Prepare(s.Function);                                                                                          \
+    ctx->SetObject(_obj);                                                                                              \
+    setup;                                                                                                             \
+    auto scriptResult = ctx->Execute();                                                                                \
+    if (scriptResult != asEXECUTION_FINISHED) {                                                                        \
+        if (scriptResult == asEXECUTION_EXCEPTION) {                                                                   \
+            std::stringstream err;                                                                                     \
+            err << "Script exception in script '" << GetName().c_str() << "', line " << ctx->GetExceptionLineNumber()  \
+                << ". Message: '" << ctx->GetExceptionString() << "'.";                                                \
+            if (newContext) {                                                                                          \
+                _ctxPool->ReturnContextToPool(ctx);                                                                    \
+            } else {                                                                                                   \
+                ctx->PopState();                                                                                       \
+            }                                                                                                          \
+            throw CreatureException(err.str());                                                                        \
+        }                                                                                                              \
+        if (newContext) {                                                                                              \
+            _ctxPool->ReturnContextToPool(ctx);                                                                        \
+        } else {                                                                                                       \
+            ctx->PopState();                                                                                           \
+        }                                                                                                              \
+        throw CreatureException("Script didn't finish properly; message " + std::to_string(scriptResult));             \
+    }                                                                                                                  \
+    if (newContext) {                                                                                                  \
+        _ctxPool->ReturnContextToPool(ctx);                                                                            \
+    } else {                                                                                                           \
+        ctx->PopState();                                                                                               \
+    }
+
+CScriptArray*
+AngelScriptScript::GetEffectParameters(const Arbutils::Collections::List<CreatureLib::Library::EffectParameter*>& ls) {
+    asITypeInfo* t = _resolver->GetBaseType("array<EffectParameter@>"_cnc);
+    CScriptArray* arr = CScriptArray::Create(t, ls.Count());
+    for (size_t i = 0; i < ls.Count(); i++) {
+        arr->SetValue(i, (void**)&ls[i]);
+    }
+    return arr;
+}
+
+void AngelScriptScript::OnInitialize(const List<CreatureLib::Library::EffectParameter*>& parameters) {
+    CScriptArray* arr = nullptr;
+    CALL_HOOK(OnInitialize, {
+        arr = GetEffectParameters(parameters);
+        ctx->SetArgAddress(0, arr);
+    })
+    if (arr != nullptr) {
+        arr->Release();
+    }
+}
+void AngelScriptScript::Stack() { CALL_HOOK(Stack, ); }
+void AngelScriptScript::OnRemove() { CALL_HOOK(OnRemove, ); }
+void AngelScriptScript::OnBeforeTurn(const CreatureLib::Battling::BaseTurnChoice* choice) {
+    CALL_HOOK(OnBeforeTurn, { ctx->SetArgObject(0, (void*)choice); })
+}
+void AngelScriptScript::ChangeAttack(CreatureLib::Battling::AttackTurnChoice* choice, ConstString* outAttack) {
+    CALL_HOOK(ChangeAttack, {
+        ctx->SetArgObject(0, (void*)choice);
+        ctx->SetArgAddress(0, outAttack);
+    })
+}
+void AngelScriptScript::PreventAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outResult) {
+    CALL_HOOK(PreventAttack, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgAddress(1, outResult);
+    })
+}
+void AngelScriptScript::FailAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outFailed) {
+    CALL_HOOK(FailAttack, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgAddress(1, outFailed);
+    })
+}
+void AngelScriptScript::StopBeforeAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outResult) {
+    CALL_HOOK(StopBeforeAttack, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgAddress(1, outResult);
+    })
+}
+void AngelScriptScript::OnBeforeAttack(CreatureLib::Battling::ExecutingAttack* attack) {
+    CALL_HOOK(OnBeforeAttack, { ctx->SetArgObject(0, (void*)attack); })
+}
+void AngelScriptScript::FailIncomingAttack(CreatureLib::Battling::ExecutingAttack* attack,
+                                           CreatureLib::Battling::Creature* target, bool* outResult) {
+    CALL_HOOK(FailIncomingAttack, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgAddress(2, outResult);
+    })
+}
+void AngelScriptScript::IsInvulnerable(CreatureLib::Battling::ExecutingAttack* attack,
+                                       CreatureLib::Battling::Creature* target, bool* outResult) {
+    CALL_HOOK(IsInvulnerable, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgAddress(2, outResult);
+    })
+}
+void AngelScriptScript::OnAttackMiss(CreatureLib::Battling::ExecutingAttack* attack,
+                                     CreatureLib::Battling::Creature* target) {
+    CALL_HOOK(OnAttackMiss, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+    })
+}
+void AngelScriptScript::ChangeAttackType(CreatureLib::Battling::ExecutingAttack* attack,
+                                         CreatureLib::Battling::Creature* target, uint8_t hitNumber, uint8_t* outType) {
+    CALL_HOOK(ChangeAttackType, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitNumber);
+        ctx->SetArgAddress(3, outType);
+    })
+}
+void AngelScriptScript::ChangeEffectiveness(CreatureLib::Battling::ExecutingAttack* attack,
+                                            CreatureLib::Battling::Creature* target, uint8_t hitNumber,
+                                            float* effectiveness) {
+    CALL_HOOK(ChangeEffectiveness, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitNumber);
+        ctx->SetArgAddress(3, effectiveness);
+    })
+}
+void AngelScriptScript::PreventSecondaryEffects(const CreatureLib::Battling::ExecutingAttack* attack,
+                                                CreatureLib::Battling::Creature* target, uint8_t hitNumber,
+                                                bool* outResult) {
+    CALL_HOOK(PreventSecondaryEffects, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitNumber);
+        ctx->SetArgAddress(3, outResult);
+    })
+}
+void AngelScriptScript::OnSecondaryEffect(const CreatureLib::Battling::ExecutingAttack* attack,
+                                          CreatureLib::Battling::Creature* target, uint8_t hitNumber) {
+    CALL_HOOK(OnSecondaryEffect, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitNumber);
+    })
+}
+void AngelScriptScript::OnAfterHits(const CreatureLib::Battling::ExecutingAttack* attack,
+                                    CreatureLib::Battling::Creature* target) {
+    CALL_HOOK(OnAfterHits, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+    })
+}
+void AngelScriptScript::PreventSelfSwitch(const CreatureLib::Battling::SwitchTurnChoice* choice, bool* outResult) {
+    CALL_HOOK(PreventSelfSwitch, {
+        ctx->SetArgObject(0, (void*)choice);
+        ctx->SetArgAddress(1, outResult);
+    })
+}
+void AngelScriptScript::ModifyEffectChance(const CreatureLib::Battling::ExecutingAttack* attack,
+                                           CreatureLib::Battling::Creature* target, float* chance) {
+    CALL_HOOK(ModifyEffectChance, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgAddress(2, chance);
+    })
+}
+void AngelScriptScript::ModifyIncomingEffectChance(const CreatureLib::Battling::ExecutingAttack* attack,
+                                                   CreatureLib::Battling::Creature* target, float* chance) {
+    CALL_HOOK(ModifyIncomingEffectChance, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgAddress(2, chance);
+    })
+}
+void AngelScriptScript::OverrideBasePower(CreatureLib::Battling::ExecutingAttack* attack,
+                                          CreatureLib::Battling::Creature* target, uint8_t hitIndex,
+                                          uint8_t* basePower) {
+    CALL_HOOK(OverrideBasePower, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, basePower);
+    })
+}
+void AngelScriptScript::ChangeDamageStatsUser(CreatureLib::Battling::ExecutingAttack* attack,
+                                              CreatureLib::Battling::Creature* target, uint8_t hitIndex,
+                                              CreatureLib::Battling::Creature** statsUser) {
+    CALL_HOOK(ChangeDamageStatsUser, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, statsUser);
+    })
+}
+void AngelScriptScript::BypassDefensiveStat(CreatureLib::Battling::ExecutingAttack* attack,
+                                            CreatureLib::Battling::Creature* target, uint8_t hitIndex, bool* bypass) {
+    CALL_HOOK(BypassDefensiveStat, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, bypass);
+    })
+}
+void AngelScriptScript::BypassOffensiveStat(CreatureLib::Battling::ExecutingAttack* attack,
+                                            CreatureLib::Battling::Creature* target, uint8_t hitIndex, bool* bypass) {
+    CALL_HOOK(BypassOffensiveStat, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, bypass);
+    })
+}
+void AngelScriptScript::ModifyStatModifier(CreatureLib::Battling::ExecutingAttack* attack,
+                                           CreatureLib::Battling::Creature* target, uint8_t hitIndex, float* modifier) {
+    CALL_HOOK(ModifyStatModifier, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, modifier);
+    })
+}
+void AngelScriptScript::ModifyDamageModifier(CreatureLib::Battling::ExecutingAttack* attack,
+                                             CreatureLib::Battling::Creature* target, uint8_t hitIndex,
+                                             float* modifier) {
+    CALL_HOOK(ModifyDamageModifier, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, modifier);
+    })
+}
+void AngelScriptScript::OverrideDamage(CreatureLib::Battling::ExecutingAttack* attack,
+                                       CreatureLib::Battling::Creature* target, uint8_t hitIndex, uint32_t* damage) {
+    CALL_HOOK(OverrideDamage, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hitIndex);
+        ctx->SetArgAddress(3, damage);
+    })
+}
+void AngelScriptScript::ModifyCriticalStage(CreatureLib::Battling::ExecutingAttack* attack,
+                                            CreatureLib::Battling::Creature* target, uint8_t hit, uint8_t* critStage) {
+    CALL_HOOK(ModifyCriticalStage, {
+        ctx->SetArgObject(0, (void*)attack);
+        ctx->SetArgObject(1, (void*)target);
+        ctx->SetArgByte(2, hit);
+        ctx->SetArgAddress(3, critStage);
+    })
+}
diff --git a/src/ScriptResolving/AngelScript/AngelScriptScript.hpp b/src/ScriptResolving/AngelScript/AngelScriptScript.hpp
index 7c90646..82a9265 100644
--- a/src/ScriptResolving/AngelScript/AngelScriptScript.hpp
+++ b/src/ScriptResolving/AngelScript/AngelScriptScript.hpp
@@ -10,16 +10,19 @@
 #include "AngelScriptTypeInfo.hpp"
 #include "ContextPool.hpp"
 
+class AngelScripResolver;
 class AngelScriptScript : public PkmnLib::Battling::PkmnScript {
 private:
+    AngelScripResolver* _resolver = nullptr;
     AngelScriptTypeInfo* _type = nullptr;
     ContextPool* _ctxPool = nullptr;
 
     asIScriptObject* _obj = nullptr;
-
+    CScriptArray* GetEffectParameters(const List<CreatureLib::Library::EffectParameter*>& ls);
 public:
-    AngelScriptScript(AngelScriptTypeInfo* type, asIScriptObject* obj, ContextPool* ctxPool)
-        : _type(type), _ctxPool(ctxPool), _obj(obj) {}
+    AngelScriptScript(AngelScripResolver* resolver, AngelScriptTypeInfo* type, asIScriptObject* obj,
+                      ContextPool* ctxPool)
+        : _resolver(resolver), _type(type), _ctxPool(ctxPool), _obj(obj) {}
 
     ~AngelScriptScript() override { _obj->Release(); }
 
@@ -34,281 +37,72 @@ public:
 
     ContextPool* GetContextPool() { return _ctxPool; }
 
-#define CALL_HOOK(name, setup)                                                                                         \
-    auto s = _type->Get##name();                                                                                       \
-    if (!s.Exists)                                                                                                     \
-        return;                                                                                                        \
-    auto ctx = asGetActiveContext();                                                                                   \
-    bool newContext = false;                                                                                           \
-    if (ctx == nullptr) {                                                                                              \
-        ctx = _ctxPool->RequestContext();                                                                              \
-        newContext = true;                                                                                             \
-    } else {                                                                                                           \
-        ctx->PushState();                                                                                              \
-    }                                                                                                                  \
-    ctx->Prepare(s.Function);                                                                                          \
-    ctx->SetObject(_obj);                                                                                              \
-    setup;                                                                                                             \
-    auto scriptResult = ctx->Execute();                                                                                \
-    if (scriptResult != asEXECUTION_FINISHED) {                                                                        \
-        if (scriptResult == asEXECUTION_EXCEPTION) {                                                                   \
-            std::stringstream err;                                                                                     \
-            err << "Script exception in script '" << GetName().c_str() << "', line " << ctx->GetExceptionLineNumber()  \
-                << ". Message: '" << ctx->GetExceptionString() << "'.";                                                \
-            if (newContext) {                                                                                          \
-                _ctxPool->ReturnContextToPool(ctx);                                                                    \
-            } else {                                                                                                   \
-                ctx->PopState();                                                                                       \
-            }                                                                                                          \
-            throw CreatureException(err.str());                                                                        \
-        }                                                                                                              \
-        if (newContext) {                                                                                              \
-            _ctxPool->ReturnContextToPool(ctx);                                                                        \
-        } else {                                                                                                       \
-            ctx->PopState();                                                                                           \
-        }                                                                                                              \
-        throw CreatureException("Script didn't finish properly; message " + std::to_string(scriptResult));             \
-    }                                                                                                                  \
-    if (newContext) {                                                                                                  \
-        _ctxPool->ReturnContextToPool(ctx);                                                                            \
-    } else {                                                                                                           \
-        ctx->PopState();                                                                                               \
-    }
+    void OnInitialize(const Arbutils::Collections::List<CreatureLib::Library::EffectParameter*>& parameters) override;
+    void Stack() override;
 
-    static CScriptArray*
-    GetEffectParameters(asIScriptContext* ctx,
-                        const Arbutils::Collections::List<CreatureLib::Library::EffectParameter*>& ls) {
-        asIScriptEngine* engine = ctx->GetEngine();
-        asITypeInfo* t = engine->GetTypeInfoByDecl("array<EffectParameter@>");
-        CScriptArray* arr = CScriptArray::Create(t, ls.Count());
-        for (size_t i = 0; i < ls.Count(); i++) {
-            arr->SetValue(i, (void**)&ls[i]);
-        }
-        return arr;
-    }
+    void OnRemove() override;
 
-    void OnInitialize(const Arbutils::Collections::List<CreatureLib::Library::EffectParameter*>& parameters) override {
-        CScriptArray* arr = nullptr;
-        CALL_HOOK(OnInitialize, {
-            arr = GetEffectParameters(ctx, parameters);
-            ctx->SetArgAddress(0, arr);
-        })
-        if (arr != nullptr) {
-            arr->Release();
-        }
-    }
-    void Stack() override { CALL_HOOK(Stack, ); }
+    void OnBeforeTurn(const CreatureLib::Battling::BaseTurnChoice* choice) override;
 
-    void OnRemove() override { CALL_HOOK(OnRemove, ); }
+    void ChangeAttack(CreatureLib::Battling::AttackTurnChoice* choice, ConstString* outAttack) override;
 
-    void OnBeforeTurn(const CreatureLib::Battling::BaseTurnChoice* choice) override {
-        CALL_HOOK(OnBeforeTurn, { ctx->SetArgObject(0, (void*)choice); })
-    }
+    void PreventAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outResult) override;
 
-    void ChangeAttack(CreatureLib::Battling::AttackTurnChoice* choice, ConstString* outAttack) override {
-        CALL_HOOK(ChangeAttack, {
-            ctx->SetArgObject(0, (void*)choice);
-            ctx->SetArgAddress(0, outAttack);
-        })
-    }
+    void FailAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outFailed) override;
 
-    void PreventAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outResult) override {
-        CALL_HOOK(PreventAttack, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgAddress(1, outResult);
-        })
-    }
+    void StopBeforeAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outResult) override;
 
-    void FailAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outFailed) override {
-        CALL_HOOK(FailAttack, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgAddress(1, outFailed);
-        })
-    }
-
-    void StopBeforeAttack(CreatureLib::Battling::ExecutingAttack* attack, bool* outResult) override {
-        CALL_HOOK(StopBeforeAttack, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgAddress(1, outResult);
-        })
-    }
-
-    void OnBeforeAttack(CreatureLib::Battling::ExecutingAttack* attack) override {
-        CALL_HOOK(OnBeforeAttack, { ctx->SetArgObject(0, (void*)attack); })
-    }
+    void OnBeforeAttack(CreatureLib::Battling::ExecutingAttack* attack) override;
 
     void FailIncomingAttack(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                            bool* outResult) override {
-        CALL_HOOK(FailIncomingAttack, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgAddress(2, outResult);
-        })
-    }
+                            bool* outResult) override;
     void IsInvulnerable(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                        bool* outResult) override {
-        CALL_HOOK(IsInvulnerable, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgAddress(2, outResult);
-        })
-    }
-    void OnAttackMiss(CreatureLib::Battling::ExecutingAttack* attack,
-                      CreatureLib::Battling::Creature* target) override {
-        CALL_HOOK(OnAttackMiss, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-        })
-    }
+                        bool* outResult) override;
+    void OnAttackMiss(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target) override;
 
     void ChangeAttackType(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                          uint8_t hitNumber, uint8_t* outType) override {
-        CALL_HOOK(ChangeAttackType, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitNumber);
-            ctx->SetArgAddress(3, outType);
-        })
-    }
+                          uint8_t hitNumber, uint8_t* outType) override;
 
     void ChangeEffectiveness(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                             uint8_t hitNumber, float* effectiveness) override {
-        CALL_HOOK(ChangeEffectiveness, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitNumber);
-            ctx->SetArgAddress(3, effectiveness);
-        })
-    }
+                             uint8_t hitNumber, float* effectiveness) override;
 
     void PreventSecondaryEffects(const CreatureLib::Battling::ExecutingAttack* attack,
-                                 CreatureLib::Battling::Creature* target, uint8_t hitNumber, bool* outResult) override {
-        CALL_HOOK(PreventSecondaryEffects, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitNumber);
-            ctx->SetArgAddress(3, outResult);
-        })
-    }
+                                 CreatureLib::Battling::Creature* target, uint8_t hitNumber, bool* outResult) override;
 
     void OnSecondaryEffect(const CreatureLib::Battling::ExecutingAttack* attack,
-                           CreatureLib::Battling::Creature* target, uint8_t hitNumber) override {
-        CALL_HOOK(OnSecondaryEffect, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitNumber);
-        })
-    }
+                           CreatureLib::Battling::Creature* target, uint8_t hitNumber) override;
 
     void OnAfterHits(const CreatureLib::Battling::ExecutingAttack* attack,
-                     CreatureLib::Battling::Creature* target) override {
-        CALL_HOOK(OnAfterHits, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-        })
-    }
+                     CreatureLib::Battling::Creature* target) override;
 
-    void PreventSelfSwitch(const CreatureLib::Battling::SwitchTurnChoice* choice, bool* outResult) override {
-        CALL_HOOK(PreventSelfSwitch, {
-            ctx->SetArgObject(0, (void*)choice);
-            ctx->SetArgAddress(1, outResult);
-        })
-    }
+    void PreventSelfSwitch(const CreatureLib::Battling::SwitchTurnChoice* choice, bool* outResult) override;
 
     void ModifyEffectChance(const CreatureLib::Battling::ExecutingAttack* attack,
-                            CreatureLib::Battling::Creature* target, float* chance) override {
-        CALL_HOOK(ModifyEffectChance, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgAddress(2, chance);
-        })
-    }
+                            CreatureLib::Battling::Creature* target, float* chance) override;
     void ModifyIncomingEffectChance(const CreatureLib::Battling::ExecutingAttack* attack,
-                                    CreatureLib::Battling::Creature* target, float* chance) override {
-        CALL_HOOK(ModifyIncomingEffectChance, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgAddress(2, chance);
-        })
-    }
+                                    CreatureLib::Battling::Creature* target, float* chance) override;
 
     void OverrideBasePower(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                           uint8_t hitIndex, uint8_t* basePower) override {
-        CALL_HOOK(OverrideBasePower, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, basePower);
-        })
-    }
+                           uint8_t hitIndex, uint8_t* basePower) override;
     void ChangeDamageStatsUser(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                               uint8_t hitIndex, CreatureLib::Battling::Creature** statsUser) override {
-        CALL_HOOK(ChangeDamageStatsUser, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, statsUser);
-        })
-    }
+                               uint8_t hitIndex, CreatureLib::Battling::Creature** statsUser) override;
     void BypassDefensiveStat(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                             uint8_t hitIndex, bool* bypass) override {
-        CALL_HOOK(BypassDefensiveStat, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, bypass);
-        })
-    }
+                             uint8_t hitIndex, bool* bypass) override;
     void BypassOffensiveStat(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                             uint8_t hitIndex, bool* bypass) override {
-        CALL_HOOK(BypassOffensiveStat, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, bypass);
-        })
-    }
+                             uint8_t hitIndex, bool* bypass) override;
     void ModifyStatModifier(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                            uint8_t hitIndex, float* modifier) override {
-        CALL_HOOK(ModifyStatModifier, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, modifier);
-        })
-    }
+                            uint8_t hitIndex, float* modifier) override;
     void ModifyDamageModifier(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                              uint8_t hitIndex, float* modifier) override {
-        CALL_HOOK(ModifyDamageModifier, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, modifier);
-        })
-    }
+                              uint8_t hitIndex, float* modifier) override;
     void OverrideDamage(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                        uint8_t hitIndex, uint32_t* damage) override {
-        CALL_HOOK(OverrideDamage, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hitIndex);
-            ctx->SetArgAddress(3, damage);
-        })
-    }
+                        uint8_t hitIndex, uint32_t* damage) override;
 
     ////////////////////
     // PkmnLib methods//
     ////////////////////
 
     void ModifyCriticalStage(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
-                             uint8_t hit, uint8_t* critStage) override {
-        CALL_HOOK(ModifyCriticalStage, {
-            ctx->SetArgObject(0, (void*)attack);
-            ctx->SetArgObject(1, (void*)target);
-            ctx->SetArgByte(2, hit);
-            ctx->SetArgAddress(3, critStage);
-        })
-    }
+                             uint8_t hit, uint8_t* critStage) override;
 };
 
 #undef CALL_HOOK