Deukhoofd 3802587313
Some checks failed
continuous-integration/drone/push Build is failing
Added HasVolatileScript function to Creature and Battle.
2020-02-23 16:17:57 +01:00

135 lines
4.4 KiB
C++

#include "Battle.hpp"
#include "../../Core/Exceptions/NotImplementedException.hpp"
#include "../Flow/TurnHandler.hpp"
#include "../Flow/TurnOrdering.hpp"
using namespace CreatureLib;
using namespace CreatureLib::Battling;
const BattleLibrary* Battle::GetLibrary() const { return _library; }
bool Battle::CanUse(const BaseTurnChoice* choice) {
if (choice->GetKind() == TurnChoiceKind::Attack) {
// HOOK: change number of uses needed.
return dynamic_cast<const AttackTurnChoice*>(choice)->GetAttack()->GetRemainingUses() > 1;
}
return true;
}
bool Battle::TrySetChoice(BaseTurnChoice* choice) {
if (!CanUse(choice))
return false;
choice->GetUser()->GetBattleSide()->SetChoice(choice);
CheckChoicesSetAndRun();
return true;
}
void Battle::CheckChoicesSetAndRun() {
for (auto side : _sides) {
if (!side->AllChoicesSet()) {
return;
}
}
for (auto side : _sides) {
if (!side->AllPossibleSlotsFilled()) {
return;
}
}
auto choices = std::vector<BaseTurnChoice*>(_numberOfSides * _creaturesPerSide);
auto i = 0;
for (auto side : _sides) {
for (BaseTurnChoice* choice : side->GetChoices()) {
if (choice == nullptr) {
throw CreatureException("Choice was null");
}
if (choice->GetKind() == TurnChoiceKind::Attack) {
auto attack = (dynamic_cast<AttackTurnChoice*>((choice)))->GetAttack();
uint8_t uses = 1;
// HOOK: change number of uses needed.
if (attack->GetRemainingUses() < uses) {
// TODO: Implement default move
throw NotImplementedException("Not enough remaining uses, change to default move.");
}
// HOOK: Check if we need to change the move
}
choices[i] = choice;
i++;
}
side->ResetChoices();
}
TurnOrdering::OrderChoices(choices, _random.GetRNG());
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; }
BattleRandom* Battle::GetRandom() { return &_random; }
bool Battle::CreatureInField(const Creature* creature) const {
for (auto s : _sides) {
if (s->CreatureOnSide(creature))
return true;
}
return false;
}
void Battle::ForceRecall(uint8_t side, uint8_t index) { _sides[side]->SetCreature(nullptr, index); }
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);
}
bool Battle::CanSlotBeFilled(uint8_t side, uint8_t index) const {
for (const auto& party : _parties) {
if (party.IsResponsibleForIndex(side, index)) {
if (party.HasCreaturesNotInField())
return true;
}
}
return false;
}
void Battle::ValidateBattleState() {
bool survivingSideExists = false;
uint8_t winningSide = 0;
for (uint8_t i = 0; i < _sides.size(); i++) {
auto side = _sides[i];
if (side->HasFled()) {
this->_battleResult = BattleResult::Inconclusive();
this->_hasEnded = true;
return;
}
if (!side->IsDefeated()) {
if (survivingSideExists) {
return;
}
survivingSideExists = true;
winningSide = i;
}
}
this->_battleResult = BattleResult::Conclusive(winningSide);
this->_hasEnded = true;
}
void Battle::AddVolatileScript(const std::string& key) {
auto script = _volatile.Get(key);
if (script != nullptr) {
script->Stack();
return;
}
script = _library->LoadScript(ScriptCategory::Battle, key);
return _volatile.Add(script);
}
void Battle::AddVolatileScript(Script* script) { return _volatile.Add(script); }
void Battle::RemoveVolatileScript(const std::string& name) { _volatile.Remove(name); }
void Battle::RemoveVolatileScript(Script* script) { _volatile.Remove(script->GetName()); }
void Battle::HasVolatileScript(const std::string& name) const { _volatile.Has(name); }