Skip to content

Commit

Permalink
IV Range Filter update for Ursaluna.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mysticial committed Oct 3, 2023
1 parent 615ad3c commit 385c1b2
Show file tree
Hide file tree
Showing 10 changed files with 355 additions and 128 deletions.
4 changes: 2 additions & 2 deletions SerialPrograms/Source/CommonFramework/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ namespace PokemonAutomation{

const bool IS_BETA_VERSION = true;
const int PROGRAM_VERSION_MAJOR = 0;
const int PROGRAM_VERSION_MINOR = 41;
const int PROGRAM_VERSION_PATCH = 8;
const int PROGRAM_VERSION_MINOR = 42;
const int PROGRAM_VERSION_PATCH = 1;

const std::string PROGRAM_VERSION_BASE =
"v" + std::to_string(PROGRAM_VERSION_MAJOR) +
Expand Down
182 changes: 130 additions & 52 deletions SerialPrograms/Source/Pokemon/Options/Pokemon_StatsHuntFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ std::string gender_to_string(StatsHuntGenderFilter gender){
}


const EnumDatabase<StatsHuntAction>& EggHatchAction_Database(){
const EnumDatabase<StatsHuntAction>& StatsHuntAction_Database(){
static const EnumDatabase<StatsHuntAction> database({
{StatsHuntAction::StopProgram, "stop", "Stop Program"},
{StatsHuntAction::Keep, "keep", "Keep"},
// {EggHatchAction::Release, "release", "Release"},
});
return database;
}
const EnumDatabase<StatsHuntShinyFilter>& EggHatchShinyFilter_Database(){
const EnumDatabase<StatsHuntShinyFilter>& StatsHuntShinyFilter_Database(){
static const EnumDatabase<StatsHuntShinyFilter> database({
{StatsHuntShinyFilter::Anything, "anything", "Anything"},
{StatsHuntShinyFilter::NotShiny, "not-shiny", "Not Shiny"},
{StatsHuntShinyFilter::Shiny, "shiny", "Shiny"},
});
return database;
}
const EnumDatabase<StatsHuntGenderFilter>& EggHatchGenderFilter_Database(){
const EnumDatabase<StatsHuntGenderFilter>& StatsHuntGenderFilter_Database(){
static const EnumDatabase<StatsHuntGenderFilter> database({
{StatsHuntGenderFilter::Any, "any", "Any"},
{StatsHuntGenderFilter::Male, "male", "Male"},
Expand Down Expand Up @@ -74,17 +74,55 @@ const char* StatsHuntIvJudgeFilterTable_Label_Regular =

StatsHuntRowMisc::StatsHuntRowMisc(const StatsHuntMiscFeatureFlags& p_feature_flags)
: feature_flags(p_feature_flags)
, action(EggHatchAction_Database(), LockMode::LOCK_WHILE_RUNNING, StatsHuntAction::Keep)
, shiny(EggHatchShinyFilter_Database(), LockMode::LOCK_WHILE_RUNNING, StatsHuntShinyFilter::Anything)
, gender(EggHatchGenderFilter_Database(), LockMode::LOCK_WHILE_RUNNING, StatsHuntGenderFilter::Any)
, nature(NatureCheckerFilter_Database(), LockMode::LOCK_WHILE_RUNNING, NatureCheckerFilter::Any)
, action(
StatsHuntAction_Database(),
LockMode::UNLOCK_WHILE_RUNNING,
feature_flags.action
? StatsHuntAction::Keep
: StatsHuntAction::StopProgram
)
, shiny(StatsHuntShinyFilter_Database(), LockMode::UNLOCK_WHILE_RUNNING, StatsHuntShinyFilter::Anything)
, gender(StatsHuntGenderFilter_Database(), LockMode::UNLOCK_WHILE_RUNNING, StatsHuntGenderFilter::Any)
, nature(NatureCheckerFilter_Database(), LockMode::UNLOCK_WHILE_RUNNING, NatureCheckerFilter::Any)
{}
void StatsHuntRowMisc::set(const StatsHuntRowMisc& x){
action.set(x.action);
shiny.set(x.shiny);
gender.set(x.gender);
nature.set(x.nature);
}
bool StatsHuntRowMisc::matches(
bool shiny,
StatsHuntGenderFilter gender,
NatureCheckerValue nature
) const{
// Check the shiny filter.
switch (this->shiny){
case StatsHuntShinyFilter::Anything:
break;
case StatsHuntShinyFilter::NotShiny:
if (shiny){
return false;
}
break;
case StatsHuntShinyFilter::Shiny:
if (!shiny){
return false;
}
break;
}

StatsHuntGenderFilter filter_gender = this->gender;
if (filter_gender != gender && filter_gender != StatsHuntGenderFilter::Any){
return false;
}

if (!NatureChecker_filter_match(this->nature, nature)){
return false;
}

return true;
}


StatsHuntIvJudgeFilterRow::StatsHuntIvJudgeFilterRow(const StatsHuntMiscFeatureFlags& feature_flags)
Expand Down Expand Up @@ -128,24 +166,12 @@ std::unique_ptr<EditableTableRow> StatsHuntIvJudgeFilterRow::clone() const{
}
bool StatsHuntIvJudgeFilterRow::matches(
bool shiny,
const IvJudgeReader::Results& IVs,
StatsHuntGenderFilter gender,
NatureReader::Results nature
NatureCheckerValue nature,
const IvJudgeReader::Results& IVs
) const{
// Check the shiny filter.
switch (misc.shiny){
case StatsHuntShinyFilter::Anything:
break;
case StatsHuntShinyFilter::NotShiny:
if (shiny){
return false;
}
break;
case StatsHuntShinyFilter::Shiny:
if (!shiny){
return false;
}
break;
if (!misc.matches(shiny, gender, nature)){
return false;
}

// Check all the IV filters.
Expand All @@ -156,23 +182,14 @@ bool StatsHuntIvJudgeFilterRow::matches(
if (!IvJudge_filter_match(iv_spdef, IVs.spdef)) return false;
if (!IvJudge_filter_match(iv_speed, IVs.speed)) return false;

StatsHuntGenderFilter filter_gender = misc.gender;
if (filter_gender != gender && filter_gender != StatsHuntGenderFilter::Any){
return false;
}

if (!NatureChecker_filter_match(misc.nature, nature.nature)){
return false;
}

return true;
}

StatsHuntIvJudgeFilterTable::StatsHuntIvJudgeFilterTable(
const std::string& label,
const StatsHuntMiscFeatureFlags& p_feature_flags
)
: EditableTableOption_t<StatsHuntIvJudgeFilterRow>(label, LockMode::LOCK_WHILE_RUNNING)
: EditableTableOption_t<StatsHuntIvJudgeFilterRow>(label, LockMode::UNLOCK_WHILE_RUNNING)
, feature_flags(p_feature_flags)
{
set_default(make_defaults());
Expand Down Expand Up @@ -210,16 +227,16 @@ std::vector<std::unique_ptr<EditableTableRow>> StatsHuntIvJudgeFilterTable::make
}
StatsHuntAction StatsHuntIvJudgeFilterTable::get_action(
bool shiny,
const IvJudgeReader::Results& IVs,
StatsHuntGenderFilter gender,
NatureReader::Results nature
NatureCheckerValue nature,
const IvJudgeReader::Results& IVs
) const{
StatsHuntAction action = StatsHuntAction::Discard;
std::vector<std::unique_ptr<StatsHuntIvJudgeFilterRow>> list = copy_snapshot();
for (size_t c = 0; c < list.size(); c++){
const StatsHuntIvJudgeFilterRow& filter = *list[c];

if (!filter.matches(shiny, IVs, gender, nature)){
if (!filter.matches(shiny, gender, nature, IVs)){
continue;
}

Expand All @@ -243,6 +260,14 @@ StatsHuntAction StatsHuntIvJudgeFilterTable::get_action(




const char* StatsHuntIvRangeFilterTable_Label_Regular =
"<b>Stop Conditions:</b><br>"
"If the Pok\u00e9mon matches one of these filters, the program will stop.<br>"
"Partially overlapping IV ranges will count as a match. So if a filter is for 0-1, but the IV calculation returns a range 1-2, it will count.";



StatsHuntIvRangeFilterRow::StatsHuntIvRangeFilterRow(const StatsHuntMiscFeatureFlags& feature_flags)
: misc(feature_flags)
, iv_hp(LockMode::UNLOCK_WHILE_RUNNING, 0, 31, 0, 0, 0, 31, 31, 31)
Expand Down Expand Up @@ -277,12 +302,49 @@ std::unique_ptr<EditableTableRow> StatsHuntIvRangeFilterRow::clone() const{
ret->iv_speed.set(iv_speed);
return ret;
}
bool StatsHuntIvRangeFilterRow::match_iv(const IvRange& desired, const IvRange& actual){
if (desired.low == 0 && desired.high == 31){
return true;
}
if (actual.high < desired.low){
return false;
}
if (desired.high < actual.low){
return false;
}
return true;
}
bool StatsHuntIvRangeFilterRow::match_iv(const IntegerRangeCell<uint8_t>& desired, const IvRange& actual){
uint8_t lo, hi;
desired.current_values(lo, hi);
return match_iv(IvRange{(int8_t)lo, (int8_t)hi}, actual);
}
bool StatsHuntIvRangeFilterRow::matches(
bool shiny,
StatsHuntGenderFilter gender,
NatureCheckerValue nature,
const IvRanges& IVs
) const{
if (!misc.matches(shiny, gender, nature)){
return false;
}

if (!match_iv(iv_hp, IVs.hp)) return false;
if (!match_iv(iv_atk, IVs.attack)) return false;
if (!match_iv(iv_def, IVs.defense)) return false;
if (!match_iv(iv_spatk, IVs.spatk)) return false;
if (!match_iv(iv_spdef, IVs.spdef)) return false;
if (!match_iv(iv_speed, IVs.speed)) return false;

return true;
}


StatsHuntIvRangeFilterTable::StatsHuntIvRangeFilterTable(
const std::string& label,
const StatsHuntMiscFeatureFlags& p_feature_flags
)
: EditableTableOption_t<StatsHuntIvRangeFilterRow>(label, LockMode::LOCK_WHILE_RUNNING)
: EditableTableOption_t<StatsHuntIvRangeFilterRow>(label, LockMode::UNLOCK_WHILE_RUNNING)
, feature_flags(p_feature_flags)
{
// set_default(make_defaults());
Expand All @@ -302,30 +364,46 @@ std::vector<std::string> StatsHuntIvRangeFilterTable::make_header() const{
ret.emplace_back("Nature");
}

#if 1
ret.emplace_back("HP");
ret.emplace_back("Atk");
ret.emplace_back("Def");
ret.emplace_back("SpAtk");
ret.emplace_back("SpDef");
ret.emplace_back("Spd");
#else
ret.emplace_back("HP (low)");
ret.emplace_back("HP (high)");
ret.emplace_back("Atk (low)");
ret.emplace_back("Atk (high)");
ret.emplace_back("Def (low)");
ret.emplace_back("Def (high)");
ret.emplace_back("SpAtk (low)");
ret.emplace_back("SpAtk (high)");
ret.emplace_back("SpDef (low)");
ret.emplace_back("SpDef (high)");
ret.emplace_back("Spd (low)");
ret.emplace_back("Spd (high)");
#endif

return ret;
}
StatsHuntAction StatsHuntIvRangeFilterTable::get_action(
bool shiny,
StatsHuntGenderFilter gender,
NatureCheckerValue nature,
const IvRanges& IVs
) const{
StatsHuntAction action = StatsHuntAction::Discard;
std::vector<std::unique_ptr<StatsHuntIvRangeFilterRow>> list = copy_snapshot();
for (size_t c = 0; c < list.size(); c++){
const StatsHuntIvRangeFilterRow& filter = *list[c];

if (!filter.matches(shiny, gender, nature, IVs)){
continue;
}

StatsHuntAction filter_action = filter.misc.action;

// No action matched so far. Take the current action and continue.
if (action == StatsHuntAction::Discard){
action = filter_action;
continue;
}

// Conflicting actions.
if (action != filter_action){
global_logger_tagged().log("Multiple filters matched with conflicting actions. Stopping program...", COLOR_RED);
return StatsHuntAction::StopProgram;
}
}
return action;
}



Expand Down
31 changes: 23 additions & 8 deletions SerialPrograms/Source/Pokemon/Options/Pokemon_StatsHuntFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ struct StatsHuntRowMisc{
StatsHuntRowMisc(const StatsHuntMiscFeatureFlags& p_feature_flags);
void set(const StatsHuntRowMisc& x);

bool matches(
bool shiny,
StatsHuntGenderFilter gender,
NatureCheckerValue nature
) const;

const StatsHuntMiscFeatureFlags& feature_flags;

EnumDropdownCell<StatsHuntAction> action;
Expand All @@ -82,9 +88,9 @@ class StatsHuntIvJudgeFilterRow : public EditableTableRow{

bool matches(
bool shiny,
const IvJudgeReader::Results& IVs,
StatsHuntGenderFilter gender,
NatureReader::Results nature
NatureCheckerValue nature,
const IvJudgeReader::Results& IVs
) const;

public:
Expand All @@ -108,9 +114,9 @@ class StatsHuntIvJudgeFilterTable : public EditableTableOption_t<StatsHuntIvJudg

StatsHuntAction get_action(
bool shiny,
const IvJudgeReader::Results& IVs,
StatsHuntGenderFilter gender,
NatureReader::Results nature
NatureCheckerValue nature,
const IvJudgeReader::Results& IVs
) const;

public:
Expand All @@ -123,6 +129,11 @@ class StatsHuntIvJudgeFilterTable : public EditableTableOption_t<StatsHuntIvJudg




// Preset labels.
extern const char* StatsHuntIvRangeFilterTable_Label_Regular;


class StatsHuntIvRangeFilterTable;
class StatsHuntIvRangeFilterRow : public EditableTableRow{
public:
Expand All @@ -132,11 +143,15 @@ class StatsHuntIvRangeFilterRow : public EditableTableRow{

bool matches(
bool shiny,
const IvRanges& IVs,
StatsHuntGenderFilter gender,
NatureReader::Results nature
NatureCheckerValue nature,
const IvRanges& IVs
) const;

private:
static bool match_iv(const IvRange& desired, const IvRange& actual);
static bool match_iv(const IntegerRangeCell<uint8_t>& desired, const IvRange& actual);

public:
StatsHuntRowMisc misc;

Expand All @@ -158,9 +173,9 @@ class StatsHuntIvRangeFilterTable : public EditableTableOption_t<StatsHuntIvRang

StatsHuntAction get_action(
bool shiny,
const IvRanges& IVs,
StatsHuntGenderFilter gender,
NatureReader::Results nature
NatureCheckerValue nature,
const IvRanges& IVs
) const;

public:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ bool EggAutonomousState::process_party(){
StatsHuntGenderFilter gender = read_gender_from_box(m_console, m_console, screen);
NatureReader::Results nature = nature_detector.read(m_console.logger(), screen);

StatsHuntAction action = m_filters.get_action(shiny, IVs, gender, nature);
StatsHuntAction action = m_filters.get_action(shiny, gender, nature.nature, IVs);

switch (action){
case StatsHuntAction::StopProgram:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bool check_stats_reset_info(
bool shiny = false;

console.log(IVs.to_string(), COLOR_GREEN);
action = FILTERS.get_action(shiny, IVs, StatsHuntGenderFilter::Any, nature);
action = FILTERS.get_action(shiny, StatsHuntGenderFilter::Any, nature.nature, IVs);

return shiny;
}
Expand Down
Loading

0 comments on commit 385c1b2

Please sign in to comment.