Bueno, he estado entretenido haciendo los cambios necesarios para que cuando se mueva un bloque empujable este no borre el "fondo"
He partido de la Churrera 3.99.3b para ello. El método es básicamente lo que na_th_an propuso pero enfocado de otra manera para generalizar el método sin realizar cambios profundos en el motor y hacerlo compatible con juegos anteriores con sólo unos añadidos.
No se si será la mejor forma, y hay varias cosas que se pueden implementar mejor, pero aquí van:
**Recomiendo encarecidamente que hagais copia de vuestro directorio de juego antes de empezar con los cambios**1. Los tiles empujables tendrán que añadirse desde scripting. Esto lo he hecho así porque si se hace directamente desde el mapa el "suelo/fondo" cuando se carga la pantalla sería desconocido (¿que tile hay bajo el bloque empujable? ¿suelo? ¿una alfombra?). Así pues todo el "suelo/fondo" será conocido (pintado con Mappy/Tiled..) y posteriormente al entrar en una habitación colocariamos los tiles. Esto nos da además la elección de pintarlos o no dependiendo del resto de condiciones del script si así quisieramos. Ejemplo:$this->bbcode_second_pass_code('', 'ENTERING SCREEN 0
IF TRUE
THEN
SET TILE (3,6) = 14
SET TILE (3,4) = 14
END
END')
2. Modificar config.h . Definimos una nueva constante
MAX_PUSHABLE que representa el número máximo de bloques + 1 gestionables por pantalla. Puedes cambiar el valor, pero no os paseis. Aparte añado aquí (no creo que sea el mejor sitio para ponerla, quizás sería mejor en definitions.h, pero bueno, yo lo dejo ahí) la estructura PUSHABLES y una variable
pushables que no es más que un array de dicha estructura del tamaño de MAX_PUSHABLE. Añadir:$this->bbcode_second_pass_code('', '#define MAX_PUSHABLE 4 // donde 4 es el número máximo de bloques empujables por pantalla + 1
typedef struct {
unsigned char x, y, t;
} PUSHABLE;
PUSHABLE pushables [MAX_PUSHABLE];
unsigned char push_ord = 0;')
3. Copiar msc.exe modificado a \script\ . Para poder usar esta característica se tendra que hacer uso de la utilidad msc.exe modificada para ello donde se ha modificado el código del funcionamiento de SET TILE (desde tu churromain.spt). Si detecta que se trata de un tile empujable este se gestiona como de costumbre (actualizando tanto map_buff como map_attr) pero además guarda en la variable
pushables los datos del tile sobre el que se pinta (tile, x, y). Un indice cutre
push_ord se va incrementando segun se añaden los tiles empujables desde scripting. *Nota: por no añadir lineas innecesarias hay que tener en cuenta que si tu juego no va a usar tiles empujables no uses este msc.exe ya que tu tile 14 no se pintará.
4. Modificar engine.h . Para gestionar los tiles empujables se ha modificado la función
process_tile de manera que si se ha definido
MAX_PUSHABLE en lugar de mover el bloque y pintar el tile 0 se recorre la estructura
pushables buscando una equivlencia de x0 e y0 con la posición inicial del bloque empujable (iniciada con SET TILE automáticamente), se modifica map_buff y map_attr de x0 e y0 con los valores de
pushables (lo que había antes) y se pinta el "fondo/suelo", se actualiza
pushables con los valores de x1 e y1. pintar el bloque empujable en su nueva posicion x1 e y1 se hará con normalidad. Los cambios en la linea 552$this->bbcode_second_pass_code('', '
if (qtile (x0, y0) == 14 && attr (x1, y1) == 0 && x1 >= 0 && x1 < 15 && y1 >= 0 && y1 < 10) {
#if defined(ACTIVATE_SCRIPTING) && defined(ENABLE_PUSHED_SCRIPTING)
flags [MOVED_TILE_FLAG] = map_buff [15 * y1 + x1];
flags [MOVED_X_FLAG] = x1;
flags [MOVED_Y_FLAG] = y1;
#endif
// Mover
map_attr [15 * y1 + x1] = 10;
map_buff [15 * y1 + x1] = 14;
map_attr [15 * y0 + x0] = 0;
map_buff [15 * y0 + x0] = 0;
// Pintar
draw_coloured_tile (VIEWPORT_X + x0 + x0, VIEWPORT_Y + y0 + y0, 0);
draw_coloured_tile (VIEWPORT_X + x1 + x1, VIEWPORT_Y + y1 + y1, 14);
// Sonido')cambiar por$this->bbcode_second_pass_code('', '
if (qtile (x0, y0) == 14 && attr (x1, y1) == 0 && x1 >= 0 && x1 < 15 && y1 >= 0 && y1 < 10) {
#if defined(ACTIVATE_SCRIPTING) && defined(ENABLE_PUSHED_SCRIPTING)
flags [MOVED_TILE_FLAG] = map_buff [15 * y1 + x1];
flags [MOVED_X_FLAG] = x1;
flags [MOVED_Y_FLAG] = y1;
#endif
map_attr [15 * y1 + x1] = 10;
map_attr [15 * y0 + x0] = 0;
#ifdef MAX_PUSHABLE
// Comprobamos que bloque es
for (gpt=0; gpt<MAX_PUSHABLE; gpt++) {
if (pushables[gpt].x==x0 && pushables[gpt].y==y0) break;
}
map_buff [15 * y0 + x0] = pushables[gpt].t;
draw_coloured_tile (VIEWPORT_X + x0 + x0, VIEWPORT_Y + y0 + y0, pushables[gpt].t);
pushables[gpt].x = x1;
pushables[gpt].y = y1;
pushables[gpt].t = map_buff [15 * y1 + x1];
#else
map_buff [15 * y0 + x0] = 0;
draw_coloured_tile (VIEWPORT_X + x0 + x0, VIEWPORT_Y + y0 + y0, 0);
#endif
map_buff [15 * y1 + x1] = 14;
draw_coloured_tile (VIEWPORT_X + x1 + x1, VIEWPORT_Y + y1 + y1, 14);
// Sonido')
5. Modificar engine.h . "Gracias" a
push_ord tenemos que reiniciar dicha variable a 0 cuando cambiemos de pantalla. Para ello al final de
draw_scr justo bajo el #endif de la línea 1477$this->bbcode_second_pass_code('', '#ifdef PLAYER_CAN_FIRE
init_bullets ();
#endif')añadir $this->bbcode_second_pass_code('', '#ifdef MAX_PUSHABLE
push_ord=0;
#endif')
Creo que no me dejo nada
A continuación dejo el paquete con msc.exe + código fuente y engine.h (basado en la Churrera 3.99.3b) donde sólo se reflejan los cambios mencionados respecto a la versión origina del fichero. Si ya has hecho modificaciones en tu engine.h sigue los pasos explicados arriba (aunque estaran en otra linea) para no perder los cambios. Si veis algún error o cualquier cosa comentar por aquí.