PkmnLib/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp

200 lines
10 KiB
C++

#ifndef PKMNLIB_ANGELSCRIPTTYPEINFO_HPP
#define PKMNLIB_ANGELSCRIPTTYPEINFO_HPP
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
#include <Arbutils/Collections/Dictionary.hpp>
#include <CreatureLib/Library/Exceptions/CreatureException.hpp>
#include <angelscript.h>
class AngelScriptTypeInfo {
private:
asITypeInfo* _type = nullptr;
ArbUt::Dictionary<uint32_t, asIScriptFunction*> _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<EffectParameter@>@ 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