Notifiquese: Que el Grupo POSITRON, en persona de su representante @Juanjo considere que esta investigación sea abierta al público debido a que el grupo POSITRON no se encuentra en su mejor momento ni sus miembros están completamente enfocados en su subforo y al mismo tiempo incitar a la generación de nuevos miembros.
PRESENTA:
PRESENTA:
¿CÓMO CRIAR POKéMON SHINY EN TERCERA GENERACIÓN?
PSEB System - Positron Shiny Egg Breeding System
INTRODUCCIÓN
INTRODUCCIÓN
Como muchos sabrán en los juegos de segunda generación era genial poder criar pokémon shinys, es decir si lograbas conseguir uno de estos raros especímenes al criar en la guardería obtenías un 1.5% de posibilidad (1/64) de tener un huevo del que nacería un pokémon shiny.
Para tercera generación esto se perdió. Y los pokémon shiny quedaron relegados a un simple azar y no a una mutación genética que me gustaba más.
MISIÓN
Lograr que la guardería de tercera generación logre generar ese 1.5% de probabilidad de generar un huevo shiny si el padre o la madre es shiny.
PROCEDIMIENTO
- Estudiar el script de la guardería.
- Lograr que el huevo que entregue sea shiny, aún cuando no existe un giveegg.
- Controlar la probabilidad del 15 mediante vars y flags.
- Que al recibir un pokemon en la guardería se permita analizarlo.
- Identificar que un Pokémon sea Shiny.
LOGROS CONSEGUIDOS
ESTUDIAR EL SCRIPT DE LA GUARDERÍA: Al investigarlo he descubierto que el special 0xB5 genera en el [Buffer1] y en el [Buffer2] los Pokémon de la guardería (Y hace algunas cosas más que no he descubierto).
El special2 LASTRESULT 0xB6 devuelve en la variable LASTRESULT un número que:
0x0 = No tienes Pokes y se presenta.
0x1 = Te va a dar un huevo.
0x2 = Tienes un solo Poke en la guardería y te dice que está bien.
0x3 = Tienes 2 Pokes en la guardería y te dice que están bien.
La parte del script que interesa es:
Código:
#org 0x1B22B2
preparemsg 0x81B27A2 '"[player] received the EGG from\nth..."
fanfare 0x16F
waitfanfare
waitmsg
waitkeypress
msgbox 0x81B27CD MSG_KEEPOPEN '"Take good care of it."
special 0xB8
clearflag 0x86
release
end
LOGRAR QUE EL HUEVO SEA SHINY: Aún así introduciendo la rutina del shinyzer:
Código:
#org 0x71234A
checkflag 0x1234
if 0x1 call 0x871243C
preparemsg 0x81B27A2 '"[player] received the EGG from\nth..."
fanfare 0x16F
waitfanfare
waitmsg
waitkeypress
msgbox 0x81B27CD MSG_KEEPOPEN '"Take good care of it."
special 0xB8
clearflag 0x86
clearflag 0x1234
release
end
'---------------
#org 0x71243C
setvar 0x8003 0x1
return
La ventaja de hacer esto es que da independencia total de si el huevo es shiny o no, y el viejo solamente mirara si la flag externa está activa o no. (A este paso lo llamé la palanca de radioactividad de la guardería
CONTROLAR LA PROBABILIDAD DEL 15%:
A pesar de que realmente sera de 1.5%, se ha investigado para un 15% (es más fácil para probarlo pero el valor al final puede ser corregido perfectamente).
Bueno, no se mucho de como se manejan los eventos aleatorios del juego (Supongo que a muy bajo nivel hacen operaciones con bytes y comparan si el resultado están entre algún rango, o algo por el estilo).
Un 15% significa que de 100 posibilidades, 15 son aciertos. Es decir si una variable aleatoria toma 100 posibles valores, 15 de ellos serán aciertos. Por lo que me fui a la fácil: Generar una variable aleatoria random y evaluar los aciertos. ¡Por supuesto no iba a tomar 100 valores y tomar 15 como aciertos! simplemente 15/100 = 3/20. Una variable que toma 20 posiciones de los cuales 3 son aciertos:
Código:
'---------------
#org 0x712393
random 0x14
copyvar 0x50FE LASTRESULT
buffernumber 0x2 0x50FE
compare 0x50FE 0x0
if 0x1 goto 0x8712457
compare 0x50FE 0x1
if 0x1 goto 0x8712457
compare 0x50FE 0x2
if 0x1 goto 0x8712457
msgbox 0x87123EF MSG_FACE '"[buffer3] No hay huevos shiny."
end
'---------------
#org 0x712457
msgbox 0x8170CA7 MSG_FACE '"[buffer3] Hay huevos shiny."
setflag 0x1234
end
'---------
' Strings
'---------
#org 0x7123EF
= [buffer3] No hay huevos shiny.
#org 0x170CA7
= [buffer3] Hay huevos shiny.
Aquí pueden ver esto funcionando:
DETERMINAR SI EL POKéMON ES SHINY:
Gracias al método descrito por Mastermind_X, y planteado por @Javi4315♪ lo que define que un Pokémon sea Shiny o no es su personalidad que lo podemos obtener como los 4 primeros bytes de la información de un Pokémon (Para más información pueden ver esta investigación de @Gershel.
Esos cuatro bytes definen la personalidad del pokemon. Otro dato importante es la ID de entrenador (Que vemos en la TrainerCard) y la ID de entrenador secreta (Un número también aleatorio que no podemos ver).
La fórmula para saber si pokémon es Shiny es:
Trainer ID ⊕ Secret ID ⊕ P1 ⊕ P2
Donde:
Trainer ID, es la ID del TrainerCard que podemos ver en la dirección 0x02024EAE (2 Bytes).
Secret ID, es la ID secreta del Trainer que podemos ver en la dirección 0x02024EB0 (2 Bytes).
P1, son los 2 primeros bytes de la personalidad del pokémon.
P2, son los 2 últimos bytes de la personalidad del pokémon.
⊕, es el operador XOR.
El resultado de esta operación debe dar un valor en hexadecimal que si es menor a 08, entonces el Pokémon es Shiny.
Investigando un poco (Y jugando con los bytes) He descubierto que al almacenar un pokemón en la guardería podemos conseguir la personalidad del pokémon almacenado directamente (Sin tener que buscar cual pokémon del equipo insertamos):
0x20286D0 -> Primer Pokémon de la Guardería
0x2028720 -> Segundo Pokémon de la Guardería
Con esto para identificar un Pokémon Shiny habría que hacer esta operación. (Se requiere ASM para poder hacer XOR).
Gracias a @Cheve_X, tenemos una rutina específicamente diseñada para retornar el resultado de la operación para el primer pokemon de la guardería:
INSERTARLO EN EL SCRIPT DE LA GUARDERÍAPara aquellos con problemas en pasarla a HEX...Código:.text .align 2 .thumb .thumb_func .global lesson1 main: push {r0-r4, lr} ldr r4, .PKMN_DATA ldrh r0, [r4] ldrh r2, [r4, #0X2] EOR r0, r2 ldr r4, .PKMN_DATA2 ldrh r3, [r4] ldr r4, .PKMN_DATA3 ldrh r2, [r4] EOR r3, r2 EOR r0,r3 ldr r1, .VAR strh r0, [r1] pop {r0-r1, pc} .align 2 .PKMN_DATA: .word 0x20286D0 .PKMN_DATA2: .word 0x2024EB0 .PKMN_DATA3: .word 0x2024EAE .VAR: .word 0x0201E8C2 + (0x800D * 2)
Deben copiar ese código en un Offset vacío que termine en 0, 4, 8 o C, luego deberan usar un callasm a esa direccion+1Código:1F B5 06 4C 20 88 62 88 50 40 05 4C 23 88 05 4C 22 88 53 40 58 40 04 49 08 80 03 BD D0 86 02 02 B0 4E 02 02 AE 4E 02 02 DC E8 02 02
Si por ejemplo lo ponen en 0x700000 un script simple con ésto funcionando sería así:
Código:#include std.rbh #DYNAMIC 0x800000 #org @Inicio callasm 0x700001 compare LASTRESULT 0x8 if B_> call @NoShiny msgbox @sms1 MSG_NORMAL end #org @NoShiny msgbox @sms2 MSG_NORMAL '"o hay un Shiny" end #org @sms1 = Hay un Shiny #org @sms2 = No hay un Shiny
Como la rutina de Cheve solo identifica si un Pokemon es shiny (y no el segundo dos), he creado una segunda rutina (Que es igual pero carga el segundo Pokémon)
Código:
88 53 40 58 40 04 49 08 80 03 BD D0 86 02 02 B0 4E 02 02 AE 4E 02 02 DC E8 02 02 FF 1F B5 06 4C 20 88 62 88 50 40 05 4C 23 88 05 4C 22 88 53 40 58 40 04 49 08 80 03 BD 20 87 02 02 B0 4E 02 02 AE 4E 02 02 DC E8 02 02
Código:
'---------------
#include std.rbh
#dynamic 0x712345
#org @Inicio
callasm 0x700001
compare LASTRESULT 0x8
if B_< call [MENTION=31325]Sis[/MENTION]hiny
callasm 0x70000D
compare LASTRESULT 0x8
if B_< call [MENTION=31325]Sis[/MENTION]hiny
msgbox @sms2 MSG_NORMAL
end
#org [MENTION=31325]Sis[/MENTION]hiny
msgbox @sms1 MSG_NORMAL
goto @Proba
end
#org @sms1
= Hay un Shiny
#org @sms2
= No hay un Shiny
#org @Proba
random 0x14
copyvar 0x50FE LASTRESULT
buffernumber 0x2 0x50FE
compare 0x50FE 0x0
if 0x1 goto 0x8712457
compare 0x50FE 0x1
if 0x1 goto 0x8712457
compare 0x50FE 0x2
if 0x1 goto 0x8712457
msgbox 0x87123EF MSG_FACE '"[buffer3] No hay huevos shiny."
end
'---------------
#org 0x712457
msgbox 0x8170CA7 MSG_FACE '"[buffer3] Hay huevos shiny."
setflag 0x1234
end
'---------
' Strings
'---------
#org 0x7123EF
= [buffer3] No hay huevos shiny.
#org 0x170CA7
= [buffer3] Hay huevos shiny.
He insertado la rutina en 0x700000, recuerden que esta incluye una segunda rutina en 0x70000C.
Les dejo el script completo de la guardería con el 100% de esta investigación y listo para usarse: (Con el 1.5%)
Código:
'---------------
#include std.rbh
#dynamic 0x712345
#org 0x1B222D
lock
faceplayer
special 0xB5
special2 LASTRESULT 0xB6
compare LASTRESULT 0x1
if 0x1 goto 0x81B2262
compare LASTRESULT 0x2
if 0x1 goto 0x81B22E7
compare LASTRESULT 0x3
if 0x1 goto 0x81B22FE
msgbox 0x81B25CB MSG_KEEPOPEN '"I'm the DAY-CARE MAN.\pI help take..."
release
end
'---------------
#org 0x1B2262
msgbox 0x81B2659 MSG_YESNO '"Ah, it's you!\pWe were raising you..."
compare LASTRESULT 0x1
if 0x1 goto 0x81B2298
msgbox 0x81B28C4 MSG_YESNO '"ine."
compare LASTRESULT 0x1
if 0x1 goto 0x81B2298
msgbox 0x81B2745 MSG_KEEPOPEN '" ell then, I'll keep it.\nThanks!"
clearflag 0x86
special 0xB7
release
end
'---------------
#org 0x1B22E7
special 0xB5
msgbox 0x81B2710 MSG_KEEPOPEN '"Ah, it's you! Good to see you.\nYo..."
setvar 0x8004 0x0
call 0x81B22CD
release
end
'---------------
#org 0x1B22FE
special 0xB5
msgbox 0x81B2897 MSG_KEEPOPEN '"Ah, it's you! Your [buffer1] and\n..."
special 0xB9
special 0x8D
waitmsg
waitkeypress
setvar 0x8004 0x0
call 0x81B22CD
setvar 0x8004 0x1
call 0x81B22CD
release
end
'---------------
#org 0x1B2298
special2 LASTRESULT 0x83
compare LASTRESULT 0x6
if 0x5 goto 0x871234A
msgbox 0x81B2766 MSG_KEEPOPEN '"You have no room for it...\nCome b..."
release
end
'---------------
#org 0x1B22CD
clearflag 0x86
release
end
'---------------
#org 0x71234A
call @BusqueShiny
preparemsg 0x81B27A2 '"[player] received the EGG from\nth..."
fanfare 0x16F
waitfanfare
waitmsg
waitkeypress
msgbox 0x81B27CD MSG_KEEPOPEN '"Take good care of it."
special 0xB8
clearflag 0x86
clearflag 0x1234
release
end
'---------------
#org @BusqueShiny
callasm 0x700001
compare LASTRESULT 0x8
if B_< call [MENTION=31325]Sis[/MENTION]hiny
callasm 0x70000D
compare LASTRESULT 0x8
if B_< call [MENTION=31325]Sis[/MENTION]hiny
return
#org [MENTION=31325]Sis[/MENTION]hiny
random 0x40
compare LASTRESULT 0x0
if 0x1 goto @NaceShiny
return
#org @NaceShiny
setvar 0x8003 0x1
return
'---------
' Strings
'---------
#org 0x1B25CB
= I'm the DAY-CARE MAN.\pI help take care of the precious\nPOKéMON of TRAINERS.\pIf you'd like me to raise your POKéMON,\nhave a word with my wife.
#org 0x1B2659
= Ah, it's you!\pWe were raising your POKéMON, and my\ngoodness, were we surprised!\pYour POKéMON had an EGG!\pWe don't know how it got there,\nbut your POKéMON had it.\pYou do want it, yes?
#org 0x1B28C4
= ine.
#org 0x1B2745
= ell then, I'll keep it.\nThanks!
#org 0x1B2710
= Ah, it's you! Good to see you.\nYour [buffer1]'s doing fine.
#org 0x1B2897
= Ah, it's you! Your [buffer1] and\n[buffer2] are doing fine.
#org 0x1B2766
= You have no room for it...\nCome back when you've made room.
#org 0x1B27A2
= [player] received the EGG from\nthe DAY-CARE MAN.
#org 0x1B27CD
= Take good care of it.
EN RESUMEN
Este sistema hace que si alguno de los padres de un huevos es shiny genere un 1.5% de que el pokémon del huevo nazca Shiny.
Investigación iniciada a los 14 día del primer mes de 2014
Investigación principal finalizada a los 18 días del primer mes de 2014. Queda abierta a extensiones, mejores, adaptaciones [FR] y desarrollos posteriores de elementos descubiertos.
AGRADECIMIENTOS
-A @Serg!o, por su apoyo, ayuda y estar siempre dispuesto a resolverme dudas.
-A @Javi4315♪, por ayudarme y estar respaldando la investigación.
-A @Cheve_X, Por su granito de arena por el que pude completar la investigación.
-A @BLAx, por su interés y querer ayudar.
-Al grupo POSITRON.
-A la Comunidad Whack a Hack! en general
Firman:
Juanjo - Grupo POSITRON
Ha nacido el PSEB System - Positron Shiny Egg Breeding System
Última edición por un moderador: