Added lots of security using asserts.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
970ca8ddd5
commit
899e432271
|
@ -116,6 +116,8 @@ Standard: Cpp11
|
|||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
- Assert
|
||||
- AssertNotNull
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
...
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "EventHook.hpp"
|
|
@ -16,6 +16,7 @@ namespace CreatureLib::Battling {
|
|||
void RegisterListener(EVENT_HOOK_FUNC(func)) { _listeners.push_back(func); }
|
||||
|
||||
void TriggerEvent(EventData* eventData) const {
|
||||
AssertNotNull(eventData)
|
||||
for (auto listener : _listeners) {
|
||||
listener(eventData);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "ChoiceQueue.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
|
||||
bool CreatureLib::Battling::ChoiceQueue::MoveCreatureChoiceNext(CreatureLib::Battling::Creature* creature) {
|
||||
AssertNotNull(creature)
|
||||
// Find which index the creature choice is at.
|
||||
size_t choiceIndex = SIZE_MAX;
|
||||
for (size_t index = _current; index < _queue.size(); index++) {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#include "TurnHandler.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "../../Library/Exceptions/NotImplementedException.hpp"
|
||||
#include "../Models/Battle.hpp"
|
||||
#include "../ScriptHandling/ScriptMacros.hpp"
|
||||
|
||||
using namespace CreatureLib::Battling;
|
||||
|
||||
void TurnHandler::RunTurn(Battle* battle, ChoiceQueue* queue) {
|
||||
void TurnHandler::RunTurn(ChoiceQueue* queue) {
|
||||
AssertNotNull(queue)
|
||||
for (auto choice : queue->GetInnerQueue()) {
|
||||
HOOK(OnBeforeTurn, choice, choice);
|
||||
}
|
||||
|
@ -31,6 +32,7 @@ void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) {
|
|||
return;
|
||||
}
|
||||
auto battle = user->GetBattle();
|
||||
AssertNotNull(battle)
|
||||
// If the user is not in the field, we don't want to execute its choice.
|
||||
if (!battle->CreatureInField(user)) {
|
||||
return;
|
||||
|
@ -51,6 +53,7 @@ void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) {
|
|||
}
|
||||
|
||||
void TurnHandler::ExecuteAttackChoice(AttackTurnChoice* choice) {
|
||||
AssertNotNull(choice)
|
||||
auto attackName = choice->GetAttack()->GetAttack()->GetName();
|
||||
HOOK(ChangeAttack, choice, choice, &attackName);
|
||||
if (attackName != choice->GetAttack()->GetAttack()->GetName()) {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace CreatureLib::Battling {
|
|||
static void ExecuteFleeChoice(FleeTurnChoice* choice);
|
||||
|
||||
public:
|
||||
static void RunTurn(Battle* battle, ChoiceQueue* queue);
|
||||
static void RunTurn(ChoiceQueue* queue);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "BattleLibrary.hpp"
|
||||
#include <cassert>
|
||||
|
||||
using namespace CreatureLib::Battling;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "BattleStatCalculator.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "../../Library/Exceptions/NotImplementedException.hpp"
|
||||
#include "../Models/Creature.hpp"
|
||||
|
||||
|
@ -24,12 +25,14 @@ Battling::BattleStatCalculator::CalculateBoostedStats(Battling::Creature* creatu
|
|||
}
|
||||
|
||||
uint32_t CalculateHealthStat(Battling::Creature* creature) {
|
||||
AssertNotNull(creature)
|
||||
auto level = creature->GetLevel();
|
||||
auto a = (creature->GetBaseStat(Library::Statistic::Health)) * 2 * level;
|
||||
return floor(a / 100) + level + 10;
|
||||
}
|
||||
|
||||
uint32_t CalculateOtherStat(Battling::Creature* creature, Library::Statistic stat) {
|
||||
AssertNotNull(creature)
|
||||
auto level = creature->GetLevel();
|
||||
auto a = (creature->GetBaseStat(stat)) * 2 * level;
|
||||
return floor(a / 100) + 10;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "DamageLibrary.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "../ScriptHandling/ScriptMacros.hpp"
|
||||
|
||||
using namespace CreatureLib::Battling;
|
||||
uint32_t DamageLibrary::GetDamage(ExecutingAttack* attack, Creature* target, uint8_t hitIndex) const {
|
||||
AssertNotNull(attack)
|
||||
AssertNotNull(target)
|
||||
auto levelMod = static_cast<float>(2 * attack->GetUser()->GetLevel());
|
||||
auto hit = attack->GetAttackDataForTarget(target)->GetHit(hitIndex);
|
||||
auto bp = hit->GetBasePower();
|
||||
|
@ -15,13 +18,18 @@ uint32_t DamageLibrary::GetDamage(ExecutingAttack* attack, Creature* target, uin
|
|||
}
|
||||
|
||||
uint8_t DamageLibrary::GetBasePower(ExecutingAttack* attack, Creature* target, uint8_t hitIndex) const {
|
||||
AssertNotNull(attack)
|
||||
AssertNotNull(target)
|
||||
auto bp = attack->GetAttack()->GetAttack()->GetBasePower();
|
||||
HOOK(OverrideBasePower, attack, attack, target, hitIndex, &bp);
|
||||
return bp;
|
||||
}
|
||||
|
||||
float DamageLibrary::GetStatModifier(ExecutingAttack* attack, Creature* target, uint8_t hitIndex) const {
|
||||
AssertNotNull(attack)
|
||||
AssertNotNull(target)
|
||||
auto user = attack->GetUser();
|
||||
AssertNotNull(user)
|
||||
HOOK(ChangeDamageStatsUser, attack, attack, target, hitIndex, &user);
|
||||
auto hit = attack->GetAttackDataForTarget(target)->GetHit(hitIndex);
|
||||
Library::Statistic offensiveStat;
|
||||
|
@ -57,8 +65,11 @@ float DamageLibrary::GetStatModifier(ExecutingAttack* attack, Creature* target,
|
|||
}
|
||||
|
||||
float DamageLibrary::GetDamageModifier(ExecutingAttack* attack, Creature* target, uint8_t hitIndex) const {
|
||||
AssertNotNull(attack)
|
||||
AssertNotNull(target)
|
||||
float mod = 1;
|
||||
auto hit = attack->GetAttackDataForTarget(target)->GetHit(hitIndex);
|
||||
AssertNotNull(hit)
|
||||
mod *= hit->GetEffectiveness();
|
||||
HOOK(ModifyDamageModifier, attack, attack, target, hitIndex, &mod);
|
||||
return mod;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
void CreatureLib::Battling::ExperienceLibrary::HandleExperienceGain(
|
||||
CreatureLib::Battling::Creature* faintedMon, const std::unordered_set<Creature*>& opponents) const {
|
||||
for (auto opponent : opponents) {
|
||||
if (opponent == nullptr)
|
||||
continue;
|
||||
auto levelDiff = faintedMon->GetLevel() - opponent->GetLevel() + 10;
|
||||
if (levelDiff <= 0)
|
||||
continue;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#include "MiscLibrary.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "../Models/Battle.hpp"
|
||||
#include "../TurnChoices/AttackTurnChoice.hpp"
|
||||
|
||||
bool CreatureLib::Battling::MiscLibrary::IsCritical(CreatureLib::Battling::ExecutingAttack* attack,
|
||||
CreatureLib::Battling::Creature* target, uint8_t hit) const {
|
||||
AssertNotNull(target)
|
||||
auto rand = target->GetBattle()->GetRandom();
|
||||
return rand->Get(10) <= 0;
|
||||
}
|
||||
|
@ -31,6 +33,7 @@ static CreatureLib::Battling::LearnedAttack* GetReplacementAttack() {
|
|||
bool CreatureLib::Battling::MiscLibrary::CanFlee(FleeTurnChoice* switchChoice) const { return true; }
|
||||
CreatureLib::Battling::BaseTurnChoice*
|
||||
CreatureLib::Battling::MiscLibrary::ReplacementAttack(Creature* user, CreatureIndex target) const {
|
||||
AssertNotNull(user)
|
||||
auto sideTarget = 0;
|
||||
if (user->GetBattleSide()->GetSideIndex() == 0)
|
||||
sideTarget = 1;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "Battle.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "../../Library/Exceptions/NotImplementedException.hpp"
|
||||
#include "../Flow/TurnHandler.hpp"
|
||||
#include "../Flow/TurnOrdering.hpp"
|
||||
|
@ -9,6 +10,7 @@ using namespace CreatureLib::Battling;
|
|||
const BattleLibrary* Battle::GetLibrary() const { return _library; }
|
||||
|
||||
bool Battle::CanUse(const BaseTurnChoice* choice) {
|
||||
AssertNotNull(choice)
|
||||
if (choice->GetKind() == TurnChoiceKind::Attack) {
|
||||
// HOOK: change number of uses needed.
|
||||
return dynamic_cast<const AttackTurnChoice*>(choice)->GetAttack()->GetRemainingUses() > 1;
|
||||
|
@ -17,6 +19,7 @@ bool Battle::CanUse(const BaseTurnChoice* choice) {
|
|||
}
|
||||
|
||||
bool Battle::TrySetChoice(BaseTurnChoice* choice) {
|
||||
AssertNotNull(choice)
|
||||
if (!CanUse(choice))
|
||||
return false;
|
||||
choice->GetUser()->GetBattleSide()->SetChoice(choice);
|
||||
|
@ -40,9 +43,7 @@ void Battle::CheckChoicesSetAndRun() {
|
|||
auto i = 0;
|
||||
for (auto side : _sides) {
|
||||
for (BaseTurnChoice* choice : side->GetChoices()) {
|
||||
if (choice == nullptr) {
|
||||
throw CreatureException("Choice was null");
|
||||
}
|
||||
AssertNotNull(choice)
|
||||
if (choice->GetKind() == TurnChoiceKind::Attack) {
|
||||
auto attack = (dynamic_cast<AttackTurnChoice*>((choice)))->GetAttack();
|
||||
uint8_t uses = 1;
|
||||
|
@ -60,7 +61,7 @@ void Battle::CheckChoicesSetAndRun() {
|
|||
}
|
||||
TurnOrdering::OrderChoices(choices, _random.GetRNG());
|
||||
this->_currentTurnQueue = new ChoiceQueue(choices);
|
||||
TurnHandler::RunTurn(this, this->_currentTurnQueue);
|
||||
TurnHandler::RunTurn(this->_currentTurnQueue);
|
||||
if (this->_currentTurnQueue->HasCompletedQueue) {
|
||||
delete this->_currentTurnQueue;
|
||||
this->_currentTurnQueue = nullptr;
|
||||
|
@ -72,6 +73,7 @@ ChoiceQueue* Battle::GetCurrentTurnQueue() const { return _currentTurnQueue; }
|
|||
BattleRandom* Battle::GetRandom() { return &_random; }
|
||||
|
||||
bool Battle::CreatureInField(const Creature* creature) const {
|
||||
AssertNotNull(creature)
|
||||
for (auto s : _sides) {
|
||||
if (s->CreatureOnSide(creature))
|
||||
return true;
|
||||
|
@ -84,6 +86,7 @@ void Battle::ForceRecall(uint8_t side, uint8_t index) { _sides[side]->SetCreatur
|
|||
void Battle::GetActiveScripts(std::vector<ScriptWrapper>& scripts) { scripts.emplace_back(&_volatile); }
|
||||
|
||||
void Battle::SwitchCreature(uint8_t sideIndex, uint8_t index, Creature* c) {
|
||||
AssertNotNull(c)
|
||||
auto side = this->_sides[sideIndex];
|
||||
side->SetCreature(c, index);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_BATTLE_HPP
|
||||
#define CREATURELIB_BATTLE_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <vector>
|
||||
#include "../EventHooks/EventHook.hpp"
|
||||
#include "../Flow/ChoiceQueue.hpp"
|
||||
|
@ -33,6 +34,10 @@ namespace CreatureLib::Battling {
|
|||
uint8_t numberOfSides = 2, uint8_t creaturesPerSide = 1)
|
||||
: _library(library), _parties(std::move(parties)), _canFlee(canFlee), _numberOfSides(numberOfSides),
|
||||
_creaturesPerSide(creaturesPerSide) {
|
||||
AssertNotNull(_library)
|
||||
for (auto p : parties)
|
||||
AssertNotNull(p)
|
||||
|
||||
_sides = std::vector<BattleSide*>(numberOfSides);
|
||||
for (size_t i = 0; i < numberOfSides; i++) {
|
||||
_sides[i] = new BattleSide(i, this, creaturesPerSide);
|
||||
|
@ -64,6 +69,7 @@ namespace CreatureLib::Battling {
|
|||
bool CreatureInField(const Creature* creature) const;
|
||||
|
||||
Creature* GetCreature(const CreatureIndex& target) const {
|
||||
Assert(target.GetSideIndex() < _sides.size())
|
||||
return _sides[target.GetSideIndex()]->GetCreature(target.GetCreatureIndex());
|
||||
}
|
||||
Creature* GetCreature(uint8_t side, uint8_t target) const { return _sides[side]->GetCreature(target); }
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef CREATURELIB_BATTLEPARTY_HPP
|
||||
#define CREATURELIB_BATTLEPARTY_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "CreatureIndex.hpp"
|
||||
#include "CreatureParty.hpp"
|
||||
|
||||
namespace CreatureLib::Battling {
|
||||
class BattleParty {
|
||||
CreatureParty* _party;
|
||||
|
@ -11,7 +11,9 @@ namespace CreatureLib::Battling {
|
|||
|
||||
public:
|
||||
BattleParty(CreatureParty* party, std::vector<CreatureIndex> responsibleIndices)
|
||||
: _party(party), _responsibleIndices(responsibleIndices) {}
|
||||
: _party(party), _responsibleIndices(responsibleIndices) {
|
||||
AssertNotNull(_party)
|
||||
}
|
||||
|
||||
inline CreatureParty* GetParty() const { return _party; }
|
||||
inline const std::vector<CreatureIndex>& GetResponsibleIndices() const { return _responsibleIndices; }
|
||||
|
|
|
@ -8,6 +8,7 @@ using namespace CreatureLib::Battling;
|
|||
bool BattleSide::AllChoicesSet() const { return _choicesSet == _creaturesPerSide; }
|
||||
|
||||
bool BattleSide::AllPossibleSlotsFilled() const {
|
||||
AssertNotNull(_battle)
|
||||
for (size_t i = 0; i < _creatures.size(); i++) {
|
||||
auto c = _creatures[i];
|
||||
if (c == nullptr || c->IsFainted()) {
|
||||
|
@ -28,6 +29,7 @@ void BattleSide::ResetChoices() {
|
|||
const std::vector<BaseTurnChoice*>& BattleSide::GetChoices() const { return _choices; }
|
||||
|
||||
void BattleSide::SetChoice(BaseTurnChoice* choice) {
|
||||
AssertNotNull(choice)
|
||||
auto find = std::find(_creatures.begin(), _creatures.end(), choice->GetUser());
|
||||
if (find == _creatures.end())
|
||||
throw CreatureException("User not found");
|
||||
|
@ -37,6 +39,7 @@ void BattleSide::SetChoice(BaseTurnChoice* choice) {
|
|||
}
|
||||
|
||||
void BattleSide::SetCreature(Creature* creature, uint8_t index) {
|
||||
AssertNotNull(creature)
|
||||
auto old = _creatures[index];
|
||||
if (old != nullptr) {
|
||||
old->SetOnBattleField(false);
|
||||
|
@ -59,6 +62,7 @@ void BattleSide::SetCreature(Creature* creature, uint8_t index) {
|
|||
}
|
||||
|
||||
bool BattleSide::CreatureOnSide(const Creature* creature) const {
|
||||
AssertNotNull(creature)
|
||||
return std::find(_creatures.begin(), _creatures.end(), creature) != _creatures.end();
|
||||
}
|
||||
|
||||
|
@ -70,5 +74,6 @@ void BattleSide::GetActiveScripts(std::vector<ScriptWrapper>& scripts) {
|
|||
}
|
||||
uint8_t BattleSide::GetRandomCreatureIndex() {
|
||||
// TODO: Consider adding parameter to only get index for available creatures.
|
||||
AssertNotNull(_battle)
|
||||
return _battle->GetRandom()->Get(_creaturesPerSide);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_BATTLESIDE_HPP
|
||||
#define CREATURELIB_BATTLESIDE_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <vector>
|
||||
#include "../TurnChoices/BaseTurnChoice.hpp"
|
||||
#include "Creature.hpp"
|
||||
|
@ -19,10 +20,8 @@ namespace CreatureLib::Battling {
|
|||
|
||||
public:
|
||||
explicit BattleSide(uint8_t index, Battle* battle, uint8_t creaturesPerSide)
|
||||
: _index(index), _creaturesPerSide(creaturesPerSide), _battle(battle) {
|
||||
_creatures = std::vector<Creature*>(creaturesPerSide);
|
||||
_choices = std::vector<BaseTurnChoice*>(creaturesPerSide);
|
||||
_fillableSlots = std::vector<bool>(creaturesPerSide);
|
||||
: _index(index), _creaturesPerSide(creaturesPerSide), _creatures(creaturesPerSide),
|
||||
_choices(creaturesPerSide), _fillableSlots(creaturesPerSide), _battle(battle) {
|
||||
for (size_t i = 0; i < creaturesPerSide; i++) {
|
||||
_creatures[i] = nullptr;
|
||||
_choices[i] = nullptr;
|
||||
|
|
|
@ -14,6 +14,9 @@ Battling::Creature::Creature(const BattleLibrary* library, const Library::Creatu
|
|||
: _library(library), _species(species), _variant(variant), _level(level), _experience(experience),
|
||||
_uniqueIdentifier(uid), _gender(gender), _coloring(coloring), _heldItem(heldItem), _nickname(std::move(nickname)),
|
||||
_talentIndex(talent), _hasOverridenTalent(false), _attacks(std::move(attacks)) {
|
||||
AssertNotNull(library)
|
||||
AssertNotNull(species)
|
||||
AssertNotNull(variant)
|
||||
|
||||
_activeTalent = _library->LoadScript(ScriptCategory::Talent, GetActiveTalent());
|
||||
if (_nickname.empty()) {
|
||||
|
@ -84,7 +87,7 @@ Battling::Battle* Battling::Creature::GetBattle() const { return _battle; }
|
|||
|
||||
Battling::BattleSide* Battling::Creature::GetBattleSide() const { return _side; }
|
||||
|
||||
bool Battling::Creature::IsFainted() const { return this->_currentHealth <= 0; }
|
||||
bool Battling::Creature::IsFainted() const noexcept { return this->_currentHealth <= 0; }
|
||||
|
||||
void Battling::Creature::OnFaint() {
|
||||
// HOOK: On Faint
|
||||
|
@ -140,12 +143,12 @@ void Battling::Creature::OverrideActiveTalent(const ConstString& talent) {
|
|||
_activeTalent = this->_library->LoadScript(ScriptCategory::Talent, talent);
|
||||
}
|
||||
|
||||
const std::vector<uint8_t>& Battling::Creature::GetTypes() const {
|
||||
const std::vector<uint8_t>& Battling::Creature::GetTypes() const noexcept {
|
||||
// HOOK: override types.
|
||||
return this->_variant->GetTypes();
|
||||
}
|
||||
|
||||
bool Battling::Creature::HasType(uint8_t type) const {
|
||||
bool Battling::Creature::HasType(uint8_t type) const noexcept {
|
||||
auto t = GetTypes();
|
||||
return std::find(t.begin(), t.end(), type) != t.end();
|
||||
}
|
||||
|
|
|
@ -76,24 +76,24 @@ namespace CreatureLib::Battling {
|
|||
_currentHealth = GetBoostedStat(Library::Statistic::Health);
|
||||
}
|
||||
|
||||
inline const Library::CreatureSpecies* GetSpecies() const { return _species; }
|
||||
inline const Library::SpeciesVariant* GetVariant() const { return _variant; }
|
||||
inline uint8_t GetLevel() const { return _level; }
|
||||
inline uint32_t GetExperience() const { return _experience; }
|
||||
inline Library::Gender GetGender() const { return _gender; }
|
||||
inline uint8_t GetColoring() const { return _coloring; }
|
||||
inline bool HasHeldItem(const ConstString& name) const {
|
||||
inline const Library::CreatureSpecies* GetSpecies() const noexcept { return _species; }
|
||||
inline const Library::SpeciesVariant* GetVariant() const noexcept { return _variant; }
|
||||
inline uint8_t GetLevel() const noexcept { return _level; }
|
||||
inline uint32_t GetExperience() const noexcept { return _experience; }
|
||||
inline Library::Gender GetGender() const noexcept { return _gender; }
|
||||
inline uint8_t GetColoring() const noexcept { return _coloring; }
|
||||
inline bool HasHeldItem(const ConstString& name) const noexcept {
|
||||
return _heldItem != nullptr && _heldItem->GetName() == name;
|
||||
}
|
||||
inline bool HasHeldItem(uint32_t nameHash) const {
|
||||
inline bool HasHeldItem(uint32_t nameHash) const noexcept {
|
||||
return _heldItem != nullptr && _heldItem->GetName() == nameHash;
|
||||
}
|
||||
inline const Library::Item* GetHeldItem() const { return _heldItem; }
|
||||
inline const Library::Item* GetHeldItem() const noexcept { return _heldItem; }
|
||||
void SetHeldItem(const ConstString& itemName);
|
||||
void SetHeldItem(uint32_t itemNameHash);
|
||||
inline void SetHeldItem(const Library::Item* item) { _heldItem = item; };
|
||||
inline void SetHeldItem(const Library::Item* item) noexcept { _heldItem = item; };
|
||||
|
||||
inline uint32_t GetCurrentHealth() const { return _currentHealth; }
|
||||
inline uint32_t GetCurrentHealth() const noexcept { return _currentHealth; }
|
||||
|
||||
void SetBattleData(Battle* battle, BattleSide* side);
|
||||
Battle* GetBattle() const;
|
||||
|
@ -101,14 +101,14 @@ namespace CreatureLib::Battling {
|
|||
void SetOnBattleField(bool value) { _onBattleField = value; }
|
||||
bool IsOnBattleField() const { return _onBattleField; }
|
||||
|
||||
const std::string& GetNickname() const { return _nickname; }
|
||||
const std::string& GetNickname() const noexcept { return _nickname; }
|
||||
const ConstString& GetActiveTalent() const;
|
||||
|
||||
[[nodiscard]] bool IsFainted() const;
|
||||
[[nodiscard]] const std::vector<uint8_t>& GetTypes() const;
|
||||
[[nodiscard]] bool HasType(uint8_t type) const;
|
||||
[[nodiscard]] bool IsFainted() const noexcept;
|
||||
[[nodiscard]] const std::vector<uint8_t>& GetTypes() const noexcept;
|
||||
[[nodiscard]] bool HasType(uint8_t type) const noexcept;
|
||||
|
||||
uint32_t GetMaxHealth() const { return _boostedStats.GetHealth(); }
|
||||
uint32_t GetMaxHealth() const noexcept { return _boostedStats.GetHealth(); }
|
||||
void ChangeLevelBy(int8_t amount);
|
||||
void Damage(uint32_t damage, DamageSource source);
|
||||
void Heal(uint32_t amount, bool canRevive = false);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_EXECUTINGATTACK_HPP
|
||||
#define CREATURELIB_EXECUTINGATTACK_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -61,6 +62,8 @@ namespace CreatureLib::Battling {
|
|||
ExecutingAttack(const std::vector<Creature*>& targets, uint8_t numberHits, Creature* user,
|
||||
LearnedAttack* attack, Script* script)
|
||||
: _user(user), _attack(attack), _script(script) {
|
||||
AssertNotNull(user)
|
||||
AssertNotNull(attack)
|
||||
_targets.reserve(targets.size());
|
||||
for (auto target : targets) {
|
||||
_targets.insert({target, TargetData(numberHits)});
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include "LearnedAttack.hpp"
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
CreatureLib::Battling::LearnedAttack::LearnedAttack(CreatureLib::Library::AttackData* attack, uint8_t maxUses,
|
||||
AttackLearnMethod learnMethod)
|
||||
: _attack(attack), _maxUses(maxUses), _remainingUses(maxUses), _learnMethod(learnMethod) {}
|
||||
: _attack(attack), _maxUses(maxUses), _remainingUses(maxUses), _learnMethod(learnMethod) {
|
||||
AssertNotNull(_attack)
|
||||
}
|
||||
|
||||
CreatureLib::Battling::LearnedAttack::LearnedAttack(const CreatureLib::Library::AttackData* attack,
|
||||
AttackLearnMethod learnMethod)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "ScriptWrapper.hpp"
|
|
@ -29,6 +29,7 @@ namespace CreatureLib::Battling {
|
|||
public:
|
||||
AttackTurnChoice(Creature* user, LearnedAttack* attack, const CreatureIndex& target)
|
||||
: BaseTurnChoice(user), _attack(attack), _target(target) {
|
||||
AssertNotNull(attack)
|
||||
ResolveScript();
|
||||
}
|
||||
AttackTurnChoice(Creature* user, LearnedAttack* attack, const CreatureIndex& target, Script* script)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_BASETURNCHOICE_HPP
|
||||
#define CREATURELIB_BASETURNCHOICE_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "../ScriptHandling/ScriptSource.hpp"
|
||||
#include "TurnChoiceKind.hpp"
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ namespace CreatureLib::Battling {
|
|||
Creature* _newCreature;
|
||||
|
||||
public:
|
||||
SwitchTurnChoice(Creature* user, Creature* newCreature) : BaseTurnChoice(user), _newCreature(newCreature) {}
|
||||
SwitchTurnChoice(Creature* user, Creature* newCreature) : BaseTurnChoice(user), _newCreature(newCreature) {
|
||||
AssertNotNull(_newCreature)
|
||||
}
|
||||
|
||||
TurnChoiceKind GetKind() const final { return TurnChoiceKind::Switch; }
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_BASELIBRARY_HPP
|
||||
#define CREATURELIB_BASELIBRARY_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <Arbutils/ConstString.hpp>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
@ -21,21 +22,19 @@ namespace CreatureLib::Library {
|
|||
}
|
||||
|
||||
inline void Insert(const Arbutils::CaseInsensitiveConstString& key, const T* value) {
|
||||
AssertNotNull(value)
|
||||
_values.insert({key.GetHash(), value});
|
||||
}
|
||||
inline void Insert(uint32_t hashedKey, const T* value) { _values.insert({hashedKey, value}); }
|
||||
inline void Insert(uint32_t hashedKey, const T* value) {
|
||||
AssertNotNull(value)
|
||||
_values.insert({hashedKey, value});
|
||||
}
|
||||
|
||||
inline void Delete(const Arbutils::CaseInsensitiveConstString& key) { _values.erase(key.GetHash()); }
|
||||
inline void Delete(uint32_t hashedKey) { _values.erase({hashedKey}); }
|
||||
|
||||
bool TryGet(const Arbutils::CaseInsensitiveConstString& name, const T*& out) const {
|
||||
auto find = this->_values.find(name.GetHash());
|
||||
if (find == this->_values.end()) {
|
||||
out = nullptr;
|
||||
return false;
|
||||
}
|
||||
out = find->second;
|
||||
return true;
|
||||
return TryGet(name.GetHash(), out);
|
||||
}
|
||||
bool TryGet(uint32_t hashedKey, const T*& out) const {
|
||||
auto find = this->_values.find(hashedKey);
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#include "CreatureSpecies.hpp"
|
||||
#include <Arbutils/Assert.hpp>
|
||||
|
||||
using namespace CreatureLib::Library;
|
||||
|
||||
CreatureSpecies::CreatureSpecies(uint16_t id, const ConstString& name, const SpeciesVariant* defaultVariant,
|
||||
float genderRatio, const ConstString& growthRate, uint8_t captureRate)
|
||||
: _name(name), _id(id), _genderRate(genderRatio), _growthRate(growthRate), _captureRate(captureRate),
|
||||
_variants({{"default"_cnc, defaultVariant}}) {}
|
||||
_variants({{"default"_cnc, defaultVariant}}) {
|
||||
AssertNotNull(defaultVariant)
|
||||
}
|
||||
|
||||
bool CreatureSpecies::HasVariant(const ConstString& name) const { return _variants.find(name) != _variants.end(); }
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_LEARNABLEATTACKS_HPP
|
||||
#define CREATURELIB_LEARNABLEATTACKS_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "../Attacks/AttackData.hpp"
|
||||
|
@ -11,7 +12,12 @@ namespace CreatureLib::Library {
|
|||
|
||||
public:
|
||||
LearnableAttacks(size_t levelAttackCapacity)
|
||||
: _learnedByLevel(std::unordered_map<uint8_t, std::vector<const AttackData*>>(levelAttackCapacity)) {}
|
||||
: _learnedByLevel(std::unordered_map<uint8_t, std::vector<const AttackData*>>(levelAttackCapacity)) {
|
||||
for (auto kv : _learnedByLevel) {
|
||||
for (auto attack : kv.second)
|
||||
AssertNotNull(attack)
|
||||
}
|
||||
}
|
||||
|
||||
void AddLevelMove(uint8_t level, const AttackData* attack);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ const CreatureLib::Library::LearnableAttacks* CreatureLib::Library::SpeciesVaria
|
|||
|
||||
CreatureLib::Library::SpeciesVariant::SpeciesVariant(ConstString name, float height, float weight,
|
||||
uint32_t baseExperience, std::vector<uint8_t> types,
|
||||
CreatureLib::Library::StatisticSet<uint16_t> baseStats,
|
||||
const CreatureLib::Library::StatisticSet<uint16_t>& baseStats,
|
||||
std::vector<ConstString> talents,
|
||||
std::vector<ConstString> secretTalents,
|
||||
const LearnableAttacks* attacks)
|
||||
|
|
|
@ -23,14 +23,14 @@ namespace CreatureLib::Library {
|
|||
|
||||
private:
|
||||
std::vector<uint8_t> _types;
|
||||
const Library::StatisticSet<uint16_t> _baseStatistics;
|
||||
const Library::StatisticSet<uint16_t>& _baseStatistics;
|
||||
std::vector<ConstString> _talents;
|
||||
std::vector<ConstString> _secretTalents;
|
||||
const LearnableAttacks* _attacks;
|
||||
|
||||
public:
|
||||
SpeciesVariant(ConstString name, float height, float weight, uint32_t baseExperience,
|
||||
std::vector<uint8_t> types, Library::StatisticSet<uint16_t> baseStats,
|
||||
std::vector<uint8_t> types, const Library::StatisticSet<uint16_t>& baseStats,
|
||||
std::vector<ConstString> talents, std::vector<ConstString> secretTalents,
|
||||
const LearnableAttacks* attacks);
|
||||
|
||||
|
|
|
@ -6,7 +6,14 @@ CreatureLib::Library::DataLibrary::DataLibrary(LibrarySettings* settings, Creatu
|
|||
CreatureLib::Library::GrowthRateLibrary* growthRates,
|
||||
TypeLibrary* typeLibrary)
|
||||
: _settings(settings), _species(species), _attacks(attacks), _items(items), _growthRates(growthRates),
|
||||
_typeLibrary(typeLibrary) {}
|
||||
_typeLibrary(typeLibrary) {
|
||||
AssertNotNull(_settings)
|
||||
AssertNotNull(_species)
|
||||
AssertNotNull(_attacks)
|
||||
AssertNotNull(_items)
|
||||
AssertNotNull(_growthRates)
|
||||
AssertNotNull(_typeLibrary)
|
||||
}
|
||||
|
||||
const CreatureLib::Library::LibrarySettings* CreatureLib::Library::DataLibrary::GetSettings() const {
|
||||
return _settings;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef CREATURELIB_EXTERNGROWTHRATE_HPP
|
||||
#define CREATURELIB_EXTERNGROWTHRATE_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include "GrowthRate.hpp"
|
||||
namespace CreatureLib::Library {
|
||||
class ExternGrowthRate : public GrowthRate {
|
||||
|
@ -9,7 +10,10 @@ namespace CreatureLib::Library {
|
|||
|
||||
public:
|
||||
ExternGrowthRate(uint8_t (*calcLevel)(uint32_t), uint32_t (*calcExperience)(uint8_t level))
|
||||
: _calcLevel(calcLevel), _calcExperience(calcExperience) {}
|
||||
: _calcLevel(calcLevel), _calcExperience(calcExperience) {
|
||||
AssertNotNull(calcLevel)
|
||||
AssertNotNull(calcExperience)
|
||||
}
|
||||
|
||||
uint8_t CalculateLevel(uint32_t experience) const override { return _calcLevel(experience); }
|
||||
uint32_t CalculateExperience(uint8_t level) const override { return _calcExperience(level); }
|
||||
|
|
|
@ -20,7 +20,10 @@ namespace CreatureLib::Library {
|
|||
return _experience[_experience.size() - 1];
|
||||
}
|
||||
|
||||
uint32_t CalculateExperience(uint8_t level) const override { return _experience[level - 1]; }
|
||||
uint32_t CalculateExperience(uint8_t level) const override {
|
||||
Assert(level <= _experience.size())
|
||||
return _experience[level - 1];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace CreatureLib::Library {
|
|||
T _magicalDefense;
|
||||
T _speed;
|
||||
|
||||
private:
|
||||
StatisticSet<T>(const StatisticSet<T>& v) = delete;
|
||||
|
||||
public:
|
||||
StatisticSet(T health, T physicalAttack, T physicalDefense, T magicalAttack, T magicalDefense, T speed)
|
||||
: _health(health), _physicalAttack(physicalAttack), _physicalDefense(physicalDefense),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "TypeLibrary.hpp"
|
||||
#include <algorithm>
|
||||
#include <Arbutils/Assert.hpp>
|
||||
|
||||
using namespace CreatureLib::Library;
|
||||
|
||||
|
@ -12,6 +12,8 @@ float TypeLibrary::GetEffectiveness(uint8_t attacking, const std::vector<uint8_t
|
|||
}
|
||||
|
||||
float TypeLibrary::GetSingleEffectiveness(uint8_t attacking, uint8_t defensive) const {
|
||||
Assert(attacking < _effectiveness.size())
|
||||
Assert(defensive < _effectiveness.size())
|
||||
return _effectiveness[attacking][defensive];
|
||||
}
|
||||
|
||||
|
@ -36,5 +38,7 @@ uint8_t TypeLibrary::RegisterType(uint32_t key) {
|
|||
}
|
||||
|
||||
void TypeLibrary::SetEffectiveness(uint8_t attacking, uint8_t defensive, float effectiveness) {
|
||||
Assert(attacking < _effectiveness.size())
|
||||
Assert(defensive < _effectiveness.size())
|
||||
_effectiveness[attacking][defensive] = effectiveness;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,10 @@ using namespace CreatureLib;
|
|||
using namespace CreatureLib::Battling;
|
||||
|
||||
TEST_CASE("Turn ordering: Attack before pass", "[Battling]") {
|
||||
auto lib = TestLibrary::Get();
|
||||
auto learnedAttack = LearnedAttack(lib->GetAttackLibrary()->Get("standard"_cnc), AttackLearnMethod::Unknown);
|
||||
auto choice1 = new PassTurnChoice(nullptr);
|
||||
auto choice2 = new AttackTurnChoice(nullptr, nullptr, CreatureIndex(0, 0));
|
||||
auto choice2 = new AttackTurnChoice(nullptr, &learnedAttack, CreatureIndex(0, 0));
|
||||
auto vec = std::vector<BaseTurnChoice*>{choice1, choice2};
|
||||
auto rand = Arbutils::Random();
|
||||
TurnOrdering::OrderChoices(vec, rand);
|
||||
|
|
Loading…
Reference in New Issue