Commit Graph
13 Commits
Author SHA1 Message Date
JailDesigner 28ff425c89 refactor(entities): polimorfisme per substituir dynamic_casts
Quatre virtuals nous a `Entity` capten decisions que abans vivien al
manager com a discriminacions de tipus:

- `onWhipHit(WhipAttack*)` → bool. Default no-op/false. Override a
  `Mummy` per entrar HURT si és whippable. WhipAttack::applyDamage
  passa de `dynamic_cast<Mummy*>` + `isWhippable()` a una crida
  polimòrfica neta. RollingRock no override → immune al látigo per
  disseny, sense flag.

- `onJustSpawned()`. Default no-op. Override a `DynamicHazard` per
  disparar `triggerSpawnExit()`. `spawnPendingActors` i `spawnActor`
  passen de `dynamic_cast<DynamicHazard*>(observer)->triggerSpawnExit()`
  a `observer->onJustSpawned()`.

- `onRemoved()`. Default no-op. Override a `Sarcophagus` per cridar
  `entity_manager_->onSarcophagusRemoved()`. `removeEntity` passa de
  `getName() == "sarcophagus"` a dispatch polimòrfic.

- `shouldReceiveContact()`. Default `collides() || triggersOnOverlap()`.
  Override a `DynamicHazard` per excloure SPAWN. `checkPlayerCollisions`
  passa de tres condicions inline per a sacs distints a una crida
  unificada.

`whipDirToMummyDir` es mou de whip_attack.cpp a mummy.cpp — el mapping
viu on s'usa (dins de `Mummy::onWhipHit`).

`hitMummyIfApplicable` es renomena a `hitEntityIfApplicable`: ja no
discrimina tipus, aplica `entity->onWhipHit` i marca `already_hit_`
segons el retorn.

Comportament idèntic, tests verds. Aquest commit prepara el següent:
amb el polimorfisme madurat, el sac dual ja no aporta valor i podem
tornar a un únic `entities_`.
2026-05-11 13:01:26 +02:00
JailDesignerandClaude Opus 4.7 6a6a1a52c7 feat(em): spawn diferit de DynamicHazards (pending_actors_)
`loadFromLevel` ja no instancia immediatament les DynamicHazards del
YAML del mapa: les acumula a `pending_actors_` (estructura {type,
spawn_node}). El loader decideix per la categoria semàntica de la
plantilla (`type:` del YAML d'entity: "dynamic_hazard" → pending; la
resta → addSpawn d'instant).

Dues APIs noves consumeixen pending_actors_:
- `spawnPendingActors()` — itera la cua, instancia tots via addSpawn
  i arma `triggerSpawnExit()` a cada un. Vacia la cua. El path
  d'aparició massiva al final del text-exit de ROOM_INTRO.
- `spawnActor(type, col, row)` — instancia un únic actor on-demand
  des d'un spawn YAML sintètic. Pensat per a futurs generadors
  (StaticHazards que produeixen DynamicHazards en runtime: gotes,
  roques, etc.). Cada actor neix ja en EMERGING.

`GameScene::triggerHazardSpawnExit` ara és un wrapper de
`spawnPendingActors()` — el dispar segueix en la subfase actual
(fase 5 de ROOM_INTRO) i a `respawnPlayersInstant`. El canvi de timing
ve en el commit següent.

`reload` també buida pending_actors_. Log: "N map entities + M actors
pending des de PATH" — visible per a diagnòstic.

Sense canvis de comportament observables al joc: les mòmies segueixen
apareixent al final del text-exit, però ara la "aparició" és la seua
instanciació real (abans ja existien quietes des del fade-in).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 10:35:02 +02:00
JailDesignerandClaude Opus 4.7 62f4b857ef 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>
2026-05-11 10:23:44 +02:00
JailDesigner b4e36944d7 feat(editor): mode mà — selecció, mou, borra i marc d'entitats 2026-05-02 11:28:41 +02:00
JailDesigner 9b09ccb765 feat(editor): col·locació d'entitats amb snap per tipus i bloqueig de solapaments 2026-05-02 11:21:05 +02:00
JailDesigner 3e5217066f fix(hazard): aterrar damunt d'un Hole salta el LANDING_STUN 2026-04-30 13:53:26 +02:00
JailDesigner 8da18a6a86 feat(debug): tecla Keypad 1 per forçar l'obertura de la porta
Hook només Debug que crida EntityManager::forceOpenDoor (nou helper
públic que delega a Door::open). El flux posterior — creuar la porta,
player_exited, level_complete, transició a OUTRO — funciona idèntic
al del joc real, perquè depèn de la Door, no del comptador de
sarcòfags. Útil per saltar la mecànica de pintat/sarcs durant proves
de progressió de sales.

Tecla configurable a data/input/keys.yaml > id: open_door
(per defecte Keypad 1). Mateixos gates que els salts [/]: ignora la
pulsació si la pausa està activa o l'editor obert. En Release la
ENTRADA del YAML segueix carregant-se però no té consumidor.
2026-04-26 17:20:12 +02:00
JailDesigner 59cd9b524c feat(entity-manager): reload del nivell + PaintLayer::clear 2026-04-26 10:26:07 +02:00
JailDesigner 28e55a0615 feat(entity-manager): comptador player_exited agrega a level_complete 2026-04-26 10:22:42 +02:00
JailDesigner e3cf2eb773 refactor(entities): rename notifyTileEntered → notifyTilePainted i escolta tile_painted 2026-04-23 13:22:02 +02:00
JailDesigner ee8dc25181 feat(entities): fase 4 - moviment de la momia amb col·lisió, z-order per peus i contacte amb el jugador 2026-04-21 20:14:47 +02:00
JailDesigner 7191a08618 feat(entities): integració del sistema d'entitats al GameScene 2026-04-21 13:55:21 +02:00
JailDesigner 96b71b0f65 feat(entities): andamiatge del sistema d'entitats (classes, factory, bus, YAML, placeholders, smoke tests) 2026-04-21 12:35:19 +02:00