El caso, que llevo tiempo buscando la forma de añadir Pokémon errantes al Esmeralda (en español, es la ROM que utilizo). He buscado en este foro y en foro de PokemonCommunity, y no he conseguido encontrar nada. Así que empecé a investigar la forma en que aparecían Latios y Latias en el juego. A continuación dejo los pasos que he seguido durante mi investigación, por si a alguien le interesa o le pueda servir de ayuda. Si sólo quieres saber cómo se meten pokémon errantes, sáltate este paso.
A nosotros nos interesa esta parte:
multichoice 0x16 0x8 0x6C 0x1
copyvar 0x8004 LASTRESULT
special 0x12B
copyvar 0x40D5 LASTRESULT
El special 0x12B tiene como variable de entrada la 0x8004. Lo que hace el special es lo siguiente: si 0x8004 es igual a 0, el pokémon errante que aparece es Latias; si es igual a 1, aparece Latios (por lo que he probado, cualquier valor distinto de 0 hace que aparezca Latios). La variable 0x40D5 no nos interesa, lo que hace es guardar el valor que hemos escogido para más tarde, en la isla del sur, que aparezca el pokémon que no hayamos elegido.
El special 0x12B nos lleva a la dirección 0x8161961 y ejecuta el código en ASM que se encuentra allí. Pensé que la información del pokémon que nos aparece se guardaba en alguna parte de ese código, pero he estado buscando y no he encontrado nada (aunque tampoco sé como funciona el código). El código en cuestión es éste:
Como no encontré nada buscando en el interior de la ROM, pasé a buscar en la memoria RAM. Para eso, hay que usar el buscador de cheats del emulador VBA (Ctrl + C). El valor de Latias en hexadecimal es 0x197, así que mi idea fue ejecutar el siguiente script:
#org @inicio
setvar 0x8004 0x0
special 0x12B
end
Que hace que aparezca Latias. Después de activar el special, busqué en el buscador de cheats el valor 0197, y me apareció la siguiente dirección:
Si abrimos el Tools > Memory Viewer, y nos vamos a esa dirección…
Parece ser que esos números tienen que ver con el pokémon errante que nos aparece. Algunos se pueden deducir a primera vista, otros he tenido que investigarlos un poco:
Azul: número del pokémon errante invertido (Latias: 197, que invertido es 97 01)
Verde: vitalidad actual. Cuando hieres a un pokémon errante y se escapa, la próxima vez que te lo encuentras sigue con la misma vida. Pues parece ser que es aquí donde se guarda ese valor (en HEX, por supuesto).
Amarillo: nivel del pokémon, 28 en hex es 40 en decimal.
Marrón: el estado del pokémon, que también se guarda de un combate a otro.
Naranja: disponibilidad del pokémon (1 = vivo y salvaje, 0 = capturado o debilitado)
Rojo: información encriptada que definen los valores iniciales, la naturaleza y posiblemente el género.
Visto esto, mi primera idea fue bien simple, sustituir el número 0197 por el valor del nuevo pokémon. Después de investigar un poco acerca de las flags y las variables noté que la memoria donde se aloja la información del pokémon errante coincide con la memoria usada para las variables, es decir, que los pokémon errantes se guardan en variables. Las variables son:
- Variable del pokémon: Esmeralda 0x4F24; RF 0x506C
- Variable de la vitalidad: Esmeralda 0x4F25; RF 0x506D
- Variable del nivel y estado: Esmeralda 0x4F26; RF 0x506E
- Variable de la disponibilidad (0x100 = disponible, 0x0 = no disponible) = Esmeralda 0x5F29; FR 0x5071
Así que en teoría podríamos elegir al pokémon errante sólo editando las variables de antes con "setvar". En mi caso empecé probando con un Raikou, cuyo valor es 00F3. Ejecutando el script:
#org @inicio
special 0x12B
setvar 0x4F24 0xF3
end
Debería de aparecernos un Raikou errante.
Efectivamente, nuestro script ha sustituido el 0197 por nuestro 00F3 que le habíamos dicho. Entonces… ¿Debería de aparecernos un Raikou errante? Vamos a consultar en la pokédex…
(Nota: para facilitar el proceso, antes programé un "wildbattle" contra un Raikou para que me saliera en la pokédex, y que después me diera una masterball):
Efectivamente aparece el área de Raikou en la pokédex, y además va cambiando cada vez que nos movemos. Pero y si lo buscamos, ¿que nos encontramos?
¡Toma, a la primera! ¡Nos ha salido un Raikou perfecto!
Ahora se pueden sustituir los valores del pokémon que nos encontramos por los que nosotros queramos usando sólo "setvar". Ésa es la sección que viene a continuación.
Bueno, el Raikou no es del todo perfecto... ¿Habéis notado ese trocito de vida que le falta? Eso es porque sólo he cambiado el pokémon que aparece, pero no la vida (¿os acordáis del 0076 que estaba marcado en verde? no es casualidad que 76 en HEX sea 118 en decimal). Por tanto, el pokémon tiene la misma vida que cuando era un Latias, y como Raikou tiene más vida máxima que Latias... ¿Entendéis?
De momento no he encontrado una solución permanente para esto. He provado a ponerle una vida mayor que la máxima, pero lo que pasa es que si hieres al pokémon, durante un tiempo parecerá que no le restas vida... Lo único que se me ocurre es que si quieres poner X pokemon al nivel Y, busques en una calculadora de estadísticas la vida que debería de tener a ese nivel con valores iniciales al máximo, para asegurarte de que no te quedas corto, y así tampoco te pasas mucho de la vida máxima.[/SPOILER]
Script del Pokémon Errante
Hacer que aparezca un pokémon errante es tan simple como ejecutar un script. En Esmeralda el special 0x12B hace que aparezca un pokémon errante u otro dependiendo del valor que hay en la variable 0x8004: si es 0, aparece Latias, y si es 1 aparece Latios. En FR se usa el special 0x129 y la variable de entrada que utiliza es la 0x4031, que es donde se guarda el pokémon inicial que escogiste, y hace que aparezca Raikou, Entei o Suicune. Lo que vamos a hacer es llamar al special, hacer que aparezca uno de éstos pokemon como errante y sustituirlo por el pokemon que queramos.
Los datos del pokémon errante se guardan en variables, así que conociendo estas variables podemos editar al pokémon errante como queramos. Concretamente, las variables son éstas:
- Variable del pokémon: Esmeralda 0x4F24; RF 0x506C
- Variable de la vitalidad: Esmeralda 0x4F25; RF 0x506D
- Variable del nivel y estado: Esmeralda 0x4F26; RF 0x506E
- Variable de la disponibilidad (0x100 = disponible, 0x0 = no disponible) = Esmeralda 0x5F29; FR 0x5071
Ahora explicaré qué significa cada variable y los pasos a seguir en Esmeralda, para Fire Red los pasos a seguir son idénticos. El script del pokémon es el siguiente:
Voy a explicar para qué sirve cada variable:
La primera indica el pokémon que nos aparecerá por la región. Por poner un ejemplo, yo quiero que me aparezca Raikou, cuyo número es F3, pues en mi caso pondré setvar 0x4F24 0xF3.
La segunda determina la vida con la que nos encontramos al pokémon. Esto es muy importante, porque un valor muy alto provocaría que, al herir al pokémon, durante un tiempo su vida no decrezca (dependiendo de lo mucho que te hayas pasado de su vida máxima), y con un valor bajo te encontraías al pokémon con escasa vida. Para elegir un valor adecuado, podéis usar la siguiente calculadora Pokéxperto; Calculadora DS/Advance de IV's & Stats
Eliges el pokémon, su nivel, y a la derecha donde dice Resultados, en PS escribes 31, y pulsa "calcular stats"
A mí me ha salido a la izquierda, en PS, 165. Pues paso este valor a hexadecimal (165 = A5 en HEX) y ya está. Lo que tengo que poner es setvar 0x4F25 0xA5.
La tercera variable es complicada. En una misma variable se guarda el nivel y el estado (envenenamiento, parálisis...). El nivel es simple: escoge un nivel de 1 a 100 y lo pasas a hexadecimal. En mi caso quiero que salga al 50, que en HEX es 32, luego YY = 32. El estado es algo difícil; si no te interesa modificar el estado, ignora el siguiente spoiler y haz XX = 00.
Para poner un estado, escribe ocho ceros:
00000000
Esto es un número binario de ocho bits, donde cada uno puede tomar un valor entre 0 y 1. La tabla indica, para un número de 8 bits, qué estado aplica cada bit, leído de derecha a izquierda. Por ejemplo, este número
00001000
Tiene el cuarto bit igual a 1, y el resto 0. Según la tabla, el cuarto bit es envenenamiento, así que nuestro pokémon con este código estará envenenado (Notad que la tabla dice 3 para Poison, no 4, pero hay que tener en cuenta que empieza a contar desde 0, no desde 1).
Si por ejemplo, aplicamos este código
00010000
El quinto bit indica quemado, es decir, nos encontraremos al pokémon quemado. También podemos mezclar algunos estados, por ejemplo:
01100000
Hará que el pokémon esté congelado, y cuando se descongele estará paralizado.
El sueño ocupa 3 bits. Esto es porque además determina los turnos que quedan para que el pokémon se despierte. Por ejemplo, 001 en binario es 1, así que el próximo turno se despertará; 101 en binario es 5, así que dormirá durante 5 turnos, etc...
Vale, muy bonito esto de los bits, pero… ¿cómo se aplica?
Simple. Una vez que tengas tu código de 8 cifras en binario, lo pasas de binario a hexadecimal en la calculadora. Yo quiero que mi Raikou esté congelado. El código para congelamiento es 00100000, que en hexadecimal es 20. Por tanto, XX = 20.
Entiendo que este procedimiento es bastante confuso. Si no te ha quedado claro y tienes alguna duda, deja tu pregunta en los comentarios ;)
Nota: Si lo que tienes pensado es dormir o congelar al pokémon para que no se escape... Olvídate, porque se va a escapar igualmente. Y si no, que le pregunten a este pobre hombre ... (min 8:00) Pokémon FireRed - Episode 37 - Suicune - YouTube[/SPOILER]
La variable 0x4F29 indica si el pokémon está disponible (0x100 salvaje y vivo) o no (0x0 debilitado o capturado). Cuando llamas al "special" este valor es automáticamente 0x100, así que en principio no hace falta tocarlo. Lo que sí puede servir es para saber si ya hemos capturado o debilitado al pokémon (para interactuar con la historia de nuestro hack o cosas así).
A modo de ejemplo, mi script queda de la siguiente forma:
#org inicio
special 0x12B
setvar 0x4F24 0xF3
setvar 0x4F25 0xA5
setvar 0x4F26 0x2032 'o si no quieres poner ningún estado, simplemente 0x32
end
Ejecutamos el script y...
...
Vaya, parece que no ha pasado nada. Sin embargo, yo me he adelantado y antes programé un wildbattle contra Raikou para que me apareciera en la Pokédex. El resultado es el siguiente...
o.O
o.O o.O o.O o.O o.O
¡¡Funciona!!
Bueno, si y no. Todavía queda investigar las zonas donde aparece, y poder hacer que aparezca más de un pokémon errante a la vez. Pero... yo diría que es un buen comienzo, ¿no te parece? :)
Aquí dejo algunos ejemplos más, donde se ve que tampoco hace falta poner siempre la vida máxima al pokémon:
Editando la localización
Para esta parte recomiendo que tengáis experiencia manejando editores hexadecimales. Cuando ejecutes el script de antes, el pokémon errante aparecerá por unos mapas específicos que están predefinidos en la ROM. Concretamente hay una tabla que indica las rutas por donde se mueve el poke:
Cada fila de la tabla tiene la siguiente información:
- Primer byte: nº de mapa en hex donde se encuentra el pokémon.
- Resto de bytes: nº de mapa en hex donde estará el pokémon cuando cambiemos de mapa.
- FF: todos los bytes que sean FF son ignorados.
Además, nos encontramos con tres limitaciones:
- El nº de filas de la tabla indica el nº máximo de posibles localizaciones del pokémon. Por ejemplo, en esmeralda la tabla tiene 20 filas, así que el poke no podrá aparecer en más de 20 rutas. Ésta limitación se puede saltar.
- El ancho de la tabla - 1 indica el nº máximo de rutas a las que puede estar conectada una ruta. En esmeralda cada fila tiene 6 bytes, pues como máximo una ruta podrá estar conectada a 6 - 1 = 5 posibles rutas. Ésta limitación no se puede saltar.
- Cada fila tiene como mínimo 3 bytes distintos de FF. Es decir, cada ruta está conectada como mínimo con otras 2. Esto tiene una explicación curiosa, resulta que la rutina que calcula el área del pokemon errante está programada para que el poke no pueda aparecer donde tú estuviste hace 2 localizaciones. De esta forma se evita eso de alternar constantemente entre dos rutas hasta que aparezca el poke. Si un pokémon solo puede ir de una ruta a otra, y tu estuviste en esa ruta hace 2 mapas, el juego se queda pillado. Ésta limitación se puede saltar, pero requiere conocimientos de ASM y no lo recomiendo.
Ya estamos en condiciones de editar la localización. Para editar esta tabla hará falta un editor hexadecimal, yo utilizo HxD. Primero debes tener una idea de las zonas donde se moverá el poke. Yo haré que el poke se mueva por este mapa (cortesía de Dani_SR_17):
-Pueblo Paleta - Ruta 1 - Ciudad Verde - Ruta 2
____ __ _ _ __- Ruta 3 -
Abre Advance Map y apunta el nº de cada mapa, y conviértelos a hexadecimal con la calculadora de windows:
Pueblo Paleta: 0 --> 0
Ciudad verde: 1 --> 1
Ruta 1: 19 --> 13
Ruta 2: 20 --> 14
Ruta 3: 21 --> 15
Ahora tenemos que hacer la tabla. Tenemos 5 localizaciones, así que la tabla tendrá 5 filas. No os preocupéis por el número de filas, podéis poner hasta 256 (LOL). Cada fila empieza con una localización, y los números siguientes son las localizaciones a las que se puede mover el poke. Mi tabla queda así:
00 13
01 13 14
13 00 01 15
14 01
15 13
Pero esta tabla puede hacer que el juego se trabe, porque hay filas con sólo 2 bytes y el mínimo es 3. En efecto, pueblo paleta y las rutas 2 y 3 sólo tienen una conexión, y el mínimo son 2 conexiones. Así que conectaré la ruta 2 con pueblo paleta y la ruta 3 con ciudad verde:
00 13 14
01 13 14
13 00 01 15
14 01 00
15 13 01
Rellena de FF hasta que cada fila tenga 7 bytes en FR, o hasta 6 bytes en esmeralda:
00 13 14 FF FF FF FF
01 13 14 FF FF FF FF
13 00 01 15 FF FF FF
14 01 00 FF FF FF FF
15 13 01 FF FF FF FF
Ya tenemos nuestra tabla lista. Ahora abre la ROM con tu editor hexadecimal y ve al offset donde se encuentra la tabla. Si tu tabla es más corta que la tabla original (como es mi caso), simplemente pégala sobreescribiendo la tabla original, y rellena de FF hasta borrar por completo la tabla anterior.
Si es más grande tendrás que buscar un espacio libre en la ROM terminado en 0, 4, 8, o C. El offset A00003 está vacío, pero no es válido porque termina en 3, pero el offset A00000 sí que nos sirve. Imaginemos que vas a pegar tu tabla en A00000. Ahora tendrás que hacer un repoint. Si usas HxD, ve a Buscar -> Reemplazar... Busca los pointers 58 6C 46 08 en FR, o 04 1A 5D 08 en esmeralda, y en reemplazar escribe el offset donde hayas puesto tu tabla, pero invertido: A00000 -> 00 00 A0 08. Tipo de datos: valores hexadecimales, Dirección Todo, y cuando esté todo listo Reemplazar todo.
El último paso es decirle a la rutina la nueva longitud de la tabla. ¿Habéis visto que la tabla de FR mide 25 filas? 25 en hex es 19. Hay 3 bytes que indican el nº de filas de la tabla, aquí se indica la dirección donde se encuentran:
La nueva longitud de la tabla es 5 filas, que en hex es 5 :D Así que cambiamos esos tres bytes por sus nuevos valores:
En 141d6e: 05
En 141df6: 05
En 141eae: 04
Y listo, ya hemos definido los mapas por donde se mueve el pokemon errante.
Hay que tener en cuenta que todos los números de mapa están referidos al banco 0 en esmeralda y al banco 3 en FR. Es decir, que nuestro poke sólo se podrá mover por los mapas del banco 0 en esmeralda y el banco 3 en FR. Si por algún motivo quieres que aparezca en un mapa fuera de ese banco (una cueva, una casa, la zona safari...) puedes ejecutar el siguiente script a la entrada del mapa:
Pero al cambiar de mapa el pokémon volverá a rondar por las rutas de la tabla.
Varios Pokémon Errantes
Con lo que se ha explicado hasta ahora sería bastante para hacer que aparezca el pokémon errante que quieras en el estado que quieras y donde quieras. Pero parece que hay una pequeña limitación... y es que el juego no está pensado para que aparezca más de un pokémon errante a la vez. Así que en principio hacer que aparezca más de un pokémon errante a la vez no es posible. Pero bueno, tampoco hace falta llevarse las manos a la cabeza. Lo que sí podemos hacer es elegir el pokémon que aparece en cualquier momento, con sólo ejecutar un script.
Pondré un ejemplo: imagina que quieres que aparezcan un Lugia y un Ho-ho errantes por tu región, y que puedas elegir en cualquier momento cuál de los dos aparece. Primero tendrás que asignarle una flag a cada pokémon para establecer si ya se ha capturado o debilitado, en mi ejemplo la de Ho-ho es la 0x1100 y la de Lugia la 0x1101. Ahora puedes hacer que hayan dos personajes (o carteles, o lo que sea), de tal forma que el primero haga aparecer a Lugia y el segundo a Ho-ho. El script para el primero sería algo así:
El script para el segundo sería parecido. Este script es simple y te permite tener dos pokémon errantes, de tal forma que el jugador elige cuál de los dos quiere capturar en cualquier momento. Desafortunadamente no guarda los datos de vitalidad y estado, así que cuando se cambie a Lugia por Ho-ho o viceversa volverán a tener la vida máxima y ningún problema de estado (es decir, se "curarán"). Esto tampoco es un gran problema, si quieres guardar la salud del pokémon tendrías que guardar su vitalidad y estado en dos variables con el comando "copyvar". Pero por ejemplo en mi hack ya hay 6 pokémon errantes diferentes, si quisiera que se guardaran el estado y vit. de cada pokémon me harían falta 12 variables, y los script serían eternos. Así que no guardar el estado el errante es mucho más fácil de hacer y además tampoco supone un gran problema.
Si quieres que tus pokemon errantes aparezcan por rutas distintas, te recomiendo que uses el script que se explica al final de esta página. Así, puedes hacer que cada pokémon aparezca por rutas distintas.
¿Te ha parecido complicado? ¿No lo has entendido? ¿Se te ha ocurrido una idea pero no sabes cómo llevarla a cabo? Pues no te lo pienses y déjame un comentario, que estaré encantado de ayudarte :)
FIN
El humano (?)
Para terminar, me gustaría aclarar que para los que uséis FR (que sereis la mayoría) hay un pequeño cabo suelto en mi investigación. Resulta que si buscáis en la pokédex el área del pokémon errante no aparecerá. Sin embargo sí que os saldrá el área de uno de los tres perros legendarios. De momento no he podido cambiar ese pequeño gran detalle, y me temo que no puedo asegurar que consiga arreglarlo... Si sois capaces de aceptar este defecto entonces no tendréis ningún problema. Aquí unas imágenes, donde se ve que aunque el área que aparece en la pokédex es la de Raikou, si lo buscamos nos encontramos al pokémon que hemos definido con la rutina:
Y creo que nada mas... Espero haberte ayudado a hacer lo que querías en tu hack. Pero si no has conseguido lo que querías ya sabes, ¡¡coméntamelo!! Lo único que te pido a cambio es que si has seguido este tutorial me menciones en los créditos de tu hack (que aunque antes ya era chulo, ahora que has metido esto seguro que te ha quedado mejor :D)
Gracias a todos los que os habéis tragado este tocho ;) Y sobre todo a esta comunidad, que aunque éste sea mi primer mensaje he aprendido todo lo que sé de RH gracias a todos los tutoriales, las preguntas y las respuestas que hacéis continuamente.
Si os queda alguna duda, o veis algún fallo, mandadme un MP o comentadlo!!
Un saludo!!!