diff --git a/CInterface/AngelScript/AngelScriptResolver.cpp b/CInterface/AngelScript/AngelScriptResolver.cpp index 11bc88a..f38cafa 100644 --- a/CInterface/AngelScript/AngelScriptResolver.cpp +++ b/CInterface/AngelScript/AngelScriptResolver.cpp @@ -17,6 +17,13 @@ export uint8_t PkmnLib_AngelScriptResolver_LoadScript(CreatureLib::Battling::Bat ScriptCategory category, const char* scriptName) { Try(out = p->LoadScript(category, ArbUt::StringView(scriptName));) } +export uint8_t PkmnLib_AngelScriptResolver_LoadEvolutionScript(PkmnLib::Battling::EvolutionScript const*& out, + AngelScriptResolver* p, const char* scriptName) { + Try( + auto s = p->LoadEvolutionScript(ArbUt::StringView(scriptName)); + if (!s.HasValue()) { out = nullptr; } else { out = s.GetValue(); }) +} + export uint8_t PkmnLib_AngelScriptResolver_WriteByteCodeToFile(AngelScriptResolver* p, const char* file, bool stripDebugInfo) { Try(p->WriteByteCodeToFile(file, stripDebugInfo);) diff --git a/src/Battling/EvolutionScript.hpp b/src/Battling/EvolutionScript.hpp new file mode 100644 index 0000000..5be6705 --- /dev/null +++ b/src/Battling/EvolutionScript.hpp @@ -0,0 +1,13 @@ +#ifndef PKMNLIB_EVOLUTIONSCRIPT_HPP +#define PKMNLIB_EVOLUTIONSCRIPT_HPP + +namespace PkmnLib::Battling { + class EvolutionScript { + public: + virtual void DoesEvolveFromLevelUp(const ArbUt::BorrowedPtr& evolution, + const ArbUt::BorrowedPtr& pokemon, + bool* out) const = 0; + }; +} + +#endif // PKMNLIB_EVOLUTIONSCRIPT_HPP diff --git a/src/Battling/Library/MiscLibrary.cpp b/src/Battling/Library/MiscLibrary.cpp index a54131b..b26883d 100644 --- a/src/Battling/Library/MiscLibrary.cpp +++ b/src/Battling/Library/MiscLibrary.cpp @@ -66,7 +66,16 @@ bool PkmnLib::Battling::MiscLibrary::CanEvolveFromLevelUp( return pokemon->GetLevel() >= evolution->GetData(1)->AsInt() && pokemon->GetGender() == (CreatureLib::Library::Gender)evolution->GetData(0)->AsInt(); case Library::EvolutionMethod::Custom: - // TODO + { + auto script = dynamic_cast(pokemon->GetLibrary()->GetScriptResolver().get()) + ->LoadEvolutionScript(evolution->GetData(0)->AsString()); + if (!script.HasValue()) { + return false; + } + auto v = false; + script.GetValue()->DoesEvolveFromLevelUp(evolution, pokemon, &v); + return v; + } case Library::EvolutionMethod::EvolutionItemUse: case Library::EvolutionMethod::EvolutionItemUseWithGender: case Library::EvolutionMethod::Trade: diff --git a/src/Battling/Library/ScriptResolver.hpp b/src/Battling/Library/ScriptResolver.hpp index 22661c3..9a966dd 100644 --- a/src/Battling/Library/ScriptResolver.hpp +++ b/src/Battling/Library/ScriptResolver.hpp @@ -1,9 +1,14 @@ #ifndef PKMNLIB_SCRIPTRESOLVER_HPP #define PKMNLIB_SCRIPTRESOLVER_HPP +#include "../EvolutionScript.hpp" + namespace PkmnLib::Battling { class ScriptResolver : public CreatureLib::Battling::ScriptResolver { public: + virtual ArbUt::OptionalBorrowedPtr LoadEvolutionScript(const ArbUt::StringView&) { + return nullptr; + }; }; } diff --git a/src/Library/Moves/MoveCategory.hpp b/src/Library/Moves/MoveCategory.hpp index 0cb992a..1bb0093 100644 --- a/src/Library/Moves/MoveCategory.hpp +++ b/src/Library/Moves/MoveCategory.hpp @@ -2,7 +2,7 @@ #define PKMNLIB_MOVECATEGORY_HPP namespace PkmnLib::Library { - enum class MoveCategory : uint8_t { Physical, Special, Status }; + ENUM(MoveCategory, u8, Physical, Special, Status) } #endif // PKMNLIB_MOVECATEGORY_HPP diff --git a/src/ScriptResolving/AngelScript/AngelScriptEvolutionScript.cpp b/src/ScriptResolving/AngelScript/AngelScriptEvolutionScript.cpp new file mode 100644 index 0000000..24ac765 --- /dev/null +++ b/src/ScriptResolving/AngelScript/AngelScriptEvolutionScript.cpp @@ -0,0 +1,18 @@ +#include "AngelScriptEvolutionScript.hpp" +#include "AngelScriptResolver.hpp" + +void AngelScriptEvolutionScript::DoesEvolveFromLevelUp( + const ArbUt::BorrowedPtr& evolution, + const ArbUt::BorrowedPtr& pokemon, bool* out) const { + if (!__DoesEvolveFromLevelUp.Exists) { + return; + } + AngelScriptUtils::AngelscriptFunctionCall( + __DoesEvolveFromLevelUp.Function, _resolver->GetContextPool(), _scriptObject, ""_cnc, + [&]([[maybe_unused]] asIScriptContext* ctx) { + ctx->SetArgObject(0, (void*)evolution.GetRaw()); + ctx->SetArgObject(1, (void*)pokemon.GetRaw()); + ctx->SetArgObject(2, out); + }, + [&]([[maybe_unused]] asIScriptContext* ctx) {}); +} diff --git a/src/ScriptResolving/AngelScript/AngelScriptEvolutionScript.hpp b/src/ScriptResolving/AngelScript/AngelScriptEvolutionScript.hpp new file mode 100644 index 0000000..70e4aa2 --- /dev/null +++ b/src/ScriptResolving/AngelScript/AngelScriptEvolutionScript.hpp @@ -0,0 +1,47 @@ +#ifndef PKMNLIB_ANGELSCRIPTEVOLUTIONSCRIPT_HPP +#define PKMNLIB_ANGELSCRIPTEVOLUTIONSCRIPT_HPP +#include "../../Battling/Pokemon/Pokemon.hpp" +#include "../../Library/Evolutions/EvolutionData.hpp" +#include "AngelScriptFunctionCall.hpp" + +class AngelScriptResolver; + +class AngelScriptEvolutionScript final : public PkmnLib::Battling::EvolutionScript { + asIScriptObject* _scriptObject; + AngelScriptResolver* _resolver; + + struct FunctionInfo { + bool Exists = false; + asIScriptFunction* Function = nullptr; + }; + +#define EVO_SCRIPT_HOOK_FUNCTION(name, decl) FunctionInfo __##name = Initialize(decl); + + FunctionInfo Initialize(const std::string& decl) { + auto val = _scriptObject->GetObjectType()->GetMethodByDecl(decl.c_str(), false); + if (val == nullptr) { + return FunctionInfo{.Exists = false, .Function = nullptr}; + } + return FunctionInfo{.Exists = true, .Function = val}; + } + + EVO_SCRIPT_HOOK_FUNCTION(DoesEvolveFromLevelUp, + "void DoesEvolveFromLevelUp(bool& out, const EvolutionData@ evoData," + "const Pokemon@ pokemon)"); + +public: + AngelScriptEvolutionScript(asIScriptObject* scriptObject, AngelScriptResolver* resolver) + : _scriptObject(scriptObject), _resolver(resolver) {} + + ~AngelScriptEvolutionScript() { + if (_scriptObject != nullptr) { + _scriptObject->Release(); + } + } + + void DoesEvolveFromLevelUp(const ArbUt::BorrowedPtr& evolution, + const ArbUt::BorrowedPtr& pokemon, + bool* out) const override; +}; + +#endif // PKMNLIB_ANGELSCRIPTEVOLUTIONSCRIPT_HPP diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp index b44e657..36680f6 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp @@ -107,13 +107,13 @@ void AngelScriptResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg, void AngelScriptResolver::RegisterTypes() { // Register static library types + RegisterEffectParameter::Register(_engine); RegisterSpeciesTypes::Register(_engine); RegisterItemTypes::Register(_engine); RegisterMoveTypes::Register(_engine); RegisterGrowthRateTypes::Register(_engine); RegisterTypeLibrary::Register(_engine); RegisterStaticLibraryTypes::Register(_engine); - RegisterEffectParameter::Register(_engine); // Register battle types // Predeclare these two types, and declare their implementation later. @@ -197,6 +197,31 @@ CreatureLib::Battling::ItemUseScript* AngelScriptResolver::LoadItemScript(const return scriptObject; } +ArbUt::OptionalBorrowedPtr +AngelScriptResolver::LoadEvolutionScript(const ArbUt::StringView& view) { + auto v = this->_evolutionScripts.TryGet(view); + if (v.has_value()) { + return v.value().get(); + } + auto typeInfoOption = _evolutionTypes.TryGet(view); + if (!typeInfoOption.has_value()) { + return nullptr; + } + auto* ctx = _contextPool->RequestContext(); + auto* factory = typeInfoOption.value().get()->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(); + auto* scriptObject = new AngelScriptEvolutionScript(obj, this); + _evolutionScripts.Insert(view, scriptObject); + _contextPool->ReturnContextToPool(ctx); + return scriptObject; +} + void AngelScriptResolver::FinalizeModule() { int r = _builder.BuildModule(); if (r < 0) @@ -208,6 +233,7 @@ void AngelScriptResolver::FinalizeModule() { auto pkmnScriptType = _mainModule->GetTypeInfoByName("PkmnScript"); auto itemUseScriptType = _mainModule->GetTypeInfoByName("ItemUseScript"); + auto evolutionScriptType = _mainModule->GetTypeInfoByName("EvolutionScript"); for (asUINT n = 0; n < count; n++) { auto typeInfo = _mainModule->GetObjectTypeByIndex(n); if (typeInfo->DerivesFrom(pkmnScriptType)) { @@ -252,6 +278,27 @@ void AngelScriptResolver::FinalizeModule() { _itemUseTypes.Insert(effectName, typeInfo); } } + } else if (typeInfo->DerivesFrom(evolutionScriptType)) { + auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId()); + for (size_t m = 0; m < metadata.size(); m++) { + auto data = metadata[m]; + if (std::regex_match(data, base_match, metadataMatcher)) { + auto mt = base_match[1].str(); + auto metadataKind = ArbUt::StringView(mt.c_str(), mt.length()); + auto metadataVariables = base_match[2].str(); + if (!std::regex_match(metadataVariables, base_match, variableMatcher)) { + continue; + } + ArbUt::StringView effectName; + for (size_t variableIndex = 1; variableIndex < base_match.size(); variableIndex += 2) { + if (ArbUt::StringView::CalculateHash(base_match[variableIndex].str().c_str()) == "effect"_cnc) { + auto val = base_match[variableIndex + 1].str(); + effectName = ArbUt::StringView(val.c_str(), val.length()); + } + } + _evolutionTypes.Insert(effectName, typeInfo); + } + } } } } @@ -309,7 +356,7 @@ void AngelScriptResolver::WriteByteCodeToFile(const char* file, bool stripDebugI // We grab the current position of the written file. This is the position the types will be written on. So we need // to know this. uint64_t bytecodeSize = (uint64_t)ftell(wFile); - stream->WriteTypes(_typeDatabase, _itemUseTypes); + stream->WriteTypes(_typeDatabase, _itemUseTypes, _evolutionTypes); // Go back to the start of the file fsetpos(wFile, &startPos); @@ -351,7 +398,7 @@ uint8_t* AngelScriptResolver::WriteByteCodeToMemory(size_t& size, bool stripDebu auto result = _mainModule->SaveByteCode(stream, stripDebugInfo); Ensure(result == asSUCCESS); byteCodeSize[0] = (uint64_t)stream->GetWrittenSize(); - stream->WriteTypes(_typeDatabase, _itemUseTypes); + stream->WriteTypes(_typeDatabase, _itemUseTypes, _evolutionTypes); stream->WriteToPosition(byteCodeSize, sizeof(uint64_t), 0); auto arr = stream->GetOut(); size = stream->GetWrittenSize(); @@ -376,7 +423,7 @@ void AngelScriptResolver::LoadByteCodeFromMemory(uint8_t* byte, size_t size) { delete stream; } void AngelScriptResolver::InitializeByteCode( - const ArbUt::Dictionary>& types) { + const ArbUt::Dictionary>& types) { auto typeCount = _mainModule->GetObjectTypeCount(); ArbUt::Dictionary objectTypes; @@ -386,19 +433,29 @@ void AngelScriptResolver::InitializeByteCode( } ArbUt::Dictionary> typeDatabase; for (const auto& innerDb : types) { - if (innerDb.first != (ScriptCategory)-1) { + if (innerDb.first >= 0 && innerDb.first <= 255) { ArbUt::Dictionary newInnerDb; for (const auto& val : innerDb.second) { auto decl = val.second; auto type = objectTypes[decl]; newInnerDb.Set(val.first, new AngelScriptTypeInfo(val.first, type)); } - typeDatabase.Set(innerDb.first, newInnerDb); + typeDatabase.Set((ScriptCategory)innerDb.first, newInnerDb); } else { - for (const auto& val : innerDb.second) { - auto decl = val.second; - auto type = objectTypes[decl]; - _itemUseTypes.Set(val.first, type); + if (innerDb.first == -1) { + for (const auto& val : innerDb.second) { + auto decl = val.second; + auto type = objectTypes[decl]; + _itemUseTypes.Set(val.first, type); + } + } else if (innerDb.first == -2) { + for (const auto& val : innerDb.second) { + auto decl = val.second; + auto type = objectTypes[decl]; + _evolutionTypes.Set(val.first, type); + } + } else { + THROW("Resolving unknown script category value: " << innerDb.first); } } } @@ -426,4 +483,4 @@ i32 AngelScriptResolver::IncludeCallback(const char* include, const char*, CScri return -102; } return builder->AddSectionFromFile((const char*)path.c_str()); -} +} \ No newline at end of file diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp index 33d95c6..1d6ef96 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp @@ -4,6 +4,7 @@ #include #include "../../../extern/angelscript_addons/scriptbuilder/scriptbuilder.h" #include "../../Battling/Library/BattleLibrary.hpp" +#include "AngelScriptEvolutionScript.hpp" #define ANGELSCRIPT_DLL_LIBRARY_IMPORT #include @@ -23,18 +24,18 @@ private: ArbUt::Dictionary> _typeDatabase; ArbUt::Dictionary _baseTypes; ArbUt::Dictionary _itemUseTypes; + ArbUt::Dictionary _evolutionTypes; ArbUt::Dictionary _itemUseScripts; - + ArbUt::Dictionary _evolutionScripts; static void MessageCallback(const asSMessageInfo* msg, void* param); static void Print(const std::string& str) { std::cout << str << std::endl; } static void PrintConst(const ArbUt::StringView& str) { Print(std::string(str.std_str())); } - static i32 IncludeCallback(const char *include, const char *from, CScriptBuilder *builder, void *userParam); - + static i32 IncludeCallback(const char* include, const char* from, CScriptBuilder* builder, void* userParam); void RegisterTypes(); void - InitializeByteCode(const ArbUt::Dictionary>& types); + InitializeByteCode(const ArbUt::Dictionary>& types); void RegisterScriptType(asITypeInfo* typeInfo, const ArbUt::StringView& metadataKind, const ArbUt::StringView& effectName); @@ -64,6 +65,9 @@ public: const ArbUt::StringView& scriptName) override; CreatureLib::Battling::ItemUseScript* LoadItemScript(const CreatureLib::Library::Item* item) override; + ArbUt::OptionalBorrowedPtr + LoadEvolutionScript(const ArbUt::StringView& view) override; + void WriteByteCodeToFile(const char* file, bool stripDebugInfo = false); void LoadByteCodeFromFile(const char* file); uint8_t* WriteByteCodeToMemory(size_t& size, bool stripDebugInfo = false); diff --git a/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp b/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp index e39e1d0..44cb342 100644 --- a/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp +++ b/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp @@ -15,7 +15,8 @@ protected: public: virtual void WriteTypes( const ArbUt::Dictionary>& types, - const ArbUt::Dictionary itemUseTypes) { + const ArbUt::Dictionary& itemUseTypes, + const ArbUt::Dictionary& evolutionTypes) { // We serialize our types in the format // "[category(byte)][name(str)]\2[decl(str)]\2[name(str)]\2[decl(str)]\1[category(byte)]...." @@ -23,7 +24,7 @@ public: for (const auto& dic : types) { // Write the category categoryArr[0] = dic.first; - Write(categoryArr, sizeof(ScriptCategory)); + Write(categoryArr, sizeof(i16)); for (const auto& inner : dic.second) { // Write the script name Write(inner.first.c_str(), sizeof(char) * inner.first.Length()); @@ -40,7 +41,7 @@ public: } categoryArr[0] = (ScriptCategory)-1; - Write(categoryArr, sizeof(ScriptCategory)); + Write(categoryArr, sizeof(i16)); for (const auto& inner : itemUseTypes) { // Write the script name Write(inner.first.c_str(), sizeof(char) * inner.first.Length()); @@ -54,15 +55,31 @@ public: } // Write the divider between categories. Write("\1", sizeof(char)); + + categoryArr[0] = (ScriptCategory)-2; + Write(categoryArr, sizeof(i16)); + for (const auto& inner : evolutionTypes) { + // Write the script name + Write(inner.first.c_str(), sizeof(char) * inner.first.Length()); + // Write the divider + Write("\2", sizeof(char)); + // Write the declaration of the script + auto decl = inner.second->GetName(); + Write(decl, sizeof(char) * strlen(decl)); + // Write another divider. + Write("\2", sizeof(char)); + } + // Write the divider between categories. + Write("\1", sizeof(char)); } - virtual ArbUt::Dictionary> ReadTypes() { + virtual ArbUt::Dictionary> ReadTypes() { _angelScriptBound = SIZE_MAX; - ArbUt::Dictionary> types; - ScriptCategory categoryArr[1]; + ArbUt::Dictionary> types; + i16 categoryArr[1]; while (true) { // Every inner database starts with the category, of known size. Read that. - auto read = Read(categoryArr, sizeof(ScriptCategory)); + auto read = Read(categoryArr, sizeof(i16)); // If we haven't read anything, we are finished. if (read == 0) { break; diff --git a/src/ScriptResolving/AngelScript/TypeRegistry/BasicScriptClass.cpp b/src/ScriptResolving/AngelScript/TypeRegistry/BasicScriptClass.cpp index d4f495b..1d85f20 100644 --- a/src/ScriptResolving/AngelScript/TypeRegistry/BasicScriptClass.cpp +++ b/src/ScriptResolving/AngelScript/TypeRegistry/BasicScriptClass.cpp @@ -70,4 +70,11 @@ shared abstract class ItemUseScript { } )"); Ensure(r >= 0); + + r = engine->GetModuleByIndex(0)->AddScriptSection("EvolutionScript", R"( +shared abstract class EvolutionScript { + void DoesEvolveFromLevelUp(bool& out, const EvolutionData@ evoData, const Pokemon@ pokemon) { }; +} + )"); + Ensure(r >= 0); } diff --git a/src/ScriptResolving/AngelScript/TypeRegistry/Battling/RegisterPokemonClass.cpp b/src/ScriptResolving/AngelScript/TypeRegistry/Battling/RegisterPokemonClass.cpp index 4226a80..e534e5e 100644 --- a/src/ScriptResolving/AngelScript/TypeRegistry/Battling/RegisterPokemonClass.cpp +++ b/src/ScriptResolving/AngelScript/TypeRegistry/Battling/RegisterPokemonClass.cpp @@ -8,10 +8,6 @@ #include "../../AngelScriptScript.hpp" #include "../HelperFile.hpp" -// Hack to handle AngelScript not recognizing different sized enums on fields, and returning invalid values due to it. -#define ENUM__SIZE_WRAPPER(name, type, func) \ - int32_t name(type* obj) { return static_cast(obj->func()); } - void RegisterPokemonClass::Register(asIScriptEngine* engine) { RegisterDamageSource(engine); RegisterMoveLearnMethod(engine); diff --git a/src/ScriptResolving/AngelScript/TypeRegistry/HelperFile.hpp b/src/ScriptResolving/AngelScript/TypeRegistry/HelperFile.hpp index c5ccce0..4d76af3 100644 --- a/src/ScriptResolving/AngelScript/TypeRegistry/HelperFile.hpp +++ b/src/ScriptResolving/AngelScript/TypeRegistry/HelperFile.hpp @@ -4,3 +4,16 @@ static returns* funcName##Wrapper(o* obj) { return obj->funcName().GetValue(); } #define UNIQUE_PTR_GETTER_FUNC(o, returns, funcName) \ static returns* funcName##Wrapper(o* obj) { return obj->funcName().get(); } + +#define REGISTER_ENUM(enumName, asName) \ + { \ + auto __r = engine->RegisterEnum(asName); \ + Ensure(__r >= 0); \ + for (auto val : enumName##Helper::GetValues()) { \ + __r = engine->RegisterEnumValue(asName, enumName##Helper::ToString(val).c_str(), (i32)val); \ + Ensure(__r >= 0); \ + } \ + } +// Hack to handle AngelScript not recognizing different sized enums on fields, and returning invalid values due to it. +#define ENUM__SIZE_WRAPPER(name, type, func) \ +int32_t name(type* obj) { return static_cast(obj->func()); } \ No newline at end of file diff --git a/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterMoveTypes.cpp b/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterMoveTypes.cpp index aea87a1..b197f8b 100644 --- a/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterMoveTypes.cpp +++ b/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterMoveTypes.cpp @@ -1,6 +1,7 @@ #include "RegisterMoveTypes.hpp" #include "../../../../Library/Moves/MoveData.hpp" #include "../../../../Library/Moves/MoveLibrary.hpp" +#include "../HelperFile.hpp" void RegisterMoveTypes::Register(asIScriptEngine* engine) { RegisterMoveCategory(engine); @@ -9,33 +10,12 @@ void RegisterMoveTypes::Register(asIScriptEngine* engine) { RegisterMoveLibrary(engine); } -#define REGISTER_ENUM_VALUE(asName, cName, valueName) \ - r = engine->RegisterEnumValue(#asName, #valueName, (int)cName::valueName); \ - Ensure(r >= 0); - void RegisterMoveTypes::RegisterMoveCategory(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterEnum("MoveCategory"); - Ensure(r >= 0); - REGISTER_ENUM_VALUE(MoveCategory, PkmnLib::Library::MoveCategory, Physical) - REGISTER_ENUM_VALUE(MoveCategory, PkmnLib::Library::MoveCategory, Special) - REGISTER_ENUM_VALUE(MoveCategory, PkmnLib::Library::MoveCategory, Status) + REGISTER_ENUM(PkmnLib::Library::MoveCategory, "MoveCategory"); } void RegisterMoveTypes::RegisterMoveTarget(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterEnum("MoveTarget"); - Ensure(r >= 0); - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, Adjacent) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AdjacentAlly) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AdjacentAllySelf) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AdjacentOpponent) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, All) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AllAdjacent) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AllAdjacentOpponent) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AllAlly) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, AllOpponent) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, Any) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, RandomOpponent) - REGISTER_ENUM_VALUE(MoveTarget, CreatureLib::Library::AttackTarget, Self) + REGISTER_ENUM(CreatureLib::Library::AttackTarget, "MoveTarget"); } // Hack to handle AngelScript not recognizing different sized enums on fields, and returning invalid values due to it. diff --git a/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.cpp b/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.cpp index 8484664..11ddc5d 100644 --- a/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.cpp +++ b/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.cpp @@ -9,35 +9,36 @@ void RegisterSpeciesTypes::Register(asIScriptEngine* engine) { RegisterStatisticEnum(engine); RegisterFormeType(engine); RegisterSpeciesType(engine); + RegisterEvolutionData(engine); RegisterSpeciesLibrary(engine); } void RegisterSpeciesTypes::RegisterGenderEnum(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterEnum("Gender"); - assert(r >= 0); + int r = engine->RegisterEnum("Gender"); + Ensure(r >= 0); r = engine->RegisterEnumValue("Gender", "Male", (int)CreatureLib::Library::Gender::Male); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Gender", "Female", (int)CreatureLib::Library::Gender::Female); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Gender", "Genderless", (int)CreatureLib::Library::Gender::Genderless); - assert(r >= 0); + Ensure(r >= 0); } void RegisterSpeciesTypes::RegisterStatisticEnum(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterEnum("Statistic"); - assert(r >= 0); + int r = engine->RegisterEnum("Statistic"); + Ensure(r >= 0); r = engine->RegisterEnumValue("Statistic", "HP", (int)PkmnLib::Library::Statistic::HealthPoints); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Statistic", "Attack", (int)PkmnLib::Library::Statistic::PhysicalAttack); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Statistic", "Defense", (int)PkmnLib::Library::Statistic::PhysicalDefense); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Statistic", "SpecialAttack", (int)PkmnLib::Library::Statistic::SpecialAttack); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Statistic", "SpecialDefense", (int)PkmnLib::Library::Statistic::SpecialDefense); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterEnumValue("Statistic", "Speed", (int)PkmnLib::Library::Statistic::Speed); - assert(r >= 0); + Ensure(r >= 0); } static const PkmnLib::Library::PokemonForme* GetFormeWrapper(const std::string& s, @@ -49,29 +50,29 @@ static const PkmnLib::Library::PokemonForme* GetFormeWrapper(const std::string& BORROWED_PTR_GETTER_FUNC(PkmnLib::Library::PokemonSpecies, const PkmnLib::Library::PokemonForme, GetDefaultForme); void RegisterSpeciesTypes::RegisterSpeciesType(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterObjectType("Species", 0, asOBJ_REF | asOBJ_NOCOUNT); - assert(r >= 0); + int r = engine->RegisterObjectType("Species", 0, asOBJ_REF | asOBJ_NOCOUNT); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "const constString& get_Name() const property", asMETHOD(PkmnLib::Library::PokemonSpecies, GetName), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "uint16 get_Id() const property", asMETHOD(PkmnLib::Library::PokemonSpecies, GetId), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "float get_GenderRate() const property", asMETHOD(PkmnLib::Library::PokemonSpecies, GetGenderRate), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "uint8 get_CaptureRate() const property", asMETHOD(PkmnLib::Library::PokemonSpecies, GetCaptureRate), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "Gender GetRandomGender() const", asMETHOD(PkmnLib::Library::PokemonSpecies, GetRandomGender), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "const Forme@ GetForme(string key) const", asFUNCTION(GetFormeWrapper), asCALL_CDECL_OBJLAST); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Species", "const Forme@ get_DefaultForme() const property", asFUNCTION(GetDefaultFormeWrapper), asCALL_CDECL_OBJLAST); - assert(r >= 0); + Ensure(r >= 0); } const ArbUt::StringView& GetAbility(PkmnLib::Library::PokemonForme* p, bool hidden, uint8_t index) { @@ -79,40 +80,60 @@ const ArbUt::StringView& GetAbility(PkmnLib::Library::PokemonForme* p, bool hidd } void RegisterSpeciesTypes::RegisterFormeType(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterObjectType("Forme", 0, asOBJ_REF | asOBJ_NOCOUNT); - assert(r >= 0); + int r = engine->RegisterObjectType("Forme", 0, asOBJ_REF | asOBJ_NOCOUNT); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "const constString& get_Name() const property", asMETHOD(PkmnLib::Library::PokemonForme, GetName), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "float get_Weight() const property", asMETHOD(PkmnLib::Library::PokemonForme, GetWeight), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "float get_Height() const property", asMETHOD(PkmnLib::Library::PokemonForme, GetHeight), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "uint get_BaseExperience() const property", asMETHOD(PkmnLib::Library::PokemonForme, GetBaseExperience), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "int get_TypeCount() const property", asMETHOD(PkmnLib::Library::PokemonForme, GetTypeCount), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "uint8 GetType(int index) const", asMETHOD(PkmnLib::Library::PokemonForme, GetType), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "uint GetStatistic(Statistic stat) const", asMETHOD(PkmnLib::Library::PokemonForme, GetStatistic), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); r = engine->RegisterObjectMethod("Forme", "const constString& GetAbility(bool hidden, uint8 index) const", asFUNCTIONPR(GetAbility, (PkmnLib::Library::PokemonForme * p, bool hidden, uint8_t index), const ArbUt::StringView&), asCALL_CDECL_OBJFIRST); - assert(r >= 0); + Ensure(r >= 0); } +ENUM__SIZE_WRAPPER(EvolutionData_GetMethodWrapper, PkmnLib::Library::EvolutionData, GetMethod); + +void RegisterSpeciesTypes::RegisterEvolutionData(asIScriptEngine* engine) { + int r = engine->RegisterObjectType("EvolutionData", 0, asOBJ_REF | asOBJ_NOCOUNT); + Ensure(r >= 0); + r = engine->RegisterObjectMethod("EvolutionData", "const Species& get_NewSpecies() const property", + asMETHOD(PkmnLib::Library::EvolutionData, GetNewSpecies), asCALL_THISCALL); + Ensure(r >= 0); + REGISTER_ENUM(PkmnLib::Library::EvolutionMethod, "EvolutionMethod"); + r = engine->RegisterObjectMethod("EvolutionData", "EvolutionMethod get_Method() const property", + asFUNCTION(EvolutionData_GetMethodWrapper), asCALL_CDECL_OBJLAST); + Ensure(r >= 0); + r = engine->RegisterObjectMethod("EvolutionData", "uint64 get_DataCount() const property", + asMETHOD(PkmnLib::Library::EvolutionData, GetDataCount), asCALL_THISCALL); + Ensure(r >= 0); + r = engine->RegisterObjectMethod("EvolutionData", "EffectParameter@ GetData(uint64 index) const", + asMETHOD(PkmnLib::Library::EvolutionData, GetData), asCALL_THISCALL); + Ensure(r >= 0); +} + void RegisterSpeciesTypes::RegisterSpeciesLibrary(asIScriptEngine* engine) { - [[maybe_unused]] int r = engine->RegisterObjectType("SpeciesLibrary", 0, asOBJ_REF | asOBJ_NOCOUNT); - assert(r >= 0); + int r = engine->RegisterObjectType("SpeciesLibrary", 0, asOBJ_REF | asOBJ_NOCOUNT); + Ensure(r >= 0); r = engine->RegisterObjectMethod("SpeciesLibrary", "const Species@ Get(const constString &in name) const", asMETHOD(PkmnLib::Library::SpeciesLibrary, Get), asCALL_THISCALL); - assert(r >= 0); + Ensure(r >= 0); } diff --git a/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.hpp b/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.hpp index 97bf96d..ddae028 100644 --- a/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.hpp +++ b/src/ScriptResolving/AngelScript/TypeRegistry/Library/RegisterSpeciesTypes.hpp @@ -12,6 +12,7 @@ private: static void RegisterStatisticEnum(asIScriptEngine* engine); static void RegisterSpeciesType(asIScriptEngine* engine); static void RegisterFormeType(asIScriptEngine* engine); + static void RegisterEvolutionData(asIScriptEngine* engine); static void RegisterSpeciesLibrary(asIScriptEngine* engine); };