2020-02-20 12:28:31 +00:00
|
|
|
#include "MiscLibrary.hpp"
|
|
|
|
#include <CreatureLib/Battling/Models/Battle.hpp>
|
2021-06-27 15:11:37 +00:00
|
|
|
#include <CreatureLib/Battling/Models/LearnedAttack.hpp>
|
2020-04-17 15:56:41 +00:00
|
|
|
#include <CreatureLib/Battling/TurnChoices/AttackTurnChoice.hpp>
|
2020-02-20 12:28:31 +00:00
|
|
|
#include "../PkmnScriptHook.hpp"
|
2021-06-27 15:11:37 +00:00
|
|
|
#include "../Pokemon/LearnedMove.hpp"
|
|
|
|
#include "../Pokemon/Pokemon.hpp"
|
2020-02-20 12:28:31 +00:00
|
|
|
|
2022-03-25 18:08:42 +00:00
|
|
|
bool PkmnLib::Battling::MiscLibrary::IsCritical(CreatureLib::Battling::ExecutingAttack* non_null attack,
|
|
|
|
CreatureLib::Battling::Creature* non_null target, uint8_t hit) const {
|
2022-02-12 12:03:40 +00:00
|
|
|
bool preventCrit = false;
|
|
|
|
PKMN_HOOK(PreventIncomingCritical, target, attack, target, hit, &preventCrit);
|
|
|
|
if (preventCrit) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-02-20 12:28:31 +00:00
|
|
|
uint8_t critStage = 0;
|
|
|
|
PKMN_HOOK(ModifyCriticalStage, attack, attack, target, hit, &critStage);
|
2020-12-13 11:32:52 +00:00
|
|
|
Ensure(target->GetBattle().HasValue());
|
2020-12-12 13:25:27 +00:00
|
|
|
auto rand = target->GetBattle().GetValue()->GetRandom();
|
2020-04-17 15:56:41 +00:00
|
|
|
switch (critStage) {
|
2020-02-20 12:28:31 +00:00
|
|
|
case 0: return rand->Get(24) == 0;
|
|
|
|
case 1: return rand->Get(8) == 0;
|
|
|
|
case 2: return rand->Get(2) == 0;
|
|
|
|
default: return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-25 18:08:42 +00:00
|
|
|
bool PkmnLib::Battling::MiscLibrary::CanFlee(CreatureLib::Battling::FleeTurnChoice* non_null switchChoice) const {
|
2020-02-20 12:28:31 +00:00
|
|
|
return CreatureLib::Battling::MiscLibrary::CanFlee(switchChoice);
|
|
|
|
}
|
2020-04-17 15:56:41 +00:00
|
|
|
|
2022-03-25 18:08:42 +00:00
|
|
|
CreatureLib::Battling::BaseTurnChoice* non_null PkmnLib::Battling::MiscLibrary::ReplacementAttack(
|
|
|
|
CreatureLib::Battling::Creature* non_null user, CreatureLib::Battling::CreatureIndex target) const {
|
2020-04-17 15:56:41 +00:00
|
|
|
return new CreatureLib::Battling::AttackTurnChoice(user, GetReplacementAttack(), target);
|
|
|
|
}
|
2021-06-27 15:11:37 +00:00
|
|
|
|
|
|
|
using TimeOfDay = PkmnLib::Library::TimeOfDay;
|
|
|
|
|
|
|
|
bool PkmnLib::Battling::MiscLibrary::CanEvolveFromLevelUp(
|
|
|
|
const ArbUt::BorrowedPtr<const PkmnLib::Library::EvolutionData>& evolution,
|
|
|
|
const ArbUt::BorrowedPtr<const Pokemon>& pokemon) {
|
|
|
|
auto time = GetTime();
|
|
|
|
switch (evolution->GetMethod()) {
|
|
|
|
|
2021-09-25 15:56:31 +00:00
|
|
|
case Library::EvolutionMethod::Level: return pokemon->GetLevel() >= evolution->GetDataAt(0)->AsInt();
|
2021-06-27 15:11:37 +00:00
|
|
|
case Library::EvolutionMethod::HighFriendship:
|
2021-09-25 15:56:31 +00:00
|
|
|
return pokemon->GetFriendship() >= evolution->GetDataAt(0)->AsInt();
|
2021-06-27 15:11:37 +00:00
|
|
|
case Library::EvolutionMethod::HighFriendshipTime:
|
2021-09-25 15:56:31 +00:00
|
|
|
return pokemon->GetFriendship() >= evolution->GetDataAt(0)->AsInt() &&
|
|
|
|
time >= (TimeOfDay)evolution->GetDataAt(1)->AsInt() &&
|
|
|
|
time <= (TimeOfDay)evolution->GetDataAt(2)->AsInt();
|
2021-06-27 15:11:37 +00:00
|
|
|
case Library::EvolutionMethod::KnownMove: {
|
2021-09-25 15:56:31 +00:00
|
|
|
auto v = evolution->GetDataAt(0)->AsString();
|
2021-06-27 15:11:37 +00:00
|
|
|
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:
|
2021-09-25 15:56:31 +00:00
|
|
|
return time >= (TimeOfDay)evolution->GetDataAt(0)->AsInt() &&
|
|
|
|
time <= (TimeOfDay)evolution->GetDataAt(1)->AsInt();
|
|
|
|
case Library::EvolutionMethod::HoldsItem: return pokemon->HasHeldItem(evolution->GetDataAt(0)->AsString());
|
2021-06-27 15:11:37 +00:00
|
|
|
case Library::EvolutionMethod::HoldsItemTime:
|
2021-09-25 15:56:31 +00:00
|
|
|
return pokemon->HasHeldItem(evolution->GetDataAt(0)->AsString()) &&
|
|
|
|
time >= (TimeOfDay)evolution->GetDataAt(0)->AsInt() &&
|
|
|
|
time <= (TimeOfDay)evolution->GetDataAt(1)->AsInt();
|
2021-06-27 15:11:37 +00:00
|
|
|
case Library::EvolutionMethod::IsGenderAndLevel:
|
2021-09-25 15:56:31 +00:00
|
|
|
return pokemon->GetLevel() >= evolution->GetDataAt(1)->AsInt() &&
|
|
|
|
pokemon->GetGender() == (CreatureLib::Library::Gender)evolution->GetDataAt(0)->AsInt();
|
2021-07-09 12:36:14 +00:00
|
|
|
case Library::EvolutionMethod::Custom: {
|
2021-07-09 11:54:42 +00:00
|
|
|
auto script = dynamic_cast<ScriptResolver*>(pokemon->GetLibrary()->GetScriptResolver().get())
|
2021-09-25 15:56:31 +00:00
|
|
|
->LoadEvolutionScript(evolution->GetDataAt(0)->AsString());
|
2021-07-09 11:54:42 +00:00
|
|
|
if (!script.HasValue()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto v = false;
|
|
|
|
script.GetValue()->DoesEvolveFromLevelUp(evolution, pokemon, &v);
|
|
|
|
return v;
|
|
|
|
}
|
2021-06-27 15:11:37 +00:00
|
|
|
case Library::EvolutionMethod::EvolutionItemUse:
|
|
|
|
case Library::EvolutionMethod::EvolutionItemUseWithGender:
|
|
|
|
case Library::EvolutionMethod::Trade:
|
|
|
|
case Library::EvolutionMethod::TradeWithHeldItem:
|
|
|
|
case Library::EvolutionMethod::TradeWithSpecificPokemon: return false;
|
|
|
|
}
|
|
|
|
__builtin_unreachable();
|
|
|
|
}
|