Initial support for handling multi target attacks.
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2020-06-05 15:32:05 +02:00
parent f463ba8496
commit 66379bfa65
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
4 changed files with 116 additions and 2 deletions

View File

View File

@ -0,0 +1,112 @@
#ifndef CREATURELIB_RESOLVETARGET_HPP
#define CREATURELIB_RESOLVETARGET_HPP
#include <Arbutils/Collections/List.hpp>
#include <Arbutils/Memory/BorrowedPtr.hpp>
#include <vector>
#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<ArbUt::BorrowedPtr<Creature>> ResolveTargets(const CreatureIndex& index,
CreatureLib::Library::AttackTarget target,
const ArbUt::BorrowedPtr<Battle>& 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<Creature> 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<ArbUt::BorrowedPtr<Creature>>(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<Creature> arr[battle->GetCreaturesPerSide()];
size_t i = 0;
for (auto mon : battle->GetSides()[index.GetSideIndex()]->GetCreatures()) {
arr[i++] = mon;
}
return ArbUt::List<ArbUt::BorrowedPtr<Creature>>(arr, arr + i);
};
case CreatureLib::Library::AttackTarget::AllOpponent: {
ArbUt::BorrowedPtr<Creature> arr[battle->GetCreaturesPerSide()];
size_t i = 0;
for (auto mon : battle->GetSides()[index.GetSideIndex()]->GetCreatures()) {
arr[i++] = mon;
}
return ArbUt::List<ArbUt::BorrowedPtr<Creature>>(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

View File

@ -2,6 +2,7 @@
#include <Arbutils/Assert.hpp>
#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<AttackTurnChoice> choic
// TODO: Change attack
}
// FIXME: Resolve all targets
auto target = choice->GetUser()->GetBattle()->GetCreature(choice->GetTarget());
ArbUt::List<ArbUt::BorrowedPtr<Creature>> targets = {target};
ArbUt::List<ArbUt::BorrowedPtr<Creature>> 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;

View File

@ -49,6 +49,7 @@ namespace CreatureLib::Battling {
[[nodiscard]] const ArbUt::BorrowedPtr<const BattleLibrary>& 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<BaseTurnChoice>& choice);
virtual bool TrySetChoice(BaseTurnChoice* choice);