diff --git a/src/Battling/Pokemon/CreatePokemon.cpp b/src/Battling/Pokemon/CreatePokemon.cpp index 0988b1d..e05ce26 100644 --- a/src/Battling/Pokemon/CreatePokemon.cpp +++ b/src/Battling/Pokemon/CreatePokemon.cpp @@ -80,8 +80,8 @@ PkmnLib::Battling::Pokemon* PkmnLib::Battling::CreatePokemon::Build() { auto ivs = CreatureLib::Library::StatisticSet(_ivHp, _ivAttack, _ivDefense, _ivSpAtt, _ivSpDef, _ivSpeed); auto evs = CreatureLib::Library::StatisticSet(_evHp, _evAttack, _evDefense, _evSpAtt, _evSpDef, _evSpeed); - if (_nature == 255) { - _nature = _library->GetNatureLibrary()->GetRandomNature(rand); + if (_nature.Empty()) { + _nature = _library->GetNatureLibrary()->GetRandomNatureName(rand); } auto shiny = false; @@ -96,8 +96,8 @@ PkmnLib::Battling::Pokemon* PkmnLib::Battling::CreatePokemon::Build() { pkmn->Initialize(); return pkmn; } -PkmnLib::Battling::CreatePokemon* PkmnLib::Battling::CreatePokemon::WithNature(const std::string& nature) { - _nature = _library->GetNatureLibrary()->GetNatureIdByName(nature); +PkmnLib::Battling::CreatePokemon* PkmnLib::Battling::CreatePokemon::WithNature(const Arbutils::CaseInsensitiveConstString& nature) { + _nature = nature; return this; } PkmnLib::Battling::CreatePokemon* PkmnLib::Battling::CreatePokemon::WithIndividualValues(uint8_t hp, uint8_t att, diff --git a/src/Battling/Pokemon/CreatePokemon.hpp b/src/Battling/Pokemon/CreatePokemon.hpp index 63507fd..9b0f586 100644 --- a/src/Battling/Pokemon/CreatePokemon.hpp +++ b/src/Battling/Pokemon/CreatePokemon.hpp @@ -13,7 +13,7 @@ namespace PkmnLib::Battling { std::string _nickname = ""; Arbutils::CaseInsensitiveConstString _ability = ""_cnc; - uint8_t _nature = 255; + Arbutils::CaseInsensitiveConstString _nature; CreatureLib::Library::Gender _gender = static_cast(-1); Arbutils::CaseInsensitiveConstString _heldItem = ""_cnc; uint32_t _identifier = 0; @@ -54,7 +54,7 @@ namespace PkmnLib::Battling { CreatePokemon* WithEffortValues(uint8_t hp, uint8_t att, uint8_t def, uint8_t spAtt, uint8_t spDef, uint8_t speed); - CreatePokemon* WithNature(const std::string& nature); + CreatePokemon* WithNature(const Arbutils::CaseInsensitiveConstString& nature); Pokemon* Build(); }; diff --git a/src/Battling/Pokemon/Pokemon.cpp b/src/Battling/Pokemon/Pokemon.cpp index d773555..e737bdf 100644 --- a/src/Battling/Pokemon/Pokemon.cpp +++ b/src/Battling/Pokemon/Pokemon.cpp @@ -1,8 +1,4 @@ #include "Pokemon.hpp" const PkmnLib::Library::Nature& PkmnLib::Battling::Pokemon::GetNature() const{ - if (_natureCache == nullptr){ - auto p = const_cast(this); - p->_natureCache = this->GetLibrary()->GetNatureLibrary()->GetNaturePtr(_nature); - } - return *_natureCache; + return this->GetLibrary()->GetNatureLibrary()->GetNatureByName(_nature); } diff --git a/src/Battling/Pokemon/Pokemon.hpp b/src/Battling/Pokemon/Pokemon.hpp index 0a60f8a..0dcf9ea 100644 --- a/src/Battling/Pokemon/Pokemon.hpp +++ b/src/Battling/Pokemon/Pokemon.hpp @@ -13,8 +13,7 @@ namespace PkmnLib::Battling { CreatureLib::Library::StatisticSet _individualValues; CreatureLib::Library::StatisticSet _effortValues; - uint8_t _nature; - const Library::Nature* _natureCache = nullptr; + Arbutils::CaseInsensitiveConstString _nature; const BattleLibrary* GetLibrary() const { return reinterpret_cast(_library); } @@ -25,7 +24,7 @@ namespace PkmnLib::Battling { const std::string& nickname, const CreatureLib::Library::TalentIndex& talent, List moves, CreatureLib::Library::StatisticSet individualValues, - CreatureLib::Library::StatisticSet effortValues, uint8_t nature) + CreatureLib::Library::StatisticSet effortValues, const Arbutils::CaseInsensitiveConstString& nature) : CreatureLib::Battling::Creature(library, species, forme, level, experience, uid, gender, coloring, heldItem, nickname, talent, std::move(moves)), _individualValues(individualValues), _effortValues(effortValues), _nature(nature) {} diff --git a/src/Library/Natures/NatureLibrary.hpp b/src/Library/Natures/NatureLibrary.hpp index 1c4d3d3..67a5464 100644 --- a/src/Library/Natures/NatureLibrary.hpp +++ b/src/Library/Natures/NatureLibrary.hpp @@ -1,57 +1,36 @@ #ifndef PKMNLIB_NATURELIBRARY_HPP #define PKMNLIB_NATURELIBRARY_HPP -#include +#include +#include +#include #include +#include #include #include #include "Nature.hpp" namespace PkmnLib::Library { class NatureLibrary { private: - std::unordered_map _keyLookup; - std::vector _natures; - uint8_t _current = 0; + Arbutils::Collections::Dictionary _items; public: - NatureLibrary(uint8_t size = 32) - : _keyLookup(std::unordered_map(size)), _natures(std::vector(size)) {} + explicit NatureLibrary(uint8_t size = 32) + : _items(Arbutils::Collections::Dictionary(size)) {} - uint8_t LoadNature(const std::string& name, const Nature& nature) { - auto find = _keyLookup.find(name); - if (find != _keyLookup.end()) { - auto key = _keyLookup[name]; - _natures[key] = nature; - return key; - } else { - auto key = _current; - _keyLookup[name] = key; - _natures[_current++] = nature; - return key; - } + inline void LoadNature(const Arbutils::CaseInsensitiveConstString& name, const Nature& nature) { + _items.Insert(name, nature); } - const Nature& GetNatureByName(const std::string& name) const { - auto find = _keyLookup.find(name); - if (find == _keyLookup.end()) { - throw CreatureException("Invalid nature name."); - } - return _natures[_keyLookup.at(name)]; + inline const Nature& GetNatureByName(const Arbutils::CaseInsensitiveConstString& name) const { + return _items[name]; } - const Nature& GetNature(uint8_t id) const { return _natures[id]; } - const Nature* GetNaturePtr(uint8_t id) const { return &_natures[id]; } - - uint8_t GetNatureIdByName(const std::string& name) const { - auto find = _keyLookup.find(name); - if (find == _keyLookup.end()) { - throw CreatureException("Invalid nature name."); - } - return _keyLookup.at(name); - } - - uint8_t GetRandomNature(Arbutils::Random rand = Arbutils::Random()) const{ - return rand.Get(_current); + inline const Arbutils::CaseInsensitiveConstString& + GetRandomNatureName(Arbutils::Random rand = Arbutils::Random()) const { + auto i = rand.Get(_items.Count()); + auto& map = _items.GetStdMap(); + return std::next(std::begin(map), i)->first; } }; } diff --git a/tests/LibraryTests/NatureLibraryTests.cpp b/tests/LibraryTests/NatureLibraryTests.cpp index 87f4bb2..fa55444 100644 --- a/tests/LibraryTests/NatureLibraryTests.cpp +++ b/tests/LibraryTests/NatureLibraryTests.cpp @@ -12,15 +12,15 @@ TEST_CASE("Able to create and delete nature library", "library") { TEST_CASE("Able to insert into nature library", "library") { auto lib = new NatureLibrary(); - lib->LoadNature("testNature", Nature(Statistic::PhysicalAttack, Statistic::Speed)); + lib->LoadNature("testNature"_cnc, Nature(Statistic::PhysicalAttack, Statistic::Speed)); delete lib; } TEST_CASE("Able to retrieve nature by name", "library") { auto lib = new NatureLibrary(); - lib->LoadNature("testNature", Nature(Statistic::PhysicalAttack, Statistic::Speed)); + lib->LoadNature("testNature"_cnc, Nature(Statistic::PhysicalAttack, Statistic::Speed)); - auto nature = lib->GetNatureByName("testNature"); + auto nature = lib->GetNatureByName("testNature"_cnc); REQUIRE(nature.GetIncreasedStat() == Statistic::PhysicalAttack); REQUIRE(nature.GetDecreasedStat() == Statistic::Speed); REQUIRE(nature.GetIncreaseModifier() == 1.1f); @@ -29,54 +29,4 @@ TEST_CASE("Able to retrieve nature by name", "library") { delete lib; } -TEST_CASE("Able to retrieve nature by id", "library") { - auto lib = new NatureLibrary(); - auto id = lib->LoadNature("testNature", Nature(Statistic::PhysicalAttack, Statistic::Speed)); - - auto nature = lib->GetNature(id); - REQUIRE(nature.GetIncreasedStat() == Statistic::PhysicalAttack); - REQUIRE(nature.GetDecreasedStat() == Statistic::Speed); - REQUIRE(nature.GetIncreaseModifier() == 1.1f); - REQUIRE(nature.GetDecreaseModifier() == 0.9f); - - delete lib; -} - -TEST_CASE("Able to retrieve nature id by name", "library") { - auto lib = new NatureLibrary(); - lib->LoadNature("testNature", Nature(Statistic::PhysicalAttack, Statistic::Speed)); - auto id = lib->GetNatureIdByName("testNature"); - REQUIRE(id == 0); - auto nature = lib->GetNature(id); - REQUIRE(nature.GetIncreasedStat() == Statistic::PhysicalAttack); - REQUIRE(nature.GetDecreasedStat() == Statistic::Speed); - REQUIRE(nature.GetIncreaseModifier() == 1.1f); - REQUIRE(nature.GetDecreaseModifier() == 0.9f); - - delete lib; -} - -TEST_CASE("Able to insert and retrieve multiple natures", "library") { - auto lib = new NatureLibrary(); - auto id = lib->LoadNature("testNature", Nature(Statistic::PhysicalAttack, Statistic::Speed)); - REQUIRE(id == 0); - auto id2 = lib->LoadNature("testNature2", Nature(Statistic::Speed, Statistic::PhysicalAttack)); - REQUIRE(id2 == 1); - auto nature = lib->GetNature(id); - REQUIRE(nature.GetIncreasedStat() == Statistic::PhysicalAttack); - REQUIRE(nature.GetDecreasedStat() == Statistic::Speed); - REQUIRE(nature.GetIncreaseModifier() == 1.1f); - REQUIRE(nature.GetDecreaseModifier() == 0.9f); - nature = lib->GetNature(id2); - REQUIRE(nature.GetIncreasedStat() == Statistic::Speed); - REQUIRE(nature.GetDecreasedStat() == Statistic::PhysicalAttack); - REQUIRE(nature.GetIncreaseModifier() == 1.1f); - REQUIRE(nature.GetDecreaseModifier() == 0.9f); - - delete lib; -} - - - - #endif \ No newline at end of file diff --git a/tests/LibraryTests/StatCalculationTests.cpp b/tests/LibraryTests/StatCalculationTests.cpp index d5f773b..de9c680 100644 --- a/tests/LibraryTests/StatCalculationTests.cpp +++ b/tests/LibraryTests/StatCalculationTests.cpp @@ -7,7 +7,7 @@ using namespace PkmnLib::Battling; TEST_CASE("Low level, no IVs, no EVs, neutral nature, no stat boosts stat test") { auto pkmn = - CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 10).WithNature("neutralNature")->Build(); + CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 10).WithNature("neutralNature"_cnc)->Build(); CHECK(pkmn->GetFlatStat(PkmnLib::Library::Statistic::HealthPoints) == 40); CHECK(pkmn->GetCurrentHealth() == 40); CHECK(pkmn->GetFlatStat(PkmnLib::Library::Statistic::PhysicalAttack) == 25); @@ -20,7 +20,7 @@ TEST_CASE("Low level, no IVs, no EVs, neutral nature, no stat boosts stat test") TEST_CASE("High level, no IVs, no EVs, neutral nature, no stat boosts stat test") { auto pkmn = - CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100).WithNature("neutralNature")->Build(); + CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100).WithNature("neutralNature"_cnc)->Build(); CHECK(pkmn->GetFlatStat(PkmnLib::Library::Statistic::HealthPoints) == 310); CHECK(pkmn->GetCurrentHealth() == 310); CHECK(pkmn->GetFlatStat(PkmnLib::Library::Statistic::PhysicalAttack) == 205); @@ -33,7 +33,7 @@ TEST_CASE("High level, no IVs, no EVs, neutral nature, no stat boosts stat test" TEST_CASE("Low level, max IVs, no EVs, neutral nature, no stat boosts stat test") { auto pkmn = CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 10) - .WithNature("neutralNature") + .WithNature("neutralNature"_cnc) ->WithIndividualValues(31, 31, 31, 31, 31, 31) ->Build(); CHECK(pkmn->GetFlatStat(PkmnLib::Library::Statistic::HealthPoints) == 43); @@ -48,7 +48,7 @@ TEST_CASE("Low level, max IVs, no EVs, neutral nature, no stat boosts stat test" TEST_CASE("High level, max IVs, no EVs, neutral nature, no stat boosts stat test") { auto pkmn = CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100) - .WithNature("neutralNature") + .WithNature("neutralNature"_cnc) ->WithIndividualValues(31, 31, 31, 31, 31, 31) ->Build(); CHECK(pkmn->GetFlatStat(PkmnLib::Library::Statistic::HealthPoints) == 341); @@ -63,7 +63,7 @@ TEST_CASE("High level, max IVs, no EVs, neutral nature, no stat boosts stat test TEST_CASE("High level, max IVs, max EVs, neutral nature, no stat boosts stat test") { auto pkmn = CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100) - .WithNature("neutralNature") + .WithNature("neutralNature"_cnc) ->WithIndividualValues(31, 31, 31, 31, 31, 31) ->WithEffortValues(255, 255, 255, 255, 255, 255) ->Build(); @@ -79,7 +79,7 @@ TEST_CASE("High level, max IVs, max EVs, neutral nature, no stat boosts stat tes TEST_CASE("High level, max IVs, max EVs, nature buffs attack, nerfs speed, no stat boosts stat test") { auto pkmn = CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100) - .WithNature("buffsAttackNerfsSpeed") + .WithNature("buffsAttackNerfsSpeed"_cnc) ->WithIndividualValues(31, 31, 31, 31, 31, 31) ->WithEffortValues(255, 255, 255, 255, 255, 255) ->Build(); @@ -95,7 +95,7 @@ TEST_CASE("High level, max IVs, max EVs, nature buffs attack, nerfs speed, no st TEST_CASE("High level, max IVs, max EVs, nature buffs attack, nerfs speed, Attack boosted +6 stat test") { auto pkmn = CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100) - .WithNature("buffsAttackNerfsSpeed") + .WithNature("buffsAttackNerfsSpeed"_cnc) ->WithIndividualValues(31, 31, 31, 31, 31, 31) ->WithEffortValues(255, 255, 255, 255, 255, 255) ->Build(); @@ -114,7 +114,7 @@ TEST_CASE("High level, max IVs, max EVs, nature buffs attack, nerfs speed, Attac TEST_CASE("High level, max IVs, max EVs, nature buffs attack, nerfs speed, Attack boosted -6 stat test") { auto pkmn = CreatePokemon(TestLibrary::GetLibrary(), "statTestSpecies1"_cnc, 100) - .WithNature("buffsAttackNerfsSpeed") + .WithNature("buffsAttackNerfsSpeed"_cnc) ->WithIndividualValues(31, 31, 31, 31, 31, 31) ->WithEffortValues(255, 255, 255, 255, 255, 255) ->Build(); diff --git a/tests/PokemonTests/BasicPokemonTests.cpp b/tests/PokemonTests/BasicPokemonTests.cpp index 3ba4f1f..0964637 100644 --- a/tests/PokemonTests/BasicPokemonTests.cpp +++ b/tests/PokemonTests/BasicPokemonTests.cpp @@ -12,7 +12,7 @@ TEST_CASE("Create and delete Pokemon"){ TEST_CASE("Get Nature from Pokemon"){ auto lib = TestLibrary::GetLibrary(); auto mon = PkmnLib::Battling::CreatePokemon(lib, "testSpecies"_cnc, 1) - .WithNature("neutralNature") + .WithNature("neutralNature"_cnc) ->Build(); auto nature = mon->GetNature(); REQUIRE(nature.GetDecreaseModifier() == 1); diff --git a/tests/TestLibrary/TestLibrary.hpp b/tests/TestLibrary/TestLibrary.hpp index d4bf492..1743665 100644 --- a/tests/TestLibrary/TestLibrary.hpp +++ b/tests/TestLibrary/TestLibrary.hpp @@ -64,9 +64,10 @@ public: static PkmnLib::Library::NatureLibrary* BuildNatureLibrary() { auto lib = new PkmnLib::Library::NatureLibrary(); - lib->LoadNature("neutralNature", PkmnLib::Library::Nature(PkmnLib::Library::Statistic::PhysicalAttack, - PkmnLib::Library::Statistic::PhysicalDefense, 1, 1)); - lib->LoadNature("buffsAttackNerfsSpeed", + lib->LoadNature("neutralNature"_cnc, + PkmnLib::Library::Nature(PkmnLib::Library::Statistic::PhysicalAttack, + PkmnLib::Library::Statistic::PhysicalDefense, 1, 1)); + lib->LoadNature("buffsAttackNerfsSpeed"_cnc, PkmnLib::Library::Nature(PkmnLib::Library::Statistic::PhysicalAttack, PkmnLib::Library::Statistic::Speed, 1.1, 0.9)); return lib;