From 5fc2bf564a6ca4dd016f1dd75b65e1c5c641091a Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Wed, 6 Nov 2019 18:04:00 +0100 Subject: [PATCH] Support turn queue return prematurely when a creature is recalled, and the ability to resume it later. --- src/Battling/Flow/ChoiceQueue.hpp | 9 ++++++--- src/Battling/Flow/TurnHandler.cpp | 21 ++++++++++++--------- src/Battling/Flow/TurnHandler.hpp | 2 +- src/Battling/Models/Battle.cpp | 28 +++++++++++++++++++++++----- src/Battling/Models/Battle.hpp | 13 ++++++++++--- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/Battling/Flow/ChoiceQueue.hpp b/src/Battling/Flow/ChoiceQueue.hpp index 03f2edb..e55a848 100644 --- a/src/Battling/Flow/ChoiceQueue.hpp +++ b/src/Battling/Flow/ChoiceQueue.hpp @@ -1,6 +1,7 @@ #ifndef CREATURELIB_CHOICEQUEUE_HPP #define CREATURELIB_CHOICEQUEUE_HPP +#include #include #include "../TurnChoices/BaseTurnChoice.hpp" @@ -9,8 +10,10 @@ namespace CreatureLib::Battling{ std::vector _queue; size_t _current = 0; public: - ChoiceQueue(const std::vector& queue) - :_queue(queue){} + bool HasCompletedQueue = false; + + explicit ChoiceQueue(std::vector queue) + :_queue(std::move(queue)){} const BaseTurnChoice* Dequeue(){ auto b = _queue[_current]; @@ -18,7 +21,7 @@ namespace CreatureLib::Battling{ return b; } - bool HasNext() const{ + [[nodiscard]] bool HasNext() const{ return _current < _queue.size(); } }; diff --git a/src/Battling/Flow/TurnHandler.cpp b/src/Battling/Flow/TurnHandler.cpp index 3707530..13bfc92 100644 --- a/src/Battling/Flow/TurnHandler.cpp +++ b/src/Battling/Flow/TurnHandler.cpp @@ -1,18 +1,23 @@ #include "TurnHandler.hpp" #include "../Models/Battle.hpp" -#include "../Models/ExecutingAttack.hpp" #include "../../Core/Exceptions/NotImplementedException.hpp" -void CreatureLib::Battling::TurnHandler::RunTurn(CreatureLib::Battling::ChoiceQueue &queue) { +using namespace CreatureLib::Battling; + +void TurnHandler::RunTurn(Battle* battle, ChoiceQueue* queue) { //HOOK: On Before Turn hook for all choices - while (queue.HasNext()){ - auto item = queue.Dequeue(); + while (queue->HasNext()){ + if (!battle->HasRecalledSlots()){ + return; + } + auto item = queue->Dequeue(); ExecuteChoice(item); delete item; } + queue->HasCompletedQueue = true; } -void CreatureLib::Battling::TurnHandler::ExecuteChoice(const CreatureLib::Battling::BaseTurnChoice *choice) { +void TurnHandler::ExecuteChoice(const BaseTurnChoice *choice) { if (choice == nullptr) { return; @@ -47,7 +52,7 @@ void CreatureLib::Battling::TurnHandler::ExecuteChoice(const CreatureLib::Battli } } -void CreatureLib::Battling::TurnHandler::ExecuteAttackChoice(const CreatureLib::Battling::AttackTurnChoice *choice) { +void TurnHandler::ExecuteAttackChoice(const AttackTurnChoice *choice) { //HOOK: Change attack //HOOK: Prevent attack @@ -71,9 +76,7 @@ void CreatureLib::Battling::TurnHandler::ExecuteAttackChoice(const CreatureLib:: } } -void CreatureLib::Battling::TurnHandler::HandleAttackForTarget(CreatureLib::Battling::ExecutingAttack &attack, - CreatureLib::Battling::Creature *target, - CreatureLib::Battling::ExecutingAttack::TargetData &targetData) { +void TurnHandler::HandleAttackForTarget(ExecutingAttack &attack, Creature *target, ExecutingAttack::TargetData &targetData) { //HOOK: Check if attack fails on target //HOOK: Check if target is invulnerable diff --git a/src/Battling/Flow/TurnHandler.hpp b/src/Battling/Flow/TurnHandler.hpp index cb13942..877e774 100644 --- a/src/Battling/Flow/TurnHandler.hpp +++ b/src/Battling/Flow/TurnHandler.hpp @@ -14,7 +14,7 @@ namespace CreatureLib::Battling { static void ExecuteAttackChoice(const AttackTurnChoice* choice); static void HandleAttackForTarget(ExecutingAttack& attack, Creature* target, ExecutingAttack::TargetData& targetData); public: - static void RunTurn(ChoiceQueue& queue); + static void RunTurn(Battle* battle, ChoiceQueue* queue); }; } diff --git a/src/Battling/Models/Battle.cpp b/src/Battling/Models/Battle.cpp index da8c092..4dc1220 100644 --- a/src/Battling/Models/Battle.cpp +++ b/src/Battling/Models/Battle.cpp @@ -38,7 +38,7 @@ void Battle::CheckChoicesSetAndRun() { for (auto side: _sides){ for (auto choice: side->GetChoices()){ if (choice->GetKind() == TurnChoiceKind::Attack){ - auto attack = static_cast(choice)->GetAttack(); + auto attack = dynamic_cast(choice)->GetAttack(); uint8_t uses = 1; //HOOK: change number of uses needed. if (attack->GetRemainingUses() < uses){ @@ -52,10 +52,11 @@ void Battle::CheckChoicesSetAndRun() { } } TurnOrdering::OrderChoices(choices, _random); - auto choiceQueue = ChoiceQueue(choices); - this->_currentTurnQueue = &choiceQueue; - TurnHandler::RunTurn(choiceQueue); - this->_currentTurnQueue = nullptr; + auto choiceQueue = new ChoiceQueue(choices); + this->_currentTurnQueue = choiceQueue; + TurnHandler::RunTurn(this, choiceQueue); + if (choiceQueue->HasCompletedQueue) + _currentTurnQueue = nullptr; } ChoiceQueue* Battle::GetCurrentTurnQueue() const { @@ -73,3 +74,20 @@ bool Battle::CreatureInField(const Creature *creature) const { } return false; } + +bool Battle::HasRecalledSlots() const { + return _numberOfRecalledSlots > 0; +} + +void Battle::ForceRecall(uint8_t side, uint8_t index) { + _numberOfRecalledSlots++; + //TODO: Switch out. +} + +void Battle::FillRecall(uint8_t side, uint8_t, Creature *c) { + _numberOfRecalledSlots--; + //TODO: switch in. + if (_numberOfRecalledSlots == 0 && _currentTurnQueue != nullptr){ + TurnHandler::RunTurn(this, _currentTurnQueue); + } +} diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index b91cbd1..288ee41 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -15,17 +15,18 @@ namespace CreatureLib::Battling { uint8_t _creaturesPerSide; std::vector _sides; Core::Random _random; - ChoiceQueue* _currentTurnQueue = nullptr; + + uint8_t _numberOfRecalledSlots = 0; public: - const BattleLibrary* GetLibrary() const; + [[nodiscard]] const BattleLibrary* GetLibrary() const; virtual bool CanUse(const BaseTurnChoice* choice); virtual bool TrySetChoice(BaseTurnChoice* choice); void CheckChoicesSetAndRun(); - ChoiceQueue* GetCurrentTurnQueue() const; + [[nodiscard]] ChoiceQueue* GetCurrentTurnQueue() const; Core::Random& GetRandom(); bool CreatureInField(const Creature* creature) const; @@ -33,6 +34,12 @@ namespace CreatureLib::Battling { Creature* GetTarget(const Target& target){ return _sides[target.GetSideIndex()]->GetCreature(target.GetCreatureIndex()); } + + [[nodiscard]] bool HasRecalledSlots() const; + + void ForceRecall(uint8_t side, uint8_t index); + + void FillRecall(uint8_t side, uint8_t, Creature* c); }; }