[ASM] Nivel dinámico de los pokemon rivales

Avisos

Like Tree17Gracias
  • 14 Post By Samu
  • 1 Post By Samu
  • 2 Post By Dani_SR_17
Respuesta
 
Herramientas Desplegado
  #1  
29/01/2018
Predeterminado [ASM] Nivel dinámico de los pokemon rivales
Bueno, pues por fin os traigo está rutina. Resumiendo un poco lo que hace es cambiar los niveles de los pokemon enemigos, tanto los salvajes como de los entrenadores, en función del nivel máximo de los pokemon de tu equipo. Adicionalmente, si hacéis algún givepokemon, su nivel también se verá afectado por la rutina.

Decir que @eing ya hizo algo parecido hace tiempo (Me lo comentó @Mr. Nanren cuando ya tenía la rutina prácticamente acabada).

+Info Rutina vieja

No obstante al probar su rutina, no me funcionaba (probablemente porque sea parte de un sistema de rutinas) y en vez de dedicarme a ver que fallaba simplemente terminé la mía.

Por lo que he podido ver ahora mismo, la rutina de Eing solo estaba pensada para pokemon salvajes. De hecho, estoy casi seguro, que de utilizarla para un pokemon con movimientos custom (los de casitodos los trainer) iba a crashear el juego. Su función pisa el registro 7 antes de pushearlo (que si bien no se usa para los pokemon salvajes, si se usa para los pokes con custom moves).

El que quiera ver su rutina: [PD: es para ruby]:

rutina


Código:
.align 2
.thumb

main:
	push {r4-r7,lr}
	mov r7,r8
	push {r7}
	add sp,#0x1c @-#0x1c
	push {r0-r5}
	ldr r0,.var_lvl
	ldrh r0,[r0,#0x0]
	cmp r0,#0x0
	beq fin2
	cmp r0,#0x1
	beq avg
	sub r0,#0x1
	mov r7,r0
	b fin
	
	
avg: @Mismo nivel +fuerte equipo
	mov r10,lr
	ldr r0,.pkamount @Cargamos pointer pokemon encima
	ldrb r0,[r0,#0x0] @Cantidad pk
	cmp r0,#0x0 @Comparamos si son 0
	beq nopoke @Si son 0;Nivel 5
	mov r1, #0x0 @posicion en el equipo
	mov r2, #0x0 @nivel máximo
	ldr r3, .lvl @Pointer nivel equipo
	mov r4,#0x0 @Contador
	bl bucle @BL a bucle
	mov r0,r2 @Movemos nivel a r0
	b fin @Vamos a fin
	
addlevel:
	mov r2,r5 @Añadimos nivel
	add r1,#0x1 @Añadimos 1 a posicion
	mov r4,#0x64 @Añadimos 64 al contador
	cmp r1, r0 @Comparamos si no es pkamount
	bne bucle @Si no bucle
	bx lr

bucle: @Bucle para determinar cual nivel es el mas alto
	add r3,r4 @Sumamos Pointer+posicion
	ldrb r5,[r3,#0x0] @Cargamos lvl
	cmp r5,r2 @Comparamos nivel poke con nivel actual máximo
	bgt addlevel @Si es mayor; ponemos el nuevo nivel
	add r1,#0x1 @Añadimos 1 a posicion
	mov r4,#0x64 @Añadimos 64 al contador
	cmp r1, r0 @Comparamos si no es pkamount
	bne bucle @Si no bucle
	bx lr @Volvemos al BL
	
nopoke:         
@sin
 pokemon; Nivel 5
	mov r0,#0x5
	b fin
	
fin: @Fin rutina
	mov r7,r0 @Movemos nivel a r7
	pop {r0-r5} @Popeamos registros
	mov r2,r7 @Movemos nivel a r2
	ldr r4, .fin @Vamos al punto donde estaba la rutina
	bx r4
	
fin2:
	pop {r0-r5}
	ldr r4, .fin @Vamos al punto donde estaba la rutina
	bx r4
	
.align 2
.pkamount: .word 0x03004350 @Pointer pk_amount
.segundos: .word 0x02024EB5 @Segundos
.lvl: .word 0x030043B4 @Pointer nivel
.fin: .word 0x0803a7a1  @Rutina de retorno
.var_lvl: .word 0x02026c52 @Var decide lvl

El registro r7 lo pisa en el hook (ldr r7, bx r7).



SetEnemyPokeLevel??

La rutina que os traigo es una "plantilla" que tiene lo básico, para que podáis personalizarla según vuestras necesidades o dejarla tal cual está (de no hacerlo así tendría que subir 200 versiones distintas de la rutina. Yo creo que es mejor subir una "base" con lo "difícil", y ya cada uno que cambie 4 números distintos para hacer lo que quiera).

Aquí la rutina para cada uno de los rom.

Ruby

Código:
.thumb
.align 2

/********** setEnemyLevel = maxPartyLevel |@RUBY|********
Establece el nivel de los pokemon enemigos (salvajes y entrenadores) de forma
dinámica, igualándolo al nivel máximo existente entre los pokemon de tu equipo
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Instrucciones de uso:
-Ir a la dirección 0x0803A798 (función CreateMon) 
-Cambiar "F0 B5 47 46 80 B4 87 B0" por "80 B4 01 4F 38 47 C0 46 XX+1 XX XX 08" 
siendo "XX+1 XX XX 08" el pointer permutado a esta rutina. y el resto las instrucciones:
********************
	push {r7}
	ldr r7, =08XXXXXX+1
	bx r7
	nop
********************
-Elige un flag para controlar la rutina.
-Resta (o suma) la cantidad de niveles de diferencia deseado
-Compilar esta rutina e insertarla en "08 XX XX XX+1".
*/
/**********************
El juego crea todos los pokemon con la función "CreateMon" (@pokegba) en 08067B4C,
uno de los argumentos pasados a esta función es el nivel del pokemon, que es pasado
por el registro r2. Esta rutina modifica según nuestra conveniencia el valor de r2,
dejando el resto intacto y modificando así el nivel de los pokemon generados por el
juego.
***********************/
no_crash:				
	pop {r7}
	@Instrucciones de la rutina original
	push {r4-r7, r14}
	mov r7, r8
	push {r7}
	add sp, #-0x1C
	mov r8, r0
	mov r6, r1
	
flag_check:				@Se encarga de comprobar si hemos activado el flag
	push {r0-r2}
	ldr r0, flag_number
	ldr r2, flag_routine
	push {r1-r3}
	bl linker
	pop {r1-r3}
	cmp r0, #0x1
	bne routine_off
	pop {r0-r2}
	
main:				
	push {r3-r5}		
	ldr r3, party_lvl	@carga el puntero al nivel de los pokemon en r3
	ldrb r2, [r3]		@Carga el nivel del pokemon en r2
	mov r5, #0x5		@Establece el contador a 5 en r5
	
loop:
	add r3, #0x64		@Suma 0x64 al puntero para pasar al siguiente nivel
	ldrb r4, [r3]		@Carga el valor del segundo nivel en r4
	cmp r4, r2			@Compara ambos niveles
	ble continue		@Si el nivel de r4 es menor al de r2 lo deja tal cual está
	mov r2, r4			@Si el nivel de r4 es mayor lo escribe en r2-r5
	
continue:
	sub r5, r5, #0x1	@Resta uno al contador
	cmp r5, #0x0		@compara el contador con 0	
	bne loop			@Si el contador no ha llegado a 0 sigue ejecutando el bucle

ajuste:
	sub r2, r2, #0x0    @ Cambiar #0x0 por la cantidad de niveles a restar (cambiar la instrucción por add si queremos sumar)
	cmp r2, #0x0
	beq fixed_min
	cmp r2, #0x64
	bge fixed_max
	
end:
	pop {r3-r5}			@Popea los registros utilizados	
	
return:
	ldr r4, return_dir	@Vuelve a la rutina original
	bx r4
	
routine_off:
	pop {r0-r2}
	b return

linker:
	bx r2

fixed_max:				@Evita pokemon con nivel superior al 100
	mov r2, #0x64
	b end
	
fixed_min:				@Evita pokemon con niveles inferiores a 1
	mov r2, #0x1
	b end


.align 2
party_lvl:				@Puntero a los niveles del equipo
	.word 0x03004360 + 0x54
return_dir:				@Dirección de retorno de la rutina
	.word 0x0803A7A5
flag_routine:			@Dirección de la rutina que checkea el flag
	.word 0x08069340 +1
flag_number:			@Número del flag utilizado en la rutina
	.word 0x00000[XXX]	@Pon aquí el número de flag que desees, EJ: 406

Fire red


Código:
.thumb
.align 2

/********** setEnemyLevel = maxPartyLevel |@FRED|********
Establece el nivel de los pokemon enemigos (salvajes y entrenadores) de forma
dinámica, igualándolo al nivel máximo existente entre los pokemon de tu equipo
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Instrucciones de uso:
-Ir a la dirección 0x0803DA54 (función CreateMon) 
-Cambiar "F0 B5 47 46 80 B4 87 B0" por "80 B4 01 4F 38 47 C0 46 XX+1 XX XX 08" 
siendo "XX+1 XX XX 08" el pointer permutado a esta rutina. y el resto las instrucciones:
********************
	push {r7}
	ldr r7, =08XXXXXX+1
	bx r7
	nop
********************
-Compilar esta rutina e insertarla en "08 XX XX XX+1".
*/
/**********************
El juego crea todos los pokemon con la función "CreateMon" (@pokegba) en 0803DA54,
uno de los argumentos pasados a esta función es el nivel del pokemon, que es pasado
por el registro r2. Esta rutina modifica según nuestra conveniencia el valor de r2,
dejando el resto intacto y modificando así el nivel de los pokemon generados por el
juego.
***********************/


no_crash:				
	pop {r7}
	@Instrucciones de la rutina original
	push {r4-r7, r14}
	mov r7, r8
	push {r7}
	add sp, #-0x1C
	mov r8, r0
	mov r6, r1
	
flag_check:				@Se encarga de comprobar si hemos activado el flag
	push {r0-r2}
	ldr r0, flag_number
	ldr r2, flag_routine
	push {r1-r3}
	bl linker
	pop {r1-r3}
	cmp r0, #0x1
	bne routine_off
	pop {r0-r2}
	
main:				
	push {r3-r5}		
	ldr r3, party_lvl	@carga el puntero al nivel de los pokemon en r3
	ldrb r2, [r3]		@Carga el nivel del pokemon en r2
	mov r5, #0x5		@Establece el contador a 5 en r5
	
loop:
	add r3, #0x64		@Suma 0x64 al puntero para pasar al siguiente nivel
	ldrb r4, [r3]		@Carga el valor del segundo nivel en r4
	cmp r4, r2			@Compara ambos niveles
	ble continue		@Si el nivel de r4 es menor al de r2 lo deja tal cual está
	mov r2, r4			@Si el nivel de r4 es mayor lo escribe en r2-r5
	
continue:
	sub r5, r5, #0x1	@Resta uno al contador
	cmp r5, #0x0		@compara el contador con 0	
	bne loop			@Si el contador no ha llegado a 0 sigue ejecutando el bucle

ajuste:
	sub r2, r2, #0x0        @ Cambiar #0x0 por la cantidad de niveles a restar (cambiar la instrucción por add si queremos sumar)
	cmp r2, #0x0
	beq fixed_min
	cmp r2, #0x64
	bge fixed_max
	
end:
	pop {r3-r5}			@Popea los registros utilizados	
	
return:
	ldr r4, return_dir	@Vuelve a la rutina original
	bx r4
	
routine_off:
	pop {r0-r2}
	b return

linker:
	bx r2

fixed_max:				@Evita pokemon con nivel superior al 100
	mov r2, #0x64
	b end
	
fixed_min:				@Evita pokemon con niveles inferiores a 1
	mov r2, #0x1
	b end

	
.align 2
party_lvl:				@Puntero a los niveles del equipo
	.word 0x02024284 + 0x54
return_dir:				@Dirección de retorno de la rutina
	.word 0x0803DA60 + 1
flag_routine:			@Dirección de la rutina que checkea el flag
	.word 0x0806E6D0 + 1
flag_number:			@Número del flag utilizado en la rutina
	.word 0x00000[XXX]	@Pon aquí el número de flag que desees, EJ: 406

Emerald

Código:
.thumb
.align 2

/********** setEnemyLevel = maxPartyLevel |@EMERALD|********
Establece el nivel de los pokemon enemigos (salvajes y entrenadores) de forma
dinámica, igualándolo al nivel máximo existente entre los pokemon de tu equipo
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Instrucciones de uso:
-Ir a la dirección 0x08067B4C (función CreateMon) 
-Cambiar "F0 B5 47 46 80 B4 87 B0" por "80 B4 01 4F 38 47 C0 46 XX+1 XX XX 08" 
siendo "XX+1 XX XX 08" el pointer permutado a esta rutina. y el resto las instrucciones:
********************
	push {r7}
	ldr r7, =08XXXXXX+1
	bx r7
	nop
********************
-Elige un flag para controlar la rutina.
-Resta (o suma) la cantidad de niveles de diferencia deseado
-Compilar esta rutina e insertarla en "08 XX XX XX+1".
*/
/**********************
El juego crea todos los pokemon con la función "CreateMon" (@pokegba) en 08067B4C,
uno de los argumentos pasados a esta función es el nivel del pokemon, que es pasado
por el registro r2. Esta rutina modifica según nuestra conveniencia el valor de r2,
dejando el resto intacto y modificando así el nivel de los pokemon generados por el
juego.
***********************/
no_crash:				
	pop {r7}
	@Instrucciones de la rutina original
	push {r4-r7, r14}
	mov r7, r8
	push {r7}
	add sp, #-0x1C
	mov r8, r0
	mov r6, r1
	
flag_check:				@Se encarga de comprobar si hemos activado el flag
	push {r0-r2}
	ldr r0, flag_number
	ldr r2, flag_routine
	push {r1-r3}
	bl linker
	pop {r1-r3}
	cmp r0, #0x1
	bne routine_off
	pop {r0-r2}
	
main:				
	push {r3-r5}		
	ldr r3, party_lvl	@carga el puntero al nivel de los pokemon en r3
	ldrb r2, [r3]		@Carga el nivel del pokemon en r2
	mov r5, #0x5		@Establece el contador a 5 en r5
	
loop:
	add r3, #0x64		@Suma 0x64 al puntero para pasar al siguiente nivel
	ldrb r4, [r3]		@Carga el valor del segundo nivel en r4
	cmp r4, r2			@Compara ambos niveles
	ble continue		@Si el nivel de r4 es menor al de r2 lo deja tal cual está
	mov r2, r4			@Si el nivel de r4 es mayor lo escribe en r2-r5
	
continue:
	sub r5, r5, #0x1	@Resta uno al contador
	cmp r5, #0x0		@compara el contador con 0	
	bne loop			@Si el contador no ha llegado a 0 sigue ejecutando el bucle

ajuste:
	sub r2, r2, #0x0                @ Cambiar #0x0 por la cantidad de niveles a restar (cambiar la instrucción por add si queremos sumar)
	cmp r2, #0x0
	beq fixed_min
	cmp r2, #0x64
	bge fixed_max
	
end:
	pop {r3-r5}			@Popea los registros utilizados	
	
return:
	ldr r4, return_dir	@Vuelve a la rutina original
	bx r4
	
routine_off:
	pop {r0-r2}
	b return

linker:
	bx r2

fixed_max:				@Evita pokemon con nivel superior al 100
	mov r2, #0x64
	b end
	
fixed_min:				@Evita pokemon con niveles inferiores a 1
	mov r2, #0x1
	b end

	
.align 2
party_lvl:				@Puntero a los niveles del equipo
	.word 0x020244EC + 0x54
return_dir:				@Dirección de retorno de la rutina
	.word 0x08067B59
flag_routine:			@Dirección de la rutina que checkea el flag
	.word 0x0809D790 +1
flag_number:			@Número del flag utilizado en la rutina
	.word 0x00000[XXX]	@Pon aquí el número de flag que desees, EJ: 406


Funcionamiento de la rutina:
La rutina irá comparando el nivel de cada uno de los pokemon de vuestro equipo para quedarse con el nivel máximo del mismo. Una vez tenga este dato, lo utilizará para alterar el nivel del pokemon enemigo. La rutina puede activarse o desactivarse utilizando un flag.

Guía para instalar la rutina


En primer abrimos el rom con HxD y vamos a "0803DA54" (FRED) o "08067B4C" (EM) y escribimos los siguientes bytes:
Código:
80 B4 01 4F 38 47 C0 46 XX+1 XX XX 08
@XX+1 XX XX 08 es el offset permutado +1 donde vayáis a insertar la rutina

Una vez realizados estos cambios dentro del rom, vamos a modificar la rutina ASM según nuestras necesidades:
-Colocar el Flag que deseamos utilizar para activar/desactivar la rutina
Código:
flag_number:			
	.word 0x00000[XXX]	@En XXX escribir el número del flag EJ: 406

-Elegir la cantidad de niveles por debajo (o por encima) a los que debe encontrarse el pokemon rival.
Código:
sub r2, r2, #0x0         
@Camb
iar #0x0 por la cantidad de niveles a restar (cambiar la instrucción por add si queremos sumar)

-Compilamos la rutina y la insertamos en "08XXXXXX". Cuando el flag seleccionado este activado (setflag 0x???) la rutina modificará el nivel de los pokemon generados por el juego.

Cambios sugeridos en la rutina


Como ya os he dicho, esta rutina es una base que podéis hacer crecer para cumplir vuestras necesidades, sin tener que saber prácticamente nada de ASM (solo lo más básico). Algunas de las posibles modificaciones que se me ocurren (algunas las he llevado a cabo yo en mi propia rutina) son las siguientes:
  • -Utilizar el nivel medio de tu equipo para calcular el nivel de los pokemon salvajes en lugar del nivel máximo del equipo. (Tan fácil como sumar los niveles de todos los pokemon del equipo, dividirlo entre el número de pokemon y pasar el resultado a r2). Para dividir utilizar la instrucción "SWI 0xC" que realizará la operación r0/r1 dando el resultado en r0.
  • -Introducir un factor aleatorio que le sume o le reste algo a los niveles.(como generador de números aleatorios podéis utilizar los milisegundos del reloj del juego).
  • Hacer distintas cosas en función del tipo de pokemon que se va a generar (el número del pokemon en HEX está en el r1)


Si alguien tiene algún problema modificando la rutina tiene alguna duda que lo ponga por aquí e intentaré ayudarle.
Al final se me ha hecho muy tarde, pero dije que lo subía y lo subo. Aunque solo sea por lo poco que queda de mi orgullo. Y puede que también porque llevo un mes sin postear¿?¿?¿?.

Decir que he puesto el flag a petición de @kakarotto y creo que nada más. Mañana subo el otro tutorial que dije que iba a subir este fin de semana (xD). Ah si, también summonear a @Ωmega que dijo que quería verlo.

Edit: Me gustaría saber porque el foro se empeña en dar por culo y joderme las tabulaciones del notepad++.
Edit2: De verdad tenía que haber un usuario llamado @Camb que me joda los comentarios del ASM por que pilla @ cambiar como una mención? Mi bida es miserable. Cuando sea anciano crearé a dark Miutu y dejaré huérfano a alguien.


EDIT: Añadida versión para ruby.

Última edición por Samu; 30/03/2018 a las 00:22
  #2  
29/01/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Uff, que aportazo! Para Fire Red y Emerald >.<, asi nadie se puede quejar x'D

Últimamente me ha dado el gusanillo de ROM Hackear y me preguntaba sobre aquella rutina que yo usaba para subir el nivel de los Pokémon salvajes, y no me acababa de convencer... Viendo esto, y suponiendo que no es solo para Pokémon salvajes, pues facilita mucho las cosas! Cambiando la parte de 'ajuste' se puede adaptar la rutina facilmente.

Bravo, muy buen trabajo ^^. La probaré en unos días cuando me decida a retomar mi trabajo xD

Este tío es un...



Zero for GMod
  #3  
29/01/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
¡Esto es INCREÍBLE!

Un aportazo sin duda alguna, no había visto a profundidad la rutina de eing por lo que desconocía si tenía errores, además en un alivio saberlo, ya que usaré la tuya 100% seguro. Me parece algo realmente muy útil, puesto que le da más equilibrio, dificultad y competitividad al juego, ya que muchos al no saber esto, y optan por poner muchos niveles de más, cosa que lo hace muy aburrido por tener que levelear y demás. Poco más puedo decir, ya la probaré cuando sea el momento

Se despide, MichaKing~
El sistema de firmas no funciona correctamente. Por favor, contacte con su proveedor.

  #4  
29/01/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Nada que objetar @Samu ... tus aportes siempre tienen una calidad exquisita y me hiciste caso lo cual se agradece. Espero darle un gran uso a tu mecánica.
  #5  
01/02/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Dicho por sosilumi Ver mensaje
Lo siento por preguntarlo, pero, ¿podría usted pasarme esa rutina( Pokémon Emerald) sin los comentarios que tiene en ella?
Sí claro... por poder sin problema..

Spoiler


Código:
.thumb
.align 2

no_crash:				
	pop {r7}
	push {r4-r7, r14}
	mov r7, r8
	push {r7}
	add sp, #-0x1C
	mov r8, r0
	mov r6, r1
	
flag_check:				
	push {r0-r2}
	ldr r0, flag_number
	ldr r2, flag_routine
	push {r1-r3}
	bl linker
	pop {r1-r3}
	cmp r0, #0x1
	bne routine_off
	pop {r0-r2}
	
main:				
	push {r3-r5}		
	ldr r3, party_lvl	
	ldrb r2, [r3]		
	mov r5, #0x5		
	
loop:
	add r3, #0x64		 
	ldrb r4, [r3]		
	cmp r4, r2			
	ble continue		
	mov r2, r4			
	
continue:
	sub r5, r5, #0x1	
	cmp r5, #0x0			
	bne loop			

ajuste:
	sub r2, r2, #0x0                
	cmp r2, #0x0
	beq fixed_min
	cmp r2, #0x64
	bge fixed_max
	
end:
	pop {r3-r5}				
	
return:
	ldr r4, return_dir	
	bx r4
	
routine_off:
	pop {r0-r2}
	b return

linker:
	bx r2

fixed_max:				
	mov r2, #0x64
	b end
	
fixed_min:				
	mov r2, #0x1
	b end

	
.align 2
party_lvl:				
	.word 0x020244EC + 0x54
return_dir:				
	.word 0x08067B59
flag_routine:			
	.word 0x0809D790 +1
flag_number:			
	.word 0x00000[XXX]


Por curiosidad, ¿Cuál es el problema con los comentarios? xD. Y una última cosa y sin intención de ser demasiado borde, ¿Tan difícil era quitarlos? xDDDDD.
Gracias: sosilumi
  #6  
26/03/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Esto es un excelente aporte a la comunidad, de seguro me servir para hacer mi hack rom mas difícil, aunque si voy a la liga con Pokemon nivel 6 el campeón tendrá Pokemons nivel 6 xD, de seguro lo usare

Salu2
  #7  
26/03/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Sin duda esto es un excelente tutorial, bastante bueno y muy completo para estas 2 Roms, que le puede servir a muchos de aquí. Hiciste un gran esfuerzo de tú parte, sigue así!

-Acosta
Sin dolor, no hay honor. Sin esfuerzo, no hay éxito.

Lo único imposible es aquello que no intentas.

Siempre hay un momento en el que puedes darle cuerda de nuevo.


Acosta #5347

  #8  
30/03/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Debido a que me lo han pedido un par de personas, he añadido la versión para ruby de la rutina. Todo lo dicho y explicado para las rutinas de emerald/fred se aplica también para la rutina de ruby.

Ruby

Código:
.thumb
.align 2

/********** setEnemyLevel = maxPartyLevel |@RUBY|********
Establece el nivel de los pokemon enemigos (salvajes y entrenadores) de forma
dinámica, igualándolo al nivel máximo existente entre los pokemon de tu equipo
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Instrucciones de uso:
-Ir a la dirección 0x0803A798 (función CreateMon) 
-Cambiar "F0 B5 47 46 80 B4 87 B0" por "80 B4 01 4F 38 47 C0 46 XX+1 XX XX 08" 
siendo "XX+1 XX XX 08" el pointer permutado a esta rutina. y el resto las instrucciones:
********************
	push {r7}
	ldr r7, =08XXXXXX+1
	bx r7
	nop
********************
-Elige un flag para controlar la rutina.
-Resta (o suma) la cantidad de niveles de diferencia deseado
-Compilar esta rutina e insertarla en "08 XX XX XX+1".
*/
/**********************
El juego crea todos los pokemon con la función "CreateMon" (@pokegba) en 08067B4C,
uno de los argumentos pasados a esta función es el nivel del pokemon, que es pasado
por el registro r2. Esta rutina modifica según nuestra conveniencia el valor de r2,
dejando el resto intacto y modificando así el nivel de los pokemon generados por el
juego.
***********************/
no_crash:				
	pop {r7}
	@Instrucciones de la rutina original
	push {r4-r7, r14}
	mov r7, r8
	push {r7}
	add sp, #-0x1C
	mov r8, r0
	mov r6, r1
	
flag_check:				@Se encarga de comprobar si hemos activado el flag
	push {r0-r2}
	ldr r0, flag_number
	ldr r2, flag_routine
	push {r1-r3}
	bl linker
	pop {r1-r3}
	cmp r0, #0x1
	bne routine_off
	pop {r0-r2}
	
main:				
	push {r3-r5}		
	ldr r3, party_lvl	@carga el puntero al nivel de los pokemon en r3
	ldrb r2, [r3]		@Carga el nivel del pokemon en r2
	mov r5, #0x5		@Establece el contador a 5 en r5
	
loop:
	add r3, #0x64		@Suma 0x64 al puntero para pasar al siguiente nivel
	ldrb r4, [r3]		@Carga el valor del segundo nivel en r4
	cmp r4, r2			@Compara ambos niveles
	ble continue		@Si el nivel de r4 es menor al de r2 lo deja tal cual está
	mov r2, r4			@Si el nivel de r4 es mayor lo escribe en r2-r5
	
continue:
	sub r5, r5, #0x1	@Resta uno al contador
	cmp r5, #0x0		@compara el contador con 0	
	bne loop			@Si el contador no ha llegado a 0 sigue ejecutando el bucle

ajuste:
	sub r2, r2, #0x0    @ Cambiar #0x0 por la cantidad de niveles a restar (cambiar la instrucción por add si queremos sumar)
	cmp r2, #0x0
	beq fixed_min
	cmp r2, #0x64
	bge fixed_max
	
end:
	pop {r3-r5}			@Popea los registros utilizados	
	
return:
	ldr r4, return_dir	@Vuelve a la rutina original
	bx r4
	
routine_off:
	pop {r0-r2}
	b return

linker:
	bx r2

fixed_max:				@Evita pokemon con nivel superior al 100
	mov r2, #0x64
	b end
	
fixed_min:				@Evita pokemon con niveles inferiores a 1
	mov r2, #0x1
	b end


.align 2
party_lvl:				@Puntero a los niveles del equipo
	.word 0x03004360 + 0x54
return_dir:				@Dirección de retorno de la rutina
	.word 0x0803A7A5
flag_routine:			@Dirección de la rutina que checkea el flag
	.word 0x08069340 +1
flag_number:			@Número del flag utilizado en la rutina
	.word 0x00000[XXX]	@Pon aquí el número de flag que desees, EJ: 406
  #9  
30/03/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Sin duda un muy buen tutorial, y bastante completo en verdad, seguro les sirve a muchos, y lo traes para las 3 roms asi nadie se puede quejar xD, muy buen trabajo de tu parte.

Un saludo!!
  #10  
09/05/2018
Predeterminado Respuesta: [ASM] Nivel dinámico de los pokemon rivales
Me hacía falta que el nivel del Pokémon pudiera variar, me explico, que no fuera siempre el mismo que el de tu Pokémon más fuerte, o siempre tres niveles por encima, sino que según la situación fuera más o menos niveles por encima.
Así que he modificado un poco la rutina para que haga lo que yo quería.

Como bien sabréis, controlo de scripting, no de ASM, así que no descarto que sea optimizable o tenga algo mal.
La he probado y ha funcionado de lujo, el funcionamiento es sencillo, antes del combate hacer un setvar 0x8000 0xPlus, donde Plus es el número de niveles extra que queráis sumarle.

La rutina modificada

Código:
.thumb
.align 2

/********** setEnemyLevel = maxPartyLevel |@FRED|********
Establece el nivel de los pokemon enemigos (salvajes y entrenadores) de forma
dinámica, igualándolo al nivel máximo existente entre los pokemon de tu equipo
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Instrucciones de uso:
-Ir a la dirección 0x0803DA54 (función CreateMon) 
-Cambiar "F0 B5 47 46 80 B4 87 B0" por "80 B4 01 4F 38 47 C0 46 XX+1 XX XX 08" 
siendo "XX+1 XX XX 08" el pointer permutado a esta rutina. y el resto las instrucciones:
********************
	push {r7}
	ldr r7, =08XXXXXX+1
	bx r7
	nop
********************
-Compilar esta rutina e insertarla en "08 XX XX XX+1".
*/
/**********************
El juego crea todos los pokemon con la función "CreateMon" (@pokegba) en 0803DA54,
uno de los argumentos pasados a esta función es el nivel del pokemon, que es pasado
por el registro r2. Esta rutina modifica según nuestra conveniencia el valor de r2,
dejando el resto intacto y modificando así el nivel de los pokemon generados por el
juego.
***********************/


no_crash:				
	pop {r7}
	@Instrucciones de la rutina original
	push {r4-r7, r14}
	mov r7, r8
	push {r7}
	add sp, #-0x1C
	mov r8, r0
	mov r6, r1
	
flag_check:				@Se encarga de comprobar si hemos activado el flag
	push {r0-r2}
	ldr r0, flag_number
	ldr r2, flag_routine
	push {r1-r3}
	bl linker
	pop {r1-r3}
	cmp r0, #0x1
	bne routine_off
	pop {r0-r2}
	
main:				
	push {r3-r5}		
	ldr r3, party_lvl	@carga el puntero al nivel de los pokemon en r3
	ldrb r2, [r3]		@Carga el nivel del pokemon en r2
	mov r5, #0x5		@Establece el contador a 5 en r5
	
loop:
	add r3, #0x64		@Suma 0x64 al puntero para pasar al siguiente nivel
	ldrb r4, [r3]		@Carga el valor del segundo nivel en r4
	cmp r4, r2			@Compara ambos niveles
	ble continue		@Si el nivel de r4 es menor al de r2 lo deja tal cual está
	mov r2, r4			@Si el nivel de r4 es mayor lo escribe en r2-r5
	
continue:
	sub r5, r5, #0x1	@Resta uno al contador
	cmp r5, #0x0		@compara el contador con 0	
	bne loop			@Si el contador no ha llegado a 0 sigue ejecutando el bucle

ajuste:
	ldr r3, .Variable @Esta es la parte que he añadido, junto a las dos siguientes líneas
	ldrh r3, [r3]
	add r2, r2, r3
	cmp r2, #0x0
	beq fixed_min
	cmp r2, #0x64
	bge fixed_max
	
end:
	pop {r3-r5}			@Popea los registros utilizados	
	
return:
	ldr r4, return_dir	@Vuelve a la rutina original
	bx r4
	
routine_off:
	pop {r0-r2}
	b return

linker:
	bx r2

fixed_max:				@Evita pokemon con nivel superior al 100
	mov r2, #0x64
	b end
	
fixed_min:				@Evita pokemon con niveles inferiores a 1
	mov r2, #0x1
	b end

	
.align 2
party_lvl:				@Puntero a los niveles del equipo
	.word 0x02024284 + 0x54
return_dir:				@Dirección de retorno de la rutina
	.word 0x0803DA60 + 1
flag_routine:			@Dirección de la rutina que checkea el flag
	.word 0x0806E6D0 + 1
flag_number:			@Número del flag utilizado en la rutina
	.word 0x00000[XXX]	@Pon aquí el número de flag que desees, EJ: 406
.Variable:
	.word 0x020270B8 + (0x8000 * 2) @Podéis cambiar esta variable por otra de las variables dinámicas
Gracias: Subzero y Samu
Respuesta

Etiquetas
asm , gba , nivel , pokémon

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 14:13.