#include "CreatePokemon.hpp" namespace PkmnLib::Battling { CreatePokemon& CreatePokemon::WithRandomIndividualValues(ArbUt::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; } CreatePokemon& CreatePokemon::WithIndividualValue(CreatureLib::Library::Statistic stat, u8 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; } CreatePokemon& CreatePokemon::WithEffortValue(CreatureLib::Library::Statistic stat, u8 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; } Pokemon* CreatePokemon::Build(ArbUt::Random& rand) { auto species = this->_library->GetSpeciesLibrary()->TryGet(this->_species); if (!species.has_value()) { std::stringstream err; err << "Invalid species '" << _species << "'."; throw ArbUt::Exception(err.str()); } auto forme = species.value()->TryGetForme(this->_forme); if (!forme.has_value()) { std::stringstream err; err << "Invalid forme '" << _forme << "' for species '" << _forme << "'."; throw ArbUt::Exception(err.str()); } CreatureLib::Library::TalentIndex ability; if (this->_ability.IsEmpty()) { ability = forme.value()->GetRandomTalent(rand); } else { ability = forme.value()->GetTalentIndex(this->_ability); } auto identifier = this->_identifier; if (identifier == 0) { identifier = rand.GetUnsigned(); } auto gender = this->_gender; if (gender == static_cast(-1)) { gender = species.value()->GetRandomGender(rand); } ArbUt::OptionalBorrowedPtr heldItem = nullptr; if (!this->_heldItem.IsEmpty()) { auto item = _library->GetItemLibrary()->TryGet(this->_heldItem); if (!item.has_value()) { THROW("Unknown Item: ", this->_heldItem.std_str()); } heldItem = item.value(); } auto experience = _library->GetGrowthRateLibrary()->CalculateExperience(species.value()->GetGrowthRate(), _level); auto attacks = std::vector(_attacks.Count()); for (size_t i = 0; i < _attacks.Count(); i++) { auto& kv = _attacks[i]; auto move = kv.Move; if (move.HasValue()) { attacks[i] = new LearnedMove(move.GetValue(), kv.LearnMethod); } } auto ivs = CreatureLib::Library::ClampedStatisticSet(_ivHp, _ivAttack, _ivDefense, _ivSpAtt, _ivSpDef, _ivSpeed); auto evs = CreatureLib::Library::ClampedStatisticSet(_evHp, _evAttack, _evDefense, _evSpAtt, _evSpDef, _evSpeed); if (_nature.IsEmpty()) { _nature = _library->GetNatureLibrary()->GetRandomNatureName(rand); } auto nature = _library->GetNatureLibrary()->GetNatureByName(_nature); auto shiny = false; if (_shininessSet) { shiny = _isShiny; } else { shiny = rand.Get(_library->GetSettings()->GetShinyRate()) == 0; } auto pkmn = new Pokemon(_library, species.value(), forme.value(), _level, experience, identifier, gender, shiny, heldItem, _nickname, ability, attacks, ivs, evs, nature, _allowedExperienceGain); pkmn->Initialize(); return pkmn; } CreatePokemon& CreatePokemon::WithNature(const ArbUt::StringView& nature) { _nature = nature; return *this; } CreatePokemon& CreatePokemon::WithIndividualValues(u8 hp, u8 att, u8 def, u8 spAtt, u8 spDef, u8 speed) { _ivHp = hp; _ivAttack = att; _ivDefense = def; _ivSpAtt = spAtt; _ivSpDef = spDef; _ivSpeed = speed; return *this; } CreatePokemon& CreatePokemon::WithEffortValues(u8 hp, u8 att, u8 def, u8 spAtt, u8 spDef, u8 speed) { _evHp = hp; _evAttack = att; _evDefense = def; _evSpAtt = spAtt; _evSpDef = spDef; _evSpeed = speed; return *this; } CreatePokemon& CreatePokemon::WithForme(const ArbUt::StringView& forme) { _forme = forme; return *this; } CreatePokemon& CreatePokemon::WithGender(CreatureLib::Library::Gender gender) { _gender = gender; return *this; } CreatePokemon& CreatePokemon::IsShiny(bool value) { _shininessSet = true; _isShiny = value; return *this; } CreatePokemon& CreatePokemon::WithHeldItem(const ArbUt::StringView& item) { _heldItem = item; return *this; } CreatePokemon& CreatePokemon::LearnMove(const ArbUt::StringView& moveName, CreatureLib::Battling::AttackLearnMethod method) { auto v = _library->GetMoveLibrary()->TryGet(moveName); if (!v.has_value()) { THROW("Invalid Move given: ", moveName.std_str()); } if (_currentMove >= _library->GetSettings()->GetMaximalAttacks()) { throw ArbUt::Exception("This pokemon already has the maximal allowed moves."); } _attacks.Append(ToLearnMethod(v.value(), method)); return *this; } CreatePokemon& CreatePokemon::IsAllowedExperienceGain(bool value) { _allowedExperienceGain = value; return *this; } CreatePokemon& CreatePokemon::WithNickname(const std::string& nickname) { _nickname = nickname; return *this; } }