Skip to content

Repeated Field Medicine Use

Eduardo Quezada D'Ottone edited this page Feb 18, 2022 · 13 revisions

Keep Party Menu Open During Field Medicine Use

Credit: ghoulslash

You can pull directly from their branch, here: https://github.com/ghoulslash/pokeemerald/tree/field-medicine

If you're using a lot of potions at once, it can be annoying to keep returning to the bag after use. This simple fix keeps the menu open unless you run out of potions. The user will have to select Cancel or press B to exit the party menu. But this is intuitive.

Let's start by opening src/party_menu.c

1.

First, find the function ItemUseCB_Medicine. Replace the entire thing with:

void ItemUseCB_Medicine(u8 taskId, TaskFunc task)
{
    u16 hp = 0;
    struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
    u16 item = gSpecialVar_ItemId;
    bool8 canHeal, cannotUse;

    if (NotUsingHPEVItemOnShedinja(mon, item) == FALSE)
    {
        cannotUse = TRUE;
    }
    else
    {
        canHeal = IsHPRecoveryItem(item);
        if (canHeal == TRUE)
        {
            hp = GetMonData(mon, MON_DATA_HP);
            if (hp == GetMonData(mon, MON_DATA_MAX_HP))
                canHeal = FALSE;
        }
        cannotUse = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, item, 0);
    }

    if (cannotUse != FALSE)
    {
        gPartyMenuUseExitCallback = FALSE;
        PlaySE(SE_SELECT);
        DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
        ScheduleBgCopyTilemapToVram(2);
        if (gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD)
            gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
        else
            gTasks[taskId].func = task;
        return;
    }
    else
    {
        gPartyMenuUseExitCallback = TRUE;
        if (!IsItemFlute(item))
        {
            PlaySE(SE_USE_ITEM);
            if (gPartyMenu.action != PARTY_ACTION_REUSABLE_ITEM)
                RemoveBagItem(item, 1);
        }
        else
        {
            PlaySE(SE_GLASS_FLUTE);
        }
        SetPartyMonAilmentGfx(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
        if (gSprites[sPartyMenuBoxes[gPartyMenu.slotId].statusSpriteId].invisible)
            DisplayPartyPokemonLevelCheck(mon, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
        if (canHeal == TRUE)
        {
            if (hp == 0)
                AnimatePartySlot(gPartyMenu.slotId, 1);
            PartyMenuModifyHP(taskId, gPartyMenu.slotId, 1, GetMonData(mon, MON_DATA_HP) - hp, Task_DisplayHPRestoredMessage);
            ResetHPTaskData(taskId, 0, hp);
            return;
        }
        else
        {
            GetMonNickname(mon, gStringVar1);
            GetMedicineItemEffectMessage(item);
            DisplayPartyMenuMessage(gStringVar4, TRUE);
            ScheduleBgCopyTilemapToVram(2);
            if (gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD && CheckBagHasItem(item, 1))
                gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
            else
                gTasks[taskId].func = task;
        }
    }
}

2.

Finally, find Task_DisplayHPRestoredMessage. Replace gTasks[taskId].func = Task_ClosePartyMenuAfterText; with:

    if (gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD && CheckBagHasItem(gSpecialVar_ItemId, 1))
        gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
    else
        gTasks[taskId].func = Task_ClosePartyMenuAfterText;

Addendum: Rare Candies

Credit: AsparagusEduardo, ghoulslash

You may also want to use this for Rare Candies, so all you have to do is find PartyMenuTryEvolution and replace it with:

static void PartyMenuTryEvolution(u8 taskId)
{
    struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
    u16 targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE);

    if (targetSpecies != SPECIES_NONE)
    {
        FreePartyPointers();
        if (gSpecialVar_ItemId == ITEM_RARE_CANDY && gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD && CheckBagHasItem(gSpecialVar_ItemId, 1))
            gCB2_AfterEvolution = CB2_ReturnToPartyMenuUsingRareCandy;
        else
            gCB2_AfterEvolution = gPartyMenu.exitCallback;
        BeginEvolutionScene(mon, targetSpecies, TRUE, gPartyMenu.slotId);
        DestroyTask(taskId);
    }
    else
    {
        if (gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD && CheckBagHasItem(gSpecialVar_ItemId, 1))
            gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
        else
            gTasks[taskId].func = Task_ClosePartyMenuAfterText;
    }
}

And add the function, CB2_ReturnToPartyMenuUsingRareCandy, somewhere in the file:

static void CB2_ReturnToPartyMenuUsingRareCandy(void)
{
    gItemUseCB = ItemUseCB_RareCandy;
    SetMainCallback2(CB2_ShowPartyMenuForItemUse);
}
Clone this wiki locally