afegit suport multiidioma
afegida traducció al valencià
This commit is contained in:
@@ -81,6 +81,10 @@ namespace Defaults::Kiosk {
|
||||
constexpr bool INFINITE_LIVES = false; // Vidas infinitas en modo kiosko desactivadas por defecto
|
||||
} // namespace Defaults::Kiosk
|
||||
|
||||
namespace Defaults::Localization {
|
||||
constexpr const char* LANGUAGE = "en"; // Idioma por defecto (en = inglés, ca = catalán)
|
||||
} // namespace Defaults::Localization
|
||||
|
||||
namespace Defaults::Game::Room {
|
||||
#ifdef _DEBUG
|
||||
constexpr const char* INITIAL = "51.yaml"; // Habitación de inicio en debug
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
#include <iostream> // Para cout, cerr
|
||||
#include <utility>
|
||||
|
||||
#include "game/options.hpp" // Para Options, options
|
||||
#include "game/ui/notifier.hpp" // Para Notifier
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "game/options.hpp" // Para Options, options
|
||||
#include "game/ui/notifier.hpp" // Para Notifier
|
||||
|
||||
// [SINGLETON]
|
||||
Cheevos* Cheevos::cheevos = nullptr;
|
||||
@@ -44,18 +45,19 @@ Cheevos::~Cheevos() {
|
||||
// Inicializa los logros
|
||||
void Cheevos::init() {
|
||||
cheevos_list_.clear();
|
||||
cheevos_list_.emplace_back(Achievement{.id = 1, .caption = "SHINY THINGS", .description = "Get 25% of the items", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 2, .caption = "HALF THE WORK", .description = "Get 50% of the items", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 3, .caption = "GETTING THERE", .description = "Get 75% of the items", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 4, .caption = "THE COLLECTOR", .description = "Get 100% of the items", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 5, .caption = "WANDERING AROUND", .description = "Visit 20 rooms", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 6, .caption = "I GOT LOST", .description = "Visit 40 rooms", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 7, .caption = "I LIKE TO EXPLORE", .description = "Visit all rooms", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 8, .caption = "FINISH THE GAME", .description = "Complete the game", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 9, .caption = "I WAS SUCKED BY A HOLE", .description = "Complete the game without entering the jail", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 10, .caption = "MY LITTLE PROJECTS", .description = "Complete the game with all items", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 11, .caption = "I LIKE MY MULTICOLOURED FRIENDS", .description = "Complete the game without dying", .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 12, .caption = "SHIT PROJECTS DONE FAST", .description = "Complete the game in under 30 minutes", .icon = 2});
|
||||
auto* loc = Locale::get();
|
||||
cheevos_list_.emplace_back(Achievement{.id = 1, .caption = loc->get("achievements.c1"), .description = loc->get("achievements.d1"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 2, .caption = loc->get("achievements.c2"), .description = loc->get("achievements.d2"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 3, .caption = loc->get("achievements.c3"), .description = loc->get("achievements.d3"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 4, .caption = loc->get("achievements.c4"), .description = loc->get("achievements.d4"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 5, .caption = loc->get("achievements.c5"), .description = loc->get("achievements.d5"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 6, .caption = loc->get("achievements.c6"), .description = loc->get("achievements.d6"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 7, .caption = loc->get("achievements.c7"), .description = loc->get("achievements.d7"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 8, .caption = loc->get("achievements.c8"), .description = loc->get("achievements.d8"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 9, .caption = loc->get("achievements.c9"), .description = loc->get("achievements.d9"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 10, .caption = loc->get("achievements.c10"), .description = loc->get("achievements.d10"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 11, .caption = loc->get("achievements.c11"), .description = loc->get("achievements.d11"), .icon = 2});
|
||||
cheevos_list_.emplace_back(Achievement{.id = 12, .caption = loc->get("achievements.c12"), .description = loc->get("achievements.d12"), .icon = 2});
|
||||
}
|
||||
|
||||
// Busca un logro por id y devuelve el indice
|
||||
@@ -82,7 +84,7 @@ void Cheevos::unlock(int id) {
|
||||
cheevos_list_.at(INDEX).completed = true;
|
||||
|
||||
// Mostrar notificación en la pantalla
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", cheevos_list_.at(INDEX).caption}, Notifier::Style::CHEEVO, -1, false);
|
||||
Notifier::get()->show({Locale::get()->get("achievements.header"), cheevos_list_.at(INDEX).caption}, Notifier::Style::CHEEVO, -1, false);
|
||||
|
||||
// Guardar el estado de los logros
|
||||
saveToFile();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "core/resources/resource_helper.hpp" // Para Resource::Helper
|
||||
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
||||
#include "game/options.hpp" // Para Options::language
|
||||
#include "utils/defines.hpp" // Para Tile::SIZE
|
||||
#include "utils/utils.hpp" // Para stringToColor
|
||||
|
||||
@@ -63,7 +64,10 @@ void RoomLoader::parseRoomConfig(const fkyaml::node& yaml, Room::Data& room, con
|
||||
room.number = file_name.substr(0, file_name.find_last_of('.'));
|
||||
|
||||
// Basic properties
|
||||
if (room_node.contains("name")) {
|
||||
const std::string LANG_KEY = "name_" + Options::language;
|
||||
if (room_node.contains(LANG_KEY)) {
|
||||
room.name = room_node[LANG_KEY].get_value<std::string>();
|
||||
} else if (room_node.contains("name")) {
|
||||
room.name = room_node["name"].get_value<std::string>();
|
||||
}
|
||||
if (room_node.contains("bgColor")) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
||||
@@ -156,13 +157,13 @@ void Scoreboard::fillTexture() {
|
||||
auto text = Resource::Cache::get()->getText("smb2");
|
||||
const std::string TIME_TEXT = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10);
|
||||
const std::string ITEMS_TEXT = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10);
|
||||
text->writeColored(Tile::SIZE, LINE1, "Items collected ", data_->color);
|
||||
text->writeColored(Tile::SIZE, LINE1, Locale::get()->get("scoreboard.items"), data_->color);
|
||||
text->writeColored(17 * Tile::SIZE, LINE1, ITEMS_TEXT, items_color_);
|
||||
text->writeColored(20 * Tile::SIZE, LINE1, " Time ", data_->color);
|
||||
text->writeColored(20 * Tile::SIZE, LINE1, Locale::get()->get("scoreboard.time"), data_->color);
|
||||
text->writeColored(26 * Tile::SIZE, LINE1, TIME_TEXT, stringToColor("white"));
|
||||
|
||||
const std::string ROOMS_TEXT = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10);
|
||||
text->writeColored(22 * Tile::SIZE, LINE2, "Rooms", stringToColor("white"));
|
||||
text->writeColored(22 * Tile::SIZE, LINE2, Locale::get()->get("scoreboard.rooms"), stringToColor("white"));
|
||||
text->writeColored(28 * Tile::SIZE, LINE2, ROOMS_TEXT, stringToColor("white"));
|
||||
|
||||
// Deja el renderizador como estaba
|
||||
|
||||
@@ -487,6 +487,21 @@ namespace Options {
|
||||
}
|
||||
}
|
||||
|
||||
// Carga configuración de idioma desde YAML
|
||||
void loadLocalizationFromYaml(const fkyaml::node& yaml) {
|
||||
if (yaml.contains("localization")) {
|
||||
const auto& loc = yaml["localization"];
|
||||
|
||||
if (loc.contains("language")) {
|
||||
try {
|
||||
language = loc["language"].get_value<std::string>();
|
||||
} catch (...) {
|
||||
language = Defaults::Localization::LANGUAGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Crea e inicializa las opciones del programa
|
||||
void init() {
|
||||
#ifdef _DEBUG
|
||||
@@ -550,6 +565,7 @@ namespace Options {
|
||||
loadKeyboardControlsFromYaml(yaml);
|
||||
loadGamepadControlsFromYaml(yaml);
|
||||
loadKioskConfigFromYaml(yaml);
|
||||
loadLocalizationFromYaml(yaml);
|
||||
|
||||
if (console) {
|
||||
std::cout << "Config file loaded successfully\n\n";
|
||||
@@ -640,6 +656,12 @@ namespace Options {
|
||||
file << " text: \"" << kiosk.text << "\"\n";
|
||||
file << " infinite_lives: " << (kiosk.infinite_lives ? "true" : "false") << "\n";
|
||||
|
||||
// LOCALIZATION
|
||||
file << "\n";
|
||||
file << "# LOCALIZATION (en = English, ca = Catalan)\n";
|
||||
file << "localization:\n";
|
||||
file << " language: \"" << language << "\"\n";
|
||||
|
||||
file.close();
|
||||
|
||||
if (console) {
|
||||
|
||||
@@ -139,6 +139,9 @@ namespace Options {
|
||||
inline GamepadControls gamepad_controls{}; // Botones del gamepad usados para jugar
|
||||
inline Kiosk kiosk{}; // Opciones del modo kiosko
|
||||
|
||||
// Idioma del juego (establecido al inicio, sin cambio en caliente)
|
||||
inline std::string language{Defaults::Localization::LANGUAGE};
|
||||
|
||||
// Ruta completa del fichero de configuración (establecida mediante setConfigFile)
|
||||
inline std::string config_file_path{};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/input/input.hpp" // Para Input
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/pixel_reveal.hpp" // Para PixelReveal
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
@@ -52,35 +53,35 @@ void Credits::handleInput() {
|
||||
|
||||
// Inicializa los textos
|
||||
void Credits::iniTexts() {
|
||||
std::string keys = "CURSORS";
|
||||
auto* loc = Locale::get();
|
||||
|
||||
texts_.clear();
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"INSTRUCTIONS:", static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({loc->get("credits.instructions"), static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"HELP JAILDOC TO GET BACK ALL", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"HIS PROJECTS AND GO TO THE", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"JAIL TO FINISH THEM", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.l0"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.l1"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.l2"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
|
||||
texts_.push_back({"KEYS:", static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({loc->get("credits.keys"), static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({keys + " TO MOVE AND JUMP", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"F8 TOGGLE THE MUSIC", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"F11 PAUSE THE GAME", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"F1-F2 WINDOWS SIZE", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"F3 TOGGLE FULLSCREEN", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"F9 TOOGLE BORDER SCREEN", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.keys_move"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.f8"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.f11"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.f1f2"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.f3"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.f9"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
|
||||
texts_.push_back({"A GAME BY JAILDESIGNER", static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({"MADE ON SUMMER/FALL 2022", static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({loc->get("credits.author"), static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({loc->get("credits.date"), static_cast<Uint8>(PaletteColor::YELLOW)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
|
||||
texts_.push_back({"I LOVE JAILGAMES! ", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({loc->get("credits.love"), static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
texts_.push_back({"", static_cast<Uint8>(PaletteColor::WHITE)});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/input/input.hpp" // Para Input
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/pixel_reveal.hpp" // Para PixelReveal
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
@@ -170,37 +171,38 @@ void Ending::updateState(float delta_time) {
|
||||
|
||||
// Inicializa los textos
|
||||
void Ending::iniTexts() {
|
||||
// Vector con los textos
|
||||
// Vector con los textos (traducidos según el idioma activo)
|
||||
std::vector<TextAndPosition> texts;
|
||||
auto* loc = Locale::get();
|
||||
|
||||
// Escena #0
|
||||
texts.push_back({"HE FINALLY MANAGED", 32});
|
||||
texts.push_back({"TO GET TO THE JAIL", 42});
|
||||
texts.push_back({"WITH ALL HIS PROJECTS", 142});
|
||||
texts.push_back({"READY TO BE FREED", 152});
|
||||
texts.push_back({loc->get("ending.t0"), 32});
|
||||
texts.push_back({loc->get("ending.t1"), 42});
|
||||
texts.push_back({loc->get("ending.t2"), 142});
|
||||
texts.push_back({loc->get("ending.t3"), 152});
|
||||
|
||||
// Escena #1
|
||||
texts.push_back({"ALL THE JAILERS WERE THERE", 1});
|
||||
texts.push_back({"WAITING FOR THE JAILGAMES", 11});
|
||||
texts.push_back({"TO BE RELEASED", 21});
|
||||
texts.push_back({loc->get("ending.t4"), 1});
|
||||
texts.push_back({loc->get("ending.t5"), 11});
|
||||
texts.push_back({loc->get("ending.t6"), 21});
|
||||
|
||||
texts.push_back({"THERE WERE EVEN BARRULLS AND", 161});
|
||||
texts.push_back({"BEGINNERS AMONG THE CROWD", 171});
|
||||
texts.push_back({loc->get("ending.t7"), 161});
|
||||
texts.push_back({loc->get("ending.t8"), 171});
|
||||
|
||||
texts.push_back({"BRY WAS CRYING...", 181});
|
||||
texts.push_back({loc->get("ending.t9"), 181});
|
||||
|
||||
// Escena #2
|
||||
texts.push_back({"BUT SUDDENLY SOMETHING", 19});
|
||||
texts.push_back({"CAUGHT HIS ATTENTION", 29});
|
||||
texts.push_back({loc->get("ending.t10"), 19});
|
||||
texts.push_back({loc->get("ending.t11"), 29});
|
||||
|
||||
// Escena #3
|
||||
texts.push_back({"A PILE OF JUNK!", 36});
|
||||
texts.push_back({"FULL OF NON WORKING TRASH!!", 46});
|
||||
texts.push_back({loc->get("ending.t12"), 36});
|
||||
texts.push_back({loc->get("ending.t13"), 46});
|
||||
|
||||
// Escena #4
|
||||
texts.push_back({"AND THEN,", 36});
|
||||
texts.push_back({"FOURTY NEW PROJECTS", 46});
|
||||
texts.push_back({"WERE BORN...", 158});
|
||||
texts.push_back({loc->get("ending.t14"), 36});
|
||||
texts.push_back({loc->get("ending.t15"), 46});
|
||||
texts.push_back({loc->get("ending.t16"), 158});
|
||||
|
||||
// Crea los sprites
|
||||
sprite_texts_.clear();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/input/input.hpp" // Para Input
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
#include "core/rendering/surface_dissolve_sprite.hpp" // Para SurfaceDissolveSprite
|
||||
@@ -403,7 +404,7 @@ void Ending2::createSpriteTexts() {
|
||||
std::string txt = sprite_list_[i];
|
||||
std::ranges::replace(txt, '_', ' '); // Reemplaza '_' por ' '
|
||||
if (txt == "player") {
|
||||
txt = "JAILDOCTOR"; // Reemplaza "player" por "JAILDOCTOR"
|
||||
txt = Locale::get()->get("ending2.jaildoctor"); // Reemplaza "player" por nombre localizado
|
||||
}
|
||||
|
||||
// Calcula las dimensiones del texto
|
||||
@@ -438,7 +439,7 @@ void Ending2::createSpriteTexts() {
|
||||
void Ending2::createTexts() {
|
||||
// Crea los primeros textos
|
||||
std::vector<std::string> list;
|
||||
list.emplace_back("STARRING");
|
||||
list.emplace_back(Locale::get()->get("ending2.starring"));
|
||||
|
||||
auto text = Resource::Cache::get()->getText("smb2");
|
||||
|
||||
@@ -469,8 +470,8 @@ void Ending2::createTexts() {
|
||||
// El primer texto va a continuación del ultimo spriteText
|
||||
const int START = sprite_texts_.back()->getPosY() + (text->getCharacterSize() * 15);
|
||||
list.clear();
|
||||
list.emplace_back("THANK YOU");
|
||||
list.emplace_back("FOR PLAYING!");
|
||||
list.emplace_back(Locale::get()->get("ending2.thank_you"));
|
||||
list.emplace_back(Locale::get()->get("ending2.for_playing"));
|
||||
|
||||
// Crea los sprites de texto a partir de la lista
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/input/input.hpp" // Para Input, InputAction, Input::DO_NOT_ALLOW_REPEAT
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG
|
||||
@@ -83,7 +84,7 @@ void Game::handleInput() {
|
||||
if (Input::get()->checkAction(InputAction::TOGGLE_MUSIC, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
scoreboard_data_->music = !scoreboard_data_->music;
|
||||
scoreboard_data_->music ? Audio::get()->resumeMusic() : Audio::get()->pauseMusic();
|
||||
Notifier::get()->show({"MUSIC " + std::string(scoreboard_data_->music ? "ENABLED" : "DISABLED")});
|
||||
Notifier::get()->show({scoreboard_data_->music ? Locale::get()->get("game.music_enabled") : Locale::get()->get("game.music_disabled")});
|
||||
}
|
||||
|
||||
// Durante fade/postfade, solo procesar inputs globales
|
||||
@@ -95,7 +96,7 @@ void Game::handleInput() {
|
||||
// Input de pausa solo en estado PLAYING
|
||||
if (Input::get()->checkAction(InputAction::PAUSE, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
togglePause();
|
||||
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")});
|
||||
Notifier::get()->show({paused_ ? Locale::get()->get("game.paused") : Locale::get()->get("game.running")});
|
||||
}
|
||||
|
||||
GlobalInputs::handle();
|
||||
@@ -370,7 +371,7 @@ void Game::renderPostFadeEnding() {
|
||||
static void toggleCheat(Options::Cheat::State& cheat, const std::string& label) {
|
||||
cheat = (cheat == Options::Cheat::State::ENABLED) ? Options::Cheat::State::DISABLED : Options::Cheat::State::ENABLED;
|
||||
const bool ENABLED = (cheat == Options::Cheat::State::ENABLED);
|
||||
Notifier::get()->show({label + (ENABLED ? " ENABLED" : " DISABLED")}, Notifier::Style::DEFAULT, -1, true);
|
||||
Notifier::get()->show({label + (ENABLED ? Locale::get()->get("game.enabled") : Locale::get()->get("game.disabled"))}, Notifier::Style::DEFAULT, -1, true);
|
||||
}
|
||||
|
||||
// Pasa la información de debug
|
||||
@@ -415,7 +416,7 @@ void Game::handleDebugEvents(const SDL_Event& event) {
|
||||
switch (event.key.key) {
|
||||
case SDLK_F12:
|
||||
Debug::get()->toggleEnabled();
|
||||
Notifier::get()->show({"DEBUG " + std::string(Debug::get()->isEnabled() ? "ENABLED" : "DISABLED")});
|
||||
Notifier::get()->show({Debug::get()->isEnabled() ? Locale::get()->get("game.debug_enabled") : Locale::get()->get("game.debug_disabled")});
|
||||
room_->redrawMap(); // Redibuja el tilemap para mostrar/ocultar líneas de colisión
|
||||
Options::cheats.invincible = static_cast<Options::Cheat::State>(Debug::get()->isEnabled());
|
||||
player_->setColor();
|
||||
@@ -444,21 +445,21 @@ void Game::handleDebugEvents(const SDL_Event& event) {
|
||||
break;
|
||||
|
||||
case SDLK_1:
|
||||
toggleCheat(Options::cheats.infinite_lives, "INFINITE LIVES");
|
||||
toggleCheat(Options::cheats.infinite_lives, Locale::get()->get("game.cheat_infinite_lives"));
|
||||
player_->setColor();
|
||||
break;
|
||||
|
||||
case SDLK_2:
|
||||
toggleCheat(Options::cheats.invincible, "INVINCIBLE");
|
||||
toggleCheat(Options::cheats.invincible, Locale::get()->get("game.cheat_invincible"));
|
||||
player_->setColor();
|
||||
break;
|
||||
|
||||
case SDLK_3:
|
||||
toggleCheat(Options::cheats.jail_is_open, "JAIL IS OPEN");
|
||||
toggleCheat(Options::cheats.jail_is_open, Locale::get()->get("game.cheat_jail_open"));
|
||||
break;
|
||||
|
||||
case SDLK_7:
|
||||
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, Notifier::Style::CHEEVO, -1, false, "F7");
|
||||
Notifier::get()->show({Locale::get()->get("game.achievement_unlocked"), Locale::get()->get("game.c11")}, Notifier::Style::CHEEVO, -1, false, "F7");
|
||||
break;
|
||||
|
||||
case SDLK_0:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/input/input.hpp" // Para Input
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
|
||||
#include "core/rendering/text.hpp" // Para Text::CENTER_FLAG, Text::COLOR_FLAG, Text
|
||||
@@ -68,7 +69,8 @@ void GameOver::render() {
|
||||
auto text = Resource::Cache::get()->getText("smb2");
|
||||
|
||||
// Escribe el texto de GAME OVER
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y, "G A M E O V E R", 1, color_);
|
||||
auto* loc = Locale::get();
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y, loc->get("game_over.title"), 1, color_);
|
||||
|
||||
// Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y)
|
||||
player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET);
|
||||
@@ -78,11 +80,11 @@ void GameOver::render() {
|
||||
// Escribe el texto con las habitaciones y los items
|
||||
const std::string ITEMS_TEXT = std::to_string(Options::stats.items / 100) + std::to_string((Options::stats.items % 100) / 10) + std::to_string(Options::stats.items % 10);
|
||||
const std::string ROOMS_TEXT = std::to_string(Options::stats.rooms / 100) + std::to_string((Options::stats.rooms % 100) / 10) + std::to_string(Options::stats.rooms % 10);
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + ITEMS_Y_OFFSET, "ITEMS: " + ITEMS_TEXT, 1, color_);
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + ROOMS_Y_OFFSET, "ROOMS: " + ROOMS_TEXT, 1, color_);
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + ITEMS_Y_OFFSET, loc->get("game_over.items") + ITEMS_TEXT, 1, color_);
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + ROOMS_Y_OFFSET, loc->get("game_over.rooms") + ROOMS_TEXT, 1, color_);
|
||||
|
||||
// Escribe el texto con "Tu peor pesadilla"
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + NIGHTMARE_TITLE_Y_OFFSET, "YOUR WORST NIGHTMARE IS", 1, color_);
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + NIGHTMARE_TITLE_Y_OFFSET, loc->get("game_over.worst_nightmare"), 1, color_);
|
||||
text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, TEXT_Y + NIGHTMARE_TEXT_Y_OFFSET, Options::stats.worst_nightmare, 1, color_);
|
||||
|
||||
// Vuelca el contenido del renderizador en pantalla
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
#include "core/input/input.hpp" // Para Input, InputAction, Input::DO_NOT_ALLOW_REPEAT, REP...
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
#include "core/rendering/surface_sprite.hpp" // Para SSprite
|
||||
@@ -57,7 +58,7 @@ Title::~Title() {
|
||||
// Inicializa la marquesina
|
||||
void Title::initMarquee() {
|
||||
letters_.clear();
|
||||
long_text_ = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
|
||||
long_text_ = Locale::get()->get("title.marquee");
|
||||
|
||||
// Pre-calcular anchos de caracteres para eficiencia
|
||||
for (size_t i = 0; i < long_text_.length(); ++i) {
|
||||
@@ -460,7 +461,7 @@ void Title::createCheevosTexture() {
|
||||
cheevos_surface_->clear(CHEEVOS_BG_COLOR);
|
||||
|
||||
// Escribe la lista de logros en la textura
|
||||
const std::string CHEEVOS_OWNER = "PROJECTS";
|
||||
const std::string CHEEVOS_OWNER = Locale::get()->get("title.projects");
|
||||
const std::string CHEEVOS_LIST_CAPTION = CHEEVOS_OWNER + " (" + std::to_string(Cheevos::get()->getTotalUnlockedAchievements()) + " / " + std::to_string(Cheevos::get()->size()) + ")";
|
||||
int pos = 2;
|
||||
TEXT->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, cheevos_surface_->getWidth() / 2, pos, CHEEVOS_LIST_CAPTION, 1, stringToColor("bright_green"));
|
||||
@@ -528,10 +529,11 @@ void Title::renderMainMenu() {
|
||||
const int TOTAL_HEIGHT = 3 * SPACING; // 3 espacios entre 4 items
|
||||
const int START_Y = MENU_CENTER_Y - (TOTAL_HEIGHT / 2);
|
||||
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, "1. PLAY", 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + SPACING, "2. REDEFINE KEYBOARD", 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + (2 * SPACING), "3. REDEFINE JOYSTICK", 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + (3 * SPACING), "4. PROJECTS", 1, COLOR);
|
||||
auto* loc = Locale::get();
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.menu.play"), 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + SPACING, loc->get("title.menu.keyboard"), 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + (2 * SPACING), loc->get("title.menu.joystick"), 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y + (3 * SPACING), loc->get("title.menu.projects"), 1, COLOR);
|
||||
}
|
||||
|
||||
// Dibuja el menu de logros
|
||||
@@ -582,13 +584,13 @@ void Title::handleKeyboardRemap(const SDL_Event& event) {
|
||||
|
||||
// Valida la tecla
|
||||
if (!isKeyValid(scancode)) {
|
||||
remap_error_message_ = "INVALID KEY! TRY ANOTHER";
|
||||
remap_error_message_ = Locale::get()->get("title.keys.invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifica duplicados
|
||||
if (isKeyDuplicate(scancode, remap_step_)) {
|
||||
remap_error_message_ = "KEY ALREADY USED! TRY ANOTHER";
|
||||
remap_error_message_ = Locale::get()->get("title.keys.already_used");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -679,29 +681,28 @@ void Title::renderKeyboardRemap() {
|
||||
const int START_Y = MENU_CENTER_Y - (2 * TEXT_SIZE); // Centrado aproximado
|
||||
|
||||
// Mensaje principal: "PRESS KEY FOR [ACTION]" o "KEYS DEFINED" si completado
|
||||
auto* loc = Locale::get();
|
||||
if (remap_step_ >= 3) {
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, "KEYS DEFINED", 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.keys.defined"), 1, COLOR);
|
||||
} else {
|
||||
const std::string ACTION = getActionName(remap_step_);
|
||||
const std::string MESSAGE = "PRESS KEY FOR " + ACTION;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, MESSAGE, 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.keys.prompt" + std::to_string(remap_step_)), 1, COLOR);
|
||||
}
|
||||
|
||||
// Mostrar teclas ya capturadas (con espaciado de 2 líneas desde el mensaje principal)
|
||||
const int KEYS_START_Y = START_Y + (2 * LINE_SPACING);
|
||||
if (remap_step_ > 0) {
|
||||
const std::string LEFT_KEY = SDL_GetScancodeName(temp_keys_[0]);
|
||||
const std::string LEFT_MSG = "LEFT: " + LEFT_KEY;
|
||||
const std::string LEFT_MSG = loc->get("title.keys.label0") + LEFT_KEY;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, KEYS_START_Y, LEFT_MSG, 1, COLOR);
|
||||
}
|
||||
if (remap_step_ > 1) {
|
||||
const std::string RIGHT_KEY = SDL_GetScancodeName(temp_keys_[1]);
|
||||
const std::string RIGHT_MSG = "RIGHT: " + RIGHT_KEY;
|
||||
const std::string RIGHT_MSG = loc->get("title.keys.label1") + RIGHT_KEY;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, KEYS_START_Y + LINE_SPACING, RIGHT_MSG, 1, COLOR);
|
||||
}
|
||||
if (remap_step_ >= 3) {
|
||||
const std::string JUMP_KEY = SDL_GetScancodeName(temp_keys_[2]);
|
||||
const std::string JUMP_MSG = "JUMP: " + JUMP_KEY;
|
||||
const std::string JUMP_MSG = loc->get("title.keys.label2") + JUMP_KEY;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, KEYS_START_Y + (2 * LINE_SPACING), JUMP_MSG, 1, COLOR);
|
||||
}
|
||||
|
||||
@@ -728,29 +729,28 @@ void Title::renderJoystickRemap() {
|
||||
const int START_Y = MENU_CENTER_Y - (2 * TEXT_SIZE); // Centrado aproximado
|
||||
|
||||
// Mensaje principal: "PRESS BUTTON FOR [ACTION]" o "BUTTONS DEFINED" si completado
|
||||
auto* loc = Locale::get();
|
||||
if (remap_step_ >= 3) {
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, "BUTTONS DEFINED", 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.buttons.defined"), 1, COLOR);
|
||||
} else {
|
||||
const std::string ACTION = getActionName(remap_step_);
|
||||
const std::string MESSAGE = "PRESS BUTTON FOR " + ACTION;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, MESSAGE, 1, COLOR);
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, START_Y, loc->get("title.buttons.prompt" + std::to_string(remap_step_)), 1, COLOR);
|
||||
}
|
||||
|
||||
// Mostrar botones ya capturados (con espaciado de 2 líneas desde el mensaje principal)
|
||||
const int BUTTONS_START_Y = START_Y + (2 * LINE_SPACING);
|
||||
if (remap_step_ > 0) {
|
||||
const std::string LEFT_BTN = getButtonName(temp_buttons_[0]);
|
||||
const std::string LEFT_MSG = "LEFT: " + LEFT_BTN;
|
||||
const std::string LEFT_MSG = loc->get("title.keys.label0") + LEFT_BTN;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, BUTTONS_START_Y, LEFT_MSG, 1, COLOR);
|
||||
}
|
||||
if (remap_step_ > 1) {
|
||||
const std::string RIGHT_BTN = getButtonName(temp_buttons_[1]);
|
||||
const std::string RIGHT_MSG = "RIGHT: " + RIGHT_BTN;
|
||||
const std::string RIGHT_MSG = loc->get("title.keys.label1") + RIGHT_BTN;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, BUTTONS_START_Y + LINE_SPACING, RIGHT_MSG, 1, COLOR);
|
||||
}
|
||||
if (remap_step_ >= 3) {
|
||||
const std::string JUMP_BTN = getButtonName(temp_buttons_[2]);
|
||||
const std::string JUMP_MSG = "JUMP: " + JUMP_BTN;
|
||||
const std::string JUMP_MSG = loc->get("title.keys.label2") + JUMP_BTN;
|
||||
menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PlayArea::CENTER_X, BUTTONS_START_Y + (2 * LINE_SPACING), JUMP_MSG, 1, COLOR);
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ void Title::handleJoystickRemap(const SDL_Event& event) {
|
||||
|
||||
// Verifica duplicados
|
||||
if (isButtonDuplicate(captured_button, remap_step_)) {
|
||||
remap_error_message_ = "BUTTON ALREADY USED! TRY ANOTHER";
|
||||
remap_error_message_ = Locale::get()->get("title.buttons.already_used");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user