Kaiser de Emperana
Called in hand
Bueno, este tuto/aporte va a ser bastante pequeño. Es básicamente lo mismo que esto, pero más dinámico...
Con simplemente cambiar los valores de algunas variables y hacer un callasm van a poder ver y cambiar el valor de cualquier atributo de un pokemon (ev's, iv's, condición de estado, etc.). tal y como está ahora funciona en FR y Emerald, pero se puede adaptar a cualquier rom. Pero bueno, lo primero que tienen que hacer es insertar las funciones.
Así que descarguen esto:
- Funciones
Para insertarlo en su rom van a tener que haber instalado estas herramientas.
Una vez instaladas, extraigan el zip que deje antes. Y pongan su rom en la carpeta que apareció, con el nombre "BPRE0.gba"
Con un editor de texto que soporte codificación UTF8 (yo recomiendo notepad++) abran main.s y cambien el offset de la línea siguiente, por la dirección donde quieran insertar las funciones.
Abran cygwin y dirijanse a la carpeta extraída. Y ejecuten:
Debería de aparecer una carpeta "build" con un nuevo rom que tiene las funciones insertadas.
Y además debería haber aparecido un archivo "offsets.txt". Abranlo y busquen unas líneas como estas:
Estas son las funciones que vamos a llamar con callasm (no confundirse con getmondata y setmondata).
Ahora los scripts:
Y bueno eso sería todo... No se si se entendió del todo bien. Comenten cualquier cosa.
Todos las direcciones son sacadas de pokeagb y pokeemerald.
Ah, por si a alguien le interesa saber que clase de monstruosidad de código es el que forman estan funciones maravillosas, lo dejo acá:
(¡Pero si es más corto que el script!)
Saludos.
Con simplemente cambiar los valores de algunas variables y hacer un callasm van a poder ver y cambiar el valor de cualquier atributo de un pokemon (ev's, iv's, condición de estado, etc.). tal y como está ahora funciona en FR y Emerald, pero se puede adaptar a cualquier rom. Pero bueno, lo primero que tienen que hacer es insertar las funciones.
Así que descarguen esto:
- Funciones
Para insertarlo en su rom van a tener que haber instalado estas herramientas.
Una vez instaladas, extraigan el zip que deje antes. Y pongan su rom en la carpeta que apareció, con el nombre "BPRE0.gba"
Con un editor de texto que soporte codificación UTF8 (yo recomiendo notepad++) abran main.s y cambien el offset de la línea siguiente, por la dirección donde quieran insertar las funciones.
Código:
.org 0x08800000
Si usan emerald, en vez de llamar a su rom "BPRE0.gba" pónganle "BPEE0.gba".
Luego abran el archivo main.s y modifiquen esta línea:
Y por último habran el archivo Makefile (de vuelta con notepad++) y cambien esta línea:
Luego abran el archivo main.s y modifiquen esta línea:
Código:
.open "BPRE0.gba","build/rom.gba", 0x08000000
Código:
export ROM_CODE := BPRE
Código:
make
Y además debería haber aparecido un archivo "offsets.txt". Abranlo y busquen unas líneas como estas:
Código:
08800000 getdata
08800048 setdata
088000DC setnature
Ahora los scripts:
La función de consulta es "getdata" y en mi caso su offset es 0x8800000, ustedes usen su propio offset.
Esta función necesita que ustedes le den valor a las siguientes variables:
0x8004: la posición del equipo del pokemon con el que quieren trabajar.
0x800D: el dato que quieren pedir (miren la tabla que está unos spoiler más abajo)
0x8005: Esta variable, el 99% de las veces la van a querer dejar en 0. Lo que pasa es que las variables pueden almacenar hasta 2 bytes de memoria, pero hay algunos datos de los pokemon que ocupan 4 bytes, si ustedes quieren recibir los 2 bytes "de la izquierda" debería de poner esta variable en 1, si lo que les interesa son los 2 bytes de la derecha la deben de poner en 0. Cada vez que quieran leer un valor que ocupa 2 bytes o menos, deben ponerla en 0.
Una vez ejecuten el callasm el valor pedido se guardará en la variable 0x800D.
Así que veamos un ejemplo simple. Yo voy a aprovechar el special 0x9f de FR, que te deja elegir un pokemon y lo guarda en la variable 0x8004 (que conveniente...).
Vor a hacer un npc que te diga los IV's en ataque de un pokemon que elijas. El númeor que simboliza el ataque es 40 que es igual a 0x28. Por lo que mi script sería:
Y listo, con eso ya está, tienen un npc que mira los IV's de un pokemon y luego te los dice.
Esta función necesita que ustedes le den valor a las siguientes variables:
0x8004: la posición del equipo del pokemon con el que quieren trabajar.
0x800D: el dato que quieren pedir (miren la tabla que está unos spoiler más abajo)
0x8005: Esta variable, el 99% de las veces la van a querer dejar en 0. Lo que pasa es que las variables pueden almacenar hasta 2 bytes de memoria, pero hay algunos datos de los pokemon que ocupan 4 bytes, si ustedes quieren recibir los 2 bytes "de la izquierda" debería de poner esta variable en 1, si lo que les interesa son los 2 bytes de la derecha la deben de poner en 0. Cada vez que quieran leer un valor que ocupa 2 bytes o menos, deben ponerla en 0.
Una vez ejecuten el callasm el valor pedido se guardará en la variable 0x800D.
Así que veamos un ejemplo simple. Yo voy a aprovechar el special 0x9f de FR, que te deja elegir un pokemon y lo guarda en la variable 0x8004 (que conveniente...).
Vor a hacer un npc que te diga los IV's en ataque de un pokemon que elijas. El númeor que simboliza el ataque es 40 que es igual a 0x28. Por lo que mi script sería:
Código:
#dynamic 0x800000
#org @inicio
lock
special 0x9f // el jugador elige un pokemon y lo guarda en 0x8004
waitstate
compare 0x8004 0x7
jumpif 0x1 @fin
setvar 0x800d 0x28 // pido los iv del ataque
setvar 0x8005 0x0 // porque pido un dato que solo ocupa 2 bytes
callasm 0x8800001 // y llamo a la función getdata
buffernumber 0x0 0x800d
msgbox @mensaje 0x6
release
end
#org @fin
release
end
#org @mensaje
= Su ataque es de [buffer 1]
Ahora viene la parte interesante... Modificar datos. Esta función toma las siguientes variables:
0x8004: ídem consulta.
0x800D: ídem consulta.
0x8005: la variable 0x8005 ahora lo que hace es contener los 2 bytes de las derecha de que se van a escribir en el campo solicitado.
0x8006: esta variable contiene los dos bytes de la izquierda. Si se modifica algo que ocupe 2 o menos bytes, dejarla en 0.
Para los que no entiendan. Si la variable 0x8005 es igual a 0x1234 y la variable 0x8006 es igual a 0x5678, lo que se escribiría en el campo ingresado en 0x800D sería: 0x56781234.
¡Al ejemplo!
Supongamos que ahora queremos hacer un npc que cambie los iv de ataque de un pokemon que elijamos, por 31. Lo que deberíamos de hacer es lo siguiente:
Y bueno, con eso está, ya tienen una forma de hacer pokemon perfectos.
0x8004: ídem consulta.
0x800D: ídem consulta.
0x8005: la variable 0x8005 ahora lo que hace es contener los 2 bytes de las derecha de que se van a escribir en el campo solicitado.
0x8006: esta variable contiene los dos bytes de la izquierda. Si se modifica algo que ocupe 2 o menos bytes, dejarla en 0.
Para los que no entiendan. Si la variable 0x8005 es igual a 0x1234 y la variable 0x8006 es igual a 0x5678, lo que se escribiría en el campo ingresado en 0x800D sería: 0x56781234.
¡Al ejemplo!
Supongamos que ahora queremos hacer un npc que cambie los iv de ataque de un pokemon que elijamos, por 31. Lo que deberíamos de hacer es lo siguiente:
Código:
#dynamic 0x800000
#org @inicio
lock
special 0x9f // el jugador elige un pokemon y lo guarda en 0x8004
waitstate
compare 0x8004 0x7
jumpif 0x1 @fin
setvar 0x800d 0x28 // elijo los iv de ataque
setvar 0x8005 0x1f // 31...
setvar 0x8006 0x0 // porque ocupa menos de 2 bytes
callasm 0x8800049 // y llamo a la función setdata
msgbox @mensaje 0x6
release
end
#org @fin
release
end
#org @mensaje
= He despertado su potencial...
Esto es solo una copia de lo que está en el archivo "pokemon.h" de la carpeta "src/headers" del zip.
Estos son los valores que le tiene que dar a la variable 0x800D para modificar los diferentes atributos.
Estos son los valores que le tiene que dar a la variable 0x800D para modificar los diferentes atributos.
Código:
...
#define MON_DATA_PERSONALITY 0
#define MON_DATA_OT_ID 1
#define MON_DATA_NICKNAME 2
#define MON_DATA_LANGUAGE 3
#define MON_DATA_SANITY_BIT1 4
#define MON_DATA_SANITY_BIT2 5
#define MON_DATA_SANITY_BIT3 6
#define MON_DATA_OT_NAME 7
#define MON_DATA_MARKINGS 8
#define MON_DATA_CHECKSUM 9
#define MON_DATA_10 10
#define MON_DATA_SPECIES 11
#define MON_DATA_HELD_ITEM 12
#define MON_DATA_MOVE1 13
#define MON_DATA_MOVE2 14
#define MON_DATA_MOVE3 15
#define MON_DATA_MOVE4 16
#define MON_DATA_PP1 17
#define MON_DATA_PP2 18
#define MON_DATA_PP3 19
#define MON_DATA_PP4 20
#define MON_DATA_PP_BONUSES 21
#define MON_DATA_COOL 22
#define MON_DATA_BEAUTY 23
#define MON_DATA_CUTE 24
#define MON_DATA_EXP 25
#define MON_DATA_HP_EV 26
#define MON_DATA_ATK_EV 27
#define MON_DATA_DEF_EV 28
#define MON_DATA_SPD_EV 29
#define MON_DATA_SPATK_EV 30
#define MON_DATA_SPDEF_EV 31
#define MON_DATA_FRIENDSHIP 32
#define MON_DATA_SMART 33
#define MON_DATA_POKERUS 34
#define MON_DATA_MET_LOCATION 35
#define MON_DATA_MET_LEVEL 36
#define MON_DATA_MET_GAME 37
#define MON_DATA_POKEBALL 38
#define MON_DATA_HP_IV 39
#define MON_DATA_ATK_IV 40
#define MON_DATA_DEF_IV 41
#define MON_DATA_SPD_IV 42
#define MON_DATA_SPATK_IV 43
#define MON_DATA_SPDEF_IV 44
#define MON_DATA_IS_EGG 45
#define MON_DATA_ALT_ABILITY 46
#define MON_DATA_TOUGH 47
#define MON_DATA_SHEEN 48
#define MON_DATA_OT_GENDER 49
#define MON_DATA_COOL_RIBBON 50
#define MON_DATA_BEAUTY_RIBBON 51
#define MON_DATA_CUTE_RIBBON 52
#define MON_DATA_SMART_RIBBON 53
#define MON_DATA_TOUGH_RIBBON 54
#define MON_DATA_STATUS 55
#define MON_DATA_LEVEL 56
#define MON_DATA_HP 57
#define MON_DATA_MAX_HP 58
#define MON_DATA_ATK 59
#define MON_DATA_DEF 60
#define MON_DATA_SPD 61
#define MON_DATA_SPATK 62
#define MON_DATA_SPDEF 63
#define MON_DATA_MAIL 64
#define MON_DATA_SPECIES2 65
#define MON_DATA_IVS 66
#define MON_DATA_CHAMPION_RIBBON 67
#define MON_DATA_WINNING_RIBBON 68
#define MON_DATA_VICTORY_RIBBON 69
#define MON_DATA_ARTIST_RIBBON 70
#define MON_DATA_EFFORT_RIBBON 71
#define MON_DATA_GIFT_RIBBON_1 72
#define MON_DATA_GIFT_RIBBON_2 73
#define MON_DATA_GIFT_RIBBON_3 74
#define MON_DATA_GIFT_RIBBON_4 75
#define MON_DATA_GIFT_RIBBON_5 76
#define MON_DATA_GIFT_RIBBON_6 77
#define MON_DATA_GIFT_RIBBON_7 78
#define MON_DATA_FATEFUL_ENCOUNTER 79
#define MON_DATA_OBEDIENCE 80
#define MON_DATA_KNOWN_MOVES 81
#define MON_DATA_RIBBON_COUNT 82
#define MON_DATA_RIBBONS 83
#define MON_DATA_ATK2 84
#define MON_DATA_DEF2 85
#define MON_DATA_SPD2 86
#define MON_DATA_SPATK2 87
#define MON_DATA_SPDEF2 88
...
Las vriables que hay que settear para cambiar la naturaleza son:
0x8004: idem otras funciones.
0x800D: naturaleza que quiero poner al pokemon.
Un script simple que cambia la narutaleza a timida:
Cambiar la naturaleza deun pokemon ya creado no es tan simple, por el hecho de que hay que cambiar la misma sin cambiar las demás características involucradas al número de personalidad del pokemon. Yo me aseguré de que el pokemon:
- No cambie de sexo.
- No cambie de habilidad.
Pero los posibles efectos secundrios incluyen:
- Cambio del color de piel (shinies que se vuelven normales y viceversa).
- Movimiento de marcas de nacimiento (aka puntos de Spinda).
- Metamorphosis (Unown puede cambiar de letra).
- ¡Cambio del destino! (La evolución a la que está destinada Wurmple puede cambiar, una vez que haya evolucionado se queda como está).
- Cambio de tamaño (esa mecánica que nadie usa).
Para más info ver esto.
0x8004: idem otras funciones.
0x800D: naturaleza que quiero poner al pokemon.
Código:
0 Hardy
1 Lonely
2 Brave
3 Adamant
4 Naughty
5 Bold
6 Docile
7 Relaxed
8 Impish
9 Lax
10 Timid
11 Hasty
12 Serious
13 Jolly
14 Naive
15 Modest
16 Mild
17 Quiet
18 Bashful
19 Rash
20 Calm
21 Gentle
22 Sassy
23 Careful
24 Quirky
Un script simple que cambia la narutaleza a timida:
Código:
#dynamic 0x800000
#org @inicio
lock
special 0x9f // el jugador elige un pokemon y lo guarda en 0x8004
waitstate
compare 0x8004 0x7
jumpif 0x1 @fin
setvar 0x800d 0xa // elijo la naturaleza que quiero
callasm 0x88000dd // y llamo a la función setnature
msgbox @mensaje 0x6
release
end
#org @fin
release
end
#org @mensaje
= Ahora tu pokémon es tímido...
- No cambie de sexo.
- No cambie de habilidad.
Pero los posibles efectos secundrios incluyen:
- Cambio del color de piel (shinies que se vuelven normales y viceversa).
- Movimiento de marcas de nacimiento (aka puntos de Spinda).
- Metamorphosis (Unown puede cambiar de letra).
- ¡Cambio del destino! (La evolución a la que está destinada Wurmple puede cambiar, una vez que haya evolucionado se queda como está).
- Cambio de tamaño (esa mecánica que nadie usa).
Para más info ver esto.
Y bueno eso sería todo... No se si se entendió del todo bien. Comenten cualquier cosa.
Todos las direcciones son sacadas de pokeagb y pokeemerald.
Ah, por si a alguien le interesa saber que clase de monstruosidad de código es el que forman estan funciones maravillosas, lo dejo acá:
Código:
void GetData()
{
u32 ret;
ret = GetMonData(&gPlayerParty[gSpecialVar_0x8004], gScriptResult, 0);
if (!gSpecialVar_0x8005) {
gScriptResult = (u16) ret;
} else {
gScriptResult = (u16) (ret >> 16);
}
}
void SetData()
{
u32 data;
data = gSpecialVar_0x8005 + (gSpecialVar_0x8006 << 16);
SetMonData(&gPlayerParty[gSpecialVar_0x8004], gScriptResult, &data);
CalculateMonStats(&gPlayerParty[gSpecialVar_0x8004]);
}
Saludos.
Última edición: