From 10e16d790518fac93004cc5ce59aede58a2a8d5f Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 2 May 2026 11:37:57 +0200 Subject: [PATCH] =?UTF-8?q?feat(editor):=20valida=201=20porta=20i=20?= =?UTF-8?q?=E2=89=A51=20sarc=20en=20sortida=20i=20en=20borrar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/locale/ca.yaml | 3 +++ data/locale/en.yaml | 3 +++ source/game/editor/editor.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/data/locale/ca.yaml b/data/locale/ca.yaml index d4d6b4b..a448e58 100644 --- a/data/locale/ca.yaml +++ b/data/locale/ca.yaml @@ -27,6 +27,9 @@ input: editor_on: "Editor ON" editor_off: "Editor OFF" editor_save_error: "Editor: error guardant el mapa" + editor_keep_door: "Editor: cal almenys una porta" + editor_keep_sarc: "Editor: cal almenys un sarcòfag" + editor_invalid_level: "Editor: nivell incomplet (porta i sarcs)" hud: p1: "P1" diff --git a/data/locale/en.yaml b/data/locale/en.yaml index f9e123e..5971339 100644 --- a/data/locale/en.yaml +++ b/data/locale/en.yaml @@ -27,6 +27,9 @@ input: editor_on: "Editor ON" editor_off: "Editor OFF" editor_save_error: "Editor: map save failed" + editor_keep_door: "Editor: at least one door required" + editor_keep_sarc: "Editor: at least one sarcophagus required" + editor_invalid_level: "Editor: level incomplete (door and sarcs)" hud: p1: "P1" diff --git a/source/game/editor/editor.cpp b/source/game/editor/editor.cpp index 224c2f4..183b67d 100644 --- a/source/game/editor/editor.cpp +++ b/source/game/editor/editor.cpp @@ -229,6 +229,16 @@ void Editor::ensureEditableEntities() { namespace { + auto countByName(const EntityManager& entities, std::string_view name) -> int { + const auto LIST = entities.getEntities(); + return static_cast(std::ranges::count_if(LIST, + [name](const Entity* e) { return e->getName() == name; })); + } + + auto levelIsValid(const EntityManager& entities) -> bool { + return countByName(entities, "door") == 1 && countByName(entities, "sarcophagus") >= 1; + } + // Reconstrueix els spawns del nivell des de l'estat viu del manager. // Per cada entitat: extreu type i la posició adequada (`position` // generic, `sarc_position` per a sarcs, cap per a `door`). @@ -264,6 +274,14 @@ namespace { // invalidacions de caches d'edició, encara que `save()` sigui const. void Editor::exit(Tilemap& tilemap, const EntityManager& entities) { if (!active_) { return; } + // Constraint del nivell: cal exactament una porta i com a mínim un + // sarcòfag perquè la sala sigui jugable. Si no es compleix, ens + // quedem dins del editor i avisem; l'usuari ha d'arreglar-ho abans + // de poder eixir (i, per tant, persistir). + if (!levelIsValid(entities)) { + Notification::notify(Locale::get().text("input.editor_invalid_level")); + return; + } active_ = false; picker_ = Picker::NONE; // El writer salva sempre sobre la sala actualment carregada (segons @@ -590,6 +608,18 @@ void Editor::deleteSelected(EntityManager& entities) { auto list = entities.getEntities(); if (hand_selected_idx_ < 0 || hand_selected_idx_ >= static_cast(list.size())) { return; } auto* target = list[hand_selected_idx_]; + const auto NAME = target->getName(); + // Bloqueig en-place: només denegem el borrat si convertiria el + // nivell en invàlid. Per a sarcs deixem baixar fins a 1; per a + // porta no deixem mai eliminar la única. + if (NAME == "door") { + Notification::notify(Locale::get().text("input.editor_keep_door")); + return; + } + if (NAME == "sarcophagus" && countByName(entities, "sarcophagus") <= 1) { + Notification::notify(Locale::get().text("input.editor_keep_sarc")); + return; + } if (entities.removeEntity(target)) { hand_selected_idx_ = -1; } }