diff --git a/src/NaiveAI.hpp b/src/NaiveAI.hpp index a327400..f099f65 100644 --- a/src/NaiveAI.hpp +++ b/src/NaiveAI.hpp @@ -18,6 +18,10 @@ namespace PkmnLibAI { if (!move.HasValue()) { continue; } + auto t = GetTargetIndex(battle, user, move); + if (!t.has_value() || t.value() != target) { + continue; + } if (move.GetValue()->GetRemainingUses() <= 0) continue; auto naiveDamage = move.GetValue()->GetMoveData()->GetBasePower() * diff --git a/src/PokemonAI.hpp b/src/PokemonAI.hpp index 5581533..1293aea 100644 --- a/src/PokemonAI.hpp +++ b/src/PokemonAI.hpp @@ -1,6 +1,8 @@ #ifndef PKMNLIB_AI_POKEMONAI_HPP #define PKMNLIB_AI_POKEMONAI_HPP +#include #include +#include #include #include @@ -24,6 +26,43 @@ namespace PkmnLibAI { return CreatureLib::Battling::CreatureIndex(0, 0); } } + + std::optional GetTargetIndex(PkmnLib::Battling::Battle* battle, + PkmnLib::Battling::Pokemon* user, + PkmnLib::Battling::LearnedMove* move) { + auto moveTarget = move->GetMoveData()->GetTarget(); + auto userIndex = user->GetBattleIndex(); + switch (moveTarget) { + case CreatureLib::Library::AttackTarget::Adjacent: + case CreatureLib::Library::AttackTarget::AdjacentOpponent: + case CreatureLib::Library::AttackTarget::All: + case CreatureLib::Library::AttackTarget::AllAdjacent: + case CreatureLib::Library::AttackTarget::AllAdjacentOpponent: + case CreatureLib::Library::AttackTarget::AllOpponent: + case CreatureLib::Library::AttackTarget::Any: + case CreatureLib::Library::AttackTarget::RandomOpponent: { + return GetOppositeIndex(user); + } + case CreatureLib::Library::AttackTarget::AdjacentAlly: { + if (battle->GetCreaturesPerSide() < 2) { + return {}; + }; + if (userIndex.GetCreatureIndex() > 0) { + return CreatureLib::Battling::CreatureIndex(userIndex.GetSideIndex(), + userIndex.GetCreatureIndex() - 1); + } + return CreatureLib::Battling::CreatureIndex(userIndex.GetSideIndex(), + userIndex.GetCreatureIndex() + 1); + } + case CreatureLib::Library::AttackTarget::AdjacentAllySelf: + case CreatureLib::Library::AttackTarget::AllAlly: + case CreatureLib::Library::AttackTarget::Self: { + return userIndex; + } + } + THROW("Unknown attack target kind: '" << CreatureLib::Library::AttackTargetHelper::ToString(moveTarget) + << "'.") + } }; } diff --git a/src/RandomAI.hpp b/src/RandomAI.hpp index 3bedb24..6f56375 100644 --- a/src/RandomAI.hpp +++ b/src/RandomAI.hpp @@ -15,22 +15,24 @@ namespace PkmnLibAI { CreatureLib::Battling::BaseTurnChoice* GetChoice([[maybe_unused]] PkmnLib::Battling::Battle* battle, [[maybe_unused]] PkmnLib::Battling::Pokemon* user) override { auto moves = user->GetMoves(); - ArbUt::List validMoves; + ArbUt::List> validMoves; for (auto move : moves) { if (!move.HasValue()) { continue; } - if (move.GetValue()->GetRemainingUses() > 0) { - validMoves.Append(move.GetValue()); + auto target = GetTargetIndex(battle, user, move.GetValue()); + if (move.GetValue()->GetRemainingUses() > 0 && target.has_value()) { + validMoves.Append(std::tuple( + move.GetValue(), target.value())); } } - auto target = GetOppositeIndex(user); if (validMoves.Count() == 0) { - return battle->GetLibrary()->GetMiscLibrary()->ReplacementAttack(user, target); + return battle->GetLibrary()->GetMiscLibrary()->ReplacementAttack(user, GetOppositeIndex(user)); } auto moveIndex = rand.Get(validMoves.Count()); - return new CreatureLib::Battling::AttackTurnChoice(user, validMoves[moveIndex], target); + return new CreatureLib::Battling::AttackTurnChoice(user, std::get<0>(validMoves[moveIndex]), + std::get<1>(validMoves[moveIndex])); } }; }