Author Id: 26330 Author Name: Chamber4315♪ Post Content: Actualizo! Gracias a Miksy91 (y cierta domentacion escrita hace mucho tiempo), he podido dar con una de las rutinas que le hacia falta a mi tutor, aquella que se encarga de cargar los movimientos del pokemon seleccionado a la ram y desplegarlos en una caja de texto para asi poder seleccionar que movimiento queremos reemplazar. Aqui una muestra: [URL=http://www.youtube.com/watch?v=U0itFperpGk]YouTube Video[/URL] Con esto cumplo el objetivo de la investigador, el de tener tutores de movimientos genericos, sin embargo esto no sacia mi sed de aprendizaje y no descansare hasta perfeccionar la rutina y tener gran cantidad de tutores igual que en GBA o DS. Por el momento dejo la documentación empleada. Rutinas para el move Tutor --------- Glossary: --------- CE63 = Alojamiento temporal del ID del Movimiento D173 = ID del Movimiento en la rutina de carga de nombre (o RAM de scripts) D005 = Lugar del pokemon en el equipo(00=1ro, ..., 05=6to) D006 = Alojo temporal del espacio libre para poner el nuevo Movimiento (01=1ro, ..., 04=4to) D173 = RAM en los Scripts CF6B = StringBuffer1 CF7E = StringBuffer2 CF91 = StringBuffer3 CFA4 = StringBuffer4 CFB7 = StringBuffer5 call $317B; CopyName1, copia texto del StringBuffer1 al StringBuffer2 call $317E; CopyName2, copia texto de de a hl. Siempre se tiene que especificar antes un ld hl,nn ; para indicar el destino. call $311A; CopyBytes, copia bc bytes de hl a de call $31A3; AddNTimes, agrega de a hl igual al numero de a -----Rutina de carga de nombre-----$1BE920,0x69206F(PKSV) 1.0- Previo necesitamos cargar el ID del movimiento a la RAM 1.1- Se deja un respaldo del ID en $CE63 1.2- Se carga el nombre del move a la StringBuffer1 y se copia a StringBuffer5 ld a,[$D173]// Toma el valor de la RAM ld [$D151],a ld [$CE63],a// respaldo del ID call $373D// GetMoveName, devuelve el nombre en StringBuffer1 ($CF6B) y deja en // 'de' la direeccion de StringBuffer1 para poder usar CopyName1 o CopyName2 ld hl,$CFB7// StringBuffer5 call $317E// CopyName2 ret -----Checa compatibilidad-----$1BE940,0x69406F(PKSV) 1.0- Si el tutor es de 'Attract', carga una rutina extra. 1.1- Compatible = (RAM $01) No Compatible = (RAM $00) ld a,[$CE63] cp a,$D5// comprueba si el tutor es de Attract jr z,@attract @next ld a,[$D173] ld b,a ld de,$69E0//@noTMHMPkmnTable-1 @loop4 ld a,[de] inc de cp a,b jr z,@NoCompatible cp a,$FF jr nz,@loop4 ld a,$1 ld [$D173],a ret @NoCompatible xor a,a ld [$D173],a ld hl,$6B00// @UnknownText1 call $0F5E// PrintText ret @attract// rutina que comprueba que el pokemon tenga sexo ld a,[$D004] cp a,$97// mew queda excluido jr z,@next dec a call @getGender cp a,$FF jr z,@NoCompatible jr nz,@next @getGender push hl push de ld hl,$5B18// pointer del gender ratio del primer pokemon ld bc,$0020// longitud en base stats call $31A3// AddNTimes ld a,$14// Bank call $3128// GetFarByte, recupera un byte de ZZ:YYXX (a:hl) y lo devuelve en a, en este caso el PP pop de pop hl ret $1BE9E0 @noTMHMPkmnTable-1 0A - Caterpie 0B - Metapod 0D - Weedle 0E - Kakuna 81 - Magikarp 84 - Ditto C9 - Unown CA - Wobbuffet EB - Smeargle $1BEB00 @UnknownText1(PKSV) = Lo siento, pero\ntu text-ram 0xCF91 = \lno puede aprender\l text-ram 0xCFB7 = !\e ; codigo para copiar en HEX 0 139 174 127 178 168 164 173 179 174 244 127 175 164 177 174 79 179 180 127 80 1 145 207 0 85 173 174 127 175 180 164 163 164 127 160 175 177 164 173 163 164 177 85 80 1 183 207 0 231 87 -----Comprobar que no conosca el movimiento-----$1BE9C0,0x69C06F(PKSV) 1.0- Previo necesitamos el ID en $CE63 1.1- Checa el movepool del pokemon seleccionado: NO Conoce = (RAM $00) Si conoce = (RAM $01) call $6990//@objetslot ; regresa en hl la direccion del objeto del PKM seleccionado. ld a,[$CE63]//carga respaldo del ID ld b,$04 @loop1 inc hl cp a,[hl] jr z,@repetido dec b jr nz,@loop1 xor a,a//a = $0 ld [$D173],a ret @repetido ld a,$1 ld [$D173],a ld hl,$6B40//@UnknownText2 call $0F5E//PrintText ret $1BEB40 @UnknownText2(PKSV) = Lo siento, pero\n text-ram 0xCF91 = \lya conoce\l text-ram 0xCFB7 = !\e ; codigo para copiar en HEX 0 139 174 127 178 168 164 173 179 174 244 127 175 164 177 174 79 80 1 145 207 0 85 184 160 127 162 174 173 174 162 164 85 80 1 183 207 0 231 87 -----Comprobar si hay espacio-----$1BEA00,0x6A006F(PKSV) 1.0- Comprube si alguno de los 4 slots esta en $0 1.1- Si NO hay espacio libre regresa la RAM a $1 1.2- Si hay espacio libre regresa la RAM a $0 y... 1.3- Guarda un respaldo del slot libre en D006 call $6990//@objetslot;regresa en hl la direccion del objeto del PKM seleccionado. inc hl//;$DA2B + $1 = first move ld b,$04 ld c,$01 @loop ldi a,[hl] cp a,$00//;da como resultado el propio a sin modificar, si es 0 = set flag Z jr z,@positivo inc c dec b jr nz,@loop ld a,$01//;a = $0 ld [$D173],a ret @positivo ld a,$00 ld [$D173],a add a,c ld [$D006],a//;pone el no. del slot libre en $D006 para posteriores usos ret -----Enseña el movimiento en un espacio libre-----$1BEA30,0x6A306F(PKSV) 1.0- Carga el respaldo de D006 y... 1.1- "Enseña el movimiento" call $6990//@objetslot ld a,[$D006] ld e,a ld d,00 add hl,de call $699D//@GetNewMove ret -----Reemplaza al jugador con 0x00-----$1BEA40,0x6A406F(PKSV) ld hl,$8000 ld de,$7F40 ld bc,$270c jp $0E72 -----Carga de movimientos y Choosing Box-----$1BEA50,0x6A506F(PKSV) 1,0- Copia los movimientos del pokemon seleccionado a D149 (slots del oponente en batalla) 1.1- Despliega una caja de seleccion del movimiento a reemplazar call $6990//@objetslot inc hl ld bc,$0004 ld de,$D149 call $311A// CopyBytes ld hl,$C3CD ld b,$08 ld c,$0D call $0EEF// textbox; Draw a text box width c height b at hl call $3456// funcion de pantalla call $3546// funcion de pantalla ld hl,$C3F7 ld a,$28 ld [$D0D3],a ld a,$20 call $2E49//call Predef ld a,$04 ld [$CED8],a ld a,$06 ld [$CED9],a ld a,[$CFE3] inc a ld [$CEDA],a ld a,$01 ld [$CEDB],a ld [$CEE0],a ld [$CEE1],a ld a,$03 ld [$CEDF],a ld a,$20 ld [$CEDC],a xor a,a ld [$CEDD],a ld a,$20 ld [$CEDE],a ld hl,$7BFA ld a,$09 rst $8 ret $27BFA//unica rutina fuera del banco call $4255 call $4141 ret -----Escribe el nuevo movimiento segun la opcion seleccionada-----$1BEAC0,0x6AC06F(PKSV) 1,0- Carga el valor elegido de CEE0 y... 1.1- Escribe el nuevo movimiento. ld hl,$D148 ld a,[$CEE0]//Seleccion del menu ld e,a ld d,$00 add hl,de ld a,[hl] ld [$D151],a call $373D// GetMoveName, devuelve el nombre en StringBuffer1 ; $CF6B ld hl,$CFA4//StringBuffer4 call $317E//CopyName2 call $6990//@objetslot ld a,[$CEE0]//Seleccion del menu ld e,a ld d,$00 add hl,de call $699D//@GetNewMove ret ----- Subrutinas ----- ; encontrar movimientos del pokemon seleccionado $1BE990//; call $6990 @objetslot ld hl,$DA2B//; objeto del primer pokemon (uno antes de los movimientos) ld a,[$D005]//; no. de pokemon seleccionado 1ro=$00, 2do=$01... ld bc,$0030//; longitud de los datos del pokemon call $31A3//; AddNTimes ret $1BE99D @GetNewMove//; call $699D ld a,[$CE63] ld [hl],a ld de,$0015 add hl,de dec a call @getPP ld [hl],a ret @getPP//; call $69AB push hl push de ld hl, Moves + MOVE_PP; pointer de los moves + $5, en mi caso ld hl,$5505 ld bc, Move2 - Move1 ; ld bc,$0007 longitud de los moves call $31A3; AddNTimes ld a,BANK(Moves) ; en mi caso $26 call $3128; GetFarByte, recupera un byte de ZZ:YYXX (a:hl) y lo devuelve en a, en este caso el PP pop de pop hl ret Para los que no se les da el ASM, he creado un parche para que puedan probar el tutor. El parche hace 3 modificaciones: [LIST] [*]Agrega una rutina pequeña (7 bytes) en $27BFA, por lo que se deben de asegurar que no esten usando esa direccion. [*]De $1BE920 a 1BEE70 se cargan las rutinas y el script para PKSV (regularmente son bancos vacios, asi que no hay problemas) [*]En $F83E1 hace unas pequeñas modificaciones para agregar a la fuente las letras "ñ", "¿" y "¡" debido a que el juego carece de ellos en su version inglesa. [/LIST] Una vez aplicado el parche no es necesario cargar todo el script en cada NPC, ya que he desarrollado un sistema en el que solo tienes que usar 7 bytes para cada tutor. Esta es la sintaxis que usaremos en PKSV para cada caso: #org 0xXXXXXX '----------------------------------- faceplayer loadvar 0xD5 3jump 0x6B836F [LIST] [*]Loadvar es el comando que define nuestro tutor, osea, el movimiento que vamos a enseñar. En este caso yo use 0xD5 que corresponde a Attract. [*]3jump 0x6B836F es el comando que redirecciona el script de nuestro NPC a todas las rutinas del tutor. [/LIST] Con estos sencillos pasos podremos hacer todo lo mostrado en los vídeos. La investigación sigue, ya lo único que hace falta es que se muestre la compatibilidad con el tutor en el menú del equipo, llegando a es punto creo que podre dar por finalizada la investigación, mientras tanto, queda el tema abierto. [URL="https://www.dropbox.com/s/waxoooyuyasypep/PKMGOLD%20Base%20-%20Move%20Tutor.ips"]DESCARGA DEL PARCHE[/URL] Saludos y hasta la proxima!