feat(editor): EntityWriter — persisteix el bloc entities: al sortir

This commit is contained in:
JailDesigner committed 2026-05-02 11:35:10 +02:00
1 parent b4e36944d7
commit ecb4625465
6 files changed
+213 -9

No files matched your search

+39 -4
View File
@@ -21,6 +21,7 @@
#include "game/entities/entity_factory.hpp"
#include "game/entities/entity_loader.hpp"
#include "game/entities/entity_manager.hpp"
#include "game/entities/entity_writer.hpp"
#include "game/levels/level_manager.hpp"
#include "game/map/map.hpp"
#include "game/map/tilemap.hpp"
@@ -226,10 +227,42 @@ void Editor::ensureEditableEntities() {
}
}
namespace {
// 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`).
auto gatherSpawns(const EntityManager& entities) -> std::vector<EntityWriter::Spawn> {
std::vector<EntityWriter::Spawn> out;
const auto LIST = entities.getEntities();
out.reserve(LIST.size());
for (const auto* e : LIST) {
EntityWriter::Spawn s;
s.type = e->getName();
if (s.type == "sarcophagus") {
if (Map::pitch_x > 0 && Map::pitch_y > 0) {
const auto LOGICAL = e->getCollisionRect();
s.sarc_col = (static_cast<int>(LOGICAL.x) - Map::origin_x) / Map::pitch_x;
s.sarc_row = (static_cast<int>(LOGICAL.y) - Map::origin_y) / Map::pitch_y;
}
} else if (s.type != "door") {
if (Map::tile_size > 0) {
const auto R = e->getPixelRect();
s.col = (static_cast<int>(R.x) - Map::tilemap_origin_x) / Map::tile_size;
s.row = (static_cast<int>(R.y) - Map::tilemap_origin_y) / Map::tile_size;
}
}
out.push_back(std::move(s));
}
return out;
}
} // namespace
// cppcheck-suppress constParameterReference
// Tilemap& mutable per simetria amb `toggle()` i per futures
// invalidacions de caches d'edició, encara que `save()` sigui const.
void Editor::exit(Tilemap& tilemap) {
void Editor::exit(Tilemap& tilemap, const EntityManager& entities) {
if (!active_) { return; }
active_ = false;
picker_ = Picker::NONE;
@@ -240,13 +273,15 @@ void Editor::exit(Tilemap& tilemap) {
// no el CWD; sense això, el writer obriria el path relatiu al CWD i
// fallaria si el binari no es llança des del repo root.
const auto ABS_PATH = Resource::Helper::resolve(Levels::LevelManager::get().currentPath());
const bool SAVED = tilemap.save(ABS_PATH);
const bool TILES_OK = tilemap.save(ABS_PATH);
const bool ENTITIES_OK = EntityWriter::saveEntitiesBlock(ABS_PATH, gatherSpawns(entities));
const bool SAVED = TILES_OK && ENTITIES_OK;
Notification::notify(Locale::get().text(SAVED ? "input.editor_off" : "input.editor_save_error"));
}
void Editor::toggle(Tilemap& tilemap) {
void Editor::toggle(Tilemap& tilemap, const EntityManager& entities) {
if (active_) {
exit(tilemap);
exit(tilemap, entities);
} else {
enter();
}