Implements running from battle.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
0fad615050
commit
6ba708ad12
|
@ -44,9 +44,9 @@ void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) {
|
||||||
case TurnChoiceKind::Pass: throw NotReachableException();
|
case TurnChoiceKind::Pass: throw NotReachableException();
|
||||||
case TurnChoiceKind::Attack: return ExecuteAttackChoice(dynamic_cast<AttackTurnChoice*>(choice));
|
case TurnChoiceKind::Attack: return ExecuteAttackChoice(dynamic_cast<AttackTurnChoice*>(choice));
|
||||||
case TurnChoiceKind::Switch: return ExecuteSwitchChoice(dynamic_cast<SwitchTurnChoice*>(choice));
|
case TurnChoiceKind::Switch: return ExecuteSwitchChoice(dynamic_cast<SwitchTurnChoice*>(choice));
|
||||||
|
case TurnChoiceKind::Flee: return ExecuteFleeChoice(dynamic_cast<FleeTurnChoice*>(choice));
|
||||||
|
|
||||||
case TurnChoiceKind::Item:
|
case TurnChoiceKind::Item: throw NotImplementedException();
|
||||||
case TurnChoiceKind::RunAway: throw NotImplementedException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe
|
||||||
auto hitType = hit->GetType();
|
auto hitType = hit->GetType();
|
||||||
HOOK(ChangeAttackType, targetSource, attack, target, hitIndex, hitType);
|
HOOK(ChangeAttackType, targetSource, attack, target, hitIndex, hitType);
|
||||||
hit->SetEffectiveness(library->GetTypeLibrary()->GetEffectiveness(hitType, target->GetTypes()));
|
hit->SetEffectiveness(library->GetTypeLibrary()->GetEffectiveness(hitType, target->GetTypes()));
|
||||||
hit->SetCritical(library->GetCriticalLibrary()->IsCritical(attack, target, hitIndex));
|
hit->SetCritical(library->GetMiscLibrary()->IsCritical(attack, target, hitIndex));
|
||||||
hit->SetBasePower(dmgLibrary->GetBasePower(attack, target, hitIndex));
|
hit->SetBasePower(dmgLibrary->GetBasePower(attack, target, hitIndex));
|
||||||
hit->SetDamage(dmgLibrary->GetDamage(attack, target, hitIndex));
|
hit->SetDamage(dmgLibrary->GetDamage(attack, target, hitIndex));
|
||||||
|
|
||||||
|
@ -180,4 +180,18 @@ void TurnHandler::ExecuteSwitchChoice(CreatureLib::Battling::SwitchTurnChoice* c
|
||||||
auto userSide = user->GetBattleSide();
|
auto userSide = user->GetBattleSide();
|
||||||
auto userIndex = userSide->GetCreatureIndex(user);
|
auto userIndex = userSide->GetCreatureIndex(user);
|
||||||
userSide->SetCreature(choice->GetNewCreature(), userIndex);
|
userSide->SetCreature(choice->GetNewCreature(), userIndex);
|
||||||
}
|
}
|
||||||
|
void TurnHandler::ExecuteFleeChoice(FleeTurnChoice* choice) {
|
||||||
|
auto user = choice->GetUser();
|
||||||
|
auto battle = user->GetBattle();
|
||||||
|
if (!battle->CanFlee()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: If any of the creatures on the users side has a script that prevents it from running, block.
|
||||||
|
// TODO: If any of the creatures on any other side has a script that prevents this side from running, block.
|
||||||
|
|
||||||
|
if (battle->GetLibrary()->GetMiscLibrary()->CanFlee(choice)) {
|
||||||
|
user->GetBattleSide()->MarkAsFled();
|
||||||
|
battle->ValidateBattleState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "../Models/ExecutingAttack.hpp"
|
#include "../Models/ExecutingAttack.hpp"
|
||||||
#include "../TurnChoices/AttackTurnChoice.hpp"
|
#include "../TurnChoices/AttackTurnChoice.hpp"
|
||||||
|
#include "../TurnChoices/FleeTurnChoice.hpp"
|
||||||
#include "../TurnChoices/SwitchTurnChoice.hpp"
|
#include "../TurnChoices/SwitchTurnChoice.hpp"
|
||||||
#include "ChoiceQueue.hpp"
|
#include "ChoiceQueue.hpp"
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@ namespace CreatureLib::Battling {
|
||||||
ExecutingAttack::TargetData* targetData);
|
ExecutingAttack::TargetData* targetData);
|
||||||
|
|
||||||
static void ExecuteSwitchChoice(SwitchTurnChoice* choice);
|
static void ExecuteSwitchChoice(SwitchTurnChoice* choice);
|
||||||
|
static void ExecuteFleeChoice(FleeTurnChoice* choice);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void RunTurn(Battle* battle, ChoiceQueue* queue);
|
static void RunTurn(Battle* battle, ChoiceQueue* queue);
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
using namespace CreatureLib::Battling;
|
using namespace CreatureLib::Battling;
|
||||||
|
|
||||||
BattleLibrary::BattleLibrary(CreatureLib::Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
|
BattleLibrary::BattleLibrary(CreatureLib::Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
|
||||||
DamageLibrary* damageLibrary, CriticalLibrary* criticalLibrary,
|
DamageLibrary* damageLibrary, ExperienceLibrary* experienceLibrary,
|
||||||
ExperienceLibrary* experienceLibrary, ScriptResolver* scriptResolver)
|
ScriptResolver* scriptResolver, MiscLibrary* miscLibrary)
|
||||||
: _staticLib(staticLib), _statCalculator(statCalculator), _damageLibrary(damageLibrary),
|
: _staticLib(staticLib), _statCalculator(statCalculator), _damageLibrary(damageLibrary),
|
||||||
_criticalLibrary(criticalLibrary), _experienceLibrary(experienceLibrary), _scriptResolver(scriptResolver) {}
|
_experienceLibrary(experienceLibrary), _scriptResolver(scriptResolver), _miscLibrary(miscLibrary) {}
|
||||||
|
|
||||||
BattleLibrary::~BattleLibrary() {
|
BattleLibrary::~BattleLibrary() {
|
||||||
delete _staticLib;
|
delete _staticLib;
|
||||||
delete _statCalculator;
|
delete _statCalculator;
|
||||||
delete _damageLibrary;
|
delete _damageLibrary;
|
||||||
delete _criticalLibrary;
|
|
||||||
delete _experienceLibrary;
|
delete _experienceLibrary;
|
||||||
delete _scriptResolver;
|
delete _scriptResolver;
|
||||||
|
delete _miscLibrary;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreatureLib::Library::LibrarySettings& BattleLibrary::GetSettings() const { return _staticLib->GetSettings(); }
|
const CreatureLib::Library::LibrarySettings& BattleLibrary::GetSettings() const { return _staticLib->GetSettings(); }
|
||||||
|
@ -36,7 +36,7 @@ const CreatureLib::Library::TypeLibrary* BattleLibrary::GetTypeLibrary() const {
|
||||||
|
|
||||||
const DamageLibrary* BattleLibrary::GetDamageLibrary() const { return _damageLibrary; }
|
const DamageLibrary* BattleLibrary::GetDamageLibrary() const { return _damageLibrary; }
|
||||||
|
|
||||||
const CriticalLibrary* BattleLibrary::GetCriticalLibrary() const { return _criticalLibrary; }
|
const MiscLibrary* BattleLibrary::GetMiscLibrary() const { return _miscLibrary; }
|
||||||
|
|
||||||
Script* BattleLibrary::LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const {
|
Script* BattleLibrary::LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const {
|
||||||
return _scriptResolver->LoadScript(category, scriptName);
|
return _scriptResolver->LoadScript(category, scriptName);
|
||||||
|
|
|
@ -4,23 +4,23 @@
|
||||||
#include "../../Library/DataLibrary.hpp"
|
#include "../../Library/DataLibrary.hpp"
|
||||||
#include "../ScriptHandling/ScriptResolver.hpp"
|
#include "../ScriptHandling/ScriptResolver.hpp"
|
||||||
#include "BattleStatCalculator.hpp"
|
#include "BattleStatCalculator.hpp"
|
||||||
#include "CriticalLibrary.hpp"
|
|
||||||
#include "DamageLibrary.hpp"
|
#include "DamageLibrary.hpp"
|
||||||
#include "ExperienceLibrary.hpp"
|
#include "ExperienceLibrary.hpp"
|
||||||
|
#include "MiscLibrary.hpp"
|
||||||
|
|
||||||
namespace CreatureLib::Battling {
|
namespace CreatureLib::Battling {
|
||||||
class BattleLibrary {
|
class BattleLibrary {
|
||||||
const Library::DataLibrary* _staticLib = nullptr;
|
const Library::DataLibrary* _staticLib = nullptr;
|
||||||
BattleStatCalculator* _statCalculator = nullptr;
|
BattleStatCalculator* _statCalculator = nullptr;
|
||||||
DamageLibrary* _damageLibrary = nullptr;
|
DamageLibrary* _damageLibrary = nullptr;
|
||||||
CriticalLibrary* _criticalLibrary = nullptr;
|
|
||||||
ExperienceLibrary* _experienceLibrary = nullptr;
|
ExperienceLibrary* _experienceLibrary = nullptr;
|
||||||
ScriptResolver* _scriptResolver = nullptr;
|
ScriptResolver* _scriptResolver = nullptr;
|
||||||
|
MiscLibrary* _miscLibrary = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BattleLibrary(Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
|
BattleLibrary(Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
|
||||||
DamageLibrary* damageLibrary, CriticalLibrary* criticalLibrary,
|
DamageLibrary* damageLibrary, ExperienceLibrary* experienceLibrary,
|
||||||
ExperienceLibrary* experienceLibrary, ScriptResolver* scriptResolver);
|
ScriptResolver* scriptResolver, MiscLibrary* miscLibrary);
|
||||||
~BattleLibrary();
|
~BattleLibrary();
|
||||||
|
|
||||||
[[nodiscard]] const Library::LibrarySettings& GetSettings() const;
|
[[nodiscard]] const Library::LibrarySettings& GetSettings() const;
|
||||||
|
@ -34,7 +34,7 @@ namespace CreatureLib::Battling {
|
||||||
|
|
||||||
[[nodiscard]] const BattleStatCalculator* GetStatCalculator() const;
|
[[nodiscard]] const BattleStatCalculator* GetStatCalculator() const;
|
||||||
[[nodiscard]] const DamageLibrary* GetDamageLibrary() const;
|
[[nodiscard]] const DamageLibrary* GetDamageLibrary() const;
|
||||||
[[nodiscard]] const CriticalLibrary* GetCriticalLibrary() const;
|
[[nodiscard]] const MiscLibrary* GetMiscLibrary() const;
|
||||||
[[nodiscard]] const ExperienceLibrary* GetExperienceLibrary() const { return _experienceLibrary; }
|
[[nodiscard]] const ExperienceLibrary* GetExperienceLibrary() const { return _experienceLibrary; }
|
||||||
|
|
||||||
[[nodiscard]] Script* LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const;
|
[[nodiscard]] Script* LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#include "CriticalLibrary.hpp"
|
|
||||||
#include "../Models/Battle.hpp"
|
|
||||||
|
|
||||||
bool CreatureLib::Battling::CriticalLibrary::IsCritical(CreatureLib::Battling::ExecutingAttack* attack,
|
|
||||||
CreatureLib::Battling::Creature* target, uint8_t hit) const {
|
|
||||||
auto rand = target->GetBattle()->GetRandom();
|
|
||||||
// HOOK: Increase chance for critical hits.
|
|
||||||
return rand.Get(10) <= 0;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef CREATURELIB_CRITICALLIBRARY_HPP
|
|
||||||
#define CREATURELIB_CRITICALLIBRARY_HPP
|
|
||||||
|
|
||||||
#include "../Models/ExecutingAttack.hpp"
|
|
||||||
|
|
||||||
namespace CreatureLib::Battling {
|
|
||||||
class CriticalLibrary {
|
|
||||||
public:
|
|
||||||
virtual ~CriticalLibrary() = default;
|
|
||||||
virtual bool IsCritical(ExecutingAttack* attack, Creature* target, uint8_t hit) const;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CREATURELIB_CRITICALLIBRARY_HPP
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "MiscLibrary.hpp"
|
||||||
|
#include "../Models/Battle.hpp"
|
||||||
|
|
||||||
|
bool CreatureLib::Battling::MiscLibrary::IsCritical(CreatureLib::Battling::ExecutingAttack* attack,
|
||||||
|
CreatureLib::Battling::Creature* target, uint8_t hit) const {
|
||||||
|
auto rand = target->GetBattle()->GetRandom();
|
||||||
|
// HOOK: Increase chance for critical hits.
|
||||||
|
return rand.Get(10) <= 0;
|
||||||
|
}
|
||||||
|
bool CreatureLib::Battling::MiscLibrary::CanFlee(FleeTurnChoice* switchChoice) const { return true; }
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef CREATURELIB_MISCLIBRARY_HPP
|
||||||
|
#define CREATURELIB_MISCLIBRARY_HPP
|
||||||
|
|
||||||
|
#include "../Models/ExecutingAttack.hpp"
|
||||||
|
#include "../TurnChoices/FleeTurnChoice.hpp"
|
||||||
|
|
||||||
|
namespace CreatureLib::Battling {
|
||||||
|
class MiscLibrary {
|
||||||
|
public:
|
||||||
|
virtual ~MiscLibrary() = default;
|
||||||
|
virtual bool IsCritical(ExecutingAttack* attack, Creature* target, uint8_t hit) const;
|
||||||
|
virtual bool CanFlee(FleeTurnChoice* switchChoice) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CREATURELIB_MISCLIBRARY_HPP
|
|
@ -100,17 +100,22 @@ bool Battle::CanSlotBeFilled(uint8_t side, uint8_t index) const {
|
||||||
|
|
||||||
void Battle::ValidateBattleState() {
|
void Battle::ValidateBattleState() {
|
||||||
bool survivingSideExists = false;
|
bool survivingSideExists = false;
|
||||||
uint8_t result = 0;
|
uint8_t winningSide = 0;
|
||||||
for (uint8_t i = 0; i < _sides.size(); i++){
|
for (uint8_t i = 0; i < _sides.size(); i++) {
|
||||||
auto side = _sides[i];
|
auto side = _sides[i];
|
||||||
if (!side->IsDefeated()){
|
if (side->HasFled()) {
|
||||||
if (survivingSideExists){
|
this->_battleResult = BattleResult::Inconclusive();
|
||||||
|
this->_hasEnded = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!side->IsDefeated()) {
|
||||||
|
if (survivingSideExists) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
survivingSideExists = true;
|
survivingSideExists = true;
|
||||||
result = i;
|
winningSide = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->_battleResult = result;
|
this->_battleResult = BattleResult::Conclusive(winningSide);
|
||||||
this->_hasEnded = true;
|
this->_hasEnded = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../Library/BattleLibrary.hpp"
|
#include "../Library/BattleLibrary.hpp"
|
||||||
#include "../TurnChoices/BaseTurnChoice.hpp"
|
#include "../TurnChoices/BaseTurnChoice.hpp"
|
||||||
#include "BattleParty.hpp"
|
#include "BattleParty.hpp"
|
||||||
|
#include "BattleResult.hpp"
|
||||||
#include "BattleSide.hpp"
|
#include "BattleSide.hpp"
|
||||||
#include "CreatureIndex.hpp"
|
#include "CreatureIndex.hpp"
|
||||||
|
|
||||||
|
@ -13,20 +14,22 @@ namespace CreatureLib::Battling {
|
||||||
class Battle : public ScriptSource {
|
class Battle : public ScriptSource {
|
||||||
const BattleLibrary* _library;
|
const BattleLibrary* _library;
|
||||||
std::vector<BattleParty> _parties;
|
std::vector<BattleParty> _parties;
|
||||||
|
bool _canFlee;
|
||||||
uint8_t _numberOfSides;
|
uint8_t _numberOfSides;
|
||||||
uint8_t _creaturesPerSide;
|
uint8_t _creaturesPerSide;
|
||||||
std::vector<BattleSide*> _sides;
|
std::vector<BattleSide*> _sides;
|
||||||
Core::Random _random;
|
Core::Random _random;
|
||||||
ChoiceQueue* _currentTurnQueue = nullptr;
|
ChoiceQueue* _currentTurnQueue = nullptr;
|
||||||
bool _hasEnded = false;
|
bool _hasEnded = false;
|
||||||
uint8_t _battleResult = 0;
|
BattleResult _battleResult = BattleResult::Empty();
|
||||||
|
|
||||||
ScriptSet _volatile;
|
ScriptSet _volatile;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Battle(const BattleLibrary* library, std::vector<BattleParty> parties, uint8_t numberOfSides = 2,
|
Battle(const BattleLibrary* library, std::vector<BattleParty> parties, bool canFlee = true,
|
||||||
uint8_t creaturesPerSide = 1)
|
uint8_t numberOfSides = 2, uint8_t creaturesPerSide = 1)
|
||||||
: _library(library), _parties(parties), _numberOfSides(numberOfSides), _creaturesPerSide(creaturesPerSide) {
|
: _library(library), _parties(parties), _canFlee(canFlee), _numberOfSides(numberOfSides),
|
||||||
|
_creaturesPerSide(creaturesPerSide) {
|
||||||
_sides = std::vector<BattleSide*>(numberOfSides);
|
_sides = std::vector<BattleSide*>(numberOfSides);
|
||||||
for (size_t i = 0; i < numberOfSides; i++) {
|
for (size_t i = 0; i < numberOfSides; i++) {
|
||||||
_sides[i] = new BattleSide(i, this, creaturesPerSide);
|
_sides[i] = new BattleSide(i, this, creaturesPerSide);
|
||||||
|
@ -44,6 +47,8 @@ namespace CreatureLib::Battling {
|
||||||
virtual bool CanUse(const BaseTurnChoice* choice);
|
virtual bool CanUse(const BaseTurnChoice* choice);
|
||||||
virtual bool TrySetChoice(BaseTurnChoice* choice);
|
virtual bool TrySetChoice(BaseTurnChoice* choice);
|
||||||
|
|
||||||
|
bool CanFlee() const { return _canFlee; }
|
||||||
|
|
||||||
void CheckChoicesSetAndRun();
|
void CheckChoicesSetAndRun();
|
||||||
|
|
||||||
[[nodiscard]] ChoiceQueue* GetCurrentTurnQueue() const;
|
[[nodiscard]] ChoiceQueue* GetCurrentTurnQueue() const;
|
||||||
|
@ -63,7 +68,7 @@ namespace CreatureLib::Battling {
|
||||||
|
|
||||||
void ValidateBattleState();
|
void ValidateBattleState();
|
||||||
inline bool HasEnded() const { return _hasEnded; }
|
inline bool HasEnded() const { return _hasEnded; }
|
||||||
inline uint8_t GetResult() const { return _battleResult; }
|
inline const BattleResult& GetResult() const { return _battleResult; }
|
||||||
|
|
||||||
const std::vector<BattleSide*>& GetSides() const { return _sides; }
|
const std::vector<BattleSide*>& GetSides() const { return _sides; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef CREATURELIB_BATTLERESULT_HPP
|
||||||
|
#define CREATURELIB_BATTLERESULT_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
namespace CreatureLib::Battling {
|
||||||
|
class BattleResult {
|
||||||
|
bool _conclusiveResult;
|
||||||
|
uint8_t _winningSide;
|
||||||
|
|
||||||
|
BattleResult(bool conclusiveResult, uint8_t winningSide)
|
||||||
|
: _conclusiveResult(conclusiveResult), _winningSide(winningSide) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static BattleResult Inconclusive() { return BattleResult(false, 0); }
|
||||||
|
static BattleResult Conclusive(uint8_t winner) { return BattleResult(true, winner); }
|
||||||
|
static BattleResult Empty() { return BattleResult(false, 0); }
|
||||||
|
|
||||||
|
/// Whether or not the battle has ended with a conclusive result.
|
||||||
|
bool IsConclusiveResult() const { return _conclusiveResult; }
|
||||||
|
/// Get the index of the side that has won the battle. Only valid if the battle has a conclusive result.
|
||||||
|
uint8_t GetWinningSide() const { return _winningSide; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CREATURELIB_BATTLERESULT_HPP
|
|
@ -15,6 +15,7 @@ namespace CreatureLib::Battling {
|
||||||
uint8_t _choicesSet = 0;
|
uint8_t _choicesSet = 0;
|
||||||
ScriptSet _volatile;
|
ScriptSet _volatile;
|
||||||
Battle* _battle;
|
Battle* _battle;
|
||||||
|
bool _hasFled = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BattleSide(uint8_t index, Battle* battle, uint8_t creaturesPerSide)
|
explicit BattleSide(uint8_t index, Battle* battle, uint8_t creaturesPerSide)
|
||||||
|
@ -74,6 +75,10 @@ namespace CreatureLib::Battling {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasFled() { return _hasFled; }
|
||||||
|
|
||||||
|
void MarkAsFled() { _hasFled = true; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef CREATURELIB_FLEETURNCHOICE_HPP
|
||||||
|
#define CREATURELIB_FLEETURNCHOICE_HPP
|
||||||
|
|
||||||
|
#include "../Models/Creature.hpp"
|
||||||
|
#include "BaseTurnChoice.hpp"
|
||||||
|
|
||||||
|
namespace CreatureLib::Battling {
|
||||||
|
class FleeTurnChoice : public BaseTurnChoice {
|
||||||
|
public:
|
||||||
|
FleeTurnChoice(Creature* user) : BaseTurnChoice(user) {}
|
||||||
|
|
||||||
|
TurnChoiceKind GetKind() const override { return TurnChoiceKind ::Flee; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override { GetUser()->GetActiveScripts(scripts); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CREATURELIB_FLEETURNCHOICE_HPP
|
|
@ -4,6 +4,6 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace CreatureLib::Battling {
|
namespace CreatureLib::Battling {
|
||||||
enum class TurnChoiceKind : uint8_t { Pass, Attack, Item, Switch, RunAway };
|
enum class TurnChoiceKind : uint8_t { Pass, Attack, Item, Switch, Flee };
|
||||||
}
|
}
|
||||||
#endif // CREATURELIB_TURNCHOICEKIND_HPP
|
#endif // CREATURELIB_TURNCHOICEKIND_HPP
|
||||||
|
|
|
@ -79,7 +79,9 @@ TEST_CASE("Finish battle when all battle of one side have fainted", "[Integratio
|
||||||
c2->Damage(c2->GetCurrentHealth(), DamageSource::AttackDamage);
|
c2->Damage(c2->GetCurrentHealth(), DamageSource::AttackDamage);
|
||||||
|
|
||||||
REQUIRE(battle.HasEnded());
|
REQUIRE(battle.HasEnded());
|
||||||
REQUIRE(battle.GetResult() == 0);
|
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", "[Integrations]") {
|
TEST_CASE("When creature is dealt enough damage, faint it and mark battle as ended", "[Integrations]") {
|
||||||
|
@ -104,7 +106,9 @@ TEST_CASE("When creature is dealt enough damage, faint it and mark battle as end
|
||||||
battle.TrySetChoice(new PassTurnChoice(c2));
|
battle.TrySetChoice(new PassTurnChoice(c2));
|
||||||
|
|
||||||
REQUIRE(battle.HasEnded());
|
REQUIRE(battle.HasEnded());
|
||||||
REQUIRE(battle.GetResult() == 0);
|
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", "[Integrations]") {
|
TEST_CASE("When another creature is available on faint, make sure the battle hasn't ended", "[Integrations]") {
|
||||||
|
@ -137,7 +141,9 @@ TEST_CASE("When another creature is available on faint, make sure the battle has
|
||||||
battle.TrySetChoice(new PassTurnChoice(c3));
|
battle.TrySetChoice(new PassTurnChoice(c3));
|
||||||
|
|
||||||
REQUIRE(battle.HasEnded());
|
REQUIRE(battle.HasEnded());
|
||||||
REQUIRE(battle.GetResult() == 0);
|
auto result = battle.GetResult();
|
||||||
|
REQUIRE(result.IsConclusiveResult());
|
||||||
|
REQUIRE(result.GetWinningSide() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Switch Creature in", "[Integrations]") {
|
TEST_CASE("Switch Creature in", "[Integrations]") {
|
||||||
|
@ -221,4 +227,26 @@ TEST_CASE("Switch Creature in, mark as seen opponent for opponent", "[Integratio
|
||||||
REQUIRE(seen.find(c2) != seen.end());
|
REQUIRE(seen.find(c2) != seen.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Flee Battle", "[Integrations]") {
|
||||||
|
auto library = TestLibrary::Get();
|
||||||
|
auto c1 = CreateCreature(library, "testSpecies1", 100).WithAttack("standard", AttackLearnMethod::Unknown)->Create();
|
||||||
|
CreatureParty party1{c1};
|
||||||
|
auto battleParty1 = BattleParty(&party1, {CreatureIndex(0, 0)});
|
||||||
|
auto c2 = CreateCreature(library, "testSpecies1", 1).WithAttack("standard", AttackLearnMethod::Unknown)->Create();
|
||||||
|
CreatureParty party2{c2};
|
||||||
|
auto battleParty2 = 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());
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -13,8 +13,8 @@ BattleLibrary* TestLibrary::Get() {
|
||||||
auto l = new DataLibrary(LibrarySettings(100, 4), BuildSpeciesLibrary(), BuildAttackLibrary(),
|
auto l = new DataLibrary(LibrarySettings(100, 4), BuildSpeciesLibrary(), BuildAttackLibrary(),
|
||||||
BuildItemLibrary(), BuildGrowthRateLibrary(), BuildTypeLibrary());
|
BuildItemLibrary(), BuildGrowthRateLibrary(), BuildTypeLibrary());
|
||||||
auto statCalc = new BattleStatCalculator();
|
auto statCalc = new BattleStatCalculator();
|
||||||
auto battleLib = new BattleLibrary(l, statCalc, new DamageLibrary(), new CriticalLibrary(),
|
auto battleLib = new BattleLibrary(l, statCalc, new DamageLibrary(), new ExperienceLibrary(),
|
||||||
new ExperienceLibrary(), new ScriptResolver());
|
new ScriptResolver(), new MiscLibrary());
|
||||||
TestLibrary::_library = battleLib;
|
TestLibrary::_library = battleLib;
|
||||||
}
|
}
|
||||||
return TestLibrary::_library;
|
return TestLibrary::_library;
|
||||||
|
|
Loading…
Reference in New Issue