GBC | Tutor de movimientos

Avisos

Like Tree8Gracias

Respuesta
 
Herramientas Desplegado
  #1  
11/03/2014
Predeterminado GBC | Tutor de movimientos
A pesar de ser pocos los temas de investigacion GBC, abro este tema con el fin de que los usuarios mas experimentados apoyen con sus conocimientos técnicos y los mas novatos aporten ideas.

Objetivo: Emular/trasladar el tutor de movimiento(s) de Pokémon Crystal a Pokémon Gold & Silver.

Conocimentos previos: Gracias al desensamble de Crystal sabemos que el tutor de movimientos ocupa numero 0x83 del comando "special" (0xF).

Meta a corto plazo: A pesar de contar con toda la documentación para poder trasladar el tutor de movimientos de Crystal a Gold&silver, es mucho trabajo tener que adaptar y buscar todas las rutinas necesarias, por eso propongo una forma diferente de hacer los tutores, no mediante ASM, si no mediante Scripts (o la mezcla de ambos).

Usando la documentación del compendio de Tauwasser y la documentación Ram de KBC podemos escribir datos en la Ram y enseñarle movimientos a nuestros pokemon pero con algunas limitaciones.

Los movimientos a enseñar deberan ser "genericos", es decir, aquellos movimientos que los pueden aprender todos los pokemon con excepcion de Caterpie, Metapod, Weedle, Kakuna, Magikarp, Ditto, Unown, Wobbuffet, Smeargle,como Curse o Double Team, esto con el fin de simplificar la tarea y de paso ahorrar espacio en las TM.

Los movimientos que cuentan con estas caracteristicas son:
  • Curse
  • Double Team
  • Frustration
  • Hidden Power
  • Mimic
  • Protect
  • Rest
  • Return
  • Sleep Talk
  • Substitute
  • Toxic

NOTA: Con un poco de trabajo extra podemos comprobar si el pokemon posee sexo y hacer un tutor para Attract.

El primer paso para el script es comprobar que el pokemon seleccionado NO sea uno de los anteriores mencionados y para ello podemos usar el comando "special" con su variable 0x4C, el cual abre el menu del pokemon y pone en la RAM de los scripts ($D173) el numero del pokemon y el nombre en la MEMORY1 ($CF91).

Ejemplo



De ahi aplicamos tantos "if equal" como sean necesarios para indicar que el pokemon NO puede aprender el movimiento.

Código:
#org 0x000000
special 0x4C
if != 0x1B 0xYYXX ' 0xXXYYZZ
if != 0x1C ETC.
...
Segun Tauwasser, el special 0x4C devuelve 2 resultados, en la RAM el No. del pokemon seleccionado y en la MEMORY1 el nombre del pokemon. Tengo la teoria de que devuelve un tercer valor en $D006 (o $D005) , que vendría siendo el lugar en la party del pokémon seleccionado, de ser asi, nos podria ahorrar mucho trabajo de ASM.

Después de toda la comprobación, en el caso de que el pokemon SI pueda aprender el movimiento podemos partir de dos vertientes:
  • 1.- Que mediante ASM se haga un checkeo del 4to, 3er y 2do movimiento (DA2F, DA2E y DA2D en el caso del primer pokemon, por ejemplo) para ver si algun espacio esta libre y escribir el movimiento. En caso de no haber espacio advertir que el ultimo movimiento se va sobreescribir*

  • 2.-Que se habra una caja de texto preguntando que movimiento queremos que se reemplaze, pero ojo, la caja de texto no tendria los nombres de los movimientos, si no solo el texto de "movimiento 1", "movimiento n", etc.*

*Estos metodos propuestos no son tan profesionales, pero hasta no conocer como trabajan las TM al momento de sobrescribir movimientos, no podemos hacer nada mas.

Para escribir el movmiento del pokemon, solo hace falta hacer ramificaciones de scripts ayudados del comando "copyvartobyte", el cual escribe el index/valor del movimiento en la memoria Ram correspondiente de cada pokemon y de sus PP.

Lo mas importante de esta metodologia debe ser su versatildiad. El script debe estar hecho de tal forma que interactue con las variables, de esa forma podremos estar usando el mismo script (con 3jump) una y otra vez con tan solo estar cambiando las variables de cada movimiento.

Dentro de poco voy a publicar un borrador del script para un mejor entendimiento.

PD: Quizas los novatos no entienda muy bien de lo que hablo, pero tan pronto aprendan a hacer scripts en GBC les sera muy facil relacionar los terminos.

Saludos!

Última edición por Chamber; 11/03/2014 a las 01:00
  #2  
11/03/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
Bien, como primer punto, para el script veo necesario que miremos el script original de cristal (que debe ser mas complicado al ser un evento de un solo dia) y en base a el trasladarlo.

Suena facil, pero el problema viene en que el script usa specials exclusivos de cristal, donde viene el problema.

Ademas, el tutor enseña tres movimientos, los cuales no son genericos, y no son posibles enseñarselos a todos los pokemon, por lo cual veo posible hacerlo con cualquier movimiento, asi que lo mejor seria ojear el script de pokemon cristal y ver como esta estructurado (obvio que el RAM map varia entre ambas versiones)

  #3  
11/03/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
Ya he mirado varias (MUCHISIMAS) veces el script de crystal y no podemos hacerlo igual por las variables del comando special.

Ya tengo ubicadas las rutinas y todo lo necesario para trasladar la información, el problema es que se tiene que adaptar jumps, calls y direcciones a la RAM de Gold y eso es pesadisimo.

Lo que mencionas sobre el tutor movimientos, que los ataques que enseña son especificos (Flamethrower, Thunderbolt y Ice Beam) de momento no me parece relevante, por que si empezamos con lo mas dificil puede ser que no avancemos, por eso me parece mejor algo mas "generico".

En el caso del tutor de Crystal, el juego usa los ultimos 3 bits en los datos de los stats de los pokemon para revisar la compatibilidad. -En total son 7 bits libres los que tenemos, asi que podriamos tener 7 tutores especificos en total mas los genericos.

Ya antes @Crystal_ nos ha dicho como podemos chechar esa compatibiliad con una rutina ASM bastante sencilla, lo unico que no se es como hacer aparecer el texto "ABLE/NOT ABLE" para marcar la compatibilidad visualmente.

En Crystal, la rutina que abre la party y revisa los pokemon esta en 0x50000, asi que podemos hacer un callba y ir probando.
  #4  
14/03/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
He aqui la documentacion de DataCrystal:

Código:
SpecialsPointers: ; c029, Tabla de pointers del comando "special"

Function4925b: ; 4925b, rutina del "special 0x83" - tutor de movimientos
	call FadeToMenu		; funciones de pantalla
	call WhiteBGMap		; funciones de pantalla
	call Functionfdb	; funciones de pantalla
	call DelayFrame		; funciones de pantalla
	ld b, $14		; funciones de pantalla
	call GetSGBLayout	; funciones de pantalla
	xor a			; exclusion logica que pone a en $0
	ld [$d142], a
	call Function492a5	; determina el movimiento (Flamethrower, Thunderbolt o Ice Beam)
	ld [$d265], a		; carga el index del movimiento
	ld [$d262], a		
	call GetMoveName 	; carga el nombre a StringBuffer1 y...
	call CopyName1 	 	; lo copia al StringBuffer2
	callba Function2c7fb	; copia el contenido de StringBuffer2 a $d066
	jr c, .asm_4929c	; si presionas B termina.
	jr .asm_49291		

.asm_49289
	callba Function2c80a
	jr c, .asm_4929c

.asm_49291
	call Function492b9	; abre el menu de la party
	jr nc, .asm_49289
	xor a
	ld [ScriptVar], a
	jr .asm_492a1

.asm_4929c
	ld a, $ff
	ld [ScriptVar], a

.asm_492a1
	call Function2b3c
	ret
; 492a5

Function492a5: ; 492a5
	ld a, [ScriptVar]
	cp $1
	jr z, .asm_492b3
	cp $2
	jr z, .asm_492b6
	ld a, $3a
	ret

.asm_492b3
	ld a, $35
	ret

.asm_492b6
	ld a, $55
	ret
; 492b9
Esto nos puede dar una idea de como combinar ASM con los scripts.
  #5  
08/04/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
Después de un mes de investigación los resultados son los siguientes:

En base a ASM he logrado hacer rutinas con las siguientes funciones.
  • -Poner el nombre del tutor en la RAM, esto permite tener versatilidad para no tener que estar escribiendo el nombre del movimiento una y otra vez.
  • -Checar compatibilidad con el tutor.
  • -En el caso de Attract, checha que el pokemon posea sexo.
  • -Comprobar que el pokemon no conosca el movimiento.
  • -Comprobar si el pokemon tiene espacio libre en su movepool, y en caso de que no...
  • -Desplegar una caja de texto para indicar que movimiento queremos reemplazar.

Asuntos pendintes:
-Comprobar la compatibilidad a base de Bits y no de Bytes como se hace actualmente.
-Mostrar la compatibilidad en el menu del equipo.


Una primera versión del tutor puede ser vista en el siguiente video, sin embargo no se muestra la caja de seleccion.

Pronto actualizare con la nueva versión y un parche.


Gracias: MoonLover~
  #6  
08/04/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
Muy bien, creo que aun no llega a ser como un tutor al estilo NDS va muy bien la rutina, me estan gustando tus avances, falta poco para tenerla al 100%

Te echaria una mano, pero ando ocupado investigando otras cosas, Saludos!!
Gracias: Chamber

  #7  
12/04/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
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:





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.

Código:
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:
  • 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.

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:

Código:
#org 0xXXXXXX  
'-----------------------------------
faceplayer
loadvar 0xD5
3jump 0x6B836F
  • 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.


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.

Saludos y hasta la proxima!

Última edición por Chamber; 12/04/2014 a las 17:31
  #8  
12/04/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
waao compadre . tu si que eres tremendo en el arte del hack , no cabe duda que eres maestro de maestros xD siempre sorprendiendonos con las novedades , a este paso no dudo que también implementaras la rutina de las megae voluciones , ya casi dominas el sistema ASM cosa que no es facil , mis mas sinceras felicitaciones y mis respetos compadre , eres grande, respecto al parche es compatible con cualquier room aun asi contenga los demas parches ya mostrados por ti ?
nuevamente felicidades !!!!
Gracias: Chamber

  #9  
12/04/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
Muchas gracias por las flores Wizard.

En este caso si, la compatibilidad es con todos los roms de GBC, debido a que las rutinas son TOTALMENTE independientes de cualquier otra funcion del juego, solo como mencione antes, revisa que los offsets mensionados no tengas informacion (en $27BFA y de $1BE920 a 1BEE70).

Quizas lo que pueda llegar a fallar en roms diferentes a GOLD es que las 3 letras extras de la fuente no se carguen (o se dañen), en caso de ser asi, es facil reparalo.
Gracias: WiZaRD
  #10  
12/05/2014
Predeterminado Respuesta: [Investigacion-GBC]Tutor de movimientos para G/S
Pregunta @Chamber , mencionas que para que enseñe el movimiento (el tutor ) pide un HEART SCALE , has modificado algún ítem en el parche ? algún terusama ? o se tendrá que hacer manualmente ? , respecto al parche , una vez aplicado haces mención que tenemos que cargar el comando de movimientos en la npc , pero ha que npc tendremos que cargar y cuantos nps hay con el scrip para así modificar-lo ! .
gracias por la atención y mas aun por las respuestas ...

Respuesta

Herramientas
Desplegado

Permisos para publicar mensajes
No puedes crear nuevos temas
No puedes responder mensajes
No puedes subir archivos adjuntos
No puedes editar tus mensajes

Los BB code están Activado
Los Emoticones están Activado
El código [IMG] está Activado
El Código HTML está Desactivado
Trackbacks are Activado
Pingbacks are Activado
Refbacks are Desactivado



Extra
Estilo clásico
La franja horaria es GMT +1. Ahora son las 11:41.