feat(editor): mostra mommies i altres dynamic hazards al mode editor

This commit is contained in:
JailDesigner committed 2026-05-12 13:58:45 +02:00
1 parent a43ae21014
commit da361a1452
8 files changed
+71 -20

No files matched your search

+18 -4
View File
@@ -114,8 +114,6 @@ entities:
sarc_position: [0, 3]
- type: sarcophagus
sarc_position: [1, 3]
- type: sarcophagus
sarc_position: [2, 3]
- type: sarcophagus
sarc_position: [3, 3]
- type: sarcophagus
@@ -129,8 +127,6 @@ entities:
- type: torch
position: [4, 2]
- type: door
- type: mummy
position: [10, 11]
- type: column
position: [3, 4]
frame: 2
@@ -140,3 +136,21 @@ entities:
- type: stone
position: [4, 4]
frame: 19
- type: column
position: [13, 10]
frame: 4
- type: stone
position: [12, 10]
frame: 13
- type: stone
position: [11, 10]
frame: 23
- type: hole
position: [5, 9]
- type: hole
position: [9, 11]
- type: stone
position: [10, 10]
frame: 18
- type: mummy
position: [10, 13]
-3
View File
@@ -131,9 +131,6 @@ entities:
- type: sarcophagus
sarc_position: [3, 4]
- type: door
# Sense `position`: la porta sempre viu al mur trasser. La columna
# transitable la dicta `geometry.door_col`; el render i la caixa
# de col·lisió es deriven d'aquesta dada al loadFromLevel.
- type: mummy
position: [10, 7]
- type: mummy
+18 -12
View File
@@ -142,18 +142,10 @@ Mummy::Mummy(const fkyaml::node& yaml)
changeDirection(0.0F, 1.0F);
}
// Estat SPAWN inicial: la mòmia naix en SPAWNING amb l'animació
// `raise` activa (16 frames @ 8fps, no-loop). La duració del SPAWN
// la marca la pròpia animació — `Mummy::update` la tickeja, i quan
// `completed()`, crida `endSpawn()` i restaura la `walk_*` per la
// direcció actual. Passem 0 al countdown del DynamicHazard perquè
// no s'utilitza en aquest cas (el nostre `update` retorna abans).
enterSpawn(0.0F);
anim_ = anim_raise_;
if (anim_.has_value()) {
anim_->reset();
flip_ = anim_->flipMode();
}
// L'estat SPAWNING amb l'animació `raise` s'arma a `onJustSpawned`,
// no al ctor. Així el manager pot instanciar la mòmia sense disparar
// la cinemàtica (cas del mode editor) i veure-la ja en ROAMING amb
// la `walk_*` triada per `changeDirection` més amunt.
// Configuració de l'estat HURT: opcional. Si el bloc no apareix, la
// mòmia no entrarà mai a HURT efectiu (defensiu); el WhipAttack la
@@ -180,6 +172,20 @@ Mummy::Mummy(const fkyaml::node& yaml)
}
}
void Mummy::onJustSpawned() {
// Cinemàtica d'aparició: la mòmia "s'aixeca" reproduint `raise`
// (16 frames no-loop). El countdown del DynamicHazard NO s'utilitza
// (passem 0): `Mummy::update` controla la transició a ACTIVE per
// `anim_->completed()`. Cap crida a la base perquè el `triggerSpawnExit`
// del DynamicHazard arma aquest mateix countdown que aquí no toca.
enterSpawn(0.0F);
anim_ = anim_raise_;
if (anim_.has_value()) {
anim_->reset();
flip_ = anim_->flipMode();
}
}
void Mummy::changeDirection(float dx, float dy) {
setDirection(dx, dy);
// Una animació per cada cardinal — el flip viu al YAML
+6
View File
@@ -61,6 +61,12 @@ class Mummy : public DynamicHazard {
// En estat ROAMING delega a `step()` com sempre via la base.
void update(float delta_time) override;
// Inicia la fase SPAWNING amb l'animació `raise`. Es crida al
// spawnPendingActors() del joc, no al ctor: així l'editor (que
// materialitza les entitats sense aquest hook) veu la mòmia ja en
// ROAMING visible, sense quedar-se "soterrada".
void onJustSpawned() override;
// Contacte amb el jugador: publica `player_hit` amb el dany.
void onPlayerContact(Player* player) override;
+4 -1
View File
@@ -102,7 +102,10 @@ class Entity {
// entitat. La base no fa res; `DynamicHazard` override per disparar
// el seu `triggerSpawnExit` (anima la fase EMERGING). Substitueix el
// `dynamic_cast<DynamicHazard*>(observer)->triggerSpawnExit()` que el
// manager feia abans — ara el dispatch és polimòrfic.
// manager feia abans — ara el dispatch és polimòrfic. Entitats que
// requereixen una fase d'aparició (mòmia amb animació `raise`)
// l'inicien aquí, NO al ctor: així `materializePendingActorsStatic`
// (editor) les salta i queden visibles directament.
virtual void onJustSpawned();
// Hook just abans que el manager esborri l'entitat (via
+9
View File
@@ -134,6 +134,15 @@ class EntityManager {
// `respawnPlayersInstant` (salt debug).
void spawnPendingActors();
// Materialitza els pending actors al món sense disparar la cinemàtica
// de SPAWN (`onJustSpawned`). Pensat per a l'editor: vol veure les
// mòmies a la seva posició inicial per poder editar-les, però no
// disparar l'animació EMERGING (l'editor congela el món, l'animació
// no avançaria i quedaria invisible). En sortir de l'editor, GameScene
// fa un `reload` que torna els actors a `pending_actors_` i el flux
// normal els spawneja amb la cinemàtica al final del ROOM_INTRO.
void materializePendingActorsStatic();
// Crea un actor on-demand i el deixa en EMERGING (com a
// `spawnPendingActors` però per a un sol). Pensat per a futurs
// generadors (StaticHazards que produeixen DynamicHazards en runtime,
@@ -527,6 +527,14 @@ void EntityManager::spawnPendingActors() {
pending_actors_.clear();
}
void EntityManager::materializePendingActorsStatic() {
// Igual que `spawnPendingActors` però sense `onJustSpawned`: l'actor
// queda en el seu estat inicial (mòmia: ROAMING, walk_east) en lloc
// d'EMERGING. Vegeu el comentari del header per la motivació.
for (const auto& pa : pending_actors_) { addSpawn(pa.spawn_node); }
pending_actors_.clear();
}
auto EntityManager::spawnActor(const std::string& type, int col, int row) -> DynamicHazard* {
// Construïm un node de spawn sintètic amb el mínim que `placeGeneric`
// necessita: `type` i `position: [col, row]`. Si el caller vol
+8
View File
@@ -1484,6 +1484,14 @@ void GameScene::update(int delta_ms) {
// totes maneres) i es reactivaran amb el spawn instantani
// a la sortida.
loadRoom(Levels::LevelManager::get().currentPath());
// Materialitzem els dynamic hazards (mòmies, roques) en estat
// estàtic perquè es vegin a la posició inicial: així l'editor
// les pot seleccionar i moure com qualsevol altra entitat. El
// flux normal del joc les enruta a `pending_actors_` per a
// disparar la cinemàtica EMERGING al final del ROOM_INTRO; a
// l'editor el món està congelat i aquesta animació quedaria
// travada.
entity_manager_.materializePendingActorsStatic();
} else if (WAS_ACTIVE && !NOW_ACTIVE) {
// Acabem de sortir: el writer ja ha persistit el YAML.
// Carreguem fresh i fem spawn instantani sense cinemàtica.