editar les propietats de la habitacio
This commit is contained in:
@@ -228,13 +228,14 @@ categories:
|
||||
|
||||
- keyword: SET
|
||||
handler: cmd_set
|
||||
description: "Set enemy property (editor, select enemy first)"
|
||||
usage: "SET <ANIMATION|COLOR|VX|VY|FLIP|MIRROR> <value>"
|
||||
description: "Set property (enemy or room, editor mode)"
|
||||
usage: "SET <property> <value>"
|
||||
dynamic_completions: true
|
||||
completions:
|
||||
SET: [ANIMATION, COLOR, VX, VY, FLIP, MIRROR]
|
||||
SET: [ANIMATION, COLOR, VX, VY, FLIP, MIRROR, BGCOLOR, BORDER, ITEMCOLOR1, ITEMCOLOR2, CONVEYOR, TILESET, UP, DOWN, LEFT, RIGHT]
|
||||
SET FLIP: [ON, OFF]
|
||||
SET MIRROR: [ON, OFF]
|
||||
SET CONVEYOR: [LEFT, NONE, RIGHT]
|
||||
|
||||
- name: CHEATS
|
||||
commands:
|
||||
|
||||
@@ -121,15 +121,21 @@ auto MapEditor::revert() -> std::string {
|
||||
}
|
||||
RoomSaver::saveYAML(file_path_, yaml_, room_data_);
|
||||
|
||||
// Resetear los sprites vivos a las posiciones originales
|
||||
// Resetear enemigos a posiciones originales
|
||||
room_->resetEnemyPositions(room_data_.enemies);
|
||||
|
||||
// Resetear items (recargar posiciones)
|
||||
// Resetear items (posiciones y colores)
|
||||
auto* item_mgr = room_->getItemManager();
|
||||
for (int i = 0; i < item_mgr->getCount() && i < static_cast<int>(room_data_.items.size()); ++i) {
|
||||
item_mgr->getItem(i)->setPosition(room_data_.items[i].x, room_data_.items[i].y);
|
||||
}
|
||||
room_->setItemColors(room_data_.item_color1, room_data_.item_color2);
|
||||
|
||||
// Refrescar visuales de la habitación
|
||||
room_->setBgColor(room_data_.bg_color);
|
||||
Screen::get()->setBorderColor(stringToColor(room_data_.border_color));
|
||||
|
||||
selected_enemy_ = -1;
|
||||
return "Reverted to original";
|
||||
}
|
||||
|
||||
@@ -568,6 +574,18 @@ void MapEditor::updateStatusBarInfo() {
|
||||
if (e.flip) { sel_detail += " flip"; }
|
||||
if (e.mirror) { sel_detail += " mirror"; }
|
||||
}
|
||||
// Info de la habitación (cuando no hay nada seleccionado)
|
||||
else {
|
||||
// Conexiones compactas
|
||||
auto conn = [](const std::string& r) -> std::string {
|
||||
if (r == "0" || r.empty()) { return "-"; }
|
||||
return r.substr(0, r.find('.'));
|
||||
};
|
||||
sel_info = "bg:" + room_data_.bg_color + " brd:" + room_data_.border_color;
|
||||
sel_detail = "u:" + conn(room_data_.upper_room) + " d:" + conn(room_data_.lower_room) +
|
||||
" l:" + conn(room_data_.left_room) + " r:" + conn(room_data_.right_room) +
|
||||
" itm:" + room_data_.item_color1 + "/" + room_data_.item_color2;
|
||||
}
|
||||
|
||||
statusbar_->setSelectionInfo(sel_info);
|
||||
statusbar_->setSelectionDetail(sel_detail);
|
||||
@@ -576,7 +594,7 @@ void MapEditor::updateStatusBarInfo() {
|
||||
if (selected_enemy_ >= 0) {
|
||||
Console::get()->setPrompt("enemy " + std::to_string(selected_enemy_) + "> ");
|
||||
} else {
|
||||
Console::get()->setPrompt("> ");
|
||||
Console::get()->setPrompt("room> ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,4 +783,83 @@ auto MapEditor::duplicateEnemy() -> std::string {
|
||||
return "Duplicated as enemy " + std::to_string(selected_enemy_);
|
||||
}
|
||||
|
||||
// Modifica una propiedad de la habitación
|
||||
auto MapEditor::setRoomProperty(const std::string& property, const std::string& value) -> std::string {
|
||||
if (!active_) { return "Editor not active"; }
|
||||
|
||||
std::string val = toLower(value);
|
||||
|
||||
if (property == "BGCOLOR") {
|
||||
room_data_.bg_color = val;
|
||||
room_->setBgColor(val);
|
||||
autosave();
|
||||
return "bgcolor: " + val;
|
||||
}
|
||||
|
||||
if (property == "BORDER") {
|
||||
room_data_.border_color = val;
|
||||
Screen::get()->setBorderColor(stringToColor(val));
|
||||
autosave();
|
||||
return "border: " + val;
|
||||
}
|
||||
|
||||
if (property == "ITEMCOLOR1") {
|
||||
room_data_.item_color1 = val;
|
||||
room_->setItemColors(room_data_.item_color1, room_data_.item_color2);
|
||||
autosave();
|
||||
return "itemcolor1: " + val;
|
||||
}
|
||||
|
||||
if (property == "ITEMCOLOR2") {
|
||||
room_data_.item_color2 = val;
|
||||
room_->setItemColors(room_data_.item_color1, room_data_.item_color2);
|
||||
autosave();
|
||||
return "itemcolor2: " + val;
|
||||
}
|
||||
|
||||
if (property == "CONVEYOR") {
|
||||
if (val == "left") { room_data_.conveyor_belt_direction = -1; }
|
||||
else if (val == "right") { room_data_.conveyor_belt_direction = 1; }
|
||||
else { room_data_.conveyor_belt_direction = 0; val = "none"; }
|
||||
autosave();
|
||||
return "conveyor: " + val;
|
||||
}
|
||||
|
||||
if (property == "TILESET") {
|
||||
std::string tileset = val;
|
||||
if (tileset.find('.') == std::string::npos) { tileset += ".gif"; }
|
||||
room_data_.tile_set_file = tileset;
|
||||
autosave();
|
||||
return "tileset: " + tileset;
|
||||
}
|
||||
|
||||
// Conexiones: UP, DOWN, LEFT, RIGHT
|
||||
if (property == "UP" || property == "DOWN" || property == "LEFT" || property == "RIGHT") {
|
||||
std::string connection = "0";
|
||||
if (val != "0" && val != "null" && val != "none") {
|
||||
// Convertir número a fichero: "6" → "06.yaml"
|
||||
try {
|
||||
int num = std::stoi(val);
|
||||
char buf[16];
|
||||
std::snprintf(buf, sizeof(buf), "%02d.yaml", num);
|
||||
connection = buf;
|
||||
} catch (...) {
|
||||
// Si no es número, asumir que es un nombre de fichero
|
||||
connection = val;
|
||||
if (connection.find('.') == std::string::npos) { connection += ".yaml"; }
|
||||
}
|
||||
}
|
||||
|
||||
if (property == "UP") { room_data_.upper_room = connection; }
|
||||
else if (property == "DOWN") { room_data_.lower_room = connection; }
|
||||
else if (property == "LEFT") { room_data_.left_room = connection; }
|
||||
else { room_data_.right_room = connection; }
|
||||
|
||||
autosave();
|
||||
return toLower(property) + ": " + connection;
|
||||
}
|
||||
|
||||
return "Unknown property: " + property + " (use: bgcolor, border, itemcolor1, itemcolor2, conveyor, tileset, up, down, left, right)";
|
||||
}
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
@@ -39,6 +39,9 @@ class MapEditor {
|
||||
auto duplicateEnemy() -> std::string;
|
||||
[[nodiscard]] auto hasSelectedEnemy() const -> bool;
|
||||
|
||||
// Comandos para propiedades de la habitación
|
||||
auto setRoomProperty(const std::string& property, const std::string& value) -> std::string;
|
||||
|
||||
private:
|
||||
static MapEditor* instance_; // [SINGLETON] Objeto privado
|
||||
|
||||
|
||||
@@ -133,6 +133,25 @@ void Room::updateEditorMode(float delta_time) {
|
||||
void Room::resetEnemyPositions(const std::vector<Enemy::Data>& enemy_data) {
|
||||
enemy_manager_->resetPositions(enemy_data);
|
||||
}
|
||||
|
||||
// Cambia color de fondo y redibuja el mapa (para editor)
|
||||
void Room::setBgColor(const std::string& color) {
|
||||
bg_color_ = color;
|
||||
tilemap_renderer_->setBgColor(color);
|
||||
tilemap_renderer_->redrawMap(collision_map_.get());
|
||||
}
|
||||
|
||||
// Cambia colores de items en vivo (para editor)
|
||||
void Room::setItemColors(const std::string& color1, const std::string& color2) {
|
||||
item_color1_ = color1;
|
||||
item_color2_ = 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) {
|
||||
item_mgr->getItem(i)->setColors(c1, c2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Actualiza las variables y objetos de la habitación
|
||||
|
||||
@@ -74,6 +74,8 @@ class Room {
|
||||
void resetEnemyPositions(const std::vector<Enemy::Data>& enemy_data); // Resetea enemigos a posiciones iniciales
|
||||
auto getEnemyManager() -> EnemyManager* { return enemy_manager_.get(); } // Acceso al gestor de enemigos (para editor)
|
||||
auto getItemManager() -> ItemManager* { return item_manager_.get(); } // Acceso al gestor de items (para editor)
|
||||
void setBgColor(const std::string& color); // Cambia color de fondo y redibuja (para editor)
|
||||
void setItemColors(const std::string& color1, const std::string& color2); // Cambia colores de items (para editor)
|
||||
#endif
|
||||
void update(float delta_time); // Actualiza las variables y objetos de la habitación
|
||||
auto getRoom(Border border) -> std::string; // Devuelve la cadena del fichero de la habitación contigua segun el borde
|
||||
|
||||
@@ -69,6 +69,7 @@ class TilemapRenderer {
|
||||
* Llamado cuando se activa/desactiva el modo debug para actualizar la visualización
|
||||
*/
|
||||
void redrawMap(const CollisionMap* collision_map);
|
||||
void setBgColor(const std::string& color) { bg_color_ = color; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -705,12 +705,18 @@ static auto cmd_edit(const std::vector<std::string>& args) -> std::string {
|
||||
return "usage: edit [on|off|revert]";
|
||||
}
|
||||
|
||||
// SET <property> <value> — modifica propiedad del enemigo seleccionado en el editor
|
||||
// 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"; }
|
||||
if (!MapEditor::get()->hasSelectedEnemy()) { return "No enemy selected"; }
|
||||
if (args.size() < 2) { return "usage: set <animation|color|vx|vy|flip> <value>"; }
|
||||
return MapEditor::get()->setEnemyProperty(args[0], args[1]);
|
||||
if (args.size() < 2) { return "usage: set <property> <value>"; }
|
||||
|
||||
// Si hay enemigo seleccionado, aplicar a enemigo
|
||||
if (MapEditor::get()->hasSelectedEnemy()) {
|
||||
return MapEditor::get()->setEnemyProperty(args[0], args[1]);
|
||||
}
|
||||
|
||||
// Si no, aplicar a la habitación
|
||||
return MapEditor::get()->setRoomProperty(args[0], args[1]);
|
||||
}
|
||||
|
||||
// ENEMY [ADD|DELETE|DUPLICATE]
|
||||
@@ -959,12 +965,17 @@ void CommandRegistry::registerHandlers() {
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
// SET COLOR: colores de la paleta (UPPERCASE, sin .yaml)
|
||||
dynamic_providers_["SET COLOR"] = []() -> std::vector<std::string> {
|
||||
// Colores de la paleta (compartido por SET COLOR, BGCOLOR, BORDER, ITEMCOLOR1, ITEMCOLOR2)
|
||||
auto color_provider = []() -> std::vector<std::string> {
|
||||
return {"BLACK", "BRIGHT_BLACK", "BLUE", "BRIGHT_BLUE", "RED", "BRIGHT_RED",
|
||||
"MAGENTA", "BRIGHT_MAGENTA", "GREEN", "BRIGHT_GREEN", "CYAN", "BRIGHT_CYAN",
|
||||
"YELLOW", "BRIGHT_YELLOW", "WHITE", "BRIGHT_WHITE"};
|
||||
};
|
||||
dynamic_providers_["SET COLOR"] = color_provider;
|
||||
dynamic_providers_["SET BGCOLOR"] = color_provider;
|
||||
dynamic_providers_["SET BORDER"] = color_provider;
|
||||
dynamic_providers_["SET ITEMCOLOR1"] = color_provider;
|
||||
dynamic_providers_["SET ITEMCOLOR2"] = color_provider;
|
||||
|
||||
// SET ANIMATION: animaciones de enemigos (nombres sin extensión, UPPERCASE)
|
||||
dynamic_providers_["SET ANIMATION"] = []() -> std::vector<std::string> {
|
||||
@@ -979,6 +990,20 @@ void CommandRegistry::registerHandlers() {
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// SET TILESET: tilesets disponibles (nombres sin extensión, UPPERCASE)
|
||||
dynamic_providers_["SET TILESET"] = []() -> std::vector<std::string> {
|
||||
std::vector<std::string> result;
|
||||
auto list = Resource::List::get()->getListByType(Resource::List::Type::BITMAP);
|
||||
for (const auto& path : list) {
|
||||
if (path.find("tilesets") == std::string::npos) { continue; }
|
||||
std::string name = getFileName(path);
|
||||
auto dot = name.rfind('.');
|
||||
if (dot != std::string::npos) { name = name.substr(0, dot); }
|
||||
result.push_back(toUpper(name));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user