Replace most collections with Arbutils collections for more safety.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2020-03-22 19:21:40 +01:00
parent f190121e74
commit 27288563cd
40 changed files with 234 additions and 226 deletions

View File

@@ -84,7 +84,7 @@ bool Battle::CreatureInField(const Creature* creature) const {
void Battle::ForceRecall(uint8_t side, uint8_t index) { _sides[side]->SetCreature(nullptr, index); }
void Battle::GetActiveScripts(std::vector<ScriptWrapper>& scripts) { scripts.emplace_back(&_volatile); }
void Battle::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) { scripts.Append(&_volatile); }
void Battle::SwitchCreature(uint8_t sideIndex, uint8_t index, Creature* c) {
AssertNotNull(c)
@@ -105,7 +105,7 @@ bool Battle::CanSlotBeFilled(uint8_t side, uint8_t index) const {
void Battle::ValidateBattleState() {
bool survivingSideExists = false;
uint8_t winningSide = 0;
for (uint8_t i = 0; i < _sides.size(); i++) {
for (uint8_t i = 0; i < _sides.Count(); i++) {
auto side = _sides[i];
if (side->HasFled()) {
this->_battleResult = BattleResult::Inconclusive();

View File

@@ -2,7 +2,7 @@
#define CREATURELIB_BATTLE_HPP
#include <Arbutils/Assert.hpp>
#include <vector>
#include <Arbutils/Collections/List.hpp>
#include "../EventHooks/EventHook.hpp"
#include "../Flow/ChoiceQueue.hpp"
#include "../Library/BattleLibrary.hpp"
@@ -13,14 +13,16 @@
#include "BattleSide.hpp"
#include "CreatureIndex.hpp"
using namespace Arbutils::Collections;
namespace CreatureLib::Battling {
class Battle : public ScriptSource {
const BattleLibrary* _library;
std::vector<BattleParty*> _parties;
List<BattleParty*> _parties;
bool _canFlee;
uint8_t _numberOfSides;
uint8_t _creaturesPerSide;
std::vector<BattleSide*> _sides;
List<BattleSide*> _sides;
BattleRandom _random;
ChoiceQueue* _currentTurnQueue = nullptr;
bool _hasEnded = false;
@@ -31,15 +33,15 @@ namespace CreatureLib::Battling {
ScriptSet _volatile;
public:
Battle(const BattleLibrary* library, std::vector<BattleParty*> parties, bool canFlee = true,
uint8_t numberOfSides = 2, uint8_t creaturesPerSide = 1)
Battle(const BattleLibrary* library, List<BattleParty*> parties, bool canFlee = true, 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);
_sides = List<BattleSide*>(numberOfSides);
for (size_t i = 0; i < numberOfSides; i++) {
_sides[i] = new BattleSide(i, this, creaturesPerSide);
}
@@ -71,7 +73,6 @@ 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); }
@@ -80,13 +81,13 @@ namespace CreatureLib::Battling {
void SwitchCreature(uint8_t side, uint8_t index, Creature* c);
bool CanSlotBeFilled(uint8_t side, uint8_t index) const;
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override;
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override;
void ValidateBattleState();
inline bool HasEnded() const { return _hasEnded; }
inline const BattleResult& GetResult() const { return _battleResult; }
const std::vector<BattleSide*>& GetSides() const { return _sides; }
const List<BattleSide*>& GetSides() const { return _sides; }
Script* GetVolatileScript(const ConstString& key) const { return _volatile.Get(key); }
Script* GetVolatileScript(uint32_t keyHash) const { return _volatile.Get(keyHash); }
void AddVolatileScript(const ConstString& key);

View File

@@ -2,28 +2,28 @@
#define CREATURELIB_BATTLEPARTY_HPP
#include <Arbutils/Assert.hpp>
#include <Arbutils/Collections/List.hpp>
#include "CreatureIndex.hpp"
#include "CreatureParty.hpp"
using namespace Arbutils::Collections;
namespace CreatureLib::Battling {
class BattleParty {
CreatureParty* _party;
std::vector<CreatureIndex> _responsibleIndices;
List<CreatureIndex> _responsibleIndices;
public:
BattleParty(CreatureParty* party, std::vector<CreatureIndex> responsibleIndices)
BattleParty(CreatureParty* party, const List<CreatureIndex>& responsibleIndices)
: _party(party), _responsibleIndices(responsibleIndices) {
AssertNotNull(_party)
}
inline CreatureParty* GetParty() const { return _party; }
inline const std::vector<CreatureIndex>& GetResponsibleIndices() const { return _responsibleIndices; }
inline const List<CreatureIndex>& GetResponsibleIndices() const { return _responsibleIndices; }
inline bool IsResponsibleForIndex(const CreatureIndex& index) const {
for (const auto& i : _responsibleIndices) {
if (i == index)
return true;
}
return false;
return _responsibleIndices.Contains(index);
}
inline bool IsResponsibleForIndex(uint8_t side, uint8_t index) const {

View File

@@ -9,7 +9,7 @@ bool BattleSide::AllChoicesSet() const { return _choicesSet == _creaturesPerSide
bool BattleSide::AllPossibleSlotsFilled() const {
AssertNotNull(_battle)
for (size_t i = 0; i < _creatures.size(); i++) {
for (size_t i = 0; i < _creatures.Count(); i++) {
auto c = _creatures[i];
if (c == nullptr || c->IsFainted()) {
if (_battle->CanSlotBeFilled(_index, i))
@@ -26,7 +26,7 @@ void BattleSide::ResetChoices() {
}
}
const std::vector<BaseTurnChoice*>& BattleSide::GetChoices() const { return _choices; }
const List<BaseTurnChoice*>& BattleSide::GetChoices() const { return _choices; }
void BattleSide::SetChoice(BaseTurnChoice* choice) {
AssertNotNull(choice)
@@ -68,8 +68,8 @@ bool BattleSide::CreatureOnSide(const Creature* creature) const {
Creature* BattleSide::GetCreature(uint8_t index) const { return _creatures[index]; }
void BattleSide::GetActiveScripts(std::vector<ScriptWrapper>& scripts) {
scripts.emplace_back(&_volatile);
void BattleSide::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
scripts.Append(&_volatile);
_battle->GetActiveScripts(scripts);
}
uint8_t BattleSide::GetRandomCreatureIndex() {

View File

@@ -2,17 +2,20 @@
#define CREATURELIB_BATTLESIDE_HPP
#include <Arbutils/Assert.hpp>
#include <Arbutils/Collections/List.hpp>
#include <vector>
#include "../TurnChoices/BaseTurnChoice.hpp"
#include "Creature.hpp"
using namespace Arbutils::Collections;
namespace CreatureLib::Battling {
class BattleSide : public ScriptSource {
uint8_t _index;
uint8_t _creaturesPerSide;
std::vector<Creature*> _creatures;
std::vector<BaseTurnChoice*> _choices;
std::vector<bool> _fillableSlots;
List<Creature*> _creatures;
List<BaseTurnChoice*> _choices;
List<bool> _fillableSlots;
uint8_t _choicesSet = 0;
ScriptSet _volatile;
Battle* _battle;
@@ -33,7 +36,7 @@ namespace CreatureLib::Battling {
virtual ~BattleSide() = default;
[[nodiscard]] bool AllChoicesSet() const;
[[nodiscard]] const std::vector<BaseTurnChoice*>& GetChoices() const;
[[nodiscard]] const List<BaseTurnChoice*>& GetChoices() const;
[[nodiscard]] bool AllPossibleSlotsFilled() const;
@@ -45,13 +48,13 @@ namespace CreatureLib::Battling {
Creature* GetCreature(uint8_t index) const;
bool CreatureOnSide(const Creature* creature) const;
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) final;
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) final;
const std::vector<Creature*>& GetCreatures() { return _creatures; }
const List<Creature*>& GetCreatures() { return _creatures; }
uint8_t GetSideIndex() { return _index; }
uint8_t GetCreatureIndex(Creature* c) {
for (size_t i = 0; i < _creatures.size(); i++) {
for (size_t i = 0; i < _creatures.Count(); i++) {
if (c == _creatures[i])
return i;
}
@@ -61,7 +64,7 @@ namespace CreatureLib::Battling {
void MarkSlotAsUnfillable(Creature* creature) {
for (uint8_t i = 0; i < _creaturesPerSide; i++) {
if (_creatures[i] == creature) {
_fillableSlots[i] = false;
_fillableSlots.At(i) = false;
return;
}
}

View File

@@ -22,11 +22,11 @@ CreateCreature* CreateCreature::WithGender(Library::Gender gender) {
CreateCreature* CreateCreature::WithAttack(const Arbutils::CaseInsensitiveConstString& attackName,
AttackLearnMethod learnMethod) {
if (_attacks.size() >= _library->GetSettings()->GetMaximalMoves())
if (_attacks.Count() >= _library->GetSettings()->GetMaximalMoves())
throw CreatureException("You have already set the maximum amount of allowed moves.");
auto attackData = _library->GetAttackLibrary()->Get(attackName);
_attacks.emplace_back(attackData, learnMethod);
_attacks.Append(std::tuple(attackData, learnMethod));
return this;
}
@@ -56,8 +56,8 @@ Creature* CreateCreature::Create() {
}
auto experience = _library->GetGrowthRateLibrary()->CalculateExperience(species->GetGrowthRate(), _level);
auto attacks = std::vector<LearnedAttack*>(_attacks.size());
for (size_t i = 0; i < attacks.size(); i++) {
auto attacks = List<LearnedAttack*>(_attacks.Count());
for (size_t i = 0; i < attacks.Count(); i++) {
auto kv = _attacks[i];
attacks[i] = new LearnedAttack(std::get<0>(kv), std::get<1>(kv));
}

View File

@@ -1,9 +1,12 @@
#ifndef CREATURELIB_CREATECREATURE_HPP
#define CREATURELIB_CREATECREATURE_HPP
#include <Arbutils/Collections/List.hpp>
#include "../../Library/DataLibrary.hpp"
#include "Creature.hpp"
using namespace Arbutils::Collections;
namespace CreatureLib::Battling {
class CreateCreature {
const BattleLibrary* _library;
@@ -17,7 +20,7 @@ namespace CreatureLib::Battling {
uint8_t _coloring = 0;
Arbutils::CaseInsensitiveConstString _heldItem = ""_cnc;
uint32_t _identifier = 0;
std::vector<std::tuple<const Library::AttackData*, AttackLearnMethod>> _attacks = {};
List<std::tuple<const Library::AttackData*, AttackLearnMethod>> _attacks = {};
public:
CreateCreature(const BattleLibrary* library, std::string species, uint8_t level)

View File

@@ -9,8 +9,7 @@ using namespace CreatureLib;
Battling::Creature::Creature(const BattleLibrary* library, const Library::CreatureSpecies* species,
const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience, uint32_t uid,
Library::Gender gender, uint8_t coloring, const Library::Item* heldItem,
std::string nickname, const Library::TalentIndex& talent,
std::vector<LearnedAttack*> attacks)
std::string nickname, const Library::TalentIndex& talent, List<LearnedAttack*> attacks)
: _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)) {
@@ -143,7 +142,7 @@ void Battling::Creature::OverrideActiveTalent(const ConstString& talent) {
_activeTalent = this->_library->LoadScript(ScriptCategory::Talent, talent);
}
const std::vector<uint8_t>& Battling::Creature::GetTypes() const noexcept {
const List<uint8_t>& Battling::Creature::GetTypes() const noexcept {
// HOOK: override types.
return this->_variant->GetTypes();
}
@@ -153,10 +152,10 @@ bool Battling::Creature::HasType(uint8_t type) const noexcept {
return std::find(t.begin(), t.end(), type) != t.end();
}
void Battling::Creature::GetActiveScripts(std::vector<ScriptWrapper>& scripts) {
scripts.emplace_back(&_activeTalent);
scripts.emplace_back(&_status);
scripts.emplace_back(&_volatile);
void Battling::Creature::GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) {
scripts.Append(&_activeTalent);
scripts.Append(&_status);
scripts.Append(&_volatile);
if (_side != nullptr) {
_side->GetActiveScripts(scripts);
}

View File

@@ -1,6 +1,7 @@
#ifndef CREATURELIB_BATTLECREATURE_HPP
#define CREATURELIB_BATTLECREATURE_HPP
#include <Arbutils/Collections/List.hpp>
#include "../../Library/CreatureData/CreatureSpecies.hpp"
#include "../../Library/Items/Item.hpp"
#include "../ScriptHandling/ScriptAggregator.hpp"
@@ -9,6 +10,8 @@
#include "DamageSource.hpp"
#include "LearnedAttack.hpp"
using namespace Arbutils::Collections;
namespace CreatureLib::Battling {
// Forward declare battle class
class Battle;
@@ -49,7 +52,7 @@ namespace CreatureLib::Battling {
ConstString _overridenTalentName = ""_cnc;
std::unordered_set<Creature*> _seenOpponents = {};
std::vector<LearnedAttack*> _attacks;
List<LearnedAttack*> _attacks;
Script* _status = nullptr;
ScriptSet _volatile = {};
@@ -61,7 +64,7 @@ namespace CreatureLib::Battling {
Creature(const BattleLibrary* library, const Library::CreatureSpecies* species,
const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience, uint32_t uid,
Library::Gender gender, uint8_t coloring, const Library::Item* heldItem, std::string nickname,
const Library::TalentIndex& talent, std::vector<LearnedAttack*> attacks);
const Library::TalentIndex& talent, List<LearnedAttack*> attacks);
virtual ~Creature() {
for (auto attack : _attacks) {
@@ -105,7 +108,7 @@ namespace CreatureLib::Battling {
const ConstString& GetActiveTalent() const;
[[nodiscard]] bool IsFainted() const noexcept;
[[nodiscard]] const std::vector<uint8_t>& GetTypes() const noexcept;
[[nodiscard]] const List<uint8_t>& GetTypes() const noexcept;
[[nodiscard]] bool HasType(uint8_t type) const noexcept;
uint32_t GetMaxHealth() const noexcept { return _boostedStats.GetHealth(); }
@@ -118,7 +121,7 @@ namespace CreatureLib::Battling {
void MarkOpponentAsSeen(Creature* creature) { _seenOpponents.insert(creature); }
const std::unordered_set<Creature*>& GetSeenOpponents() const { return _seenOpponents; }
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override;
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override;
void ClearVolatileScripts();
void AddVolatileScript(const ConstString& name);
void AddVolatileScript(Script* script);
@@ -126,7 +129,7 @@ namespace CreatureLib::Battling {
void RemoveVolatileScript(Script* script);
bool HasVolatileScript(const ConstString& name) const;
std::vector<LearnedAttack*>& GetAttacks() { return _attacks; }
List<LearnedAttack*>& GetAttacks() { return _attacks; }
const Library::CreatureSpecies* GetDisplaySpecies() const;
const Library::SpeciesVariant* GetDisplayVariant() const;

View File

@@ -1,16 +1,16 @@
#ifndef CREATURELIB_CREATUREPARTY_HPP
#define CREATURELIB_CREATUREPARTY_HPP
#include <array>
#include <Arbutils/Collections/List.hpp>
#include "Creature.hpp"
namespace CreatureLib::Battling {
class CreatureParty {
std::vector<Creature*> _party;
Arbutils::Collections::List<Creature*> _party;
public:
CreatureParty(size_t size) : _party(size) {}
CreatureParty(std::vector<Creature*> party) : _party(party) {}
CreatureParty(Arbutils::Collections::List<Creature*> party) : _party(party) {}
CreatureParty(std::initializer_list<Creature*> party) : _party(party) {}
virtual ~CreatureParty() {
@@ -38,10 +38,10 @@ namespace CreatureLib::Battling {
return false;
}
std::vector<Creature*>& GetParty() { return _party; }
const std::vector<Creature*>& GetParty() const { return _party; }
Arbutils::Collections::List<Creature*>& GetParty() { return _party; }
const Arbutils::Collections::List<Creature*>& GetParty() const { return _party; }
size_t GetLength() const { return _party.size(); }
size_t GetLength() const { return _party.Count(); }
};
}

View File

@@ -2,11 +2,15 @@
#define CREATURELIB_EXECUTINGATTACK_HPP
#include <Arbutils/Assert.hpp>
#include <Arbutils/Collections/Dictionary.hpp>
#include <Arbutils/Collections/List.hpp>
#include <cstdint>
#include <unordered_map>
#include <vector>
#include "Creature.hpp"
using namespace Arbutils::Collections;
namespace CreatureLib::Battling {
class ExecutingAttack : public ScriptSource {
public:
@@ -35,7 +39,7 @@ namespace CreatureLib::Battling {
class TargetData {
bool _isHit = true;
std::vector<HitData> _hits;
List<HitData> _hits;
public:
explicit TargetData(uint8_t numberOfHits) : _hits(numberOfHits) {
@@ -47,26 +51,25 @@ namespace CreatureLib::Battling {
HitData* GetHit(uint8_t index) { return &_hits[index]; }
uint8_t GetNumberOfHits() const { return _hits.size(); }
uint8_t GetNumberOfHits() const { return _hits.Count(); }
bool IsHit() const { return _isHit; }
};
private:
std::unordered_map<Creature*, TargetData> _targets;
Dictionary<Creature*, TargetData> _targets;
Creature* _user;
LearnedAttack* _attack;
Script* _script;
public:
ExecutingAttack(const std::vector<Creature*>& targets, uint8_t numberHits, Creature* user,
LearnedAttack* attack, Script* script)
: _user(user), _attack(attack), _script(script) {
ExecutingAttack(const List<Creature*>& targets, uint8_t numberHits, Creature* user, LearnedAttack* attack,
Script* script)
: _targets(targets.Count()), _user(user), _attack(attack), _script(script) {
AssertNotNull(user)
AssertNotNull(attack)
_targets.reserve(targets.size());
for (auto target : targets) {
_targets.insert({target, TargetData(numberHits)});
_targets.Insert(target, TargetData(numberHits));
}
}
@@ -74,17 +77,17 @@ namespace CreatureLib::Battling {
TargetData* GetAttackDataForTarget(Creature* creature) { return &_targets[creature]; }
bool IsCreatureTarget(Creature* creature) { return _targets.find(creature) != _targets.end(); }
bool IsCreatureTarget(Creature* creature) { return _targets.Has(creature); }
std::unordered_map<Creature*, TargetData>& GetTargets() { return _targets; }
Dictionary<Creature*, TargetData>& GetTargets() { return _targets; }
Creature* GetUser() { return _user; }
LearnedAttack* GetAttack() { return _attack; }
protected:
void GetActiveScripts(std::vector<ScriptWrapper>& scripts) override {
scripts.emplace_back(&_script);
void GetActiveScripts(Arbutils::Collections::List<ScriptWrapper>& scripts) override {
scripts.Append(&_script);
_user->GetActiveScripts(scripts);
}
};