Registrarse

[ASM] FR, E | Sistema de EV's en Entrenadores.

Gold

Porrero a tiempo parcial
Miembro insignia
Durante estos días me puse a jugar un poco algunos hackroms que han salido últimamente, puedo decir que en todos los que jugué los autores han querido incrementar la dificultad, pero em vez de ello lo que han hecho es hacer nada divertida la dificultad de los mismos, usando métodos como:

• Darle a los entrenadores Pokémon de stats altísimos en partes tempranas de la historia.
• Hacer la curva de niveles absurdamente alta.
• Buffear los stats de muchos Pokémon.
• Darle a la IA Pokémon con movimientos ilegales o muy rotos respecto a su temprana aparición (Como Porygon con Psíquico)

Siempre quize buscar alternativas para mejorar la dificultad, y justo me topé con que Doesntknowhowtoplay hizo una rutina ASM que nos da la posibilidad de darle puntos de esfuerzo (EV) a los pokémon de los entrenadores, lo incluye también darle valores individuales (IV) e incluso naturaleza. En los juegos de tercera generación solo los entrenadores del frente de batalla tienen asignados Pokémon con EV específicos (Por eso son más difíciles que un entrenador común)

Para saber más sobre los EV puedes leer aquí: https://pokemon.fandom.com/es/wiki/Puntos_de_esfuerzo

¿Qué hacer para tener esta opción?

Lo primero es convertir esta rutina a binario e insertarla en nuestra ROM. Si obtienes un archivo binario de 15MB significa que se compiló correctamente.

Fire Red:
Código:
#Formato de tabla de EV específico
#Cada tabla tiene 0xF bytes (16 bytes)
#0x0 = Naturaleza
#0x1-0x3 = Bytes vacíos (00)
#0x4 = IVs (desde 0-31, no 0-255, usado para todos los IVs)
# (si quieres Poderes Ocultos, recuerda que la AI no puede manejar -- movimientos por pb)
#0x5 = PS EVs
#0x6 = Atq EVs
#0x7 = Def EVs
#0x8 = Vel EVs
#0x9 = At. Esp EVs
#0xA = Def. Esp EVs
#0xB = Pokeball
#0xC-0xF - Últimos 4 bytes son bytes vacios (00)

.align 2
.thumb
.thumb_func

.org 0x115f6
mov r0, r1
mov r6, r0
b 0x11604

.org 0x1162c
ldr r0, .Method_Addr
bx r0

[color=red].Method_Addr: .word 0x08F90001[/color]

.org 0x3dc70
b 0x3dcd0


[Color=red].org 0xF90000[/color]

LoadItem:
add r5, #0x6
add r0, r4, #0x0
mov r1, #0xc
add r2, r5, #0x0
bl Insert_Element

LoadHPEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x5
mov r1, #0x1A
mov r0, r4
bl Insert_Element

LoadAtkEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x6
mov r1, #0x1B
mov r0, r4
bl Insert_Element

LoadDefEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x7
mov r1, #0x1C
mov r0, r4
bl Insert_Element

LoadSpeedEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x8
mov r1, #0x1D
mov r0, r4
bl Insert_Element

LoadSAtkEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x9
mov r1, #0x1E
mov r0, r4
bl Insert_Element

LoadSDefEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0xA
mov r1, #0x1F
mov r0, r4
bl Insert_Element

LoadBall:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0xB
mov r1, #0x26
mov r0, r4
bl Insert_Element

StartNatureLoop:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
ldrb r5, [r2, #0x0]
cmp r5, #0x0
beq LoadIVs
ldr r0, [r4, #0x0]
ldr r1, [r4, #0x4]
eor r1, r0, r1
str r1, [r4, #0x4]

NatureLoop:
ldr r0, [r4, #0x0]
add r0, r0, #0x18
str r0, [r4, #0x0]
mov r1, #0x19
bl Mod
cmp r0, r5
bne NatureLoop

EndNatureLoop:
ldr r0, [r4, #0x0]
ldr r1, [r4, #0x4]
eor r1, r0, r1
str r1, [r4, #0x4]

LoadIVs:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
ldrb r6, [r2, #0x4]
push {r6}

StartIVLoop:
mov r5, #0x27

IVLoop:
mov r0, r4
mov r1, r5
mov r2, sp
bl Insert_Element
add r5, r5, #0x1
cmp r5, #0x2D
bne IVLoop

End:
pop {r6}
bl Recalculate_Stats
ldr r1, .Return_Addr
bx r1

Insert_Element:
ldr r3, .Insert_Addr
bx r3

Recalculate_Stats:
mov r0, r4
ldr r1, .Recalc_Addr
bx r1

Mod:
ldr r3, .Mod_Addr
bx r3

.align 2
.Return_Addr: .word 0x08011639
[Color=yellow].EV_Table: .word 0x08F00000[/color]
.Insert_Addr: .word 0x0804037d
.Recalc_Addr: .word 0x0803e47d
.Mod_Addr: .word 0x081e4685

Emerald:
Código:
#Formato de tabla de EV específico
#Cada tabla tiene 0xF bytes (16 bytes)
#0x0 = Naturaleza
#0x1-0x3 = Bytes vacíos (00)
#0x4 = IVs (desde 0-31, no 0-255, usado para todos los IVs)
# (si quieres Poderes Ocultos, recuerda que la AI no puede manejar -- movimientos por pb)
#0x5 = PS EVs
#0x6 = Atq EVs
#0x7 = Def EVs
#0x8 = Vel EVs
#0x9 = At. Esp EVs
#0xA = Def. Esp EVs
#0xB = Pokeball
#0xC-0xF - Últimos 4 bytes son bytes vacios (00)

.align 2
.thumb
.thumb_func

.org 0x38936
mov r0, r1
mov r6, r0
b 0x38944

.org 0x3896c
ldr r0, .Method_Addr
bx r0

[Color=red].Method_Addr: .word 0x08F90001[/color]

.org 0x67d68
b 0x67dc8

[Color=red].org 0xF90000[/color]

LoadItem:
add r5, #0x6
add r0, r4, #0x0
mov r1, #0xc
add r2, r5, #0x0
bl Insert_Element

LoadHPEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x5
mov r1, #0x1A
mov r0, r4
bl Insert_Element

LoadAtkEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x6
mov r1, #0x1B
mov r0, r4
bl Insert_Element

LoadDefEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x7
mov r1, #0x1C
mov r0, r4
bl Insert_Element

LoadSpeedEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x8
mov r1, #0x1D
mov r0, r4
bl Insert_Element

LoadSAtkEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0x9
mov r1, #0x1E
mov r0, r4
bl Insert_Element

LoadSDefEV:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0xA
mov r1, #0x1F
mov r0, r4
bl Insert_Element

LoadBall:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0xB
mov r1, #0x26
mov r0, r4
bl Insert_Element

StartNatureLoop:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
ldrb r5, [r2, #0x0]
cmp r5, #0x0
beq LoadIVs
ldr r0, [r4, #0x0]
ldr r1, [r4, #0x4]
eor r1, r0, r1
str r1, [r4, #0x4]

NatureLoop:
ldr r0, [r4, #0x0]
add r0, r0, #0x18
str r0, [r4, #0x0]
mov r1, #0x19
bl Mod
cmp r0, r5
bne NatureLoop

EndNatureLoop:
ldr r0, [r4, #0x0]
ldr r1, [r4, #0x4]
eor r1, r0, r1
str r1, [r4, #0x4]

LoadIVs:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
ldrb r6, [r2, #0x4]
push {r6}

StartIVLoop:
mov r5, #0x27

IVLoop:
mov r0, r4
mov r1, r5
mov r2, sp
bl Insert_Element
add r5, r5, #0x1
cmp r5, #0x2D
bne IVLoop

End:
pop {r6}
bl Recalculate_Stats
ldr r1, .Return_Addr
bx r1

Insert_Element:
ldr r3, .Insert_Addr
bx r3

Recalculate_Stats:
mov r0, r4
ldr r1, .Recalc_Addr
bx r1

Mod:
ldr r3, .Mod_Addr
bx r3

.align 2
.Return_Addr: .word 0x08038979
[Color=yellow].EV_Table: .word 0x08EF0000[/color]
.Insert_Addr: .word 0x0806acad
.Recalc_Addr: .word 0x08068d0d
.Mod_Addr: .word 0x082e7be1

Todo el código fue escrito para ser insertado en 0xF90000. No es necesario que el código lo insertes ahí, puede ser movido a cualquier área de la ROM con espacio libre. Solo asegurate que la línea Method_Addr apunte a la nueva dirección donde pondrás el código +1 (En el ejemplo está puesta en 0xF90000 +1 que es en total 0xF90001. Tambien cambia el .org 0xF90000 si gustas, mas no le sumes +1)

El archivo .bin generado pesa 15MB más o menos, la mayoría de bytes son puros 00. Esto pasa porque la rutina ya tiene los hooks incluídos, así que dentro del archivo solo hay que ir donde están ubicados los hooks (En el código de la rutina se encuentran), copiar los bytes y pegarlos en las mismas direcciones dentro de nuestra ROM. tambien hacer lo mismo donde se insertó la rutina principal.

¿Ves el texto amarillo en el código? Ese texto es el puntero donde se ubicará la tabla de EV para nuestros entrenadores. Esta tabla debe ser ubicada en un espacio con 0x1000 bytes libres. Para el ejemplo la line .EV_Table apunta a 0xEF0000. Puedes cambiar dirección a otro espacio alineado (Sin sumar nada). Ahí pondremos nuestras tablas de EVs. Este método te dará 255 tablas de EV. No hay mucho control sobre ellas, pero al menos es mejor que las 38 por defecto en Emerald. El formato de la tabla de EV's es:

0x0 Naturaleza
0x1-0x3 Bytes vacíos (00)
0x4 IV (Van desde 0-31 para todas las estadísticas)
0x5 PS EV
0x6 Ataque EV
0x7 Defensa EV
0x8 Velocidad EV
0x9 Ataque Especial EV
0xADefensa Especial EV
0xB En qué Pokéball saldrá el Pokémon
0xC-0xF bytes de relleno (00)

Recuerda que los EV van desde 0x0 hasta 0xFF. Aunque si has aplicado la limitación de EV a 252 entonces el límite será 0xFC.

Para asignar una entrada en la tabla de EV a un Pokémon de un entrenador solo debes de abrir los datos del entrenador usando cualquier herramienta de edición de entrenadores (Yo recomiendo Gen 3 Tools), en G3T abres el Pokémon del entrenador y debes editar el campo donde dice "EVs" (En advance trainer dice AI value) y poner ahí en decimal el número de entrada en la tabla (Lo cual recuerda, es desde 1 hasta 255, poniendo 0 no cargará absolutamente nada). Ten en cuenta que todos los valores solo funcionan si el entrenador tiene Pokémon con movimientos personalizados y objetos. Si solo tiene los movimientos o los objetos solo se cargarán los valores de IV's. Si quieres que funcione con los movimientos por defecto solo basta con presionar en G3T el botón "defauñt moves" para que tengan los movimientos por defecto a ese nivel. El proceso es el mismo para cada uno de los Pokémon.

Como esta rutina acepta naturalezas, puedes usar la lista de abajo para asignar una naturaleza.

0x0 - Arbitraria
0x1 - Huraña (+Atq, -Def)
0x2 - Firme (+Atq, -Vel)
0x3 - Audaz (+Atq, -AtqEsp)
0x4 - Pícara (+Atq, -DefEsp)
0x5 - Osada (+Def, -Atq)
0x6 - Dócil (Neutral)
0x7 - Plácida (+Def, -Vel)
0x8 - Agitada (+Def, -AtqEsp)
0x9 - Floja (+Def, -DefEsp)
0xA - Miedosa (+Vel, -Atq)
0xB - Activa (+Vel, -Def)
0xC - Seria (Neutral)
0xD - Alegre (+Vel, -AtqEsp)
0xE - Ingénua (+Vel, -DefEsp)
0xF - Modesta (+AtqEsp, -Atq)
0x10 - Afable (+AtqEsp, -Def)
0x11 - Mansa (+AtqEsp, -Vel)
0x12 - Tímida (Neutral)
0x13 - Alocada (+AtqEsp, -DefEsp)
0x14 - Serena (+DefEsp, -Atq)
0x15 - Amable (+DefEsp, -Def)
0x16 - Grosera (+DefEsp, -Vel)
0x17 - Cauta (+DefEsp, -AtkEsp)
0x18 - Rara (Neutral)

La naturaleza Fuerte no está disponible debido a como funciona la misma, pero igual no importa al ser naturaleza netral. Valores superiores a 0x18 colgarán el juego, si se usa 00 como valor de naturaleza esta no será modificada y será el mismo juego quien determine la misma..

Tambien recalcar que este método le puede dar a un Pokémon rival más de 510 EVs en total por si eres insanamente malvado.

Y es todo. Los créditos del tutorial y el código van para Doesntknowhowtoplay. Yo solo traduje y agregé unos datos extra para que todos entiendan mejor como funciona la misma.
Espero alguien la use y veamos hackroms con mayor dificultad a solo levelear cruelmente.
 

FiaPlay

Bro, This Fire!
Hola , al intentar compilar la rutina de emerald
( arrastrarla sobre el famoso compilador de hackmew )
no me aparece el .bin que es la rutina compilada
¿Que hice mal?🤔
Pantallazo 19-08-2021 22.41.58.png

espero que esta imágen diga algo
Edit:la octava es la vencida , lo logré
, sigo sin saber que hice mal , pero problema resuelto😂
 
Última edición:

Inver_Hacks

Room hacking de Android y pc
Una pregunta, Donde debo poner,
Por ejemplo, si quiero que el Pokémon De un rival tenga la naturaleza Firme Pongo
*0x2(naturaleza Firme) antes del scrip De el Trainer o Donde?
 

Versekr Dark

Usuario mítico
Una pregunta, Donde debo poner,
Por ejemplo, si quiero que el Pokémon De un rival tenga la naturaleza Firme Pongo
*0x2(naturaleza Firme) antes del scrip De el Trainer o Donde?
Debes crear una tabla dentro de la rom, se debe ver así

1686928503961.png


Y si te das cuenta el primer byte es la naturaleza.
 

Inver_Hacks

Room hacking de Android y pc
Debes crear una tabla dentro de la rom, se debe ver así

Ver el archivo adjunto 14561

Y si te das cuenta el primer byte es la naturaleza.
Gracias, otra pregunta, Debe ser ajuro en Hex Maniatic Advance o Puede ser También en HxD, y hay alguna limitación, o puede ser para Todos los Pokémons que queramos, emmm, otra, y gracias jsjsjs, Si ya utilice a un espacio de la tabla con un Pokémon, como hago para ocupar otra y no la misma, sigo "1;2;3 etc"?
 
Arriba