refactor(em): separa entitats en dos sacs (map_entities_/actors_)

EntityManager guanya dues llistes lògiques:
- `map_entities_` — decoració, static_hazards (Hole, FloorTrap, WallTrap)
  i interactables (Sarcophagus, Door). Persistents tota la sala.
- `actors_` — DynamicHazards (Mummy, RollingRock, futurs enemics).
  Tipats com `unique_ptr<DynamicHazard>`, sense dynamic_cast.

`add()` enruta automàticament segons sigui DynamicHazard o no.
`update`, `notifyPlayerTilePainted`, `findFloorTriggerAt`, `removeEntity`,
`reload` i `renderAll` iteren el(s) sac(s) que toca.

`checkPlayerCollisions`: el filtre de SPAWN sobre el sac d'actors ja no
necessita dynamic_cast — `actor->isSpawning()` és directe. El filtre per
floor decals només toca map_entities_ (els decals viuen exclusivament
allà). Filtres per-jugador extrets a helpers per acotar complexitat.

API nova: `getMapEntities()` i `getActors()` exposen cada sac per
separat. `getEntities()` es manté com a concatenació per retro-compat
(editor, z-sort debug).

`GameScene::triggerHazardSpawnExit` itera `getActors()` directe — fora
dynamic_cast.

`GameScene::render` mergeja els tres orígens (map + actors + players)
en un sol vector temporal abans del stable_sort per `feet_y` — mateix
patró que ja s'usava amb players, ara amb una transformació més.

Comportament idèntic: les momies segueixen instanciant-se al
loadFromLevel. La preparació per al spawn diferit ve en el commit
següent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
JailDesignerandClaude Opus 4.7 committed 2026-05-11 10:23:44 +02:00
1 parent 3b378e2b29
commit 62f4b857ef
4 files changed
+149 -70

No files matched your search

+19 -2
View File
@@ -9,6 +9,7 @@
#include "external/fkyaml_node.hpp"
#include "game/entities/event_bus.hpp"
#include "game/entities/hazard.hpp"
class Entity;
class Sarcophagus;
@@ -74,7 +75,13 @@ class EntityManager {
// Accés als punters observacionals a les entitats per a consumidors
// externs que necessiten construir una llista ordenada (z-order).
// `getEntities()` concatena els dos sacs interns (mapa + actors) per
// a consumidors retro-compat (editor, z-sort debug). `getMapEntities`
// i `getActors` exposen cada sac per separat — útil per a iteracions
// que ja saben quin tipus volen i estalvien filtres O(n).
[[nodiscard]] auto getEntities() const -> std::vector<Entity*>;
[[nodiscard]] auto getMapEntities() const -> std::vector<Entity*>;
[[nodiscard]] auto getActors() const -> std::vector<DynamicHazard*>;
// Comprova contacte del(s) jugador(s) amb entitats `collides()=true`.
// Si la caixa base del jugador solapa amb la caixa de col·lisió de
@@ -136,7 +143,7 @@ class EntityManager {
void setExpectedPlayerCount(int n);
[[nodiscard]] auto getBus() -> EventBus& { return bus_; }
[[nodiscard]] auto entityCount() const -> std::size_t { return entities_.size(); }
[[nodiscard]] auto entityCount() const -> std::size_t { return map_entities_.size() + actors_.size(); }
[[nodiscard]] auto sarcophagusCount() const -> std::size_t { return total_sarcs_; }
[[nodiscard]] auto openedSarcophagusCount() const -> std::size_t { return opened_sarcs_; }
[[nodiscard]] auto exitedPlayerCount() const -> std::size_t { return exited_players_; }
@@ -150,7 +157,17 @@ class EntityManager {
private:
EventBus bus_;
std::vector<std::unique_ptr<Entity>> entities_;
// Dos sacs lògics:
// `map_entities_` — decoració, static_hazards (Hole, FloorTrap,
// WallTrap) i interactables (Sarcophagus, Door).
// Cargades al loadFromLevel i persistents durant
// tota la sala.
// `actors_` — DynamicHazards (Mummy, RollingRock, futurs
// enemics). Separats per eliminar dynamic_casts
// i preparar el spawn diferit (commit posterior).
// `add()` enruta automàticament segons sigui o no DynamicHazard.
std::vector<std::unique_ptr<Entity>> map_entities_;
std::vector<std::unique_ptr<DynamicHazard>> actors_;
Door* door_{nullptr};
std::size_t total_sarcs_{0};
std::size_t opened_sarcs_{0};