Implemented and fixed all code required to run at least a single turn.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
5d6ac316eb
commit
6f32d1245b
|
@ -10,7 +10,7 @@ void TurnHandler::RunTurn(Battle* battle, ChoiceQueue* queue) {
|
|||
HOOK(OnBeforeTurn, choice, choice);
|
||||
}
|
||||
while (queue->HasNext()) {
|
||||
if (!battle->HasRecalledSlots()) {
|
||||
if (battle->HasRecalledSlots()) {
|
||||
return;
|
||||
}
|
||||
auto item = queue->Dequeue();
|
||||
|
|
|
@ -37,7 +37,6 @@ const DamageLibrary* BattleLibrary::GetDamageLibrary() const { return _damageLib
|
|||
|
||||
const CriticalLibrary* BattleLibrary::GetCriticalLibrary() const { return _criticalLibrary; }
|
||||
|
||||
Script* BattleLibrary::LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) {
|
||||
assert(this->_scriptResolver != nullptr);
|
||||
Script* BattleLibrary::LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const {
|
||||
return _scriptResolver->LoadScript(category, scriptName);
|
||||
}
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
|
||||
namespace CreatureLib::Battling {
|
||||
class BattleLibrary {
|
||||
const Library::DataLibrary* _staticLib;
|
||||
BattleStatCalculator* _statCalculator;
|
||||
DamageLibrary* _damageLibrary;
|
||||
CriticalLibrary* _criticalLibrary;
|
||||
ScriptResolver* _scriptResolver;
|
||||
const Library::DataLibrary* _staticLib = nullptr;
|
||||
BattleStatCalculator* _statCalculator = nullptr;
|
||||
DamageLibrary* _damageLibrary = nullptr;
|
||||
CriticalLibrary* _criticalLibrary = nullptr;
|
||||
ScriptResolver* _scriptResolver = nullptr;
|
||||
|
||||
public:
|
||||
BattleLibrary(Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
|
||||
|
@ -30,7 +30,7 @@ namespace CreatureLib::Battling {
|
|||
[[nodiscard]] const DamageLibrary* GetDamageLibrary() const;
|
||||
[[nodiscard]] const CriticalLibrary* GetCriticalLibrary() const;
|
||||
|
||||
[[nodiscard]] Script* LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName);
|
||||
[[nodiscard]] Script* LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -50,11 +50,12 @@ void Battle::CheckChoicesSetAndRun() {
|
|||
side->ResetChoices();
|
||||
}
|
||||
TurnOrdering::OrderChoices(choices, _random);
|
||||
auto choiceQueue = new ChoiceQueue(choices);
|
||||
this->_currentTurnQueue = choiceQueue;
|
||||
TurnHandler::RunTurn(this, choiceQueue);
|
||||
if (choiceQueue->HasCompletedQueue)
|
||||
_currentTurnQueue = nullptr;
|
||||
this->_currentTurnQueue = new ChoiceQueue(choices);
|
||||
TurnHandler::RunTurn(this, this->_currentTurnQueue);
|
||||
if (this->_currentTurnQueue->HasCompletedQueue) {
|
||||
delete this->_currentTurnQueue;
|
||||
this->_currentTurnQueue = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ChoiceQueue* Battle::GetCurrentTurnQueue() const { return _currentTurnQueue; }
|
||||
|
@ -85,3 +86,7 @@ void Battle::FillRecall(uint8_t side, uint8_t, Creature* c) {
|
|||
}
|
||||
|
||||
void Battle::GetActiveScripts(std::vector<ScriptWrapper>& scripts) { scripts.emplace_back(&_volatile); }
|
||||
void Battle::SwitchCreature(uint8_t sideIndex, uint8_t index, Creature* c) {
|
||||
auto side = this->_sides[sideIndex];
|
||||
side->SetCreature(c, index);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
#include "../Flow/ChoiceQueue.hpp"
|
||||
#include "../Library/BattleLibrary.hpp"
|
||||
#include "../TurnChoices/BaseTurnChoice.hpp"
|
||||
#include "BattleParty.hpp"
|
||||
#include "BattleSide.hpp"
|
||||
#include "CreatureIndex.hpp"
|
||||
|
||||
namespace CreatureLib::Battling {
|
||||
class Battle : public ScriptSource {
|
||||
const BattleLibrary* _library;
|
||||
std::vector<BattleParty> _parties;
|
||||
uint8_t _numberOfSides;
|
||||
uint8_t _creaturesPerSide;
|
||||
std::vector<BattleSide*> _sides;
|
||||
|
@ -21,6 +23,21 @@ namespace CreatureLib::Battling {
|
|||
ScriptSet _volatile;
|
||||
|
||||
public:
|
||||
Battle(const BattleLibrary* library, std::vector<BattleParty> parties, uint8_t numberOfSides = 2,
|
||||
uint8_t creaturesPerSide = 1)
|
||||
: _library(library), _parties(parties), _numberOfSides(numberOfSides), _creaturesPerSide(creaturesPerSide) {
|
||||
_sides = std::vector<BattleSide*>(numberOfSides);
|
||||
for (size_t i = 0; i < numberOfSides; i++) {
|
||||
_sides[i] = new BattleSide(this, creaturesPerSide);
|
||||
}
|
||||
}
|
||||
|
||||
~Battle() {
|
||||
for (auto s : _sides) {
|
||||
delete s;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] const BattleLibrary* GetLibrary() const;
|
||||
|
||||
virtual bool CanUse(const BaseTurnChoice* choice);
|
||||
|
@ -40,8 +57,8 @@ namespace CreatureLib::Battling {
|
|||
[[nodiscard]] bool HasRecalledSlots() const;
|
||||
|
||||
void ForceRecall(uint8_t side, uint8_t index);
|
||||
|
||||
void FillRecall(uint8_t side, uint8_t, Creature* c);
|
||||
void SwitchCreature(uint8_t side, uint8_t index, Creature* c);
|
||||
|
||||
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef CREATURELIB_BATTLEPARTY_HPP
|
||||
#define CREATURELIB_BATTLEPARTY_HPP
|
||||
|
||||
#include "CreatureIndex.hpp"
|
||||
#include "CreatureParty.hpp"
|
||||
|
||||
namespace CreatureLib::Battling {
|
||||
class BattleParty {
|
||||
CreatureParty* _party;
|
||||
std::vector<CreatureIndex> _responsibleIndices;
|
||||
|
||||
public:
|
||||
BattleParty(CreatureParty* party, std::vector<CreatureIndex> responsibleIndices)
|
||||
: _party(party), _responsibleIndices(responsibleIndices) {}
|
||||
|
||||
CreatureParty* GetParty() { return _party; }
|
||||
std::vector<CreatureIndex>& GetResponsibleIndices() { return _responsibleIndices; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CREATURELIB_BATTLEPARTY_HPP
|
|
@ -25,7 +25,10 @@ void BattleSide::SetChoice(BaseTurnChoice* choice) {
|
|||
_choicesSet++;
|
||||
}
|
||||
|
||||
void BattleSide::SetCreature(Creature* creature, uint8_t index) { _creatures[index] = creature; }
|
||||
void BattleSide::SetCreature(Creature* creature, uint8_t index) {
|
||||
_creatures[index] = creature;
|
||||
creature->SetBattleData(_battle, this);
|
||||
}
|
||||
|
||||
bool BattleSide::CreatureOnSide(const Creature* creature) const {
|
||||
return std::find(_creatures.begin(), _creatures.end(), creature) != _creatures.end();
|
||||
|
|
|
@ -16,11 +16,18 @@ namespace CreatureLib::Battling {
|
|||
|
||||
public:
|
||||
explicit BattleSide(Battle* battle, uint8_t creaturesPerSide)
|
||||
: _creaturesPerSide(creaturesPerSide), _creatures(creaturesPerSide), _choices(creaturesPerSide),
|
||||
_battle(battle) {
|
||||
: _creaturesPerSide(creaturesPerSide), _battle(battle) {
|
||||
_creatures = std::vector<Creature*>(creaturesPerSide);
|
||||
_choices = std::vector<BaseTurnChoice*>(creaturesPerSide);
|
||||
for (size_t i = 0; i < creaturesPerSide; i++) {
|
||||
_creatures[i] = nullptr;
|
||||
_choices[i] = nullptr;
|
||||
}
|
||||
ResetChoices();
|
||||
}
|
||||
|
||||
virtual ~BattleSide() = default;
|
||||
|
||||
[[nodiscard]] bool AllChoicesSet() const;
|
||||
[[nodiscard]] const std::vector<BaseTurnChoice*>& GetChoices() const;
|
||||
|
||||
|
@ -32,7 +39,7 @@ namespace CreatureLib::Battling {
|
|||
Creature* GetCreature(uint8_t index) const;
|
||||
bool CreatureOnSide(const Creature* creature) const;
|
||||
|
||||
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override;
|
||||
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) final;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -107,10 +107,10 @@ Creature* CreateCreature::Create() {
|
|||
_magAttackPotential, _magDefensePotential, _speedPotential);
|
||||
|
||||
auto attacks = std::vector<LearnedAttack*>(_attacks.size());
|
||||
for (auto kv : _attacks) {
|
||||
attacks.push_back(new LearnedAttack(std::get<0>(kv), std::get<1>(kv)));
|
||||
for (size_t i = 0; i < attacks.size(); i++) {
|
||||
auto kv = _attacks[i];
|
||||
attacks[i] = new LearnedAttack(std::get<0>(kv), std::get<1>(kv));
|
||||
}
|
||||
|
||||
return new Creature(species, variant, _level, experience, statExperience, statPotential, identifier, gender,
|
||||
_coloring, heldItem, _nickname, talent, attacks);
|
||||
return new Creature(_library, species, variant, _level, experience, statExperience, statPotential, identifier,
|
||||
gender, _coloring, heldItem, _nickname, talent, attacks);
|
||||
}
|
||||
|
|
|
@ -5,16 +5,18 @@
|
|||
|
||||
using namespace CreatureLib;
|
||||
|
||||
Battling::Creature::Creature(const Library::CreatureSpecies* species, const Library::SpeciesVariant* variant,
|
||||
uint8_t level, uint32_t experience, Core::StatisticSet<uint8_t> statExp,
|
||||
Core::StatisticSet<uint8_t> statPotential, uint32_t uid, Library::Gender gender,
|
||||
uint8_t coloring, const Library::Item* heldItem, std::string nickname, int8_t talent,
|
||||
std::vector<LearnedAttack*> attacks)
|
||||
: __Species(species), __Variant(variant), __Level(level), __Experience(experience), __StatExperience(statExp),
|
||||
__StatPotential(statPotential), __UniqueIdentifier(uid), __Gender(gender), __Coloring(coloring),
|
||||
__HeldItem(heldItem), _nickname(std::move(nickname)), _talentIndex(talent), _hasOverridenTalent(false),
|
||||
_attacks(std::move(attacks)) {
|
||||
Battling::Creature::Creature(const BattleLibrary* library, const Library::CreatureSpecies* species,
|
||||
const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience,
|
||||
Core::StatisticSet<uint8_t> statExp, Core::StatisticSet<uint8_t> statPotential,
|
||||
uint32_t uid, Library::Gender gender, uint8_t coloring, const Library::Item* heldItem,
|
||||
std::string nickname, int8_t talent, std::vector<LearnedAttack*> attacks)
|
||||
: _library(library), __Species(species), __Variant(variant), __Level(level), __Experience(experience),
|
||||
__StatExperience(statExp), __StatPotential(statPotential), __UniqueIdentifier(uid), __Gender(gender),
|
||||
__Coloring(coloring), __HeldItem(heldItem), _nickname(std::move(nickname)), _talentIndex(talent),
|
||||
_hasOverridenTalent(false), _attacks(std::move(attacks)) {
|
||||
RecalculateFlatStats();
|
||||
__CurrentHealth = GetBoostedStat(Core::Statistic::Health);
|
||||
_activeTalent = _library->LoadScript(ScriptResolver::ScriptCategory::Talent, GetActiveTalent());
|
||||
}
|
||||
|
||||
void Battling::Creature::ChangeLevel(int8_t amount) {
|
||||
|
@ -22,13 +24,6 @@ void Battling::Creature::ChangeLevel(int8_t amount) {
|
|||
RecalculateFlatStats();
|
||||
}
|
||||
|
||||
void Battling::Creature::SetBattle(Battling::Battle* battle) { this->_battle = battle; }
|
||||
|
||||
void Battling::Creature::SetBattleLibrary(Battling::BattleLibrary* library) {
|
||||
this->_library = library;
|
||||
_activeTalent = _library->LoadScript(ScriptResolver::ScriptCategory::Talent, GetActiveTalent());
|
||||
}
|
||||
|
||||
const std::string& Battling::Creature::GetNickname() const {
|
||||
if (_nickname.empty())
|
||||
return __Species->GetName();
|
||||
|
@ -70,7 +65,8 @@ uint32_t Battling::Creature::GetStatExperience(Core::Statistic stat) const { ret
|
|||
int8_t Battling::Creature::GetStatBoost(Core::Statistic stat) const { return _statBoost.GetStat(stat); }
|
||||
|
||||
void Battling::Creature::RecalculateFlatStats() {
|
||||
this->_flatStats = this->_library->GetStatCalculator()->CalculateFlatStats(this);
|
||||
auto statCalc = this->_library->GetStatCalculator();
|
||||
this->_flatStats = statCalc->CalculateFlatStats(this);
|
||||
RecalculateBoostedStats();
|
||||
}
|
||||
void Battling::Creature::RecalculateBoostedStats() {
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace CreatureLib::Battling {
|
|||
class BattleLibrary;
|
||||
|
||||
class Creature : public ScriptSource {
|
||||
const BattleLibrary* _library;
|
||||
|
||||
GetProperty(const Library::CreatureSpecies*, Species);
|
||||
GetProperty(const Library::SpeciesVariant*, Variant);
|
||||
|
||||
|
@ -37,7 +39,6 @@ namespace CreatureLib::Battling {
|
|||
|
||||
Battle* _battle;
|
||||
BattleSide* _side;
|
||||
BattleLibrary* _library;
|
||||
|
||||
std::string _nickname = "";
|
||||
int8_t _talentIndex;
|
||||
|
@ -52,12 +53,17 @@ namespace CreatureLib::Battling {
|
|||
ScriptSet _volatile = {};
|
||||
|
||||
public:
|
||||
Creature(const Library::CreatureSpecies* species, const Library::SpeciesVariant* variant, uint8_t level,
|
||||
uint32_t experience, Core::StatisticSet<uint8_t> statExp, Core::StatisticSet<uint8_t> statPotential,
|
||||
uint32_t uid, Library::Gender gender, uint8_t coloring, const Library::Item* heldItem,
|
||||
std::string nickname, int8_t talent, std::vector<LearnedAttack*> attacks);
|
||||
Creature(const BattleLibrary* library, const Library::CreatureSpecies* species,
|
||||
const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience,
|
||||
Core::StatisticSet<uint8_t> statExp, Core::StatisticSet<uint8_t> statPotential, uint32_t uid,
|
||||
Library::Gender gender, uint8_t coloring, const Library::Item* heldItem, std::string nickname,
|
||||
int8_t talent, std::vector<LearnedAttack*> attacks);
|
||||
|
||||
virtual ~Creature() = default;
|
||||
virtual ~Creature() {
|
||||
for (auto attack : _attacks) {
|
||||
delete attack;
|
||||
}
|
||||
};
|
||||
|
||||
void SetBattleData(Battle* battle, BattleSide* side);
|
||||
Battle* GetBattle() const;
|
||||
|
@ -76,10 +82,9 @@ namespace CreatureLib::Battling {
|
|||
|
||||
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override;
|
||||
|
||||
// region Stat APIs
|
||||
std::vector<LearnedAttack*>& GetAttacks() { return _attacks; }
|
||||
|
||||
void SetBattle(Battle* battle);
|
||||
void SetBattleLibrary(BattleLibrary* library);
|
||||
// region Stat APIs
|
||||
|
||||
void ChangeStatBoost(Core::Statistic stat, int8_t diffAmount);
|
||||
[[nodiscard]] uint32_t GetFlatStat(Core::Statistic stat) const;
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "CreatureParty.hpp"
|
|
@ -5,11 +5,18 @@
|
|||
#include "Creature.hpp"
|
||||
|
||||
namespace CreatureLib::Battling {
|
||||
template <int max> class CreatureParty {
|
||||
std::array<Creature*, max> _party;
|
||||
class CreatureParty {
|
||||
std::vector<Creature*> _party;
|
||||
|
||||
public:
|
||||
CreatureParty(std::array<Creature*, max> party) : _party(party) {}
|
||||
CreatureParty(std::vector<Creature*> party) : _party(party) {}
|
||||
CreatureParty(std::initializer_list<Creature*> party) : _party(party) {}
|
||||
|
||||
~CreatureParty() {
|
||||
for (auto c : _party) {
|
||||
delete c;
|
||||
}
|
||||
}
|
||||
|
||||
Creature* GetAtIndex(int index) const { return _party[index]; }
|
||||
|
||||
|
@ -29,6 +36,8 @@ namespace CreatureLib::Battling {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Creature*>& GetParty() { return _party; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "ExecutingAttack.hpp"
|
|
@ -9,7 +9,7 @@ namespace CreatureLib::Battling {
|
|||
class AttackTurnChoice : public BaseTurnChoice {
|
||||
LearnedAttack* _attack;
|
||||
CreatureIndex _target;
|
||||
Script* _attackScript;
|
||||
Script* _attackScript = nullptr;
|
||||
|
||||
public:
|
||||
AttackTurnChoice(Creature* user, LearnedAttack* attack, const CreatureIndex& target)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#ifdef TESTS_BUILD
|
||||
#include "../../extern/catch.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 "../TestLibrary/TestLibrary.cpp"
|
||||
|
||||
using namespace CreatureLib;
|
||||
using namespace Battling;
|
||||
|
||||
TEST_CASE("Create Party", "[Integrations]") {
|
||||
auto library = GetLibrary();
|
||||
auto c1 = CreateCreature(library, "testSpecies1", 50).WithAttack("standard", AttackLearnMethod::Unknown)->Create();
|
||||
CreatureParty party1{c1};
|
||||
auto battleParty = BattleParty(&party1, {CreatureIndex(0, 0)});
|
||||
REQUIRE(battleParty.GetParty()->GetAtIndex(0) == c1);
|
||||
}
|
||||
|
||||
TEST_CASE("Create Battle", "[Integrations]") {
|
||||
auto library = GetLibrary();
|
||||
auto c1 = CreateCreature(library, "testSpecies1", 50).WithAttack("standard", AttackLearnMethod::Unknown)->Create();
|
||||
CreatureParty party1{c1};
|
||||
auto battleParty1 = BattleParty(&party1, {CreatureIndex(0, 0)});
|
||||
auto c2 = CreateCreature(library, "testSpecies1", 50).WithAttack("standard", AttackLearnMethod::Unknown)->Create();
|
||||
CreatureParty party2{c2};
|
||||
auto battleParty2 = BattleParty(&party2, {CreatureIndex(1, 0)});
|
||||
|
||||
auto battle = Battle(library, {battleParty1, battleParty2});
|
||||
}
|
||||
|
||||
TEST_CASE("Use damaging move", "[Integrations]") {
|
||||
auto library = GetLibrary();
|
||||
auto c1 = CreateCreature(library, "testSpecies1", 50).WithAttack("standard", AttackLearnMethod::Unknown)->Create();
|
||||
CreatureParty party1{c1};
|
||||
auto battleParty1 = BattleParty(&party1, {CreatureIndex(0, 0)});
|
||||
auto c2 = CreateCreature(library, "testSpecies1", 50).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 AttackTurnChoice(c1, c1->GetAttacks()[0], CreatureIndex(1, 0)));
|
||||
battle.TrySetChoice(new PassTurnChoice(c2));
|
||||
|
||||
REQUIRE(c2->GetCurrentHealth() < c2->GetBoostedStat(Statistic::Health));
|
||||
}
|
||||
|
||||
#endif
|
|
@ -52,8 +52,8 @@ static TypeLibrary* BuildTypeLibrary() {
|
|||
static BattleLibrary* BuildLibrary() {
|
||||
auto l = new DataLibrary(LibrarySettings(100, 4), BuildSpeciesLibrary(), BuildAttackLibrary(), BuildItemLibrary(),
|
||||
BuildGrowthRateLibrary(), BuildTypeLibrary());
|
||||
auto battleLib = new BattleLibrary(l, new BattleStatCalculator(), new DamageLibrary(), new CriticalLibrary(),
|
||||
new ScriptResolver());
|
||||
auto statCalc = new BattleStatCalculator();
|
||||
auto battleLib = new BattleLibrary(l, statCalc, new DamageLibrary(), new CriticalLibrary(), new ScriptResolver());
|
||||
return battleLib;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue