Registrarse

Cambios de forma equipando un objeto

Estado
Cerrado para nuevas respuestas.

Kaktus

Miembro insignia
Miembro insignia
Bueno, debido a uno de los retos que me pusieron, me puse a investigar acerca del cambio de forma, y visto que lo que quería era cumplir el reto y poco más, he decidido compartir lo que averigüé por el camino, creo que puede ser interesante para más de una persona, y desde luego, quita bastante trabajo de encima.

Soy consciente de que es algo hecho de una forma bastante chapucera, pero es funcional, que al final es lo que buscamos, si alguien prefiere hacerle con más perfección, está en la libertad de hacerlo (y postearlo si gusta)

Voy al grano, lo único que he cambiado son un par de líneas del archivo "src/party_menu.c"

Concrétamente, la función "party_menu_link_mon_held_item_object" que se encuentra aproximadamente en la línea 3696.

He añadido esto:

Código:
void party_menu_link_mon_held_item_object(u8 taskId)
{	
	if (gUnknown_0202E8F6 == 0)
    {
        SetHeldItemIconVisibility(ewram1C000.unk4, ewram1C000.primarySelectedMonIndex);
        gTasks[ewram1C000.unk4].func = ewram1C000.unk10;
		
	[B][COLOR="#ff5252"]DestroySprite(&gSprites[ewram1C000.primarySelectedMonIndex]);
	TryCreatePartyMenuMonIcon(taskId, ewram1C000.primarySelectedMonIndex, &gPlayerParty[ewram1C000.primarySelectedMonIndex]);[/COLOR][/B]
		
	DestroyTask(taskId);
    }
}
Lo que resumiendo, sirve para "actualizar" el icono cada vez que das o quitas un objeto, esta es la parte que peor está del código, y de la que si se tuviera que tocar algo, sería esto, pues tiene diversos fallos. Lo principal sería que en lugar de eliminar el icono original, y crear uno nuevo, se editara tan sólo el icono que se carga, sin eliminar el propio objeto. Pero visto que es algo tedioso, prefiero no hacerlo por el momento.

Lo siguiente, es cambiar la función "PartyMenuUpdateMonHeldItem", en la que añadí:

Código:
bool8 PartyMenuUpdateMonHeldItem(struct Pokemon *pkmn, u16 item)
{
    u8 itemData[2];
    [COLOR="#ff5252"]u16 monDexValue;[/COLOR]

    if (ItemIsMail(item) == TRUE)
    {
        if (GiveMailToMon(pkmn, item) == 0xFF)
            return TRUE;
        gUnknown_0202E8F4 = 2;
    }
    else
    {
        gUnknown_0202E8F4 = 1;
    }

    itemData[0] = item;
    itemData[1] = item >> 8;
    SetMonData(pkmn, MON_DATA_HELD_ITEM, itemData);
    [COLOR="#ff5252"]if (item == ITEM_POTION && GetMonData(ewram1C000.pokemon, MON_DATA_SPECIES) == SPECIES_TORCHIC){
        monDexValue = 25;
        SetMonData(&gPlayerParty[ewram1C000.primarySelectedMonIndex], MON_DATA_SPECIES, &monDexValue);
    }[/COLOR]
    return FALSE;
    }
}
Aquí estamos preguntando si el Pokémon lleva equipada una poción, y si además, dicho Pokémon es Torchic. En caso de que ambas condiciones se cumplan, se cambiará la especie de Torchic, por la de Pikachu (que es la número 25 en la Pokédex, es decir, el número de "monDexValue")

Por útimo, la función "PartyMenuTryGiveMonHeldItem", que está justo abajo de la anterior. En esta, tan sólo he añadido esto:

Código:
void PartyMenuTryGiveMonHeldItem(u8 taskId, u16 newItem, TaskFunc c)
{
    u16 currentItem;
    [COLOR="#ff5252"]u16 monDexValue;[/COLOR]

    gTasks[taskId].func = TaskDummy;
    sub_806E8D0(taskId, newItem, c);
    currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
    gUnknown_0202E8F4 = 0;
    gUnknown_0202E8F8 = 0;
    [COLOR="#ff5252"]if (newItem != ITEM_POTION && GetMonData(ewram1C000.pokemon, MON_DATA_SPECIES) == SPECIES_PIKACHU){
	monDexValue = 280;
	SetMonData(&gPlayerParty[ewram1C000.primarySelectedMonIndex], MON_DATA_SPECIES, &monDexValue);
    }[/COLOR]
    if (currentItem != 0)
    {
        if (ItemIsMail(currentItem) == TRUE)
        {
            sub_806E834(gOtherText_MailMustBeRemoved, 1);
            CreateTask(party_menu_link_mon_held_item_object, 5);
        }
        else
        {
            GetMonNickname(ewram1C000.pokemon, gStringVar1);
            CopyItemName(currentItem, gStringVar2);
            StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyHolding);
            sub_806E834(gStringVar4, 1);
            CreateTask(Task_ConfirmGiveHeldItem, 5);
            if (ItemIsMail(newItem) == TRUE)
                gUnknown_0202E8F8 = currentItem;
        }
    }
    else
    {
        PartyMenuUpdateMonHeldItem(ewram1C000.pokemon, newItem);
        RemoveBagItem(newItem, 1);
        if (ItemIsMail(newItem))
        {
            gTasks[taskId].func = c;
        }
        else
        {
            DisplayGiveHeldItemMessage(ewram1C000.primarySelectedMonIndex, newItem, 1);
            CreateTask(party_menu_link_mon_held_item_object, 5);
        }
    }
}
Básicamente, en el condicional (if), pregunto si el objeto que se le va a equipar ahora al Pokémon es diferente de una poción, y además, que si dicho Pokémon es Pikachu, en caso de que si, se cambia su especie por la que corresponda en la Pokedex al número de la variable "monDexValue", en este caso, lo que ocurre es que si nuestro Pikachu tiene equipada una poción, y si se la quitamos, pasa a ser Torchic.

Si cabe lugar a dudas, aquí dejo un vídeo de demostración de lo que hace

Siento ser tan breve, pero no me da tiempo a más, espero que de verdad tratéis de investigarlo un pelín más ;)

Chao <3
 

Omega

For endless fight
Miembro del equipo
Moderador/a
Bueno, aún te quedan 29 días (?
Jaja nah, el método fue más simple de lo que pensaba sería (y es, en FR), he visto el video de demostración y ha quedado super bien, el asunto de icon no supone algo grave así que no pasa nada xD

Gracias por aceptar el reto :lovelon:
 

Lunos

Enfrentando a La Organización
Miembro insignia
Yo creo que acá olvidaste compartir algun cambio o algo, porque a mi no me está funcionando correctamente :/ ...
Incluso probé con un puro copy y paste sin ninguna modificación extra, e igualmente no me va.

Torchic se convierte en Pikachu al darle una Poción, pero al quitarsela no vuelve a ser Torchic, y lo que es mas, si le das a Pikachu un objeto cualquiera que no sea una Poción, ahi si vuelve a ser Torchic. Es rarisimo.


Igualmente el hecho de que hayas conseguido hacer un cambio de forma exitosamente me parece genial, sos un idolo papu <3
 

Kaiser de Emperana

Called in hand
Actualmente no tengo instaladas las herramientas para compilar pokeruby, así que no lo puedo probarlo como tal, pero espero que mi mensaje sirva de ayuda.

Tu sistema tiene un problema, al cambiar la especie de un pokemon, hay que recalcular las stats del mismo. Si te fijas, Pikachu tiene exactamente las mismas estadísticas que cuando era un Torchic. Por eso despues de cambiar la especie tendrían que agregar una línea más de código.
...

Código:
void party_menu_link_mon_held_item_object(u8 taskId)
{	
	if (gUnknown_0202E8F6 == 0)
    {
        SetHeldItemIconVisibility(ewram1C000.unk4, ewram1C000.primarySelectedMonIndex);
        gTasks[ewram1C000.unk4].func = ewram1C000.unk10;
		
	[B][COLOR="#ff5252"]DestroySprite(&gSprites[ewram1C000.primarySelectedMonIndex]);
	TryCreatePartyMenuMonIcon(taskId, ewram1C000.primarySelectedMonIndex, &gPlayerParty[ewram1C000.primarySelectedMonIndex]);[/COLOR][/B]
		
	DestroyTask(taskId);
    }
}
...

Código:
bool8 PartyMenuUpdateMonHeldItem(struct Pokemon *pkmn, u16 item)
{
    u8 itemData[2];
    [COLOR="#ff5252"]u16 monDexValue;[/COLOR]

    if (ItemIsMail(item) == TRUE)
    {
        if (GiveMailToMon(pkmn, item) == 0xFF)
            return TRUE;
        gUnknown_0202E8F4 = 2;
    }
    else
    {
        gUnknown_0202E8F4 = 1;
    }

    itemData[0] = item;
    itemData[1] = item >> 8;
    SetMonData(pkmn, MON_DATA_HELD_ITEM, itemData);
    [COLOR="#ff5252"]if (item == ITEM_POTION && GetMonData(ewram1C000.pokemon, MON_DATA_SPECIES) == SPECIES_TORCHIC){
        monDexValue = 25;
        SetMonData(&gPlayerParty[ewram1C000.primarySelectedMonIndex], MON_DATA_SPECIES, &monDexValue);
        [COLOR="RoyalBlue"]CalculateMonStats(&gPlayerParty[ewram1C000.primarySelectedMonIndex]);[/COLOR]
    }[/COLOR]
    return FALSE;
    }
}
...

Código:
void PartyMenuTryGiveMonHeldItem(u8 taskId, u16 newItem, TaskFunc c)
{
    u16 currentItem;
    [COLOR="#ff5252"]u16 monDexValue;[/COLOR]

    gTasks[taskId].func = TaskDummy;
    sub_806E8D0(taskId, newItem, c);
    currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
    gUnknown_0202E8F4 = 0;
    gUnknown_0202E8F8 = 0;
    [COLOR="#ff5252"]if (newItem != ITEM_POTION && GetMonData(ewram1C000.pokemon, MON_DATA_SPECIES) == SPECIES_PIKACHU){
	monDexValue = 280;
	SetMonData(&gPlayerParty[ewram1C000.primarySelectedMonIndex], MON_DATA_SPECIES, &monDexValue);
	[COLOR="RoyalBlue"]CalculateMonStats(&gPlayerParty[ewram1C000.primarySelectedMonIndex]);[/COLOR]
    }[/COLOR]
    if (currentItem != 0)
    {
        if (ItemIsMail(currentItem) == TRUE)
        {
            sub_806E834(gOtherText_MailMustBeRemoved, 1);
            CreateTask(party_menu_link_mon_held_item_object, 5);
        }
        else
        {
            GetMonNickname(ewram1C000.pokemon, gStringVar1);
            CopyItemName(currentItem, gStringVar2);
            StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyHolding);
            sub_806E834(gStringVar4, 1);
            CreateTask(Task_ConfirmGiveHeldItem, 5);
            if (ItemIsMail(newItem) == TRUE)
                gUnknown_0202E8F8 = currentItem;
        }
    }
    else
    {
        PartyMenuUpdateMonHeldItem(ewram1C000.pokemon, newItem);
        RemoveBagItem(newItem, 1);
        if (ItemIsMail(newItem))
        {
            gTasks[taskId].func = c;
        }
        else
        {
            DisplayGiveHeldItemMessage(ewram1C000.primarySelectedMonIndex, newItem, 1);
            CreateTask(party_menu_link_mon_held_item_object, 5);
        }
    }
}
Por otro lado el problema que menciona Lunos es debido a que te faltó el caso en que se quite el objeto sin poner uno a cambio. Creo que con agregar estas líneas en azul, en el mismo archivo alcanzaría:

Código:
void PartyMenuTryGiveMonHeldItem_806ECE8(u8 taskId, TaskFunc func)
{
    u16 currentItem[COLOR="RoyalBlue"], species[/COLOR];

    gTasks[taskId].func = TaskDummy;
    sub_806E8D0(taskId, 0, func);
    currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
    if (currentItem == 0)
    {
        StringExpandPlaceholders(gStringVar4, gOtherText_NotHoldingAnything);
        sub_806E834(gStringVar4, 0);
        CreateTask(party_menu_link_mon_held_item_object, 5);
    }
    else
    {
        u8 itemData[2];

        itemData[0] = 0;
        itemData[1] = 0;
        if (AddBagItem(currentItem, 1) == TRUE)
        {
            if (ItemIsMail(currentItem) == TRUE)
                TakeMailFromMon(ewram1C000.pokemon);
            DisplayTakeHeldItemMessage(ewram1C000.primarySelectedMonIndex, currentItem, 0);
            SetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM, itemData);
            [COLOR="RoyalBlue"]if (GetMonData(ewram1C000.pokemon, MON_DATA_SPECIES) == SPECIES_PIKACHU){
                species = SPECIES_TORCHIC;
                SetMonData(&gPlayerParty[ewram1C000.primarySelectedMonIndex], MON_DATA_SPECIES, &species);
                CalculateMonStats(&gPlayerParty[ewram1C000.primarySelectedMonIndex]);
            }[/COLOR]
        }
        else
        {
            sub_806E834(gOtherText_BagFullCannotRemoveItem, 0);
        }
        CreateTask(party_menu_link_mon_held_item_object, 5);
    }
}
Y creo que con eso alcanzaría...
 

Lunos

Enfrentando a La Organización
Miembro insignia
Puto heroe.


EDITO: El problemita con los iconos aun sigue ahi, pero eh, al menos funciona en su mayoria.


EDITO2: Tambien encontré un extraño problema con el icono de objeto equipado.
Creo que ocurre por el simple hecho de tener a Giratina en el equipo.


EDITO3: Y si intento quitarle un objeto a Giratina pese a que no esté cargando uno, el icono del primer pokémon en el equipo desaparece.
Oof. Estos problemas son... bueno, bastante problematicos.
 
Última edición:

Kaktus

Miembro insignia
Miembro insignia
Puto heroe.


EDITO: El problemita con los iconos aun sigue ahi, pero eh, al menos funciona en su mayoria.


EDITO2: Tambien encontré un extraño problema con el icono de objeto equipado.
Creo que ocurre por el simple hecho de tener a Giratina en el equipo.


EDITO3: Y si intento quitarle un objeto a Giratina pese a que no esté cargando uno, el icono del primer pokémon en el equipo desaparece.
Oof. Estos problemas son... bueno, bastante problematicos.
Yo ya era consciente de todos estos problemas con los iconos, por eso mismo en el post principal dije que es mejor sustituir simplemente el icono en lugar de eliminar el objeto, porque esto conlleva muchos más problemas. Quizás si saco un rato lo investigaré bien. Y gracias @Monika por dejar parte de la solución del código.

Insisto, la verdadera solución es reemplazar tan solo la imagen y su paleta, y no eliminar todo el objeto, esto da muchos problemas
 

Lunos

Enfrentando a La Organización
Miembro insignia
Puees... creo que logré solucionar el inconveniente con el icono del objeto equipado.

Los cambios que hice aparecen en esta commit, pero basicamente son los ya mencionados en sus posts, IK y Zell.
https://github.com/LOuroboros/pokeruby493/commit/b40c8c585f2d5714024e86fde5330990e7561226

La unica diferencia es que añadí un CreateTask(party_menu_link_mon_held_item_object, 5); en la sección del cambio de forma dentro de la función PartyMenuUpdateMonHeldItem.

Resultado:
https://streamable.com/tly1w
 
Última edición:
Estado
Cerrado para nuevas respuestas.
Arriba