diff --git a/conanfile.py b/conanfile.py index 90bdc83..4062b21 100644 --- a/conanfile.py +++ b/conanfile.py @@ -12,7 +12,7 @@ class PkmnLibConan(ConanFile): generators = "cmake" exports_sources = "*" compiler = "clang" - requires = "CreatureLib/00582174fb98b79efe8106d8c4809828098da8c0@creaturelib/master" + requires = "CreatureLib/b98b470f0dd9e0cc1d7452d5fae4fcdfec2f7cba@creaturelib/master" def build(self): cmake = CMake(self) diff --git a/src/Battling/Library/BattleLibrary.cpp b/src/Battling/Library/BattleLibrary.cpp new file mode 100644 index 0000000..d60aa39 --- /dev/null +++ b/src/Battling/Library/BattleLibrary.cpp @@ -0,0 +1 @@ +#include "BattleLibrary.hpp" diff --git a/src/Battling/Library/BattleLibrary.hpp b/src/Battling/Library/BattleLibrary.hpp new file mode 100644 index 0000000..acc1f6f --- /dev/null +++ b/src/Battling/Library/BattleLibrary.hpp @@ -0,0 +1,29 @@ +#ifndef PKMNLIB_BATTLELIBRARY_HPP +#define PKMNLIB_BATTLELIBRARY_HPP + +#include +#include "../../Library/PokemonLibrary.hpp" + +namespace PkmnLib::Battling { + class BattleLibrary : public CreatureLib::Battling::BattleLibrary { + public: + BattleLibrary(Library::PokemonLibrary* staticLib, CreatureLib::Battling::BattleStatCalculator* statCalculator, + CreatureLib::Battling::DamageLibrary* damageLibrary, + CreatureLib::Battling::ExperienceLibrary* experienceLibrary, + CreatureLib::Battling::ScriptResolver* scriptResolver, + CreatureLib::Battling::MiscLibrary* miscLibrary) + : CreatureLib::Battling::BattleLibrary(staticLib, statCalculator, damageLibrary, experienceLibrary, + scriptResolver, miscLibrary) {} + + const Library::SpeciesLibrary* GetSpeciesLibrary() const { + return reinterpret_cast(CreatureLib::Battling::BattleLibrary::GetSpeciesLibrary()); + } + + const Library::ItemLibrary* GetItemLibrary() const { + return reinterpret_cast(CreatureLib::Battling::BattleLibrary::GetItemLibrary()); + } + + }; +} + +#endif // PKMNLIB_BATTLELIBRARY_HPP diff --git a/src/Battling/Pokemon/CreatePokemon.cpp b/src/Battling/Pokemon/CreatePokemon.cpp new file mode 100644 index 0000000..00ebf15 --- /dev/null +++ b/src/Battling/Pokemon/CreatePokemon.cpp @@ -0,0 +1,71 @@ +#include "CreatePokemon.hpp" +#include "../../Library/Statistic.hpp" +PkmnLib::Battling::CreatePokemon* PkmnLib::Battling::CreatePokemon::RandomizeIndividualValues(CreatureLib::Core::Random rand) { + _ivHp = rand.Get(0, 32); + _ivAttack = rand.Get(0, 32); + _ivDefense = rand.Get(0, 32); + _ivSpAtt = rand.Get(0, 32); + _ivSpDef = rand.Get(0, 32); + _ivSpeed = rand.Get(0, 32); + return this; +} + +PkmnLib::Battling::CreatePokemon* PkmnLib::Battling::CreatePokemon::SetIndividualValue(CreatureLib::Core::Statistic stat, uint8_t value) { + switch (stat) { + case PkmnLib::Library::Statistic::HealthPoints: _ivHp = value; break; + case PkmnLib::Library::Statistic::PhysicalAttack: _ivAttack = value; break; + case PkmnLib::Library::Statistic::PhysicalDefense: _ivDefense = value; break; + case PkmnLib::Library::Statistic::SpecialAttack: _ivSpAtt = value; break; + case PkmnLib::Library::Statistic::SpecialDefense: _ivSpDef = value; break; + case PkmnLib::Library::Statistic::Speed: _ivSpeed = value; break; + } + return this; +} + +PkmnLib::Battling::CreatePokemon* PkmnLib::Battling::CreatePokemon::SetEffortValue(CreatureLib::Core::Statistic stat, uint8_t value) { + switch (stat) { + case PkmnLib::Library::Statistic::HealthPoints: _evHp = value; break; + case PkmnLib::Library::Statistic::PhysicalAttack: _evAttack = value; break; + case PkmnLib::Library::Statistic::PhysicalDefense: _evDefense = value; break; + case PkmnLib::Library::Statistic::SpecialAttack: _evSpAtt = value; break; + case PkmnLib::Library::Statistic::SpecialDefense: _evSpDef = value; break; + case PkmnLib::Library::Statistic::Speed: _evSpeed = value; break; + } + return this; +} + +PkmnLib::Battling::Pokemon* PkmnLib::Battling::CreatePokemon::Build() { + auto rand = CreatureLib::Core::Random(); + auto species = this->_library->GetSpeciesLibrary()->GetPkmnSpecies(this->_species); + auto forme = species->GetForme(this->_variant); + int8_t ability; + if (this->_ability.empty()) { + ability = forme->GetRandomTalent(&rand); + } else { + ability = forme->GetTalentIndex(this->_ability); + } + auto identifier = this->_identifier; + if (identifier == 0) { + identifier = rand.Get(); + } + auto gender = this->_gender; + if (gender == static_cast(-1)) { + gender = species->GetRandomGender(rand); + } + const Library::Item* heldItem = nullptr; + if (!this->_heldItem.empty()) { + heldItem = _library->GetItemLibrary()->GetItem(this->_heldItem); + } + auto experience = _library->GetGrowthRateLibrary()->CalculateExperience(species->GetGrowthRate(), _level); + + auto attacks = std::vector(_attacks.size()); + for (size_t i = 0; i < attacks.size(); i++) { + auto kv = _attacks[i]; + attacks[i] = new LearnedMove(std::get<0>(kv), std::get<1>(kv)); + } + auto ivs = CreatureLib::Core::StatisticSet(_ivHp, _ivAttack, _ivDefense, _ivSpAtt, _ivSpDef, _ivSpeed); + auto evs = CreatureLib::Core::StatisticSet(_evHp, _evAttack, _evDefense, _evSpAtt, _evSpDef, _evSpeed); + + return new Pokemon(_library, species, forme, _level, experience, identifier, gender, _coloring, heldItem, _nickname, + ability, attacks, ivs, evs); +} diff --git a/src/Battling/Pokemon/CreatePokemon.hpp b/src/Battling/Pokemon/CreatePokemon.hpp new file mode 100644 index 0000000..3a60702 --- /dev/null +++ b/src/Battling/Pokemon/CreatePokemon.hpp @@ -0,0 +1,49 @@ +#ifndef PKMNLIB_CREATEPOKEMON_HPP +#define PKMNLIB_CREATEPOKEMON_HPP + +#include "Pokemon.hpp" + +#include +namespace PkmnLib::Battling { + class CreatePokemon { + private: + const BattleLibrary* _library; + std::string _species; + std::string _variant = "default"; + uint8_t _level; + std::string _nickname = ""; + + std::string _ability = ""; + CreatureLib::Library::Gender _gender = static_cast(-1); + uint8_t _coloring = 0; + std::string _heldItem = ""; + uint32_t _identifier = 0; + std::vector> _attacks = {}; + + uint8_t _ivHp = 0; + uint8_t _ivAttack = 0; + uint8_t _ivDefense = 0; + uint8_t _ivSpAtt = 0; + uint8_t _ivSpDef = 0; + uint8_t _ivSpeed = 0; + + uint8_t _evHp = 0; + uint8_t _evAttack = 0; + uint8_t _evDefense = 0; + uint8_t _evSpAtt = 0; + uint8_t _evSpDef = 0; + uint8_t _evSpeed = 0; + + public: + CreatePokemon(const BattleLibrary* library, std::string species, uint8_t level) + : _library(library), _species(std::move(species)), _level(level) {} + + CreatePokemon* RandomizeIndividualValues(CreatureLib::Core::Random rand = CreatureLib::Core::Random()); + CreatePokemon* SetIndividualValue(CreatureLib::Core::Statistic stat, uint8_t value); + CreatePokemon* SetEffortValue(CreatureLib::Core::Statistic stat, uint8_t value); + + Pokemon* Build(); + }; +} + +#endif // PKMNLIB_CREATEPOKEMON_HPP diff --git a/src/Battling/Pokemon/LearnedMove.cpp b/src/Battling/Pokemon/LearnedMove.cpp new file mode 100644 index 0000000..88464b8 --- /dev/null +++ b/src/Battling/Pokemon/LearnedMove.cpp @@ -0,0 +1 @@ +#include "LearnedMove.hpp" diff --git a/src/Battling/Pokemon/LearnedMove.hpp b/src/Battling/Pokemon/LearnedMove.hpp new file mode 100644 index 0000000..d45cb7a --- /dev/null +++ b/src/Battling/Pokemon/LearnedMove.hpp @@ -0,0 +1,14 @@ +#ifndef PKMNLIB_LEARNEDMOVE_HPP +#define PKMNLIB_LEARNEDMOVE_HPP + +#include +#include "../../Library/Moves/MoveData.hpp" +namespace PkmnLib::Battling { + class LearnedMove : public CreatureLib::Battling::LearnedAttack { + public: + LearnedMove(const Library::MoveData* move, CreatureLib::Battling::AttackLearnMethod learnMethod) + : CreatureLib::Battling::LearnedAttack(move, learnMethod){} + }; +} + +#endif // PKMNLIB_LEARNEDMOVE_HPP diff --git a/src/Battling/Pokemon/Pokemon.cpp b/src/Battling/Pokemon/Pokemon.cpp new file mode 100644 index 0000000..71f641f --- /dev/null +++ b/src/Battling/Pokemon/Pokemon.cpp @@ -0,0 +1 @@ +#include "Pokemon.hpp" diff --git a/src/Battling/Pokemon/Pokemon.hpp b/src/Battling/Pokemon/Pokemon.hpp new file mode 100644 index 0000000..4fd413c --- /dev/null +++ b/src/Battling/Pokemon/Pokemon.hpp @@ -0,0 +1,28 @@ +#ifndef PKMNLIB_POKEMON_HPP +#define PKMNLIB_POKEMON_HPP + +#include +#include +#include "../Library/BattleLibrary.hpp" +#include "LearnedMove.hpp" + +namespace PkmnLib::Battling { + class Pokemon : public CreatureLib::Battling::Creature { + private: + CreatureLib::Core::StatisticSet _individualValues; + CreatureLib::Core::StatisticSet _effortValues; + + public: + Pokemon(const BattleLibrary* library, const Library::PokemonSpecies* species, + const Library::PokemonForme* forme, uint8_t level, uint32_t experience, uint32_t uid, + CreatureLib::Library::Gender gender, uint8_t coloring, const Library::Item* heldItem, + const std::string& nickname, int8_t talent, std::vector moves, + CreatureLib::Core::StatisticSet individualValues, + CreatureLib::Core::StatisticSet effortValues) + : CreatureLib::Battling::Creature(library, species, forme, level, experience, uid, gender, coloring, + heldItem, nickname, talent, std::move(moves)), + _individualValues(individualValues), _effortValues(effortValues) {} + }; +} + +#endif // PKMNLIB_POKEMON_HPP diff --git a/src/Library/Moves/MoveLibrary.hpp b/src/Library/Moves/MoveLibrary.hpp index 14b982c..249828f 100644 --- a/src/Library/Moves/MoveLibrary.hpp +++ b/src/Library/Moves/MoveLibrary.hpp @@ -6,6 +6,8 @@ namespace PkmnLib::Library { class MoveLibrary : public CreatureLib::Library::AttackLibrary { public: + MoveLibrary(size_t initialCapacity = 32) : CreatureLib::Library::AttackLibrary(initialCapacity) {} + virtual const MoveData* operator[](const std::string& name) const { return GetAttack(name); } const MoveData* GetMove(const std::string& name) const { return GetAttack(name); } @@ -13,14 +15,13 @@ namespace PkmnLib::Library { const MoveData* GetAttack(const std::string& name) const { return reinterpret_cast(CreatureLib::Library::AttackLibrary::GetAttack(name)); } - void LoadAttack(const std::string& name, const MoveData* attack){ + void LoadAttack(const std::string& name, const MoveData* attack) { CreatureLib::Library::AttackLibrary::LoadAttack(name, attack); } - void LoadMove(const std::string& name, const MoveData* attack){ + void LoadMove(const std::string& name, const MoveData* attack) { CreatureLib::Library::AttackLibrary::LoadAttack(name, attack); } - }; } diff --git a/tests/PokemonTests/BasicPokemonTests.cpp b/tests/PokemonTests/BasicPokemonTests.cpp new file mode 100644 index 0000000..c9f5e96 --- /dev/null +++ b/tests/PokemonTests/BasicPokemonTests.cpp @@ -0,0 +1,12 @@ +#ifdef TESTS_BUILD +#include "../../extern/catch.hpp" +#include "../../src/Battling/Pokemon/CreatePokemon.hpp" +#include "../TestLibrary/TestLibrary.hpp" + +TEST_CASE("Create and delete Pokemon"){ + auto lib = TestLibrary::GetLibrary(); + auto mon = PkmnLib::Battling::CreatePokemon(lib, "testSpecies", 1).Build(); + delete mon; +} + +#endif \ No newline at end of file diff --git a/tests/TestLibrary/TestLibrary.cpp b/tests/TestLibrary/TestLibrary.cpp index 56a2b9d..76f2d31 100644 --- a/tests/TestLibrary/TestLibrary.cpp +++ b/tests/TestLibrary/TestLibrary.cpp @@ -1 +1,2 @@ #include "TestLibrary.hpp" +PkmnLib::Battling::BattleLibrary* TestLibrary::_library = nullptr; diff --git a/tests/TestLibrary/TestLibrary.hpp b/tests/TestLibrary/TestLibrary.hpp index ea17272..b28deab 100644 --- a/tests/TestLibrary/TestLibrary.hpp +++ b/tests/TestLibrary/TestLibrary.hpp @@ -1,21 +1,31 @@ #ifndef PKMNLIB_TESTLIBRARY_HPP #define PKMNLIB_TESTLIBRARY_HPP +#include +#include "../../src/Battling/Library/BattleLibrary.hpp" #include "../../src/Library/Moves/MoveLibrary.hpp" #include "../../src/Library/PokemonLibrary.hpp" class TestLibrary { private: - static PkmnLib::Library::PokemonLibrary* _library; + static PkmnLib::Battling::BattleLibrary* _library; public: - static PkmnLib::Library::PokemonLibrary* GetLibrary() { + static PkmnLib::Battling::BattleLibrary* GetLibrary() { if (_library == nullptr) { _library = BuildLibrary(); } return _library; } - static PkmnLib::Library::PokemonLibrary* BuildLibrary() { + static PkmnLib::Battling::BattleLibrary* BuildLibrary() { + auto statCalc = new CreatureLib::Battling::BattleStatCalculator(); + return new PkmnLib::Battling::BattleLibrary( + BuildStaticLibrary(), statCalc, new CreatureLib::Battling::DamageLibrary(), + new CreatureLib::Battling::ExperienceLibrary(), new CreatureLib::Battling::ScriptResolver(), + new CreatureLib::Battling::MiscLibrary()); + } + + static PkmnLib::Library::PokemonLibrary* BuildStaticLibrary() { return new PkmnLib::Library::PokemonLibrary(CreatureLib::Library::LibrarySettings(100, 4), BuildSpeciesLibrary(), BuildMoveLibrary(), BuildItemLibrary(), BuildGrowthRateLibrary(), BuildTypeLibrary(), BuildNatureLibrary()); @@ -23,6 +33,23 @@ public: static PkmnLib::Library::SpeciesLibrary* BuildSpeciesLibrary() { auto lib = new PkmnLib::Library::SpeciesLibrary(); + lib->LoadSpecies("testSpecies", new PkmnLib::Library::PokemonSpecies( + 1, "testSpecies", + new PkmnLib::Library::PokemonForme( + "default", 1.0f, 1.0f, 100, {0}, + CreatureLib::Core::StatisticSet(100, 100, 100, 100, 100, 100), + {"testAbility"}, {"testHiddenAbility"}, + new CreatureLib::Library::LearnableAttacks(100)), + 0.5f, "testGrowthRate", 100, 100)); + lib->LoadSpecies( + "testSpecies2", + new PkmnLib::Library::PokemonSpecies( + 2, "testSpecies2", + new PkmnLib::Library::PokemonForme( + "default", 1.0f, 1.0f, 100, {0}, + CreatureLib::Core::StatisticSet(100, 100, 100, 100, 100, 100), {"testAbility"}, + {"testHiddenAbility"}, new CreatureLib::Library::LearnableAttacks(100)), + 0.5f, "testGrowthRate", 100, 100)); return lib; } @@ -38,6 +65,7 @@ public: static CreatureLib::Library::GrowthRateLibrary* BuildGrowthRateLibrary() { auto lib = new CreatureLib::Library::GrowthRateLibrary(); + lib->AddGrowthRate("testGrowthRate", new CreatureLib::Library::LookupGrowthRate()); return lib; } @@ -50,7 +78,6 @@ public: auto lib = new PkmnLib::Library::NatureLibrary(); return lib; } - }; #endif // PKMNLIB_TESTLIBRARY_HPP