#ifndef CREATURELIB_RESOLVETARGET_HPP #define CREATURELIB_RESOLVETARGET_HPP #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::OptionalBorrowedPtr 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::OptionalBorrowedPtr 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::OptionalBorrowedPtr 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)}; }; } THROW("Unknown attack target kind: '" << CreatureLib::Library::AttackTargetHelper::ToString(target) << "'."); } }; } #endif // CREATURELIB_RESOLVETARGET_HPP