From 1d5c6d696eaa4456a5a646e2bc4ca3e68c29d928 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 24 Apr 2020 00:02:10 +0200 Subject: [PATCH] Improve OnInitialize performance in AngelScript by caching type of parameter array. --- .../AngelScript/AngelScripResolver.cpp | 2 +- .../AngelScript/AngelScripResolver.hpp | 10 + .../AngelScript/AngelScriptScript.cpp | 259 +++++++++++++++++ .../AngelScript/AngelScriptScript.hpp | 274 +++--------------- 4 files changed, 304 insertions(+), 241 deletions(-) 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> _typeDatabase; + Dictionary _baseTypes; void RegisterTypes(); void InitializeByteCode(asIBinaryStream* stream, @@ -55,5 +56,14 @@ public: const Dictionary>& 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& ls) { + asITypeInfo* t = _resolver->GetBaseType("array"_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& 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& 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& parameters) override; + void Stack() override; - static CScriptArray* - GetEffectParameters(asIScriptContext* ctx, - const Arbutils::Collections::List& ls) { - asIScriptEngine* engine = ctx->GetEngine(); - asITypeInfo* t = engine->GetTypeInfoByDecl("array"); - 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& 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