Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ StateMachineAction run_state_iteration(
global_state,
runtime.console_settings[console_index],
battle_menu.dmaxed(),
battle_menu.cheer()
battle_menu.cheer(),
runtime.actions
);
case 5:
console.log("Current State: Catch Select");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class EndBattleDecider{
const PathStats& path_stats,
bool any_shiny, bool boss_is_shiny
) const = 0;

virtual bool stop_for_non_boss(const std::string& slug) const = 0;
};


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/* Max Lair Non-Boss Action
*
* From: https://github.com/PokemonAutomation/
*
*/

#include "Pokemon/Pokemon_Strings.h"
#include "Pokemon/Resources/Pokemon_PokemonNames.h"
#include "PokemonSwSh/Resources/PokemonSwSh_PokemonSprites.h"
#include "PokemonSwSh/Resources/PokemonSwSh_MaxLairDatabase.h"
#include "PokemonSwSh_MaxLair_Options_NonBossAction.h"

//#include <iostream>
//using std::cout;
//using std::endl;

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonSwSh{
namespace MaxLairInternal{




const EnumDropdownDatabase<NonBossAction>& NonBossAction_Database(){
static const EnumDropdownDatabase<NonBossAction> database({
{NonBossAction::IGNORE, "ignore", "Ignore"},
{NonBossAction::STOP_PROGRAM, "stop", "Stop program"},
});
return database;
}

static std::string format_display_name(const std::string& slug) {
static const std::vector<std::pair<std::string, std::string>> region_map = {

{"-alola", "Alolan "},
{"-galar", "Galarian "}
};

std::string base_slug = slug;
std::string prefix;

for (const auto& pair : region_map) {
size_t pos = slug.find(pair.first);
if (pos != std::string::npos) {
base_slug = slug.substr(0, pos);

prefix = pair.second;
break;
}
}

// Get base Pokemon name
std::string base_name = get_pokemon_name(base_slug).display_name();
return prefix + base_name;
}

NonBossActionRow::NonBossActionRow(std::string slug, const std::string& name_slug, const std::string& sprite_slug)
: StaticTableRow(slug)
, pokemon(
LockMode::UNLOCK_WHILE_RUNNING,
format_display_name(slug),
ALL_POKEMON_SPRITES().get_throw(sprite_slug).icon
)
, action(
NonBossAction_Database(),
LockMode::UNLOCK_WHILE_RUNNING,
NonBossAction::IGNORE
)
{
PA_ADD_STATIC(pokemon);
add_option(action, "Action");
}


NonBossActionTable::NonBossActionTable()
: StaticTableOption("<b>Other Pokemon Actions:</b>", LockMode::UNLOCK_WHILE_RUNNING)
{

// Limited mode: only display Alolan-Raichu and Alolan-Marowak by default. If the developer wants, it can also add the full list
const bool LIMITED_MODE = true;

if (LIMITED_MODE) {
std::vector<std::string> slugs = {"raichu-alola", "marowak-alola"};
for (const std::string& slug : slugs) {
const MaxLairSlugs& slugs_info = get_maxlair_slugs(slug);
const std::string& sprite_slug = *slugs_info.sprite_slugs.begin();
const std::string& name_slug = slugs_info.name_slug;
add_row(std::make_unique<NonBossActionRow>(slug, name_slug, sprite_slug));
}
} else {
std::set<std::string> added_grouped_base; // Track base slugs for grouped forms

for (const auto& item : all_rentals_by_dex()){
const std::string& full_slug = item.second;
const MaxLairSlugs& slugs = get_maxlair_slugs(full_slug);
const std::string& sprite_slug = *slugs.sprite_slugs.begin();
const std::string& name_slug = slugs.name_slug;

if (full_slug == name_slug) {
add_row(std::make_unique<NonBossActionRow>(full_slug, name_slug, sprite_slug));
continue;
}

// Check Alola and Galar variants
if (full_slug.size() > 6 && full_slug.substr(full_slug.size() - 6) == "-alola") {
add_row(std::make_unique<NonBossActionRow>(full_slug, name_slug, sprite_slug));
continue;
}
if (full_slug.size() > 6 && full_slug.substr(full_slug.size() - 6) == "-galar") {
add_row(std::make_unique<NonBossActionRow>(full_slug, name_slug, sprite_slug));
continue;
}

// All other pokemon with suffixes (e.g. Basculin) are grouped under one name

if (added_grouped_base.find(name_slug) == added_grouped_base.end()) {
add_row(std::make_unique<NonBossActionRow>(name_slug, name_slug, sprite_slug));
added_grouped_base.insert(name_slug);
}
}
}
finish_construction();
}

std::vector<std::string> NonBossActionTable::make_header() const{
std::vector<std::string> ret{
STRING_POKEMON,
"Action",
};
return ret;
}






}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* Max Lair Boss Action
*
* From: https://github.com/PokemonAutomation/
*
*/

#ifndef PokemonAutomation_PokemonSwSh_MaxLair_Options_NonBossAction_H
#define PokemonAutomation_PokemonSwSh_MaxLair_Options_NonBossAction_H

#include "Common/Cpp/Options/EnumDropdownOption.h"
#include "Common/Cpp/Options/StaticTableOption.h"
#include "CommonFramework/Options/LabelCellOption.h"

namespace PokemonAutomation{
namespace NintendoSwitch{
namespace PokemonSwSh{
namespace MaxLairInternal{


enum class NonBossAction{
IGNORE,
STOP_PROGRAM,
};

class NonBossActionRow : public StaticTableRow{
public:
NonBossActionRow(std::string slug, const std::string& name_slug, const std::string& sprite_slug);

LabelCellOption pokemon;
EnumDropdownCell<NonBossAction> action;
};

class NonBossActionTable : public StaticTableOption{
public:
NonBossActionTable();
virtual std::vector<std::string> make_header() const;
};





}
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ MaxLairBossFinder::MaxLairBossFinder()

PA_ADD_OPTION(CONSOLES);
PA_ADD_OPTION(BOSS_LIST);
PA_ADD_OPTION(NON_BOSS_LIST);
PA_ADD_OPTION(HOSTING);

PA_ADD_OPTION(TOUCH_DATE_INTERVAL);
Expand Down Expand Up @@ -119,9 +120,10 @@ void MaxLairBossFinder::update_active_consoles(size_t switch_count){

class EndBattleDecider_BossFinder : public EndBattleDecider{
public:
EndBattleDecider_BossFinder(const Consoles& consoles, const BossActionTable& boss_list)
EndBattleDecider_BossFinder(const Consoles& consoles, const BossActionTable& boss_list, NonBossActionTable& non_boss_list)
: m_consoles(consoles)
, m_boss_list(boss_list)
, m_non_boss_list(non_boss_list)
{}
virtual const std::string& normal_ball(
size_t console_index
Expand Down Expand Up @@ -151,6 +153,28 @@ class EndBattleDecider_BossFinder : public EndBattleDecider{
}
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid enum.");
}
virtual bool stop_for_non_boss(const std::string& slug) const override {
for (const StaticTableRow* row : m_non_boss_list.table()) {
const NonBossActionRow* nb_row = static_cast<const NonBossActionRow*>(row);

const std::string& row_slug = nb_row->slug();

// Exact match
if (slug == row_slug) {
return nb_row->action == NonBossAction::STOP_PROGRAM;
}

// If it has a specific variant, match any OCR slug that starts with it and has a hyphen (a form)
if (row_slug.find('-') == std::string::npos) {
if (slug.size() > row_slug.size() &&
slug.substr(0, row_slug.size()) == row_slug &&
slug[row_slug.size()] == '-') {
return nb_row->action == NonBossAction::STOP_PROGRAM;
}
}
}
return false;
}


private:
Expand All @@ -171,6 +195,7 @@ class EndBattleDecider_BossFinder : public EndBattleDecider{

const Consoles& m_consoles;
const BossActionTable& m_boss_list;
const NonBossActionTable& m_non_boss_list;

};

Expand All @@ -194,7 +219,7 @@ void MaxLairBossFinder::program(MultiSwitchProgramEnvironment& env, CancellableS
}
});

EndBattleDecider_BossFinder decider(CONSOLES, BOSS_LIST);
EndBattleDecider_BossFinder decider(CONSOLES, BOSS_LIST, NON_BOSS_LIST);

loop_adventures(
env, scope, CONSOLES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Options/PokemonSwSh_MaxLair_Options_Consoles.h"
#include "Options/PokemonSwSh_MaxLair_Options_Hosting.h"
#include "Options/PokemonSwSh_MaxLair_Options_BossAction.h"
#include "Options/PokemonSwSh_MaxLair_Options_NonBossAction.h"


namespace PokemonAutomation{
Expand Down Expand Up @@ -46,6 +47,7 @@ class MaxLairBossFinder : public MultiSwitchProgramInstance{

MaxLairInternal::Consoles CONSOLES;
MaxLairInternal::BossActionTable BOSS_LIST;
MaxLairInternal::NonBossActionTable NON_BOSS_LIST;
MaxLairInternal::HostingSettings HOSTING;

TouchDateIntervalOption TOUCH_DATE_INTERVAL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ class EndBattleDecider_Standard : public EndBattleDecider{
}
return actions.no_shinies;
}
virtual bool stop_for_non_boss(const std::string& slug) const override {
return false;
}

private:
const MaxLairStandard_ConsoleOptions& console(size_t index) const{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ class EndBattleDecider_StrongBoss : public EndBattleDecider{
return CaughtScreenAction::TAKE_NON_BOSS_SHINY_AND_CONTINUE;
}
}
virtual bool stop_for_non_boss(const std::string& slug) const override {
return false;
}

private:
const MaxLairStrongBoss_ConsoleOptions& console(size_t index) const{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ StateMachineAction run_move_select(
OcrFailureWatchdog& ocr_watchdog,
GlobalStateTracker& state_tracker,
const ConsoleSpecificOptions& settings,
bool currently_dmaxed, bool cheer_only
bool currently_dmaxed, bool cheer_only,
const EndBattleDecider& decider
){
GlobalState& state = state_tracker[console_index];
size_t player_index = state.find_player_index(console_index);
Expand All @@ -216,6 +217,14 @@ StateMachineAction run_move_select(
)){
return StateMachineAction::RESET_RECOVER;
}

if (state.wins < 4) {
const std::string& opponent = state.opponent.empty() ? "" : *state.opponent.begin();
if (!opponent.empty() && decider.stop_for_non_boss(opponent)) {
stream.log("Stopping program as " + opponent + " was encountered.", COLOR_PURPLE);
return StateMachineAction::STOP_PROGRAM;
}
}


GlobalState inferred = state_tracker.synchronize(stream.logger(), console_index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ StateMachineAction run_move_select(
OcrFailureWatchdog& ocr_watchdog,
GlobalStateTracker& state_tracker,
const ConsoleSpecificOptions& settings,
bool currently_dmaxed, bool cheer_only
bool currently_dmaxed, bool cheer_only,
const EndBattleDecider& decider
);

StateMachineAction throw_balls(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ struct MaxLairDatabase{
std::map<std::string, MaxLairMon> m_bosses;

std::map<size_t, std::string> m_bosses_by_dex;
std::multimap<size_t, std::string> m_rentals_by_dex;

static MaxLairDatabase& instance(){
static MaxLairDatabase data;
Expand All @@ -218,6 +219,15 @@ struct MaxLairDatabase{
}
m_bosses_by_dex[iter->second] = item.first;
}

for (const auto& item : m_rentals){
const MaxLairSlugs& slugs = get_maxlair_slugs(item.first);
auto iter = national_dex.find(slugs.name_slug);
if (iter == national_dex.end()){
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Rental slug not found in national dex: " + slugs.name_slug);
}
m_rentals_by_dex.insert({iter->second, item.first});
}

#if 0
for (const auto& item : m_bosses_by_dex){
Expand All @@ -237,6 +247,10 @@ const std::map<size_t, std::string>& all_bosses_by_dex(){
const MaxLairDatabase& database = MaxLairDatabase::instance();
return database.m_bosses_by_dex;
}
const std::multimap<size_t, std::string>& all_rentals_by_dex(){
const MaxLairDatabase& database = MaxLairDatabase::instance();
return database.m_rentals_by_dex;
}
bool is_boss(const std::string& slug){
const MaxLairDatabase& database = MaxLairDatabase::instance();
auto iter = database.m_bosses.find(slug);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct MaxLairMon{
};

const std::map<size_t, std::string>& all_bosses_by_dex();
const std::multimap<size_t, std::string>& all_rentals_by_dex();
bool is_boss(const std::string& slug);

const MaxLairMon& get_maxlair_mon(const std::string& slug);
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/cmake/SourceFiles.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2412,6 +2412,8 @@ file(GLOB LIBRARY_SOURCES
Source/PokemonSwSh/MaxLair/Options/PokemonSwSh_MaxLair_Options_Consoles.h
Source/PokemonSwSh/MaxLair/Options/PokemonSwSh_MaxLair_Options_Hosting.cpp
Source/PokemonSwSh/MaxLair/Options/PokemonSwSh_MaxLair_Options_Hosting.h
Source/PokemonSwSh/MaxLair/Options/PokemonSwSh_MaxLair_Options_NonBossAction.cpp
Source/PokemonSwSh/MaxLair/Options/PokemonSwSh_MaxLair_Options_NonBossAction.h
Source/PokemonSwSh/MaxLair/PokemonSwSh_MaxLair_BossFinder.cpp
Source/PokemonSwSh/MaxLair/PokemonSwSh_MaxLair_BossFinder.h
Source/PokemonSwSh/MaxLair/PokemonSwSh_MaxLair_Standard.cpp
Expand Down
Loading