#if TESTS_BUILD and ANGELSCRIPT #include #include "../../../../TestLibrary/TestLibrary.hpp" #include "../../../../src/Battling/Pokemon/CreatePokemon.hpp" #include "../../../../src/ScriptResolving/AngelScript/AngelScriptResolver.hpp" #include "../../../../src/ScriptResolving/AngelScript/ContextPool.hpp" static std::unordered_map _scripts = std::unordered_map{{"testScript1", R"( namespace Pokemon{ [Pokemon effect=testScript1] class testScript1 : PkmnScript { bool testSpecies(Pokemon@ p, const Species@ species){ return p.Species is species; } bool testForme(Pokemon@ p, const Forme@ forme){ return p.Forme is forme; } bool testLevel(Pokemon@ p, uint8 level){ return p.Level == level; } bool testExperience(Pokemon@ p, uint experience){ return p.Experience == experience; } bool testGender(Pokemon@ p, Gender gender){ return p.Gender == gender; } bool testShiny(Pokemon@ p, bool shiny){ return p.Shiny == shiny; } bool testHeldItem(Pokemon@ p, Item@ item){ return p.HeldItem is item; } bool testCurrentHealth(Pokemon@ p, uint health){ return p.CurrentHealth == health; } bool testNickname(Pokemon@ p, const string& name){ return p.Nickname == name; } bool testActiveAbility(Pokemon@ p, const constString &in ability){ return p.ActiveAbility == ability; } bool testIsFainted(Pokemon@ p, bool b){ return p.IsFainted == b; } bool testHasType(Pokemon@ p, uint8 type){ return p.HasType(type); } void testDamage(Pokemon@ p, uint32 damage, DamageSource source){ p.Damage(damage, source); } void testHeal(Pokemon@ p, uint32 amount){ p.Heal(amount); } bool testMove(Pokemon@ p, uint index, LearnedMove@ move){ return p.Moves[index] is move; } bool testHasHeldItem(Pokemon@ p, const constString &in item){ return p.HasHeldItem(item); } void testSetHeldItem(Pokemon@ p, const constString &in item){ p.SetHeldItem(item); } void testSetHeldItem2(Pokemon@ p){ p.SetHeldItem("testItem"); } }} )"}}; struct ScriptData { AngelScriptScript* Script = nullptr; AngelScriptResolver* Resolver = nullptr; asIScriptFunction* Func = nullptr; asIScriptContext* Context = nullptr; ~ScriptData() { Script->GetContextPool()->ReturnContextToPool(Context); delete Script; } }; static AngelScriptResolver* _resolverCache = nullptr; static AngelScriptResolver* GetScriptResolver(PkmnLib::Battling::BattleLibrary* mainLib) { if (_resolverCache == nullptr) { _resolverCache = dynamic_cast(PkmnLib::Battling::BattleLibrary::CreateScriptResolver()); _resolverCache->Initialize(mainLib); _resolverCache->CreateScript("testScript1", _scripts["testScript1"]); _resolverCache->FinalizeModule(); } return _resolverCache; } static ScriptData GetScript(PkmnLib::Battling::BattleLibrary* mainLib, const ArbUt::StringView& funcName) { auto lib = GetScriptResolver(mainLib); auto s = lib->LoadScript(nullptr, ScriptCategory::Creature, "testScript1"_cnc).TakeOwnership(); auto script = dynamic_cast(s); REQUIRE(script != nullptr); auto ctxPool = script->GetContextPool(); auto ctx = ctxPool->RequestContext(); auto func = script->PrepareMethod(funcName, ctx); REQUIRE(func != nullptr); return {.Script = script, .Resolver = lib, .Func = func, .Context = ctx}; } TEST_CASE("Validate Pokemon Species in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testSpecies"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30).Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgObject(1, (void*)mon->GetSpecies().GetRaw()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Forme in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testForme"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30).WithForme("default"_cnc).Build(); data.Context->SetArgObject(0, (void*)mon); data.Context->SetArgObject(1, (void*)mon->GetForme().GetRaw()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Level in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testLevel"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30).WithForme("default"_cnc).Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgByte(1, mon->GetLevel()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Experience in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testExperience"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30).WithForme("default"_cnc).Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgDWord(1, mon->GetExperience()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Gender in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testGender"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgDWord(1, (int)mon->GetGender()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Shininess in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testShiny"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgByte(1, mon->IsShiny()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon HeldItem in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testHeldItem"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithHeldItem("testItem"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgObject(1, (void*)mon->GetHeldItem().GetValue()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon CurrentHealth in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testCurrentHealth"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgDWord(1, mon->GetCurrentHealth()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Nickname in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testNickname"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .WithNickname("foobar") .Build(); data.Context->SetArgObject(0, (void*)mon); auto name = std::string(mon->GetNickname().value()); data.Context->SetArgAddress(1, &name); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon Active Ability in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testActiveAbility"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); data.Context->SetArgObject(0, (void*)mon); auto name = mon->GetActiveTalent()->GetName(); data.Context->SetArgAddress(1, &name); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon IsFainted in Script") { auto mainLib = TestLibrary::GetLibrary(); auto data = GetScript(mainLib, "testIsFainted"_cnc); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgByte(1, mon->IsFainted()); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); delete mon; } TEST_CASE("Validate Pokemon HasType in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); for (auto t : mon->GetTypes()) { auto data = GetScript(mainLib, "testHasType"_cnc); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgByte(1, t); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); } delete mon; } TEST_CASE("Validate Pokemon Damage in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); auto data = GetScript(mainLib, "testDamage"_cnc); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgDWord(1, 30); data.Context->SetArgDWord(2, (asDWORD)CreatureLib::Battling::DamageSource::AttackDamage); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE(mon->GetCurrentHealth() == mon->GetBoostedStat(PkmnLib::Library::Statistic::HealthPoints) - 30); delete mon; } TEST_CASE("Validate Pokemon Heal in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30) .WithForme("default"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .Build(); mon->Damage(50, CreatureLib::Battling::DamageSource::AttackDamage); auto data = GetScript(mainLib, "testHeal"_cnc); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgDWord(1, 30); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE(mon->GetCurrentHealth() == mon->GetBoostedStat(PkmnLib::Library::Statistic::HealthPoints) - 20); delete mon; } TEST_CASE("Validate Pokemon GetMoves in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30) .WithForme("default"_cnc) .LearnMove("testMove"_cnc, CreatureLib::Battling::AttackLearnMethod::Level) .LearnMove("testMove2"_cnc, CreatureLib::Battling::AttackLearnMethod::Unknown) .Build(); for (size_t i = 0; i < mon->GetMoves().Count(); i++) { auto data = GetScript(mainLib, "testMove"_cnc); data.Context->SetArgObject(0, const_cast(mon)); data.Context->SetArgDWord(1, i); data.Context->SetArgObject(2, (void*)mon->GetMoves()[i]); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnWord()); } delete mon; } TEST_CASE("Validate Pokemon HasHeldItem in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30) .WithForme("default"_cnc) .WithHeldItem("testItem"_cnc) .Build(); auto data = GetScript(mainLib, "testHasHeldItem"_cnc); data.Context->SetArgObject(0, const_cast(mon)); ArbUt::StringView item = "testItem"_cnc; data.Context->SetArgAddress(1, &item); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE((bool)data.Context->GetReturnDWord()); delete mon; } TEST_CASE("Test Pokemon SetHeldItem in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30).WithForme("default"_cnc).Build(); auto data = GetScript(mainLib, "testSetHeldItem"_cnc); data.Context->SetArgObject(0, const_cast(mon)); ArbUt::StringView item = "testItem"_cnc; data.Context->SetArgAddress(1, &item); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE(mon->HasHeldItem("testItem"_cnc)); delete mon; } TEST_CASE("Test Pokemon SetHeldItem2 in Script") { auto mainLib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(mainLib, "testSpecies3"_cnc, 30).WithForme("default"_cnc).Build(); auto data = GetScript(mainLib, "testSetHeldItem2"_cnc); data.Context->SetArgObject(0, const_cast(mon)); REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED); REQUIRE(mon->HasHeldItem("testItem"_cnc)); delete mon; } #endif