Registrarse

[ASM] FR, E | Wonder Trade

Bugrhak

A long time ago I used to call myself "Subzero".
Respuesta: FR y EM | Scripting | Wonder Trade

Lunos dijo:
El callasm no funciona correctamente antes del givepokemon, por eso puse la comprobación del equipo de el Jugador. Eres libre de probarlo tú mismo, ponte 6 Pokémon y activa el script, perderás uno de tus Pokémon.
Si lo digo es precisamente porque YA LO PROBÉ tanto en RF, como en FR. Y no lo probé una, dos, ni tres veces, si no que intercambié todo el equipo. ¿Y que crees? No me surgió ningún tipo de error aunque increíble te parezca.

Es mas, examine la rutina, y tal y como está echa, no tendría que darte el error que te da a ti puesto que esta eliminando un Pokémon que éste en un slot, slot que se determina por la variable 8004, si no me equivoco.
Si no te funciona correctamente, pon un "pause" entre el callasm y el givepokemon, para darle tiempo a que ambas instrucciones se ejecuten correctamente y no una sobre la otra, por así decirlo.

Lunos dijo:
Rechazado, el punto del Intercambio Prodigioso es que el resultado sea aleatorio. Vos entregás un Pokémon y recibís uno a cambio sin saber cual Pokémon será. Perfectamente puedes recibir exactamente el mismo Pokémon que entregaste (recordemos que la función en X/Y es de Jugador a Jugador, no de Jugador a IA).
Lunos dijo:
Rechazado. Vos entregás un Pokémon y recibís uno a cambio sin saber cual Pokémon será, ese es el punto.
¿Rechazado? T_T

¡Sin palabras, colega!

Al igual y como TU mismo dices más arriba, cada quien que use el script, es libre de añadirle "detallas".
No veo donde quepa el rechazo por querer compartir una " versión" un tanto más "personal" del script.
 

Lunos

Enfrentando a La Organización
Miembro insignia
Re: Respuesta: FR y EM | Scripting | Wonder Trade

♠Subzero♠;399349 dijo:
Si lo digo es precisamente porque YA LO PROBÉ tanto en RF, como en FR. Y no lo probé una, dos, ni tres veces, si no que intercambié todo el equipo. ¿Y que crees? No me surgió ningún tipo de error aunque increíble te parezca.

Es mas, examine la rutina, y tal y como está echa, no tendría que darte el error que te da a ti puesto que esta eliminando un Pokémon que éste en un slot, slot que se determina por la variable 8004, si no me equivoco.
Si no te funciona correctamente, pon un "pause" entre el callasm y el givepokemon, para darle tiempo a que ambas instrucciones se ejecuten correctamente y no una sobre la otra, por así decirlo.
A ver, basicamente lo que yo probé fue tomar mi script, quitar la comprobación del equipo, quitar @snippet3, poner el callasm antes del givepokemon, y el resultado fue ese. Con 6 Pokémon en el equipo y al activar el script, tú pierdes uno de tus Pokémon y el que recibes, es depositado en la PC.

Si removés la comprobación del equipo de el jugador, quitás @snippet3 pero no cambiás el orden del givepokemon y el callasm, en lugar del Pokémon "aleatorizado" recibes un Bulbasaur Nivel 5.

Tambien probé añadiendo otro Pause 0x13 entre el Callasm y el Givepokemon, mismos resultados.

♠Subzero♠;399349 dijo:
¿Rechazado? T_T

¡Sin palabras, colega!

Al igual y como TU mismo dices más arriba, cada quien que use el script, es libre de añadirle "detallas".
No veo donde quepa el rechazo por querer compartir una " versión" un tanto más "personal" del script.
Como autor de este tema y persona que creó el script posteado en él, yo personalmente rechazo la idea de aplicar tus "mejoras" que no son mejoras y que a su vez van en contra de la función en si creada por Game Freak. Pero me alegra que concordemos en que si alguien quiere ajustar el script a su antojo, puede hacerlo. Si alguien quiere usar tus "mejoras", naturalmente puede usarlas (y espero que te den los creditos correspondientes). Las añadiré al post principal, en la sección de notas relevantes.
 
Última edición:

Bugrhak

A long time ago I used to call myself "Subzero".
Respuesta: Re: Respuesta: FR y EM | Scripting | Wonder Trade

En fin... No es mi intención sobrecargar el tema con mis comentarios, pero bueno, el ultimo.

Lunos dijo:
A ver, basicamente lo que yo probé fue tomar mi script, quitar la comprobación del equipo, quitar @snippet3, poner el callasm antes del givepokemon, y el resultado fue ese. Con 6 Pokémon en el equipo y al activar el script, tú pierdes uno de tus Pokémon y el que recibes, es depositado en la PC.

Si removés la comprobación del equipo de el jugador, quitás @snippet3 pero no cambiás el orden del givepokemon y el callasm, en lugar del Pokémon "aleatorizado" recibes un Bulbasaur Nivel 5.

Tambien probé añadiendo otro Pause 0x13 entre el Callasm y el Givepokemon, mismos resultados.
Haciendo caso omiso al hecho de que no te hayan hecho buen sabor mis modificaciones (?), decir que, en dicho script, no ocurre esto que tu bien muy mencionas.
Eres libre de corroborarlo por ti mismo XD

Ahora bien, usando el script original, hice esta vez yo lo que tu mencionas. Podría decirce que obtuve el mismo resultado.

Pero eso dejó de ser así cuando añadí cierto comando, un copyvar.

aquí el susodicho script.

Código:
#dynamic 0x71BBA0
#org @start
faceplayer
lockall
msgbox @#String1 0x5
compare 0x800D 0x1
if 0x1 goto @snippet1
msgbox @#String2 0x6
releaseall
end

#org @snippet1
msgbox @#String3 0x6
special 0x9F
waitstate
compare 0x8004 0x6
if 0x4 goto @snippet3
goto @snippet4

#org @snippet3
msgbox @#String2 0x6
releaseall
end

#org @snippet4
random 0x19C
compare 0x800D 0x0
if 0x1 goto @snippet4
compare 0x800D 0xFB
if 0x3 goto @snippet5
compare 0x800D 0x115
if 0x4 goto @snippet5
goto @snippet4

#org @snippet5
copyvar 0x8000 0x800D
bufferpokemon 0x0 0x8000
showpokepic 0x8000 0xA 0x3
waitcry
callasm 0x8FFFFFF+1
givepokemon 0x8000 0x5 0x0 0x0 0x0 0x0
pause 0x13
fanfare 0x13E
msgbox @#String5 0x4
waitfanfare
closeonkeypress
hidepokepic
msgbox @#String6 0x5
compare 0x800D 0x1
if 0x1 call @snippet6
msgbox @#String2 0x6
releaseall
end

#org @snippet6
countpokemon
subvar 0x800D 0x1
copyvar 0x8004 0x800D
fadescreen 0x1
special 0x9E
waitstate
return

#org @#String1
= Wanna wonder trade?

#org @#String2
= Come back anytime.

#org @#String3
= Select the Pokémon you wanna trade.

#org @#String4
= I'm sorry, your team is full.\nCome back later.

#org @#String5
= [player] got a [buffer1]!

#org @#String6
= Wanna give it a nickname?
Tengo la garantía de que así funciona perfectamente de esta forma.

El copyvar lo usé para pasar lo que contiene la variable 800D, a la 8000.
Luego, cambié el bufferpokemon, showpokepic, y givepokemon, para que ahora en vez de la variable 800D, usen la 8000 (para eso el copyvar).

No me puse a examinar muy a fondo, pero si el givepokemon usa la variable 800D, es ahí donde recibes el bulbasaur.

♠That's all♠
 

Lunos

Enfrentando a La Organización
Miembro insignia
Re: Respuesta: Re: Respuesta: FR y EM | Scripting | Wonder Trade

♠Subzero♠;399383 dijo:
En fin... No es mi intención sobrecargar el tema con mis comentarios, pero bueno, el ultimo.



Haciendo caso omiso al hecho de que no te hayan hecho buen sabor mis modificaciones (?), decir que, en dicho script, no ocurre esto que tu bien muy mencionas.
Eres libre de corroborarlo por ti mismo XD

Ahora bien, usando el script original, hice esta vez yo lo que tu mencionas. Podría decirce que obtuve el mismo resultado.

Pero eso dejó de ser así cuando añadí cierto comando, un copyvar.

aquí el susodicho script.

Código:
#dynamic 0x71BBA0
#org @start
faceplayer
lockall
msgbox @#String1 0x5
compare 0x800D 0x1
if 0x1 goto @snippet1
msgbox @#String2 0x6
releaseall
end

#org @snippet1
msgbox @#String3 0x6
special 0x9F
waitstate
compare 0x8004 0x6
if 0x4 goto @snippet3
goto @snippet4

#org @snippet3
msgbox @#String2 0x6
releaseall
end

#org @snippet4
random 0x19C
compare 0x800D 0x0
if 0x1 goto @snippet4
compare 0x800D 0xFB
if 0x3 goto @snippet5
compare 0x800D 0x115
if 0x4 goto @snippet5
goto @snippet4

#org @snippet5
copyvar 0x8000 0x800D
bufferpokemon 0x0 0x8000
showpokepic 0x8000 0xA 0x3
waitcry
callasm 0x8FFFFFF+1
givepokemon 0x8000 0x5 0x0 0x0 0x0 0x0
pause 0x13
fanfare 0x13E
msgbox @#String5 0x4
waitfanfare
closeonkeypress
hidepokepic
msgbox @#String6 0x5
compare 0x800D 0x1
if 0x1 call @snippet6
msgbox @#String2 0x6
releaseall
end

#org @snippet6
countpokemon
subvar 0x800D 0x1
copyvar 0x8004 0x800D
fadescreen 0x1
special 0x9E
waitstate
return

#org @#String1
= Wanna wonder trade?

#org @#String2
= Come back anytime.

#org @#String3
= Select the Pokémon you wanna trade.

#org @#String4
= I'm sorry, your team is full.\nCome back later.

#org @#String5
= [player] got a [buffer1]!

#org @#String6
= Wanna give it a nickname?
Tengo la garantía de que así funciona perfectamente de esta forma.

El copyvar lo usé para pasar lo que contiene la variable 800D, a la 8000.
Luego, cambié el bufferpokemon, showpokepic, y givepokemon, para que ahora en vez de la variable 800D, usen la 8000 (para eso el copyvar).

No me puse a examinar muy a fondo, pero si el givepokemon usa la variable 800D, es ahí donde recibes el bulbasaur.

♠That's all♠
Pues si, ahora si funciona correctamente. Esta es una buena lección a tener en cuenta, la variable 800D no es muy estable y siempre es una buena idea pasar su valor a una variable mas confiable en lugar de depender de ella.
En fin, añadido al post principal y añadidos los creditos correspondientes, gracias.
EDITO: Lo que si, removí #org @#String4 por obvios motivos.
 
Última edición:

Kaiser de Emperana

Called in hand
Re: FR y EM | Scripting | Wonder Trade

Cuando vi esto pensé, ¿por que no usar la animación de los intercambios?. Así que heche un vistazo a como funcionaban los specials de los intercambios. Pokeruby tiene las dos funciones decompiladas:
Código:
void sub_804DB68(void)
{
    sub_804D948(gSpecialVar_0x8005, gSpecialVar_0x8004);
}

static void sub_804D948(u8 whichPlayerMon, u8 whichInGameTrade)
{
    const struct InGameTrade *inGameTrade = &gIngameTrades[whichInGameTrade];
    u8 level = GetMonData(&gPlayerParty[whichPlayerMon], MON_DATA_LEVEL);

    struct MailStruct mail;
    u8 metLocation = 0xFE;
    u8 isMail;
    u8 *item;
    struct Pokemon *pokemon = &gEnemyParty[0];

    CreateMon(pokemon, inGameTrade->species, level, 32, TRUE, inGameTrade->personality, TRUE, inGameTrade->otId);

    SetMonData(pokemon, MON_DATA_HP_IV, &inGameTrade->ivs[0]);
    SetMonData(pokemon, MON_DATA_ATK_IV, &inGameTrade->ivs[1]);
    SetMonData(pokemon, MON_DATA_DEF_IV, &inGameTrade->ivs[2]);
    SetMonData(pokemon, MON_DATA_SPEED_IV, &inGameTrade->ivs[3]);
    SetMonData(pokemon, MON_DATA_SPATK_IV, &inGameTrade->ivs[4]);
    SetMonData(pokemon, MON_DATA_SPDEF_IV, &inGameTrade->ivs[5]);
    SetMonData(pokemon, MON_DATA_NICKNAME, inGameTrade->name);
    SetMonData(pokemon, MON_DATA_OT_NAME, inGameTrade->otName);
    SetMonData(pokemon, MON_DATA_OT_GENDER, &inGameTrade->otGender);
    SetMonData(pokemon, MON_DATA_ALT_ABILITY, &inGameTrade->secondAbility);
    SetMonData(pokemon, MON_DATA_BEAUTY, &inGameTrade->stats[1]);
    SetMonData(pokemon, MON_DATA_CUTE, &inGameTrade->stats[2]);
    SetMonData(pokemon, MON_DATA_COOL, &inGameTrade->stats[0]);
    SetMonData(pokemon, MON_DATA_SMART, &inGameTrade->stats[3]);
    SetMonData(pokemon, MON_DATA_TOUGH, &inGameTrade->stats[4]);
    SetMonData(pokemon, MON_DATA_SHEEN, &inGameTrade->sheen);
    SetMonData(pokemon, MON_DATA_MET_LOCATION, &metLocation);

    isMail = FALSE;
    if (inGameTrade->heldItem != ITEM_NONE)
    {
        if (ItemIsMail(inGameTrade->heldItem))
        {
            sub_804DAD4(&mail, inGameTrade);
            gUnknown_02029700[0] = mail;
            SetMonData(pokemon, MON_DATA_MAIL, &isMail);
            SetMonData(pokemon, MON_DATA_HELD_ITEM, (u8 *)&inGameTrade->heldItem);
        }
        else
        {
            item = (u8 *)&inGameTrade->heldItem;
            SetMonData(pokemon, MON_DATA_HELD_ITEM, item);
        }
    }
    CalculateMonStats(&gEnemyParty[0]);
}

Código:

A simple vista, lo que hace la primera es crear el pokemon a cambiar. Mientras que la segunda es la que comienza la animación.
Conclusion, la primera es la que nos interesa y la segunda nos sirve tal cual está.

Yo me escribí esta función:
Código:
void SetTrade()
{
	struct Pokemon *pokemon = &gEnemyParty[0];
	u8 met_location = 0xFE;
	CreateMon(pokemon, gScriptResult, gSpecialVar_0x8004, 32, 0, 0, 1, &sScriptContext1.data[0]);
	SetMonData(pokemon, MON_DATA_OT_NAME, sScriptContext1.data[1]);
	SetMonData(pokemon, MON_DATA_NICKNAME, sScriptContext1.data[2]);
	SetMonData(pokemon, MON_DATA_MET_LOCATION, &met_location);
	CalculateMonStats(pokemon);

	gSpecialVar_0x8004 = 0; // To prevent the texts from breaking...
}
Que lo que hace es crear un pokemon de la especie almacenada en la variable 0x800D, del nivel almacenado en 0x8004 y con los datos de entrenador cargados en los buffer.
Así que si compilan este repositorio, pueden usar el siguiente script para hacer un intercambio por un pokemon especifico:
Código:
#dynamic 0x800000
#org @inicio
lock
loadpointer 0x0 123456 'ID del entrenador original
loadpointer 0x1 @nombre_entrenador_original
loadpointer 0x2 @mote_pokemon
setvar 0x8004 0x1 'Especie del pokemon
setvar 0x8005 0x0 'Posicion en el equipo del pokemon que será intercambiado
setvar 0x800D 0x5 'Nivel del pokemon
callasm 0xXXXXXX+1 'Offset donde insertaron la rutina
special 0xfe 'O 0x101 para emerald
waitspecial
release
end

#org @nombre_entrenador_original
= Pedro

#org @mote_pokemon
= Bolb
Al hacer el intercambio va a mostrar los nombre del primer intercambio programado del juego. Sería una buena idea el hacer los mensajes más generales...
Con esta forma, yo no es necesario el borrar el pokemon luego, porque el juego lo hace solo y los pokemon que evolucionan por intercambio también lo harán.
Si quieren una especie/nivel aleatorio solo pongan un valor random. Y si quieren un mote/id/nombre de entrenador aleatorio, se las van a tener que ingeniar un poco más :)

Espero que le sirva a alguien.

PD: ¿Me pueden confirmar de que el comando loadpointer funcione en XSE? No lo puedo probar porque estoy en linux y ningún tuto lo menciona...
Si no lo tiene, habría que cambiarlo por:
Código:
#raw 0xf
#raw 0x0 'Número de buffer
#raw pointer @algo 'Puntero
Edit:
Parece que solo es para Emerald, quiero decir, pese a que ahi veo un "BPRE.ld" si ponia solamente una ROM de Pokémon Fire Red nombrada "BPRE0.gba" en la carpeta raiz, el make no actuaba y me decia que si o si necesitaba una ROM llamada BPEE0.gba tambien, que seria Emerald.

Pero bueno, definitivamente estaré curioseando un poco con esto durante esta madrugada, me pica la curiosidad ver el script con la animación de intercambio como debe ser. Muchisimas gracias por crear este repositorio Kaiser
También es para FR, pero me olvidé de mencionar el como...

Por defecto está para compilarse en emerald. Para fire red tienen que modificar los archivos "main.s" y "Makefile". Las líneas:
Código:
.open "BPEE0.gba","build/rom.gba", 0x08000000
Y:
Código:
export ROM_CODE := BPEE
Respectivamente.
 
Última edición:

Lunos

Enfrentando a La Organización
Miembro insignia
Re: FR y EM | Scripting | Wonder Trade

Parece que solo es para Emerald, quiero decir, pese a que ahi veo un "BPRE.ld" si ponia solamente una ROM de Pokémon Fire Red nombrada "BPRE0.gba" en la carpeta raiz, el make no actuaba y me decia que si o si necesitaba una ROM llamada BPEE0.gba tambien, que seria Emerald.

Pero bueno, definitivamente estaré curioseando un poco con esto durante esta madrugada, me pica la curiosidad ver el script con la animación de intercambio como debe ser. Muchisimas gracias por crear este repositorio Kaiser

EDITO:
También es para FR, pero me olvidé de mencionar el como...

Por defecto está para compilarse en emerald. Para fire red tienen que modificar los archivos "main.s" y "Makefile". Las líneas:
Código:
.open "BPEE0.gba","build/rom.gba", 0x08000000
Y:
Código:
export ROM_CODE := BPEE
Respectivamente.
Uh, copado, asi podré hacer mis pruebitas locas con ambas ROMs.
 
Última edición:
Respuesta: FR y EM | Scripting | Wonder Trade

Holi.
Ultimamente he estado trabajando en un script de Wonder Trade tras ver el que posteó el usuario Harlee Quinn en PokeCommunity justo aqui. Como tiene algunos fallos serios que imposibilitan su uso en proyectos serios, decidí compartir el mio.
Sin mas que decir, empecemos.

Requisitos:
-ROM de Pokémon Fire Red (USA) v1.0 o de Pokémon Emerald (USA).
-Editor de texto y editor hexadecimal de su preferencia (como siempre, yo usaré Notepad & HxD)
-Advance Map y XSE, obviamente

Instrucciones:
1) Copiamos y pegamos la siguiente Rutina ASM compilada en un offset que tenga espacio vacio dentro de nuestra ROM dependiendo de la ROM que estén modificando.

Fire Red:
Código:
FF B5 00 25 11 4E 0F 4F 3C 78 02 2C 18 DB 33 88 A3 42 15 D2 62 1E 3A 70 01 33 E2 1A 64 25 6A 43 52 08 6B 43 08 4F F8 18 41 1B 0B DF 6C 43 3F 19 7F 1B 00 20 19 22 01 25 01 C7 01 3A 00 2A FB D1 35 82 FF BD 29 40 02 02 84 42 02 02 C0 70 03 02

Emerald:
Código:
FF B5 00 25 11 4E 0F 4F 3C 78 02 2C 18 DB 33 88 A3 42 15 D2 62 1E 3A 70 01 33 E2 1A 64 25 6A 43 52 08 6B 43 08 4F F8 18 41 1B 0B DF 6C 43 3F 19 7F 1B 00 20 19 22 01 25 01 C7 01 3A 00 2A FB D1 35 82 FF BD E9 44 02 02 EC 44 02 02 E0 75 03 02

Como a mi me gusta apostarle a lo seguro, sugiero poner la rutina en un offset que termine en 0, 4, 8 o C. Yo la puse en 71A250.

2) Vayanse a Advance Map, elijan el mapa que les apetezca, añadan un NPC y denle este script:

Fire Red:
Código:
[center]#dynamic 0x71BBA0
#org @#start
faceplayer
lockall
msgbox @#String1 0x5
compare 0x800D 0x1
if 0x1 goto @#snippet1
msgbox @#String2 0x6
releaseall
end

#org @#snippet1
countpokemon
compare LASTRESULT 0x1
if 0x1 goto @#snippet7
msgbox @#String3 0x6
special 0x9F
waitstate
special2 0x8003 0x147
compare 0x8003 0x19c
if 0x1 goto @#snippet8
compare 0x8004 0x6
if 0x4 goto @#snippet3
goto @#snippet4

#org @#snippet3
msgbox @#String2 0x6
releaseall
end

#org @#snippet4
random 0x19C
compare 0x800D 0x0
if 0x1 goto @#snippet4
compare 0x800D 0xFB
if 0x3 goto @#snippet5
compare 0x800D 0x115
if 0x4 goto @#snippet5
goto @#snippet4

#org @#snippet5
copyvar 0x8000 0x800D
bufferpokemon 0x0 0x8000
showpokepic 0x8000 0xA 0x3
waitcry
[B][COLOR="red"]callasm 0x8FFFFFF+1[/COLOR][/B]
givepokemon 0x8000 0x5 0x0 0x0 0x0 0x0
pause 0x13
fanfare 0x13E
msgbox @#String5 0x4
waitfanfare
closeonkeypress
hidepokepic
msgbox @#String6 0x5
compare 0x800D 0x1
if 0x1 call @#snippet6
msgbox @#String2 0x6
releaseall
end

#org @#snippet6
countpokemon
subvar 0x800D 0x1
copyvar 0x8004 0x800D
fadescreen 0x1
special 0x9E
waitstate
return

#org @#snippet7
msgbox @#String7 0x6
releaseall
end

#org @#snippet8
msgbox @#String8 0x6
releaseall
end

#org @#String1
= Wanna wonder trade?

#org @#String2
= Come back anytime.

#org @#String3
= Select the Pokémon you wanna trade.

#org @#String5
= [player] got a [buffer1]!

#org @#String6
= Wanna give it a nickname?

#org @#String7
= Sorry, you need two Pokémon\nto use the Wonder Trade.\pCome back anytime.

#org @#String8
= I'm sorry, you cannot trade\na Pokémon Egg using the\lWonder Trade System.\pCome back anytime.[/center]

Emerald:
Código:
[center]`#freespace 0xFF
#dynamic 0x71BBA0

#org @#start
faceplayer
lockall
msgbox @#String1 0x5
compare 0x800D 0x1
if 0x1 goto @#snippet1
msgbox @#String2 0x6
releaseall
end

#org @#snippet1
countpokemon
compare LASTRESULT 0x1
if 0x1 goto @#snippet7
msgbox @#String3 0x6
special 0xA2
waitstate
special2 0x8003 0x149
compare 0x8003 0x19c
if 0x1 goto @#snippet8
compare 0x8004 0x6
if 0x4 goto @#snippet3
goto @#snippet4

#org @#snippet3
msgbox @#String2 0x6
releaseall
end

#org @#snippet4
random 0x19C
compare 0x800D 0x0
if 0x1 goto @#snippet4
compare 0x800D 0xFB
if 0x3 goto @#snippet5
compare 0x800D 0x115
if 0x4 goto @#snippet5
goto @#snippet4

#org @#snippet5
copyvar 0x8000 0x800D
bufferpokemon 0x0 0x8000
cry 0x8000 0x0
showpokepic 0x8000 0xA 0x3
waitcry
[B][COLOR="Red"]callasm 0x8FFFFFF+1[/COLOR][/B]
givepokemon 0x8000 0x5 0x0 0x0 0x0 0x0
pause 0x13
fanfare 0x13E
msgbox @#String5 0x4
waitfanfare
closeonkeypress
hidepokepic
msgbox @#String6 0x5
compare 0x800D 0x1
if 0x1 call @#snippet6
msgbox @#String2 0x6
releaseall
end

#org @#snippet6
countpokemon
subvar 0x800D 0x1
copyvar 0x8004 0x800D
fadescreen 0x1
special 0xA1
waitstate
return

#org @#Snippet7
msgbox @#String7 0x6
releaseall
end

#org @#snippet8
msgbox @#String8 0x6
releaseall
end

#org @#String1
= Wanna wonder trade?

#org @#String2
= Come back anytime.

#org @#String3
= Select the Pokémon you wanna trade.

#org @#String5
= [player] got a [buffer1]!

#org @#String6
= Wanna give it a nickname?

#org @#String7
= Sorry, you need two Pokémon\nto use the Wonder Trade.\pCome back anytime.

#org @#String8
= I'm sorry, you cannot trade\na Pokémon Egg using the\lWonder Trade System.\pCome back anytime.[/center]
Nota: FFFFFF+1 = Offset donde insertaron la rutina compilada, +1.

3) A Probar.

Notas Relevantes
-Este script no es mas que una base, si tú quieres añadir una función o cambiar X parte por Y motivo, eres libre de hacerlo.

-El Wonder Trade como tal, puede evolucionar a Pokémon como Machoke, Haunter, Kadabra y Graveler. Por defecto no es posible forzar una evolución de esa forma con los comandos que ofrece XSE, pero afortunadamente hay Rutinas ASM como esta para Fire Red que permiten hacerlo.

-El usuario @♠Subzero♠ hizo su propia modificación justo aqui, en caso de que alguien esté interesado en sus cambios personales.

Creditos
-Harlee Quinn de PokeCommunity, pues su script me inspiró para hacer el mio.
-Bela de PokeCommunity, pues él me enseñó a comprobar la posibilidad de que el Jugador cancele el special 0x9F.
-HackMew por todos sus aportes a la Comunidad de ROM Hacking Pokémon.
-@Dani_SR_17 por haberme indicado una forma de optimizar el filtro en "@snippet4".
-@BluRose por ayudarme a comprender un error increiblemente estupido que estaba cometiendo.
- @♠Subzero♠ por haber dado una buena sugerencia a tener en cuenta en caso de usar el script (ver "Notas Relevantes").
-Tester Anonimo de Pokémon Shiny Gold Sigma por haber notado que los Huevos Pokémon eran intercambiables.
-LuHo por haber creado Advance Map.

Aqui una muestra del resultado en Fire Red.


Aqui una muestra del resultado en Emerald.


Y eso fue todo.​
Hola!
Encontramos un detalle con unos testers. Cuando tienes 01 Pokémon en Banca y usas el script, el intercambio te regala el Pokémon en vez de cambiar ese único Pokémon que tienes.

https://imgur.com/7lf4OQm

https://imgur.com/0H9Y1sI

Gracias!
 

Versekr Dark

Usuario mítico
Respuesta: Re: FR y EM | Scripting | Wonder Trade

Cuando vi esto pensé, ¿por que no usar la animación de los intercambios?. Así que heche un vistazo a como funcionaban los specials de los intercambios. Pokeruby tiene las dos funciones decompiladas:
Código:
void sub_804DB68(void)
{
    sub_804D948(gSpecialVar_0x8005, gSpecialVar_0x8004);
}

static void sub_804D948(u8 whichPlayerMon, u8 whichInGameTrade)
{
    const struct InGameTrade *inGameTrade = &gIngameTrades[whichInGameTrade];
    u8 level = GetMonData(&gPlayerParty[whichPlayerMon], MON_DATA_LEVEL);

    struct MailStruct mail;
    u8 metLocation = 0xFE;
    u8 isMail;
    u8 *item;
    struct Pokemon *pokemon = &gEnemyParty[0];

    CreateMon(pokemon, inGameTrade->species, level, 32, TRUE, inGameTrade->personality, TRUE, inGameTrade->otId);

    SetMonData(pokemon, MON_DATA_HP_IV, &inGameTrade->ivs[0]);
    SetMonData(pokemon, MON_DATA_ATK_IV, &inGameTrade->ivs[1]);
    SetMonData(pokemon, MON_DATA_DEF_IV, &inGameTrade->ivs[2]);
    SetMonData(pokemon, MON_DATA_SPEED_IV, &inGameTrade->ivs[3]);
    SetMonData(pokemon, MON_DATA_SPATK_IV, &inGameTrade->ivs[4]);
    SetMonData(pokemon, MON_DATA_SPDEF_IV, &inGameTrade->ivs[5]);
    SetMonData(pokemon, MON_DATA_NICKNAME, inGameTrade->name);
    SetMonData(pokemon, MON_DATA_OT_NAME, inGameTrade->otName);
    SetMonData(pokemon, MON_DATA_OT_GENDER, &inGameTrade->otGender);
    SetMonData(pokemon, MON_DATA_ALT_ABILITY, &inGameTrade->secondAbility);
    SetMonData(pokemon, MON_DATA_BEAUTY, &inGameTrade->stats[1]);
    SetMonData(pokemon, MON_DATA_CUTE, &inGameTrade->stats[2]);
    SetMonData(pokemon, MON_DATA_COOL, &inGameTrade->stats[0]);
    SetMonData(pokemon, MON_DATA_SMART, &inGameTrade->stats[3]);
    SetMonData(pokemon, MON_DATA_TOUGH, &inGameTrade->stats[4]);
    SetMonData(pokemon, MON_DATA_SHEEN, &inGameTrade->sheen);
    SetMonData(pokemon, MON_DATA_MET_LOCATION, &metLocation);

    isMail = FALSE;
    if (inGameTrade->heldItem != ITEM_NONE)
    {
        if (ItemIsMail(inGameTrade->heldItem))
        {
            sub_804DAD4(&mail, inGameTrade);
            gUnknown_02029700[0] = mail;
            SetMonData(pokemon, MON_DATA_MAIL, &isMail);
            SetMonData(pokemon, MON_DATA_HELD_ITEM, (u8 *)&inGameTrade->heldItem);
        }
        else
        {
            item = (u8 *)&inGameTrade->heldItem;
            SetMonData(pokemon, MON_DATA_HELD_ITEM, item);
        }
    }
    CalculateMonStats(&gEnemyParty[0]);
}

Código:

A simple vista, lo que hace la primera es crear el pokemon a cambiar. Mientras que la segunda es la que comienza la animación.
Conclusion, la primera es la que nos interesa y la segunda nos sirve tal cual está.

Yo me escribí esta función:
Código:
void SetTrade()
{
	struct Pokemon *pokemon = &gEnemyParty[0];
	u8 met_location = 0xFE;
	CreateMon(pokemon, gScriptResult, gSpecialVar_0x8004, 32, 0, 0, 1, &sScriptContext1.data[0]);
	SetMonData(pokemon, MON_DATA_OT_NAME, sScriptContext1.data[1]);
	SetMonData(pokemon, MON_DATA_NICKNAME, sScriptContext1.data[2]);
	SetMonData(pokemon, MON_DATA_MET_LOCATION, &met_location);
	CalculateMonStats(pokemon);

	gSpecialVar_0x8004 = 0; // To prevent the texts from breaking...
}
Que lo que hace es crear un pokemon de la especie almacenada en la variable 0x800D, del nivel almacenado en 0x8004 y con los datos de entrenador cargados en los buffer.
Así que si compilan este repositorio, pueden usar el siguiente script para hacer un intercambio por un pokemon especifico:
Código:
#dynamic 0x800000
#org @inicio
lock
loadpointer 0x0 123456 'ID del entrenador original
loadpointer 0x1 @nombre_entrenador_original
loadpointer 0x2 @mote_pokemon
setvar 0x8004 0x1 'Especie del pokemon
setvar 0x8005 0x0 'Posicion en el equipo del pokemon que será intercambiado
setvar 0x800D 0x5 'Nivel del pokemon
callasm 0xXXXXXX+1 'Offset donde insertaron la rutina
special 0xfe 'O 0x101 para emerald
waitspecial
release
end

#org @nombre_entrenador_original
= Pedro

#org @mote_pokemon
= Bolb
Al hacer el intercambio va a mostrar los nombre del primer intercambio programado del juego. Sería una buena idea el hacer los mensajes más generales...
Con esta forma, yo no es necesario el borrar el pokemon luego, porque el juego lo hace solo y los pokemon que evolucionan por intercambio también lo harán.
Si quieren una especie/nivel aleatorio solo pongan un valor random. Y si quieren un mote/id/nombre de entrenador aleatorio, se las van a tener que ingeniar un poco más :)

Espero que le sirva a alguien.

PD: ¿Me pueden confirmar de que el comando loadpointer funcione en XSE? No lo puedo probar porque estoy en linux y ningún tuto lo menciona...
Si no lo tiene, habría que cambiarlo por:
Código:
#raw 0xf
#raw 0x0 'Número de buffer
#raw pointer @algo 'Puntero
Edit:

También es para FR, pero me olvidé de mencionar el como...

Por defecto está para compilarse en emerald. Para fire red tienen que modificar los archivos "main.s" y "Makefile". Las líneas:
Código:
.open "BPEE0.gba","build/rom.gba", 0x08000000
Y:
Código:
export ROM_CODE := BPEE
Respectivamente.
La especie del Pokémon y el nivel estan intercambiados:

setvar 0x8004 0x1 Nivel del pokemon
setvar 0x8005 0x0 'Posicion en el equipo del pokemon que será intercambiado
setvar 0x800D 0x5 'Especie del pokemon

Script con el sistema de @Emperor Zell:

#dynamic 0x800000

#org @random
random 0x19C
compare 0x800D 0x0
if 0x1 goto @random
compare 0x800D 0xFB
if 0x3 goto @inicio2
compare 0x800D 0x115
if 0x4 goto @inicio2
goto @random

#org @inicio2
loadpointer 0x0 123456 'ID del entrenador original
loadpointer 0x1 @nombre_entrenador_original
loadpointer 0x2 @mote_pokemon
setvar 0x8004 0x5
setvar 0x8005 0x0
addvar 0x800D 0x1
callasm 0xF1495D
special 0xfe
waitstate
release
end

#org @fin
release
end

#org @nombre_entrenador_original
= Wonder

#org @mote_pokemon
= Pokémon

Créditos a la Pokeloteria y a este post.
 
Última edición:

Versekr Dark

Usuario mítico
Respuesta: Re: FR y EM | Scripting | Wonder Trade

Cuando vi esto pensé, ¿por que no usar la animación de los intercambios?. Así que heche un vistazo a como funcionaban los specials de los intercambios. Pokeruby tiene las dos funciones decompiladas:
Código:
void sub_804DB68(void)
{
    sub_804D948(gSpecialVar_0x8005, gSpecialVar_0x8004);
}

static void sub_804D948(u8 whichPlayerMon, u8 whichInGameTrade)
{
    const struct InGameTrade *inGameTrade = &gIngameTrades[whichInGameTrade];
    u8 level = GetMonData(&gPlayerParty[whichPlayerMon], MON_DATA_LEVEL);

    struct MailStruct mail;
    u8 metLocation = 0xFE;
    u8 isMail;
    u8 *item;
    struct Pokemon *pokemon = &gEnemyParty[0];

    CreateMon(pokemon, inGameTrade->species, level, 32, TRUE, inGameTrade->personality, TRUE, inGameTrade->otId);

    SetMonData(pokemon, MON_DATA_HP_IV, &inGameTrade->ivs[0]);
    SetMonData(pokemon, MON_DATA_ATK_IV, &inGameTrade->ivs[1]);
    SetMonData(pokemon, MON_DATA_DEF_IV, &inGameTrade->ivs[2]);
    SetMonData(pokemon, MON_DATA_SPEED_IV, &inGameTrade->ivs[3]);
    SetMonData(pokemon, MON_DATA_SPATK_IV, &inGameTrade->ivs[4]);
    SetMonData(pokemon, MON_DATA_SPDEF_IV, &inGameTrade->ivs[5]);
    SetMonData(pokemon, MON_DATA_NICKNAME, inGameTrade->name);
    SetMonData(pokemon, MON_DATA_OT_NAME, inGameTrade->otName);
    SetMonData(pokemon, MON_DATA_OT_GENDER, &inGameTrade->otGender);
    SetMonData(pokemon, MON_DATA_ALT_ABILITY, &inGameTrade->secondAbility);
    SetMonData(pokemon, MON_DATA_BEAUTY, &inGameTrade->stats[1]);
    SetMonData(pokemon, MON_DATA_CUTE, &inGameTrade->stats[2]);
    SetMonData(pokemon, MON_DATA_COOL, &inGameTrade->stats[0]);
    SetMonData(pokemon, MON_DATA_SMART, &inGameTrade->stats[3]);
    SetMonData(pokemon, MON_DATA_TOUGH, &inGameTrade->stats[4]);
    SetMonData(pokemon, MON_DATA_SHEEN, &inGameTrade->sheen);
    SetMonData(pokemon, MON_DATA_MET_LOCATION, &metLocation);

    isMail = FALSE;
    if (inGameTrade->heldItem != ITEM_NONE)
    {
        if (ItemIsMail(inGameTrade->heldItem))
        {
            sub_804DAD4(&mail, inGameTrade);
            gUnknown_02029700[0] = mail;
            SetMonData(pokemon, MON_DATA_MAIL, &isMail);
            SetMonData(pokemon, MON_DATA_HELD_ITEM, (u8 *)&inGameTrade->heldItem);
        }
        else
        {
            item = (u8 *)&inGameTrade->heldItem;
            SetMonData(pokemon, MON_DATA_HELD_ITEM, item);
        }
    }
    CalculateMonStats(&gEnemyParty[0]);
}

Código:

A simple vista, lo que hace la primera es crear el pokemon a cambiar. Mientras que la segunda es la que comienza la animación.
Conclusion, la primera es la que nos interesa y la segunda nos sirve tal cual está.

Yo me escribí esta función:
Código:
void SetTrade()
{
	struct Pokemon *pokemon = &gEnemyParty[0];
	u8 met_location = 0xFE;
	CreateMon(pokemon, gScriptResult, gSpecialVar_0x8004, 32, 0, 0, 1, &sScriptContext1.data[0]);
	SetMonData(pokemon, MON_DATA_OT_NAME, sScriptContext1.data[1]);
	SetMonData(pokemon, MON_DATA_NICKNAME, sScriptContext1.data[2]);
	SetMonData(pokemon, MON_DATA_MET_LOCATION, &met_location);
	CalculateMonStats(pokemon);

	gSpecialVar_0x8004 = 0; // To prevent the texts from breaking...
}
Que lo que hace es crear un pokemon de la especie almacenada en la variable 0x800D, del nivel almacenado en 0x8004 y con los datos de entrenador cargados en los buffer.
Así que si compilan este repositorio, pueden usar el siguiente script para hacer un intercambio por un pokemon especifico:
Código:
#dynamic 0x800000
#org @inicio
lock
loadpointer 0x0 123456 'ID del entrenador original
loadpointer 0x1 @nombre_entrenador_original
loadpointer 0x2 @mote_pokemon
setvar 0x8004 0x1 'Especie del pokemon
setvar 0x8005 0x0 'Posicion en el equipo del pokemon que será intercambiado
setvar 0x800D 0x5 'Nivel del pokemon
callasm 0xXXXXXX+1 'Offset donde insertaron la rutina
special 0xfe 'O 0x101 para emerald
waitspecial
release
end

#org @nombre_entrenador_original
= Pedro

#org @mote_pokemon
= Bolb
Al hacer el intercambio va a mostrar los nombre del primer intercambio programado del juego. Sería una buena idea el hacer los mensajes más generales...
Con esta forma, yo no es necesario el borrar el pokemon luego, porque el juego lo hace solo y los pokemon que evolucionan por intercambio también lo harán.
Si quieren una especie/nivel aleatorio solo pongan un valor random. Y si quieren un mote/id/nombre de entrenador aleatorio, se las van a tener que ingeniar un poco más :)

Espero que le sirva a alguien.

PD: ¿Me pueden confirmar de que el comando loadpointer funcione en XSE? No lo puedo probar porque estoy en linux y ningún tuto lo menciona...
Si no lo tiene, habría que cambiarlo por:
Código:
#raw 0xf
#raw 0x0 'Número de buffer
#raw pointer @algo 'Puntero
Edit:

También es para FR, pero me olvidé de mencionar el como...

Por defecto está para compilarse en emerald. Para fire red tienen que modificar los archivos "main.s" y "Makefile". Las líneas:
Código:
.open "BPEE0.gba","build/rom.gba", 0x08000000
Y:
Código:
export ROM_CODE := BPEE
Respectivamente.
Gracias @Emperor Zell tenemos tambien el sistema para ruby:

Aquí dejo el documentos para la inserción del sistema en Ruby:

SetMonData = 0x0803D1FC|1;
CalculateMonStats = 0x0803B1B8|1;
sScriptContext1 = 0x030005b8;
gEnemyParty = 0x030045c0;
CreateMon = 0x0803A798|1;
gSpecialVar_0x8004 = 0x0202e8cc;
gScriptResult = 0x0202e8dc;
 

jrlopes

Héroe de WaH
Re: FR y EM | Scripting | Wonder Trade

Cuando vi esto pensé, ¿por que no usar la animación de los intercambios?. Así que heche un vistazo a como funcionaban los specials de los intercambios. Pokeruby tiene las dos funciones decompiladas:
Código:
void sub_804DB68(void)
{
    sub_804D948(gSpecialVar_0x8005, gSpecialVar_0x8004);
}

static void sub_804D948(u8 whichPlayerMon, u8 whichInGameTrade)
{
    const struct InGameTrade *inGameTrade = &gIngameTrades[whichInGameTrade];
    u8 level = GetMonData(&gPlayerParty[whichPlayerMon], MON_DATA_LEVEL);

    struct MailStruct mail;
    u8 metLocation = 0xFE;
    u8 isMail;
    u8 *item;
    struct Pokemon *pokemon = &gEnemyParty[0];

    CreateMon(pokemon, inGameTrade->species, level, 32, TRUE, inGameTrade->personality, TRUE, inGameTrade->otId);

    SetMonData(pokemon, MON_DATA_HP_IV, &inGameTrade->ivs[0]);
    SetMonData(pokemon, MON_DATA_ATK_IV, &inGameTrade->ivs[1]);
    SetMonData(pokemon, MON_DATA_DEF_IV, &inGameTrade->ivs[2]);
    SetMonData(pokemon, MON_DATA_SPEED_IV, &inGameTrade->ivs[3]);
    SetMonData(pokemon, MON_DATA_SPATK_IV, &inGameTrade->ivs[4]);
    SetMonData(pokemon, MON_DATA_SPDEF_IV, &inGameTrade->ivs[5]);
    SetMonData(pokemon, MON_DATA_NICKNAME, inGameTrade->name);
    SetMonData(pokemon, MON_DATA_OT_NAME, inGameTrade->otName);
    SetMonData(pokemon, MON_DATA_OT_GENDER, &inGameTrade->otGender);
    SetMonData(pokemon, MON_DATA_ALT_ABILITY, &inGameTrade->secondAbility);
    SetMonData(pokemon, MON_DATA_BEAUTY, &inGameTrade->stats[1]);
    SetMonData(pokemon, MON_DATA_CUTE, &inGameTrade->stats[2]);
    SetMonData(pokemon, MON_DATA_COOL, &inGameTrade->stats[0]);
    SetMonData(pokemon, MON_DATA_SMART, &inGameTrade->stats[3]);
    SetMonData(pokemon, MON_DATA_TOUGH, &inGameTrade->stats[4]);
    SetMonData(pokemon, MON_DATA_SHEEN, &inGameTrade->sheen);
    SetMonData(pokemon, MON_DATA_MET_LOCATION, &metLocation);

    isMail = FALSE;
    if (inGameTrade->heldItem != ITEM_NONE)
    {
        if (ItemIsMail(inGameTrade->heldItem))
        {
            sub_804DAD4(&mail, inGameTrade);
            gUnknown_02029700[0] = mail;
            SetMonData(pokemon, MON_DATA_MAIL, &isMail);
            SetMonData(pokemon, MON_DATA_HELD_ITEM, (u8 *)&inGameTrade->heldItem);
        }
        else
        {
            item = (u8 *)&inGameTrade->heldItem;
            SetMonData(pokemon, MON_DATA_HELD_ITEM, item);
        }
    }
    CalculateMonStats(&gEnemyParty[0]);
}

Código:

A simple vista, lo que hace la primera es crear el pokemon a cambiar. Mientras que la segunda es la que comienza la animación.
Conclusion, la primera es la que nos interesa y la segunda nos sirve tal cual está.

Yo me escribí esta función:
Código:
void SetTrade()
{
    struct Pokemon *pokemon = &gEnemyParty[0];
    u8 met_location = 0xFE;
    CreateMon(pokemon, gScriptResult, gSpecialVar_0x8004, 32, 0, 0, 1, &sScriptContext1.data[0]);
    SetMonData(pokemon, MON_DATA_OT_NAME, sScriptContext1.data[1]);
    SetMonData(pokemon, MON_DATA_NICKNAME, sScriptContext1.data[2]);
    SetMonData(pokemon, MON_DATA_MET_LOCATION, &met_location);
    CalculateMonStats(pokemon);

    gSpecialVar_0x8004 = 0; // To prevent the texts from breaking...
}
Que lo que hace es crear un pokemon de la especie almacenada en la variable 0x800D, del nivel almacenado en 0x8004 y con los datos de entrenador cargados en los buffer.
Así que si compilan este repositorio, pueden usar el siguiente script para hacer un intercambio por un pokemon especifico:
Código:
#dynamic 0x800000
#org @inicio
lock
loadpointer 0x0 123456 'ID del entrenador original
loadpointer 0x1 @nombre_entrenador_original
loadpointer 0x2 @mote_pokemon
setvar 0x8004 0x1 'Especie del pokemon
setvar 0x8005 0x0 'Posicion en el equipo del pokemon que será intercambiado
setvar 0x800D 0x5 'Nivel del pokemon
callasm 0xXXXXXX+1 'Offset donde insertaron la rutina
special 0xfe 'O 0x101 para emerald
waitspecial
release
end

#org @nombre_entrenador_original
= Pedro

#org @mote_pokemon
= Bolb
Al hacer el intercambio va a mostrar los nombre del primer intercambio programado del juego. Sería una buena idea el hacer los mensajes más generales...
Con esta forma, yo no es necesario el borrar el pokemon luego, porque el juego lo hace solo y los pokemon que evolucionan por intercambio también lo harán.
Si quieren una especie/nivel aleatorio solo pongan un valor random. Y si quieren un mote/id/nombre de entrenador aleatorio, se las van a tener que ingeniar un poco más :)

Espero que le sirva a alguien.

PD: ¿Me pueden confirmar de que el comando loadpointer funcione en XSE? No lo puedo probar porque estoy en linux y ningún tuto lo menciona...
Si no lo tiene, habría que cambiarlo por:
Código:
#raw 0xf
#raw 0x0 'Número de buffer
#raw pointer @algo 'Puntero
Edit:

También es para FR, pero me olvidé de mencionar el como...

Por defecto está para compilarse en emerald. Para fire red tienen que modificar los archivos "main.s" y "Makefile". Las líneas:
Código:
.open "BPEE0.gba","build/rom.gba", 0x08000000
Y:
Código:
export ROM_CODE := BPEE
Respectivamente.
Descargué el archivo, estoy generando a través de / make (como foto) muestra este error, ¿puedes decirme dónde me equivoco?
 

Adjuntos

Jaizu

Usuario mítico
Descargué el archivo, estoy generando a través de / make (como foto) muestra este error, ¿puedes decirme dónde me equivoco?
Si vas a hacer una carpeta para tutoriales de tu canal de youtube quizá deberías diferenciar entre binario y decomp antes de enseñarle a la gente nada creo yo.
 

jrlopes

Héroe de WaH
Si vas a hacer una carpeta para tutoriales de tu canal de youtube quizá deberías diferenciar entre binario y decomp antes de enseñarle a la gente nada creo yo.
En mi canal solo enseño lo que aprendí dando crédito a los que estaban dispuestos a enseñar, creo que en video es más fácil de entender para la gente que en texto. El foro es excelente, pero al carecer de un canal oficial en youtube sería de gran ayuda para los principiantes. binary y decom está mucho más allá de mis conocimientos básicos, solo estaba intentando activar SPECIAL 0XFE para tener animación de intercambio de pokemon, pero leyendo aquí, vi que es necesario compilar pero como pueden ver en la foto está dando error.
 

Jaizu

Usuario mítico
En mi canal solo enseño lo que aprendí dando crédito a los que estaban dispuestos a enseñar, creo que en video es más fácil de entender para la gente que en texto. El foro es excelente, pero al carecer de un canal oficial en youtube sería de gran ayuda para los principiantes. binary y decom está mucho más allá de mis conocimientos básicos, solo estaba intentando activar SPECIAL 0XFE para tener animación de intercambio de pokemon, pero leyendo aquí, vi que es necesario compilar pero como pueden ver en la foto está dando error.
Estás en una carpeta de pokeemerald intentando hacer un make.
Aquí solo tienes que compilar el script, y se compila en XSE, no en la terminal.
La rutina ya te la dan compilada.
 

jrlopes

Héroe de WaH
Estás en una carpeta de pokeemerald intentando hacer un make.
Aquí solo tienes que compilar el script, y se compila en XSE, no en la terminal.
La rutina ya te la dan compilada.
Sí, el código con Rutina está funcionando perfectamente. Solo quería agregar SPECIAL 0XFE para tener una animación del intercambio de Pokémon, lo que está provocando un error en el código.
Un suscribirse al canal vio esta animación en el juego Pkm GS Chronicles y pidió enseñar en el canal, ni siquiera sabía que tenía este especial, como dije anteriormente solo sé lo básico, ayer buscando un tutorial sobre whack hack encontré esta publicación, pero ayer hice una prueba solo insertando codifica el especial 0xfe pero al cambiar el pokemon no se cambia la imagen correcta del pokemon (solo si es el primero de mi equipo).
 

Tahmid

Usuario Legendario
:c queria utilizarlo ya que te esforzaste para hacer este aporte tan guapo y lo utilize muchas veces hasta que me saliera el problema no es el offset libre eso ya lo consigo con FSF pero lo que no me deja es XSE me dice que no puedo compilar el codigo con el +1 que tiene tu codigo lo hice todo bien y cuando borro el +1 si me deja compilar pero el wonder trade se bugea cuando el trader te da el pokemon el imagen se queda haciendo el cry y nada funciona y despues el juego se crashea y el VBA se cierra solo. muy buen aporte y muy interesante solo si pudieras haer que el XSE te deje compilar con el +1 pues seria 10/10 y me viene de perlas este sistema tan guapo para mi rom el tradeo basico ya es algo "viejo" y conseguir pokemons randoms es algo mas divertido
 

Jaizu

Usuario mítico
:c queria utilizarlo ya que te esforzaste para hacer este aporte tan guapo y lo utilize muchas veces hasta que me saliera el problema no es el offset libre eso ya lo consigo con FSF pero lo que no me deja es XSE me dice que no puedo compilar el codigo con el +1 que tiene tu codigo lo hice todo bien y cuando borro el +1 si me deja compilar pero el wonder trade se bugea cuando el trader te da el pokemon el imagen se queda haciendo el cry y nada funciona y despues el juego se crashea y el VBA se cierra solo. muy buen aporte y muy interesante solo si pudieras haer que el XSE te deje compilar con el +1 pues seria 10/10 y me viene de perlas este sistema tan guapo para mi rom el tradeo basico ya es algo "viejo" y conseguir pokemons randoms es algo mas divertido
A ver, por partes.
Primero no escribas más de cinco líneas de texto sin una coma o punto, es horrible de leer, calma.
Segundo, el +1 se lo sumas a tu offset, no escribes +1 en el programa.
 

Tahmid

Usuario Legendario
A ver, por partes.
Primero no escribas más de cinco líneas de texto sin una coma o punto, es horrible de leer, calma.
Segundo, el +1 se lo sumas a tu offset, no escribes +1 en el programa.
A. bueno no se como habras leido ese a pero no va en modo enfadado va en modo de a ok pues el +1 como lo sumo? espera me estas diciendo que hago offset+rutina? la rutina ya lo añadi en HxD


~Saludos~
 

Bugrhak

A long time ago I used to call myself "Subzero".
A. bueno no se como habras leido ese a pero no va en modo enfadado va en modo de a ok pues el +1 como lo sumo? espera me estas diciendo que hago offset+rutina? la rutina ya lo añadi en HxD


~Saludos~
Primero que todo, ya te voy recomendando que leas algún tutorial que explique como insertar rutinas asm, ahí podrás evacuar esta duda que tienes y muchas más.
Pero enga, te cuento. Y para hacernos la vida más fácil te daré un ejemplo.

Si por alguna casualidad has insertado la rutina en la dirección (offset) 0x800000 en tu rom.
Lo que tines que hacer es pillar alguna calculadora que tenga soporte para cálculos con numeración hexadecimal (puedes usar la calculadora nativa de windows o la que viene integrada en XSE) y hacer la siguiente operación:

800000 + 1

Entonces: 800000 + 1 = 800001

El resultado de esa operación será el numero que debas poner en el callasm, quedando de tal forma:

callasm 0x800001

Naturalmente, si tu has insertado la rutina en otro offset, sumarás 1 a ese offset.
Ahora bien, cada vez que necesites usar la rutina, usarás el callasm con el valor que te ha dado como resultado de la suma.
Todo esto se aplica a cualquier rutina que vayas a usar, recuérdalo.
 
Última edición:
Arriba