#ifdef TESTS_BUILD #include #include "../../src/Battling/Models/Battle.hpp" #include "../../src/Battling/Models/BattleParty.hpp" #include "../../src/Battling/Models/CreateCreature.hpp" #include "../../src/Battling/TurnChoices/AttackTurnChoice.hpp" #include "../../src/Battling/TurnChoices/PassTurnChoice.hpp" #include "../../src/Battling/TurnChoices/SwitchTurnChoice.hpp" #include "../TestLibrary/TestLibrary.hpp" using namespace CreatureLib; using namespace Battling; TEST_CASE("Create Party") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1}; auto battleParty = BattleParty(&party1, {CreatureIndex(0, 0)}); REQUIRE(battleParty.GetParty()->GetAtIndex(0) == c1); } TEST_CASE("Create Battle") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); } TEST_CASE("Use damaging move") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c2); battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0))); battle.TrySetChoice(new PassTurnChoice(c2)); REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(Statistic::Health)); } TEST_CASE("Run more turns") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); auto c3 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2, c3}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c2); battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0))); battle.TrySetChoice(new PassTurnChoice(c2)); REQUIRE(c2->IsFainted()); battle.SwitchCreature(1, 0, c3); battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0))); battle.TrySetChoice(new PassTurnChoice(c3)); } TEST_CASE("Finish battle when all battle of one side have fainted") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); REQUIRE_FALSE(battle.HasEnded()); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c2); REQUIRE_FALSE(battle.HasEnded()); REQUIRE(battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0)))); REQUIRE(battle.TrySetChoice(new PassTurnChoice(c2))); REQUIRE_FALSE(battle.HasEnded()); REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(Statistic::Health)); c2->Damage(c2->GetCurrentHealth(), DamageSource::AttackDamage); REQUIRE(battle.HasEnded()); auto result = battle.GetResult(); REQUIRE(result.IsConclusiveResult()); REQUIRE(result.GetWinningSide() == 0); } TEST_CASE("When creature is dealt enough damage, faint it and mark battle as ended") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) .Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); REQUIRE_FALSE(battle.HasEnded()); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c2); REQUIRE_FALSE(battle.HasEnded()); battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0))); battle.TrySetChoice(new PassTurnChoice(c2)); REQUIRE(battle.HasEnded()); auto result = battle.GetResult(); REQUIRE(result.IsConclusiveResult()); REQUIRE(result.GetWinningSide() == 0); } TEST_CASE("When another creature is available on faint, make sure the battle hasn't ended") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) .Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); auto c3 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2, c3}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); REQUIRE_FALSE(battle.HasEnded()); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c2); REQUIRE_FALSE(battle.HasEnded()); battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0))); battle.TrySetChoice(new PassTurnChoice(c2)); REQUIRE_FALSE(battle.HasEnded()); battle.SwitchCreature(1, 0, c3); battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0))); battle.TrySetChoice(new PassTurnChoice(c3)); REQUIRE(battle.HasEnded()); auto result = battle.GetResult(); REQUIRE(result.IsConclusiveResult()); REQUIRE(result.GetWinningSide() == 0); } TEST_CASE("Switch Creature in") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) .Create(); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1, c2}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c3 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c3}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c3); REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c1); battle.TrySetChoice(new SwitchTurnChoice(c1, c2)); battle.TrySetChoice(new PassTurnChoice(c3)); REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c2); } TEST_CASE("Switch Creature in with event listener") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) .Create(); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1, c2}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c3 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c3}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); std::vector events; battle.RegisterEventListener([&](const EventData* evt) mutable -> void { events.push_back(evt); }); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c3); REQUIRE(events.size() == 2); REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c1); battle.TrySetChoice(new SwitchTurnChoice(c1, c2)); battle.TrySetChoice(new PassTurnChoice(c3)); REQUIRE(battle.GetCreature(CreatureIndex(0, 0)) == c2); } TEST_CASE("Switch Creature in, but have attack aimed at it. Attack should hit new creature") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1, c2}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c3 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c3}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c3); battle.TrySetChoice(new SwitchTurnChoice(c1, c2)); battle.TrySetChoice(new AttackTurnChoice(c3, c3->GetAttacks()[0].GetValue(), CreatureIndex(0, 0))); REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(Library::Statistic::Health)); REQUIRE(c1->GetCurrentHealth() == c1->GetBoostedStat(Library::Statistic::Health)); } TEST_CASE("Switch Creature in, mark as seen opponent for opponent") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) .Create(); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1, c2}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c3 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c3}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c3); auto seen = c3->GetSeenOpponents(); REQUIRE(seen.size() == 1); REQUIRE(seen.contains(c1)); battle.TrySetChoice(new SwitchTurnChoice(c1, c2)); battle.TrySetChoice(new PassTurnChoice(c3)); seen = c3->GetSeenOpponents(); REQUIRE(seen.size() == 2); REQUIRE(seen.contains(c1)); REQUIRE(seen.contains(c2)); battle.TrySetChoice(new SwitchTurnChoice(c2, c1)); battle.TrySetChoice(new PassTurnChoice(c3)); seen = c3->GetSeenOpponents(); REQUIRE(seen.size() == 2); REQUIRE(seen.contains(c1)); REQUIRE(seen.contains(c2)); } TEST_CASE("Flee Battle") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 100) .WithAttack("standard"_cnc, AttackLearnMethod::Unknown) .Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 1).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = Battle(library, {battleParty1, battleParty2}); battle.SwitchCreature(0, 0, c1); battle.SwitchCreature(1, 0, c2); battle.TrySetChoice(new FleeTurnChoice(c1)); battle.TrySetChoice(new PassTurnChoice(c2)); REQUIRE(battle.HasEnded()); auto result = battle.GetResult(); REQUIRE_FALSE(result.IsConclusiveResult()); } TEST_CASE("Heal creature after battle") { auto library = TestLibrary::Get(); auto c1 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party1{c1}; auto battleParty1 = new BattleParty(&party1, {CreatureIndex(0, 0)}); auto c2 = CreateCreature(library, "testSpecies1"_cnc, 50).WithAttack("standard"_cnc, AttackLearnMethod::Unknown).Create(); CreatureParty party2{c2}; auto battleParty2 = new BattleParty(&party2, {CreatureIndex(1, 0)}); auto battle = new Battle(library, {battleParty1, battleParty2}); std::vector events; battle->RegisterEventListener([&](const EventData* evt) mutable -> void { events.push_back(evt); }); REQUIRE_FALSE(battle->HasEnded()); battle->SwitchCreature(0, 0, c1); battle->SwitchCreature(1, 0, c2); REQUIRE_FALSE(battle->HasEnded()); REQUIRE(battle->TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0].GetValue(), CreatureIndex(1, 0)))); REQUIRE(battle->TrySetChoice(new PassTurnChoice(c2))); REQUIRE_FALSE(battle->HasEnded()); REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(Statistic::Health)); c2->Damage(c2->GetCurrentHealth(), DamageSource::AttackDamage); REQUIRE(battle->HasEnded()); auto result = battle->GetResult(); REQUIRE(result.IsConclusiveResult()); REQUIRE(result.GetWinningSide() == 0); delete battle; c2->Heal(1000, true); REQUIRE(c2->GetCurrentHealth() == c2->GetMaxHealth()); } #endif