3 Commits

6 changed files with 85 additions and 14 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.cache/
.vscode/
*data/config/config.yaml
*stats.txt

View File

@@ -21,20 +21,32 @@ namespace GlobalInputs {
// Funciones internas
namespace {
void handleQuit() {
const std::string CODE = SceneManager::current == SceneManager::Scene::GAME ? "PRESS AGAIN TO RETURN TO MENU" : "PRESS AGAIN TO EXIT";
auto code_found = stringInVector(Notifier::get()->getCodes(), CODE);
if (code_found) {
// Si la notificación de salir está activa, cambia de sección
switch (SceneManager::current) {
case SceneManager::Scene::GAME:
SceneManager::current = SceneManager::Scene::TITLE;
break;
default:
SceneManager::current = SceneManager::Scene::QUIT;
break;
// En la escena GAME el comportamiento es siempre el mismo (con o sin modo kiosko)
if (SceneManager::current == SceneManager::Scene::GAME) {
const std::string CODE = "PRESS AGAIN TO RETURN TO MENU";
if (stringInVector(Notifier::get()->getCodes(), CODE)) {
SceneManager::current = SceneManager::Scene::TITLE;
} else {
Notifier::get()->show({CODE}, Notifier::Style::DEFAULT, -1, true, CODE);
}
return;
}
// En modo kiosko, fuera de GAME: mostrar el texto del kiosko y no salir nunca
if (Options::kiosk.enabled) {
const std::string KIOSK_CODE = "KIOSK_EXIT";
if (!stringInVector(Notifier::get()->getCodes(), KIOSK_CODE)) {
Notifier::get()->show({Options::kiosk.text}, Notifier::Style::DEFAULT, -1, true, KIOSK_CODE);
}
// Segunda pulsación: notificación ya activa → no hacer nada
return;
}
// Comportamiento normal fuera del modo kiosko
const std::string CODE = "PRESS AGAIN TO EXIT";
if (stringInVector(Notifier::get()->getCodes(), CODE)) {
SceneManager::current = SceneManager::Scene::QUIT;
} else {
// Si la notificación de salir no está activa, muestra la notificación
Notifier::get()->show({CODE}, Notifier::Style::DEFAULT, -1, true, CODE);
}
}

View File

@@ -88,4 +88,11 @@ constexpr int GAMEPAD_BUTTON_RIGHT = SDL_GAMEPAD_BUTTON_DPAD_RIGHT; // Botón d
constexpr int GAMEPAD_BUTTON_JUMP = SDL_GAMEPAD_BUTTON_WEST; // Botón salto por defecto
} // namespace Controls
// --- KIOSK ---
namespace Kiosk {
constexpr bool ENABLED = false; // Modo kiosko desactivado por defecto
constexpr const char* TEXT = ""; // Texto del modo kiosko por defecto
constexpr bool INFINITE_LIVES = false; // Vidas infinitas en modo kiosko desactivadas por defecto
} // namespace Kiosk
} // namespace Defaults

View File

@@ -257,7 +257,9 @@ auto stringToGamepadButton(const std::string& str, int default_value) -> int {
}
auto isValidPalette(const std::string& palette) -> bool {
return std::ranges::any_of(VALID_PALETTES, [&palette](const auto& valid) { return valid == palette; });
std::string lower_palette = palette;
std::ranges::transform(lower_palette, lower_palette.begin(), ::tolower);
return std::ranges::any_of(VALID_PALETTES, [&lower_palette](const auto& valid) { return valid == lower_palette; });
}
// --- Funciones helper para loadFromFile() ---
@@ -454,6 +456,37 @@ void loadGamepadControlsFromYaml(const fkyaml::node& yaml) {
}
}
// Carga configuración del modo kiosko desde YAML
void loadKioskConfigFromYaml(const fkyaml::node& yaml) {
if (yaml.contains("kiosk")) {
const auto& k = yaml["kiosk"];
if (k.contains("enabled")) {
try {
kiosk.enabled = k["enabled"].get_value<bool>();
} catch (...) {
kiosk.enabled = Defaults::Kiosk::ENABLED;
}
}
if (k.contains("text")) {
try {
kiosk.text = k["text"].get_value<std::string>();
} catch (...) {
kiosk.text = Defaults::Kiosk::TEXT;
}
}
if (k.contains("infinite_lives")) {
try {
kiosk.infinite_lives = k["infinite_lives"].get_value<bool>();
} catch (...) {
kiosk.infinite_lives = Defaults::Kiosk::INFINITE_LIVES;
}
}
}
}
// Crea e inicializa las opciones del programa
void init() {
#ifdef _DEBUG
@@ -516,6 +549,7 @@ auto loadFromFile() -> bool {
loadVideoConfigFromYaml(yaml);
loadKeyboardControlsFromYaml(yaml);
loadGamepadControlsFromYaml(yaml);
loadKioskConfigFromYaml(yaml);
if (console) {
std::cout << "Config file loaded successfully\n\n";
@@ -598,6 +632,14 @@ auto saveToFile() -> bool {
file << " button_right: " << gamepadButtonToString(gamepad_controls.button_right) << "\n";
file << " button_jump: " << gamepadButtonToString(gamepad_controls.button_jump) << "\n";
// KIOSK
file << "\n";
file << "# KIOSK MODE\n";
file << "kiosk:\n";
file << " enabled: " << (kiosk.enabled ? "true" : "false") << "\n";
file << " text: \"" << kiosk.text << "\"\n";
file << " infinite_lives: " << (kiosk.infinite_lives ? "true" : "false") << "\n";
file.close();
if (console) {

View File

@@ -53,6 +53,13 @@ struct Stats {
std::string worst_nightmare{Defaults::Stats::WORST_NIGHTMARE}; // Habitación con más muertes acumuladas
};
// Estructura para el modo kiosko
struct Kiosk {
bool enabled{Defaults::Kiosk::ENABLED}; // Indica si el modo kiosko está activo
std::string text{Defaults::Kiosk::TEXT}; // Texto a mostrar en el modo kiosko
bool infinite_lives{Defaults::Kiosk::INFINITE_LIVES}; // Indica si el jugador tiene vidas infinitas en modo kiosko
};
// Estructura con opciones de la ventana
struct Window {
std::string caption{Texts::WINDOW_CAPTION}; // Texto que aparece en la barra de título de la ventana
@@ -117,6 +124,7 @@ inline Window window{}; // Opciones relativas a la ventana
inline Audio audio{}; // Opciones relativas al audio
inline KeyboardControls keyboard_controls{}; // Teclas usadas para jugar
inline GamepadControls gamepad_controls{}; // Botones del gamepad usados para jugar
inline Kiosk kiosk{}; // Opciones del modo kiosko
// Ruta completa del fichero de configuración (establecida mediante setConfigFile)
inline std::string config_file_path{};

View File

@@ -640,7 +640,8 @@ void Game::killPlayer() {
}
// Resta una vida al jugador
if (Options::cheats.infinite_lives == Options::Cheat::State::DISABLED) {
if (Options::cheats.infinite_lives == Options::Cheat::State::DISABLED &&
!(Options::kiosk.enabled && Options::kiosk.infinite_lives)) {
--scoreboard_data_->lives;
}