summaryrefslogtreecommitdiff
path: root/Repeated-Field-Medicine-Use.md
blob: d9d8e903f245ba6f55c8a1cc7065b43397cfbe7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
## 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](../blob/master/src/party_menu.c)

### 1. 

First, find the function `ItemUseCB_Medicine`. Replace the entire thing with:
```c
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:
```c
    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

Credits: AsparagusEduardo, ghoulslash, Alex N

You may also want to use this for Rare Candies, so what you have to do is find `PartyMenuTryEvolution` and replace it with:
```c
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;
    }
}
```
Then add the function, `CB2_ReturnToPartyMenuUsingRareCandy`, somewhere in the file:
```c
static void CB2_ReturnToPartyMenuUsingRareCandy(void)
{
    gItemUseCB = ItemUseCB_RareCandy;
    SetMainCallback2(CB2_ShowPartyMenuForItemUse);
}
```
This last section is for letting the player keep using Rare Candies after learning a new move. (*credit to Alex N*)

Look for `CB2_ReturnToPartyMenuWhileLearningMove` and replace it with the following:
```c
static void CB2_ReturnToPartyMenuWhileLearningMove(void)
{
    if (gSpecialVar_ItemId == ITEM_RARE_CANDY && gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD && CheckBagHasItem(gSpecialVar_ItemId, 1))
        InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_USE_ITEM, TRUE, PARTY_MSG_NONE, Task_ReturnToPartyMenuWhileLearningMove, gPartyMenu.exitCallback);
    else
        InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, TRUE, PARTY_MSG_NONE, Task_ReturnToPartyMenuWhileLearningMove, gPartyMenu.exitCallback);
}
```