- faltava propietat mirror

- al fer clic es tanca la consola
This commit is contained in:
2026-04-02 13:02:35 +02:00
parent 273d9304dc
commit fc28586940
5 changed files with 143 additions and 5 deletions

View File

@@ -566,6 +566,7 @@ void MapEditor::updateStatusBarInfo() {
sel_detail = e.color + " vx:" + std::to_string(static_cast<int>(e.vx)) +
" vy:" + std::to_string(static_cast<int>(e.vy));
if (e.flip) { sel_detail += " flip"; }
if (e.mirror) { sel_detail += " mirror"; }
}
statusbar_->setSelectionInfo(sel_info);
@@ -652,13 +653,116 @@ auto MapEditor::setEnemyProperty(const std::string& property, const std::string&
if (property == "FLIP") {
enemy.flip = (value == "ON" || value == "TRUE" || value == "1");
if (enemy.flip) { enemy.mirror = false; } // Mutuamente excluyentes
// Recrear el enemigo (flip/mirror se aplican en el constructor)
try {
auto* enemy_mgr = room_->getEnemyManager();
enemy_mgr->getEnemy(selected_enemy_) = std::make_shared<Enemy>(enemy);
} catch (const std::exception& e) {
return std::string("Error: ") + e.what();
}
room_->getEnemyManager()->getEnemy(selected_enemy_)->resetToInitialPosition(enemy);
autosave();
return std::string("flip: ") + (enemy.flip ? "on" : "off");
}
return "Unknown property: " + property + " (use: animation, color, vx, vy, flip)";
if (property == "MIRROR") {
enemy.mirror = (value == "ON" || value == "TRUE" || value == "1");
if (enemy.mirror) { enemy.flip = false; } // Mutuamente excluyentes
// Recrear el enemigo (flip/mirror se aplican en el constructor)
try {
auto* enemy_mgr = room_->getEnemyManager();
enemy_mgr->getEnemy(selected_enemy_) = std::make_shared<Enemy>(enemy);
} catch (const std::exception& e) {
return std::string("Error: ") + e.what();
}
autosave();
return std::string("mirror: ") + (enemy.mirror ? "on" : "off");
}
return "Unknown property: " + property + " (use: animation, color, vx, vy, flip, mirror)";
}
// Crea un nuevo enemigo con valores por defecto, centrado en la habitación
auto MapEditor::addEnemy() -> std::string {
if (!active_) { return "Editor not active"; }
constexpr float CENTER_X = PlayArea::CENTER_X;
constexpr float CENTER_Y = PlayArea::CENTER_Y;
constexpr float ROUTE_HALF = 2.0F * Tile::SIZE; // 2 tiles a cada lado (5 tiles total con el centro)
Enemy::Data new_enemy;
new_enemy.animation_path = "spider.yaml";
new_enemy.x = CENTER_X;
new_enemy.y = CENTER_Y;
new_enemy.vx = 24.0F;
new_enemy.vy = 0.0F;
new_enemy.x1 = static_cast<int>(CENTER_X - ROUTE_HALF);
new_enemy.y1 = static_cast<int>(CENTER_Y);
new_enemy.x2 = static_cast<int>(CENTER_X + ROUTE_HALF);
new_enemy.y2 = static_cast<int>(CENTER_Y);
new_enemy.color = "white";
new_enemy.flip = true;
new_enemy.frame = -1;
// Añadir a los datos y crear el sprite vivo
room_data_.enemies.push_back(new_enemy);
room_->getEnemyManager()->addEnemy(std::make_shared<Enemy>(new_enemy));
// Seleccionar el nuevo enemigo
selected_enemy_ = static_cast<int>(room_data_.enemies.size()) - 1;
autosave();
return "Added enemy " + std::to_string(selected_enemy_);
}
// Elimina el enemigo seleccionado
auto MapEditor::deleteEnemy() -> std::string {
if (!active_) { return "Editor not active"; }
if (!hasSelectedEnemy()) { return "No enemy selected"; }
const int IDX = selected_enemy_;
// Eliminar de los datos
room_data_.enemies.erase(room_data_.enemies.begin() + IDX);
// Recrear todos los enemigos vivos (los índices cambian al borrar)
auto* enemy_mgr = room_->getEnemyManager();
enemy_mgr->clear();
for (const auto& enemy_data : room_data_.enemies) {
enemy_mgr->addEnemy(std::make_shared<Enemy>(enemy_data));
}
selected_enemy_ = -1;
autosave();
return "Deleted enemy " + std::to_string(IDX);
}
// Duplica el enemigo seleccionado (lo pone un tile a la derecha)
auto MapEditor::duplicateEnemy() -> std::string {
if (!active_) { return "Editor not active"; }
if (!hasSelectedEnemy()) { return "No enemy selected"; }
// Copiar datos del enemigo seleccionado
Enemy::Data copy = room_data_.enemies[selected_enemy_];
// Desplazar un tile a la derecha
copy.x += Tile::SIZE;
copy.x1 += Tile::SIZE;
copy.x2 += Tile::SIZE;
// Añadir y crear sprite vivo
room_data_.enemies.push_back(copy);
room_->getEnemyManager()->addEnemy(std::make_shared<Enemy>(copy));
// Seleccionar el nuevo enemigo
selected_enemy_ = static_cast<int>(room_data_.enemies.size()) - 1;
autosave();
return "Duplicated as enemy " + std::to_string(selected_enemy_);
}
#endif // _DEBUG

View File

@@ -32,8 +32,11 @@ class MapEditor {
void handleEvent(const SDL_Event& event);
auto revert() -> std::string;
// Comandos SET para modificar el enemigo seleccionado (llamados desde console_commands)
// Comandos para enemigos (llamados desde console_commands)
auto setEnemyProperty(const std::string& property, const std::string& value) -> std::string;
auto addEnemy() -> std::string;
auto deleteEnemy() -> std::string;
auto duplicateEnemy() -> std::string;
[[nodiscard]] auto hasSelectedEnemy() const -> bool;
private:

View File

@@ -175,6 +175,12 @@ void Game::handleEvents() {
while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event);
#ifdef _DEBUG
// En modo editor: click del ratón cierra la consola
if (Console::get()->isActive() && MapEditor::get()->isActive() &&
event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
Console::get()->toggle();
}
if (!Console::get()->isActive()) {
// Tecla 9: toggle editor (funciona tanto dentro como fuera del editor)
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_9 && static_cast<int>(event.key.repeat) == 0) {

View File

@@ -712,6 +712,22 @@ static auto cmd_set(const std::vector<std::string>& args) -> std::string {
if (args.size() < 2) { return "usage: set <animation|color|vx|vy|flip> <value>"; }
return MapEditor::get()->setEnemyProperty(args[0], args[1]);
}
// 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"; }
if (args.empty()) { return "usage: enemy <add|delete|duplicate>"; }
if (args[0] == "ADD") { return MapEditor::get()->addEnemy(); }
if (args[0] == "DELETE") {
if (!MapEditor::get()->hasSelectedEnemy()) { return "No enemy selected"; }
return MapEditor::get()->deleteEnemy();
}
if (args[0] == "DUPLICATE") {
if (!MapEditor::get()->hasSelectedEnemy()) { return "No enemy selected"; }
return MapEditor::get()->duplicateEnemy();
}
return "usage: enemy <add|delete|duplicate>";
}
#endif
// SHOW [INFO|NOTIFICATION|CHEEVO]
@@ -914,6 +930,7 @@ void CommandRegistry::registerHandlers() {
handlers_["cmd_scene"] = cmd_scene;
handlers_["cmd_edit"] = cmd_edit;
handlers_["cmd_set"] = cmd_set;
handlers_["cmd_enemy"] = cmd_enemy;
#endif
// HELP se registra en load() como lambda que captura this