2019-10-17 12:33:25 +00:00
|
|
|
#ifndef CREATURELIB_BATTLE_HPP
|
|
|
|
#define CREATURELIB_BATTLE_HPP
|
|
|
|
|
2020-03-22 12:42:26 +00:00
|
|
|
#include <Arbutils/Assert.hpp>
|
2020-03-22 18:21:40 +00:00
|
|
|
#include <Arbutils/Collections/List.hpp>
|
2020-05-26 16:31:06 +00:00
|
|
|
#include <memory>
|
2019-12-15 11:24:08 +00:00
|
|
|
#include "../EventHooks/EventHook.hpp"
|
2019-11-28 11:55:22 +00:00
|
|
|
#include "../Flow/ChoiceQueue.hpp"
|
2019-10-17 12:33:25 +00:00
|
|
|
#include "../Library/BattleLibrary.hpp"
|
2019-10-29 10:19:25 +00:00
|
|
|
#include "../TurnChoices/BaseTurnChoice.hpp"
|
2019-12-05 11:56:41 +00:00
|
|
|
#include "BattleParty.hpp"
|
2020-02-16 14:08:22 +00:00
|
|
|
#include "BattleRandom.hpp"
|
2019-12-15 10:52:10 +00:00
|
|
|
#include "BattleResult.hpp"
|
2019-11-28 11:55:22 +00:00
|
|
|
#include "BattleSide.hpp"
|
2019-12-05 08:53:48 +00:00
|
|
|
#include "CreatureIndex.hpp"
|
2019-10-17 12:33:25 +00:00
|
|
|
|
|
|
|
namespace CreatureLib::Battling {
|
2019-11-28 11:55:22 +00:00
|
|
|
class Battle : public ScriptSource {
|
2020-04-18 13:22:25 +00:00
|
|
|
protected:
|
2020-05-26 16:31:06 +00:00
|
|
|
ArbUt::BorrowedPtr<const BattleLibrary> _library;
|
2020-05-31 17:01:45 +00:00
|
|
|
ArbUt::UniquePtrList<BattleParty> _parties;
|
2019-12-15 10:52:10 +00:00
|
|
|
bool _canFlee;
|
2019-10-31 11:02:23 +00:00
|
|
|
uint8_t _numberOfSides;
|
|
|
|
uint8_t _creaturesPerSide;
|
2020-05-31 17:01:45 +00:00
|
|
|
ArbUt::UniquePtrList<BattleSide> _sides;
|
2020-02-16 14:08:22 +00:00
|
|
|
BattleRandom _random;
|
2020-05-31 17:01:45 +00:00
|
|
|
std::unique_ptr<ChoiceQueue> _currentTurnQueue = nullptr;
|
2019-12-07 20:56:29 +00:00
|
|
|
bool _hasEnded = false;
|
2019-12-15 10:52:10 +00:00
|
|
|
BattleResult _battleResult = BattleResult::Empty();
|
2020-07-31 17:52:12 +00:00
|
|
|
EventHook _eventHook;
|
2020-03-22 14:25:38 +00:00
|
|
|
uint32_t _currentTurn = 0;
|
2019-11-06 17:04:00 +00:00
|
|
|
|
2019-11-10 13:32:05 +00:00
|
|
|
ScriptSet _volatile;
|
2019-11-28 11:55:22 +00:00
|
|
|
|
2019-10-17 12:33:25 +00:00
|
|
|
public:
|
2020-05-26 16:31:06 +00:00
|
|
|
Battle(const BattleLibrary* library, ArbUt::List<BattleParty*> parties, bool canFlee = true,
|
2020-07-26 08:16:25 +00:00
|
|
|
uint8_t numberOfSides = 2, uint8_t creaturesPerSide = 1,
|
|
|
|
uint_fast32_t randomSeed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
|
|
std::chrono::system_clock::now().time_since_epoch())
|
|
|
|
.count())
|
2020-05-31 17:01:45 +00:00
|
|
|
: _library(library), _parties(parties.GetStdList()), _canFlee(canFlee), _numberOfSides(numberOfSides),
|
2020-07-26 08:16:25 +00:00
|
|
|
_creaturesPerSide(creaturesPerSide), _sides(numberOfSides), _random(randomSeed) {
|
2020-04-25 08:41:15 +00:00
|
|
|
AssertNotNull(_library);
|
|
|
|
AssertAllNotNull(parties);
|
2020-03-22 12:42:26 +00:00
|
|
|
|
2019-12-05 11:56:41 +00:00
|
|
|
for (size_t i = 0; i < numberOfSides; i++) {
|
2020-04-25 08:41:15 +00:00
|
|
|
_sides.Append(new BattleSide(i, this, creaturesPerSide));
|
2019-12-05 11:56:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-31 17:01:45 +00:00
|
|
|
virtual ~Battle() = default;
|
2019-12-05 11:56:41 +00:00
|
|
|
|
2020-05-26 16:31:06 +00:00
|
|
|
[[nodiscard]] const ArbUt::BorrowedPtr<const BattleLibrary>& GetLibrary() const noexcept;
|
2020-03-22 14:25:38 +00:00
|
|
|
[[nodiscard]] uint32_t GetCurrentTurn() const noexcept { return _currentTurn; }
|
2020-06-05 13:32:05 +00:00
|
|
|
inline uint8_t GetCreaturesPerSide() const noexcept { return _creaturesPerSide; }
|
2019-10-29 10:19:25 +00:00
|
|
|
|
2020-05-31 16:00:39 +00:00
|
|
|
virtual bool CanUse(const ArbUt::BorrowedPtr<BaseTurnChoice>& choice);
|
2019-10-29 10:19:25 +00:00
|
|
|
virtual bool TrySetChoice(BaseTurnChoice* choice);
|
2019-10-31 11:02:23 +00:00
|
|
|
|
2020-03-25 18:07:36 +00:00
|
|
|
bool CanFlee() const noexcept { return _canFlee; }
|
2019-12-15 10:52:10 +00:00
|
|
|
|
2019-10-31 11:02:23 +00:00
|
|
|
void CheckChoicesSetAndRun();
|
|
|
|
|
2020-05-31 17:01:45 +00:00
|
|
|
[[nodiscard]] ArbUt::BorrowedPtr<ChoiceQueue> GetCurrentTurnQueue() const noexcept;
|
2020-03-25 18:07:36 +00:00
|
|
|
BattleRandom* GetRandom() noexcept;
|
2019-11-02 12:57:43 +00:00
|
|
|
|
2020-06-02 11:06:24 +00:00
|
|
|
bool CreatureInField(ArbUt::BorrowedPtr<Creature> creature) const;
|
2019-11-02 12:57:43 +00:00
|
|
|
|
2020-06-02 11:06:24 +00:00
|
|
|
const ArbUt::BorrowedPtr<Creature>& GetCreature(const CreatureIndex& target) const {
|
2019-11-02 12:57:43 +00:00
|
|
|
return _sides[target.GetSideIndex()]->GetCreature(target.GetCreatureIndex());
|
|
|
|
}
|
2020-06-02 11:06:24 +00:00
|
|
|
const ArbUt::BorrowedPtr<Creature>& GetCreature(uint8_t side, uint8_t target) const {
|
|
|
|
return _sides[side]->GetCreature(target);
|
|
|
|
}
|
2019-11-06 17:04:00 +00:00
|
|
|
|
|
|
|
void ForceRecall(uint8_t side, uint8_t index);
|
2019-12-05 11:56:41 +00:00
|
|
|
void SwitchCreature(uint8_t side, uint8_t index, Creature* c);
|
2019-12-07 11:13:12 +00:00
|
|
|
bool CanSlotBeFilled(uint8_t side, uint8_t index) const;
|
2019-11-10 13:32:05 +00:00
|
|
|
|
2020-04-25 09:33:25 +00:00
|
|
|
size_t ScriptCount() const override;
|
2020-05-26 16:31:06 +00:00
|
|
|
void GetActiveScripts(ArbUt::List<ScriptWrapper>& scripts) override;
|
2019-12-07 20:56:29 +00:00
|
|
|
|
|
|
|
void ValidateBattleState();
|
2020-03-25 18:07:36 +00:00
|
|
|
inline bool HasEnded() const noexcept { return _hasEnded; }
|
|
|
|
inline const BattleResult& GetResult() const noexcept { return _battleResult; }
|
2019-12-14 11:40:50 +00:00
|
|
|
|
2020-05-31 17:01:45 +00:00
|
|
|
const ArbUt::UniquePtrList<BattleParty>& GetParties() const noexcept { return _parties; }
|
|
|
|
const ArbUt::UniquePtrList<BattleSide>& GetSides() const noexcept { return _sides; }
|
2020-06-26 15:08:23 +00:00
|
|
|
ArbUt::BorrowedPtr<Script> GetVolatileScript(const ArbUt::StringView& key) const { return _volatile.Get(key); }
|
2020-06-02 13:03:31 +00:00
|
|
|
ArbUt::BorrowedPtr<Script> GetVolatileScript(uint32_t keyHash) const noexcept { return _volatile.Get(keyHash); }
|
2020-06-26 16:23:40 +00:00
|
|
|
void AddVolatileScript(const ArbUt::StringView& key);
|
2020-02-23 10:11:47 +00:00
|
|
|
void AddVolatileScript(Script* script);
|
2020-06-26 15:08:23 +00:00
|
|
|
void RemoveVolatileScript(const ArbUt::BasicStringView& name) { _volatile.Remove(name); }
|
2020-03-09 09:16:57 +00:00
|
|
|
void RemoveVolatileScript(uint32_t keyHash) { _volatile.Remove(keyHash); }
|
2020-02-23 10:11:47 +00:00
|
|
|
void RemoveVolatileScript(Script* script);
|
2020-06-26 15:08:23 +00:00
|
|
|
bool HasVolatileScript(const ArbUt::BasicStringView& name) const { return _volatile.Has(name); }
|
2020-03-09 09:16:57 +00:00
|
|
|
bool HasVolatileScript(uint32_t keyHash) const { return _volatile.Has(keyHash); }
|
2020-07-31 14:19:39 +00:00
|
|
|
const EventHook& GetEventHook() const noexcept { return _eventHook; }
|
2019-12-15 11:24:08 +00:00
|
|
|
|
2020-07-31 14:19:39 +00:00
|
|
|
void DisplayText(const ArbUt::StringView& text);
|
2020-07-31 16:39:47 +00:00
|
|
|
void RegisterEventListener(EventHook::EventHookFunc listener) { this->_eventHook.RegisterListener(listener); }
|
2020-07-31 14:19:39 +00:00
|
|
|
template <class T, class... parameters> void TriggerEventListener(parameters... args) {
|
|
|
|
this->_eventHook.Trigger<T>(args...);
|
|
|
|
}
|
2019-10-17 12:33:25 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-11-28 11:55:22 +00:00
|
|
|
#endif // CREATURELIB_BATTLE_HPP
|