91 lines
4.4 KiB
C++
91 lines
4.4 KiB
C++
#include "MiscLibrary.hpp"
|
|
#include <CreatureLib/Battling/Models/Battle.hpp>
|
|
#include <CreatureLib/Battling/Models/LearnedAttack.hpp>
|
|
#include <CreatureLib/Battling/TurnChoices/AttackTurnChoice.hpp>
|
|
#include "../PkmnScriptHook.hpp"
|
|
#include "../Pokemon/LearnedMove.hpp"
|
|
#include "../Pokemon/Pokemon.hpp"
|
|
|
|
bool PkmnLib::Battling::MiscLibrary::IsCritical(CreatureLib::Battling::ExecutingAttack* non_null attack,
|
|
CreatureLib::Battling::Creature* non_null target, uint8_t hit) const {
|
|
bool preventCrit = false;
|
|
PKMN_HOOK(PreventIncomingCritical, target, attack, target, hit, &preventCrit);
|
|
if (preventCrit) {
|
|
return false;
|
|
}
|
|
|
|
uint8_t critStage = 0;
|
|
PKMN_HOOK(ModifyCriticalStage, attack, attack, target, hit, &critStage);
|
|
Ensure(target->GetBattle().HasValue());
|
|
auto rand = target->GetBattle().GetValue()->GetRandom();
|
|
switch (critStage) {
|
|
case 0: return rand->Get(24) == 0;
|
|
case 1: return rand->Get(8) == 0;
|
|
case 2: return rand->Get(2) == 0;
|
|
default: return true;
|
|
}
|
|
}
|
|
|
|
bool PkmnLib::Battling::MiscLibrary::CanFlee(CreatureLib::Battling::FleeTurnChoice* non_null switchChoice) const {
|
|
return CreatureLib::Battling::MiscLibrary::CanFlee(switchChoice);
|
|
}
|
|
|
|
CreatureLib::Battling::BaseTurnChoice* non_null PkmnLib::Battling::MiscLibrary::ReplacementAttack(
|
|
CreatureLib::Battling::Creature* non_null user, 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<const PkmnLib::Library::EvolutionData>& evolution,
|
|
const ArbUt::BorrowedPtr<const Pokemon>& pokemon) {
|
|
auto time = GetTime();
|
|
switch (evolution->GetMethod()) {
|
|
|
|
case Library::EvolutionMethod::Level: return pokemon->GetLevel() >= evolution->GetDataAt(0)->AsInt();
|
|
case Library::EvolutionMethod::HighFriendship:
|
|
return pokemon->GetFriendship() >= evolution->GetDataAt(0)->AsInt();
|
|
case Library::EvolutionMethod::HighFriendshipTime:
|
|
return pokemon->GetFriendship() >= evolution->GetDataAt(0)->AsInt() &&
|
|
time >= (TimeOfDay)evolution->GetDataAt(1)->AsInt() &&
|
|
time <= (TimeOfDay)evolution->GetDataAt(2)->AsInt();
|
|
case Library::EvolutionMethod::KnownMove: {
|
|
auto v = evolution->GetDataAt(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->GetDataAt(0)->AsInt() &&
|
|
time <= (TimeOfDay)evolution->GetDataAt(1)->AsInt();
|
|
case Library::EvolutionMethod::HoldsItem: return pokemon->HasHeldItem(evolution->GetDataAt(0)->AsString());
|
|
case Library::EvolutionMethod::HoldsItemTime:
|
|
return pokemon->HasHeldItem(evolution->GetDataAt(0)->AsString()) &&
|
|
time >= (TimeOfDay)evolution->GetDataAt(0)->AsInt() &&
|
|
time <= (TimeOfDay)evolution->GetDataAt(1)->AsInt();
|
|
case Library::EvolutionMethod::IsGenderAndLevel:
|
|
return pokemon->GetLevel() >= evolution->GetDataAt(1)->AsInt() &&
|
|
pokemon->GetGender() == (CreatureLib::Library::Gender)evolution->GetDataAt(0)->AsInt();
|
|
case Library::EvolutionMethod::Custom: {
|
|
auto script = dynamic_cast<ScriptResolver*>(pokemon->GetLibrary()->GetScriptResolver().get())
|
|
->LoadEvolutionScript(evolution->GetDataAt(0)->AsString());
|
|
if (!script.HasValue()) {
|
|
return false;
|
|
}
|
|
auto v = false;
|
|
script.GetValue()->DoesEvolveFromLevelUp(evolution, pokemon, &v);
|
|
return v;
|
|
}
|
|
case Library::EvolutionMethod::EvolutionItemUse:
|
|
case Library::EvolutionMethod::EvolutionItemUseWithGender:
|
|
case Library::EvolutionMethod::Trade:
|
|
case Library::EvolutionMethod::TradeWithHeldItem:
|
|
case Library::EvolutionMethod::TradeWithSpecificPokemon: return false;
|
|
}
|
|
__builtin_unreachable();
|
|
}
|