From 20b53833c46f649083b297c2475df7d79a9e42d6 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 23 Oct 2021 16:57:58 +0200 Subject: [PATCH] Cleans up HistoryHolder to be a lot less complicated (although possibly a bit slower), adds DamageHistory. Signed-off-by: Deukhoofd --- CInterface/Battling/HistoryHandler.cpp | 10 ++-- src/Battling/History/HistoryElementKind.hpp | 2 +- .../HistoryElements/AttackUseHistory.hpp | 9 ++-- .../History/HistoryElements/DamageHistory.hpp | 24 ++++++++++ .../HistoryElements/HistoryElement.hpp | 28 ++++++----- src/Battling/History/HistoryHolder.hpp | 46 +++---------------- src/Battling/Models/Battle.hpp | 2 +- src/Battling/Models/Creature.cpp | 2 + 8 files changed, 54 insertions(+), 69 deletions(-) create mode 100644 src/Battling/History/HistoryElements/DamageHistory.hpp diff --git a/CInterface/Battling/HistoryHandler.cpp b/CInterface/Battling/HistoryHandler.cpp index 3b1ade7..c5e52d0 100644 --- a/CInterface/Battling/HistoryHandler.cpp +++ b/CInterface/Battling/HistoryHandler.cpp @@ -4,19 +4,15 @@ using namespace CreatureLib::Battling; export const HistoryElement* CreatureLib_HistoryHandler_GetTopElement(const HistoryHolder* p) { - return p->GetTopElement().GetRaw(); + return p->GetTopElement().GetValue(); } export const HistoryElement* CreatureLib_HistoryHandler_GetLastUsedAttack(const HistoryHolder* p) { - auto res = p->GetLastUsedAttack(); - if (res.has_value()) { - return res.value(); - } - return nullptr; + return p->GetLastUsedAttack().GetValue(); } export HistoryElementKind CreatureLib_HistoryElement_GetKind(const HistoryElement* p) { return p->GetKind(); } export const HistoryElement* CreatureLib_HistoryElement_GetPrevious(const HistoryElement* p) { - return p->GetPrevious().GetRaw(); + return p->GetPrevious().GetValue(); } export const ExecutingAttack* CreatureLib_AttackUseHistory_GetAttack(const AttackUseHistory* p) { diff --git a/src/Battling/History/HistoryElementKind.hpp b/src/Battling/History/HistoryElementKind.hpp index dc54dd6..3fcdd60 100644 --- a/src/Battling/History/HistoryElementKind.hpp +++ b/src/Battling/History/HistoryElementKind.hpp @@ -1,5 +1,5 @@ #ifndef CREATURELIB_HISTORYELEMENTKIND_HPP #define CREATURELIB_HISTORYELEMENTKIND_HPP -ENUM(HistoryElementKind, uint8_t, AttackUse) +ENUM(HistoryElementKind, uint8_t, AttackUse, Damage) #endif // CREATURELIB_HISTORYELEMENTKIND_HPP diff --git a/src/Battling/History/HistoryElements/AttackUseHistory.hpp b/src/Battling/History/HistoryElements/AttackUseHistory.hpp index 15ab55b..1a1bbfa 100644 --- a/src/Battling/History/HistoryElements/AttackUseHistory.hpp +++ b/src/Battling/History/HistoryElements/AttackUseHistory.hpp @@ -7,17 +7,14 @@ namespace CreatureLib::Battling { class AttackUseHistory final : public HistoryElement { std::unique_ptr _attack; - protected: - void Clear() override { + public: + AttackUseHistory(u32 turn, const ExecutingAttack* attack) : HistoryElement(turn), _attack(attack) {} + ~AttackUseHistory() { if (_attack != nullptr) { _attack.reset(); } - HistoryElement::Clear(); } - public: - AttackUseHistory(const ExecutingAttack* attack) : _attack(attack) {} - HistoryElementKind GetKind() const noexcept override { return HistoryElementKind::AttackUse; } ArbUt::BorrowedPtr GetAttack() const noexcept { return _attack; } }; diff --git a/src/Battling/History/HistoryElements/DamageHistory.hpp b/src/Battling/History/HistoryElements/DamageHistory.hpp new file mode 100644 index 0000000..117acd5 --- /dev/null +++ b/src/Battling/History/HistoryElements/DamageHistory.hpp @@ -0,0 +1,24 @@ +#ifndef CREATURELIB_DAMAGEHISTORY_HPP +#define CREATURELIB_DAMAGEHISTORY_HPP +#include "HistoryElement.hpp" + +namespace CreatureLib::Battling { + class DamageHistory final : public HistoryElement { + ArbUt::BorrowedPtr _target; + u32 _amount; + DamageSource _source; + + public: + DamageHistory(u32 turn, ArbUt::BorrowedPtr target, u32 amount, + DamageSource source) + : HistoryElement(turn), _target(target), _amount(amount), _source(source) {} + + HistoryElementKind GetKind() const noexcept override { return HistoryElementKind::Damage; } + + inline ArbUt::BorrowedPtr GetTarget() const noexcept { return _target; } + inline u32 GetAmount() const noexcept { return _amount; } + inline DamageSource GetDamageSource() const noexcept { return _source; } + }; +} + +#endif // CREATURELIB_DAMAGEHISTORY_HPP diff --git a/src/Battling/History/HistoryElements/HistoryElement.hpp b/src/Battling/History/HistoryElements/HistoryElement.hpp index 4ebbef4..d89ec5f 100644 --- a/src/Battling/History/HistoryElements/HistoryElement.hpp +++ b/src/Battling/History/HistoryElements/HistoryElement.hpp @@ -5,25 +5,23 @@ namespace CreatureLib::Battling { class HistoryElement { - friend class HistoryHolder; - u8* _previousOffset = nullptr; - - protected: - virtual void Clear() { - if (_previousOffset != nullptr) { - GetPrevious()->Clear(); - } - } + ArbUt::OptionalUniquePtr _previous; + u32 _turnNumber; public: - virtual HistoryElementKind GetKind() const noexcept = 0; - ArbUt::BorrowedPtr GetPrevious() const noexcept { - return reinterpret_cast((u8*)this - _previousOffset); + HistoryElement(u32 turn) : _turnNumber(turn) {} + virtual ~HistoryElement() {} + + [[nodiscard]] virtual HistoryElementKind GetKind() const noexcept = 0; + [[nodiscard]] ArbUt::OptionalBorrowedPtr GetPrevious() const noexcept { + return _previous.GetValue(); } - ArbUt::BorrowedPtr GetPrevious() noexcept { - return reinterpret_cast((u8*)this - _previousOffset); - } + ArbUt::OptionalBorrowedPtr GetPrevious() noexcept { return _previous.GetValue(); } + + void SetPrevious(HistoryElement* el) noexcept { _previous = el; } + + inline u32 GetTurnNumber() const noexcept { return _turnNumber; } }; } diff --git a/src/Battling/History/HistoryHolder.hpp b/src/Battling/History/HistoryHolder.hpp index 59146c4..335b667 100644 --- a/src/Battling/History/HistoryHolder.hpp +++ b/src/Battling/History/HistoryHolder.hpp @@ -9,56 +9,24 @@ concept HistoryElementType = std::is_base_of(ptr); - } + HistoryHolder() {} HistoryHolder(const HistoryHolder&) = delete; HistoryHolder& operator=(const HistoryHolder&) = delete; - ~HistoryHolder() { - if (_top != nullptr) - _top->Clear(); - free(_memory); - } - - void Resize() { - _capacity += stepSize; - auto newPtr = realloc(_memory, _capacity); - if (newPtr == nullptr) { - THROW("Out of memory."); - } - _memory = static_cast(newPtr); - } + virtual ~HistoryHolder() { delete _top; } template void Register(parameters... args) { - if (_offset + sizeof(T) >= _capacity) { - Resize(); - } - u8* ptr = _memory + _offset; - T* element = new (ptr) T(args...); - _offset += sizeof(T); - if (_top != nullptr) { - element->_previousOffset = (u8*)sizeof(T); - } - _top = element; + auto* prev = _top; + _top = new T(args...); + _top->SetPrevious(prev); } - ArbUt::BorrowedPtr GetTopElement() const noexcept { return _top; } + [[nodiscard]] ArbUt::OptionalBorrowedPtr GetTopElement() const noexcept { return _top; } - std::optional> GetLastUsedAttack() const noexcept { + ArbUt::OptionalBorrowedPtr GetLastUsedAttack() const noexcept { const auto* c = _top; while (c != nullptr) { if (c->GetKind() == HistoryElementKind::AttackUse) diff --git a/src/Battling/Models/Battle.hpp b/src/Battling/Models/Battle.hpp index a7ab720..70ec42b 100644 --- a/src/Battling/Models/Battle.hpp +++ b/src/Battling/Models/Battle.hpp @@ -112,7 +112,7 @@ namespace CreatureLib::Battling { const EventHook& GetEventHook() const noexcept { return _eventHook; } template void RegisterHistoryElement(parameters... args) { - try_creature(this->_historyHolder.Register(args...); + try_creature(this->_historyHolder.Register(this->GetCurrentTurn(), args...); , "Exception occurred during history element registration."); } const HistoryHolder& GetHistory() const noexcept { return _historyHolder; } diff --git a/src/Battling/Models/Creature.cpp b/src/Battling/Models/Creature.cpp index 96cb839..103c714 100644 --- a/src/Battling/Models/Creature.cpp +++ b/src/Battling/Models/Creature.cpp @@ -1,6 +1,7 @@ #include "Creature.hpp" #include #include "../EventHooks/EventDataClasses.hpp" +#include "../History/HistoryElements/DamageHistory.hpp" #include "../Models/Battle.hpp" #include "../ScriptHandling/ScriptMacros.hpp" @@ -176,6 +177,7 @@ namespace CreatureLib::Battling { auto battle = this->GetBattle(); if (battle.HasValue()) { battle.GetValue()->TriggerEventListener(this, source, _currentHealth, newHealth); + battle.GetValue()->RegisterHistoryElement(this, damage, source); } _currentHealth = newHealth;