diff --git a/src/Battling/Flow/ResolveTarget.cpp b/src/Battling/Flow/ResolveTarget.cpp index fc34a48..453da04 100644 --- a/src/Battling/Flow/ResolveTarget.cpp +++ b/src/Battling/Flow/ResolveTarget.cpp @@ -97,3 +97,57 @@ TargetList TargetResolver::ResolveTargets(const CreatureIndex& index, AttackTarg } THROW("Unknown attack target kind: '" << AttackTargetHelper::ToString(target) << "'.") } + +bool TargetResolver::IsValidTarget(const CreatureIndex& index, CreatureLib::Library::AttackTarget target, + const BorrowedPtr& user) { + auto userIndex = user->GetBattleIndex(); + switch (target) { + case AttackTarget::Adjacent: + case AttackTarget::AllAdjacent: { + auto diff = abs(index.GetCreatureIndex() - userIndex.GetCreatureIndex()); + // If the difference is 0, ensure the move is not targeting self. + if (diff == 0) { + return index.GetSideIndex() != userIndex.GetSideIndex(); + } + // Otherwise check if the difference is max 1. + return diff <= 1; + } + case AttackTarget::AdjacentAlly: { + if (index.GetSideIndex() != userIndex.GetSideIndex()) { + return false; + } + auto diff = abs(index.GetCreatureIndex() - userIndex.GetCreatureIndex()); + return diff == 1; + } + case AttackTarget::AdjacentAllySelf: { + if (index.GetSideIndex() != userIndex.GetSideIndex()) { + return false; + } + auto diff = abs(index.GetCreatureIndex() - userIndex.GetCreatureIndex()); + return diff <= 1; + } + case AttackTarget::AdjacentOpponent: + case AttackTarget::AllAdjacentOpponent: { + if (index.GetSideIndex() == userIndex.GetSideIndex()) { + return false; + } + auto diff = abs(index.GetCreatureIndex() - userIndex.GetCreatureIndex()); + return diff <= 1; + } + case AttackTarget::All: + case AttackTarget::Any: + case AttackTarget::RandomOpponent: { + return true; + } + case AttackTarget::AllAlly: { + return index.GetSideIndex() == userIndex.GetSideIndex(); + } + case AttackTarget::AllOpponent: { + return index.GetSideIndex() != userIndex.GetSideIndex(); + } + case AttackTarget::Self: { + return index == userIndex; + } + } + THROW("Unknown attack target kind: '" << AttackTargetHelper::ToString(target) << "'.") +} diff --git a/src/Battling/Flow/ResolveTarget.hpp b/src/Battling/Flow/ResolveTarget.hpp index 926ac6a..952766d 100644 --- a/src/Battling/Flow/ResolveTarget.hpp +++ b/src/Battling/Flow/ResolveTarget.hpp @@ -12,6 +12,9 @@ namespace CreatureLib::Battling { public: static TargetList ResolveTargets(const CreatureIndex& index, CreatureLib::Library::AttackTarget target, const ArbUt::BorrowedPtr& battle); + + static bool IsValidTarget(const CreatureIndex& index, CreatureLib::Library::AttackTarget target, + const ArbUt::BorrowedPtr& user); }; } diff --git a/src/Battling/Models/Battle.cpp b/src/Battling/Models/Battle.cpp index 432f226..de1e3fa 100644 --- a/src/Battling/Models/Battle.cpp +++ b/src/Battling/Models/Battle.cpp @@ -1,5 +1,6 @@ #include "Battle.hpp" #include "../EventHooks/EventDataClasses.hpp" +#include "../Flow/ResolveTarget.hpp" #include "../Flow/TurnHandler.hpp" #include "../Flow/TurnOrdering.hpp" @@ -10,8 +11,15 @@ const ArbUt::BorrowedPtr& Battle::GetLibrary() const noexce bool Battle::CanUse(const ArbUt::BorrowedPtr& choice) { if (choice->GetKind() == TurnChoiceKind::Attack) { + auto attack = choice.ForceAs(); // HOOK: change number of uses needed. - return choice.ForceAs()->GetAttack()->GetRemainingUses() >= 1; + if (attack->GetAttack()->GetRemainingUses() < 1) { + return false; + } + if (!TargetResolver::IsValidTarget(attack->GetTarget(), attack->GetAttack()->GetAttack()->GetTarget(), + attack->GetUser())) { + return false; + } } return true; }