feat(editor): mostra mommies i altres dynamic hazards al mode editor
This commit is contained in:
1 parent
a43ae21014
commit
da361a1452
8 files changed
+71
-20
No files matched your search
+18
-4
@@ -114,8 +114,6 @@ entities:
|
|||||||
sarc_position: [0, 3]
|
sarc_position: [0, 3]
|
||||||
- type: sarcophagus
|
- type: sarcophagus
|
||||||
sarc_position: [1, 3]
|
sarc_position: [1, 3]
|
||||||
- type: sarcophagus
|
|
||||||
sarc_position: [2, 3]
|
|
||||||
- type: sarcophagus
|
- type: sarcophagus
|
||||||
sarc_position: [3, 3]
|
sarc_position: [3, 3]
|
||||||
- type: sarcophagus
|
- type: sarcophagus
|
||||||
@@ -129,8 +127,6 @@ entities:
|
|||||||
- type: torch
|
- type: torch
|
||||||
position: [4, 2]
|
position: [4, 2]
|
||||||
- type: door
|
- type: door
|
||||||
- type: mummy
|
|
||||||
position: [10, 11]
|
|
||||||
- type: column
|
- type: column
|
||||||
position: [3, 4]
|
position: [3, 4]
|
||||||
frame: 2
|
frame: 2
|
||||||
@@ -140,3 +136,21 @@ entities:
|
|||||||
- type: stone
|
- type: stone
|
||||||
position: [4, 4]
|
position: [4, 4]
|
||||||
frame: 19
|
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]
|
||||||
@@ -131,9 +131,6 @@ entities:
|
|||||||
- type: sarcophagus
|
- type: sarcophagus
|
||||||
sarc_position: [3, 4]
|
sarc_position: [3, 4]
|
||||||
- type: door
|
- 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
|
- type: mummy
|
||||||
position: [10, 7]
|
position: [10, 7]
|
||||||
- type: mummy
|
- type: mummy
|
||||||
|
|||||||
@@ -142,18 +142,10 @@ Mummy::Mummy(const fkyaml::node& yaml)
|
|||||||
changeDirection(0.0F, 1.0F);
|
changeDirection(0.0F, 1.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Estat SPAWN inicial: la mòmia naix en SPAWNING amb l'animació
|
// L'estat SPAWNING amb l'animació `raise` s'arma a `onJustSpawned`,
|
||||||
// `raise` activa (16 frames @ 8fps, no-loop). La duració del SPAWN
|
// no al ctor. Així el manager pot instanciar la mòmia sense disparar
|
||||||
// la marca la pròpia animació — `Mummy::update` la tickeja, i quan
|
// la cinemàtica (cas del mode editor) i veure-la ja en ROAMING amb
|
||||||
// `completed()`, crida `endSpawn()` i restaura la `walk_*` per la
|
// la `walk_*` triada per `changeDirection` més amunt.
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configuració de l'estat HURT: opcional. Si el bloc no apareix, la
|
// Configuració de l'estat HURT: opcional. Si el bloc no apareix, la
|
||||||
// mòmia no entrarà mai a HURT efectiu (defensiu); el WhipAttack 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) {
|
void Mummy::changeDirection(float dx, float dy) {
|
||||||
setDirection(dx, dy);
|
setDirection(dx, dy);
|
||||||
// Una animació per cada cardinal — el flip viu al YAML
|
// Una animació per cada cardinal — el flip viu al YAML
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ class Mummy : public DynamicHazard {
|
|||||||
// En estat ROAMING delega a `step()` com sempre via la base.
|
// En estat ROAMING delega a `step()` com sempre via la base.
|
||||||
void update(float delta_time) override;
|
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.
|
// Contacte amb el jugador: publica `player_hit` amb el dany.
|
||||||
void onPlayerContact(Player* player) override;
|
void onPlayerContact(Player* player) override;
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,10 @@ class Entity {
|
|||||||
// entitat. La base no fa res; `DynamicHazard` override per disparar
|
// entitat. La base no fa res; `DynamicHazard` override per disparar
|
||||||
// el seu `triggerSpawnExit` (anima la fase EMERGING). Substitueix el
|
// el seu `triggerSpawnExit` (anima la fase EMERGING). Substitueix el
|
||||||
// `dynamic_cast<DynamicHazard*>(observer)->triggerSpawnExit()` que 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();
|
virtual void onJustSpawned();
|
||||||
|
|
||||||
// Hook just abans que el manager esborri l'entitat (via
|
// Hook just abans que el manager esborri l'entitat (via
|
||||||
|
|||||||
@@ -134,6 +134,15 @@ class EntityManager {
|
|||||||
// `respawnPlayersInstant` (salt debug).
|
// `respawnPlayersInstant` (salt debug).
|
||||||
void spawnPendingActors();
|
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
|
// Crea un actor on-demand i el deixa en EMERGING (com a
|
||||||
// `spawnPendingActors` però per a un sol). Pensat per a futurs
|
// `spawnPendingActors` però per a un sol). Pensat per a futurs
|
||||||
// generadors (StaticHazards que produeixen DynamicHazards en runtime,
|
// generadors (StaticHazards que produeixen DynamicHazards en runtime,
|
||||||
|
|||||||
@@ -527,6 +527,14 @@ void EntityManager::spawnPendingActors() {
|
|||||||
pending_actors_.clear();
|
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* {
|
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`
|
// Construïm un node de spawn sintètic amb el mínim que `placeGeneric`
|
||||||
// necessita: `type` i `position: [col, row]`. Si el caller vol
|
// necessita: `type` i `position: [col, row]`. Si el caller vol
|
||||||
|
|||||||
@@ -1484,6 +1484,14 @@ void GameScene::update(int delta_ms) {
|
|||||||
// totes maneres) i es reactivaran amb el spawn instantani
|
// totes maneres) i es reactivaran amb el spawn instantani
|
||||||
// a la sortida.
|
// a la sortida.
|
||||||
loadRoom(Levels::LevelManager::get().currentPath());
|
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) {
|
} else if (WAS_ACTIVE && !NOW_ACTIVE) {
|
||||||
// Acabem de sortir: el writer ja ha persistit el YAML.
|
// Acabem de sortir: el writer ja ha persistit el YAML.
|
||||||
// Carreguem fresh i fem spawn instantani sense cinemàtica.
|
// Carreguem fresh i fem spawn instantani sense cinemàtica.
|
||||||
|
|||||||
Reference in new issue
Block a user