Commit Graph
64 Commits
Author SHA1 Message Date
JailDesigner df60709e6d feat(whip): aplicació de dany amb retall de hitbox, alreadyHit i friendly fire 2026-04-28 16:20:22 +02:00
JailDesigner d208ba02df feat(player): estat ATTACKING amb edge-detect, animacions i spawn del whip via bus 2026-04-28 16:20:22 +02:00
JailDesigner 9ad21eb5bb feat(attack): esquelet WhipAttack + canal d'spawn via EventBus 2026-04-28 16:20:22 +02:00
JailDesigner 15a7c4e18a feat(audio): música només a PLAYING; so del rètol al final del fade-in d'INTRO 2026-04-27 08:48:01 +02:00
JailDesigner 47bb92144e feat(audio): reverb 'stone_hall' al primer LAND cinemàtic d'INTRO
Lligua el reverb al moment de la cinemàtica d'entrada de sala, no als
salts en general. La sala dóna "més detall" sonor a l'INTRO; un cop el
joc està en marxa, els salts (i els respawns post-mort) tornen al so
sec. Així el primer aterratge es percep com a part de l'animació
d'arribada, no com una propietat permanent del personatge.

  - RoomFsm::Config: nou camp `intro_land_reverb_preset` carregat des
    de `room_intro.land_reverb` a `data/scenes/game.yaml` (per defecte
    'stone_hall'). Buit = sense reverb a l'INTRO.
  - Player: membre `next_land_reverb_preset_` consumit per
    `integrateJump` al primer aterratge que el trobe armat. Setter
    públic `armNextLandReverb(preset)` per a GameScene. Cap altre punt
    (respawn, exit, disable) el toca: el reverb és estrictament
    one-shot lligat al spawn aeri d'INTRO.
  - GameScene::triggerPlayerSpawn: arma el preset al jugador just
    després de `spawnFromAir`, així cada slot rep el seu reverb un
    sol cop per cinemàtica.
  - JumpConfig perd `land_reverb_preset` i els YAMLs de Sam/Morcus
    perden `land_reverb`: la decisió ja no viu al personatge.
2026-04-27 08:31:51 +02:00
JailDesigner 8e2865efbd feat(intro): delay de spawn independent per al segon jugador en mode BOTH 2026-04-26 18:55:30 +02:00
JailDesigner 99eb42b319 refactor(game-scene): extreu helpers de renderRoomText i elimina el NOLINT 2026-04-26 18:44:49 +02:00
JailDesigner 8243e95ef1 feat(intro/outro): panel translúcid sota el rètol amb easing del text 2026-04-26 18:41:17 +02:00
JailDesigner 0752df0f62 feat(intro/outro): rètol centrat sobre el playfield i ajustos de timings/colors 2026-04-26 18:08:02 +02:00
JailDesigner 98303f7ce8 feat(outro): pausa en negre opac entre sales (5a fase de OUTRO)
Nova fase 4 a ROOM_OUTRO: black_hold. Va just després del fade_out;
durant aquesta fase la pantalla queda completament en negre opac i
la FSM espera abans de transitar a INTRO. Permet donar respir entre
el final del rètol Fase/Completada i el rellançament del Piramide/Sala
de la sala següent, sense necessitat d'un estat nou.

Implementacio:
- RoomFsm::Config guanya outro_black_hold_ms (default 0 — backward
  compatible). YAML key room_outro.black_hold_ms al data/scenes/game.yaml
  (default visible 500 ms; lo afines sense recompilar).
- L'array DURS de l'OUTRO passa de 4 a 5 elements; el while-loop
  consumeix la fase exactament igual.
- renderRoomFade detecta fase 4 i dibuixa alpha=255 fix; sense aquesta
  branca, el fade s'apagaria a final de la fase 3 i el món tornaria
  a ser visible durant la pausa.
- renderRoomText no canvia: phases 3 i 4 ja queden fora del rang
  0..2 on dibuixa el rètol.

Backward compat: black_hold_ms=0 fa que el while-loop avance
immediatament la fase i recauen tots els tests existents (T7 i
companys) sense modificacions.
2026-04-26 17:39:02 +02:00
JailDesigner 7982df922b feat(outro): rètol "fase completada" en dues línies oposades
Mateixa tècnica que l'INTRO: la línia 1 ("Fase") entra per
l'esquerra, la línia 2 ("Completada") per la dreta, i surten cap
al costat oposat al d'entrada. Centrades verticalment al voltant
del CENTER_Y amb el gap configurable ( a
data/scenes/game.yaml; 0 per defecte, paral·lel a la del room_intro).

Locale: la clau game.room_complete es divideix en
game.room_complete_line1 / room_complete_line2 als ca.yaml i en.yaml
("Fase"/"Completada" i "Stage"/"Complete"). Cada línia es
tradueix per separat — útil si demà voleu paraules de longitud o
ordre distint en altres idiomes.
2026-04-26 17:28:07 +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 3b05704e97 feat(intro): colors del rètol independents + restitueix line_gap_px
Dues claus noves a data/ui.yaml > colors:
  room_text         (relleno, default 232)
  room_text_outline (contorn, default 255)
Abans el relleno reciclava notification_text (compartit amb les
notificacions del HUD) i el contorn estava hardcodejat a 255 dins
renderRoomText. Ara són canals separats: tocar el rètol no afecta
les notificacions i tot viu al YAML.

UiConfig guanya roomText() / roomTextOutline(); Defaults::UI hi posa
els fallbacks; renderRoomText els consumeix.

Drive-by: torna a posar la clau room_intro.line_gap_px: 8 al
data/scenes/game.yaml — s'havia perdut en una edició manual del
fitxer per afinar timings.
2026-04-26 17:02:26 +02:00
JailDesigner 00594d9eb2 feat(intro): línies del rètol travessen en direccions oposades
compute_x guanya un paràmetre from_right que decideix per quin costat
entra i per quin surt. La línia de la piràmide es queda amb el patró
clàssic (entra per l'esquerra, surt per la dreta); la de la sala s'hi
inverteix (entra per la dreta, surt per l'esquerra). El text de
l'OUTRO continua amb la direcció original.
2026-04-26 16:59:01 +02:00
JailDesigner af25a31639 feat(intro): font dedicada (CaesarDressing) i separació vertical entre línies
Nova font del rètol de transició de sala (ROOM_INTRO i ROOM_OUTRO):
CaesarDressing-Regular, vista com a fonts.room_text al data/ui.yaml i
exposada per UiConfig::roomTextFont(). Director la preloda al costat
de la del HUD i la del placeholder; GameScene construeix
room_text_font_ paral·lel a pause_font_ i renderRoomText l'usa per a
les dues línies de l'INTRO i el text de l'OUTRO. La pausa segueix
amb la font placeholder antiga — no es barregen.

Espai vertical configurable: nova clau room_intro.line_gap_px al
data/scenes/game.yaml (default 8 px). El gap es suma al lineHeight
natural del font i es reparteix simètricament cap amunt i cap avall
del CENTER_Y, deixant el bloc de dues línies sempre centrat. Es
poden afinar des del YAML sense recompilar.
2026-04-26 15:40:09 +02:00
JailDesigner e2f6d326aa feat(level-manager): HUD i text d'INTRO segueixen el LevelManager
HUD: la GameScene crida hud_->setPyramidRoom amb els valors del
LevelManager al ctor i a cada loadRoom — el marcador deixa de
mostrar 1/1 fix i s'actualitza en avançar de sala, en saltar amb
[/] i en arrencar amb starting_level del debug.yaml.

INTRO a dues línies: substitueix la clau game.room_intro per
game.room_intro_pyramid ("Piramide {p}") i game.room_intro_room
("Sala {r}") als locale ca/en. RoomFsm::formatRoomTitle(int)
desapareix i el reemplacen formatIntroPyramidLine(int) +
formatIntroRoomLine(int). renderRoomText es refactoritza per
dibuixar les dues línies (piràmide damunt, sala davall) amb
writeDX independents — comparteixen animació ara mateix però el
disseny ja les deixa preparades per ser desacoblades en el futur.

Drive-by: elimina el membre room_index_ de GameScene; les tres
ubicacions que el sincronitzaven amb el LevelManager (ctor,
advanceToNextRoom, salt debug) ja no fan falta — renderRoomText
i el HUD pregunten directament al singleton, evitant qualsevol
mirror local desincronitzable.

Test: T9/T10 actualitzats per a les dues noves formatadores.
2026-04-26 15:25:22 +02:00
JailDesigner b147590a39 feat(level-manager): salts debug entre sales (només Debug)
Tecles [ i ] al keys.yaml (prev_room / next_room) que mouen
LevelManager::setIndex en ±1 i recarreguen la sala via loadRoom +
enterRoomIntro. Ignorades si la pausa està activa o l'editor obert
(qualsevol dels dos invalida l'estat editat).

Refactor de la FSM al mateix pas: l'avanç de sala (LevelManager +
loadRoom) ja no viu dins setState — el dispara updateRoomTransition
quan detecta el final de l'OUTRO via advanceToNextRoom. setState
torna a ser una transició pura, condició necessària perquè el salt
debug puga entrar a INTRO sense disparar un advance addicional.
Nou helper enterRoomIntro() reusable per la sortida de l'OUTRO i pels
salts; idempotent quan ja s'estava a INTRO.
2026-04-26 14:59:34 +02:00
JailDesigner 9d4f92c98b feat(level-manager): avança a la sala següent al creuar la porta
Reemplaça resetRoom() per loadRoom(yaml_path) — la mateixa mecànica de
recàrrega però parametritzada amb el path de la nova sala. setState
de OUTRO → INTRO ara crida advanceToNextRoom(): demana al LevelManager
el següent nivell, sincronitza room_index_ amb el currentRoom() i
carrega via loadRoom. Si l'OUTRO arriba a l'última sala del levels.yaml,
fa loop a la primera (política temporal mentre no hi haja pantalla de
fi de joc). El comentari TODO de room_fsm.cpp queda actualitzat: la
FSM continua sent agnostica a quina sala ve, només marca el canvi
d'estat — l'itinerari el resol GameScene amb el LevelManager.
2026-04-26 14:53:07 +02:00
JailDesigner f51fe3d820 feat(level-manager): GameScene pren el mapa del LevelManager
defaultConfig() llig el path del nivell actual amb
Levels::LevelManager::get().currentPath() en lloc de la constant
Pyramid::MAP_YAML (que desapareix). El ctor sincronitza room_index_
amb LevelManager::currentRoom() per al text d'intro de sala. Encara
no hi ha progressió: cada arrencada continua a la primera sala del
levels.yaml; el comportament visible és idèntic, però la responsabilitat
de 'quin fitxer carreguem' ha passat al LevelManager.
2026-04-26 14:50:51 +02:00
JailDesigner 580c13e854 feat: estat DISABLED i spawn aeri al començar la sala — v0.25.0 2026-04-26 14:17:17 +02:00
JailDesigner c0214b233b fix(game-scene): text d'INTRO/OUTRO surt cap a la dreta després del hold 2026-04-26 10:47:41 +02:00
JailDesigner cd5bb94223 fix(player): EXITED no participa al resolver ni a checkPlayerCollisions 2026-04-26 10:41:05 +02:00
JailDesigner 811c6c482d feat(game-scene): spawn lligat a door_col i respawn a OUTRO->INTRO 2026-04-26 10:30:31 +02:00
JailDesigner 28e55a0615 feat(entity-manager): comptador player_exited agrega a level_complete 2026-04-26 10:22:42 +02:00
JailDesigner 63bb41425a test(game-scene): extracció RoomFsm i smoke test de la FSM de sala 2026-04-26 09:10:54 +02:00
JailDesigner 4a9a037cd8 feat(game-scene): ROOM_OUTRO — text de sortida i fade out del món 2026-04-26 09:02:30 +02:00
JailDesigner 67b06c0a10 feat(game-scene): ROOM_INTRO — fade in del món i text d'entrada de sala 2026-04-26 09:00:15 +02:00
JailDesigner 368f9d2d6a feat(scenes): data/scenes/game.yaml amb timings i corbes de transició 2026-04-26 08:54:45 +02:00
JailDesigner 651db50a93 feat(game-scene): FSM mínima ROOM_INTRO/PLAYING/ROOM_OUTRO sense efectes 2026-04-26 08:51:56 +02:00
JailDesigner 3e379ce129 feat(effects): polvet transitori al despegue i a l'aterratge 2026-04-25 17:51:55 +02:00
JailDesigner e8407ce35e feat(player): nou estat HURT — caure damunt d'un altre el llança projectat 2026-04-25 14:56:15 +02:00
JailDesigner 188f035333 feat(player): saltar travessa el caminant; rebot mid-aire entre dos saltadors 2026-04-25 14:20:38 +02:00
JailDesigner 64390f8ad7 feat(player): sombra translúcida sota el jugador mentre està en l'aire 2026-04-25 11:59:13 +02:00
JailDesigner cd50626b88 feat(collisions): filtre per altura — saltar esquiva momies, roques i altres jugadors 2026-04-25 11:49:48 +02:00
JailDesigner 7b09a076b2 feat(player): salt vertical amb física, màquina d'estats i animació jump_* 2026-04-25 11:42:07 +02:00
JailDesigner 4f1a3260a5 fix(player): snapToLane respecta col·lisió PvP i empeny amb push_factor 2026-04-24 22:38:36 +02:00
JailDesigner ea0f6d98a9 feat(player): inèrcia de frenada amb acumulador de moviment 2026-04-24 20:20:30 +02:00
JailDesigner 858e444842 feat(player): hit-box 8×8 per a contacte actor-actor (player, momia, trampa) 2026-04-24 19:23:30 +02:00
JailDesigner 511f8d5b09 fix(player): el jugador empentat es queda en stand, no walk 2026-04-24 19:00:04 +02:00
JailDesigner e22f3240da feat(player): col·lisió i empenta entre jugadors amb push_factor al YAML del mapa 2026-04-24 18:54:19 +02:00
JailDesigner 4e9d5df872 feat(players): suport del segon jugador amb events amb player_id 2026-04-24 14:33:52 +02:00
JailDesigner 5c70019eb5 feat(game): pausa graduada amb easing i separador al HUD 2026-04-24 11:56:38 +02:00
JailDesigner dc8a7723e3 feat(ui): captura F9, tema a data/ui.yaml i retocs estètics
Captura de pantalla amb F9: volca el canvas ARGB a
screenshots/scr_<timestamp>.png via stb_image_write.

Tot el tema d'UI (colors, timings, fonts, flag hud.bg_enabled)
passa a data/ui.yaml via UiConfig; els valors de Defaults::UI
queden com a fallbacks si el fitxer falta o li manca alguna clau.

Retocs estètics: paleta "uzebox" per a la UI, strings del HUD
(P1/P2/V/T/PIRAMIDE/SALA) traduïts a locale, i fons del marcador
opcional amb backdrop continu de franja per evitar el trencament
visual durant el shake o l'animació d'entrada dels panells.
2026-04-24 10:58:02 +02:00
JailDesigner 82b229222f feat(hud): marcador de la franja superior amb 3 blocs i animació d'entrada 2026-04-23 23:46:41 +02:00
JailDesigner d0503ff8b1 feat(game_scene): integra PaintLayer i llegeix paint_tile del YAML del mapa 2026-04-23 13:31:13 +02:00
JailDesigner a612a8255f feat(editor): mode editor mínim amb toggle, border blau i mutex amb pausa 2026-04-23 12:09:04 +02:00
JailDesigner 459d18b49c feat(game): pausa amb F11/START i contorn NSEO al Text 2026-04-23 09:47:59 +02:00
JailDesignerandClaude Opus 4.7 64e0178ee9 refactor(game): COUP-02 inject MapInfo snapshot into Player
Afegit `Map::Info` (POD trivialment copiable) que empaqueta playfield,
pitch, grid, tile_size, tilemap_origin + 2 punters a funció (collides,
inside_playfield). `Map::makeInfo()` el construeix a partir dels globals
del namespace.

`Player` ara rep `const Map::Info&` al ctor i en guarda una còpia plana
(`map_`), substituint totes les lectures de `Map::*` per `map_.*`. La
inclusió `#include "game/map/map.hpp"` puja al header per la dependència
de `Map::Info`; player.cpp deixa d'incloure'l (transitiu).

Només el Player es desacobla — momies, roques i `loadFromLevel`
continuen llegint `Map::*` directament, com diu la nota original del
audit (mentre hi hagi un Map global actiu, l'acoblament és acceptable).
Si quan s'acabi PATCH-01 algun consumidor extra chirría, COUP-02b en
una rama nova.

Smoke tests 13/13 OK; log Game start → Bye! sota xvfb-run idèntic al
baseline. clang-tidy i cppcheck nets sobre els fitxers modificats.

Refs: docs/audit-game.md (COUP-02).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 08:46:34 +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