afegits cheats a la consola

This commit is contained in:
2026-03-29 12:42:51 +02:00
parent 145bab037f
commit f5a82229fe
7 changed files with 170 additions and 83 deletions

View File

@@ -92,6 +92,32 @@ void Debug::setDebugFile(const std::string& path) {
debug_file_path_ = path;
}
// Convierte string a SceneManager::Scene (para debug.yaml)
static auto sceneFromString(const std::string& s) -> SceneManager::Scene {
if (s == "LOGO") { return SceneManager::Scene::LOGO; }
if (s == "LOADING") { return SceneManager::Scene::LOADING_SCREEN; }
if (s == "TITLE") { return SceneManager::Scene::TITLE; }
if (s == "CREDITS") { return SceneManager::Scene::CREDITS; }
if (s == "DEMO") { return SceneManager::Scene::DEMO; }
if (s == "ENDING") { return SceneManager::Scene::ENDING; }
if (s == "ENDING2") { return SceneManager::Scene::ENDING2; }
return SceneManager::Scene::GAME; // Fallback seguro
}
// Convierte SceneManager::Scene a string (para debug.yaml)
static auto sceneToString(SceneManager::Scene scene) -> std::string {
switch (scene) {
case SceneManager::Scene::LOGO: return "LOGO";
case SceneManager::Scene::LOADING_SCREEN: return "LOADING";
case SceneManager::Scene::TITLE: return "TITLE";
case SceneManager::Scene::CREDITS: return "CREDITS";
case SceneManager::Scene::DEMO: return "DEMO";
case SceneManager::Scene::ENDING: return "ENDING";
case SceneManager::Scene::ENDING2: return "ENDING2";
default: return "GAME";
}
}
// Carga la configuración de debug desde debug.yaml
void Debug::loadFromFile() {
// Inicializar con valores de release por defecto
@@ -99,6 +125,7 @@ void Debug::loadFromFile() {
spawn_settings_.spawn_x = Defaults::Game::Player::SPAWN_X;
spawn_settings_.spawn_y = Defaults::Game::Player::SPAWN_Y;
spawn_settings_.flip = Defaults::Game::Player::SPAWN_FLIP;
initial_scene_ = SceneManager::Scene::GAME;
std::ifstream file(debug_file_path_);
if (!file.good()) {
@@ -124,12 +151,16 @@ void Debug::loadFromFile() {
auto s = yaml["spawn_flip"].get_value<std::string>();
spawn_settings_.flip = (s == "right") ? Flip::RIGHT : Flip::LEFT;
}
if (yaml.contains("initial_scene")) {
initial_scene_ = sceneFromString(yaml["initial_scene"].get_value<std::string>());
}
} catch (...) {
// YAML inválido: resetear a defaults y sobreescribir
spawn_settings_.room = Defaults::Game::Room::INITIAL;
spawn_settings_.spawn_x = Defaults::Game::Player::SPAWN_X;
spawn_settings_.spawn_y = Defaults::Game::Player::SPAWN_Y;
spawn_settings_.flip = Defaults::Game::Player::SPAWN_FLIP;
initial_scene_ = SceneManager::Scene::GAME;
saveToFile();
}
}
@@ -144,6 +175,7 @@ void Debug::saveToFile() const {
file << "spawn_x: " << (spawn_settings_.spawn_x / Tile::SIZE) << " # en tiles\n";
file << "spawn_y: " << (spawn_settings_.spawn_y / Tile::SIZE) << " # en tiles\n";
file << "spawn_flip: " << ((spawn_settings_.flip == Flip::RIGHT) ? "right" : "left") << "\n";
file << "initial_scene: " << sceneToString(initial_scene_) << "\n";
}
#endif // _DEBUG

View File

@@ -8,6 +8,8 @@
#include <string> // Para string
#include <vector> // Para vector
#include "game/scene_manager.hpp" // Para SceneManager::Scene
// Clase Debug
class Debug {
public:
@@ -41,8 +43,10 @@ class Debug {
void setDebugFile(const std::string& path); // Establece la ruta del archivo debug.yaml
void loadFromFile(); // Carga la configuración de debug desde debug.yaml
void saveToFile() const; // Guarda la configuración de debug en debug.yaml
[[nodiscard]] auto getSpawnSettings() const -> const SpawnSettings& { return spawn_settings_; } // Obtiene los valores de spawn
void setSpawnSettings(const SpawnSettings& s) { spawn_settings_ = s; } // Establece los valores de spawn
[[nodiscard]] auto getSpawnSettings() const -> const SpawnSettings& { return spawn_settings_; } // Obtiene los valores de spawn
void setSpawnSettings(const SpawnSettings& s) { spawn_settings_ = s; } // Establece los valores de spawn
[[nodiscard]] auto getInitialScene() const -> SceneManager::Scene { return initial_scene_; } // Obtiene la escena inicial de debug
void setInitialScene(SceneManager::Scene s) { initial_scene_ = s; } // Establece la escena inicial de debug
private:
static Debug* debug; // [SINGLETON] Objeto privado
@@ -59,6 +63,7 @@ class Debug {
bool enabled_ = false; // Indica si esta activo el modo debug
std::string debug_file_path_; // Ruta del archivo debug.yaml
SpawnSettings spawn_settings_; // Configuración de spawn para debug
SceneManager::Scene initial_scene_ = SceneManager::Scene::GAME; // Escena inicial en debug
};
#endif // _DEBUG

View File

@@ -171,6 +171,7 @@ Director::Director(std::vector<std::string> const& args) {
Debug::init();
Debug::get()->setDebugFile(Resource::List::get()->get("debug.yaml"));
Debug::get()->loadFromFile();
SceneManager::current = Debug::get()->getInitialScene();
#endif
std::cout << "\n"; // Fin de inicialización de sistemas

View File

@@ -1,13 +1,18 @@
#pragma once
#ifdef _DEBUG
#include <functional>
#include <string>
namespace GameControl {
// Disponible en todos los builds — refresca el color del jugador según cheats
inline std::function<void()> refresh_player_color;
}
#ifdef _DEBUG
namespace GameControl {
// Registrada por Game::Game() — cambia la habitación activa
inline std::function<bool(const std::string&)> change_room;
// Registrada por Game::Game() — refresca el color del jugador según cheats
inline std::function<void()> refresh_player_color;
// Registrada por Game::Game() — fija el contador de items recogidos
inline std::function<void(int)> set_items;
// Registrada por Game::Game() — hace toggle del modo debug (equivale a tecla 0)
inline std::function<void()> toggle_debug_mode;
// Registrada por Game::Game() — guarda la habitación actual como habitación de inicio en debug.yaml

View File

@@ -34,13 +34,8 @@ namespace SceneManager {
};
// --- Variables de estado globales ---
#ifdef _DEBUG
inline Scene current = Scene::GAME; // Escena actual
inline Scene current = Scene::LOGO; // Escena actual (en _DEBUG sobrescrito por Director tras cargar debug.yaml)
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
#else
inline Scene current = Scene::LOGO; // Escena actual
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
#endif
inline Scene scene_before_restart = Scene::LOGO; // escena a relanzar tras RESTART_CURRENT
inline Scene scene_before_restart = Scene::LOGO; // escena a relanzar tras RESTART_CURRENT
} // namespace SceneManager

View File

@@ -64,9 +64,14 @@ Game::Game(Mode mode)
Cheevos::get()->enable(!Options::cheats.enabled()); // Deshabilita los logros si hay trucos activados
Cheevos::get()->clearUnobtainableState();
GameControl::refresh_player_color = [this]() -> void { player_->setColor(); };
#ifdef _DEBUG
GameControl::change_room = [this](const std::string& r) -> bool { return this->changeRoom(r); };
GameControl::refresh_player_color = [this]() -> void { player_->setColor(); };
GameControl::set_items = [this](int count) -> void {
scoreboard_data_->items = count;
Options::stats.items = count;
};
GameControl::toggle_debug_mode = [this]() -> void {
Debug::get()->toggleEnabled();
room_->redrawMap();
@@ -104,9 +109,11 @@ Game::Game(Mode mode)
Game::~Game() {
ItemTracker::destroy();
GameControl::refresh_player_color = nullptr;
#ifdef _DEBUG
GameControl::change_room = nullptr;
GameControl::refresh_player_color = nullptr;
GameControl::set_items = nullptr;
GameControl::toggle_debug_mode = nullptr;
GameControl::set_initial_room = nullptr;
GameControl::set_initial_pos = nullptr;

View File

@@ -19,9 +19,10 @@
#include "game/scene_manager.hpp" // Para SceneManager
#include "game/ui/notifier.hpp" // Para Notifier
#include "game/game_control.hpp" // Para GameControl (refresh_player_color)
#ifdef _DEBUG
#include "core/system/debug.hpp" // Para Debug
#include "game/game_control.hpp" // Para GameControl
#endif
// ── Sistema de comandos ────────────────────────────────────────────────────────
@@ -89,11 +90,13 @@ static void printHelp() {
#ifdef _DEBUG
SDL_Log(" DEBUG Toggle debug overlay (F12)");
SDL_Log(" ROOM <1-60> Change to room number (GAME only)");
SDL_Log(" INFINITE LIVES [ON|OFF] Infinite lives cheat (GAME only)");
SDL_Log(" INVENCIBILITY [ON|OFF] Invincibility cheat (GAME only)");
SDL_Log(" OPEN THE JAIL Open the jail (GAME only)");
SDL_Log(" CLOSE THE JAIL Close the jail (GAME only)");
SDL_Log(" SET INITIAL [ROOM|POS] Set initial room/position from current state (GAME only)");
SDL_Log(" SET INITIAL SCENE [<name>] Set initial debug scene (GAME|LOGO|TITLE|LOADING|CREDITS|ENDING|ENDING2)");
SDL_Log(" SET ITEMS <0-200> Set collected items count (GAME only)");
SDL_Log(" CHEAT INFINITE LIVES [ON|OFF] Infinite lives (GAME only)");
SDL_Log(" CHEAT INVINCIBILITY [ON|OFF] Invincibility (GAME only)");
SDL_Log(" CHEAT OPEN THE JAIL Open the jail (GAME only)");
SDL_Log(" CHEAT CLOSE THE JAIL Close the jail (GAME only)");
#endif
SDL_Log(" AUDIO [ON|OFF|VOL <0-100>] Audio master");
SDL_Log(" MUSIC [ON|OFF|VOL <0-100>] Music volume");
@@ -408,70 +411,76 @@ static const std::vector<ConsoleCommand> COMMANDS = {
return std::string("Room not found: ") + buf;
}},
// INFINITE LIVES [ON|OFF] — Truco vidas infinitas (tecla 1); solo en escena GAME
{.keyword = "INFINITE", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty() || args[0] != "LIVES") { return "Usage: INFINITE LIVES [ON|OFF]"; }
auto& cheat = Options::cheats.infinite_lives;
using State = Options::Cheat::State;
const std::vector<std::string> REST(args.begin() + 1, args.end());
if (REST.empty()) {
cheat = (cheat == State::ENABLED) ? State::DISABLED : State::ENABLED;
} else if (REST[0] == "ON") {
if (cheat == State::ENABLED) { return "Infinite lives already ON"; }
cheat = State::ENABLED;
} else if (REST[0] == "OFF") {
if (cheat == State::DISABLED) { return "Infinite lives already OFF"; }
cheat = State::DISABLED;
} else {
return "Usage: INFINITE LIVES [ON|OFF]";
}
if (GameControl::refresh_player_color) { GameControl::refresh_player_color(); }
return std::string("Infinite lives ") + (cheat == State::ENABLED ? "ON" : "OFF");
}},
// INVENCIBILITY [ON|OFF] — Truco invencibilidad (tecla 2); solo en escena GAME
{.keyword = "INVENCIBILITY", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
auto& cheat = Options::cheats.invincible;
using State = Options::Cheat::State;
if (args.empty()) {
cheat = (cheat == State::ENABLED) ? State::DISABLED : State::ENABLED;
} else if (args[0] == "ON") {
if (cheat == State::ENABLED) { return "Invencibility already ON"; }
cheat = State::ENABLED;
} else if (args[0] == "OFF") {
if (cheat == State::DISABLED) { return "Invencibility already OFF"; }
cheat = State::DISABLED;
} else {
return "Usage: INVENCIBILITY [ON|OFF]";
}
if (GameControl::refresh_player_color) { GameControl::refresh_player_color(); }
return std::string("Invencibility ") + (cheat == State::ENABLED ? "ON" : "OFF");
}},
// OPEN THE JAIL — Abre la jail (tecla 3 → ON); solo en escena GAME
{.keyword = "OPEN", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.size() < 2 || args[0] != "THE" || args[1] != "JAIL") { return "Usage: OPEN THE JAIL"; }
if (Options::cheats.jail_is_open == Options::Cheat::State::ENABLED) { return "Jail already open"; }
Options::cheats.jail_is_open = Options::Cheat::State::ENABLED;
return "Jail opened";
}},
// CLOSE THE JAIL — Cierra la jail (tecla 3 → OFF); solo en escena GAME
{.keyword = "CLOSE", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.size() < 2 || args[0] != "THE" || args[1] != "JAIL") { return "Usage: CLOSE THE JAIL"; }
if (Options::cheats.jail_is_open == Options::Cheat::State::DISABLED) { return "Jail already closed"; }
Options::cheats.jail_is_open = Options::Cheat::State::DISABLED;
return "Jail closed";
}},
#endif
// SET SHADER [POSTFX|CRTPI] — Activa un shader concreto (disponible en todos los builds)
// SET INITIAL [ROOM|POS] — Guarda habitación/posición actual como inicio (solo _DEBUG, GAME)
// CHEAT <subcomando> — Trucos de juego; solo en escena GAME; no aparece en ayuda en builds Release
{.keyword = "CHEAT", .execute = [](const std::vector<std::string>& args) -> std::string {
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty()) { return "Usage: CHEAT [INFINITE LIVES|INVINCIBILITY|OPEN THE JAIL|CLOSE THE JAIL]"; }
// CHEAT INFINITE LIVES [ON|OFF]
if (args[0] == "INFINITE") {
if (args.size() < 2 || args[1] != "LIVES") { return "Usage: CHEAT INFINITE LIVES [ON|OFF]"; }
auto& cheat = Options::cheats.infinite_lives;
using State = Options::Cheat::State;
const std::vector<std::string> REST(args.begin() + 2, args.end());
if (REST.empty()) {
cheat = (cheat == State::ENABLED) ? State::DISABLED : State::ENABLED;
} else if (REST[0] == "ON") {
if (cheat == State::ENABLED) { return "Infinite lives already ON"; }
cheat = State::ENABLED;
} else if (REST[0] == "OFF") {
if (cheat == State::DISABLED) { return "Infinite lives already OFF"; }
cheat = State::DISABLED;
} else {
return "Usage: CHEAT INFINITE LIVES [ON|OFF]";
}
if (GameControl::refresh_player_color) { GameControl::refresh_player_color(); }
return std::string("Infinite lives ") + (cheat == State::ENABLED ? "ON" : "OFF");
}
// CHEAT INVINCIBILITY [ON|OFF]
if (args[0] == "INVINCIBILITY" || args[0] == "INVENCIBILITY") {
auto& cheat = Options::cheats.invincible;
using State = Options::Cheat::State;
if (args.size() == 1) {
cheat = (cheat == State::ENABLED) ? State::DISABLED : State::ENABLED;
} else if (args[1] == "ON") {
if (cheat == State::ENABLED) { return "Invincibility already ON"; }
cheat = State::ENABLED;
} else if (args[1] == "OFF") {
if (cheat == State::DISABLED) { return "Invincibility already OFF"; }
cheat = State::DISABLED;
} else {
return "Usage: CHEAT INVINCIBILITY [ON|OFF]";
}
if (GameControl::refresh_player_color) { GameControl::refresh_player_color(); }
return std::string("Invincibility ") + (cheat == State::ENABLED ? "ON" : "OFF");
}
// CHEAT OPEN THE JAIL
if (args[0] == "OPEN") {
if (args.size() < 3 || args[1] != "THE" || args[2] != "JAIL") { return "Usage: CHEAT OPEN THE JAIL"; }
if (Options::cheats.jail_is_open == Options::Cheat::State::ENABLED) { return "Jail already open"; }
Options::cheats.jail_is_open = Options::Cheat::State::ENABLED;
return "Jail opened";
}
// CHEAT CLOSE THE JAIL
if (args[0] == "CLOSE") {
if (args.size() < 3 || args[1] != "THE" || args[2] != "JAIL") { return "Usage: CHEAT CLOSE THE JAIL"; }
if (Options::cheats.jail_is_open == Options::Cheat::State::DISABLED) { return "Jail already closed"; }
Options::cheats.jail_is_open = Options::Cheat::State::DISABLED;
return "Jail closed";
}
return "Usage: CHEAT [INFINITE LIVES|INVINCIBILITY|OPEN THE JAIL|CLOSE THE JAIL]";
}},
// SET SHADER [POSTFX|CRTPI] — Activa un shader concreto (disponible en todos los builds)
// SET INITIAL [ROOM|POS] — Guarda habitación/posición actual como inicio (solo _DEBUG, GAME)
// SET INITIAL SCENE [<name>] — Guarda escena como escena inicial de debug (solo _DEBUG)
// SET ITEMS <0-200> — Fija el contador de items recogidos (solo _DEBUG, GAME)
{.keyword = "SET", .execute = [](const std::vector<std::string>& args) -> std::string {
if (!args.empty() && args[0] == "SHADER") {
if (args.size() < 2) { return "Usage: SET SHADER [POSTFX|CRTPI]"; }
@@ -486,13 +495,46 @@ static const std::vector<ConsoleCommand> COMMANDS = {
return "Usage: SET SHADER [POSTFX|CRTPI]";
}
#ifdef _DEBUG
// SET INITIAL SCENE [<nombre>] — disponible desde cualquier escena
if (args.size() >= 2 && args[0] == "INITIAL" && args[1] == "SCENE") {
SceneManager::Scene target = SceneManager::current;
std::string name = "current";
if (args.size() >= 3) {
if (args[2] == "GAME") { target = SceneManager::Scene::GAME; name = "GAME"; }
else if (args[2] == "LOGO") { target = SceneManager::Scene::LOGO; name = "LOGO"; }
else if (args[2] == "LOADING") { target = SceneManager::Scene::LOADING_SCREEN; name = "LOADING"; }
else if (args[2] == "TITLE") { target = SceneManager::Scene::TITLE; name = "TITLE"; }
else if (args[2] == "CREDITS") { target = SceneManager::Scene::CREDITS; name = "CREDITS"; }
else if (args[2] == "ENDING") { target = SceneManager::Scene::ENDING; name = "ENDING"; }
else if (args[2] == "ENDING2") { target = SceneManager::Scene::ENDING2; name = "ENDING2"; }
else { return "Unknown scene: " + args[2]; }
}
Debug::get()->setInitialScene(target);
Debug::get()->saveToFile();
return "Initial scene set to: " + name;
}
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
if (args.empty() || args[0] != "INITIAL") { return "Usage: SET INITIAL [ROOM|POS] | SET SHADER [POSTFX|CRTPI]"; }
// SET ITEMS <0-200> — Fija el contador de items recogidos
if (args[0] == "ITEMS") {
if (args.size() < 2) { return "Usage: SET ITEMS <0-200>"; }
int count = 0;
try {
count = std::stoi(args[1]);
} catch (...) { return "Usage: SET ITEMS <0-200>"; }
if (count < 0 || count > 200) { return "Items must be between 0 and 200"; }
if (!GameControl::set_items) { return "Game not initialized"; }
GameControl::set_items(count);
return "Items: " + std::to_string(count);
}
if (args.empty() || args[0] != "INITIAL") { return "Usage: SET INITIAL [ROOM|POS|SCENE] | SET ITEMS <0-200> | SET SHADER [POSTFX|CRTPI]"; }
const bool DO_ROOM = args.size() == 1 || (args.size() >= 2 && args[1] == "ROOM");
const bool DO_POS = args.size() == 1 || (args.size() >= 2 && args[1] == "POS");
if (!DO_ROOM && !DO_POS) { return "Usage: SET INITIAL [ROOM|POS]"; }
if (!DO_ROOM && !DO_POS) { return "Usage: SET INITIAL [ROOM|POS|SCENE]"; }
if (!GameControl::set_initial_room || !GameControl::set_initial_pos) { return "Game not initialized"; }
std::string result;