diff --git a/include/item_use.h b/include/item_use.h index 266bcad0b..fb30f3530 100644 --- a/include/item_use.h +++ b/include/item_use.h @@ -12,6 +12,7 @@ void ItemUseOutOfBattle_SSTicket(u8); void ItemUseOutOfBattle_WailmerPail(u8); void ItemUseOutOfBattle_Medicine(u8); void ItemUseOutOfBattle_AbilityCapsule(u8); +void ItemUseOutOfBattle_AbilityPatch(u8); void ItemUseOutOfBattle_ReduceEV(u8); void ItemUseOutOfBattle_SacredAsh(u8); void ItemUseOutOfBattle_PPRecovery(u8); diff --git a/include/party_menu.h b/include/party_menu.h index 845db5222..750b859c0 100644 --- a/include/party_menu.h +++ b/include/party_menu.h @@ -50,6 +50,7 @@ void DrawHeldItemIconsForTrade(u8 *partyCounts, u8 *partySpriteIds, u8 whichPart void CB2_ShowPartyMenuForItemUse(void); void ItemUseCB_Medicine(u8 taskId, TaskFunc task); void ItemUseCB_AbilityCapsule(u8 taskId, TaskFunc task); +void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task); void ItemUseCB_ReduceEV(u8 taskId, TaskFunc task); void ItemUseCB_PPRecovery(u8 taskId, TaskFunc task); void ItemUseCB_PPUp(u8 taskId, TaskFunc task); diff --git a/src/data/items.h b/src/data/items.h index 63ad66dfe..61c1fd770 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -1095,7 +1095,7 @@ const struct Item gItems[] = .description = sAbilityPatchDesc, .pocket = POCKET_ITEMS, .type = ITEM_USE_PARTY_MENU, - .fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo + .fieldUseFunc = ItemUseOutOfBattle_AbilityPatch, }, // Mints diff --git a/src/item_use.c b/src/item_use.c index 284c94c23..86c34f854 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -755,6 +755,12 @@ void ItemUseOutOfBattle_AbilityCapsule(u8 taskId) SetUpItemUseCallback(taskId); } +void ItemUseOutOfBattle_AbilityPatch(u8 taskId) +{ + gItemUseCB = ItemUseCB_AbilityPatch; + SetUpItemUseCallback(taskId); +} + void ItemUseOutOfBattle_ReduceEV(u8 taskId) { gItemUseCB = ItemUseCB_ReduceEV; diff --git a/src/party_menu.c b/src/party_menu.c index 409143777..992aa9c40 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -4475,6 +4475,100 @@ void ItemUseCB_AbilityCapsule(u8 taskId, TaskFunc task) gTasks[taskId].func = Task_AbilityCapsule; } +void Task_AbilityPatch(u8 taskId) +{ + static const u8 askText[] = _("Would you like to change {STR_VAR_1}'s\nability to {STR_VAR_2}?"); + static const u8 doneText[] = _("{STR_VAR_1}'s ability became\n{STR_VAR_2}!{PAUSE_UNTIL_PRESS}"); + s16 *data = gTasks[taskId].data; + + switch (tState) + { + case 0: + + // If Hidden Abilities have been implemented without the use of Pokémon Expansion and added to the `abilities` field + // as ability no. 3 (eg. {ABILITY_OVERGROW, ABILITY_NONE, ABILITY_CHLOROPHYLL} ) + // you can remove this #ifdef. + #ifdef POKEMON_EXPANSION + // Can't use. + if (gBaseStats[tSpecies].abilities[tAbilityNum] == 0 + || !tSpecies + || GetMonData(&gPlayerParty[tMonId], MON_DATA_ABILITY_NUM, NULL) > 1 + ) + #endif + { + gPartyMenuUseExitCallback = FALSE; + PlaySE(SE_SELECT); + DisplayPartyMenuMessage(gText_WontHaveEffect, 1); + ScheduleBgCopyTilemapToVram(2); + gTasks[taskId].func = Task_ClosePartyMenuAfterText; + return; + } + gPartyMenuUseExitCallback = TRUE; + GetMonNickname(&gPlayerParty[tMonId], gStringVar1); + StringCopy(gStringVar2, gAbilityNames[GetAbilityBySpecies(tSpecies, tAbilityNum)]); + StringExpandPlaceholders(gStringVar4, askText); + PlaySE(SE_SELECT); + DisplayPartyMenuMessage(gStringVar4, 1); + ScheduleBgCopyTilemapToVram(2); + tState++; + break; + case 1: + if (!IsPartyMenuTextPrinterActive()) + { + PartyMenuDisplayYesNoMenu(); + tState++; + } + break; + case 2: + switch (Menu_ProcessInputNoWrapClearOnChoose()) + { + case 0: + tState++; + break; + case 1: + case MENU_B_PRESSED: + gPartyMenuUseExitCallback = FALSE; + PlaySE(SE_SELECT); + ScheduleBgCopyTilemapToVram(2); + // Don't exit party selections screen, return to choosing a mon. + ClearStdWindowAndFrameToTransparent(6, 0); + ClearWindowTilemap(6); + DisplayPartyMenuStdMessage(5); + gTasks[taskId].func = (void *)GetWordTaskArg(taskId, tOldFunc); + return; + } + break; + case 3: + PlaySE(SE_USE_ITEM); + StringExpandPlaceholders(gStringVar4, doneText); + DisplayPartyMenuMessage(gStringVar4, 1); + ScheduleBgCopyTilemapToVram(2); + tState++; + break; + case 4: + if (!IsPartyMenuTextPrinterActive()) + tState++; + break; + case 5: + SetMonData(&gPlayerParty[tMonId], MON_DATA_ABILITY_NUM, &tAbilityNum); + RemoveBagItem(gSpecialVar_ItemId, 1); + gTasks[taskId].func = Task_ClosePartyMenu; + break; + } +} + +void ItemUseCB_AbilityPatch(u8 taskId, TaskFunc task) +{ + s16 *data = gTasks[taskId].data; + + tState = 0; + tMonId = gPartyMenu.slotId; + tSpecies = GetMonData(&gPlayerParty[tMonId], MON_DATA_SPECIES, NULL); + tAbilityNum = 2; + SetWordTaskArg(taskId, tOldFunc, (uintptr_t)(gTasks[taskId].func)); + gTasks[taskId].func = Task_AbilityPatch; +} + #undef tState #undef tSpecies #undef tAbilityNum