CreatureLib/tests/Integration/BattleIntegrations.cpp

376 lines
15 KiB
C++

#ifdef TESTS_BUILD
#include "../../extern/doctest.hpp"
#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<const EventData*> 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<const EventData*> 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