#include #include #include #include #include #include "../../../extern/catch.hpp" #include "../../Library.hpp" #define SETUP_MOVE_TEST(move) \ auto library = Library::GetLibrary(); \ auto userMon = \ PkmnLib::Battling::CreatePokemon(library, "charizard"_cnc, 50) \ .LearnMove(Arbutils::CaseInsensitiveConstString(#move), CreatureLib::Battling::AttackLearnMethod::Unknown) \ ->Build(); \ auto targetMon = PkmnLib::Battling::CreatePokemon(library, "venusaur"_cnc, 50).Build(); \ \ auto userParty = new CreatureLib::Battling::CreatureParty({userMon}); \ auto targetParty = new CreatureLib::Battling::CreatureParty({targetMon}); \ auto battle = new PkmnLib::Battling::Battle( \ library, { \ CreatureLib::Battling::BattleParty(userParty, {CreatureLib::Battling::CreatureIndex(0, 0)}), \ CreatureLib::Battling::BattleParty(targetParty, {CreatureLib::Battling::CreatureIndex(1, 0)}), \ }); \ \ userMon->SetBattleData(battle, battle->GetSides()[0]); \ targetMon->SetBattleData(battle, battle->GetSides()[1]); \ \ auto script = library->LoadScript(ScriptCategory::Attack, #move); \ REQUIRE(script != nullptr); \ \ auto executingMove = \ new CreatureLib::Battling::ExecutingAttack({targetMon}, 1, userMon, userMon->GetMoves()[0], script); #define CLEANUP_MOVE_TEST \ delete executingMove; \ delete targetParty; \ delete userParty; \ delete battle; #define ON_MOVE_EFFECT_TRIGGER(move, onAfterCheck) \ TEST_CASE(#move " - On Effect Trigger", "[moves]") { \ SETUP_MOVE_TEST(move) \ \ battle->AddVolatileScript("TriggerEffectChance"); \ script->OnSecondaryEffect(executingMove, targetMon, 0); \ onAfterCheck; \ \ CLEANUP_MOVE_TEST \ } #define ON_MOVE_EFFECT_NO_TRIGGER(move, onAfterCheck) \ TEST_CASE(#move " - On Effect No Trigger", "[moves]") { \ SETUP_MOVE_TEST(move) \ \ battle->AddVolatileScript("BlockEffectChance"); \ script->OnSecondaryEffect(executingMove, targetMon, 0); \ onAfterCheck; \ \ CLEANUP_MOVE_TEST \ } #define MOVE_EFFECT_CHANCE(move, chance) \ TEST_CASE(#move " - Effect Chance = " #chance, "[moves]") { \ SETUP_MOVE_TEST(move) \ \ battle->AddVolatileScript("SaveEffectChance"); \ script->OnSecondaryEffect(executingMove, targetMon, 0); \ \ auto saveScript = dynamic_cast(battle->GetVolatileScript("SaveEffectChance")); \ \ auto ctx = saveScript->GetContextPool()->RequestContext(); \ saveScript->PrepareMethod("GetChance", ctx); \ ctx->Execute(); \ auto result = ctx->GetReturnFloat(); \ CHECK(result == Approx(chance)); \ saveScript->GetContextPool()->ReturnContextToPool(ctx); \ \ CLEANUP_MOVE_TEST \ } #define CHANCE_BASED_MOVE(moveName, chance, onEffectCheck, onNoEffectCheck) \ ON_MOVE_EFFECT_TRIGGER(moveName, onEffectCheck) \ ON_MOVE_EFFECT_NO_TRIGGER(moveName, onNoEffectCheck) \ MOVE_EFFECT_CHANCE(moveName, chance) #define INCREASED_CRITICAL_RATE(moveName, expectedStage) \ TEST_CASE(#moveName " - Increased critical ratio", "[moves]") { \ SETUP_MOVE_TEST(moveName) \ \ auto pkmnScript = dynamic_cast(script); \ uint8_t critStage = 0; \ pkmnScript->ModifyCriticalStage(executingMove, userMon, 0, &critStage); \ CHECK(critStage == expectedStage); \ \ CLEANUP_MOVE_TEST \ } #define CHANGE_USER_STAT_MOVE(moveName, stat, stage, function) \ TEST_CASE(#moveName " - Change " #stat " by " #stage, "[moves]") { \ SETUP_MOVE_TEST(moveName) \ \ CHECK(userMon->GetStatBoost(PkmnLib::Library::Statistic::stat) == 0); \ script->function(executingMove, userMon, 0); \ CHECK(userMon->GetStatBoost(PkmnLib::Library::Statistic::stat) == stage); \ \ CLEANUP_MOVE_TEST \ } #define CHANGE_TARGET_STAT_MOVE(moveName, stat, stage, function) \ TEST_CASE(#moveName " - Change " #stat " by " #stage, "[moves]") { \ SETUP_MOVE_TEST(moveName) \ \ CHECK(targetMon->GetStatBoost(PkmnLib::Library::Statistic::stat) == 0); \ script->function(executingMove, targetMon, 0); \ CHECK(targetMon->GetStatBoost(PkmnLib::Library::Statistic::stat) == stage); \ \ CLEANUP_MOVE_TEST \ }