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/RegisterTurnChoices.hpp"
|
||||
#include "TypeRegistry/ConstString.hpp"
|
||||
#include "TypeRegistry/Library/RegisterEffectParameter.hpp"
|
||||
#include "TypeRegistry/Library/RegisterGrowthRateTypes.hpp"
|
||||
#include "TypeRegistry/Library/RegisterItemTypes.hpp"
|
||||
#include "TypeRegistry/Library/RegisterMoveTypes.hpp"
|
||||
|
@ -24,6 +25,26 @@ CreatureLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateS
|
|||
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) {
|
||||
for (auto scriptCategory : ScriptCategoryHelper::GetValues()) {
|
||||
_typeDatabase.Insert(scriptCategory, {});
|
||||
|
@ -31,6 +52,7 @@ void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
|
|||
|
||||
auto library = (PkmnLib::Battling::BattleLibrary*)arg;
|
||||
_engine = asCreateScriptEngine();
|
||||
_engine->SetTranslateAppExceptionCallback(asFUNCTION(TranslateException), 0, asCALL_CDECL);
|
||||
|
||||
int32_t r = _engine->SetMessageCallback(asFUNCTION(MessageCallback), nullptr, asCALL_CDECL);
|
||||
if (r < 0)
|
||||
|
@ -76,6 +98,7 @@ void AngelScripResolver::RegisterTypes() {
|
|||
RegisterGrowthRateTypes::Register(_engine);
|
||||
RegisterTypeLibrary::Register(_engine);
|
||||
RegisterStaticLibraryTypes::Register(_engine);
|
||||
RegisterEffectParameter::Register(_engine);
|
||||
|
||||
// Register battle types
|
||||
RegisterPokemonClass::Register(_engine);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
|
||||
#include <CreatureLib/Library/Exceptions/NotImplementedException.hpp>
|
||||
#include <angelscript.h>
|
||||
#include "../../../extern/angelscript_addons/scriptarray/scriptarray.h"
|
||||
#include "../../Battling/PkmnScript.hpp"
|
||||
#include "AngelScriptTypeInfo.hpp"
|
||||
#include "ContextPool.hpp"
|
||||
|
@ -73,6 +74,28 @@ public:
|
|||
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 OnRemove() override { CALL_HOOK(OnRemove, ); }
|
||||
|
|
|
@ -77,6 +77,7 @@ private:
|
|||
public: \
|
||||
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(OnRemove, "void OnRemove()");
|
||||
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"(
|
||||
shared abstract class PkmnScript {
|
||||
// CreatureLib methods
|
||||
void OnInitialize(const array<EffectParameter@> &in parameters){};
|
||||
void Stack(){};
|
||||
void OnRemove(){};
|
||||
void PreventAttack(ExecutingMove@ attack, bool& result){};
|
||||
|
@ -38,5 +39,4 @@ shared abstract class PkmnScript {
|
|||
}
|
||||
)");
|
||||
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*>{
|
||||
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(onRemoveScript, "int value = 0; void OnRemove() override { value++; } int GetValue() { return value; }"),
|
||||
{"doubleInheritanceScript", R"(
|
||||
|
@ -93,6 +107,47 @@ TEST_CASE("Invoke non-implemented script function") {
|
|||
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") {
|
||||
auto mainLib = TestLibrary::GetLibrary();
|
||||
auto script = GetScript(mainLib, "stackScript"_cnc);
|
||||
|
@ -296,7 +351,6 @@ TEST_CASE("Get script name.") {
|
|||
delete script;
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Handle script exceptions.") {
|
||||
auto mainLib = TestLibrary::GetLibrary();
|
||||
auto script = GetScript(mainLib, "throwScript"_cnc);
|
||||
|
|
Loading…
Reference in New Issue