From 605966fe258268c3474858cacee6d3c47a2328dc Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 18 May 2026 13:45:08 +0200 Subject: [PATCH] Fase 4: gos guardia (despertar, persecucio i mossegada) --- guante_blanco.lua | 114 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 107 insertions(+), 7 deletions(-) diff --git a/guante_blanco.lua b/guante_blanco.lua index 566f680..12adb10 100644 --- a/guante_blanco.lua +++ b/guante_blanco.lua @@ -40,6 +40,14 @@ RETARDO_STEP = 50 RUIDO_RND = 15 RUIDO_UMBRAL = 10 +-- AFTER de BASIC del CPC trabaja en 1/50 s (jiffies de 20 ms). El original +-- programa "AFTER retardo*4, 1 GOSUB 310" → retardo*4 jiffies = retardo*80 ms. +MS_POR_JIFFY = 20 + +-- Cada cuántos movimientos del jugador avanza el perro (línea 1650: perro +-- alterna 1,2 y solo se mueve cuando == 2 → 1 paso de perro cada 2 del jugador). +PERRO_RATIO = 2 + -- ============================================================ -- PALETA (mapeo CPC firmware → CGA disponible) -- Original: INK 0,0 (negro) / 1,26 (pastel) / 2,15 (blanco) / @@ -226,6 +234,16 @@ robado = 0 -- joyas recogidas por el ladrón mensaje_msg = "" -- mensaje de la fila inferior (Choque, etc.) retardo = RETARDO_INI +-- Perro guardián +perro = { + activo = false, -- perro==1 del original + rm = 0, -- habitación donde se activó + x = 0, y = 0, -- posición + paso = 0, -- alterna 0/1 para PERRO_RATIO (línea 1650) + pendiente = false, -- AFTER programado pero aún no disparado + pend_t = 0, -- time() en que se disparará el AFTER +} + -- ============================================================ -- CONSTRUCCIÓN DEL MAPA LÓGICO -- Por habitación se construye una matriz [x][y] con el tipo de @@ -383,6 +401,12 @@ function pintar_habitacion() end end + -- Perro (si está activo y comparte habitación con el ladrón) + if perro.activo and perro.rm == rm then + color(COL_PERRO, paper) + print(chr(GL_PERRO), perro.x + off_x, perro.y + off_y) + end + -- El ladrón color(COL_LADRON, paper) print(chr(hombre_glifo), xp + off_x, yp + off_y) @@ -487,7 +511,73 @@ function chocar_obstaculo() mensaje_msg = "Choque" if ruido >= RUIDO_UMBRAL and retardo > RETARDO_MIN then retardo = retardo - RETARDO_STEP - -- La activación del perro en sí la maneja la Fase 4. + -- AFTER retardo*4, 1 GOSUB 310 (línea 2160 del original) + programar_perro(retardo * 4 * MS_POR_JIFFY) + end +end + +-- ============================================================ +-- PERRO GUARDIÁN (líneas 310-330, 1650, 2560-2670 del original) +-- ============================================================ +function programar_perro(ms) + perro.pendiente = true + perro.pend_t = time() + ms +end + +-- Rutina 310 del original: activa el perro si no lo estaba ya. +function activar_perro() + if perro.activo then return end + perro.activo = true + perro.rm = rm + perro.x = HABITACIONES[rm].minx + perro.y = HABITACIONES[rm].miny + perro.paso = 0 + hombre_glifo = GL_LADRON_M -- línea 2570: hombre$ = chr(225) +end + +function hay_perro_en(rm_, x, y) + return perro.activo and perro.rm == rm_ and perro.x == x and perro.y == y +end + +-- Rutina 2560 del original: el perro se mueve 1 char hacia el jugador. +function mover_perro() + if not perro.activo then return end + if perro.rm ~= rm then return end -- solo activo en su habitación + + -- Si ya está sobre el jugador, mordido (línea 2580) + if perro.x == xp and perro.y == yp then + muerto = true + return + end + + if perro.x < xp then perro.x = perro.x + 1 + elseif perro.x > xp then perro.x = perro.x - 1 end + if perro.y < yp then perro.y = perro.y + 1 + elseif perro.y > yp then perro.y = perro.y - 1 end + + if perro.x == xp and perro.y == yp then + muerto = true + return + end + + sfx_ladrido() +end + +-- Llamada después de cada movimiento exitoso del jugador (línea 1650). +function tick_perro_post_jugador() + if not perro.activo then return end + if perro.rm ~= rm then return end + perro.paso = (perro.paso + 1) % PERRO_RATIO + if perro.paso == 0 then + mover_perro() + end +end + +-- Llamada cada frame: dispara la activación si ha vencido el AFTER. +function tick_perro_pendiente() + if perro.pendiente and time() >= perro.pend_t then + perro.pendiente = false + activar_perro() end end @@ -497,6 +587,7 @@ end function sfx_joya() sound(2000, 6) end function sfx_obstaculo(r) sound(3000, 5 + r) end function sfx_conm() sound(800, 3) end +function sfx_ladrido() sound(rnd(40) + 60, 6) end -- ============================================================ -- MOVIMIENTO Y CAMBIO DE HABITACIÓN @@ -553,6 +644,13 @@ end function mover_jugador(xf, yf) if xf == 0 and yf == 0 then return end local nx, ny = xp + xf, yp + yf + + -- Perro (gol=11): si la celda destino tiene el perro, mordido directo + if hay_perro_en(rm, nx, ny) then + muerto = true + return + end + local t = mapa[rm][nx][ny] -- Conmutador (gol=1..4): toggle luz, no se mueve @@ -588,6 +686,7 @@ function mover_jugador(xf, yf) xp, yp = nx, ny recoger_joyas_en(nx, ny) mensaje_msg = "" + tick_perro_post_jugador() return end @@ -597,15 +696,10 @@ function mover_jugador(xf, yf) return end - -- Perro (gol=11): mordido (Fase 4 implementa la consecuencia) - if t == T_PERRO then - muerto = true - return - end - -- Vacío: mover xp, yp = nx, ny mensaje_msg = "" + tick_perro_post_jugador() end -- ============================================================ @@ -625,6 +719,10 @@ function init() yp = 4 escapado = false muerto = false + hombre_glifo = GL_LADRON + perro.activo = false + perro.pendiente = false + perro.paso = 0 cls() end @@ -638,6 +736,8 @@ function update() return end + tick_perro_pendiente() + if (cnt() - ultimo_tic) >= TICS_JUGADOR then local xf, yf = 0, 0 if btn(KEY_UP) then yf = -1