feat(editor): valida 1 porta i ≥1 sarc en sortida i en borrar

This commit is contained in:
JailDesigner committed 2026-05-02 11:37:57 +02:00
1 parent ecb4625465
commit 10e16d7905
3 files changed
+36

No files matched your search

+3
View File
@@ -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"
+3
View File
@@ -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"
+30
View File
@@ -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<int>(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<int>(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; }
}