diff --git a/src/BuildData/BuildNatures.cpp b/src/BuildData/BuildNatures.cpp new file mode 100644 index 0000000..b81927e --- /dev/null +++ b/src/BuildData/BuildNatures.cpp @@ -0,0 +1,86 @@ +#include "BuildNatures.hpp" +#include +#include +#include + +static CreatureLib::Core::Statistic ParseStatistic(const std::string& stat) { + if (stat.empty()) + return static_cast(255); + if (stat == "Attack") + return CreatureLib::Core::Statistic::PhysicalAttack; + if (stat == "Defense") + return CreatureLib::Core::Statistic::PhysicalDefense; + if (stat == "SpecialAttack") + return CreatureLib::Core::Statistic::MagicalAttack; + if (stat == "SpecialDefense") + return CreatureLib::Core::Statistic::MagicalDefense; + if (stat == "Speed") + return CreatureLib::Core::Statistic::Speed; + std::cout << "Invalid stat was given: '" << stat << "'.\n"; + return static_cast(254); +} + +PkmnLib::Library::NatureLibrary* BuildNatures::Build(const std::string& path) { + std::ifstream file(path); + if (file.fail()) { + std::cout << "Failed to load Natures data file at '" << path << "'\n"; + return nullptr; + } + + std::string line; + if (!std::getline(file, line)) { + std::cout << "Failed to read Natures data file at '" << path << "'\n"; + return nullptr; + } + auto divider = ','; + if (strncmp(line.c_str(), "sep=", 4) == 0) { + divider = line[4]; + std::getline(file, line); + } + auto library = new PkmnLib::Library::NatureLibrary(); + std::string substr; + while (std::getline(file, line)) { + size_t lastStart = 0; + uint8_t current = 0; + std::string natureName; + std::string increasedStat; + std::string decreasedStat; + + for (size_t i = 0; i < line.length(); i++) { + if (line[i] == divider) { + switch (current) { + case 0: natureName = line.substr(lastStart, i - lastStart); break; + case 1: increasedStat = line.substr(lastStart, i - lastStart); break; + case 2: decreasedStat = line.substr(lastStart, i - lastStart); break; + default: + std::cout << "Unknown field in nature data: '" << line.substr(lastStart, i - lastStart) + << "'.\n"; + return nullptr; + } + lastStart = i + 1; + current++; + } + } + if (current == 2) + decreasedStat = line.substr(lastStart, line.length() - lastStart); + + auto parsedIncreased = ParseStatistic(increasedStat); + float increasedModifier = 1.1; + if (parsedIncreased == 254) + return nullptr; + if (parsedIncreased == 255) + increasedModifier = 1.0; + + auto parsedDecreased = ParseStatistic(decreasedStat); + float decreasedModifier = 0.9; + if (parsedDecreased == 254) + return nullptr; + if (parsedDecreased == 255) + decreasedModifier = 1.0; + + std::cout << "Registered nature with name '" << natureName << "'.\n"; + library->LoadNature(natureName, PkmnLib::Library::Nature(parsedIncreased, parsedDecreased, increasedModifier, + decreasedModifier)); + } + return library; +} diff --git a/src/BuildData/BuildNatures.hpp b/src/BuildData/BuildNatures.hpp new file mode 100644 index 0000000..8e84876 --- /dev/null +++ b/src/BuildData/BuildNatures.hpp @@ -0,0 +1,10 @@ +#ifndef GEN7TESTS_BUILDNATURES_HPP +#define GEN7TESTS_BUILDNATURES_HPP + +#include +class BuildNatures { +public: + static PkmnLib::Library::NatureLibrary* Build(const std::string& path); +}; + +#endif // GEN7TESTS_BUILDNATURES_HPP diff --git a/src/BuildData/BuildTypes.cpp b/src/BuildData/BuildTypes.cpp index bfa2b44..262f010 100644 --- a/src/BuildData/BuildTypes.cpp +++ b/src/BuildData/BuildTypes.cpp @@ -1 +1,70 @@ #include "BuildTypes.hpp" +CreatureLib::Library::TypeLibrary* BuildTypes::Build(const std::string& path) { + std::ifstream file(path); + if (file.fail()) { + std::cout << "Failed to load Types data file at '" << path << "'\n"; + return nullptr; + } + + std::string line; + if (!std::getline(file, line)) { + std::cout << "Failed to read Types data file at '" << path << "'\n"; + return nullptr; + } + auto divider = ','; + if (strncmp(line.c_str(), "sep=", 4) == 0) { + divider = line[4]; + std::getline(file, line); + } + auto library = new CreatureLib::Library::TypeLibrary(); + + bool hasSkippedFirst = false; + size_t lastStart = 0; + std::vector types; + for (size_t i = 0; i < line.length(); i++) { + if (line[i] == divider) { + auto substr = line.substr(lastStart, i - lastStart); + lastStart = i + 1; + if (hasSkippedFirst) { + std::cout << "Registered type: " << substr << "\n"; + auto val = library->RegisterType(substr); + types.push_back(val); + } else { + hasSkippedFirst = true; + } + i++; + } + } + auto substr = line.substr(lastStart, line.length() - lastStart); + std::cout << "Registered type: " << substr << "\n"; + auto val = library->RegisterType(substr); + types.push_back(val); + + + while (std::getline(file, line)) { + uint8_t attackingType = 0; + bool gotType = false; + lastStart = 0; + int current = 0; + for (size_t i = 0; i < line.length(); i++) { + if (line[i] == divider) { + substr = line.substr(lastStart, i - lastStart); + lastStart = i + 1; + if (gotType) { + auto eff = std::atof(substr.c_str()); + library->SetEffectiveness(attackingType, types[current], eff); + current++; + } else { + gotType = true; + attackingType = library->GetTypeId(substr); + } + i++; + } + } + substr = line.substr(lastStart, line.length() - lastStart); + auto eff = std::atof(substr.c_str()); + library->SetEffectiveness(attackingType, types[current], eff); + } + + return library; +} diff --git a/src/BuildData/BuildTypes.hpp b/src/BuildData/BuildTypes.hpp index f420846..f75a6ba 100644 --- a/src/BuildData/BuildTypes.hpp +++ b/src/BuildData/BuildTypes.hpp @@ -7,75 +7,7 @@ class BuildTypes { public: - static CreatureLib::Library::TypeLibrary* Build(const std::string& path) { - std::ifstream file(path); - if (file.fail()) { - std::cout << "Failed to load Types data file at '" << path << "'\n"; - return nullptr; - } - - std::string line; - if (!std::getline(file, line)) { - std::cout << "Failed to read Types data file at '" << path << "'\n"; - return nullptr; - } - auto divider = ','; - if (strncmp(line.c_str(), "sep=", 4) == 0) { - divider = line[4]; - std::getline(file, line); - } - auto library = new CreatureLib::Library::TypeLibrary(); - - bool hasSkippedFirst = false; - size_t lastStart = 0; - std::vector types; - for (size_t i = 0; i < line.length(); i++) { - if (line[i] == divider) { - auto substr = line.substr(lastStart, i - lastStart); - lastStart = i + 1; - if (hasSkippedFirst) { - std::cout << "Registered type: " << substr << "\n"; - auto val = library->RegisterType(substr); - types.push_back(val); - } else { - hasSkippedFirst = true; - } - i++; - } - } - auto substr = line.substr(lastStart, line.length() - lastStart); - std::cout << "Registered type: " << substr << "\n"; - auto val = library->RegisterType(substr); - types.push_back(val); - - - while (std::getline(file, line)) { - uint8_t attackingType = 0; - bool gotType = false; - lastStart = 0; - int current = 0; - for (size_t i = 0; i < line.length(); i++) { - if (line[i] == divider) { - substr = line.substr(lastStart, i - lastStart); - lastStart = i + 1; - if (gotType) { - auto eff = std::atof(substr.c_str()); - library->SetEffectiveness(attackingType, types[current], eff); - current++; - } else { - gotType = true; - attackingType = library->GetTypeId(substr); - } - i++; - } - } - substr = line.substr(lastStart, line.length() - lastStart); - auto eff = std::atof(substr.c_str()); - library->SetEffectiveness(attackingType, types[current], eff); - } - - return library; - } + static CreatureLib::Library::TypeLibrary* Build(const std::string& path); }; #endif // GEN7TESTS_BUILDTYPES_HPP diff --git a/src/LibraryTests/NaturesTests.cpp b/src/LibraryTests/NaturesTests.cpp new file mode 100644 index 0000000..3a90083 --- /dev/null +++ b/src/LibraryTests/NaturesTests.cpp @@ -0,0 +1,48 @@ +#include "../../extern/catch.hpp" +#include "../Library.hpp" + +#define CHECK_NATURE_NEUTRAL(name) \ + { \ + auto nature = natureLib->GetNatureByName( #name ); \ + CHECK(nature.GetIncreaseModifier() == Approx(1.0)); \ + CHECK(nature.GetDecreaseModifier() == Approx(1.0)); \ + } + + +#define CHECK_NATURE(name, increasedStat, decreasedStat) \ + { \ + auto nature = natureLib->GetNatureByName( #name ); \ + CHECK(nature.GetIncreasedStat() == PkmnLib::Library::Statistic::increasedStat); \ + CHECK(nature.GetDecreasedStat() == PkmnLib::Library::Statistic::decreasedStat); \ + CHECK(nature.GetIncreaseModifier() == Approx(1.1)); \ + CHECK(nature.GetDecreaseModifier() == Approx(0.9)); \ + } + +TEST_CASE("Nature Checks", "[natures]") { + auto natureLib = Library::GetStaticLib()->GetNatureLibrary(); + CHECK_NATURE_NEUTRAL(Hardy); + CHECK_NATURE(Lonely, PhysicalAttack, PhysicalDefense); + CHECK_NATURE(Brave, PhysicalAttack, Speed); + CHECK_NATURE(Adamant, PhysicalAttack, SpecialAttack); + CHECK_NATURE(Naughty, PhysicalAttack, SpecialDefense); + CHECK_NATURE(Bold, PhysicalDefense, PhysicalAttack); + CHECK_NATURE_NEUTRAL(Docile); + CHECK_NATURE(Relaxed, PhysicalDefense, Speed); + CHECK_NATURE(Impish, PhysicalDefense, SpecialAttack); + CHECK_NATURE(Lax, PhysicalDefense, SpecialDefense); + CHECK_NATURE(Timid, Speed, PhysicalAttack); + CHECK_NATURE(Hasty, Speed, PhysicalDefense); + CHECK_NATURE_NEUTRAL(Serious); + CHECK_NATURE(Jolly, Speed, SpecialAttack); + CHECK_NATURE(Naive, Speed, SpecialDefense); + CHECK_NATURE(Modest, SpecialAttack, PhysicalAttack); + CHECK_NATURE(Mild, SpecialAttack, PhysicalDefense); + CHECK_NATURE(Quiet, SpecialAttack, Speed); + CHECK_NATURE_NEUTRAL(Bashful); + CHECK_NATURE(Rash, SpecialAttack, SpecialDefense); + CHECK_NATURE(Calm, SpecialDefense, PhysicalAttack); + CHECK_NATURE(Gentle, SpecialDefense, PhysicalDefense); + CHECK_NATURE(Sassy, SpecialDefense, Speed); + CHECK_NATURE(Careful, SpecialDefense, SpecialAttack); + CHECK_NATURE_NEUTRAL(Quirky); +} diff --git a/src/main.cpp b/src/main.cpp index 3bbed58..ec266a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,6 @@ #define CATCH_CONFIG_RUNNER #include "../extern/catch.hpp" +#include "BuildData/BuildNatures.hpp" #include "BuildData/BuildSpecies.hpp" #include "BuildData/BuildTypes.hpp" #include "Library.hpp" @@ -8,12 +9,13 @@ int main(int argc, char* argv[]) { Catch::Session session; std::string typesFile = "Types.csv"; + std::string naturesFile = "Natures.csv"; std::string pokemonFile = "Pokemon.json"; using namespace Catch::clara; - auto cli = session.cli() - | Opt(pokemonFile, "Species")["--species"]("Which species file to load.") - | Opt(typesFile, "Types")["--types"]("Which Types file to load."); + auto cli = session.cli() | Opt(pokemonFile, "Species")["--species"]("Which species file to load.") | + Opt(typesFile, "Types")["--types"]("Which Types file to load.") | + Opt(naturesFile, "Natures")["--natures"]("Which Natures file to load."); session.cli(cli); @@ -22,11 +24,15 @@ int main(int argc, char* argv[]) { return returnCode; auto typesLibrary = BuildTypes::Build(typesFile); + auto natureLibrary = BuildNatures::Build(naturesFile); auto speciesLibrary = BuildSpecies::BuildLibrary(pokemonFile, typesLibrary); + if (typesLibrary == nullptr || speciesLibrary == nullptr || natureLibrary == nullptr) + return 1; + auto settings = new PkmnLib::Library::LibrarySettings(100, 4, 4096); - auto library = new PkmnLib::Library::PokemonLibrary(settings, speciesLibrary,nullptr,nullptr, nullptr,typesLibrary, - nullptr); + auto library = new PkmnLib::Library::PokemonLibrary(settings, speciesLibrary, nullptr, nullptr, nullptr, + typesLibrary, natureLibrary); Library::SetStaticLib(library);