diff --git a/CInterface/Battling/BattleLibrary.cpp b/CInterface/Battling/BattleLibrary.cpp index 948c4e5..e7fd285 100644 --- a/CInterface/Battling/BattleLibrary.cpp +++ b/CInterface/Battling/BattleLibrary.cpp @@ -5,7 +5,7 @@ using namespace PkmnLib::Battling; export uint8_t PkmnLib_BattleLibrary_Construct(BattleLibrary*& out, PkmnLib::Library::PokemonLibrary* staticLib, StatCalculator* statCalculator, DamageLibrary* damageLibrary, ExperienceLibrary* experienceLibrary, - CreatureLib::Battling::ScriptResolver* scriptResolver, + PkmnLib::Battling::ScriptResolver* scriptResolver, MiscLibrary* miscLibrary) { Try(out = new BattleLibrary(staticLib, statCalculator, damageLibrary, experienceLibrary, scriptResolver, miscLibrary)); diff --git a/CInterface/Battling/MiscLibrary.cpp b/CInterface/Battling/MiscLibrary.cpp index 485be37..e343946 100644 --- a/CInterface/Battling/MiscLibrary.cpp +++ b/CInterface/Battling/MiscLibrary.cpp @@ -2,6 +2,8 @@ #include "../Core.hpp" using namespace PkmnLib::Battling; -export MiscLibrary* PkmnLib_MiscLibrary_Construct() { return new MiscLibrary(); } +export MiscLibrary* PkmnLib_MiscLibrary_Construct(PkmnLib::Library::TimeOfDay(*getTime)()) { + return new MiscLibrary(getTime); +} export void PkmnLib_MiscLibrary_Destruct(MiscLibrary* p) { delete p; } diff --git a/src/Battling/Library/BattleLibrary.hpp b/src/Battling/Library/BattleLibrary.hpp index b31d484..787c302 100644 --- a/src/Battling/Library/BattleLibrary.hpp +++ b/src/Battling/Library/BattleLibrary.hpp @@ -6,14 +6,14 @@ #include "DamageLibrary.hpp" #include "ExperienceLibrary.hpp" #include "MiscLibrary.hpp" +#include "ScriptResolver.hpp" #include "StatCalculator.hpp" namespace PkmnLib::Battling { class BattleLibrary final : public CreatureLib::Battling::BattleLibrary { public: BattleLibrary(Library::PokemonLibrary* staticLib, StatCalculator* statCalculator, DamageLibrary* damageLibrary, - PkmnLib::Battling::ExperienceLibrary* experienceLibrary, - CreatureLib::Battling::ScriptResolver* scriptResolver, + PkmnLib::Battling::ExperienceLibrary* experienceLibrary, ScriptResolver* scriptResolver, PkmnLib::Battling::MiscLibrary* miscLibrary) : CreatureLib::Battling::BattleLibrary(staticLib, statCalculator, damageLibrary, experienceLibrary, scriptResolver, miscLibrary) {} @@ -43,7 +43,7 @@ namespace PkmnLib::Battling { return GetStaticLib()->GetNatureLibrary(); } - static CreatureLib::Battling::ScriptResolver* CreateScriptResolver(); + static PkmnLib::Battling::ScriptResolver* CreateScriptResolver(); }; } #endif // PKMNLIB_BATTLELIBRARY_HPP diff --git a/src/Battling/Library/MiscLibrary.cpp b/src/Battling/Library/MiscLibrary.cpp index 1c1be70..a54131b 100644 --- a/src/Battling/Library/MiscLibrary.cpp +++ b/src/Battling/Library/MiscLibrary.cpp @@ -1,7 +1,10 @@ #include "MiscLibrary.hpp" #include +#include #include #include "../PkmnScriptHook.hpp" +#include "../Pokemon/LearnedMove.hpp" +#include "../Pokemon/Pokemon.hpp" bool PkmnLib::Battling::MiscLibrary::IsCritical(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target, uint8_t hit) const { @@ -26,3 +29,49 @@ PkmnLib::Battling::MiscLibrary::ReplacementAttack(CreatureLib::Battling::Creatur CreatureLib::Battling::CreatureIndex target) const { return new CreatureLib::Battling::AttackTurnChoice(user, GetReplacementAttack(), target); } + +using TimeOfDay = PkmnLib::Library::TimeOfDay; + +bool PkmnLib::Battling::MiscLibrary::CanEvolveFromLevelUp( + const ArbUt::BorrowedPtr& evolution, + const ArbUt::BorrowedPtr& pokemon) { + auto time = GetTime(); + switch (evolution->GetMethod()) { + + case Library::EvolutionMethod::Level: return pokemon->GetLevel() >= evolution->GetData(0)->AsInt(); + case Library::EvolutionMethod::HighFriendship: + return pokemon->GetFriendship() >= evolution->GetData(0)->AsInt(); + case Library::EvolutionMethod::HighFriendshipTime: + return pokemon->GetFriendship() >= evolution->GetData(0)->AsInt() && + time >= (TimeOfDay)evolution->GetData(1)->AsInt() && + time <= (TimeOfDay)evolution->GetData(2)->AsInt(); + case Library::EvolutionMethod::KnownMove: { + auto v = evolution->GetData(0)->AsString(); + return std::any_of(pokemon->GetMoves().begin(), pokemon->GetMoves().end(), [v](const auto& move) { + return move.HasValue() && move.GetValue()->GetMoveData()->GetName() == v; + }); + } + case Library::EvolutionMethod::LocationBased: + // TODO: Implement this + return false; + case Library::EvolutionMethod::TimeBased: + return time >= (TimeOfDay)evolution->GetData(0)->AsInt() && + time <= (TimeOfDay)evolution->GetData(1)->AsInt(); + case Library::EvolutionMethod::HoldsItem: return pokemon->HasHeldItem(evolution->GetData(0)->AsString()); + case Library::EvolutionMethod::HoldsItemTime: + return pokemon->HasHeldItem(evolution->GetData(0)->AsString()) && + time >= (TimeOfDay)evolution->GetData(0)->AsInt() && + time <= (TimeOfDay)evolution->GetData(1)->AsInt(); + case Library::EvolutionMethod::IsGenderAndLevel: + return pokemon->GetLevel() >= evolution->GetData(1)->AsInt() && + pokemon->GetGender() == (CreatureLib::Library::Gender)evolution->GetData(0)->AsInt(); + case Library::EvolutionMethod::Custom: + // TODO + case Library::EvolutionMethod::EvolutionItemUse: + case Library::EvolutionMethod::EvolutionItemUseWithGender: + case Library::EvolutionMethod::Trade: + case Library::EvolutionMethod::TradeWithHeldItem: + case Library::EvolutionMethod::TradeWithSpecificPokemon: return false; + } + __builtin_unreachable(); +} diff --git a/src/Battling/Library/MiscLibrary.hpp b/src/Battling/Library/MiscLibrary.hpp index f27852f..5ea1962 100644 --- a/src/Battling/Library/MiscLibrary.hpp +++ b/src/Battling/Library/MiscLibrary.hpp @@ -2,10 +2,13 @@ #define PKMNLIB_MISCLIBRARY_HPP #include +#include "../../Library/Evolutions/EvolutionData.hpp" #include "../../Library/Moves/MoveData.hpp" #include "../Pokemon/LearnedMove.hpp" namespace PkmnLib::Battling { + class Pokemon; + class MiscLibrary final : public CreatureLib::Battling::MiscLibrary { std::unique_ptr _struggleData = std::make_unique( "struggle"_cnc, 0, PkmnLib::Library::MoveCategory::Physical, 50, 255, 10, @@ -21,7 +24,11 @@ namespace PkmnLib::Battling { return _struggle; } + std::function _getTime; + public: + MiscLibrary(std::function getTime) : _getTime(getTime) {} + ~MiscLibrary() override = default; bool IsCritical(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target, uint8_t hit) const override; @@ -29,6 +36,11 @@ namespace PkmnLib::Battling { CreatureLib::Battling::BaseTurnChoice* ReplacementAttack(CreatureLib::Battling::Creature* user, CreatureLib::Battling::CreatureIndex target) const override; + + bool CanEvolveFromLevelUp(const ArbUt::BorrowedPtr& evolution, + const ArbUt::BorrowedPtr& pokemon); + + inline PkmnLib::Library::TimeOfDay GetTime() const noexcept { return _getTime(); } }; } diff --git a/src/Battling/Library/ScriptResolver.hpp b/src/Battling/Library/ScriptResolver.hpp new file mode 100644 index 0000000..22661c3 --- /dev/null +++ b/src/Battling/Library/ScriptResolver.hpp @@ -0,0 +1,10 @@ +#ifndef PKMNLIB_SCRIPTRESOLVER_HPP +#define PKMNLIB_SCRIPTRESOLVER_HPP + +namespace PkmnLib::Battling { + class ScriptResolver : public CreatureLib::Battling::ScriptResolver { + public: + }; +} + +#endif // PKMNLIB_SCRIPTRESOLVER_HPP diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp index ba28d94..b44e657 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp @@ -27,7 +27,7 @@ #include "TypeRegistry/Library/RegisterStaticLibraryTypes.hpp" #include "TypeRegistry/Library/RegisterTypeLibrary.hpp" -CreatureLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateScriptResolver() { +PkmnLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateScriptResolver() { return new AngelScriptResolver(); } diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp index 447a771..33d95c6 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp @@ -12,7 +12,7 @@ #include "AngelScriptScript.hpp" #include "AngelScriptTypeInfo.hpp" -class AngelScriptResolver final : public CreatureLib::Battling::ScriptResolver { +class AngelScriptResolver final : public PkmnLib::Battling::ScriptResolver { private: asIScriptEngine* _engine = nullptr; asIScriptModule* _mainModule = nullptr; diff --git a/tests/ScriptTests/BaseScriptClassTests.cpp b/tests/ScriptTests/BaseScriptClassTests.cpp index 7159121..c73239c 100644 --- a/tests/ScriptTests/BaseScriptClassTests.cpp +++ b/tests/ScriptTests/BaseScriptClassTests.cpp @@ -373,13 +373,14 @@ TEST_CASE("Handle script exceptions.") { throw ArbUt::Exception("Didn't throw"); } +static PkmnLib::Library::TimeOfDay GetTime() { return PkmnLib::Library::TimeOfDay::Morning; } TEST_CASE("Add Volatile with return script function") { auto statCalc = new PkmnLib::Battling::StatCalculator(); auto resolver = dynamic_cast(PkmnLib::Battling::BattleLibrary::CreateScriptResolver()); auto mainLib = new PkmnLib::Battling::BattleLibrary( TestLibrary::BuildStaticLibrary(), statCalc, new PkmnLib::Battling::DamageLibrary(), - new PkmnLib::Battling::ExperienceLibrary(), resolver, new PkmnLib::Battling::MiscLibrary()); + new PkmnLib::Battling::ExperienceLibrary(), resolver, new PkmnLib::Battling::MiscLibrary(GetTime)); resolver->Initialize(mainLib); for (auto kv : _scripts) { resolver->CreateScript(kv.first, kv.second); diff --git a/tests/TestLibrary/TestLibrary.hpp b/tests/TestLibrary/TestLibrary.hpp index a378784..28ac718 100644 --- a/tests/TestLibrary/TestLibrary.hpp +++ b/tests/TestLibrary/TestLibrary.hpp @@ -20,12 +20,14 @@ public: return _library; } + static PkmnLib::Library::TimeOfDay GetTime() { return PkmnLib::Library::TimeOfDay::Morning; } + static PkmnLib::Battling::BattleLibrary* BuildLibrary() { auto statCalc = new PkmnLib::Battling::StatCalculator(); auto scriptResolver = PkmnLib::Battling::BattleLibrary::CreateScriptResolver(); auto lib = new PkmnLib::Battling::BattleLibrary( BuildStaticLibrary(), statCalc, new PkmnLib::Battling::DamageLibrary(), - new PkmnLib::Battling::ExperienceLibrary(), scriptResolver, new PkmnLib::Battling::MiscLibrary()); + new PkmnLib::Battling::ExperienceLibrary(), scriptResolver, new PkmnLib::Battling::MiscLibrary(GetTime)); scriptResolver->Initialize(lib); return lib; }