#ifndef CREATURELIB_CLAMPEDSTATISTICSET_HPP #define CREATURELIB_CLAMPEDSTATISTICSET_HPP #include "Exceptions/NotReachableException.hpp" #include "Statistic.hpp" namespace CreatureLib::Library { template class ClampedStatisticSet { protected: T _health; T _physicalAttack; T _physicalDefense; T _magicalAttack; T _magicalDefense; T _speed; public: ClampedStatisticSet(T health, T physicalAttack, T physicalDefense, T magicalAttack, T magicalDefense, T speed) : _health(health), _physicalAttack(physicalAttack), _physicalDefense(physicalDefense), _magicalAttack(magicalAttack), _magicalDefense(magicalDefense), _speed(speed) {} ClampedStatisticSet() : _health(0), _physicalAttack(0), _physicalDefense(0), _magicalAttack(0), _magicalDefense(0), _speed(0) {} inline T GetHealth() const { return _health; } inline T GetPhysicalAttack() const { return _physicalAttack; } inline T GetPhysicalDefense() const { return _physicalDefense; } inline T GetMagicalAttack() const { return _magicalAttack; } inline T GetMagicalDefense() const { return _magicalDefense; } inline T GetSpeed() const { return _speed; } [[nodiscard]] inline T GetStat(Statistic stat) const { switch (stat) { case CreatureLib::Library::Statistic::Health: return _health; case CreatureLib::Library::Statistic::PhysicalAttack: return _physicalAttack; case CreatureLib::Library::Statistic::PhysicalDefense: return _physicalDefense; case CreatureLib::Library::Statistic::MagicalAttack: return _magicalAttack; case CreatureLib::Library::Statistic::MagicalDefense: return _magicalDefense; case CreatureLib::Library::Statistic::Speed: return _speed; default: throw NotReachableException(); } } inline void SetStat(Statistic stat, T value) { if (value < Min) value = Min; else if (value > Max) value = Max; switch (stat) { case CreatureLib::Library::Statistic::Health: _health = value; break; case CreatureLib::Library::Statistic::PhysicalAttack: _physicalAttack = value; break; case CreatureLib::Library::Statistic::PhysicalDefense: _physicalDefense = value; break; case CreatureLib::Library::Statistic::MagicalAttack: _magicalAttack = value; break; case CreatureLib::Library::Statistic::MagicalDefense: _magicalDefense = value; break; case CreatureLib::Library::Statistic::Speed: _speed = value; break; default: throw NotReachableException(); } } #define ModifyStat(stat, symbol) \ { \ auto newValue = stat symbol amount; \ if (newValue < Min) \ newValue = Min; \ else if (newValue > Max) \ newValue = Max; \ if (stat == newValue) { \ return false; \ } \ stat = newValue; \ return true; \ } inline bool IncreaseStatBy(Statistic stat, T amount) { switch (stat) { case CreatureLib::Library::Statistic::Health: ModifyStat(_health, +) break; case CreatureLib::Library::Statistic::PhysicalAttack: ModifyStat(_physicalAttack, +) break; case CreatureLib::Library::Statistic::PhysicalDefense: ModifyStat(_physicalDefense, +) break; case CreatureLib::Library::Statistic::MagicalAttack: ModifyStat(_magicalAttack, +) break; case CreatureLib::Library::Statistic::MagicalDefense: ModifyStat(_magicalDefense, +) break; case CreatureLib::Library::Statistic::Speed: ModifyStat(_speed, +) break; default: throw NotReachableException(); } } inline bool DecreaseStatBy(Statistic stat, T amount) { switch (stat) { case CreatureLib::Library::Statistic::Health: ModifyStat(_health, -) break; case CreatureLib::Library::Statistic::PhysicalAttack: ModifyStat(_physicalAttack, -) break; case CreatureLib::Library::Statistic::PhysicalDefense: ModifyStat(_physicalDefense, -) break; case CreatureLib::Library::Statistic::MagicalAttack: ModifyStat(_magicalAttack, -) break; case CreatureLib::Library::Statistic::MagicalDefense: ModifyStat(_magicalDefense, -) break; case CreatureLib::Library::Statistic::Speed: ModifyStat(_speed, -) break; default: throw NotReachableException(); } } }; } #endif // CREATURELIB_CLAMPEDSTATISTICSET_HPP