Registrarse

Mapas y Scripting

Estado
Cerrado para nuevas respuestas.

Laquin

Usuario mítico
Abro este tema para empezar una nueva investigación sobre el funcionamiento de las distintas partes de los mapas y el scripting en pokeruby.

Todos los números que pondremos en los archivos .inc se podrán poner tanto en decimal como en hexadecimal. Si queremos usarlo en hex, deberemos poner un 0x por delante del número. En decimal, no hace falta poner nada adicional.

El correcto uso de mayúsculas y minúsculas es esencial para no tener problemas al compilar el juego.

Mayormente, estaremos utilizando los siguientes archivos:
  • connections.inc, events.inc, header.inc, scripts.inc y text.inc, que se encuentran en data/maps/NombreDelMapa/.
  • layout.inc, que se encuentra en data/maps/layouts/NombreDelMapa/.

La única herramienta que necesitaremos sera un editor de texto(que no sea Word), preferiblemente un IDE. Hay decenas de distintos IDEs que podéis utilizar: Notepad++, Visual Studio, Sublime Text, etc. También podrá venirnos bien PretMap, aunque haré referencias al A-Map y XSE para comparar nombres y demás.

Los eventos se guardan en el archivo events.inc. Estos se dividen en los cinco grupos a continuación.
Son los eventos de objetos: las personas, árboles de corte, pokéballs del suelo, etc. Siguen la siguiente sintaxis a la hora de crearlos:
Código:
object_event NúmeroDeEvento, Sprite, ??, X, Y, Z, TipoDeMovimiento, XDeMovimiento, YDeMovimiento, Trainer, IDDeBaya/RangoDeVisión, Script, Flag
Vayamos por partes:
  • object_event: Simplemente es para decirle al compilador el tipo de evento que vamos a crear. Siempre lo dejaremos igual.
  • NúmeroDeEvento: Es una especie de número de identificación que le daremos a cada evento. En el A-Map es «Person Event no», y en el PretMap es el número que sale justo a la derecha del sprite del evento.
  • Sprite: El minisprite/overworld que usaremos para el evento. Puede ser el de un chico, una anciana, el del profesor o incluso el del rival. En el archivo .inc, al igual que en PretMap, los nombres de los sprites empezarán por EVENT_OBJ_GFX_ (Los podéis buscar de manera cómoda en el PretMap), aunque podéis sustituirlo por el número que os saldría en el A-Map al lado de «Picture no.».
  • ??: No tengo ni idea, sinceramente. No lo veo ni en el PretMap ni en el A-Map.
  • X: La coordenada X del evento en el mapa.
  • Y: La coordenada Y del evento en el mapa.
  • Z: La altura del evento. Se usa por si queremos poner, por ejemplo, que esté encima o debajo de un puente. En el A-Map sería el «Talking level».
  • Tipo de movimiento: Que esté mirando para la derecha, andando hacia arriba y hacia abajo, etc. En el archivo .inc, al igual que en PretMap, los nombres de los movimientos empezarán por MOVEMENT_TYPE_ (Los podéis buscar de manera cómoda en el PretMap), aunque podéis sustituirlo por el número que os saldría en el A-Map al lado de «Movement type:», (siempre y cuando pongáis un 0x por delante o lo paséis a decimal, como ya he explicado anteriormente).
  • XDeMovimiento e YDeMovimiento: En los eventos con tipos de movimientos dinámicos (como moverse desde arriba hacia abajo, o andar en círculos), cómo de lejos se puede ir en el eje X y en el eje Y. Por ejemplo, en el camino de bicis, hay un ciclista moviéndose en círculos. Tiene como XDeMovimiento puesto 10, 1 como YDeMovimiento, y en el tipo de movimiento pone que se moverá como las agujas del reloj. Eso quiere decir que irá 10 bloques a la izquierda, luego uno hacia arriba, 10 hacia la derecha y 1 hacia abajo.
  • Trainer: 0 o FALSE si no es un entrenador, TRUE o cualquier otro número si sí lo es. En el PretMap aparece como «Movement Radius X/Y», y en el Advance Map como «Movement».
  • IDDeBaya/RangoDeVisión: Cada baya tiene un número de identifiación. Esto hace que todas las bayas sean independientes: una puede estar recien sembrada mientras que otra es cosechable. Cada baya tendrá un número distinto. ¿Y si no es una baya? Puede que sea un trainer. En ese caso, este parámetro se utilizará para poner a cuánta distancia puede un entrenador verte. (Si pone 5, y estás a 6 bloques, no vas a entrar en combate). En PretMap es «Sight Radius / Berry Tree ID», y en A-Map es «View Radius». Si no es ni una baya ni un trainer, se pondrá 0.
  • Script: El nombre del scrip. En A-Map es «Script Offset».
  • Flag: Se utilizará, entre otros, para hacer desaparecer eventos de manera permanente. En PretMap es «Event Flag», y en A-Map es «Person ID».
Por ejemplo, el evento del rival en la ruta 103, el primer combate que haces con él:
Código:
 object_event 2, EVENT_OBJ_GFX_VAR_0, 0, 10, 2, 3, MOVEMENT_TYPE_FACE_UP, 0, 0, 0, 0, Route103_EventScript_14EB92, FLAG_HIDE_RIVAL_ROUTE103
EVENT_OBJ_GFX_VAR_0 es el sprite del rival (es chico o chica dependiendo de lo que elegiste), y FLAG_HIDE_RIVAL_ROUTE103 es la flag que hace que el rival desparezca una vez hayas combatido con él.

Si, por lo que sea, hay un parámetro que no necesitemos (como el rango de visión si no es una baya o un entrenador, por ejemplo), se tendrá que poner un 0(0x0 en hexadecimal) en su lugar. Así, la sintaxis seguirá siendo respetada.
Son los warps de toda la vida, que nos llevan a otro warp (normalmente de un mapa distinto, aunque no tiene por qué). Utilizan la siguiente sintaxis:
Código:
warp_def X, Y, Z, NúmeroDeWarpDestino, MapaDestino
  • warp_def: Simplemente es para decirle al compilador el tipo de evento que vamos a crear. Siempre lo dejaremos igual.
  • X: La coordenada X del evento en el mapa.
  • Y: La coordenada Y del evento en el mapa.
  • Z: La altura del evento. Se usa por si queremos poner, por ejemplo, que esté encima o debajo de un puente. Por norma general, se usará el valor 0. En el A-Map sería el «Talking level».
  • NúmeroDeWarpDestino: La idea del warp es llevarnos a otro warp, por lo que tenemos que poner a cuál Warp nos va a llevar (pues puede haber más de un warp en un mismo mapa). El PretMap nos dice cuál es el número del Warp. Sin embargo, tenemos que restarle 1 a ese número. Veámoslo mejor con un ejemplo:
  • MapaDestino: Es el mapa al que nos va a llevar el warp. Todos los nombres empiezan por MAP_. Podéis buscar el nombre completo en la carpeta data/maps. Por ejemplo, si queremos ir a la primera casa de OldaleTown, miramos en la carpeta y pone que es OldaleTown_House1. Luego, al crear el warp pondremos MAP_OLDALE_TOWN_HOUSE1. Todo en mayúsculas y poniendo guiones bajos entre el nombre y TOWN (Básicamente, si en la carpeta una palabra empieza por mayúscula, se tendrá que hacer eso: TradeCenter pasa a ser TRADE_CENTER, puesto que Center empieza por mayúscula). No, no hace falta escribir el banco del mapa ni nada por el estilo.
Por ejemplo, tenemos el warp que nos lleva al Centro Pokémon de Oldale Town:
Código:
 warp_def 15, 16, 0, 0, MAP_OLDALE_TOWN_HOUSE2
Uno de los que nos lleva al Bosque Petalia:
Código:
 warp_def 10, 30, 3, 0, MAP_PETALBURG_WOODS
O incluso la de la casa del buscatesoros, en la ruta 124:
Código:
 warp_def 70, 48, 3, 0, MAP_ROUTE124_DIVING_TREASURE_HUNTERS_HOUSE
También conocidos como scripts de gatillo, son aquellos eventos que se activan en el momento en que pasas por encima suyo. Por ejemplo, en Littleroot Town hay scripts de gatillo que te impiden salir del pueblo antes de hablar con el rival, que te obligan a salvar al profesor, etc. Hay más tipos de eventos dentro de los MapCoordEvents, pero la sintaxis principal es la siguiente:
Código:
coord_event X, Y, Z, Variable, Valor, Script
  • coord_event: Simplemente es para decirle al compilador el tipo de evento que vamos a crear. Siempre lo dejaremos igual.
  • X: La coordenada X del evento en el mapa.
  • Y: La coordenada Y del evento en el mapa.
  • Z: La altura del evento. Se usa por si queremos poner, por ejemplo, que esté encima o debajo de un puente. En el A-Map sería el «Talking level».
  • Variable: Las variables son espacios de memoria reservadas para almacenar valores. En el Pokémon Ruby (y todos los demás juegos de la tercera generación de Pokémon), las variables pueden tener un valor del 0 al 65 535 (0xFFFF).
  • Valor: Al pisar un evento de este tipo, el juego va a comparar el valor de la variable con el valor que le pongamos en este parámetro. Si es igual, se ejecutará. (Por ejemplo, si la variable vale 3 y ponemos un 2 en el valor del evento, no se ejecutará. Si en otro momento la variable vale 2, al pisarla se volvera a comparar y esta vez sí se ejecutará).
  • Script: El nombre del script que queremos que se ejecute.
Por ejemplo, este es el evento que ejecuta el script que nos impide salir de Littleroot Town al principio del juego(y también el que nos hace ir a salvar al profesor):
Código:
 coord_event 11, 1, 3, VAR_LITTLEROOT_STATE, 1, LittlerootTown_EventScript_14D7C7
Mediante distintos scripts, conseguimos que la variable VAR_LITTLEROOT_STATE deje de tener el valor 1, y es entonces cuando podemos pasar sin que no se ejecute ningún script.
Son los eventos de postes, carteles, etc. Esta es su sintaxis principal:
Código:
bg_event X, Y, Z, Condición, Script
  • bg_event: Simplemente es para decirle al compilador el tipo de evento que vamos a crear. Siempre lo dejaremos igual.
  • X: La coordenada X del evento en el mapa.
  • Y: La coordenada Y del evento en el mapa.
  • Z: La altura del evento. Se usa por si queremos poner, por ejemplo, que esté encima o debajo de un puente. En el A-Map sería el «Talking level».
  • Condición: Realmente no sabía bien cómo nombrar a este parámetro. Intentaré explicarme lo mejor posible. Estos eventos se ejecutan dependiendo de la dirección a la que mires. Por ejemplo veamos el siguiente BGEvent:

    Es obvio que el jugador sería incapaz de leer lo que pone si se mira desde la derecha. Para evitar esas cosas, lo que hacemos es decirle que solo se ejecuten si estamos mirando hacia arriba, poniendo BG_EVENT_PLAYER_FACING_NORTH (Todos empiezan por BG_EVENT_).
  • Script: El nombre del script que queremos que se ejecute.
Como ejemplo, pondré el mismo evento que he puetso arriba:
Código:
 bg_event 8, 16, 0, BG_EVENT_PLAYER_FACING_NORTH, OldaleTown_EventScript_1A00EA
Simplemente es un tipo de evento que, por decirlo de alguna manera, recopila los eventos del mapa. Luego en el header, en lugar de poner en él todos los grupos de eventos vistos anteriormente, simplemente le pondremos el MapEvent. Por ejemplo, el de Oldale Town:
Código:
 map_events OldaleTown_EventObjects, OldaleTown_MapWarps, OldaleTown_MapCoordEvents, OldaleTown_MapBGEvents
Hay que tener en cuenta que hay mapas que no cuentan con todos los tipos de eventos. Por ejemplo, la ruta 105 no tiene eventos de tipo MapBGEvent. En ese caso, para no romper la sintaxis, se debe poner un 0(0x0 en hexadecimal) en el sitio del tipo de evento que falte. Así se vería, verbigracia, el MapEvent de la ruta 105:
Código:
map_events Route105_EventObjects, Route105_MapWarps, 0x0, Route105_MapBGEvents
También es apreciable que los eventos se agrupan por estos tipos. Así, todos los eventos objeto estarán dentro de un mismo grupo, todos los warps estarán dentro de otro grupo, etc.
Los nombres de los grupos se forman juntando el nombre del mapa y el tipo de evento. Tomemos como ejemplo el mapa de Oldale Town:
  • OldaleTown_EventObjects::
  • OldaleTown_MapWarps::
  • OldaleTown_MapCoordEvents::
  • OldaleTown_MapBGEvents::
  • OldaleTown_MapEvents::
Nótese que, a diferencia de como se debe hacer con los Warps, aquí los mapas se ponen exactamente como aparecen en sus carpetas; con mayúscula inicial en cada palabra y, por lo general, sin guiones bajos entre estas.
Además, hay que tener en cuenta que el «::» es fundamental; si no lo ponemos, el compilador nos lanzará un mensaje de error y no compilará la ROM.
Aparte de eso, en el events.inc, también sale «@ Offset» justo después del «::». No le daremos importancia. Los de después de la arroba son comentarios ignorados por el compilador, por lo que no nos serán necesarios. (No obstante, los comentarios son muy importantes a la hora de programar, para poder entender el código con mayor facilidad. Se usarán cuando aporten algún tipo de beneficio).
Con todo esto, ya podemos entender los archivos events.inc de Pokeruby. Por ejemplo, el del pueblo que he mencionado arriba:
Código:
OldaleTown_EventObjects:: @ 8380A78
	object_event 1, EVENT_OBJ_GFX_GIRL_3, 0, 16, 11, 3, MOVEMENT_TYPE_FACE_LEFT, 0, 0, 0, 0, OldaleTown_EventScript_14DDB3, 0
	object_event 2, EVENT_OBJ_GFX_MART_EMPLOYEE, 0, 13, 7, 3, MOVEMENT_TYPE_FACE_DOWN, 0, 0, 0, 0, OldaleTown_EventScript_14DDBC, 0
	object_event 3, EVENT_OBJ_GFX_MANIAC, 0, 8, 9, 3, MOVEMENT_TYPE_FACE_RIGHT, 0, 0, 0, 0, OldaleTown_EventScript_14DEDF, 0
	object_event 4, EVENT_OBJ_GFX_VAR_0, 0, 11, 19, 3, MOVEMENT_TYPE_FACE_UP, 1, 1, 0, 0, OldaleTown_EventScript_14DF30, FLAG_HIDE_RIVAL_OLDALE_TOWN

OldaleTown_MapWarps:: @ 8380AD8
	warp_def 5, 7, 0, 0, MAP_OLDALE_TOWN_HOUSE1
	warp_def 15, 16, 0, 0, MAP_OLDALE_TOWN_HOUSE2
	warp_def 6, 16, 0, 0, MAP_OLDALE_TOWN_POKEMON_CENTER_1F
	warp_def 14, 6, 0, 0, MAP_OLDALE_TOWN_MART

OldaleTown_MapCoordEvents:: @ 8380AF8
	coord_event 0, 10, 3, VAR_ROUTE102_ACCESSIBLE, 0, OldaleTown_EventScript_14DEFF
	coord_event 8, 19, 3, VAR_OLDALE_STATE, 1, OldaleTown_EventScript_14DF41
	coord_event 9, 19, 3, VAR_OLDALE_STATE, 1, OldaleTown_EventScript_14DF5C
	coord_event 10, 19, 3, VAR_OLDALE_STATE, 1, OldaleTown_EventScript_14DF77

OldaleTown_MapBGEvents:: @ 8380B38
	bg_event 11, 9, 0, BG_EVENT_PLAYER_FACING_ANY, OldaleTown_EventScript_14DDAA
	bg_event 7, 16, 0, BG_EVENT_PLAYER_FACING_NORTH, OldaleTown_EventScript_1A00EA
	bg_event 15, 6, 0, BG_EVENT_PLAYER_FACING_NORTH, OldaleTown_EventScript_1A00E1
	bg_event 8, 16, 0, BG_EVENT_PLAYER_FACING_NORTH, OldaleTown_EventScript_1A00EA
	bg_event 16, 6, 0, BG_EVENT_PLAYER_FACING_NORTH, OldaleTown_EventScript_1A00E1

OldaleTown_MapEvents:: @ 8380B74
	map_events OldaleTown_EventObjects, OldaleTown_MapWarps, OldaleTown_MapCoordEvents, OldaleTown_MapBGEvents
Y, por supuesto, no os hace falta nada más para crear un evento propio. Tan solo se debe seguir la sintaxis adecuada, y colocar el evento en el grupo que le corresponda.
Las conexiones se guardan en el archivo connections.inc. Al abrir el archivo, veremos dos partes:
Es donde se declaran las conexiones. Se debe utilizar la siguiente sintaxis para cada conexión:
Código:
connection tipoDeConexión, Desplazamiento, Mapa
  • connection: Es para decirle al compilador que se va a declarar una conexión. No debe cambiarse.
  • TipoDeConexión: Un mapa puede tener seis tipos de conexiones: up (por arriba), down (por abajo), left (por la izquierda), right (por la derecha), dive (sumergiéndose en el agua usando buceo) y emerge (emergiendo del agua usando buceo).
  • Desplazamiento: Es la cantidad de bloques que va a haber entre el punto cero del mapa principal y el punto cero del mapa conectado. Por ejemplo, en la conexión entre la ruta 116 y Verdanturf Town, el desplazamiento es de 80:
    Y en la conexión entre Lavaridge Town y la ruta 112, el desplazamiento es -40:
    ¿Por qué en uno positivo y en otro negativo?
    • En las conexiones de derecha e izquierda, el punto cero será el bloque número 0 del eje Y. Si el punto cero del mapa principal está más arriba que el del conectado, el desplazamiento será positivo. (Y si está por debajo, será negativo).
    • En las conexiones de arriba y abajo, el punto cero será el bloque número 0 del eje X. Si el punto cero del mapa principal está más a la izquierda que el del conectado, el desplazamiento será positivo. (Y si está más a la derecha, será negativo).
    Podéis volver a observar las imágenes, y veréis que el punto cero de la ruta 116 está, efectivamente, a la derecha que el de Verdanturf Town, por lo que el desplazamiento es positivo.
    En cambio, el punto cero de Lavaridge Town está por debajo que el de la ruta 112, por lo que el desplazamiento es negativo.
  • Mapa: El nombre del mapa conectado, exactamente como se hacía en los eventos de tipo warp:
    Todos los nombres empiezan por MAP_. Podéis buscar el nombre completo en la carpeta data/maps. Por ejemplo, si queremos ir a la primera casa de OldaleTown, miramos en la carpeta y pone que es OldaleTown_House1. Luego, al crear el warp pondremos MAP_OLDALE_TOWN_HOUSE1. Todo en mayúsculas y poniendo guiones bajos entre el nombre y TOWN (Básicamente, si en la carpeta una palabra empieza por mayúscula, se tendrá que hacer eso: TradeCenter pasa a ser TRADE_CENTER, puesto que Center empieza por mayúscula).
Aquí tendremos que poner únicamente dos cosas:
  • .4byte N, donde N es la cantidad de conexiones del mapa.
  • .4byte Mapa_MapConnectionList, donde «Mapa» es el nombre del Mapa, tal y como sale en la carpeta del mapa. (A diferencia de en el parámetro «Mapa» a la hora de crear una conexión, aquí se pone con mayúscula inicial en cada palabra y, por lo general, sin guiones bajos entre estas).
Un ejemplo de un connections.inc es el de Underwater3:
Código:
Underwater3_MapConnectionsList:: @ 8308D5C
	connection emerge, 0, MAP_ROUTE127
	connection left, 0, MAP_UNDERWATER2
	connection down, 0, MAP_UNDERWATER4

Underwater3_MapConnections:: @ 8308D80
	.4byte 0x3
	.4byte Underwater3_MapConnectionsList
Hay que tener en cuenta que el «::» es fundamental; si no lo ponemos, el compilador nos lanzará un mensaje de error y no compilará la ROM.
Aparte de eso, después del «::», también sale «@ Offset». No le daremos importancia. Los de después de la arroba son comentarios ignorados por el compilador, por lo que no nos serán necesarios. (No obstante, los comentarios son muy importantes a la hora de programar, para poder entender el código con mayor facilidad. Se usarán cuando aporten algún tipo de beneficio).
Tampoco está demás aclarar que un mapa puede tener más de una conexión del mismo tipo. Por poner un ejemplo, la ruta 111 tiene dos conexiones a la izquierda:
Código:
Route111_MapConnectionsList:: @ 8308974
	connection down, 0, MAP_MAUVILLE_CITY
	connection left, 0, MAP_ROUTE113
	connection left, 20, MAP_ROUTE112

Route111_MapConnections:: @ 8308998
	.4byte 0x3
	.4byte Route111_MapConnectionsList
Por último, recomendaría usar PretMap para crear las conexiones, más que nada para no tener que andar calculando manualmente el desplazamiento correcto. Además, la herramienta nos ofrece una manera de hacer que, si creas una conexión en un mapa, se cree la conexión desde el otro mapa también. Es decir; si se crea una conexión en el connections.inc de la ruta 111 que lleva a la ruta 112, se debe también crear la conexión desde la ruta 112 a la ruta 111, algo que la herramienta ofrece hacer de manera automática.

Iré actualizando a medida que vaya aprendiendo cosas nuevas.

¡Saludos!
 
Última edición:

Laquin

Usuario mítico
Respuesta: Re: Investigación GBA | Pokeruby | Mapas y Scripting

I will just wait for Pokeemerald...
Actually, Pokeemerald works in a rather similar way to Pokeruby, so it may also be helpful for this one.

------------------------------------------------------------------------

He actualizado con explicaciones acerca de las conexiones entre mapas:
Las conexiones se guardan en el archivo connections.inc. Al abrir el archivo, veremos dos partes:
Es donde se declaran las conexiones. Se debe utilizar la siguiente sintaxis para cada conexión:
Código:
connection tipoDeConexión, Desplazamiento, Mapa
  • connection: Es para decirle al compilador que se va a declarar una conexión. No debe cambiarse.
  • TipoDeConexión: Un mapa puede tener seis tipos de conexiones: up (por arriba), down (por abajo), left (por la izquierda), right (por la derecha), dive (sumergiéndose en el agua usando buceo) y emerge (emergiendo del agua usando buceo).
  • Desplazamiento: Es la cantidad de bloques que va a haber entre el punto cero del mapa principal y el punto cero del mapa conectado. Por ejemplo, en la conexión entre la ruta 116 y Verdanturf Town, el desplazamiento es de 80:
    Y en la conexión entre Lavaridge Town y la ruta 112, el desplazamiento es -40:
    ¿Por qué en uno positivo y en otro negativo?
    • En las conexiones de derecha e izquierda, el punto cero será el bloque número 0 del eje Y. Si el punto cero del mapa principal está más arriba que el del conectado, el desplazamiento será positivo. (Y si está por debajo, será negativo).
    • En las conexiones de arriba y abajo, el punto cero será el bloque número 0 del eje X. Si el punto cero del mapa principal está más a la izquierda que el del conectado, el desplazamiento será positivo. (Y si está más a la derecha, será negativo).
    Podéis volver a observar las imágenes, y veréis que el punto cero de la ruta 116 está, efectivamente, a la derecha que el de Verdanturf Town, por lo que el desplazamiento es positivo.
    En cambio, el punto cero de Lavaridge Town está por debajo que el de la ruta 112, por lo que el desplazamiento es negativo.
  • Mapa: El nombre del mapa conectado, exactamente como se hacía en los eventos de tipo warp:
    Todos los nombres empiezan por MAP_. Podéis buscar el nombre completo en la carpeta data/maps. Por ejemplo, si queremos ir a la primera casa de OldaleTown, miramos en la carpeta y pone que es OldaleTown_House1. Luego, al crear el warp pondremos MAP_OLDALE_TOWN_HOUSE1. Todo en mayúsculas y poniendo guiones bajos entre el nombre y TOWN (Básicamente, si en la carpeta una palabra empieza por mayúscula, se tendrá que hacer eso: TradeCenter pasa a ser TRADE_CENTER, puesto que Center empieza por mayúscula).
Aquí tendremos que poner únicamente dos cosas:
  • .4byte N, donde N es la cantidad de conexiones del mapa.
  • .4byte Mapa_MapConnectionList, donde «Mapa» es el nombre del Mapa, tal y como sale en la carpeta del mapa. (A diferencia de en el parámetro «Mapa» a la hora de crear una conexión, aquí se pone con mayúscula inicial en cada palabra y, por lo general, sin guiones bajos entre estas).
Un ejemplo de un connections.inc es el de Underwater3:
Código:
Underwater3_MapConnectionsList:: @ 8308D5C
	connection emerge, 0, MAP_ROUTE127
	connection left, 0, MAP_UNDERWATER2
	connection down, 0, MAP_UNDERWATER4

Underwater3_MapConnections:: @ 8308D80
	.4byte 0x3
	.4byte Underwater3_MapConnectionsList
Hay que tener en cuenta que el «::» es fundamental; si no lo ponemos, el compilador nos lanzará un mensaje de error y no compilará la ROM.
Aparte de eso, después del «::», también sale «@ Offset». No le daremos importancia. Los de después de la arroba son comentarios ignorados por el compilador, por lo que no nos serán necesarios. (No obstante, los comentarios son muy importantes a la hora de programar, para poder entender el código con mayor facilidad. Se usarán cuando aporten algún tipo de beneficio).
Tampoco está demás aclarar que un mapa puede tener más de una conexión del mismo tipo. Por poner un ejemplo, la ruta 111 tiene dos conexiones a la izquierda:
Código:
Route111_MapConnectionsList:: @ 8308974
	connection down, 0, MAP_MAUVILLE_CITY
	connection left, 0, MAP_ROUTE113
	connection left, 20, MAP_ROUTE112

Route111_MapConnections:: @ 8308998
	.4byte 0x3
	.4byte Route111_MapConnectionsList
Por último, recomendaría usar PretMap para crear las conexiones, más que nada para no tener que andar calculando manualmente el desplazamiento correcto. Además, la herramienta nos ofrece una manera de hacer que, si creas una conexión en un mapa, se cree la conexión desde el otro mapa también. Es decir; si se crea una conexión en el connections.inc de la ruta 111 que lleva a la ruta 112, se debe también crear la conexión desde la ruta 112 a la ruta 111, algo que la herramienta ofrece hacer de manera automática.

¡Saludos!
 

L!no

GBA Developer
Re: Investigación GBA | Pokeruby | Mapas y Scripting

Buena investigaciòn
cabe resaltar que en include/macros/events.inc estan las definiciones de todos los comandos del juego y que en scripts.inc estan todos los scripts, que tienen una sintaxis parecida a la de XSE
 

Laquin

Usuario mítico
Respuesta: Re: Investigación GBA | Pokeruby | Mapas y Scripting

Buena investigaciòn
cabe resaltar que en include/macros/events.inc estan las definiciones de todos los comandos del juego y que en scripts.inc estan todos los scripts, que tienen una sintaxis parecida a la de XSE
¡@L!no! Me has dado la vida con esto. He estado mirando el tema de las macros, y realmente serán de gran utilidad sin ninguna duda. Además, supongo que se podrán crear macros propias, lo que implicaría también la posibilidad de crear comandos para el scripting, quizás para simplificar el código. Algo así como las funciones en programación. Sin duda habrá que mirar eso más profundamente.

No tenía pensado traer nada hoy, pero casi por casualidad me he dado cuenta de que, además de los que puse en el post principal, existen más tipos de eventos. Si bien no parecen existir más grupos, dentro de estos hay distintos tipos de eventos. Por ejemplo, dentro del grupo de los MapCoordsEvents existe otro tipo de evento aparte del coord_event, que sería coord_weather_event. He mirado la macros de los eventos (include/macros/map.inc), y parece ser que hay bastantes más. Tomará más tiempo del que esperaba en un principio xD
 

L!no

GBA Developer
Respuesta: Investigación GBA | Pokeruby | Mapas y Scripting

es exactamente lo que yo estoy intentando xD
sobre las funciones, dataso: hay un comando 'func foo' que llama a la funcion nativa de C guardada bajo el nombre de foo.

todavia no se donde se deberia guardar 'foo', pero seguro en scrcmd.c

Enviado desde mi SM-G531M mediante Tapatalk
 

Laquin

Usuario mítico
Respuesta: Investigación GBA | Pokeruby | Mapas y Scripting

es exactamente lo que yo estoy intentando xD
sobre las funciones, dataso: hay un comando 'func foo' que llama a la funcion nativa de C guardada bajo el nombre de foo.

todavia no se donde se deberia guardar 'foo', pero seguro en scrcmd.c

Enviado desde mi SM-G531M mediante Tapatalk
He mirado la macros y ese comando se compila en 0x23, que coincide con el callasm de XSE, lo cual tiene mucho sentido. Las rutinas C se compilan en rutinas ASM. Nosotros estamos trabajando con el código en sí, descompilado, por lo que llamará a una rutina de C. El XSE, en cambio, trabaja con una ROM ya compilada, por lo que no tendrá rutinas C sino rutinas ASM.

De todos modos, según he mirado, el comando es callnative y func es el parámetro, ¿no?
 

L!no

GBA Developer
Respuesta: Investigación GBA | Pokeruby | Mapas y Scripting

ups. mala mia. ahora mismo no tenia el codigo a mano.

Enviado desde mi SM-G531M mediante Tapatalk
 

Laquin

Usuario mítico
Respuesta: Investigación GBA | Pokeruby | Mapas y Scripting

es exactamente lo que yo estoy intentando xD
sobre las funciones, dataso: hay un comando 'func foo' que llama a la funcion nativa de C guardada bajo el nombre de foo.

todavia no se donde se deberia guardar 'foo', pero seguro en scrcmd.c

Enviado desde mi SM-G531M mediante Tapatalk
De hecho, la función la puedes guardar en cualquier archivo dentro de src/. Sin embargo, he probado a crear test.c, y no me reconocía la función (aun habiendo creado test.h también en include/).

Esto me lleva a pensar que tiene que haber un sitio donde estén escritos los distintos ficheros donde debería buscar la función.

Y, después de un rato de investigación, lo puedo confirmar. Es el archivo ld_script.txt. A partir de la línea 40, están escritos los archivos donde debería buscar la función, con extensión .o (archivos creados en el proceso de compilación).

Así que, si creamos un archivo test.c en src/, debemos venir a ld_script.txt, y escribir test.o en esa lista. Luego, compilamos, y ya.

Ahora bien, no he conseguido pasar parámetros a las funciones llamadas con callnative. Se me ocurre una cosa. Si, por ejemplo, queremos pasar el valor 2 como parámetro de la función test(), usar las variables que siempre hemos usado en scripting (las cuales se declaran en include/constants/vars.h). Quizás podríamos declarar variables temporales y, de alguna manera, usarlas en la función. De hecho, las variables del 0x8000 al 0x800B son variables especiales, y se usan básicamente como parámetros.

Algo como poner setvar VARIABLE, 1, y luego en la función hacer referencias a la misma de alguna forma. (De hecho, me suena que así se hacía con el callasm).

EDITO: Hay más comandos para llamar a funciones: callnative, gotonative, special. También existe specialvar, que corre la función y devuelve el valor (con un return;).

Para usar las variables en las rutinas C:
#include "event_data.h"

Ahí están declaradas las variables. Para la prueba, he hecho una función que cambia la velocidad de texto dependiendo de valor de la variable VAR_SPECIAL_0. El script en sí se vería así:
Código:
Route101_Script_Test::
	setvar VAR_SPECIAL_0, 2 @Guarda el valor 2 en la variable 0x8000
	callnative test @Llama a la función test()
	end @Acaba el script
Y, en mi archivo test.c he puesto lo siguiente:
Código:
#include "global.h"
#include "constants/vars.h"
#include "event_data.h"

void test(){
    switch(gSpecialVar_0x8000){
        case 0: //Si gSpecialVar_0x8000 es igual a 0
            gSaveBlock2.optionsTextSpeed = OPTIONS_TEXT_SPEED_SLOW; //La velocidad de texto será lenta
            break;
        case 1: //Si gSpecialVar_0x8000 es igual a 1
            gSaveBlock2.optionsTextSpeed = OPTIONS_TEXT_SPEED_MID; //La velocidad de texto será media
            break;
        case 2: //Si gSpecialVar_0x8000 es igual a 2
            gSaveBlock2.optionsTextSpeed = OPTIONS_TEXT_SPEED_FAST; //La velocidad de texto será rápida
            break;
    }
}
Como le hemos dado el valor 2, la velocidad de texto se pondrá en rápido:
 
Última edición:
Estado
Cerrado para nuevas respuestas.
Arriba