clang-tidy
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "game/editor/editor_statusbar.hpp"
|
||||
|
||||
#include <string> // Para to_string
|
||||
#include <utility>
|
||||
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/rendering/surface.hpp" // Para Surface
|
||||
@@ -13,9 +14,9 @@
|
||||
#include "utils/utils.hpp" // Para stringToColor, toLower
|
||||
|
||||
// Constructor
|
||||
EditorStatusBar::EditorStatusBar(const std::string& room_number, const std::string& room_name)
|
||||
: room_number_(room_number),
|
||||
room_name_(room_name) {
|
||||
EditorStatusBar::EditorStatusBar(std::string room_number, std::string room_name)
|
||||
: room_number_(std::move(room_number)),
|
||||
room_name_(std::move(room_name)) {
|
||||
const float SURFACE_WIDTH = Options::game.width;
|
||||
constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE; // 48 pixels, igual que el scoreboard
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Surface;
|
||||
|
||||
class EditorStatusBar {
|
||||
public:
|
||||
EditorStatusBar(const std::string& room_number, const std::string& room_name);
|
||||
EditorStatusBar(std::string room_number, std::string room_name);
|
||||
~EditorStatusBar() = default;
|
||||
|
||||
void render();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath> // Para std::round
|
||||
#include <cstdio> // Para std::remove (borrar fichero)
|
||||
#include <fstream> // Para ifstream, ofstream
|
||||
@@ -88,7 +89,7 @@ void MapEditor::loadSettings() {
|
||||
}
|
||||
|
||||
// Guarda las opciones del editor a editor.yaml
|
||||
void MapEditor::saveSettings() {
|
||||
void MapEditor::saveSettings() const {
|
||||
std::string path = Resource::List::get()->get("editor.yaml");
|
||||
if (path.empty()) { return; }
|
||||
|
||||
@@ -332,7 +333,7 @@ void MapEditor::update(float delta_time) {
|
||||
|
||||
// Si estamos pintando tiles, pintar en la posición actual del ratón
|
||||
if (painting_ && brush_tile_ != NO_BRUSH) {
|
||||
int tile_index = mouse_tile_y_ * 32 + mouse_tile_x_;
|
||||
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
|
||||
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
|
||||
if (room_data_.tile_map[tile_index] != brush_tile_) {
|
||||
room_data_.tile_map[tile_index] = brush_tile_;
|
||||
@@ -382,7 +383,7 @@ void MapEditor::render() {
|
||||
}
|
||||
|
||||
// Maneja eventos del editor
|
||||
void MapEditor::handleEvent(const SDL_Event& event) {
|
||||
void MapEditor::handleEvent(const SDL_Event& event) { // NOLINT(readability-function-cognitive-complexity)
|
||||
// Si el tile picker está abierto, los eventos van a él
|
||||
if (tile_picker_.isOpen()) {
|
||||
tile_picker_.handleEvent(event);
|
||||
@@ -426,7 +427,7 @@ void MapEditor::handleEvent(const SDL_Event& event) {
|
||||
selected_item_ = -1;
|
||||
|
||||
// Tile bajo el cursor como tile actual del picker
|
||||
int tile_index = mouse_tile_y_ * 32 + mouse_tile_x_;
|
||||
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
|
||||
int current = (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size()))
|
||||
? room_data_.tile_map[tile_index]
|
||||
: -1;
|
||||
@@ -463,7 +464,7 @@ void MapEditor::handleEvent(const SDL_Event& event) {
|
||||
if (!hit_entity) {
|
||||
// Pintar tile y entrar en modo painting
|
||||
painting_ = true;
|
||||
int tile_index = mouse_tile_y_ * 32 + mouse_tile_x_;
|
||||
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
|
||||
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
|
||||
room_data_.tile_map[tile_index] = brush_tile_;
|
||||
room_->setTile(tile_index, brush_tile_);
|
||||
@@ -487,7 +488,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
|
||||
// Prioridad de hit test: jugador → enemigos (initial) → enemigos (boundaries) → items
|
||||
|
||||
// Helper para iniciar drag
|
||||
auto startDrag = [&](DragTarget target, int index, float entity_x, float entity_y) {
|
||||
auto start_drag = [&](DragTarget target, int index, float entity_x, float entity_y) {
|
||||
drag_.target = target;
|
||||
drag_.index = index;
|
||||
drag_.offset_x = game_x - entity_x;
|
||||
@@ -500,7 +501,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
|
||||
// 1. Hit test sobre el jugador (8x16)
|
||||
SDL_FRect player_rect = player_->getRect();
|
||||
if (pointInRect(game_x, game_y, player_rect)) {
|
||||
startDrag(DragTarget::PLAYER, -1, player_rect.x, player_rect.y);
|
||||
start_drag(DragTarget::PLAYER, -1, player_rect.x, player_rect.y);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -509,7 +510,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
|
||||
for (int i = 0; i < enemy_mgr->getCount(); ++i) {
|
||||
SDL_FRect enemy_rect = enemy_mgr->getEnemy(i)->getRect();
|
||||
if (pointInRect(game_x, game_y, enemy_rect)) {
|
||||
startDrag(DragTarget::ENEMY_INITIAL, i, enemy_rect.x, enemy_rect.y);
|
||||
start_drag(DragTarget::ENEMY_INITIAL, i, enemy_rect.x, enemy_rect.y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -517,17 +518,17 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
|
||||
// 3. Hit test sobre boundaries de enemigos (rectángulos 8x8 en las posiciones de room_data_)
|
||||
for (int i = 0; i < static_cast<int>(room_data_.enemies.size()); ++i) {
|
||||
const auto& ed = room_data_.enemies[i];
|
||||
constexpr float SZ = static_cast<float>(Tile::SIZE);
|
||||
constexpr auto SZ = static_cast<float>(Tile::SIZE);
|
||||
|
||||
SDL_FRect b1_rect = {.x = static_cast<float>(ed.x1), .y = static_cast<float>(ed.y1), .w = SZ, .h = SZ};
|
||||
if (pointInRect(game_x, game_y, b1_rect)) {
|
||||
startDrag(DragTarget::ENEMY_BOUND1, i, b1_rect.x, b1_rect.y);
|
||||
start_drag(DragTarget::ENEMY_BOUND1, i, b1_rect.x, b1_rect.y);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_FRect b2_rect = {.x = static_cast<float>(ed.x2), .y = static_cast<float>(ed.y2), .w = SZ, .h = SZ};
|
||||
if (pointInRect(game_x, game_y, b2_rect)) {
|
||||
startDrag(DragTarget::ENEMY_BOUND2, i, b2_rect.x, b2_rect.y);
|
||||
start_drag(DragTarget::ENEMY_BOUND2, i, b2_rect.x, b2_rect.y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -537,7 +538,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
|
||||
for (int i = 0; i < item_mgr->getCount(); ++i) {
|
||||
SDL_FRect item_rect = item_mgr->getItem(i)->getCollider();
|
||||
if (pointInRect(game_x, game_y, item_rect)) {
|
||||
startDrag(DragTarget::ITEM, i, item_rect.x, item_rect.y);
|
||||
start_drag(DragTarget::ITEM, i, item_rect.x, item_rect.y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -548,7 +549,7 @@ void MapEditor::handleMouseDown(float game_x, float game_y) {
|
||||
}
|
||||
|
||||
// Procesa soltar el ratón: commit del drag
|
||||
void MapEditor::handleMouseUp() {
|
||||
void MapEditor::handleMouseUp() { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (drag_.target == DragTarget::NONE) { return; }
|
||||
|
||||
const int IDX = drag_.index;
|
||||
@@ -681,7 +682,7 @@ void MapEditor::renderSelectionHighlight() {
|
||||
auto game_surface = Screen::get()->getRendererSurface();
|
||||
if (!game_surface) { return; }
|
||||
|
||||
constexpr float SZ = static_cast<float>(Tile::SIZE);
|
||||
constexpr auto SZ = static_cast<float>(Tile::SIZE);
|
||||
|
||||
// Highlight del enemigo seleccionado (persistente, color bright_green)
|
||||
if (selected_enemy_ >= 0 && selected_enemy_ < room_->getEnemyManager()->getCount()) {
|
||||
@@ -767,10 +768,10 @@ void MapEditor::renderEnemyBoundaries() {
|
||||
// Posiciones base (pueden estar siendo arrastradas)
|
||||
float init_x = enemy.x;
|
||||
float init_y = enemy.y;
|
||||
float b1_x = static_cast<float>(enemy.x1);
|
||||
float b1_y = static_cast<float>(enemy.y1);
|
||||
float b2_x = static_cast<float>(enemy.x2);
|
||||
float b2_y = static_cast<float>(enemy.y2);
|
||||
auto b1_x = static_cast<float>(enemy.x1);
|
||||
auto b1_y = static_cast<float>(enemy.y1);
|
||||
auto b2_x = static_cast<float>(enemy.x2);
|
||||
auto b2_y = static_cast<float>(enemy.y2);
|
||||
|
||||
// Si estamos arrastrando una boundary de este enemigo, usar la posición snapped
|
||||
if (drag_.index == i) {
|
||||
@@ -824,14 +825,14 @@ void MapEditor::updateMousePosition() {
|
||||
mouse_tile_y_ = static_cast<int>(mouse_game_y_) / Tile::SIZE;
|
||||
|
||||
// Clampear a los límites del mapa
|
||||
if (mouse_tile_x_ < 0) { mouse_tile_x_ = 0; }
|
||||
mouse_tile_x_ = std::max(mouse_tile_x_, 0);
|
||||
if (mouse_tile_x_ >= PlayArea::WIDTH / Tile::SIZE) { mouse_tile_x_ = PlayArea::WIDTH / Tile::SIZE - 1; }
|
||||
if (mouse_tile_y_ < 0) { mouse_tile_y_ = 0; }
|
||||
mouse_tile_y_ = std::max(mouse_tile_y_, 0);
|
||||
if (mouse_tile_y_ >= PlayArea::HEIGHT / Tile::SIZE) { mouse_tile_y_ = PlayArea::HEIGHT / Tile::SIZE - 1; }
|
||||
}
|
||||
|
||||
// Actualiza la información de la barra de estado
|
||||
void MapEditor::updateStatusBarInfo() {
|
||||
void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!statusbar_) { return; }
|
||||
|
||||
statusbar_->setMouseTile(mouse_tile_x_, mouse_tile_y_);
|
||||
@@ -944,7 +945,7 @@ auto MapEditor::getSetCompletions() const -> std::vector<std::string> {
|
||||
}
|
||||
|
||||
// Modifica una propiedad del enemigo seleccionado
|
||||
auto MapEditor::setEnemyProperty(const std::string& property, const std::string& value) -> std::string {
|
||||
auto MapEditor::setEnemyProperty(const std::string& property, const std::string& value) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!active_) { return "Editor not active"; }
|
||||
if (!hasSelectedEnemy()) { return "No enemy selected"; }
|
||||
|
||||
@@ -1124,7 +1125,7 @@ auto MapEditor::duplicateEnemy() -> std::string {
|
||||
}
|
||||
|
||||
// Modifica una propiedad de la habitación
|
||||
auto MapEditor::setRoomProperty(const std::string& property, const std::string& value) -> std::string {
|
||||
auto MapEditor::setRoomProperty(const std::string& property, const std::string& value) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!active_) { return "Editor not active"; }
|
||||
|
||||
std::string val = toLower(value);
|
||||
@@ -1267,7 +1268,7 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string&
|
||||
}
|
||||
|
||||
// Crea una nueva habitación
|
||||
auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
|
||||
auto MapEditor::createNewRoom(const std::string& direction) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!active_) { return "Editor not active"; }
|
||||
|
||||
// Validar dirección si se proporcionó
|
||||
@@ -1340,7 +1341,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
|
||||
}
|
||||
|
||||
// Conexiones del YAML
|
||||
auto connStr = [](const std::string& c) -> std::string { return (c == "0") ? "null" : c; };
|
||||
auto conn_str = [](const std::string& c) -> std::string { return (c == "0") ? "null" : c; };
|
||||
|
||||
// Crear el YAML
|
||||
std::ofstream file(new_path);
|
||||
@@ -1355,10 +1356,10 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
|
||||
file << " tileSetFile: standard.gif\n";
|
||||
file << "\n";
|
||||
file << " connections:\n";
|
||||
file << " up: " << connStr(new_room.upper_room) << "\n";
|
||||
file << " down: " << connStr(new_room.lower_room) << "\n";
|
||||
file << " left: " << connStr(new_room.left_room) << "\n";
|
||||
file << " right: " << connStr(new_room.right_room) << "\n";
|
||||
file << " up: " << conn_str(new_room.upper_room) << "\n";
|
||||
file << " down: " << conn_str(new_room.lower_room) << "\n";
|
||||
file << " left: " << conn_str(new_room.left_room) << "\n";
|
||||
file << " right: " << conn_str(new_room.right_room) << "\n";
|
||||
file << "\n";
|
||||
file << " itemColor1: bright_cyan\n";
|
||||
file << " itemColor2: yellow\n";
|
||||
@@ -1405,7 +1406,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string {
|
||||
}
|
||||
|
||||
// Elimina la habitación actual
|
||||
auto MapEditor::deleteRoom() -> std::string {
|
||||
auto MapEditor::deleteRoom() -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!active_) { return "Editor not active"; }
|
||||
|
||||
std::string deleted_name = room_path_;
|
||||
@@ -1434,7 +1435,7 @@ auto MapEditor::deleteRoom() -> std::string {
|
||||
if (target == "0") { return "Cannot delete: no other room to navigate to"; }
|
||||
|
||||
// Desenlazar todas las conexiones recíprocas
|
||||
auto unlinkReciprocal = [&](const std::string& neighbor, const std::string& field_name) {
|
||||
auto unlink_reciprocal = [&](const std::string& neighbor, const std::string& field_name) {
|
||||
if (neighbor == "0" || neighbor.empty()) { return; }
|
||||
auto other = Resource::Cache::get()->getRoom(neighbor);
|
||||
if (!other) { return; }
|
||||
@@ -1455,10 +1456,10 @@ auto MapEditor::deleteRoom() -> std::string {
|
||||
}
|
||||
};
|
||||
|
||||
unlinkReciprocal(room_data_.upper_room, "lower_room"); // Si nosotros somos su lower
|
||||
unlinkReciprocal(room_data_.lower_room, "upper_room"); // Si nosotros somos su upper
|
||||
unlinkReciprocal(room_data_.left_room, "right_room"); // Si nosotros somos su right
|
||||
unlinkReciprocal(room_data_.right_room, "left_room"); // Si nosotros somos su left
|
||||
unlink_reciprocal(room_data_.upper_room, "lower_room"); // Si nosotros somos su lower
|
||||
unlink_reciprocal(room_data_.lower_room, "upper_room"); // Si nosotros somos su upper
|
||||
unlink_reciprocal(room_data_.left_room, "right_room"); // Si nosotros somos su right
|
||||
unlink_reciprocal(room_data_.right_room, "left_room"); // Si nosotros somos su left
|
||||
|
||||
// Navegar a la room destino antes de borrar
|
||||
reenter_ = true;
|
||||
@@ -1473,9 +1474,7 @@ auto MapEditor::deleteRoom() -> std::string {
|
||||
|
||||
// Quitar del cache
|
||||
auto& cache_rooms = Resource::Cache::get()->getRooms();
|
||||
cache_rooms.erase(
|
||||
std::remove_if(cache_rooms.begin(), cache_rooms.end(), [&](const RoomResource& r) { return r.name == deleted_name; }),
|
||||
cache_rooms.end());
|
||||
std::erase_if(cache_rooms, [&](const RoomResource& r) { return r.name == deleted_name; });
|
||||
|
||||
// Quitar de Resource::List (mapa + assets.yaml)
|
||||
Resource::List::get()->removeAsset(deleted_name);
|
||||
@@ -1598,7 +1597,7 @@ auto MapEditor::duplicateItem() -> std::string {
|
||||
// Elige un color de grid que contraste con el fondo
|
||||
// Empieza con bright_black (1), si coincide con el bg en la paleta activa, sube índices
|
||||
static auto pickGridColor(Uint8 bg, const std::shared_ptr<Surface>& surface) -> Uint8 {
|
||||
Uint8 grid = static_cast<Uint8>(PaletteColor::BRIGHT_BLACK);
|
||||
auto grid = static_cast<Uint8>(PaletteColor::BRIGHT_BLACK);
|
||||
Uint32 bg_argb = surface->getPaletteColor(bg);
|
||||
|
||||
// Si bright_black es igual al bg, buscar el siguiente color distinto
|
||||
@@ -1610,7 +1609,7 @@ static auto pickGridColor(Uint8 bg, const std::shared_ptr<Surface>& surface) ->
|
||||
}
|
||||
|
||||
// Dibuja la cuadrícula de tiles (líneas de puntos, 1 pixel sí / 1 no)
|
||||
void MapEditor::renderGrid() {
|
||||
void MapEditor::renderGrid() const {
|
||||
auto game_surface = Screen::get()->getRendererSurface();
|
||||
if (!game_surface) { return; }
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class MapEditor {
|
||||
void openTilePicker(const std::string& tileset_name, int current_tile);
|
||||
|
||||
private:
|
||||
static MapEditor* instance_; // [SINGLETON] Objeto privado
|
||||
static MapEditor* instance_; // NOLINT(readability-identifier-naming) [SINGLETON] Objeto privado
|
||||
|
||||
MapEditor(); // Constructor
|
||||
~MapEditor(); // Destructor
|
||||
@@ -79,7 +79,7 @@ class MapEditor {
|
||||
};
|
||||
Settings settings_;
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
void saveSettings() const;
|
||||
|
||||
// Tipos para drag & drop y selección
|
||||
enum class DragTarget { NONE,
|
||||
@@ -102,9 +102,9 @@ class MapEditor {
|
||||
// Métodos internos
|
||||
void updateMousePosition();
|
||||
void renderEnemyBoundaries();
|
||||
void renderBoundaryMarker(float x, float y, Uint8 color);
|
||||
static void renderBoundaryMarker(float x, float y, Uint8 color);
|
||||
void renderSelectionHighlight();
|
||||
void renderGrid();
|
||||
void renderGrid() const;
|
||||
void handleMouseDown(float game_x, float game_y);
|
||||
void handleMouseUp();
|
||||
void updateDrag();
|
||||
|
||||
@@ -94,7 +94,7 @@ void MiniMap::layoutRooms() {
|
||||
|
||||
// Empezar por la primera room
|
||||
const std::string& start = rooms[0].name;
|
||||
bfs.push({start, {0, 0}});
|
||||
bfs.push({start, {.x = 0, .y = 0}});
|
||||
visited.insert(start);
|
||||
|
||||
// Grid ocupado: posición → nombre de room
|
||||
@@ -120,21 +120,21 @@ void MiniMap::layoutRooms() {
|
||||
int dx, dy;
|
||||
};
|
||||
std::array<Neighbor, 4> neighbors = {{
|
||||
{data->upper_room, 0, -1},
|
||||
{data->lower_room, 0, 1},
|
||||
{data->left_room, -1, 0},
|
||||
{data->right_room, 1, 0},
|
||||
{.room = data->upper_room, .dx = 0, .dy = -1},
|
||||
{.room = data->lower_room, .dx = 0, .dy = 1},
|
||||
{.room = data->left_room, .dx = -1, .dy = 0},
|
||||
{.room = data->right_room, .dx = 1, .dy = 0},
|
||||
}};
|
||||
|
||||
for (const auto& [neighbor_name, dx, dy] : neighbors) {
|
||||
if (neighbor_name == "0" || neighbor_name.empty()) { continue; }
|
||||
if (visited.contains(neighbor_name)) { continue; }
|
||||
|
||||
GridPos neighbor_pos = {pos.x + dx, pos.y + dy};
|
||||
GridPos neighbor_pos = {.x = pos.x + dx, .y = pos.y + dy};
|
||||
auto nkey = std::make_pair(neighbor_pos.x, neighbor_pos.y);
|
||||
if (!grid_occupied.contains(nkey)) {
|
||||
visited.insert(neighbor_name);
|
||||
bfs.push({neighbor_name, neighbor_pos});
|
||||
bfs.emplace(neighbor_name, neighbor_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,7 +181,7 @@ auto MiniMap::getRoomMiniSurface(const std::string& room_name) -> std::shared_pt
|
||||
const auto& tile_map = room_data->tile_map;
|
||||
for (int y = 0; y < ROOM_H; ++y) {
|
||||
for (int x = 0; x < ROOM_W; ++x) {
|
||||
int index = y * ROOM_W + x;
|
||||
int index = (y * ROOM_W) + x;
|
||||
if (index >= static_cast<int>(tile_map.size())) { continue; }
|
||||
|
||||
int tile = tile_map[index];
|
||||
@@ -253,14 +253,14 @@ void MiniMap::drawConnections() {
|
||||
// Conexión derecha
|
||||
if (room_data->right_room != "0" && !room_data->right_room.empty() && room_positions_.contains(room_data->right_room)) {
|
||||
int x1 = px + CELL_W;
|
||||
int y_mid = py + CELL_H / 2 - 1;
|
||||
int y_mid = py + (CELL_H / 2) - 1;
|
||||
SDL_FRect line = {.x = static_cast<float>(x1), .y = static_cast<float>(y_mid), .w = static_cast<float>(GAP), .h = 3.0F};
|
||||
map_surface_->fillRect(&line, conn_color_);
|
||||
}
|
||||
|
||||
// Conexión abajo
|
||||
if (room_data->lower_room != "0" && !room_data->lower_room.empty() && room_positions_.contains(room_data->lower_room)) {
|
||||
int x_mid = px + CELL_W / 2 - 1;
|
||||
int x_mid = px + (CELL_W / 2) - 1;
|
||||
int y1 = py + CELL_H;
|
||||
SDL_FRect line = {.x = static_cast<float>(x_mid), .y = static_cast<float>(y1), .w = 3.0F, .h = static_cast<float>(GAP)};
|
||||
map_surface_->fillRect(&line, conn_color_);
|
||||
@@ -274,8 +274,8 @@ void MiniMap::centerOnRoom(const std::string& room_name) {
|
||||
if (it == room_positions_.end()) { return; }
|
||||
const auto& pos = it->second.pos;
|
||||
|
||||
float room_cx = static_cast<float>(cellPixelX(pos.x) + CELL_W / 2);
|
||||
float room_cy = static_cast<float>(cellPixelY(pos.y) + CELL_H / 2);
|
||||
auto room_cx = static_cast<float>(cellPixelX(pos.x) + (CELL_W / 2));
|
||||
auto room_cy = static_cast<float>(cellPixelY(pos.y) + (CELL_H / 2));
|
||||
view_x_ = static_cast<float>(PlayArea::WIDTH) / 2.0F - room_cx;
|
||||
view_y_ = static_cast<float>(PlayArea::HEIGHT) / 2.0F - room_cy;
|
||||
}
|
||||
@@ -287,8 +287,8 @@ auto MiniMap::roomAtScreen(float screen_x, float screen_y) -> std::string {
|
||||
float map_y = screen_y - view_y_;
|
||||
|
||||
for (const auto& [name, mini] : room_positions_) {
|
||||
float rx = static_cast<float>(cellPixelX(mini.pos.x));
|
||||
float ry = static_cast<float>(cellPixelY(mini.pos.y));
|
||||
auto rx = static_cast<float>(cellPixelX(mini.pos.x));
|
||||
auto ry = static_cast<float>(cellPixelY(mini.pos.y));
|
||||
if (map_x >= rx && map_x < rx + CELL_W && map_y >= ry && map_y < ry + CELL_H) {
|
||||
return name;
|
||||
}
|
||||
@@ -314,8 +314,8 @@ void MiniMap::render(const std::string& current_room) {
|
||||
if (it != room_positions_.end()) {
|
||||
float cur_x = vx + static_cast<float>(cellPixelX(it->second.pos.x)) - 1;
|
||||
float cur_y = vy + static_cast<float>(cellPixelY(it->second.pos.y)) - 1;
|
||||
float cur_w = static_cast<float>(CELL_W + 2);
|
||||
float cur_h = static_cast<float>(CELL_H + 2);
|
||||
auto cur_w = static_cast<float>(CELL_W + 2);
|
||||
auto cur_h = static_cast<float>(CELL_H + 2);
|
||||
if (cur_x >= 0 && cur_y >= 0 && cur_x + cur_w <= PlayArea::WIDTH && cur_y + cur_h <= PlayArea::HEIGHT) {
|
||||
SDL_FRect highlight = {.x = cur_x, .y = cur_y, .w = cur_w, .h = cur_h};
|
||||
game_surface->drawRectBorder(&highlight, stringToColor("bright_white"));
|
||||
|
||||
@@ -54,8 +54,8 @@ class MiniMap {
|
||||
auto getRoomMiniSurface(const std::string& room_name) -> std::shared_ptr<Surface>;
|
||||
void drawConnections();
|
||||
auto roomAtScreen(float screen_x, float screen_y) -> std::string;
|
||||
auto cellPixelX(int grid_x) const -> int { return PADDING + (grid_x - min_grid_x_) * (CELL_W + GAP); }
|
||||
auto cellPixelY(int grid_y) const -> int { return PADDING + (grid_y - min_grid_y_) * (CELL_H + GAP); }
|
||||
auto cellPixelX(int grid_x) const -> int { return PADDING + ((grid_x - min_grid_x_) * (CELL_W + GAP)); }
|
||||
auto cellPixelY(int grid_y) const -> int { return PADDING + ((grid_y - min_grid_y_) * (CELL_H + GAP)); }
|
||||
|
||||
// Tabla de color predominante por tile index
|
||||
std::vector<Uint8> tile_colors_; // tile_index → palette color index
|
||||
@@ -84,11 +84,11 @@ class MiniMap {
|
||||
float view_start_y_{0.0F};
|
||||
|
||||
// Constantes
|
||||
static constexpr int ROOM_W = 32; // Ancho de una room en pixels del minimapa
|
||||
static constexpr int ROOM_H = 16; // Alto de una room en pixels del minimapa
|
||||
static constexpr int BORDER = 1; // Borde alrededor de cada room
|
||||
static constexpr int CELL_W = ROOM_W + BORDER * 2; // Room + borde
|
||||
static constexpr int CELL_H = ROOM_H + BORDER * 2;
|
||||
static constexpr int ROOM_W = 32; // Ancho de una room en pixels del minimapa
|
||||
static constexpr int ROOM_H = 16; // Alto de una room en pixels del minimapa
|
||||
static constexpr int BORDER = 1; // Borde alrededor de cada room
|
||||
static constexpr int CELL_W = ROOM_W + (BORDER * 2); // Room + borde
|
||||
static constexpr int CELL_H = ROOM_H + (BORDER * 2);
|
||||
static constexpr int GAP = 4; // Separación entre celdas
|
||||
static constexpr int SHADOW_OFFSET = 1; // Desplazamiento de la sombra
|
||||
static constexpr int PADDING = 4; // Padding alrededor del minimapa
|
||||
|
||||
@@ -36,7 +36,7 @@ auto RoomSaver::conveyorBeltToString(int direction) -> std::string {
|
||||
}
|
||||
|
||||
// Genera el YAML completo como texto con formato compacto
|
||||
auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string {
|
||||
auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
std::ostringstream out;
|
||||
|
||||
// --- Cabecera: nombre como comentario ---
|
||||
@@ -49,9 +49,9 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
|
||||
if (original_yaml.contains("room")) {
|
||||
const auto& room_node = original_yaml["room"];
|
||||
for (auto it = room_node.begin(); it != room_node.end(); ++it) {
|
||||
const std::string key = it.key().get_value<std::string>();
|
||||
if (key.substr(0, 5) == "name_") {
|
||||
out << " " << key << ": \"" << it.value().get_value<std::string>() << "\"\n";
|
||||
const auto KEY = it.key().get_value<std::string>();
|
||||
if (KEY.substr(0, 5) == "name_") {
|
||||
out << " " << KEY << ": \"" << it.value().get_value<std::string>() << "\"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
|
||||
for (int row = 0; row < MAP_HEIGHT; ++row) {
|
||||
out << " - [";
|
||||
for (int col = 0; col < MAP_WIDTH; ++col) {
|
||||
int index = row * MAP_WIDTH + col;
|
||||
int index = (row * MAP_WIDTH) + col;
|
||||
if (index < static_cast<int>(room_data.tile_map.size())) {
|
||||
out << room_data.tile_map[index];
|
||||
} else {
|
||||
|
||||
@@ -38,12 +38,12 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
|
||||
|
||||
// Dimensiones de salida (con spacing visual entre tiles)
|
||||
int out_cell = Tile::SIZE + spacing_out_;
|
||||
int display_w = tileset_width_ * out_cell - spacing_out_; // Sin trailing
|
||||
int display_h = tileset_height_ * out_cell - spacing_out_;
|
||||
int display_w = (tileset_width_ * out_cell) - spacing_out_; // Sin trailing
|
||||
int display_h = (tileset_height_ * out_cell) - spacing_out_;
|
||||
|
||||
// Frame: display + borde
|
||||
int frame_w = display_w + BORDER_PAD * 2;
|
||||
int frame_h = display_h + BORDER_PAD * 2;
|
||||
int frame_w = display_w + (BORDER_PAD * 2);
|
||||
int frame_h = display_h + (BORDER_PAD * 2);
|
||||
frame_surface_ = std::make_shared<Surface>(frame_w, frame_h);
|
||||
|
||||
// Componer: fondo + borde + tiles uno a uno
|
||||
@@ -61,7 +61,7 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
|
||||
frame_surface_->drawRectBorder(&inner, stringToColor("white"));
|
||||
|
||||
// Renderizar cada tile individualmente
|
||||
constexpr float TS = static_cast<float>(Tile::SIZE);
|
||||
constexpr auto TS = static_cast<float>(Tile::SIZE);
|
||||
for (int row = 0; row < tileset_height_; ++row) {
|
||||
for (int col = 0; col < tileset_width_; ++col) {
|
||||
// Fuente: posición en el tileset original
|
||||
@@ -72,8 +72,8 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
|
||||
.h = TS};
|
||||
|
||||
// Destino: posición en el frame con spacing de salida
|
||||
int dst_x = BORDER_PAD + col * out_cell;
|
||||
int dst_y = BORDER_PAD + row * out_cell;
|
||||
int dst_x = BORDER_PAD + (col * out_cell);
|
||||
int dst_y = BORDER_PAD + (row * out_cell);
|
||||
|
||||
if (source_color >= 0 && target_color >= 0) {
|
||||
tileset_->renderWithColorReplace(dst_x, dst_y, static_cast<Uint8>(source_color), static_cast<Uint8>(target_color), &src);
|
||||
@@ -90,7 +90,7 @@ void TilePicker::open(const std::string& tileset_name, int current_tile, int bg_
|
||||
// Centrar en el play area
|
||||
offset_x_ = (PlayArea::WIDTH - frame_w) / 2;
|
||||
int offset_y = (PlayArea::HEIGHT - frame_h) / 2;
|
||||
if (offset_y < 0) { offset_y = 0; }
|
||||
offset_y = std::max(offset_y, 0);
|
||||
|
||||
visible_height_ = PlayArea::HEIGHT;
|
||||
|
||||
@@ -143,7 +143,7 @@ void TilePicker::render() {
|
||||
int out_cell = Tile::SIZE + spacing_out_;
|
||||
float tileset_screen_x = frame_dst_.x + BORDER_PAD;
|
||||
float tileset_screen_y = frame_dst_.y + BORDER_PAD - static_cast<float>(scroll_y_);
|
||||
constexpr float TS = static_cast<float>(Tile::SIZE);
|
||||
constexpr auto TS = static_cast<float>(Tile::SIZE);
|
||||
|
||||
// Highlight del tile bajo el cursor (blanco)
|
||||
if (hover_tile_ >= 0) {
|
||||
@@ -190,7 +190,7 @@ void TilePicker::handleEvent(const SDL_Event& event) {
|
||||
if (event.type == SDL_EVENT_MOUSE_WHEEL) {
|
||||
scroll_y_ -= static_cast<int>(event.wheel.y) * Tile::SIZE * 2;
|
||||
int max_scroll = static_cast<int>(frame_dst_.h) - visible_height_;
|
||||
if (max_scroll < 0) { max_scroll = 0; }
|
||||
max_scroll = std::max(max_scroll, 0);
|
||||
scroll_y_ = std::clamp(scroll_y_, 0, max_scroll);
|
||||
updateMousePosition();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ Enemy::Enemy(const Data& enemy)
|
||||
|
||||
const int FLIP = (should_flip_ && enemy.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR));
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) SDL flags are designed for bitwise OR
|
||||
|
||||
collider_ = getRect();
|
||||
|
||||
@@ -63,7 +63,7 @@ void Enemy::resetToInitialPosition(const Data& data) {
|
||||
|
||||
const int FLIP = (should_flip_ && data.vx < 0.0F) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
|
||||
const int MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR));
|
||||
sprite_->setFlip(static_cast<SDL_FlipMode>(FLIP | MIRROR)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||
|
||||
collider_ = getRect();
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ void Room::setItemColors(const std::string& color1, const std::string& color2) {
|
||||
Uint8 c1 = stringToColor(color1);
|
||||
Uint8 c2 = stringToColor(color2);
|
||||
auto* item_mgr = item_manager_.get();
|
||||
for (int i = 0; i < static_cast<int>(item_mgr->getCount()); ++i) {
|
||||
for (int i = 0; i < item_mgr->getCount(); ++i) {
|
||||
item_mgr->getItem(i)->setColors(c1, c2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ Scoreboard::Scoreboard(std::shared_ptr<Data> data)
|
||||
constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE;
|
||||
|
||||
// Reserva memoria para los objetos
|
||||
const std::string player_anim_path = Player::skinToAnimationPath(Options::game.player_skin);
|
||||
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(player_anim_path);
|
||||
const std::string PLAYER_ANIM_PATH = Player::skinToAnimationPath(Options::game.player_skin);
|
||||
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(PLAYER_ANIM_PATH);
|
||||
player_sprite_ = std::make_shared<AnimatedSprite>(player_animation_data);
|
||||
player_sprite_->setCurrentAnimation("default");
|
||||
|
||||
@@ -78,8 +78,8 @@ auto Scoreboard::getTime() -> Scoreboard::ClockData { // NOLINT(readability-con
|
||||
|
||||
// Actualiza el sprite del jugador con la skin actual
|
||||
void Scoreboard::refreshPlayerSkin() {
|
||||
const std::string player_anim_path = Player::skinToAnimationPath(Options::game.player_skin);
|
||||
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(player_anim_path);
|
||||
const std::string PLAYER_ANIM_PATH = Player::skinToAnimationPath(Options::game.player_skin);
|
||||
const auto& player_animation_data = Resource::Cache::get()->getAnimationData(PLAYER_ANIM_PATH);
|
||||
player_sprite_ = std::make_shared<AnimatedSprite>(player_animation_data);
|
||||
player_sprite_->setCurrentAnimation("default");
|
||||
}
|
||||
|
||||
@@ -359,8 +359,8 @@ namespace Options {
|
||||
}
|
||||
if (sh_node.contains("current_shader")) {
|
||||
try {
|
||||
const std::string s = sh_node["current_shader"].get_value<std::string>();
|
||||
video.shader.current_shader = (s == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX;
|
||||
const auto S = sh_node["current_shader"].get_value<std::string>();
|
||||
video.shader.current_shader = (S == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX;
|
||||
} catch (...) {
|
||||
video.shader.current_shader = Rendering::ShaderType::POSTFX;
|
||||
}
|
||||
@@ -566,7 +566,7 @@ namespace Options {
|
||||
}
|
||||
|
||||
// Carga configuración de audio desde YAML
|
||||
void loadAudioConfigFromYaml(const fkyaml::node& yaml) {
|
||||
void loadAudioConfigFromYaml(const fkyaml::node& yaml) { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!yaml.contains("audio")) { return; }
|
||||
const auto& a = yaml["audio"];
|
||||
|
||||
@@ -688,9 +688,9 @@ namespace Options {
|
||||
|
||||
// Helper: retorna el nombre del preset PostFX actual (para guardar en config)
|
||||
auto currentPostFXPresetName() -> std::string {
|
||||
const auto idx = static_cast<size_t>(video.shader.current_postfx_preset);
|
||||
if (idx < postfx_presets.size()) {
|
||||
return postfx_presets[idx].name;
|
||||
const auto IDX = static_cast<size_t>(video.shader.current_postfx_preset);
|
||||
if (IDX < postfx_presets.size()) {
|
||||
return postfx_presets[IDX].name;
|
||||
}
|
||||
// Presets no cargados aún: devolver el nombre almacenado del config
|
||||
return video.shader.current_postfx_preset_name;
|
||||
@@ -698,9 +698,9 @@ namespace Options {
|
||||
|
||||
// Helper: retorna el nombre del preset CrtPi actual (para guardar en config)
|
||||
auto currentCrtPiPresetName() -> std::string {
|
||||
const auto idx = static_cast<size_t>(video.shader.current_crtpi_preset);
|
||||
if (idx < crtpi_presets.size()) {
|
||||
return crtpi_presets[idx].name;
|
||||
const auto IDX = static_cast<size_t>(video.shader.current_crtpi_preset);
|
||||
if (IDX < crtpi_presets.size()) {
|
||||
return crtpi_presets[IDX].name;
|
||||
}
|
||||
return video.shader.current_crtpi_preset_name;
|
||||
}
|
||||
@@ -1021,17 +1021,17 @@ namespace Options {
|
||||
}
|
||||
|
||||
// Carga los presets del shader CrtPi desde el fichero. Crea defaults si no existe.
|
||||
auto loadCrtPiFromFile() -> bool {
|
||||
auto loadCrtPiFromFile() -> bool { // NOLINT(readability-function-cognitive-complexity)
|
||||
crtpi_presets.clear();
|
||||
|
||||
std::ifstream file(crtpi_file_path);
|
||||
if (!file.good()) {
|
||||
std::cout << "CrtPi file not found, creating default: " << crtpi_file_path << '\n';
|
||||
// Crear directorio padre si no existe
|
||||
const std::filesystem::path p(crtpi_file_path);
|
||||
if (p.has_parent_path()) {
|
||||
const std::filesystem::path P(crtpi_file_path);
|
||||
if (P.has_parent_path()) {
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(p.parent_path(), ec);
|
||||
std::filesystem::create_directories(P.parent_path(), ec);
|
||||
}
|
||||
// Escribir defaults
|
||||
std::ofstream out(crtpi_file_path);
|
||||
|
||||
@@ -164,7 +164,7 @@ void Console::redrawText() {
|
||||
}
|
||||
|
||||
// Actualiza la animación de la consola
|
||||
void Console::update(float delta_time) {
|
||||
void Console::update(float delta_time) { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (status_ == Status::HIDDEN) {
|
||||
return;
|
||||
}
|
||||
@@ -196,9 +196,9 @@ void Console::update(float delta_time) {
|
||||
if (status_ == Status::ACTIVE && height_ != target_height_) {
|
||||
const float PREV_HEIGHT = height_;
|
||||
if (height_ < target_height_) {
|
||||
height_ = std::min(height_ + SLIDE_SPEED * delta_time, target_height_);
|
||||
height_ = std::min(height_ + (SLIDE_SPEED * delta_time), target_height_);
|
||||
} else {
|
||||
height_ = std::max(height_ - SLIDE_SPEED * delta_time, target_height_);
|
||||
height_ = std::max(height_ - (SLIDE_SPEED * delta_time), target_height_);
|
||||
}
|
||||
// Actualizar el Notifier incrementalmente con el delta de altura
|
||||
if (Notifier::get() != nullptr) {
|
||||
@@ -300,7 +300,7 @@ void Console::toggle() {
|
||||
}
|
||||
|
||||
// Procesa el evento SDL: entrada de texto, Backspace, Enter
|
||||
void Console::handleEvent(const SDL_Event& event) {
|
||||
void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (status_ != Status::ACTIVE) { return; }
|
||||
|
||||
if (event.type == SDL_EVENT_TEXT_INPUT) {
|
||||
@@ -348,8 +348,8 @@ void Console::handleEvent(const SDL_Event& event) {
|
||||
std::string upper;
|
||||
for (unsigned char c : input_line_) { upper += static_cast<char>(std::toupper(c)); }
|
||||
|
||||
const size_t space_pos = upper.rfind(' ');
|
||||
if (space_pos == std::string::npos) {
|
||||
const size_t SPACE_POS = upper.rfind(' ');
|
||||
if (SPACE_POS == std::string::npos) {
|
||||
// Modo comando: ciclar keywords visibles que empiecen por el prefijo
|
||||
for (const auto& kw : registry_.getVisibleKeywords()) {
|
||||
if (upper.empty() || kw.starts_with(upper)) {
|
||||
@@ -357,12 +357,12 @@ void Console::handleEvent(const SDL_Event& event) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const std::string base_cmd = upper.substr(0, space_pos);
|
||||
const std::string sub_prefix = upper.substr(space_pos + 1);
|
||||
const auto opts = registry_.getCompletions(base_cmd);
|
||||
for (const auto& arg : opts) {
|
||||
if (sub_prefix.empty() || std::string_view{arg}.starts_with(sub_prefix)) {
|
||||
tab_matches_.emplace_back(base_cmd + " " + arg);
|
||||
const std::string BASE_CMD = upper.substr(0, SPACE_POS);
|
||||
const std::string SUB_PREFIX = upper.substr(SPACE_POS + 1);
|
||||
const auto OPTS = registry_.getCompletions(BASE_CMD);
|
||||
for (const auto& arg : OPTS) {
|
||||
if (SUB_PREFIX.empty() || std::string_view{arg}.starts_with(SUB_PREFIX)) {
|
||||
tab_matches_.emplace_back(BASE_CMD + " " + arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static auto boolToggle(
|
||||
// ── Command handlers ─────────────────────────────────────────────────────────
|
||||
|
||||
// SS [ON|OFF|SIZE|UPSCALE [NEAREST|LINEAR]|DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3]]
|
||||
static auto cmd_ss(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdSs(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
|
||||
static const std::array<std::string_view, 3> DOWNSCALE_NAMES = {"Bilinear", "Lanczos2", "Lanczos3"};
|
||||
if (!args.empty() && args[0] == "SIZE") {
|
||||
@@ -118,34 +118,34 @@ static auto applyPreset(const std::vector<std::string>& args) -> std::string {
|
||||
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
|
||||
const auto& presets_postfx = Options::postfx_presets;
|
||||
const auto& presets_crtpi = Options::crtpi_presets;
|
||||
const std::string shader_label = IS_CRTPI ? "CrtPi" : "PostFX";
|
||||
const std::string SHADER_LABEL = IS_CRTPI ? "CrtPi" : "PostFX";
|
||||
|
||||
auto& current_idx = IS_CRTPI ? Options::video.shader.current_crtpi_preset
|
||||
: Options::video.shader.current_postfx_preset;
|
||||
const int count = static_cast<int>(IS_CRTPI ? presets_crtpi.size() : presets_postfx.size());
|
||||
const int COUNT = static_cast<int>(IS_CRTPI ? presets_crtpi.size() : presets_postfx.size());
|
||||
|
||||
if (count == 0) { return "No " + shader_label + " presets available"; }
|
||||
if (COUNT == 0) { return "No " + SHADER_LABEL + " presets available"; }
|
||||
|
||||
const auto presetName = [&]() -> std::string {
|
||||
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(current_idx)].name
|
||||
: presets_postfx[static_cast<size_t>(current_idx)].name;
|
||||
const auto PRESET_NAME = [&]() -> std::string {
|
||||
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(current_idx)].name // NOLINT(clang-analyzer-core.CallAndMessage)
|
||||
: presets_postfx[static_cast<size_t>(current_idx)].name; // NOLINT(clang-analyzer-core.CallAndMessage)
|
||||
return prettyName(name);
|
||||
};
|
||||
|
||||
if (args.empty()) {
|
||||
return shader_label + " preset: " + presetName();
|
||||
return SHADER_LABEL + " preset: " + PRESET_NAME();
|
||||
}
|
||||
|
||||
if (args[0] == "NEXT") {
|
||||
current_idx = (current_idx + 1) % count;
|
||||
current_idx = (current_idx + 1) % COUNT;
|
||||
} else if (args[0] == "PREV") {
|
||||
current_idx = (current_idx - 1 + count) % count;
|
||||
current_idx = (current_idx - 1 + COUNT) % COUNT;
|
||||
} else {
|
||||
// Buscar por nombre (case-insensitive, con guiones)
|
||||
std::string search = args[0];
|
||||
std::ranges::transform(search, search.begin(), ::toupper);
|
||||
bool found = false;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (int i = 0; i < COUNT; ++i) {
|
||||
const auto& name = IS_CRTPI ? presets_crtpi[static_cast<size_t>(i)].name
|
||||
: presets_postfx[static_cast<size_t>(i)].name;
|
||||
if (toUpper(name) == search) {
|
||||
@@ -166,11 +166,11 @@ static auto applyPreset(const std::vector<std::string>& args) -> std::string {
|
||||
} else {
|
||||
Screen::get()->reloadPostFX();
|
||||
}
|
||||
return shader_label + " preset: " + presetName();
|
||||
return SHADER_LABEL + " preset: " + PRESET_NAME();
|
||||
}
|
||||
|
||||
// SHADER [ON|OFF|NEXT|POSTFX|CRTPI|PRESET [NEXT|PREV|<name>]]
|
||||
static auto cmd_shader(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdShader(const std::vector<std::string>& args) -> std::string {
|
||||
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
|
||||
if (args.empty()) {
|
||||
Screen::get()->toggleShaders();
|
||||
@@ -200,19 +200,19 @@ static auto cmd_shader(const std::vector<std::string>& args) -> std::string {
|
||||
(Options::video.shader.current_shader == Rendering::ShaderType::CRTPI ? "CrtPi" : "PostFX");
|
||||
}
|
||||
if (args[0] == "PRESET") {
|
||||
const std::vector<std::string> rest(args.begin() + 1, args.end());
|
||||
return applyPreset(rest);
|
||||
const std::vector<std::string> REST(args.begin() + 1, args.end());
|
||||
return applyPreset(REST);
|
||||
}
|
||||
return "usage: shader [on|off|next|postfx|crtpi|preset [next|prev|<name>]]";
|
||||
}
|
||||
|
||||
// BORDER [ON|OFF]
|
||||
static auto cmd_border(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdBorder(const std::vector<std::string>& args) -> std::string {
|
||||
return boolToggle("Border", Options::video.border.enabled, [] { Screen::get()->toggleBorder(); }, args);
|
||||
}
|
||||
|
||||
// FULLSCREEN [ON|OFF [PLEASE]]
|
||||
static auto cmd_fullscreen(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdFullscreen(const std::vector<std::string>& args) -> std::string {
|
||||
const bool EXPLICIT_ON = !args.empty() && args[0] == "ON";
|
||||
const bool EXPLICIT_OFF = !args.empty() && args[0] == "OFF";
|
||||
const bool WITH_PLEASE = !args.empty() && args.back() == "PLEASE";
|
||||
@@ -240,8 +240,8 @@ static auto cmd_fullscreen(const std::vector<std::string>& args) -> std::string
|
||||
}
|
||||
|
||||
// ZOOM UP/DOWN/<num>
|
||||
static auto cmd_zoom(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty()) { return "usage: zoom [up|down|<1-" + std::to_string(Screen::get()->getMaxZoom()) + ">]"; }
|
||||
static auto cmdZoom(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty()) { return "usage: zoom [up|down|<1-" + std::to_string(Screen::getMaxZoom()) + ">]"; }
|
||||
if (args[0] == "UP") {
|
||||
if (!Screen::get()->incWindowZoom()) { return "Max zoom reached"; }
|
||||
return "Zoom " + std::to_string(Options::window.zoom);
|
||||
@@ -252,7 +252,7 @@ static auto cmd_zoom(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
try {
|
||||
const int N = std::stoi(args[0]);
|
||||
const int MAX = Screen::get()->getMaxZoom();
|
||||
const int MAX = Screen::getMaxZoom();
|
||||
if (N < 1 || N > MAX) {
|
||||
return "Zoom must be between 1 and " + std::to_string(MAX);
|
||||
}
|
||||
@@ -260,11 +260,11 @@ static auto cmd_zoom(const std::vector<std::string>& args) -> std::string {
|
||||
Screen::get()->setWindowZoom(N);
|
||||
return "Zoom " + std::to_string(Options::window.zoom);
|
||||
} catch (...) {}
|
||||
return "usage: zoom [up|down|<1-" + std::to_string(Screen::get()->getMaxZoom()) + ">]";
|
||||
return "usage: zoom [up|down|<1-" + std::to_string(Screen::getMaxZoom()) + ">]";
|
||||
}
|
||||
|
||||
// INTSCALE [ON|OFF]
|
||||
static auto cmd_intscale(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdIntscale(const std::vector<std::string>& args) -> std::string {
|
||||
const bool ON = args.empty() ? !Options::video.integer_scale
|
||||
: (args[0] == "ON");
|
||||
if (!args.empty() && args[0] != "ON" && args[0] != "OFF") {
|
||||
@@ -279,12 +279,12 @@ static auto cmd_intscale(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// VSYNC [ON|OFF]
|
||||
static auto cmd_vsync(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdVsync(const std::vector<std::string>& args) -> std::string {
|
||||
return boolToggle("VSync", Options::video.vertical_sync, [] { Screen::get()->toggleVSync(); }, args);
|
||||
}
|
||||
|
||||
// DRIVER [LIST|AUTO|NONE|<name>]
|
||||
static auto cmd_driver(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdDriver(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty()) {
|
||||
const auto& driver = Screen::get()->getGPUDriver();
|
||||
return "GPU: " + (driver.empty() ? std::string("sdl") : driver);
|
||||
@@ -336,22 +336,22 @@ static auto cmd_driver(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// PALETTE NEXT/PREV/SORT/DEFAULT/<name>
|
||||
static auto cmd_palette(const std::vector<std::string>& args) -> std::string {
|
||||
const auto palName = []() -> std::string {
|
||||
static auto cmdPalette(const std::vector<std::string>& args) -> std::string {
|
||||
const auto PAL_NAME = []() -> std::string {
|
||||
return Screen::get()->getPalettePrettyName();
|
||||
};
|
||||
if (args.empty()) { return "usage: palette [next|prev|sort [original|luminance|spectrum]|default|<name>]"; }
|
||||
if (args[0] == "NEXT") {
|
||||
Screen::get()->nextPalette();
|
||||
return "Palette: " + palName();
|
||||
return "Palette: " + PAL_NAME();
|
||||
}
|
||||
if (args[0] == "PREV") {
|
||||
Screen::get()->previousPalette();
|
||||
return "Palette: " + palName();
|
||||
return "Palette: " + PAL_NAME();
|
||||
}
|
||||
if (args[0] == "DEFAULT") {
|
||||
Screen::get()->setPaletteByName(Defaults::Video::PALETTE_NAME);
|
||||
return "Palette: " + palName();
|
||||
return "Palette: " + PAL_NAME();
|
||||
}
|
||||
if (args[0] == "SORT") {
|
||||
if (args.size() == 1) {
|
||||
@@ -374,11 +374,11 @@ static auto cmd_palette(const std::vector<std::string>& args) -> std::string {
|
||||
std::ranges::transform(arg_lower, arg_lower.begin(), ::tolower);
|
||||
return "Unknown palette: " + arg_lower;
|
||||
}
|
||||
return "Palette: " + palName();
|
||||
return "Palette: " + PAL_NAME();
|
||||
}
|
||||
|
||||
// AUDIO [ON|OFF|VOL <0-100>]
|
||||
static auto cmd_audio(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdAudio(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty()) {
|
||||
const int VOL = static_cast<int>(Options::audio.volume * 100.0F);
|
||||
return std::string("Audio ") + (Options::audio.enabled ? "ON" : "OFF") +
|
||||
@@ -409,7 +409,7 @@ static auto cmd_audio(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// MUSIC [ON|OFF|VOL <0-100>]
|
||||
static auto cmd_music(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdMusic(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty()) {
|
||||
const int VOL = static_cast<int>(Options::audio.music.volume * 100.0F);
|
||||
return std::string("Music ") + (Options::audio.music.enabled ? "ON" : "OFF") +
|
||||
@@ -444,7 +444,7 @@ static auto cmd_music(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// SOUND [ON|OFF|VOL <0-100>]
|
||||
static auto cmd_sound(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdSound(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty()) {
|
||||
const int VOL = static_cast<int>(Options::audio.sound.volume * 100.0F);
|
||||
return std::string("Sound ") + (Options::audio.sound.enabled ? "ON" : "OFF") +
|
||||
@@ -480,7 +480,7 @@ static auto cmd_sound(const std::vector<std::string>& args) -> std::string {
|
||||
|
||||
#ifdef _DEBUG
|
||||
// DEBUG [MODE [ON|OFF]|START [HERE|ROOM|POS|SCENE <name>]]
|
||||
static auto cmd_debug(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdDebug(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
// --- START subcommands (START SCENE works from any scene) ---
|
||||
if (!args.empty() && args[0] == "START") {
|
||||
// START SCENE [<name>] — works from any scene
|
||||
@@ -566,7 +566,7 @@ static auto cmd_debug(const std::vector<std::string>& args) -> std::string {
|
||||
static auto changeRoomWithEditor(const std::string& room_file) -> std::string {
|
||||
if (!GameControl::change_room) { return "Game not initialized"; }
|
||||
|
||||
const bool EDITOR_WAS_ACTIVE = MapEditor::get() && MapEditor::get()->isActive();
|
||||
const bool EDITOR_WAS_ACTIVE = (MapEditor::get() != nullptr) && MapEditor::get()->isActive();
|
||||
|
||||
// Si el editor está activo, salir primero (guarda y recarga la room actual)
|
||||
if (EDITOR_WAS_ACTIVE && GameControl::exit_editor) {
|
||||
@@ -591,19 +591,19 @@ static auto changeRoomWithEditor(const std::string& room_file) -> std::string {
|
||||
return std::string("Room: ") + room_file;
|
||||
}
|
||||
|
||||
static auto cmd_room(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdRoom(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
|
||||
if (args.empty()) { return "usage: room <1-60>|next|prev|left|right|up|down"; }
|
||||
|
||||
// DELETE: borrar la habitación actual
|
||||
if (args[0] == "DELETE") {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
return MapEditor::get()->deleteRoom();
|
||||
}
|
||||
|
||||
// NEW [LEFT|RIGHT|UP|DOWN]: crear habitación nueva (opcionalmente conectada)
|
||||
if (args[0] == "NEW") {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
std::string direction = (args.size() >= 2) ? args[1] : "";
|
||||
return MapEditor::get()->createNewRoom(direction);
|
||||
}
|
||||
@@ -621,9 +621,9 @@ static auto cmd_room(const std::vector<std::string>& args) -> std::string {
|
||||
int num = 0;
|
||||
if (args[0] == "NEXT" || args[0] == "PREV") {
|
||||
if (!GameControl::get_current_room) { return "Game not initialized"; }
|
||||
const std::string current = GameControl::get_current_room();
|
||||
const std::string CURRENT = GameControl::get_current_room();
|
||||
try {
|
||||
num = std::stoi(current.substr(0, current.find('.')));
|
||||
num = std::stoi(CURRENT.substr(0, CURRENT.find('.')));
|
||||
} catch (...) { return "Cannot determine current room"; }
|
||||
num += (args[0] == "NEXT") ? 1 : -1;
|
||||
} else {
|
||||
@@ -638,7 +638,7 @@ static auto cmd_room(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// ITEMS <0-200>
|
||||
static auto cmd_items(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdItems(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: items <0-200>"; }
|
||||
int count = 0;
|
||||
@@ -652,7 +652,7 @@ static auto cmd_items(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// SCENE [LOGO|LOADING|TITLE|CREDITS|GAME|ENDING|ENDING2|RESTART]
|
||||
static auto cmd_scene(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdScene(const std::vector<std::string>& args) -> std::string {
|
||||
if (Options::kiosk.enabled) { return "Not allowed in kiosk mode"; }
|
||||
if (args.empty()) { return "usage: scene [logo|loading|title|credits|game|ending|ending2|restart]"; }
|
||||
|
||||
@@ -683,10 +683,10 @@ static auto cmd_scene(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// EDIT [ON|OFF|REVERT]
|
||||
static auto cmd_edit(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdEdit(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
if (args.empty()) {
|
||||
// Toggle: si está activo → off, si no → on
|
||||
if (MapEditor::get() && MapEditor::get()->isActive()) {
|
||||
if ((MapEditor::get() != nullptr) && MapEditor::get()->isActive()) {
|
||||
if (GameControl::exit_editor) { GameControl::exit_editor(); }
|
||||
return "Editor OFF";
|
||||
}
|
||||
@@ -718,26 +718,26 @@ static auto cmd_edit(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
// EDIT SHOW/HIDE INFO/GRID
|
||||
if ((args[0] == "SHOW" || args[0] == "HIDE") && args.size() >= 2) {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
bool show = (args[0] == "SHOW");
|
||||
if (args[1] == "INFO") { return MapEditor::get()->showInfo(show); }
|
||||
if (args[1] == "GRID") { return MapEditor::get()->showGrid(show); }
|
||||
}
|
||||
// EDIT MAPBG/MAPCONN <color>
|
||||
if (args[0] == "MAPBG" && args.size() >= 2) {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
return MapEditor::get()->setMiniMapBg(args[1]);
|
||||
}
|
||||
if (args[0] == "MAPCONN" && args.size() >= 2) {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
return MapEditor::get()->setMiniMapConn(args[1]);
|
||||
}
|
||||
return "usage: edit [on|off|revert|show|hide|mapbg|mapconn] [...]";
|
||||
}
|
||||
|
||||
// SET <property> <value> — modifica propiedad del enemigo seleccionado o de la habitación
|
||||
static auto cmd_set(const std::vector<std::string>& args) -> std::string {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
static auto cmdSet(const std::vector<std::string>& args) -> std::string {
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if (args.empty()) { return "usage: set <property> <value>"; }
|
||||
|
||||
// SET TILE no necesita argumento (abre el tile picker visual)
|
||||
@@ -762,8 +762,8 @@ static auto cmd_set(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// ENEMY [ADD|DELETE|DUPLICATE]
|
||||
static auto cmd_enemy(const std::vector<std::string>& args) -> std::string {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
static auto cmdEnemy(const std::vector<std::string>& args) -> std::string {
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if (args.empty()) { return "usage: enemy <add|delete|duplicate>"; }
|
||||
if (args[0] == "ADD") { return MapEditor::get()->addEnemy(); }
|
||||
if (args[0] == "DELETE") {
|
||||
@@ -778,8 +778,8 @@ static auto cmd_enemy(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// ITEM [ADD|DELETE|DUPLICATE]
|
||||
static auto cmd_item(const std::vector<std::string>& args) -> std::string {
|
||||
if (!MapEditor::get() || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
static auto cmdItem(const std::vector<std::string>& args) -> std::string {
|
||||
if ((MapEditor::get() == nullptr) || !MapEditor::get()->isActive()) { return "Editor not active"; }
|
||||
if (args.empty()) { return "usage: item <add|delete|duplicate>"; }
|
||||
if (args[0] == "ADD") { return MapEditor::get()->addItem(); }
|
||||
if (args[0] == "DELETE") {
|
||||
@@ -795,7 +795,7 @@ static auto cmd_item(const std::vector<std::string>& args) -> std::string {
|
||||
#endif
|
||||
|
||||
// SHOW [INFO|NOTIFICATION|CHEEVO]
|
||||
static auto cmd_show(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdShow(const std::vector<std::string>& args) -> std::string {
|
||||
#ifdef _DEBUG
|
||||
if (!args.empty() && args[0] == "NOTIFICATION") {
|
||||
Notifier::get()->show({"NOTIFICATION"});
|
||||
@@ -815,7 +815,7 @@ static auto cmd_show(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// HIDE [INFO]
|
||||
static auto cmd_hide(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdHide(const std::vector<std::string>& args) -> std::string {
|
||||
if (args.empty() || args[0] != "INFO") { return "usage: hide [info]"; }
|
||||
if (!RenderInfo::get()->isActive()) { return "Info overlay already OFF"; }
|
||||
RenderInfo::get()->toggle();
|
||||
@@ -823,7 +823,7 @@ static auto cmd_hide(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// CHEAT [subcomando]
|
||||
static auto cmd_cheat(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdCheat(const std::vector<std::string>& args) -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
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]"; }
|
||||
|
||||
@@ -885,7 +885,7 @@ static auto cmd_cheat(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// PLAYER SKIN / PLAYER COLOR
|
||||
static auto cmd_player(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdPlayer(const std::vector<std::string>& args) -> std::string {
|
||||
if (SceneManager::current != SceneManager::Scene::GAME) { return "Only available in GAME scene"; }
|
||||
|
||||
// PLAYER SKIN <name>
|
||||
@@ -920,14 +920,14 @@ static auto cmd_player(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// RESTART
|
||||
static auto cmd_restart(const std::vector<std::string>&) -> std::string {
|
||||
static auto cmdRestart(const std::vector<std::string>& /*unused*/) -> std::string {
|
||||
SceneManager::current = SceneManager::Scene::LOGO;
|
||||
Audio::get()->stopMusic();
|
||||
return "Restarting...";
|
||||
}
|
||||
|
||||
// KIOSK [ON|OFF PLEASE|PLEASE]
|
||||
static auto cmd_kiosk(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdKiosk(const std::vector<std::string>& args) -> std::string {
|
||||
const bool DISABLE = (!args.empty() && args[0] == "PLEASE") ||
|
||||
(args.size() >= 2 && args[0] == "OFF" && args[1] == "PLEASE");
|
||||
if (DISABLE) {
|
||||
@@ -947,7 +947,7 @@ static auto cmd_kiosk(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// EXIT / QUIT
|
||||
static auto cmd_exit(const std::vector<std::string>& args) -> std::string {
|
||||
static auto cmdExit(const std::vector<std::string>& args) -> std::string {
|
||||
if (Options::kiosk.enabled && (args.empty() || args[0] != "PLEASE")) {
|
||||
return "Not allowed in kiosk mode";
|
||||
}
|
||||
@@ -956,7 +956,7 @@ static auto cmd_exit(const std::vector<std::string>& args) -> std::string {
|
||||
}
|
||||
|
||||
// SIZE
|
||||
static auto cmd_size(const std::vector<std::string>&) -> std::string {
|
||||
static auto cmdSize(const std::vector<std::string>& /*unused*/) -> std::string {
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
SDL_GetWindowSize(SDL_GetRenderWindow(Screen::get()->getRenderer()), &w, &h);
|
||||
@@ -965,37 +965,37 @@ static auto cmd_size(const std::vector<std::string>&) -> std::string {
|
||||
|
||||
// ── CommandRegistry ──────────────────────────────────────────────────────────
|
||||
|
||||
void CommandRegistry::registerHandlers() {
|
||||
handlers_["cmd_ss"] = cmd_ss;
|
||||
handlers_["cmd_shader"] = cmd_shader;
|
||||
handlers_["cmd_border"] = cmd_border;
|
||||
handlers_["cmd_fullscreen"] = cmd_fullscreen;
|
||||
handlers_["cmd_zoom"] = cmd_zoom;
|
||||
handlers_["cmd_intscale"] = cmd_intscale;
|
||||
handlers_["cmd_vsync"] = cmd_vsync;
|
||||
handlers_["cmd_driver"] = cmd_driver;
|
||||
handlers_["cmd_palette"] = cmd_palette;
|
||||
handlers_["cmd_audio"] = cmd_audio;
|
||||
handlers_["cmd_music"] = cmd_music;
|
||||
handlers_["cmd_sound"] = cmd_sound;
|
||||
handlers_["cmd_show"] = cmd_show;
|
||||
handlers_["cmd_hide"] = cmd_hide;
|
||||
handlers_["cmd_cheat"] = cmd_cheat;
|
||||
handlers_["cmd_player"] = cmd_player;
|
||||
handlers_["cmd_restart"] = cmd_restart;
|
||||
handlers_["cmd_kiosk"] = cmd_kiosk;
|
||||
handlers_["cmd_exit"] = cmd_exit;
|
||||
handlers_["cmd_quit"] = cmd_exit; // QUIT usa el mismo handler que EXIT
|
||||
handlers_["cmd_size"] = cmd_size;
|
||||
void CommandRegistry::registerHandlers() { // NOLINT(readability-function-cognitive-complexity)
|
||||
handlers_["cmd_ss"] = cmdSs;
|
||||
handlers_["cmd_shader"] = cmdShader;
|
||||
handlers_["cmd_border"] = cmdBorder;
|
||||
handlers_["cmd_fullscreen"] = cmdFullscreen;
|
||||
handlers_["cmd_zoom"] = cmdZoom;
|
||||
handlers_["cmd_intscale"] = cmdIntscale;
|
||||
handlers_["cmd_vsync"] = cmdVsync;
|
||||
handlers_["cmd_driver"] = cmdDriver;
|
||||
handlers_["cmd_palette"] = cmdPalette;
|
||||
handlers_["cmd_audio"] = cmdAudio;
|
||||
handlers_["cmd_music"] = cmdMusic;
|
||||
handlers_["cmd_sound"] = cmdSound;
|
||||
handlers_["cmd_show"] = cmdShow;
|
||||
handlers_["cmd_hide"] = cmdHide;
|
||||
handlers_["cmd_cheat"] = cmdCheat;
|
||||
handlers_["cmd_player"] = cmdPlayer;
|
||||
handlers_["cmd_restart"] = cmdRestart;
|
||||
handlers_["cmd_kiosk"] = cmdKiosk;
|
||||
handlers_["cmd_exit"] = cmdExit;
|
||||
handlers_["cmd_quit"] = cmdExit; // QUIT usa el mismo handler que EXIT
|
||||
handlers_["cmd_size"] = cmdSize;
|
||||
#ifdef _DEBUG
|
||||
handlers_["cmd_debug"] = cmd_debug;
|
||||
handlers_["cmd_items"] = cmd_items;
|
||||
handlers_["cmd_room"] = cmd_room;
|
||||
handlers_["cmd_scene"] = cmd_scene;
|
||||
handlers_["cmd_edit"] = cmd_edit;
|
||||
handlers_["cmd_set"] = cmd_set;
|
||||
handlers_["cmd_enemy"] = cmd_enemy;
|
||||
handlers_["cmd_item"] = cmd_item;
|
||||
handlers_["cmd_debug"] = cmdDebug;
|
||||
handlers_["cmd_items"] = cmdItems;
|
||||
handlers_["cmd_room"] = cmdRoom;
|
||||
handlers_["cmd_scene"] = cmdScene;
|
||||
handlers_["cmd_edit"] = cmdEdit;
|
||||
handlers_["cmd_set"] = cmdSet;
|
||||
handlers_["cmd_enemy"] = cmdEnemy;
|
||||
handlers_["cmd_item"] = cmdItem;
|
||||
#endif
|
||||
// HELP se registra en load() como lambda que captura this
|
||||
|
||||
@@ -1081,7 +1081,7 @@ void CommandRegistry::registerHandlers() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommandRegistry::load(const std::string& yaml_path) {
|
||||
void CommandRegistry::load(const std::string& yaml_path) { // NOLINT(readability-function-cognitive-complexity)
|
||||
registerHandlers();
|
||||
|
||||
// Cargar y parsear el YAML
|
||||
@@ -1103,8 +1103,8 @@ void CommandRegistry::load(const std::string& yaml_path) {
|
||||
if (!yaml.contains("categories")) { return; }
|
||||
|
||||
for (const auto& cat_node : yaml["categories"]) {
|
||||
const std::string category = cat_node["name"].get_value<std::string>();
|
||||
const bool cat_debug_only = cat_node.contains("debug_only") && cat_node["debug_only"].get_value<bool>();
|
||||
const auto CATEGORY = cat_node["name"].get_value<std::string>();
|
||||
const bool CAT_DEBUG_ONLY = cat_node.contains("debug_only") && cat_node["debug_only"].get_value<bool>();
|
||||
|
||||
// Scopes por defecto de la categoría
|
||||
std::vector<std::string> cat_scopes;
|
||||
@@ -1123,12 +1123,12 @@ void CommandRegistry::load(const std::string& yaml_path) {
|
||||
CommandDef def;
|
||||
def.keyword = cmd_node["keyword"].get_value<std::string>();
|
||||
def.handler_id = cmd_node["handler"].get_value<std::string>();
|
||||
def.category = category;
|
||||
def.category = CATEGORY;
|
||||
def.description = cmd_node.contains("description") ? cmd_node["description"].get_value<std::string>() : "";
|
||||
def.usage = cmd_node.contains("usage") ? cmd_node["usage"].get_value<std::string>() : def.keyword;
|
||||
def.instant = cmd_node.contains("instant") && cmd_node["instant"].get_value<bool>();
|
||||
def.hidden = cmd_node.contains("hidden") && cmd_node["hidden"].get_value<bool>();
|
||||
def.debug_only = cat_debug_only || (cmd_node.contains("debug_only") && cmd_node["debug_only"].get_value<bool>());
|
||||
def.debug_only = CAT_DEBUG_ONLY || (cmd_node.contains("debug_only") && cmd_node["debug_only"].get_value<bool>());
|
||||
def.help_hidden = cmd_node.contains("help_hidden") && cmd_node["help_hidden"].get_value<bool>();
|
||||
def.dynamic_completions = cmd_node.contains("dynamic_completions") && cmd_node["dynamic_completions"].get_value<bool>();
|
||||
|
||||
@@ -1143,14 +1143,14 @@ void CommandRegistry::load(const std::string& yaml_path) {
|
||||
} else if (!cat_scopes.empty()) {
|
||||
def.scopes = cat_scopes;
|
||||
} else {
|
||||
def.scopes.push_back("global");
|
||||
def.scopes.emplace_back("global");
|
||||
}
|
||||
|
||||
// Completions estáticas
|
||||
if (cmd_node.contains("completions")) {
|
||||
auto completions_node = cmd_node["completions"];
|
||||
for (auto it = completions_node.begin(); it != completions_node.end(); ++it) {
|
||||
std::string path = it.key().get_value<std::string>();
|
||||
auto path = it.key().get_value<std::string>();
|
||||
std::vector<std::string> opts;
|
||||
for (const auto& opt : *it) {
|
||||
opts.push_back(opt.get_value<std::string>());
|
||||
@@ -1171,7 +1171,7 @@ void CommandRegistry::load(const std::string& yaml_path) {
|
||||
def.completions.clear();
|
||||
auto extras_completions = extras["completions"];
|
||||
for (auto it = extras_completions.begin(); it != extras_completions.end(); ++it) {
|
||||
std::string path = it.key().get_value<std::string>();
|
||||
auto path = it.key().get_value<std::string>();
|
||||
std::vector<std::string> opts;
|
||||
for (const auto& opt : *it) {
|
||||
opts.push_back(opt.get_value<std::string>());
|
||||
@@ -1237,9 +1237,9 @@ auto CommandRegistry::findCommand(const std::string& keyword) const -> const Com
|
||||
auto CommandRegistry::execute(const std::string& keyword, const std::vector<std::string>& args) const -> std::string {
|
||||
const auto* def = findCommand(keyword);
|
||||
if (def == nullptr) { return ""; }
|
||||
const auto it = handlers_.find(def->handler_id);
|
||||
if (it == handlers_.end()) { return "Handler not found: " + def->handler_id; }
|
||||
return it->second(args);
|
||||
const auto IT = handlers_.find(def->handler_id);
|
||||
if (IT == handlers_.end()) { return "Handler not found: " + def->handler_id; }
|
||||
return IT->second(args);
|
||||
}
|
||||
|
||||
auto CommandRegistry::generateTerminalHelp() const -> std::string {
|
||||
@@ -1270,7 +1270,7 @@ auto CommandRegistry::generateTerminalHelp() const -> std::string {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
auto CommandRegistry::generateConsoleHelp() const -> std::string {
|
||||
auto CommandRegistry::generateConsoleHelp() const -> std::string { // NOLINT(readability-function-cognitive-complexity)
|
||||
// Agrupar comandos visibles por scope
|
||||
std::string global_cmds;
|
||||
std::string debug_cmds;
|
||||
@@ -1328,13 +1328,13 @@ auto CommandRegistry::getCompletions(const std::string& path) const -> std::vect
|
||||
}
|
||||
|
||||
// Primero: buscar proveedor dinámico (tiene prioridad si existe)
|
||||
const auto dyn_it = dynamic_providers_.find(path);
|
||||
if (dyn_it != dynamic_providers_.end()) {
|
||||
return dyn_it->second();
|
||||
const auto DYN_IT = dynamic_providers_.find(path);
|
||||
if (DYN_IT != dynamic_providers_.end()) {
|
||||
return DYN_IT->second();
|
||||
}
|
||||
// Fallback: completions estáticas del YAML
|
||||
const auto it = completions_map_.find(path);
|
||||
if (it != completions_map_.end()) { return it->second; }
|
||||
const auto IT = completions_map_.find(path);
|
||||
if (IT != completions_map_.end()) { return IT->second; }
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -1345,12 +1345,11 @@ auto CommandRegistry::getCompletions(const std::string& path) const -> std::vect
|
||||
auto CommandRegistry::isCommandVisible(const CommandDef& cmd) const -> bool {
|
||||
if (cmd.hidden) { return false; }
|
||||
|
||||
for (const auto& s : cmd.scopes) {
|
||||
return std::ranges::any_of(cmd.scopes, [this](const auto& s) {
|
||||
if (s == "global" || s == "game") { return true; }
|
||||
if (s == "debug" && (active_scope_ == "debug" || active_scope_ == "editor")) { return true; }
|
||||
if (s == "editor" && active_scope_ == "editor") { return true; }
|
||||
}
|
||||
return false;
|
||||
return s == "editor" && active_scope_ == "editor";
|
||||
});
|
||||
}
|
||||
|
||||
auto CommandRegistry::getVisibleKeywords() const -> std::vector<std::string> {
|
||||
|
||||
Reference in New Issue
Block a user