inv_gba
Thread Id: 27909
Thread Name: Pokémon Errantes [Investigación Fire Red y Esmeralda FINALIZADA!!]
#0
Razhier 28815
Lo primero, un saludo a todo el foro. Éste es mi primer mensaje y mi primera aportación al RH, espero que os sirva de ayuda.

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:



Además, nos encontramos con tres limitaciones:



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!!!
#1
wobba_ffet 12383
wow, que buena investigación, esta demasiado completa la verdad es que sera muy util, aunque no se si también lo hicieras para firered, que es la base mas popular del momento.
#2
G0LD_ZTHVARD0X! 27515
Veo que no eres tan novato en ASM, como sabras por aca casi nadie ocupa Esmeralda, y menos Español.

Para portearlo a Fire Red se me ocurre comparar la funcion del Special que activa a Latios con el de los perros legendarios de FR, en base a tu investigacion hallar las direcciones para Fire Red, vere si este finde puedo ponerme a trabajar en ello, pero gracias a ti por hacer la investigacion
#3
Razhier 28815
Gracias por comentar,

Sí, entiendo que Fire Red es la más usada. El caso es que empecé un pequeñísimo proyecto en el esmeralda, y claro, poco a poco ha ido creciendo...

Supongo que una vez conocido el procedimiento, es relativamente fácil llevarlo a FR. Con cambiar un par de offsets y un poco la rutina de ASM, en principio debería de funcionar.
#4
RedMort 26611
Mae mia, a esto le llamo yo mensaje de presentación, a ver si más gente sigue tu ejemplo xD.
Con respecto al aporte, yo tenía una idea en mi mente pero no tan pro xD
Gran investigación-tutorial, espero que sigas aportando, que te entretengas con nosotros y que alguien lo adapte a Ruby, o si no es muy dificil ya lo intentaré yo xD

Saludos, y bienvenido al foro! ^^
#5
Razhier 28815


¿Y os habéis fijado en ese pequeño "01" que hay debajo del 36? Pues bien, cuando vale 1 significa que el pokémon está disponible (vivo y salvaje), mientras que si vale 0 no nos lo podremos encontrar (debilitado o capturado).


- He intentado aplicar la rutina en firered. La variable de entrada, en vez de 0x8004, es la variable 0x4031, que tiene que ver con el pokémon inicial que elegiste. En cualquier caso, la rutina funciona, es decir, sustituye los valores del pokémon errante por los que nosotros queramos. Sin embargo, parece que el pokémon no cambia.
Pongo un ejemplo: estoy intentando cambiar a Entei (00F4) por Rayquaza (0196). La rutina consigue cambiar el 00F3 por el 0196, pero cuando miro la pokédex no me aparece el área de Rayquaza, pero sí la de Entei... Tampoco entiendo muy bien cómo funciona FR, así que si alguien más especializado que yo le interesa este tema, le agradecería que retomara la investigación.

Seguiré investigando, a ver si soy capaz de hacer más cositas :)[/SPOILER]
#6
Dani_SR_17 28493
Una investigación muy útil e impresionante, un trabajo magnífico, a ver si consigues entenderlo también en Fire Red.

Sobre lo que dijiste de los mapas, lo que se podría hacer es por ejemplo:
(No sé ASM, lo que te digo es con mis conocimientos de scripts normales)
Con scripts de nivel, al entrar en un determinado mapa comprobar en que mapa está el Pokémon (ya lo has predefinido antes en esa variable).
Y mediante un random, "seleccionar" uno de los mapas contiguos a dicho mapa. Y guardar en otra variable dicho mapa contiguo, al cambiar a otro mapa, usamos la variable del mapa contiguo y hacemos con lo que has explicado que el Pokémon en cuestión aparezca en dicho mapa contiguo, y así sucesivamente.

No sé si me he explicado bien, si no se entiende, lo puedo decir de otra forma ;)

PD: Bienvenido al foro.
#7
Razhier 28815
Iniciado por Dani_SR_17
Con scripts de nivel, al entrar en un determinado mapa comprobar en que mapa está el Pokémon (ya lo has predefinido antes en esa variable).
Y mediante un random, "seleccionar" uno de los mapas contiguos a dicho mapa. Y guardar en otra variable dicho mapa contiguo, al cambiar a otro mapa, usamos la variable del mapa contiguo y hacemos con lo que has explicado que el Pokémon en cuestión aparezca en dicho mapa contiguo, y así sucesivamente.


Se lo que quieres decir, a mí se me habia ocurrido algo parecido, con randoms y scripts de nivel. En principio es una buena idea y se podría hacer... Pero es muuuy tedioso hacer un script de nivel para cada mapa. Quiero saber si se puede hacer una rutina en ASM que se ejecute cada vez que cambias de mapa, y que haga eso mismo que tu dices (o algo parecido). Pienso que esta forma es mucho más eficiente, pero hasta entonces, con scripts de nivel nos las podemos apañar.
#8
Dani_SR_17 28493
Iniciado por Razhier
Se lo que quieres decir, a mí se me habia ocurrido algo parecido, con randoms y scripts de nivel. En principio es una buena idea y se podría hacer... Pero es muuuy tedioso hacer un script de nivel para cada mapa. Quiero saber si se puede hacer una rutina en ASM que se ejecute cada vez que cambias de mapa, y que haga eso mismo que tu dices (o algo parecido). Pienso que esta forma es mucho más eficiente, pero hasta entonces, con scripts de nivel nos las podemos apañar.


Realmente sería el mismo script para todos los mapas, lo jodio sería que habría que recrear mediante comparaciones el mapa con todas las zonas del Hack.


Un ejemplo. Tenemos el siguiente mapa:

-Pueblo Paleta - Ruta 1 - Ciudad Verde - Ruta 2
____ __ _ _ __- Ruta 3 -


Imagínate que aparece en "Ruta 1".

Primero hay que asignar un valor a cada zona, ejemplo.
Pueblo Paleta = 0
Ruta 1 = 1
Ciudad verde = 2
Ruta 2 = 3
Ruta 3 = 4

Hacemos una comparación de una variable para reconocer en que mapa esta.

En este caso estaría en "1".
Como está en uno, puede ir a 3 zonas: Pueblo Paleta, Ruta 3 o Ciudad Verde.
Usamos un "random 0x3", imagínate que sale 2.
Pues ahora en las variables para el siguiente mapa ponemos los datos de "Ruta 3".

Bien, empezamos en Pueblo Paleta y ya ha ocurrido eso, ahora vamos a "Ruta 1"
Vuelve a ejecutar el mismo script, ahora copiamos las variables de los datos de la "Ruta 3", para que aparezca en dicha ruta. Esta vez la variable de "posición" vale 4, y el único mapa posible desde ahí es "Ruta 1", luego ya sin random ni nada, almacenamos en las variables para el siguiente mapa los datos de "Ruta 1"

Y así sucesivamente.

Además es un método bastante eficiente.

Solo se usan:
- Las 2 variables que determinan el banco y el mapa en el que está actualmente el Poké en cuestión.
- Las 2 variables que determinan el siguiente banco y mapa.
- La variable para crear el "mapa" virtual.

Es más, podríamos suprimir incluso 2 variables de las anteriores.
#9
Razhier 28815
Visto así, es más fácil de lo que imaginaba. He hecho un script con tu ejemplo y no ha sido tan difícil:



Creo que era esto a lo que te referías, no? Una vez implantado el script en la ROM es tan fácil como hacer call 0xoffsetdelscript a la entrada de un nivel.


#10
Dani_SR_17 28493


Creo que era esto a lo que te referías, no? Una vez implantado el script en la ROM es tan fácil como hacer call 0xoffsetdelscript a la entrada de un nivel.

Gracias por la explicación, pensaba que era más complicado. He tardado nada en hacerlo, y cuando le coges el truco acaba siendo bastante simple. Esto puede servir de mucha ayuda :D

A ver si entre todos conseguimos hacerlo funcionar en firered, que esto tiene mucho potencial![/SPOILER]

Exacto, esa es la idea, y como ves es bastante sencillo :D
#11
Razhier 28815
EDITO: Este mensaje tenía muchas cosas de ASM que resulta que ya no son necesarias.
#12
Razhier 28815
Post principal actualizado!!
#13
Dani_SR_17 28493
Me alegro de que una investigación tan útil esté completa, que pena que por ahora no me sirva para mi hack...., aunque quizás le de algún uso pero a pequeña escala, como que un Pokémon ronde por ciertas zonas.

Pues eso, enhorabuena por completarla y me alegro de poder haber ayudado :D
#14
eing 12479
La investigación está muy bien,y la forma de hayar los datos me ha sorprendido.
Enhorabuena, de verdad.

Pero ahora viene la pregunta del millón .. ¿Cuantas veces habrás de poner ese script?
¿Una vez por cada pokémon errante? Y cuando tu pones la ruta, pones la ruta inicial, pero imagino que al hacer vuelo cambiará de ubicación, ¿no? En ese caso, ¿Para que asignarla si volverá a ser calculado?

Son duads que tengo, no te lo tomes a mal que me gustaría que me explicases, es que estoy perezoso..
#15
Jack Johnson 28130
Puedes solucionar el problema de la pokedex para varios errantes, si usas un objeto "detector de pokemon", que diga la zona según la variable.
#16
Razhier 28815
eing: Bueno, el script una vez que lo has hecho sólo lo tienes que poner una vez, y después tienes que guardarte el offset donde se ha puesto. Ahora es tan simple como pegar el offset en todos los mapas donde quieras que aparezca el pokémon, en nuestro ejemplo serían 5 mapas: pueblo paleta, ciudad verde, rutas 1 2 y 3. El script lo que hace es asignar la posición cada vez que entres en el mapa, independientemente de si entras andando normal y corriente, usando vuelo, por una puerta, saliendo de una cueva, o lo que sea.

Creo que a lo que te refieres es que si usas vuelo el pokémon aparecerá en otro mapa aleatorio fuera de las rutas 1 2 y 3, ¿no? Eso no importa, porque tenemos guardada la posición "virtual" en la variable 0x5000 que puede valer desde 0 (se encuentra en pueblo paleta) hasta 4 (se encuentra en la ruta 3). Cuando vuelvas a entrar digamos en la ruta 1 se ejecutará el script, que mira el valor de la variable 0x5000 para saber dónde está el pokémon dentro de nuestro "mapa virtual". A continuación elige uno de los mapas vecinos aleatoriamente, guarda la nueva posición virtual en la variable 0x5000 y asigna la nueva posición real independientemente de la posición actual del pokémon.

Un ejemplo: imagina que pones un Zapdos errante que se mueva por las zonas del ejemplo, y que ahora mismo se encuentra en Ciudad Verde (0x5000 = 2). Cuando vueles a Ciudad Celeste, aparecerá en una ruta aleatoria, imagina que es la ruta 17. Pero cuando entres en la ruta 2 se ejecutará el script, verá que la variable vale 2 y a partir de ahí calculará una nueva posición, que podrá ser de forma aleatoria la ruta 1 o la ruta 2. Igualmente, pasará lo mismo si vuelas a pueblo paleta o a ciudad verde, o si entras en las rutas 1 y 3.

Espero haberte aclarado la duda.

Un saludo!

Jack Johnson: una idea genial! tendría que ver cómo ejecutar scripts o rutinas de ASM desde el menú de objetos. Gracias!
#17
G0LD_ZTHVARD0X! 27515
Iniciado por Jack Johnson
Puedes solucionar el problema de la pokedex para varios errantes, si usas un objeto "detector de pokemon", que diga la zona según la variable.

Es una genial idea, pero la veo mas complicada ya que deberia de agregarse esa funcion ASM a la de los items existentes, para mi es mas viable solucionar el problema directamente y no metiendote a uno mas complicado.

Y la rutina sera muy util para muchos, aunque yo no piense usarla la veo genial.
#18
Natsu Dragneel 23919
Nice One!
Gran info para los que están haciendo un hack en estos momentos y tambien para los que van a hacer uno.
Ultimamente no he abierto las pouertas de mi hack, pero tal vez lo haga, otro dia.
Ahora estoy haciendo histórias.
#19
Razhier 28815
Post actualizado.

He descubierto que el pokémon errante se guarda en una serie de variables. Así que simplemente ejecutando un script con el comando "setvar" podemos definir al pokémon errante que nos encontramos. Este procedimiento es mucho más simple que todo lo que había antes de ASM, así que he editado el post principal y he quitado mucha información que ya no es relevante.

También me he dado cuenta de que, si ponemos varios errantes, no hace falta guardar los datos de vitalidad y estado, así que el script para cambiar entre dos pokémon errantes es más simple. Por otra parte esto provoca que al cambiar de errante el nuevo aparezca con la salud a tope, y no con la que tenía antes, pero esto tampoco es un gran problema. De hecho GameFreak ya tuvo ese problema con los pokémon y el PC, de tal forma que si guardas un pokémon en el PC y lo sacas automáticamente se curará, y ellos no hicieron nada para arreglarlo ^^.

Comentad con cualquier duda que tengáis!
#20
Dani_SR_17 28493
Iniciado por Razhier
Post actualizado.

He descubierto que el pokémon errante se guarda en una serie de variables. Así que simplemente ejecutando un script con el comando "setvar" podemos definir al pokémon errante que nos encontramos. Este procedimiento es mucho más simple que todo lo que había antes de ASM, así que he editado el post principal y he quitado mucha información que ya no es relevante.

También me he dado cuenta de que, si ponemos varios errantes, no hace falta guardar los datos de vitalidad y estado, así que el script para cambiar entre dos pokémon errantes es más simple. Por otra parte esto provoca que al cambiar de errante el nuevo aparezca con la salud a tope, y no con la que tenía antes, pero esto tampoco es un gran problema. De hecho GameFreak ya tuvo ese problema con los pokémon y el PC, de tal forma que si guardas un pokémon en el PC y lo sacas automáticamente se curará, y ellos no hicieron nada para arreglarlo ^^.

Comentad con cualquier duda que tengáis!


Ahora sí que seguramente use la investigación, me da una parece mu grande (entre otras cosas por el tiempo) aprender ASM y la verdad, no me gusta tocar cosas que no entiendo, y como no tengo ni idea de ASm, pues me da palo usar las cosas de ASM.

Es más, ya se donde usarla :blush:
Aunque no me gusta eso de no guardar el estado del Pokémon, pero vaya que la solución es sencilla :D

Bueno, pues gracias por el aporte, deberían pasar el post a "Tutoriales GBA", puesto que realmente ya es eso, un tutorial.
#21
Megascep_9 Kuchiki 28187
O_O ¡Que gran investigación y bastante útil!
Gracias por odo esto...¿extraño?...en serio no te
conozco XD.

Veo que eres bueno para estas cosas y me atrevería
a pedirte que investigues acerca del worldmap. Es que
muchos no sabemos casi nada de este tema.

Creeme, sería un gran aporte para el romhacking.
En fin gracias :D
#22
Tito Sayer301 26309
Estoo... Bienvenido!?!??!? jajajaja engorilante a mas no poder todo el asunto estoy deseando probarlo aunque me rayan algunos defectos que comentas pero bueeee no todo es perfecto en esta vida jajaja

En fin creo que para una investigación que se completa, merece la pena que se quede donde esta ajajajaja

saludos y espero que sigas trayendo aportes asi de impresionantes!
#23
Razhier 28815
Post actualizado!

He encontrado la tabla donde se calcula la nueva posición del pokémon errante. Editando la tabla y 3 bytes podemos definir las zonas donde se mueve el poke, sin necesidad de scripts ni nada.

Cualquier duda o problema, comenten!

Saludos!
#24
Dani_SR_17 28493
Iniciado por Razhier
Post actualizado!

He encontrado la tabla donde se calcula la nueva posición del pokémon errante. Editando la tabla y 3 bytes podemos definir las zonas donde se mueve el poke, sin necesidad de scripts ni nada.

Cualquier duda o problema, comenten!

Saludos!


Aunque me gusta el nuevo método, como quiero hacer que en diversas zonas puedan aparecer diferentes pokes errantes, creo que me quedaré con el método antiguo, ya que no me molesta nada hacer el mapa virtual, puesto que van a ser quizás solo por 6-8 zonas.

Aun así, un gran aporte ;)