diff --git a/src/Battling/Flow/ResolveTarget.cpp b/src/Battling/Flow/ResolveTarget.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Battling/Flow/ResolveTarget.hpp b/src/Battling/Flow/ResolveTarget.hpp new file mode 100644 index 0000000..4667151 --- /dev/null +++ b/src/Battling/Flow/ResolveTarget.hpp @@ -0,0 +1,112 @@ +#ifndef CREATURELIB_RESOLVETARGET_HPP +#define CREATURELIB_RESOLVETARGET_HPP +#include +#include +#include +#include "../../Library/Attacks/AttackTarget.hpp" +#include "../Models/Battle.hpp" +#include "../Models/Creature.hpp" +#include "../Models/CreatureIndex.hpp" +using namespace CreatureLib::Battling; + +namespace CreatureLib::Battling { + class TargetResolver { + public: + static inline constexpr uint8_t GetOppositeSide(uint8_t v) { + if (v == 1) + return 0; + return 1; + } + + static ArbUt::List> ResolveTargets(const CreatureIndex& index, + CreatureLib::Library::AttackTarget target, + const ArbUt::BorrowedPtr& battle) { + switch (target) { + case CreatureLib::Library::AttackTarget::Adjacent: { + return {battle->GetCreature(index)}; + }; + case CreatureLib::Library::AttackTarget::AdjacentAlly: { + return {battle->GetCreature(index)}; + }; + case CreatureLib::Library::AttackTarget::AdjacentAllySelf: { + return {battle->GetCreature(index)}; + }; + case CreatureLib::Library::AttackTarget::AdjacentOpponent: { + return {battle->GetCreature(index)}; + }; + case CreatureLib::Library::AttackTarget::All: { + ArbUt::BorrowedPtr arr[battle->GetCreaturesPerSide() * battle->GetSides().Count()]; + size_t i = 0; + for (auto side : battle->GetSides()) { + for (auto mon : side->GetCreatures()) { + arr[i++] = mon; + } + } + return ArbUt::List>(arr, arr + i); + } + case CreatureLib::Library::AttackTarget::AllAdjacent: { + auto left = index.GetCreatureIndex() - 1; + auto right = index.GetCreatureIndex() + 1; + if (left < 0 && right >= battle->GetCreaturesPerSide()) { + return {battle->GetCreature(index), + battle->GetCreature(GetOppositeSide(index.GetSideIndex()), index.GetCreatureIndex())}; + } else if (left >= 0) { + if (right < battle->GetCreaturesPerSide()) { + return { + battle->GetCreature(index), battle->GetCreature(index.GetSideIndex(), left), + battle->GetCreature(index.GetSideIndex(), right), + battle->GetCreature(GetOppositeSide(index.GetSideIndex()), index.GetCreatureIndex())}; + } + return {battle->GetCreature(index), battle->GetCreature(index.GetSideIndex(), left), + battle->GetCreature(GetOppositeSide(index.GetSideIndex()), index.GetCreatureIndex())}; + } else { + return {battle->GetCreature(index), battle->GetCreature(index.GetSideIndex(), right), + battle->GetCreature(GetOppositeSide(index.GetSideIndex()), index.GetCreatureIndex())}; + } + } + case CreatureLib::Library::AttackTarget::AllAdjacentOpponent: { + auto left = index.GetCreatureIndex() - 1; + auto right = index.GetCreatureIndex() + 1; + if (left < 0 && right >= battle->GetCreaturesPerSide()) { + return {battle->GetCreature(index)}; + } else if (left >= 0) { + if (right < battle->GetCreaturesPerSide()) { + return {battle->GetCreature(index), battle->GetCreature(index.GetSideIndex(), left), + battle->GetCreature(index.GetSideIndex(), right)}; + } + return {battle->GetCreature(index), battle->GetCreature(index.GetSideIndex(), left)}; + } else { + return {battle->GetCreature(index), battle->GetCreature(index.GetSideIndex(), right)}; + } + } + case CreatureLib::Library::AttackTarget::AllAlly: { + ArbUt::BorrowedPtr arr[battle->GetCreaturesPerSide()]; + size_t i = 0; + for (auto mon : battle->GetSides()[index.GetSideIndex()]->GetCreatures()) { + arr[i++] = mon; + } + return ArbUt::List>(arr, arr + i); + }; + case CreatureLib::Library::AttackTarget::AllOpponent: { + ArbUt::BorrowedPtr arr[battle->GetCreaturesPerSide()]; + size_t i = 0; + for (auto mon : battle->GetSides()[index.GetSideIndex()]->GetCreatures()) { + arr[i++] = mon; + } + return ArbUt::List>(arr, arr + i); + }; + case CreatureLib::Library::AttackTarget::Any: { + return {battle->GetCreature(index)}; + }; + case CreatureLib::Library::AttackTarget::RandomOpponent: { + return {battle->GetCreature(index)}; + }; + case CreatureLib::Library::AttackTarget::Self: { + return {battle->GetCreature(index)}; + }; + } + } + }; +} + +#endif // CREATURELIB_RESOLVETARGET_HPP diff --git a/src/Battling/Flow/TurnHandler.cpp b/src/Battling/Flow/TurnHandler.cpp index 0266c0f..14f19af 100644 --- a/src/Battling/Flow/TurnHandler.cpp +++ b/src/Battling/Flow/TurnHandler.cpp @@ -2,6 +2,7 @@ #include #include "../../Library/Exceptions/NotImplementedException.hpp" #include "../ScriptHandling/ScriptMacros.hpp" +#include "ResolveTarget.hpp" using namespace CreatureLib::Battling; @@ -57,9 +58,9 @@ void TurnHandler::ExecuteAttackChoice(ArbUt::BorrowedPtr choic // TODO: Change attack } - // FIXME: Resolve all targets auto target = choice->GetUser()->GetBattle()->GetCreature(choice->GetTarget()); - ArbUt::List> targets = {target}; + ArbUt::List> targets = TargetResolver::ResolveTargets( + choice->GetTarget(), choice->GetAttack()->GetAttack()->GetTarget(), choice->GetUser()->GetBattle()); auto attack = ExecutingAttack(targets, 1, choice->GetUser(), choice->GetAttack(), choice->GetAttackScript()); bool prevented = false; diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index d701fa5..2f45583 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -49,6 +49,7 @@ namespace CreatureLib::Battling { [[nodiscard]] const ArbUt::BorrowedPtr& GetLibrary() const noexcept; [[nodiscard]] uint32_t GetCurrentTurn() const noexcept { return _currentTurn; } + inline uint8_t GetCreaturesPerSide() const noexcept { return _creaturesPerSide; } virtual bool CanUse(const ArbUt::BorrowedPtr& choice); virtual bool TrySetChoice(BaseTurnChoice* choice);