#ifndef PKMNLIB_ANGELSCRIPTTYPEINFO_HPP #define PKMNLIB_ANGELSCRIPTTYPEINFO_HPP #define ANGELSCRIPT_DLL_LIBRARY_IMPORT #include #include #include class AngelScriptTypeInfo { private: asITypeInfo* _type = nullptr; ArbUt::Dictionary _functions; ArbUt::StringView _name; struct FunctionInfo { bool Exists = false; asIScriptFunction* Function = nullptr; }; FunctionInfo Initialize(const std::string& decl) { auto val = _type->GetMethodByDecl(decl.c_str(), false); if (val == nullptr) { return FunctionInfo{.Exists = false, .Function = nullptr}; } return FunctionInfo{.Exists = true, .Function = val}; } public: explicit AngelScriptTypeInfo(const ArbUt::StringView& name, asITypeInfo* type) : _type(type), _name(name) {} ~AngelScriptTypeInfo() { for (const auto& f : _functions) { f.second->Release(); } _functions.Clear(); } const ArbUt::StringView& GetName() const noexcept { return _name; } inline asITypeInfo* GetType() const { return _type; } inline const char* GetDecl() { return _type->GetName(); } asIScriptFunction* GetFunction(const ArbUt::BasicStringView& functionName) { auto v = _functions.TryGet(functionName); if (v.has_value()) { return v.value(); } auto func = _type->GetMethodByName(functionName.c_str()); if (func != nullptr) { func->AddRef(); } _functions.Insert(functionName, func); return func; } asIScriptObject* Instantiate(asIScriptContext* ctx) { auto* factory = _type->GetFactoryByIndex(0); ctx->Prepare(factory); auto result = ctx->Execute(); if (result != asEXECUTION_FINISHED) { throw ArbUt::Exception("Instantiation failed."); } asIScriptObject* obj = *(asIScriptObject**)ctx->GetAddressOfReturnValue(); obj->AddRef(); return obj; } #define SCRIPT_HOOK_FUNCTION(name, decl) \ private: \ FunctionInfo __##name = Initialize(decl); \ \ public: \ const FunctionInfo& Get##name() const { return __##name; } private: FunctionInfo InitializeGetOwner() { auto t = _type; while (t != nullptr) { auto val = t->GetMethodByDecl("ref@& GetOwner()", true); if (val != nullptr) { return FunctionInfo{.Exists = true, .Function = val}; } t = t->GetBaseType(); } return FunctionInfo{.Exists = false, .Function = nullptr}; } FunctionInfo __GetOwner = InitializeGetOwner(); public: const FunctionInfo& GetGetOwner() const { return __GetOwner; } SCRIPT_HOOK_FUNCTION(OnInitialize, "void OnInitialize(const BattleLibrary@ library, const narray@ parameters)"); SCRIPT_HOOK_FUNCTION(Stack, "void Stack()"); SCRIPT_HOOK_FUNCTION(OnRemove, "void OnRemove()"); SCRIPT_HOOK_FUNCTION(OnBeforeTurn, "void OnBeforeTurn(BaseTurnChoice@ choice)"); SCRIPT_HOOK_FUNCTION(ChangeAttack, "void ChangeAttack(MoveTurnChoice@ choice, constString& changedMove)"); SCRIPT_HOOK_FUNCTION(ModifyNumberOfHits, "void ModifyNumberOfHits(MoveTurnChoice@ choice, uint8& result)"); SCRIPT_HOOK_FUNCTION(PreventAttack, "void PreventAttack(ExecutingMove@ attack, bool& result)"); SCRIPT_HOOK_FUNCTION(FailAttack, "void FailAttack(ExecutingMove@ attack, bool& result)"); SCRIPT_HOOK_FUNCTION(StopBeforeAttack, "void StopBeforeAttack(ExecutingMove@ attack, bool& result)"); SCRIPT_HOOK_FUNCTION(OnBeforeAttack, "void OnBeforeAttack(ExecutingMove@ attack)"); SCRIPT_HOOK_FUNCTION(FailIncomingAttack, "void FailIncomingAttack(ExecutingMove@ attack, Pokemon@ target, bool& result)"); SCRIPT_HOOK_FUNCTION(IsInvulnerable, "void IsInvulnerable(ExecutingMove@ attack, Pokemon@ target, bool& result)"); SCRIPT_HOOK_FUNCTION(OnAttackMiss, "void OnAttackMiss(ExecutingMove@ attack, Pokemon@ target)"); SCRIPT_HOOK_FUNCTION(ChangeAttackType, "void ChangeAttackType(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& outType)"); SCRIPT_HOOK_FUNCTION( ChangeEffectiveness, "void ChangeEffectiveness(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& effectiveness)"); SCRIPT_HOOK_FUNCTION(BlockCritical, "void BlockCritical(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& blockCritical)"); SCRIPT_HOOK_FUNCTION(PreventStatBoostChange, "void PreventStatBoostChange(Pokemon@ target, Statistic stat, int8 amount, bool& prevent)"); SCRIPT_HOOK_FUNCTION(ModifyStatBoostChange, "void ModifyStatBoostChange(Pokemon@ target, Statistic stat, int8& amount)"); SCRIPT_HOOK_FUNCTION( PreventSecondaryEffects, "void PreventSecondaryEffects(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& outResult)"); SCRIPT_HOOK_FUNCTION(OnIncomingHit, "void OnIncomingHit(ExecutingMove@ attack, Pokemon@ target, uint8 hit)"); SCRIPT_HOOK_FUNCTION(OnFaintingOpponent, "void OnFaintingOpponent(ExecutingMove@ attack, Pokemon@ target, uint8 hit)"); SCRIPT_HOOK_FUNCTION(OnSecondaryEffect, "void OnSecondaryEffect(ExecutingMove@ attack, Pokemon@ target, uint8 hit)"); SCRIPT_HOOK_FUNCTION(OnAfterHits, "void OnAfterHits(ExecutingMove@ attack, Pokemon@ target)"); SCRIPT_HOOK_FUNCTION(PreventSelfSwitch, "void PreventSelfSwitch(SwitchTurnChoice@ choice, bool& prevented)"); SCRIPT_HOOK_FUNCTION(ModifyEffectChance, "void ModifyEffectChance(ExecutingMove@ attack, Pokemon@ target, float& chance)"); SCRIPT_HOOK_FUNCTION(ModifyIncomingEffectChance, "void ModifyIncomingEffectChance(ExecutingMove@ attack, Pokemon@ target, float& chance)"); SCRIPT_HOOK_FUNCTION(OverrideBasePower, "void OverrideBasePower(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& chance)"); SCRIPT_HOOK_FUNCTION( ChangeDamageStatsUser, "void ChangeDamageStatsUser(ExecutingMove@ attack, Pokemon@ target, uint8 hit, Pokemon@& user)"); SCRIPT_HOOK_FUNCTION(BypassDefensiveStat, "void BypassDefensiveStat(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& bypass)"); SCRIPT_HOOK_FUNCTION(BypassOffensiveStat, "void BypassOffensiveStat(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& bypass)"); SCRIPT_HOOK_FUNCTION(ModifyStatModifier, "void ModifyStatModifier(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& modifier)"); SCRIPT_HOOK_FUNCTION( ModifyDamageModifier, "void ModifyDamageModifier(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& modifier)"); SCRIPT_HOOK_FUNCTION(OverrideDamage, "void OverrideDamage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, int& damage)"); SCRIPT_HOOK_FUNCTION(OverrideIncomingDamage, "void OverrideIncomingDamage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, int& damage)"); SCRIPT_HOOK_FUNCTION( PreventIncomingCritical, "void PreventIncomingCritical(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& preventCrit)"); SCRIPT_HOOK_FUNCTION( ModifyCriticalStage, "void ModifyCriticalStage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& critStage)"); SCRIPT_HOOK_FUNCTION( OverrideCriticalModifier, "void OverrideCriticalModifier(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& critModifier)"); SCRIPT_HOOK_FUNCTION( OverrideSTABModifier, "void OverrideSTABModifier(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& stabModifier)"); SCRIPT_HOOK_FUNCTION(ModifyExperienceGain, "void ModifyExperienceGain(Pokemon@ faintedMon, Pokemon@ winningMon, uint32& critStage)"); SCRIPT_HOOK_FUNCTION(DoesShareExperience, "void DoesShareExperience(Pokemon@ faintedMon, Pokemon@ winningMon, bool& shareExperience)"); SCRIPT_HOOK_FUNCTION(ChangePriority, "void ChangePriority(MoveTurnChoice@ choice, int8& priority)"); SCRIPT_HOOK_FUNCTION(OnFail, "void OnFail(Pokemon@ user)"); SCRIPT_HOOK_FUNCTION(OnOpponentFail, "void OnOpponentFail(Pokemon@ user)"); SCRIPT_HOOK_FUNCTION(PreventRunAway, "void PreventRunAway(FleeTurnChoice@ choice, bool& result)"); SCRIPT_HOOK_FUNCTION(PreventOpponentRunAway, "void PreventOpponentRunAway(FleeTurnChoice@ choice, bool& result)"); SCRIPT_HOOK_FUNCTION(PreventOpponentSwitch, "void PreventOpponentSwitch(SwitchTurnChoice@ choice, bool& result)"); SCRIPT_HOOK_FUNCTION(OnEndTurn, "void OnEndTurn()"); SCRIPT_HOOK_FUNCTION(OnDamage, "void OnDamage(Pokemon@ pokemon, DamageSource damageSource, uint oldHealth, uint newHealth)"); SCRIPT_HOOK_FUNCTION(OnFaint, "void OnFaint(Pokemon@ pokemon, DamageSource damageSource)"); SCRIPT_HOOK_FUNCTION(BlockWeather, "void BlockWeather(Battle@ battle, bool& result)"); SCRIPT_HOOK_FUNCTION(OnSwitchIn, "void OnSwitchIn(Pokemon@ pokemon)"); SCRIPT_HOOK_FUNCTION( ModifyOffensiveStatValue, "void ModifyOffensiveStatValue(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& offensiveStatValue)"); SCRIPT_HOOK_FUNCTION( ModifyDefensiveStatValue, "void ModifyDefensiveStatValue(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& defensiveStatValue)"); SCRIPT_HOOK_FUNCTION( OnAfterHeldItemConsume, "void OnAfterHeldItemConsume(Pokemon@ target, const Item@ item)"); }; #undef SCRIPT_HOOK_FUNCTION #endif // PKMNLIB_ANGELSCRIPTTYPEINFO_HPP