Implements new Effect Parameters in AngelScript/
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
0700f7cfbd
commit
d12267c695
|
@ -13,6 +13,7 @@
|
||||||
#include "TypeRegistry/Battling/RegisterPokemonClass.hpp"
|
#include "TypeRegistry/Battling/RegisterPokemonClass.hpp"
|
||||||
#include "TypeRegistry/Battling/RegisterTurnChoices.hpp"
|
#include "TypeRegistry/Battling/RegisterTurnChoices.hpp"
|
||||||
#include "TypeRegistry/ConstString.hpp"
|
#include "TypeRegistry/ConstString.hpp"
|
||||||
|
#include "TypeRegistry/Library/RegisterEffectParameter.hpp"
|
||||||
#include "TypeRegistry/Library/RegisterGrowthRateTypes.hpp"
|
#include "TypeRegistry/Library/RegisterGrowthRateTypes.hpp"
|
||||||
#include "TypeRegistry/Library/RegisterItemTypes.hpp"
|
#include "TypeRegistry/Library/RegisterItemTypes.hpp"
|
||||||
#include "TypeRegistry/Library/RegisterMoveTypes.hpp"
|
#include "TypeRegistry/Library/RegisterMoveTypes.hpp"
|
||||||
|
@ -24,6 +25,26 @@ CreatureLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateS
|
||||||
return new AngelScripResolver();
|
return new AngelScripResolver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TranslateException(asIScriptContext *ctx, void* /*userParam*/)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Retrow the original exception so we can catch it again
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch( std::exception &e )
|
||||||
|
{
|
||||||
|
// Tell the VM the type of exception that occurred
|
||||||
|
ctx->SetException(e.what());
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
// The callback must not allow any exception to be thrown, but it is not necessary
|
||||||
|
// to explicitly set an exception string if the default exception string is sufficient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
|
void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
|
||||||
for (auto scriptCategory : ScriptCategoryHelper::GetValues()) {
|
for (auto scriptCategory : ScriptCategoryHelper::GetValues()) {
|
||||||
_typeDatabase.Insert(scriptCategory, {});
|
_typeDatabase.Insert(scriptCategory, {});
|
||||||
|
@ -31,6 +52,7 @@ void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
|
||||||
|
|
||||||
auto library = (PkmnLib::Battling::BattleLibrary*)arg;
|
auto library = (PkmnLib::Battling::BattleLibrary*)arg;
|
||||||
_engine = asCreateScriptEngine();
|
_engine = asCreateScriptEngine();
|
||||||
|
_engine->SetTranslateAppExceptionCallback(asFUNCTION(TranslateException), 0, asCALL_CDECL);
|
||||||
|
|
||||||
int32_t r = _engine->SetMessageCallback(asFUNCTION(MessageCallback), nullptr, asCALL_CDECL);
|
int32_t r = _engine->SetMessageCallback(asFUNCTION(MessageCallback), nullptr, asCALL_CDECL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -76,6 +98,7 @@ void AngelScripResolver::RegisterTypes() {
|
||||||
RegisterGrowthRateTypes::Register(_engine);
|
RegisterGrowthRateTypes::Register(_engine);
|
||||||
RegisterTypeLibrary::Register(_engine);
|
RegisterTypeLibrary::Register(_engine);
|
||||||
RegisterStaticLibraryTypes::Register(_engine);
|
RegisterStaticLibraryTypes::Register(_engine);
|
||||||
|
RegisterEffectParameter::Register(_engine);
|
||||||
|
|
||||||
// Register battle types
|
// Register battle types
|
||||||
RegisterPokemonClass::Register(_engine);
|
RegisterPokemonClass::Register(_engine);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
|
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
|
||||||
#include <CreatureLib/Library/Exceptions/NotImplementedException.hpp>
|
#include <CreatureLib/Library/Exceptions/NotImplementedException.hpp>
|
||||||
#include <angelscript.h>
|
#include <angelscript.h>
|
||||||
|
#include "../../../extern/angelscript_addons/scriptarray/scriptarray.h"
|
||||||
#include "../../Battling/PkmnScript.hpp"
|
#include "../../Battling/PkmnScript.hpp"
|
||||||
#include "AngelScriptTypeInfo.hpp"
|
#include "AngelScriptTypeInfo.hpp"
|
||||||
#include "ContextPool.hpp"
|
#include "ContextPool.hpp"
|
||||||
|
@ -73,6 +74,28 @@ public:
|
||||||
ctx->PopState(); \
|
ctx->PopState(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CScriptArray*
|
||||||
|
GetEffectParameters(asIScriptContext* ctx,
|
||||||
|
const Arbutils::Collections::List<CreatureLib::Library::EffectParameter*>& ls) {
|
||||||
|
asIScriptEngine* engine = ctx->GetEngine();
|
||||||
|
asITypeInfo* t = engine->GetTypeInfoByDecl("array<EffectParameter@>");
|
||||||
|
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 OnInitialize(const Arbutils::Collections::List<CreatureLib::Library::EffectParameter*>& 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 Stack() override { CALL_HOOK(Stack, ); }
|
||||||
|
|
||||||
void OnRemove() override { CALL_HOOK(OnRemove, ); }
|
void OnRemove() override { CALL_HOOK(OnRemove, ); }
|
||||||
|
|
|
@ -77,6 +77,7 @@ private:
|
||||||
public: \
|
public: \
|
||||||
const FunctionInfo& Get##name() const { return __##name; }
|
const FunctionInfo& Get##name() const { return __##name; }
|
||||||
|
|
||||||
|
SCRIPT_HOOK_FUNCTION(OnInitialize, "void OnInitialize(const array<EffectParameter@> &in parameters)");
|
||||||
SCRIPT_HOOK_FUNCTION(Stack, "void Stack()");
|
SCRIPT_HOOK_FUNCTION(Stack, "void Stack()");
|
||||||
SCRIPT_HOOK_FUNCTION(OnRemove, "void OnRemove()");
|
SCRIPT_HOOK_FUNCTION(OnRemove, "void OnRemove()");
|
||||||
SCRIPT_HOOK_FUNCTION(PreventAttack, "void PreventAttack(ExecutingMove@ attack, bool& result)");
|
SCRIPT_HOOK_FUNCTION(PreventAttack, "void PreventAttack(ExecutingMove@ attack, bool& result)");
|
||||||
|
|
|
@ -7,6 +7,7 @@ void BasicScriptClass::Register(asIScriptEngine* engine) {
|
||||||
[[maybe_unused]] int r = engine->GetModuleByIndex(0)->AddScriptSection("PkmnScript", R"(
|
[[maybe_unused]] int r = engine->GetModuleByIndex(0)->AddScriptSection("PkmnScript", R"(
|
||||||
shared abstract class PkmnScript {
|
shared abstract class PkmnScript {
|
||||||
// CreatureLib methods
|
// CreatureLib methods
|
||||||
|
void OnInitialize(const array<EffectParameter@> &in parameters){};
|
||||||
void Stack(){};
|
void Stack(){};
|
||||||
void OnRemove(){};
|
void OnRemove(){};
|
||||||
void PreventAttack(ExecutingMove@ attack, bool& result){};
|
void PreventAttack(ExecutingMove@ attack, bool& result){};
|
||||||
|
@ -38,5 +39,4 @@ shared abstract class PkmnScript {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include "RegisterEffectParameter.hpp"
|
||||||
|
#include <Arbutils/Assert.hpp>
|
||||||
|
#include <CreatureLib/Library/EffectParameter.hpp>
|
||||||
|
|
||||||
|
static CreatureLib::Library::EffectParameter* Ref_Factory() { return new CreatureLib::Library::EffectParameter(); }
|
||||||
|
|
||||||
|
static std::string AsString(const CreatureLib::Library::EffectParameter* p) { return p->AsString(); }
|
||||||
|
|
||||||
|
void RegisterEffectParameter::Register(asIScriptEngine* engine) {
|
||||||
|
[[maybe_unused]] int r = engine->RegisterEnum("EffectParameterType");
|
||||||
|
Assert(r >= 0);
|
||||||
|
for (auto val : CreatureLib::Library::EffectParameterTypeHelper::GetValues()) {
|
||||||
|
r = engine->RegisterEnumValue("EffectParameterType",
|
||||||
|
CreatureLib::Library::EffectParameterTypeHelper::ToString(val), (int)val);
|
||||||
|
Assert(r >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = engine->RegisterObjectType("EffectParameter", 0, asOBJ_REF | asOBJ_NOCOUNT);
|
||||||
|
Assert(r >= 0);
|
||||||
|
|
||||||
|
r = engine->RegisterObjectBehaviour("EffectParameter", asBEHAVE_FACTORY, "EffectParameter@ f()",
|
||||||
|
asFUNCTION(Ref_Factory), asCALL_CDECL);
|
||||||
|
Assert(r >= 0);
|
||||||
|
r = engine->RegisterObjectMethod("EffectParameter", "EffectParameterType GetType() const",
|
||||||
|
asMETHOD(CreatureLib::Library::EffectParameter, GetType), asCALL_THISCALL);
|
||||||
|
Assert(r >= 0);
|
||||||
|
|
||||||
|
r = engine->RegisterObjectMethod("EffectParameter", "bool AsBool() const",
|
||||||
|
asMETHOD(CreatureLib::Library::EffectParameter, AsBool), asCALL_THISCALL);
|
||||||
|
Assert(r >= 0);
|
||||||
|
r = engine->RegisterObjectMethod("EffectParameter", "int64 AsInt() const",
|
||||||
|
asMETHOD(CreatureLib::Library::EffectParameter, AsInt), asCALL_THISCALL);
|
||||||
|
Assert(r >= 0);
|
||||||
|
r = engine->RegisterObjectMethod(
|
||||||
|
"EffectParameter", "string AsString() const",
|
||||||
|
asFUNCTIONPR(AsString, (const CreatureLib::Library::EffectParameter*), std::string), asCALL_CDECL_OBJFIRST);
|
||||||
|
Assert(r >= 0);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef PKMNLIB_REGISTEREFFECTPARAMETER_HPP
|
||||||
|
#define PKMNLIB_REGISTEREFFECTPARAMETER_HPP
|
||||||
|
|
||||||
|
#include <angelscript.h>
|
||||||
|
class RegisterEffectParameter {
|
||||||
|
public:
|
||||||
|
static void Register(asIScriptEngine* engine);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PKMNLIB_REGISTEREFFECTPARAMETER_HPP
|
|
@ -9,6 +9,20 @@
|
||||||
|
|
||||||
static std::unordered_map<const char*, const char*> _scripts = std::unordered_map<const char*, const char*>{
|
static std::unordered_map<const char*, const char*> _scripts = std::unordered_map<const char*, const char*>{
|
||||||
AS_CLASS(blankScript, ),
|
AS_CLASS(blankScript, ),
|
||||||
|
AS_CLASS(initializeScript, R"(
|
||||||
|
bool boolValue = false;
|
||||||
|
int64 intValue = 0;
|
||||||
|
string stringValue = "";
|
||||||
|
void OnInitialize(const array<EffectParameter@> &in parameters) override {
|
||||||
|
boolValue = parameters[0].AsBool();
|
||||||
|
intValue = parameters[1].AsInt();
|
||||||
|
stringValue = parameters[2].AsString();
|
||||||
|
}
|
||||||
|
bool GetBoolValue() { return boolValue; }
|
||||||
|
int64 GetIntValue() { return intValue; }
|
||||||
|
string GetStringValue() { return stringValue; }
|
||||||
|
)"),
|
||||||
|
|
||||||
AS_CLASS(stackScript, "int value = 0; void Stack() override { value++; } int GetValue() { return value; }"),
|
AS_CLASS(stackScript, "int value = 0; void Stack() override { value++; } int GetValue() { return value; }"),
|
||||||
AS_CLASS(onRemoveScript, "int value = 0; void OnRemove() override { value++; } int GetValue() { return value; }"),
|
AS_CLASS(onRemoveScript, "int value = 0; void OnRemove() override { value++; } int GetValue() { return value; }"),
|
||||||
{"doubleInheritanceScript", R"(
|
{"doubleInheritanceScript", R"(
|
||||||
|
@ -93,6 +107,47 @@ TEST_CASE("Invoke non-implemented script function") {
|
||||||
delete script;
|
delete script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Invoke OnInitialize script function") {
|
||||||
|
auto mainLib = TestLibrary::GetLibrary();
|
||||||
|
auto script = GetScript(mainLib, "initializeScript"_cnc);
|
||||||
|
REQUIRE(script != nullptr);
|
||||||
|
|
||||||
|
auto parameters = {
|
||||||
|
new CreatureLib::Library::EffectParameter(true),
|
||||||
|
new CreatureLib::Library::EffectParameter((int64_t)684),
|
||||||
|
new CreatureLib::Library::EffectParameter(std::string("foobar"))
|
||||||
|
};
|
||||||
|
|
||||||
|
script->OnInitialize(parameters);
|
||||||
|
|
||||||
|
auto ctxPool = script->GetContextPool();
|
||||||
|
auto ctx = ctxPool->RequestContext();
|
||||||
|
|
||||||
|
script->PrepareMethod("GetBoolValue"_cnc, ctx);
|
||||||
|
REQUIRE(ctx->Execute() == asEXECUTION_FINISHED);
|
||||||
|
REQUIRE((bool)ctx->GetReturnDWord());
|
||||||
|
ctxPool->ReturnContextToPool(ctx);
|
||||||
|
|
||||||
|
ctx = ctxPool->RequestContext();
|
||||||
|
script->PrepareMethod("GetIntValue"_cnc, ctx);
|
||||||
|
REQUIRE(ctx->Execute() == asEXECUTION_FINISHED);
|
||||||
|
REQUIRE(ctx->GetReturnQWord() == 684);
|
||||||
|
ctxPool->ReturnContextToPool(ctx);
|
||||||
|
|
||||||
|
ctx = ctxPool->RequestContext();
|
||||||
|
script->PrepareMethod("GetStringValue"_cnc, ctx);
|
||||||
|
REQUIRE(ctx->Execute() == asEXECUTION_FINISHED);
|
||||||
|
std::string s;
|
||||||
|
s = *(std::string*)ctx->GetReturnAddress();
|
||||||
|
REQUIRE(s == "foobar");
|
||||||
|
ctxPool->ReturnContextToPool(ctx);
|
||||||
|
|
||||||
|
for (auto p : parameters){
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
delete script;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Invoke Stack script function") {
|
TEST_CASE("Invoke Stack script function") {
|
||||||
auto mainLib = TestLibrary::GetLibrary();
|
auto mainLib = TestLibrary::GetLibrary();
|
||||||
auto script = GetScript(mainLib, "stackScript"_cnc);
|
auto script = GetScript(mainLib, "stackScript"_cnc);
|
||||||
|
@ -296,7 +351,6 @@ TEST_CASE("Get script name.") {
|
||||||
delete script;
|
delete script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("Handle script exceptions.") {
|
TEST_CASE("Handle script exceptions.") {
|
||||||
auto mainLib = TestLibrary::GetLibrary();
|
auto mainLib = TestLibrary::GetLibrary();
|
||||||
auto script = GetScript(mainLib, "throwScript"_cnc);
|
auto script = GetScript(mainLib, "throwScript"_cnc);
|
||||||
|
|
Loading…
Reference in New Issue