Adds a bunch of helpers for evolution, as well as custom script evolution methods.
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2021-07-09 13:54:42 +02:00
parent 8fc29d925b
commit 9424a209ec
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
16 changed files with 281 additions and 86 deletions

View File

@ -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);)

View File

@ -0,0 +1,13 @@
#ifndef PKMNLIB_EVOLUTIONSCRIPT_HPP
#define PKMNLIB_EVOLUTIONSCRIPT_HPP
namespace PkmnLib::Battling {
class EvolutionScript {
public:
virtual void DoesEvolveFromLevelUp(const ArbUt::BorrowedPtr<const PkmnLib::Library::EvolutionData>& evolution,
const ArbUt::BorrowedPtr<const PkmnLib::Battling::Pokemon>& pokemon,
bool* out) const = 0;
};
}
#endif // PKMNLIB_EVOLUTIONSCRIPT_HPP

View File

@ -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<ScriptResolver*>(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:

View File

@ -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<const EvolutionScript> LoadEvolutionScript(const ArbUt::StringView&) {
return nullptr;
};
};
}

View File

@ -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

View File

@ -0,0 +1,18 @@
#include "AngelScriptEvolutionScript.hpp"
#include "AngelScriptResolver.hpp"
void AngelScriptEvolutionScript::DoesEvolveFromLevelUp(
const ArbUt::BorrowedPtr<const PkmnLib::Library::EvolutionData>& evolution,
const ArbUt::BorrowedPtr<const PkmnLib::Battling::Pokemon>& 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) {});
}

View File

@ -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<const PkmnLib::Library::EvolutionData>& evolution,
const ArbUt::BorrowedPtr<const PkmnLib::Battling::Pokemon>& pokemon,
bool* out) const override;
};
#endif // PKMNLIB_ANGELSCRIPTEVOLUTIONSCRIPT_HPP

View File

@ -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<const PkmnLib::Battling::EvolutionScript>
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<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& types) {
const ArbUt::Dictionary<i16, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& types) {
auto typeCount = _mainModule->GetObjectTypeCount();
ArbUt::Dictionary<uint32_t, asITypeInfo*> objectTypes;
@ -386,20 +433,30 @@ void AngelScriptResolver::InitializeByteCode(
}
ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*>> typeDatabase;
for (const auto& innerDb : types) {
if (innerDb.first != (ScriptCategory)-1) {
if (innerDb.first >= 0 && innerDb.first <= 255) {
ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*> 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 {
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);
}
}
}
_typeDatabase = typeDatabase;

View File

@ -4,6 +4,7 @@
#include <CreatureLib/Battling/ScriptHandling/ScriptResolver.hpp>
#include "../../../extern/angelscript_addons/scriptbuilder/scriptbuilder.h"
#include "../../Battling/Library/BattleLibrary.hpp"
#include "AngelScriptEvolutionScript.hpp"
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
#include <Arbutils/StringView.hpp>
@ -23,18 +24,18 @@ private:
ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*>> _typeDatabase;
ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> _baseTypes;
ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> _itemUseTypes;
ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> _evolutionTypes;
ArbUt::Dictionary<const CreatureLib::Library::Item*, AngelScriptItemUseScript*> _itemUseScripts;
ArbUt::Dictionary<ArbUt::StringView, AngelScriptEvolutionScript*> _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);
void RegisterTypes();
void
InitializeByteCode(const ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& types);
InitializeByteCode(const ArbUt::Dictionary<i16, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& 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<const PkmnLib::Battling::EvolutionScript>
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);

View File

@ -15,7 +15,8 @@ protected:
public:
virtual void WriteTypes(
const ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*>>& types,
const ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> itemUseTypes) {
const ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*>& itemUseTypes,
const ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*>& 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<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, uint32_t>> ReadTypes() {
virtual ArbUt::Dictionary<i16, ArbUt::Dictionary<ArbUt::StringView, uint32_t>> ReadTypes() {
_angelScriptBound = SIZE_MAX;
ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, uint32_t>> types;
ScriptCategory categoryArr[1];
ArbUt::Dictionary<i16, ArbUt::Dictionary<ArbUt::StringView, uint32_t>> 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;

View File

@ -67,6 +67,13 @@ shared abstract class ItemUseScript {
void OnUse() { };
void OnPokemonUse(Pokemon@ target) { };
}
)");
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);

View File

@ -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<int32_t>(obj->func()); }
void RegisterPokemonClass::Register(asIScriptEngine* engine) {
RegisterDamageSource(engine);
RegisterMoveLearnMethod(engine);

View File

@ -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<int32_t>(obj->func()); }

View File

@ -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.

View File

@ -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);
}

View File

@ -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);
};