More defensive programming.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
Signed-off-by: Deukhoofd <Deukhoofd@gmail.com>
This commit is contained in:
parent
32f75f4a47
commit
3233daf9ab
|
@ -8,20 +8,27 @@ using namespace Battling;
|
|||
|
||||
class ChoiceCompare {
|
||||
public:
|
||||
explicit ChoiceCompare() {}
|
||||
bool operator()(const std::shared_ptr<BaseTurnChoice>& a, const std::shared_ptr<BaseTurnChoice>& b) {
|
||||
auto aKind = a->GetKind();
|
||||
auto bKind = b->GetKind();
|
||||
if (aKind != bKind)
|
||||
return aKind > bKind;
|
||||
if (aKind == TurnChoiceKind::Attack) {
|
||||
auto aPriority = dynamic_cast<const AttackTurnChoice*>(a.get())->GetPriority();
|
||||
auto bPriority = dynamic_cast<const AttackTurnChoice*>(b.get())->GetPriority();
|
||||
auto aAttack = std::dynamic_pointer_cast<AttackTurnChoice>(a);
|
||||
auto bAttack = std::dynamic_pointer_cast<AttackTurnChoice>(b);
|
||||
AssertNotNull(aAttack);
|
||||
AssertNotNull(bAttack);
|
||||
auto aPriority = aAttack->GetPriority();
|
||||
auto bPriority = bAttack->GetPriority();
|
||||
if (aPriority != bPriority)
|
||||
return aPriority > bPriority;
|
||||
}
|
||||
auto aSpeed = a->GetUser()->GetBoostedStat(Library::Statistic::Speed);
|
||||
auto bSpeed = b->GetUser()->GetBoostedStat(Library::Statistic::Speed);
|
||||
auto aUser = a->GetUser();
|
||||
auto bUser = b->GetUser();
|
||||
AssertNotNull(aUser);
|
||||
AssertNotNull(bUser);
|
||||
auto aSpeed = aUser->GetBoostedStat(Library::Statistic::Speed);
|
||||
auto bSpeed = bUser->GetBoostedStat(Library::Statistic::Speed);
|
||||
if (aSpeed != bSpeed)
|
||||
return aSpeed > bSpeed;
|
||||
|
||||
|
@ -29,13 +36,14 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void TurnOrdering::OrderChoices(std::vector<std::shared_ptr<BaseTurnChoice>>& vec,
|
||||
[[maybe_unused]] ArbUt::Random& rand) {
|
||||
for (auto item : vec) {
|
||||
void TurnOrdering::OrderChoices(std::vector<std::shared_ptr<BaseTurnChoice>>& vec) {
|
||||
for (const auto& item : vec) {
|
||||
AssertNotNull(item);
|
||||
if (item->GetKind() == TurnChoiceKind::Attack) {
|
||||
auto attackChoice = static_cast<AttackTurnChoice*>(item.get());
|
||||
auto attackChoice = std::dynamic_pointer_cast<AttackTurnChoice>(item);
|
||||
AssertNotNull(attackChoice);
|
||||
auto priority = attackChoice->GetPriority();
|
||||
HOOK(ChangePriority, attackChoice, attackChoice, &priority);
|
||||
HOOK(ChangePriority, attackChoice, attackChoice.get(), &priority);
|
||||
attackChoice->SetPriority(priority);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
namespace CreatureLib::Battling {
|
||||
class TurnOrdering {
|
||||
public:
|
||||
static void OrderChoices(std::vector<std::shared_ptr<BaseTurnChoice>>& vec, ArbUt::Random& rand);
|
||||
static void OrderChoices(std::vector<std::shared_ptr<BaseTurnChoice>>& vec);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -54,12 +54,12 @@ void Battle::CheckChoicesSetAndRun() {
|
|||
for (auto choice : side->GetChoices()) {
|
||||
AssertNotNull(choice)
|
||||
if (choice->GetKind() == TurnChoiceKind::Attack) {
|
||||
auto attack = ((AttackTurnChoice*)choice.get())->GetAttack();
|
||||
auto attack = std::static_pointer_cast<AttackTurnChoice>(choice);
|
||||
uint8_t uses = 1;
|
||||
// HOOK: change number of uses needed.
|
||||
if (attack->GetRemainingUses() < uses) {
|
||||
if (attack->GetAttack()->GetRemainingUses() < uses) {
|
||||
choice = std::shared_ptr<BaseTurnChoice>(_library->GetMiscLibrary()->ReplacementAttack(
|
||||
choice->GetUser().GetRaw(), ((AttackTurnChoice*)choice.get())->GetTarget()));
|
||||
choice->GetUser().GetRaw(), attack->GetTarget()));
|
||||
}
|
||||
// HOOK: Check if we need to change the move
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ void Battle::CheckChoicesSetAndRun() {
|
|||
}
|
||||
_currentTurn++;
|
||||
try {
|
||||
TurnOrdering::OrderChoices(choices, _random.GetRNG());
|
||||
TurnOrdering::OrderChoices(choices);
|
||||
} catch (const std::exception& e) {
|
||||
THROW("Exception during turn ordering: '" << e.what() << "'.")
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@ TEST_CASE("Turn ordering: Attack before pass", "[Battling]") {
|
|||
auto choice2 = std::make_shared<AttackTurnChoice>(nullptr, &learnedAttack, CreatureIndex(0, 0));
|
||||
auto vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice1, choice2};
|
||||
auto rand = ArbUt::Random();
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice2, choice1};
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
}
|
||||
|
@ -34,11 +34,11 @@ TEST_CASE("Turn ordering: High priority goes before no priority", "[Battling]")
|
|||
auto choice2 = std::make_shared<AttackTurnChoice>(nullptr, a2, CreatureIndex(0, 0));
|
||||
auto vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice1, choice2};
|
||||
auto rand = ArbUt::Random();
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice2, choice1};
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
|
||||
|
@ -54,11 +54,11 @@ TEST_CASE("Turn ordering: Higher priority goes before high priority", "[Battling
|
|||
auto choice2 = std::make_shared<AttackTurnChoice>(nullptr, a2, CreatureIndex(0, 0));
|
||||
auto vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice1, choice2};
|
||||
auto rand = ArbUt::Random();
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice2, choice1};
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
delete a1;
|
||||
|
@ -73,11 +73,11 @@ TEST_CASE("Turn ordering: High priority goes before low priority", "[Battling]")
|
|||
auto choice2 = std::make_shared<AttackTurnChoice>(nullptr, a2, CreatureIndex(0, 0));
|
||||
auto vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice1, choice2};
|
||||
auto rand = ArbUt::Random();
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice2, choice1};
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
|
||||
|
@ -93,11 +93,11 @@ TEST_CASE("Turn ordering: No priority goes before low priority", "[Battling]") {
|
|||
auto choice2 = std::make_shared<AttackTurnChoice>(nullptr, a2, CreatureIndex(0, 0));
|
||||
auto vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice1, choice2};
|
||||
auto rand = ArbUt::Random();
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
vec = std::vector<std::shared_ptr<BaseTurnChoice>>{choice2, choice1};
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
TurnOrdering::OrderChoices(vec);
|
||||
CHECK(vec[0] == choice2);
|
||||
CHECK(vec[1] == choice1);
|
||||
|
||||
|
|
|
@ -56,6 +56,33 @@ TEST_CASE("Use damaging move", "[Integrations]") {
|
|||
REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(Statistic::Health));
|
||||
}
|
||||
|
||||
TEST_CASE("Run more turns", "[Integrations]") {
|
||||
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], CreatureIndex(1, 0)));
|
||||
battle.TrySetChoice(new PassTurnChoice(c2));
|
||||
|
||||
REQUIRE(c2->IsFainted());
|
||||
battle.SwitchCreature(1, 0, c3);
|
||||
battle.TrySetChoice(new AttackTurnChoice(c1, c1->GetAttacks()[0], CreatureIndex(1, 0)));
|
||||
battle.TrySetChoice(new PassTurnChoice(c3));
|
||||
}
|
||||
|
||||
TEST_CASE("Finish battle when all battle of one side have fainted", "[Integrations]") {
|
||||
auto library = TestLibrary::Get();
|
||||
auto c1 =
|
||||
|
|
Loading…
Reference in New Issue