Adds support for modifying volatile scripts after adding them.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
5cfa174396
commit
e361507ec9
|
@ -31,6 +31,7 @@ public:
|
||||||
} else {
|
} else {
|
||||||
ctx->PopState();
|
ctx->PopState();
|
||||||
}
|
}
|
||||||
|
printf("%s\n", err.str().c_str());
|
||||||
throw ArbUt::Exception(err.str());
|
throw ArbUt::Exception(err.str());
|
||||||
}
|
}
|
||||||
if (newContext) {
|
if (newContext) {
|
||||||
|
|
|
@ -32,6 +32,9 @@ static void TranslateException(asIScriptContext* ctx, void* /*userParam*/) {
|
||||||
try {
|
try {
|
||||||
// Retrow the original exception so we can catch it again
|
// Retrow the original exception so we can catch it again
|
||||||
throw;
|
throw;
|
||||||
|
} catch (ArbUt::Exception& e) {
|
||||||
|
// Tell the VM the type of exception that occurred
|
||||||
|
ctx->SetException(e.what());
|
||||||
}catch (std::exception& e) {
|
}catch (std::exception& e) {
|
||||||
// Tell the VM the type of exception that occurred
|
// Tell the VM the type of exception that occurred
|
||||||
ctx->SetException(e.what());
|
ctx->SetException(e.what());
|
||||||
|
|
|
@ -84,7 +84,10 @@ public:
|
||||||
asITypeInfo* t;
|
asITypeInfo* t;
|
||||||
auto v = _baseTypes.TryGet(name);
|
auto v = _baseTypes.TryGet(name);
|
||||||
if (!v.has_value()) {
|
if (!v.has_value()) {
|
||||||
t = this->_engine->GetTypeInfoByDecl(name.c_str());
|
t = _mainModule->GetTypeInfoByName(name.c_str());
|
||||||
|
if (t == NULL){
|
||||||
|
t = _engine->GetTypeInfoByDecl(name.c_str());
|
||||||
|
}
|
||||||
_baseTypes.Insert(name, t);
|
_baseTypes.Insert(name, t);
|
||||||
} else {
|
} else {
|
||||||
t = v.value();
|
t = v.value();
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
|
|
||||||
~AngelScriptScript() override { _obj->Release(); }
|
~AngelScriptScript() override { _obj->Release(); }
|
||||||
|
|
||||||
|
inline asIScriptObject* GetRawAngelscriptObject() const noexcept { return _obj; }
|
||||||
|
|
||||||
[[nodiscard]] const ArbUt::StringView& GetName() const noexcept override { return _type->GetName(); }
|
[[nodiscard]] const ArbUt::StringView& GetName() const noexcept override { return _type->GetName(); }
|
||||||
const AngelScriptTypeInfo* GetType() const noexcept { return _type; }
|
const AngelScriptTypeInfo* GetType() const noexcept { return _type; }
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <CreatureLib/Battling/Models/Battle.hpp>
|
#include <CreatureLib/Battling/Models/Battle.hpp>
|
||||||
#include <CreatureLib/Battling/Models/BattleSide.hpp>
|
#include <CreatureLib/Battling/Models/BattleSide.hpp>
|
||||||
#include "../../../../Battling/Battle/Battle.hpp"
|
#include "../../../../Battling/Battle/Battle.hpp"
|
||||||
|
#include "../../AngelScriptScript.hpp"
|
||||||
#include "../HelperFile.hpp"
|
#include "../HelperFile.hpp"
|
||||||
|
|
||||||
void RegisterBattleClass::Register(asIScriptEngine* engine) {
|
void RegisterBattleClass::Register(asIScriptEngine* engine) {
|
||||||
|
@ -50,6 +51,11 @@ CreatureLib::Battling::BattleSide* GetBattleSideWrapper(PkmnLib::Battling::Battl
|
||||||
return battle->GetSides()[index];
|
return battle->GetSides()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static asIScriptObject* AddVolatileWrapper(PkmnLib::Battling::Battle* obj, const ArbUt::StringView& name) {
|
||||||
|
auto* scriptObject = (AngelScriptScript*)obj->AddVolatileScript(name);
|
||||||
|
return scriptObject->GetRawAngelscriptObject();
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterBattleClass::RegisterBattleSide(asIScriptEngine* engine) {
|
void RegisterBattleClass::RegisterBattleSide(asIScriptEngine* engine) {
|
||||||
int r = engine->RegisterObjectMethod(
|
int r = engine->RegisterObjectMethod(
|
||||||
"BattleSide", "bool SwapPositions(uint8 a, uint8 b)",
|
"BattleSide", "bool SwapPositions(uint8 a, uint8 b)",
|
||||||
|
@ -81,9 +87,8 @@ void RegisterBattleClass::RegisterBattle(asIScriptEngine* engine) {
|
||||||
r = engine->RegisterObjectMethod("Battle", "ChoiceQueue@ get_TurnQueue() const property",
|
r = engine->RegisterObjectMethod("Battle", "ChoiceQueue@ get_TurnQueue() const property",
|
||||||
asFUNCTION(GetCurrentTurnQueueWrapper), asCALL_CDECL_OBJFIRST);
|
asFUNCTION(GetCurrentTurnQueueWrapper), asCALL_CDECL_OBJFIRST);
|
||||||
Ensure(r >= 0);
|
Ensure(r >= 0);
|
||||||
r = engine->RegisterObjectMethod(
|
r = engine->RegisterObjectMethod("Battle", "ref@ AddVolatile(const constString &in name) const",
|
||||||
"Battle", "void AddVolatile(const constString &in name) const",
|
asFUNCTION(AddVolatileWrapper), asCALL_CDECL_OBJFIRST);
|
||||||
asMETHODPR(PkmnLib::Battling::Battle, AddVolatileScript, (const ArbUt::StringView&), void), asCALL_THISCALL);
|
|
||||||
Ensure(r >= 0);
|
Ensure(r >= 0);
|
||||||
r = engine->RegisterObjectMethod(
|
r = engine->RegisterObjectMethod(
|
||||||
"Battle", "void RemoveVolatile(const constString &in name) const",
|
"Battle", "void RemoveVolatile(const constString &in name) const",
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include "RegisterPokemonClass.hpp"
|
#include "RegisterPokemonClass.hpp"
|
||||||
#include <CreatureLib/Battling/Models/LearnedAttack.hpp>
|
#include <CreatureLib/Battling/Models/LearnedAttack.hpp>
|
||||||
#include "../../../../../extern/angelscript_addons/scriptarray/scriptarray.h"
|
#include "../../../../../extern/angelscript_addons/scriptarray/scriptarray.h"
|
||||||
|
#include "../../../../../extern/angelscript_addons/scripthandle/scripthandle.h"
|
||||||
#include "../../../../Battling/PkmnDamageSource.hpp"
|
#include "../../../../Battling/PkmnDamageSource.hpp"
|
||||||
#include "../../../../Battling/Pokemon/Pokemon.hpp"
|
#include "../../../../Battling/Pokemon/Pokemon.hpp"
|
||||||
|
#include "../../AngelScriptResolver.hpp"
|
||||||
|
#include "../../AngelScriptScript.hpp"
|
||||||
#include "../HelperFile.hpp"
|
#include "../HelperFile.hpp"
|
||||||
|
|
||||||
// Hack to handle AngelScript not recognizing different sized enums on fields, and returning invalid values due to it.
|
// Hack to handle AngelScript not recognizing different sized enums on fields, and returning invalid values due to it.
|
||||||
|
@ -87,6 +90,15 @@ OPTIONAL_BORROWED_PTR_GETTER_FUNC(PkmnLib::Battling::Pokemon, const CreatureLib:
|
||||||
OPTIONAL_BORROWED_PTR_GETTER_FUNC(PkmnLib::Battling::Pokemon, CreatureLib::Battling::Battle, GetBattle);
|
OPTIONAL_BORROWED_PTR_GETTER_FUNC(PkmnLib::Battling::Pokemon, CreatureLib::Battling::Battle, GetBattle);
|
||||||
OPTIONAL_BORROWED_PTR_GETTER_FUNC(PkmnLib::Battling::Pokemon, CreatureLib::Battling::BattleSide, GetBattleSide);
|
OPTIONAL_BORROWED_PTR_GETTER_FUNC(PkmnLib::Battling::Pokemon, CreatureLib::Battling::BattleSide, GetBattleSide);
|
||||||
|
|
||||||
|
static CScriptHandle AddVolatileWrapper(PkmnLib::Battling::Pokemon* obj, const ArbUt::StringView& name) {
|
||||||
|
auto handle = CScriptHandle();
|
||||||
|
auto *resolver = static_cast<AngelScriptResolver*>(obj->GetLibrary()->GetScriptResolver().get());
|
||||||
|
auto script = static_cast<AngelScriptScript*>(obj->AddVolatileScript(name))->GetRawAngelscriptObject();
|
||||||
|
script->AddRef();
|
||||||
|
handle.Set(script, resolver->GetBaseType("PkmnScript"));
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterPokemonClass::RegisterPokemonType(asIScriptEngine* engine) {
|
void RegisterPokemonClass::RegisterPokemonType(asIScriptEngine* engine) {
|
||||||
[[maybe_unused]] int r = engine->RegisterObjectType("Pokemon", 0, asOBJ_REF | asOBJ_NOCOUNT);
|
[[maybe_unused]] int r = engine->RegisterObjectType("Pokemon", 0, asOBJ_REF | asOBJ_NOCOUNT);
|
||||||
Ensure(r >= 0);
|
Ensure(r >= 0);
|
||||||
|
@ -177,9 +189,8 @@ void RegisterPokemonClass::RegisterPokemonType(asIScriptEngine* engine) {
|
||||||
r = engine->RegisterObjectMethod("Pokemon", "int8 GetStatBoost(Statistic stat) const",
|
r = engine->RegisterObjectMethod("Pokemon", "int8 GetStatBoost(Statistic stat) const",
|
||||||
asMETHOD(PkmnLib::Battling::Pokemon, GetStatBoost), asCALL_THISCALL);
|
asMETHOD(PkmnLib::Battling::Pokemon, GetStatBoost), asCALL_THISCALL);
|
||||||
Ensure(r >= 0);
|
Ensure(r >= 0);
|
||||||
r = engine->RegisterObjectMethod(
|
r = engine->RegisterObjectMethod("Pokemon", "ref@ AddVolatile(const constString &in name)",
|
||||||
"Pokemon", "void AddVolatile(const constString &in name) const",
|
asFUNCTION(AddVolatileWrapper), asCALL_CDECL_OBJFIRST);
|
||||||
asMETHODPR(PkmnLib::Battling::Pokemon, AddVolatileScript, (const ArbUt::StringView&), void), asCALL_THISCALL);
|
|
||||||
Ensure(r >= 0);
|
Ensure(r >= 0);
|
||||||
r = engine->RegisterObjectMethod(
|
r = engine->RegisterObjectMethod(
|
||||||
"Pokemon", "void RemoveVolatile(const constString &in name) const",
|
"Pokemon", "void RemoveVolatile(const constString &in name) const",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "../TestLibrary/TestLibrary.hpp"
|
#include "../TestLibrary/TestLibrary.hpp"
|
||||||
|
|
||||||
#define AS_CLASS(name, contents) \
|
#define AS_CLASS(name, contents) \
|
||||||
{ #name, "namespace Pokemon{ [Pokemon effect=" #name "] class " #name " : PkmnScript { " contents "}}" }
|
{ #name, "namespace Pokemon{ [Pokemon effect=" #name "] shared class " #name " : PkmnScript { " contents "}}" }
|
||||||
|
|
||||||
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, ),
|
||||||
|
@ -53,8 +53,11 @@ void StopBeforeAttack(ExecutingMove@ attack, bool& result) override{
|
||||||
R"(void IsInvulnerable(ExecutingMove@ attack, Pokemon@ target, bool& result) override{ result = !result; })"),
|
R"(void IsInvulnerable(ExecutingMove@ attack, Pokemon@ target, bool& result) override{ result = !result; })"),
|
||||||
|
|
||||||
AS_CLASS(OnAttackMissScript,
|
AS_CLASS(OnAttackMissScript,
|
||||||
"int value = 0; void OnAttackMiss(ExecutingMove@ attack, Pokemon@ target) override { value++; } "
|
R"(
|
||||||
"int GetValue() { return value; }"),
|
int value = 0;
|
||||||
|
void OnAttackMiss(ExecutingMove@ attack, Pokemon@ target) override { value++; }
|
||||||
|
int GetValue() { return value; }
|
||||||
|
)"),
|
||||||
AS_CLASS(
|
AS_CLASS(
|
||||||
ChangeAttackTypeScript,
|
ChangeAttackTypeScript,
|
||||||
R"(void ChangeAttackType(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& outType) override{outType = 1; };)"),
|
R"(void ChangeAttackType(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& outType) override{outType = 1; };)"),
|
||||||
|
@ -64,15 +67,31 @@ void StopBeforeAttack(ExecutingMove@ attack, bool& result) override{
|
||||||
AS_CLASS(
|
AS_CLASS(
|
||||||
PreventSecondaryEffectsScript,
|
PreventSecondaryEffectsScript,
|
||||||
R"(void PreventSecondaryEffects(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& result) override{ result = !result; })"),
|
R"(void PreventSecondaryEffects(ExecutingMove@ attack, Pokemon@ target, uint8 hit, bool& result) override{ result = !result; })"),
|
||||||
AS_CLASS(OnSecondaryEffectScript, "int value = 0; void OnSecondaryEffect(ExecutingMove@ attack, Pokemon@ target, "
|
AS_CLASS(OnSecondaryEffectScript, R"(
|
||||||
"uint8 hit) override { value++; } "
|
int value = 0;
|
||||||
"int GetValue() { return value; }"),
|
void OnSecondaryEffect(ExecutingMove@ attack, Pokemon@ target, uint8 hit) override {
|
||||||
|
value++;
|
||||||
|
}
|
||||||
|
int GetValue() { return value; })"),
|
||||||
AS_CLASS(OnAfterHitsScript,
|
AS_CLASS(OnAfterHitsScript,
|
||||||
"int value = 0; void OnAfterHits(ExecutingMove@ attack, Pokemon@ target) override { value++; } "
|
"int value = 0; void OnAfterHits(ExecutingMove@ attack, Pokemon@ target) override { value++; } "
|
||||||
"int GetValue() { return value; }"),
|
"int GetValue() { return value; }"),
|
||||||
AS_CLASS(throwScript,
|
AS_CLASS(throwScript,
|
||||||
R"(void PreventAttack(ExecutingMove@ attack, bool& result) override{ throw("test exception"); })"),
|
R"(void PreventAttack(ExecutingMove@ attack, bool& result) override{ throw("test exception"); })"),
|
||||||
|
|
||||||
|
AS_CLASS(AddVolatileModMain,
|
||||||
|
R"(
|
||||||
|
void OnSecondaryEffect(ExecutingMove@ attack, Pokemon@ target, uint8 hit) override {
|
||||||
|
auto script = cast<AddVolatileModSecondary>(target.AddVolatile("AddVolatileModSecondary"));
|
||||||
|
script.value++;
|
||||||
|
};
|
||||||
|
)"),
|
||||||
|
AS_CLASS(AddVolatileModSecondary,
|
||||||
|
R"(
|
||||||
|
int value = 0;
|
||||||
|
int GetValue() { return value; }
|
||||||
|
)"),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static AngelScriptResolver* _resolverCache = nullptr;
|
static AngelScriptResolver* _resolverCache = nullptr;
|
||||||
|
@ -354,4 +373,37 @@ TEST_CASE("Handle script exceptions.") {
|
||||||
throw ArbUt::Exception("Didn't throw");
|
throw ArbUt::Exception("Didn't throw");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Add Volatile with return script function") {
|
||||||
|
auto statCalc = new PkmnLib::Battling::StatCalculator();
|
||||||
|
|
||||||
|
auto resolver = dynamic_cast<AngelScriptResolver*>(PkmnLib::Battling::BattleLibrary::CreateScriptResolver());
|
||||||
|
auto mainLib = new PkmnLib::Battling::BattleLibrary(
|
||||||
|
TestLibrary::BuildStaticLibrary(), statCalc, new PkmnLib::Battling::DamageLibrary(),
|
||||||
|
new PkmnLib::Battling::ExperienceLibrary(), resolver, new PkmnLib::Battling::MiscLibrary());
|
||||||
|
resolver->Initialize(mainLib);
|
||||||
|
for (auto kv : _scripts) {
|
||||||
|
resolver->CreateScript(kv.first, kv.second);
|
||||||
|
}
|
||||||
|
resolver->FinalizeModule();
|
||||||
|
|
||||||
|
auto script = GetScript(mainLib, "AddVolatileModMain"_cnc);
|
||||||
|
auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30).Build();
|
||||||
|
|
||||||
|
script->OnSecondaryEffect(nullptr, mon, 0);
|
||||||
|
|
||||||
|
auto scriptObjOption = const_cast<CreatureLib::Battling::ScriptAggregator&>(mon->GetScriptIterator()).GetNextNotNull();
|
||||||
|
REQUIRE(scriptObjOption.has_value());
|
||||||
|
REQUIRE(scriptObjOption.value()->GetName() == "AddVolatileModSecondary"_cnc);
|
||||||
|
auto scriptObj = scriptObjOption.value();
|
||||||
|
auto script2 = scriptObj.As<AngelScriptScript>();
|
||||||
|
auto ctxPool = script2->GetContextPool();
|
||||||
|
auto ctx = ctxPool->RequestContext();
|
||||||
|
script2->PrepareMethod("GetValue"_cnc, ctx);
|
||||||
|
REQUIRE(ctx->Execute() == asEXECUTION_FINISHED);
|
||||||
|
REQUIRE(ctx->GetReturnDWord() == 1);
|
||||||
|
ctxPool->ReturnContextToPool(ctx);
|
||||||
|
|
||||||
|
delete script;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue