PkmnLib/tests/ScriptTests/Angelscript/ScriptTypeTests/Battle/PokemonTests.cpp

369 lines
15 KiB
C++

#if TESTS_BUILD and ANGELSCRIPT
#include <doctest.h>
#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<const char*, const char*> _scripts =
std::unordered_map<const char*, const char*>{{"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<AngelScriptResolver*>(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<AngelScriptScript*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(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<PkmnLib::Battling::Pokemon*>(mon));
REQUIRE(data.Context->Execute() == asEXECUTION_FINISHED);
REQUIRE(mon->HasHeldItem("testItem"_cnc));
delete mon;
}
#endif