Support turn queue return prematurely when a creature is recalled, and the ability to resume it later.

This commit is contained in:
Deukhoofd 2019-11-06 18:04:00 +01:00
parent f184572837
commit 5fc2bf564a
5 changed files with 52 additions and 21 deletions

View File

@ -1,6 +1,7 @@
#ifndef CREATURELIB_CHOICEQUEUE_HPP #ifndef CREATURELIB_CHOICEQUEUE_HPP
#define CREATURELIB_CHOICEQUEUE_HPP #define CREATURELIB_CHOICEQUEUE_HPP
#include <utility>
#include <vector> #include <vector>
#include "../TurnChoices/BaseTurnChoice.hpp" #include "../TurnChoices/BaseTurnChoice.hpp"
@ -9,8 +10,10 @@ namespace CreatureLib::Battling{
std::vector<const BaseTurnChoice*> _queue; std::vector<const BaseTurnChoice*> _queue;
size_t _current = 0; size_t _current = 0;
public: public:
ChoiceQueue(const std::vector<const BaseTurnChoice*>& queue) bool HasCompletedQueue = false;
:_queue(queue){}
explicit ChoiceQueue(std::vector<const BaseTurnChoice*> queue)
:_queue(std::move(queue)){}
const BaseTurnChoice* Dequeue(){ const BaseTurnChoice* Dequeue(){
auto b = _queue[_current]; auto b = _queue[_current];
@ -18,7 +21,7 @@ namespace CreatureLib::Battling{
return b; return b;
} }
bool HasNext() const{ [[nodiscard]] bool HasNext() const{
return _current < _queue.size(); return _current < _queue.size();
} }
}; };

View File

@ -1,18 +1,23 @@
#include "TurnHandler.hpp" #include "TurnHandler.hpp"
#include "../Models/Battle.hpp" #include "../Models/Battle.hpp"
#include "../Models/ExecutingAttack.hpp"
#include "../../Core/Exceptions/NotImplementedException.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 //HOOK: On Before Turn hook for all choices
while (queue.HasNext()){ while (queue->HasNext()){
auto item = queue.Dequeue(); if (!battle->HasRecalledSlots()){
return;
}
auto item = queue->Dequeue();
ExecuteChoice(item); ExecuteChoice(item);
delete 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) if (choice == nullptr)
{ {
return; 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: Change attack
//HOOK: Prevent attack //HOOK: Prevent attack
@ -71,9 +76,7 @@ void CreatureLib::Battling::TurnHandler::ExecuteAttackChoice(const CreatureLib::
} }
} }
void CreatureLib::Battling::TurnHandler::HandleAttackForTarget(CreatureLib::Battling::ExecutingAttack &attack, void TurnHandler::HandleAttackForTarget(ExecutingAttack &attack, Creature *target, ExecutingAttack::TargetData &targetData) {
CreatureLib::Battling::Creature *target,
CreatureLib::Battling::ExecutingAttack::TargetData &targetData) {
//HOOK: Check if attack fails on target //HOOK: Check if attack fails on target
//HOOK: Check if target is invulnerable //HOOK: Check if target is invulnerable

View File

@ -14,7 +14,7 @@ namespace CreatureLib::Battling {
static void ExecuteAttackChoice(const AttackTurnChoice* choice); static void ExecuteAttackChoice(const AttackTurnChoice* choice);
static void HandleAttackForTarget(ExecutingAttack& attack, Creature* target, ExecutingAttack::TargetData& targetData); static void HandleAttackForTarget(ExecutingAttack& attack, Creature* target, ExecutingAttack::TargetData& targetData);
public: public:
static void RunTurn(ChoiceQueue& queue); static void RunTurn(Battle* battle, ChoiceQueue* queue);
}; };
} }

View File

@ -38,7 +38,7 @@ void Battle::CheckChoicesSetAndRun() {
for (auto side: _sides){ for (auto side: _sides){
for (auto choice: side->GetChoices()){ for (auto choice: side->GetChoices()){
if (choice->GetKind() == TurnChoiceKind::Attack){ if (choice->GetKind() == TurnChoiceKind::Attack){
auto attack = static_cast<const AttackTurnChoice*>(choice)->GetAttack(); auto attack = dynamic_cast<const AttackTurnChoice*>(choice)->GetAttack();
uint8_t uses = 1; uint8_t uses = 1;
//HOOK: change number of uses needed. //HOOK: change number of uses needed.
if (attack->GetRemainingUses() < uses){ if (attack->GetRemainingUses() < uses){
@ -52,10 +52,11 @@ void Battle::CheckChoicesSetAndRun() {
} }
} }
TurnOrdering::OrderChoices(choices, _random); TurnOrdering::OrderChoices(choices, _random);
auto choiceQueue = ChoiceQueue(choices); auto choiceQueue = new ChoiceQueue(choices);
this->_currentTurnQueue = &choiceQueue; this->_currentTurnQueue = choiceQueue;
TurnHandler::RunTurn(choiceQueue); TurnHandler::RunTurn(this, choiceQueue);
this->_currentTurnQueue = nullptr; if (choiceQueue->HasCompletedQueue)
_currentTurnQueue = nullptr;
} }
ChoiceQueue* Battle::GetCurrentTurnQueue() const { ChoiceQueue* Battle::GetCurrentTurnQueue() const {
@ -73,3 +74,20 @@ bool Battle::CreatureInField(const Creature *creature) const {
} }
return false; 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);
}
}

View File

@ -15,17 +15,18 @@ namespace CreatureLib::Battling {
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;
uint8_t _numberOfRecalledSlots = 0;
public: public:
const BattleLibrary* GetLibrary() const; [[nodiscard]] const BattleLibrary* GetLibrary() const;
virtual bool CanUse(const BaseTurnChoice* choice); virtual bool CanUse(const BaseTurnChoice* choice);
virtual bool TrySetChoice(BaseTurnChoice* choice); virtual bool TrySetChoice(BaseTurnChoice* choice);
void CheckChoicesSetAndRun(); void CheckChoicesSetAndRun();
ChoiceQueue* GetCurrentTurnQueue() const; [[nodiscard]] ChoiceQueue* GetCurrentTurnQueue() const;
Core::Random& GetRandom(); Core::Random& GetRandom();
bool CreatureInField(const Creature* creature) const; bool CreatureInField(const Creature* creature) const;
@ -33,6 +34,12 @@ namespace CreatureLib::Battling {
Creature* GetTarget(const Target& target){ Creature* GetTarget(const Target& target){
return _sides[target.GetSideIndex()]->GetCreature(target.GetCreatureIndex()); 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);
}; };
} }