CreatureLib/src/Battling/Models/BattleSide.cpp

133 lines
4.2 KiB
C++

#include "BattleSide.hpp"
#include "../EventHooks/EventDataClasses.hpp"
#include "Battle.hpp"
using namespace CreatureLib::Battling;
bool BattleSide::AllChoicesSet() const noexcept { return _choicesSet == _creaturesPerSide; }
bool BattleSide::AllPossibleSlotsFilled() const {
try {
for (size_t i = 0; i < _creatures.Count(); i++) {
auto c = _creatures[i];
if (!c.HasValue() || c.GetValue()->IsFainted()) {
if (_battle->CanSlotBeFilled(_index, i)) {
return false;
}
}
}
} catch (const std::exception& e) {
THROW("Exception during AllPossibleSlotsFilled check: '" << e.what() << "'.");
}
return true;
}
void BattleSide::ResetChoices() noexcept {
_choicesSet = 0;
for (uint8_t i = 0; i < _creaturesPerSide; i++) {
_choices[i] = nullptr;
}
}
void BattleSide::SetChoice(BaseTurnChoice* choice) {
EnsureNotNull(choice)
try {
for (size_t i = 0; i < _creatures.Count(); i++) {
auto& c = _creatures[i];
if (!c.HasValue()) {
continue;
}
if (c.GetValue() == choice->GetUser()) {
_choices[i] = std::shared_ptr<BaseTurnChoice>(choice);
_choicesSet++;
return;
}
}
} catch (const std::exception& e) {
THROW("Error during setting choice: '" << e.what() << "'.");
}
THROW("User not found");
}
void BattleSide::SetCreature(ArbUt::OptionalBorrowedPtr<Creature> creature, uint8_t index) {
auto old = _creatures[index];
if (old.HasValue()) {
old.GetValue()->SetOnBattleField(false);
}
_creatures[index] = creature.GetValue();
if (!creature.HasValue()) {
return;
}
creature.GetValue()->SetBattleData(_battle, this);
creature.GetValue()->SetOnBattleField(true);
for (auto* side : _battle->GetSides()) {
if (side == this) {
continue;
}
for (const auto& c : side->GetCreatures()) {
if (c.HasValue()) {
c.GetValue()->MarkOpponentAsSeen(creature.GetValue());
creature.GetValue()->MarkOpponentAsSeen(c.GetValue());
}
}
}
_battle->TriggerEventListener<SwitchEvent>(CreatureIndex(this->_index, index), creature.GetValue());
}
bool BattleSide::CreatureOnSide(const ArbUt::BorrowedPtr<Creature>& creature) const {
return std::find(_creatures.begin(), _creatures.end(), creature.GetRaw()) != _creatures.end();
}
const ArbUt::OptionalBorrowedPtr<Creature>& BattleSide::GetCreature(uint8_t index) const { return _creatures[index]; }
void BattleSide::GetActiveScripts(ArbUt::List<ScriptWrapper>& scripts) {
scripts.Append(ScriptWrapper::FromSet(&_volatile));
_battle->GetActiveScripts(scripts);
}
size_t BattleSide::ScriptCount() const { return _battle->ScriptCount() + 1; }
uint8_t BattleSide::GetRandomCreatureIndex() {
// TODO: Consider adding parameter to only get index for available creatures.
return _battle->GetRandom()->Get(_creaturesPerSide);
}
bool BattleSide::SwapPositions(u8 a, u8 b) {
// If out of range, don't allow swapping.
if (a >= _creaturesPerSide || b >= _creaturesPerSide) {
return false;
}
// If the two indices are the same, don't allow swapping.
if (a == b) {
return false;
}
// Fetch parties for the two indices.
BattleParty* partyA = nullptr;
BattleParty* partyB = nullptr;
for (auto* party : this->_battle->GetParties()) {
if (party->IsResponsibleForIndex(_index, a)) {
partyA = party;
}
if (party->IsResponsibleForIndex(_index, b)) {
partyB = party;
}
}
// Don't allow swapping if different parties are responsible for the indices.
if (partyA != partyB) {
return false;
}
auto creatureA = _creatures[a];
_creatures[a] = _creatures[b];
_creatures[b] = creatureA;
_battle->TriggerEventListener<SwapEvent>(_index, a, b);
return true;
}
BattleSide* BattleSide::CloneWithoutCreatures() {
auto* side = new BattleSide(_index, _battle, _creaturesPerSide);
side->_choicesSet = _choicesSet;
_volatile.Clone(side->_volatile);
side->_hasFled = _hasFled;
return side;
}