Registrarse

[ASM] FR | Evolucionar a un Pokémon con ASM.

Rubire4

Usuario mítico
En este tutorial veremos cómo evolucionar a un Pokémon directamente con la llamada de una rutina desde un script, sin tener que cumplir necesariamente la condición de evolución del Pokémon.

Créditos por la rutina a jiangzhengwenjzw, de Pokécomunity.
Dejo el link original del tutorial por si alguien lo quiere ver: The PokéCommunity Forums - View Single Post - Development: ASM Resource Thread

Lo primero que tenemos que hacer es compilar la siguiente rutina, e insertarla en cualquier espacio vacío de nuestra ROM que acabe en 0, 4, 8 o C:
(Cómo habrá dos rutinas a ésta la llamaré rutina A.)
.thumb
push {r4, lr}
ldr r0, =0x300537C
ldr r1, =0x80568E1
str r1, [r0]
ldr r0, =0x020370C0
ldrh r1, [r0, #2]
mov r2, #1
ldrh r3, [r0, #0x10]
ldr r4, =0x80cdda9
bl bx_r4
pop {r4, pc}
bx_r4: bx r4
Rutina compilada para vagos:
Código:
10 B5 06 48 06 49 01 60 06 48 41 88 01 22 03 8A 05 4C 00 F0 01 F8 10 BD 20 47 00 00 7C 53 00 03 E1 68 05 08 C0 70 03 02 A9 DD 0C 08
Es muy importante apuntar dónde están insertadas las rutinas.​

Ahora tenemos que compilar e insertar esta otra:
(La cual llamaré Rutina B.)
.thumb
push {r4, lr}
mov r4, #0
loop:
ldr r0, =0x02024284
mov r1, #0x64
mul r1, r4
add r0, r0, r1
mov r1, #0xb
ldr r2, =0x803FBE9
bl bx_r2
ldr r1, =0x20370C0
ldrh r2, [r1]
cmp r0, r2
beq have_pre
add r4, #1
cmp r4, #6
bne loop

no_pokemon:
mov r4, #0xFF
b back

increment:
add r4, #1
cmp r4, #6
Rutina compilada:
Código:
10 B5 00 24 09 48 64 21 61 43 40 18 0B 21 08 4A FF F7 FE FF 07 49 0A 88 90 42 FE D0 01 34 06 2C F0 D1 FF 24 FE E7 01 34 06 2C 00 00 84 42 02 02 E9 FB 03 08 C0 70 03 02

Una vez insertadas las dos rutinas, tendremos que hacer el script para evolucionar.
Lo dejo aquí con indicaciones:
#dynamic 0x700000

#org @inicio
lock
faceplayer
setvar 0x8004 0x_ 'Aquí iría el número del Pokémon en Hexadecimal que quieres Evolucionar
setvar 0x8005 0x_ 'Aquí iría el número del Pokémon en Hexadecimal que saldrá de la evolución
callasm 0xRutina B+1 'Aquí hay que poner la dirección en la que insertamos la Rutina B y le sumamos 1
compare 0x800D 0xFF 'Checkea si tienes el Pokémon en el equipo
if1 1 @NoTienesElPokémon
callasm 0xRutina A+1 'Aquí iría la Rutina A, la cual sirve para evolucionar
waitstate 'Espera a que se acabe la evolución
'Puedes seguir con el script si quieres.
release
end

#org @NoTienesElPokémon
msgbox @Texto 0x6
release
end

#org @Texto
= No tienes el Pokémon
Si hemos hecho todo bien debe quedar así:

 
Última edición:

Nunk

Usuario de plata
Excelente aporte. Sólo tengo una duda: se puede hacer que la evolución no pueda ser cancelada pulsando el botón B?
 

Zhyruk

Usuario de platino
Excelente aporte. Sólo tengo una duda: se puede hacer que la evolución no pueda ser cancelada pulsando el botón B?
IMG_20230727_000822.jpg

 

Nunk

Usuario de plata
Ver el archivo adjunto 14821
Esa modificación es para evitar que la evolución se cancele si el jugador no tiene la pokédex nacional, pero sigue siendo posible cancelarla pulsando B. Gracias de todas formas :D
 

MAIDEN

SkyBlue
Podrías utilizar un script como solución alternativa. Por ejemplo, en el mismo script donde activas la rutina debes hacer un "check pokémon" donde si la evolución del Pokémon no se encuentra en el equipo entonces la rutina se vuelve ejecutar, entrando en un bucle hasta que la evolución suceda.
Para comprobar si un Pokémon está en el equipo se utiliza el "special2 0x17C"
Código:
setvar 0x8004 0x(Pokémon en Hex)
special2 LASTRESULT 0x17C
compare LASTRESULT 0x1
En palabras de nuestro amigo @FEL!X
Con el primer setvar cargas en 0x8004 la especie que quieres comprobar. Después lo que te hace el special es cargar en el LASTRESULT un valor que será 1 en caso de que tengas el pokemon y 0 en caso de que no lo tengas. Después es hacer un compare para lo que tu quieras de ese evento.
¡Suerte!
 

Nunk

Usuario de plata
Podrías utilizar un script como solución alternativa. Por ejemplo, en el mismo script donde activas la rutina debes hacer un "check pokémon" donde si la evolución del Pokémon no se encuentra en el equipo entonces la rutina se vuelve ejecutar, entrando en un bucle hasta que la evolución suceda.
Para comprobar si un Pokémon está en el equipo se utiliza el "special2 0x17C"
Código:
setvar 0x8004 0x(Pokémon en Hex)
special2 LASTRESULT 0x17C
compare LASTRESULT 0x1
En palabras de nuestro amigo @FEL!X


¡Suerte!
¡Gracias! Eso también podría usarse como como alternativa para la Rutina B, no es así?
 

MAIDEN

SkyBlue
¡Gracias! Eso también podría usarse como como alternativa para la Rutina B, no es así?
Por supuesto, sin embargo acabo de recordar otro método más eficiente...
Existe la posibilidad de "bloquear" cualquier botón en cualquier momento.
Puedes bloquear el botón "B" antes de ejecutar la rutina de evolución y restaurarlo una vez que el Pokémon haya evolucionado.

Código:
1) Insertar "Rutina 1°" en un offset nuevo:
F0 B4 08 48 00 88 08 4C 21 68 00 29 05 D0 00 F0 0F F8 00 F0 2B F8 00 F0 39 F8 F0 BC 01 1C 03 48 00 47 00 00 30 01 00 04 EC F4 03 02 EF 05 00 08 03 B5 04 22 0A 40 00 2A 11 D0 09 4D 2B 78 01 2B 0D D0 62 88 02 40 00 2A 09 D1 06 4B 1A 68 06 4B 9A 42 04 D1 01 22 2A 70 A0 68 00 F0 1F F8 03 BD 9C 0F 00 03 90 50 00 03 0D 9E 07 08 00 B5 01 22 0A 40 00 2A 09 D0 62 78 00 2A 06 D0 01 3A 62 70 0E 3C 22 88 0E 34 D2 43 10 40 00 BD 00 B5 02 22 0A 40 00 2A 01 D0 22 69 10 43 00 BD 00 49 08 47 E5 9A 06 08

2) Insertar "Rutina 2°" en otro offset nuevo:
07 B5 04 48 04 4A 11 88 01 82 01 78 02 22 11 43 01 70 07 BD EC F4 03 02 C0 70 03 02

3) Ir al Offset "0005EC" y cambiar los bytes "01 88" por "00 47"

4) Ir al Offset "000624" y cambiar los bytes"30 01 00 04" por "(Rutina 1°)+1 08"
PD: El offset de la rutina debe estar permutado.

5) Ir al Offset "160088" y cambiar los bytes "C1 AD 0C 08" por "(Rutina 2°)+1 08"
PD: El offset de la rutina debe estar permutado.

6) En un script escribir:
setvar 0x8004 0x(No° Botón)
special2 0x8004 0xCA

Lista de botones:
00: Desbloquea
01: A
02: B
04: Select
08: Start
10: Derecha
20: Izquierda
40: Arriba
80: Abajo
100: R
200: L
Esta vez los créditos son para @JPAN por la rutina.
 

eMMe97

Usuario de platino
Ho fatto una prova molto veloce, mettendo insieme le routine di jiangzhengwenjzw e di Blah.
La routine che ho creato permette di scegliere quale pokémon in squadra evolvere attraverso la var 8004.
Per scegliere la specie del pokémon è possibile utilizzare il metodo indicato da
MAIDEN
e quindi verificare la presenza di una certa specie. Oppure, in alternativa, è possibile utilizzare lo special 0x9F (scelta di un pokémon nel menù squadra).
Il pokémon scelto sarà evoluto, tramite la sua consueta evoluzione, senza dover impostare altro. Saranno conservate tutte le caratteristiche di quel pokémon (nickname, abilità, etc).

BUG per il momento presenti:
1) se si prova ad evolvere un pokémon giunto all'ultima evoluzione, il gioco si blocca;
2) nel caso di più evoluzioni (es. eevee), sarà scelta sempre la prima evoluzione.

Negli aggiornamenti della routine risolverò questi due problemi.

Vi lascio la routine:

.text
.align 2
.thumb
.thumb_func

main:
push {r0-r7, lr}
ldr r0, =0x020370C0 @calculate address of Pokemon we want to evolve
ldrh r0, [r0]
mov r4, r0
mov r1, #0x64
mul r0, r0, r1
ldr r1, =(0x2024284)
add r0, r0, r1
mov r7, r0
mov r1, #0xB
ldr r3, =(0x803FBE8 +1) @get current species, prior to evolving
bl linker
ldr r5, =0x020370C0
strh r0, [r5]
bl getEvolvedForm @check what species it evolves into
ldr r6, =0x020370C2
strh r0, [r6]
ldr r0, =0x300537C
ldr r1, =0x80568E1
str r1, [r0]
ldr r0, =0x020370C0
ldrh r1, [r0, #2]
mov r2, #1
mov r3, r4
ldr r4, =0x80cdda9 @animazione
bl bx_r4
b end

getEvolvedForm:
mov r1, #0x28 @calculate the evolution of a species
mul r1, r1, r0
ldr r3, = (0x8259754)
add r1, r3, r1
ldrh r0, [r1, #0x4] @evolution
bx lr

end:
pop {r0-r7, pc}

linker:
bx r3

bx_r4: bx r4

.align 2
 
Arriba