From 5dc6695f9e666ea636d498b6e73d7e01156d5ff3 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Thu, 2 Jan 2020 13:45:39 +0100 Subject: [PATCH] Implements system for saving Evolutions. --- src/Library/Evolutions/EvolutionData.hpp | 74 ++++++++++++++++++++++ src/Library/Evolutions/EvolutionMethod.hpp | 23 +++++++ src/Library/Species/PokemonSpecies.hpp | 5 ++ src/Library/TimeOfDay.hpp | 14 ++++ tests/LibraryTests/SpeciesTests.cpp | 25 ++++++++ 5 files changed, 141 insertions(+) create mode 100644 src/Library/Evolutions/EvolutionData.hpp create mode 100644 src/Library/Evolutions/EvolutionMethod.hpp create mode 100644 src/Library/TimeOfDay.hpp diff --git a/src/Library/Evolutions/EvolutionData.hpp b/src/Library/Evolutions/EvolutionData.hpp new file mode 100644 index 0000000..950545c --- /dev/null +++ b/src/Library/Evolutions/EvolutionData.hpp @@ -0,0 +1,74 @@ +#ifndef PKMNLIB_EVOLUTIONDATA_HPP +#define PKMNLIB_EVOLUTIONDATA_HPP + +#include +#include +#include +#include +#include +#include "../TimeOfDay.hpp" +#include "EvolutionMethod.hpp" +namespace PkmnLib::Library { + class PokemonSpecies; + class Move; + class Item; + + class EvolutionData { + private: + const PokemonSpecies* _evolvesInto; + EvolutionMethod _method; + std::vector _evolutionData; // This can probably be done in a better way, can't think of it now. + + EvolutionData(EvolutionMethod method, std::vector data, const PokemonSpecies* next) + : _evolvesInto(next), _method(method), _evolutionData(std::move(data)) {} + + public: + static EvolutionData CreateLevelEvolution(uint8_t level, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::Level, {std::any(level)}, into); + } + static EvolutionData CreateFriendshipEvolution(uint8_t friendship, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::HighFriendship, {std::any(friendship)}, into); + } + static EvolutionData CreateKnownMoveEvolution(const Move* move, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::KnownMove, {std::any(move)}, into); + } + static EvolutionData CreateLocationEvolution(const std::string& location, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::LocationBased, {std::any(location)}, into); + } + static EvolutionData CreateTimeEvolution(TimeOfDay time, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::TimeBased, {std::any(time)}, into); + } + static EvolutionData CreateHeldItemEvolution(const Item* item, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::HoldsItem, {std::any(item)}, into); + } + static EvolutionData CreateGenderBasedEvolution(CreatureLib::Library::Gender gender, uint8_t level, + const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::IsGenderAndLevel, {std::any(gender), std::any(level)}, into); + } + static EvolutionData CreateItemUseEvolution(const Item* item, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::EvolutionItemUse, {std::any(item)}, into); + } + static EvolutionData CreateItemUseWithGenderEvolution(const Item* item, CreatureLib::Library::Gender gender, + const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::EvolutionItemUseWithGender, {std::any(item), std::any(gender)}, into); + } + static EvolutionData CreateTradeEvolution(const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::Trade, {}, into); + } + static EvolutionData CreateTradeWithItemEvolution(const Item* item, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::TradeWithHeldItem, {std::any(item)}, into); + } + static EvolutionData CreateTradeWithSpeciesEvolution(const PokemonSpecies* traded, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::TradeWithSpecificPokemon, {std::any(traded)}, into); + } + static EvolutionData CreateCustomEvolution(std::vector data, const PokemonSpecies* into) { + return EvolutionData(EvolutionMethod::Custom, std::move(data), into); + } + + [[nodiscard]] inline const PokemonSpecies* GetNewSpecies() const { return _evolvesInto; } + [[nodiscard]] inline EvolutionMethod GetMethod() const { return _method; } + [[nodiscard]] inline const std::any& GetData(size_t index) const { return _evolutionData.at(index); } + }; +} + +#endif // PKMNLIB_EVOLUTIONDATA_HPP diff --git a/src/Library/Evolutions/EvolutionMethod.hpp b/src/Library/Evolutions/EvolutionMethod.hpp new file mode 100644 index 0000000..53b5643 --- /dev/null +++ b/src/Library/Evolutions/EvolutionMethod.hpp @@ -0,0 +1,23 @@ +#ifndef PKMNLIB_EVOLUTIONMETHOD_HPP +#define PKMNLIB_EVOLUTIONMETHOD_HPP + +#include +namespace PkmnLib::Library{ + enum class EvolutionMethod : uint8_t{ + Level, + HighFriendship, + KnownMove, + LocationBased, + TimeBased, + HoldsItem, + IsGenderAndLevel, + EvolutionItemUse, + EvolutionItemUseWithGender, + Trade, + TradeWithHeldItem, + TradeWithSpecificPokemon, + Custom + }; +} + +#endif // PKMNLIB_EVOLUTIONMETHOD_HPP diff --git a/src/Library/Species/PokemonSpecies.hpp b/src/Library/Species/PokemonSpecies.hpp index 4d94897..174ffb9 100644 --- a/src/Library/Species/PokemonSpecies.hpp +++ b/src/Library/Species/PokemonSpecies.hpp @@ -1,12 +1,14 @@ #ifndef PKMNLIB_POKEMONSPECIES_HPP #define PKMNLIB_POKEMONSPECIES_HPP #include +#include "../Evolutions/EvolutionData.hpp" #include "PokemonForme.hpp" namespace PkmnLib::Library { class PokemonSpecies : public CreatureLib::Library::CreatureSpecies { private: uint8_t _baseHappiness; + std::vector _evolutions; public: PokemonSpecies(uint16_t id, const std::string& name, const PokemonForme* defaultVariant, float genderRatio, @@ -23,6 +25,9 @@ namespace PkmnLib::Library { inline const PokemonForme* GetForme(const std::string& key) const { return reinterpret_cast(CreatureSpecies::GetVariant(key)); } + + inline void AddEvolution(EvolutionData data) { _evolutions.push_back(data); } + const std::vector& GetEvolutions() const { return _evolutions; } }; } diff --git a/src/Library/TimeOfDay.hpp b/src/Library/TimeOfDay.hpp new file mode 100644 index 0000000..1d0900d --- /dev/null +++ b/src/Library/TimeOfDay.hpp @@ -0,0 +1,14 @@ +#ifndef PKMNLIB_TIMEOFDAY_HPP +#define PKMNLIB_TIMEOFDAY_HPP + +#include +namespace PkmnLib::Library{ + enum class TimeOfDay : uint8_t { + Night, + Morning, + Afternoon, + Evening + }; +} + +#endif // PKMNLIB_TIMEOFDAY_HPP diff --git a/tests/LibraryTests/SpeciesTests.cpp b/tests/LibraryTests/SpeciesTests.cpp index 145283b..37a20d9 100644 --- a/tests/LibraryTests/SpeciesTests.cpp +++ b/tests/LibraryTests/SpeciesTests.cpp @@ -119,6 +119,31 @@ TEST_CASE("Able to get species base happiness", "library") { delete species; } +TEST_CASE("Able to set and get evolution", "library") { + auto species = new PkmnLib::Library::PokemonSpecies( + 1, "foo", + 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); + auto species2 = new PkmnLib::Library::PokemonSpecies( + 2, "bar", + 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); + + species->AddEvolution(PkmnLib::Library::EvolutionData::CreateLevelEvolution(16, species2)); + auto evolutions = species->GetEvolutions(); + REQUIRE(evolutions.size() == 1); + auto evo = evolutions[0]; + CHECK(evo.GetMethod() == PkmnLib::Library::EvolutionMethod::Level); + CHECK(evo.GetNewSpecies() == species2); + CHECK(std::any_cast(evo.GetData(0)) == 16); + + delete species; + delete species2; +} #endif \ No newline at end of file