pokefirered/src/item_use.c
2024-08-27 13:57:07 -04:00

926 lines
28 KiB
C

#include "global.h"
#include "gflib.h"
#include "battle.h"
#include "berry_pouch.h"
#include "berry_powder.h"
#include "bike.h"
#include "coins.h"
#include "event_data.h"
#include "field_effect.h"
#include "field_fadetransition.h"
#include "event_object_movement.h"
#include "field_player_avatar.h"
#include "field_specials.h"
#include "field_weather.h"
#include "fieldmap.h"
#include "item.h"
#include "item_menu.h"
#include "item_use.h"
#include "itemfinder.h"
#include "mail.h"
#include "event_object_lock.h"
#include "metatile_behavior.h"
#include "new_menu_helpers.h"
#include "overworld.h"
#include "party_menu.h"
#include "quest_log.h"
#include "region_map.h"
#include "script.h"
#include "strings.h"
#include "task.h"
#include "teachy_tv.h"
#include "tm_case.h"
#include "vs_seeker.h"
#include "constants/sound.h"
#include "constants/items.h"
#include "constants/item_effects.h"
#include "constants/maps.h"
#include "constants/moves.h"
#include "constants/songs.h"
#include "constants/field_weather.h"
static EWRAM_DATA void (*sItemUseOnFieldCB)(u8 taskId) = NULL;
static void FieldCB_FadeInFromBlack(void);
static void Task_WaitFadeIn_CallItemUseOnFieldCB(u8 taskId);
static void Task_ItemUse_CloseMessageBoxAndReturnToField(u8 taskId);
static void Task_ItemUseWaitForFade(u8 taskId);
static bool8 FieldCB2_UseItemFromField(void);
static void CB2_CheckMail(void);
static void ItemUseOnFieldCB_Bicycle(u8 taskId);
static bool8 CanFish(void);
static void ItemUseOnFieldCB_Rod(u8 taskId);
static void Task_PlayPokeFlute(u8 taskId);
static void Task_DisplayPokeFluteMessage(u8 taskId);
static void InitTMCaseFromBag(void);
static void Task_InitTMCaseFromField(u8 taskId);
static void InitBerryPouchFromBag(void);
static void Task_InitBerryPouchFromField(u8 taskId);
static void InitBerryPouchFromBattle(void);
static void InitTeachyTvFromBag(void);
static void Task_InitTeachyTvFromField(u8 taskId);
static void Task_UseRepel(u8 taskId);
static void RemoveUsedItem(void);
static void Task_UsedBlackWhiteFlute(u8 taskId);
static void ItemUseOnFieldCB_EscapeRope(u8 taskId);
static void UseTownMapFromBag(void);
static void Task_UseTownMapFromField(u8 taskId);
static void UseFameCheckerFromBag(void);
static void Task_UseFameCheckerFromField(u8 taskId);
static void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId);
static void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId);
// unknown unused data.
// It's curiously about the size of an array of values indexed by species (including padding),
// but the arrangement of values is not sensible (e.g., not giving all "old unown" the same value).
static const u8 sUnused[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x21, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0x00, 0xe0, 0x03, 0x00, 0x7c,
0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static void (*const sExitCallbackByItemType[])(void) = {
[ITEM_TYPE_PARTY_MENU - 1] = CB2_ShowPartyMenuForItemUse,
[ITEM_TYPE_FIELD - 1] = CB2_ReturnToField,
[ITEM_TYPE_UNUSED - 1] = NULL,
[ITEM_TYPE_BAG_MENU - 1] = NULL,
};
static void SetUpItemUseCallback(u8 taskId)
{
u8 itemType;
if (gSpecialVar_ItemId == ITEM_ENIGMA_BERRY)
itemType = gTasks[taskId].data[4] - 1;
else
itemType = ItemId_GetType(gSpecialVar_ItemId) - 1;
if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_BERRY_POUCH)
{
BerryPouch_SetExitCallback(sExitCallbackByItemType[itemType]);
BerryPouch_StartFadeToExitCallback(taskId);
}
else
{
ItemMenu_SetExitCallback(sExitCallbackByItemType[itemType]);
if (itemType == ITEM_TYPE_FIELD - 1)
Bag_BeginCloseWin0Animation();
ItemMenu_StartFadeToExitCallback(taskId);
}
}
static void SetUpItemUseOnFieldCallback(u8 taskId)
{
if (gTasks[taskId].data[3] != 1)
{
gFieldCallback = FieldCB_FadeInFromBlack;
SetUpItemUseCallback(taskId);
}
else
sItemUseOnFieldCB(taskId);
}
static void FieldCB_FadeInFromBlack(void)
{
FadeInFromBlack();
CreateTask(Task_WaitFadeIn_CallItemUseOnFieldCB, 8);
}
static void Task_WaitFadeIn_CallItemUseOnFieldCB(u8 taskId)
{
if (IsWeatherNotFadingIn() == TRUE)
sItemUseOnFieldCB(taskId);
}
static void DisplayItemMessageInCurrentContext(u8 taskId, bool8 inField, u8 fontId, const u8 *str)
{
StringExpandPlaceholders(gStringVar4, str);
if (inField == FALSE)
DisplayItemMessageInBag(taskId, fontId, gStringVar4, Task_ReturnToBagFromContextMenu);
else
DisplayItemMessageOnField(taskId, fontId, gStringVar4, Task_ItemUse_CloseMessageBoxAndReturnToField);
}
static void PrintNotTheTimeToUseThat(u8 taskId, bool8 inField)
{
DisplayItemMessageInCurrentContext(taskId, inField, FONT_MALE, gText_OakForbidsUseOfItemHere);
}
static void Task_ItemUse_CloseMessageBoxAndReturnToField(u8 taskId)
{
ClearDialogWindowAndFrame(0, 1);
DestroyTask(taskId);
ClearPlayerHeldMovementAndUnfreezeObjectEvents();
UnlockPlayerFieldControls();
}
u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId)
{
if (ItemId_GetPocket(itemId) == POCKET_TM_CASE)
return 1;
else if (ItemId_GetFieldFunc(itemId) == FieldUseFunc_EvoItem)
return 2;
else
return 0;
}
static void SetFieldCallback2ForItemUse(void)
{
gFieldCallback2 = FieldCB2_UseItemFromField;
}
static bool8 FieldCB2_UseItemFromField(void)
{
FreezeObjectEvents();
LockPlayerFieldControls();
FadeInFromBlack();
CreateTask(Task_ItemUseWaitForFade, 10);
gExitStairsMovementDisabled = FALSE;
return TRUE;
}
static void Task_ItemUseWaitForFade(u8 taskId)
{
if (IsWeatherNotFadingIn() == TRUE)
{
UnfreezeObjectEvents();
UnlockPlayerFieldControls();
DestroyTask(taskId);
}
}
void FieldUseFunc_Mail(u8 taskId)
{
ItemMenu_SetExitCallback(CB2_CheckMail);
ItemMenu_StartFadeToExitCallback(taskId);
}
static void CB2_CheckMail(void)
{
struct Mail mail;
mail.itemId = gSpecialVar_ItemId;
ReadMail(&mail, CB2_BagMenuFromStartMenu, FALSE);
}
void FieldUseFunc_Bike(u8 taskId)
{
s16 x, y;
u8 behavior;
PlayerGetDestCoords(&x, &y);
behavior = MapGridGetMetatileBehaviorAt(x, y);
if (FlagGet(FLAG_SYS_ON_CYCLING_ROAD) == TRUE
|| MetatileBehavior_IsVerticalRail(behavior) == TRUE
|| MetatileBehavior_IsHorizontalRail(behavior) == TRUE
|| MetatileBehavior_IsIsolatedVerticalRail(behavior) == TRUE
|| MetatileBehavior_IsIsolatedHorizontalRail(behavior) == TRUE)
DisplayItemMessageInCurrentContext(taskId, gTasks[taskId].data[3], FONT_NORMAL, gText_CantDismountBike);
else if (Overworld_IsBikingAllowed() == TRUE && !IsBikingDisallowedByPlayer())
{
sItemUseOnFieldCB = ItemUseOnFieldCB_Bicycle;
SetUpItemUseOnFieldCallback(taskId);
}
else
PrintNotTheTimeToUseThat(taskId, gTasks[taskId].data[3]);
}
static void ItemUseOnFieldCB_Bicycle(u8 taskId)
{
if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
PlaySE(SE_BIKE_BELL);
GetOnOffBike(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE);
ClearPlayerHeldMovementAndUnfreezeObjectEvents();
UnlockPlayerFieldControls();
DestroyTask(taskId);
}
void FieldUseFunc_Rod(u8 taskId)
{
if (CanFish() == TRUE)
{
sItemUseOnFieldCB = ItemUseOnFieldCB_Rod;
SetUpItemUseOnFieldCallback(taskId);
}
else
PrintNotTheTimeToUseThat(taskId, gTasks[taskId].data[3]);
}
static bool8 CanFish(void)
{
s16 x, y;
u16 behavior;
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
behavior = MapGridGetMetatileBehaviorAt(x, y);
if (MetatileBehavior_IsWaterfall(behavior))
return FALSE;
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_UNDERWATER))
return FALSE;
if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
{
if (IsPlayerFacingSurfableFishableWater())
return TRUE;
}
else
{
if (MetatileBehavior_IsSurfable(behavior) && MapGridGetCollisionAt(x, y) == 0)
return TRUE;
if (MetatileBehavior_IsBridge(behavior) == TRUE)
return TRUE;
}
return FALSE;
}
static void ItemUseOnFieldCB_Rod(u8 taskId)
{
StartFishing(ItemId_GetSecondaryId(gSpecialVar_ItemId));
DestroyTask(taskId);
}
void ItemUseOutOfBattle_Itemfinder(u8 taskId)
{
IncrementGameStat(GAME_STAT_USED_ITEMFINDER);
sItemUseOnFieldCB = ItemUseOnFieldCB_Itemfinder;
SetUpItemUseOnFieldCallback(taskId);
}
void FieldUseFunc_CoinCase(u8 taskId)
{
ConvertIntToDecimalStringN(gStringVar1, GetCoins(), STR_CONV_MODE_LEFT_ALIGN, 4);
StringExpandPlaceholders(gStringVar4, gText_CoinCase);
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
if (gTasks[taskId].data[3] == 0)
DisplayItemMessageInBag(taskId, FONT_NORMAL, gStringVar4, Task_ReturnToBagFromContextMenu);
else
DisplayItemMessageOnField(taskId, FONT_NORMAL, gStringVar4, Task_ItemUse_CloseMessageBoxAndReturnToField);
}
void FieldUseFunc_PowderJar(u8 taskId)
{
ConvertIntToDecimalStringN(gStringVar1, GetBerryPowder(), STR_CONV_MODE_LEFT_ALIGN, 5);
StringExpandPlaceholders(gStringVar4, gText_PowderQty);
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
if (gTasks[taskId].data[3] == 0)
DisplayItemMessageInBag(taskId, FONT_NORMAL, gStringVar4, Task_ReturnToBagFromContextMenu);
else
DisplayItemMessageOnField(taskId, FONT_NORMAL, gStringVar4, Task_ItemUse_CloseMessageBoxAndReturnToField);
}
void FieldUseFunc_PokeFlute(u8 taskId)
{
bool8 wokeSomeoneUp = FALSE;
u8 i;
for (i = 0; i < CalculatePlayerPartyCount(); i++)
{
if (!ExecuteTableBasedItemEffect(&gPlayerParty[i], ITEM_AWAKENING, i, 0))
wokeSomeoneUp = TRUE;
}
if (wokeSomeoneUp)
{
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
if (gTasks[taskId].data[3] == 0)
DisplayItemMessageInBag(taskId, FONT_NORMAL, gText_PlayedPokeFlute, Task_PlayPokeFlute);
else
DisplayItemMessageOnField(taskId, FONT_NORMAL, gText_PlayedPokeFlute, Task_PlayPokeFlute);
}
else
{
if (gTasks[taskId].data[3] == 0)
DisplayItemMessageInBag(taskId, FONT_NORMAL, gText_PlayedPokeFluteCatchy, Task_ReturnToBagFromContextMenu);
else
DisplayItemMessageOnField(taskId, FONT_NORMAL, gText_PlayedPokeFluteCatchy, Task_ItemUse_CloseMessageBoxAndReturnToField);
}
}
static void Task_PlayPokeFlute(u8 taskId)
{
PlayFanfareByFanfareNum(FANFARE_POKE_FLUTE);
gTasks[taskId].func = Task_DisplayPokeFluteMessage;
}
static void Task_DisplayPokeFluteMessage(u8 taskId)
{
if (WaitFanfare(FALSE))
{
if (gTasks[taskId].data[3] == 0)
DisplayItemMessageInBag(taskId, FONT_NORMAL, gText_PokeFluteAwakenedMon, Task_ReturnToBagFromContextMenu);
else
DisplayItemMessageOnField(taskId, FONT_NORMAL, gText_PokeFluteAwakenedMon, Task_ItemUse_CloseMessageBoxAndReturnToField);
}
}
static void DoSetUpItemUseCallback(u8 taskId)
{
SetUpItemUseCallback(taskId);
}
void FieldUseFunc_Medicine(u8 taskId)
{
gItemUseCB = ItemUseCB_Medicine;
DoSetUpItemUseCallback(taskId);
}
void FieldUseFunc_Ether(u8 taskId)
{
gItemUseCB = ItemUseCB_TryRestorePP;
DoSetUpItemUseCallback(taskId);
}
void FieldUseFunc_PpUp(u8 taskId)
{
gItemUseCB = ItemUseCB_PPUp;
DoSetUpItemUseCallback(taskId);
}
void FieldUseFunc_RareCandy(u8 taskId)
{
gItemUseCB = ItemUseCB_RareCandy;
DoSetUpItemUseCallback(taskId);
}
void FieldUseFunc_EvoItem(u8 taskId)
{
gItemUseCB = ItemUseCB_EvolutionStone;
DoSetUpItemUseCallback(taskId);
}
void FieldUseFunc_SacredAsh(u8 taskId)
{
gItemUseCB = ItemUseCB_SacredAsh;
SetUpItemUseCallback(taskId);
}
void FieldUseFunc_TmCase(u8 taskId)
{
if (gTasks[taskId].data[3] == 0)
{
ItemMenu_SetExitCallback(InitTMCaseFromBag);
ItemMenu_StartFadeToExitCallback(taskId);
}
else
{
StopPokemonLeagueLightingEffectTask();
FadeScreen(FADE_TO_BLACK, 0);
gTasks[taskId].func = Task_InitTMCaseFromField;
}
}
static void InitTMCaseFromBag(void)
{
InitTMCase(TMCASE_FIELD, CB2_BagMenuFromStartMenu, FALSE);
}
static void Task_InitTMCaseFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
CleanupOverworldWindowsAndTilemaps();
SetFieldCallback2ForItemUse();
InitTMCase(TMCASE_FIELD, CB2_ReturnToField, TRUE);
DestroyTask(taskId);
}
}
void FieldUseFunc_BerryPouch(u8 taskId)
{
if (gTasks[taskId].data[3] == 0)
{
ItemMenu_SetExitCallback(InitBerryPouchFromBag);
ItemMenu_StartFadeToExitCallback(taskId);
}
else
{
StopPokemonLeagueLightingEffectTask();
FadeScreen(FADE_TO_BLACK, 0);
gTasks[taskId].func = Task_InitBerryPouchFromField;
}
}
static void InitBerryPouchFromBag(void)
{
InitBerryPouch(BERRYPOUCH_FROMFIELD, CB2_BagMenuFromStartMenu, 0);
}
static void Task_InitBerryPouchFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
CleanupOverworldWindowsAndTilemaps();
SetFieldCallback2ForItemUse();
InitBerryPouch(BERRYPOUCH_FROMFIELD, CB2_ReturnToField, 1);
DestroyTask(taskId);
}
}
void BattleUseFunc_BerryPouch(u8 taskId)
{
ItemMenu_SetExitCallback(InitBerryPouchFromBattle);
ItemMenu_StartFadeToExitCallback(taskId);
}
static void InitBerryPouchFromBattle(void)
{
InitBerryPouch(BERRYPOUCH_FROMBATTLE, CB2_BagMenuFromBattle, 0);
}
void FieldUseFunc_TeachyTv(u8 taskId)
{
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
if (gTasks[taskId].data[3] == 0)
{
ItemMenu_SetExitCallback(InitTeachyTvFromBag);
ItemMenu_StartFadeToExitCallback(taskId);
}
else
{
StopPokemonLeagueLightingEffectTask();
FadeScreen(FADE_TO_BLACK, 0);
gTasks[taskId].func = Task_InitTeachyTvFromField;
}
}
static void InitTeachyTvFromBag(void)
{
InitTeachyTvController(0, CB2_BagMenuFromStartMenu);
}
static void Task_InitTeachyTvFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
CleanupOverworldWindowsAndTilemaps();
SetFieldCallback2ForItemUse();
InitTeachyTvController(0, CB2_ReturnToField);
DestroyTask(taskId);
}
}
void FieldUseFunc_Repel(u8 taskId)
{
if (VarGet(VAR_REPEL_STEP_COUNT) == 0)
{
PlaySE(SE_REPEL);
gTasks[taskId].func = Task_UseRepel;
}
else
// An earlier repel is still in effect
DisplayItemMessageInBag(taskId, FONT_NORMAL, gText_RepelEffectsLingered, Task_ReturnToBagFromContextMenu);
}
static void Task_UseRepel(u8 taskId)
{
if (!IsSEPlaying())
{
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gSpecialVar_ItemId));
RemoveUsedItem();
DisplayItemMessageInBag(taskId, FONT_NORMAL, gStringVar4, Task_ReturnToBagFromContextMenu);
}
}
static void RemoveUsedItem(void)
{
RemoveBagItem(gSpecialVar_ItemId, 1);
Pocket_CalculateNItemsAndMaxShowed(ItemId_GetPocket(gSpecialVar_ItemId));
PocketCalculateInitialCursorPosAndItemsAbove(ItemId_GetPocket(gSpecialVar_ItemId));
CopyItemName(gSpecialVar_ItemId, gStringVar2);
StringExpandPlaceholders(gStringVar4, gText_PlayerUsedVar2);
}
void FieldUseFunc_BlackWhiteFlute(u8 taskId)
{
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
if (gSpecialVar_ItemId == ITEM_WHITE_FLUTE)
{
FlagSet(FLAG_SYS_WHITE_FLUTE_ACTIVE);
FlagClear(FLAG_SYS_BLACK_FLUTE_ACTIVE);
CopyItemName(gSpecialVar_ItemId, gStringVar2);
StringExpandPlaceholders(gStringVar4, gText_UsedVar2WildLured);
gTasks[taskId].func = Task_UsedBlackWhiteFlute;
gTasks[taskId].data[8] = 0;
}
else if (gSpecialVar_ItemId == ITEM_BLACK_FLUTE)
{
FlagSet(FLAG_SYS_BLACK_FLUTE_ACTIVE);
FlagClear(FLAG_SYS_WHITE_FLUTE_ACTIVE);
CopyItemName(gSpecialVar_ItemId, gStringVar2);
StringExpandPlaceholders(gStringVar4, gText_UsedVar2WildRepelled);
gTasks[taskId].func = Task_UsedBlackWhiteFlute;
gTasks[taskId].data[8] = 0;
}
}
static void Task_UsedBlackWhiteFlute(u8 taskId)
{
if (++gTasks[taskId].data[8] > 7)
{
PlaySE(SE_GLASS_FLUTE);
DisplayItemMessageInBag(taskId, FONT_NORMAL, gStringVar4, Task_ReturnToBagFromContextMenu);
}
}
bool8 CanUseEscapeRopeOnCurrMap(void)
{
if (gMapHeader.allowEscaping)
return TRUE;
else
return FALSE;
}
void ItemUseOutOfBattle_EscapeRope(u8 taskId)
{
if (CanUseEscapeRopeOnCurrMap() == TRUE)
{
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, gMapHeader.regionMapSectionId);
sItemUseOnFieldCB = ItemUseOnFieldCB_EscapeRope;
SetUpItemUseOnFieldCallback(taskId);
}
else
PrintNotTheTimeToUseThat(taskId, gTasks[taskId].data[3]);
}
static void ItemUseOnFieldCB_EscapeRope(u8 taskId)
{
Overworld_ResetStateAfterDigEscRope();
RemoveUsedItem();
gTasks[taskId].data[0] = 0;
DisplayItemMessageOnField(taskId, FONT_NORMAL, gStringVar4, Task_UseDigEscapeRopeOnField);
}
void Task_UseDigEscapeRopeOnField(u8 taskId)
{
ResetInitialPlayerAvatarState();
StartEscapeRopeFieldEffect();
DestroyTask(taskId);
}
void FieldUseFunc_TownMap(u8 taskId)
{
if (gTasks[taskId].data[3] == 0)
{
ItemMenu_SetExitCallback(UseTownMapFromBag);
ItemMenu_StartFadeToExitCallback(taskId);
}
else
{
StopPokemonLeagueLightingEffectTask();
FadeScreen(FADE_TO_BLACK, 0);
gTasks[taskId].func = Task_UseTownMapFromField;
}
}
static void UseTownMapFromBag(void)
{
InitRegionMapWithExitCB(REGIONMAP_TYPE_NORMAL, CB2_BagMenuFromStartMenu);
}
static void Task_UseTownMapFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
CleanupOverworldWindowsAndTilemaps();
SetFieldCallback2ForItemUse();
InitRegionMapWithExitCB(REGIONMAP_TYPE_NORMAL, CB2_ReturnToField);
DestroyTask(taskId);
}
}
void FieldUseFunc_FameChecker(u8 taskId)
{
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, NULL, gSpecialVar_ItemId, 0xFFFF);
if (gTasks[taskId].data[3] == 0)
{
ItemMenu_SetExitCallback(UseFameCheckerFromBag);
ItemMenu_StartFadeToExitCallback(taskId);
}
else
{
StopPokemonLeagueLightingEffectTask();
FadeScreen(FADE_TO_BLACK, 0);
gTasks[taskId].func = Task_UseFameCheckerFromField;
}
}
static void UseFameCheckerFromBag(void)
{
UseFameChecker(CB2_BagMenuFromStartMenu);
}
static void Task_UseFameCheckerFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
CleanupOverworldWindowsAndTilemaps();
SetFieldCallback2ForItemUse();
UseFameChecker(CB2_ReturnToField);
DestroyTask(taskId);
}
}
void FieldUseFunc_VsSeeker(u8 taskId)
{
if ((gMapHeader.mapType != MAP_TYPE_ROUTE
&& gMapHeader.mapType != MAP_TYPE_TOWN
&& gMapHeader.mapType != MAP_TYPE_CITY)
|| (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(MAP_VIRIDIAN_FOREST)
&& (gSaveBlock1Ptr->location.mapNum == MAP_NUM(MAP_VIRIDIAN_FOREST)
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(MAP_MT_EMBER_EXTERIOR)
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(MAP_THREE_ISLAND_BERRY_FOREST)
|| gSaveBlock1Ptr->location.mapNum == MAP_NUM(MAP_SIX_ISLAND_PATTERN_BUSH))))
{
PrintNotTheTimeToUseThat(taskId, gTasks[taskId].data[3]);
}
else
{
sItemUseOnFieldCB = Task_VsSeeker_0;
SetUpItemUseOnFieldCallback(taskId);
}
}
void Task_ItemUse_CloseMessageBoxAndReturnToField_VsSeeker(u8 taskId)
{
Task_ItemUse_CloseMessageBoxAndReturnToField(taskId);
}
void BattleUseFunc_PokeBallEtc(u8 taskId)
{
if (!IsPlayerPartyAndPokemonStorageFull())
{
RemoveBagItem(gSpecialVar_ItemId, 1);
Bag_BeginCloseWin0Animation();
ItemMenu_StartFadeToExitCallback(taskId);
}
else
DisplayItemMessageInBag(taskId, FONT_NORMAL, gText_BoxFull, Task_ReturnToBagFromContextMenu);
}
void BattleUseFunc_PokeFlute(u8 taskId)
{
Bag_BeginCloseWin0Animation();
ItemMenu_StartFadeToExitCallback(taskId);
}
void BattleUseFunc_StatBooster(u8 taskId)
{
if (ExecuteTableBasedItemEffect(&gPlayerParty[gBattlerPartyIndexes[gBattlerInMenuId]], gSpecialVar_ItemId, gBattlerPartyIndexes[gBattlerInMenuId], 0))
DisplayItemMessageInBag(taskId, FONT_NORMAL, gText_WontHaveEffect, Task_ReturnToBagFromContextMenu);
else
{
gTasks[taskId].data[8] = 0;
gTasks[taskId].func = Task_BattleUse_StatBooster_DelayAndPrint;
}
}
static void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId)
{
s16 *data = gTasks[taskId].data;
if (++data[8] > 7)
{
u16 itemId = gSpecialVar_ItemId;
PlaySE(SE_USE_ITEM);
RemoveBagItem(itemId, 1);
DisplayItemMessageInBag(taskId, FONT_NORMAL, Battle_PrintStatBoosterEffectMessage(itemId), Task_BattleUse_StatBooster_WaitButton_ReturnToBattle);
}
}
static void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId)
{
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
{
Bag_BeginCloseWin0Animation();
ItemMenu_StartFadeToExitCallback(taskId);
}
}
static void ItemUse_SwitchToPartyMenuInBattle(u8 taskId)
{
if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_BERRY_POUCH)
{
BerryPouch_SetExitCallback(EnterPartyFromItemMenuInBattle);
BerryPouch_StartFadeToExitCallback(taskId);
}
else
{
ItemMenu_SetExitCallback(EnterPartyFromItemMenuInBattle);
ItemMenu_StartFadeToExitCallback(taskId);
}
}
void BattleUseFunc_Medicine(u8 taskId)
{
gItemUseCB = ItemUseCB_MedicineStep;
ItemUse_SwitchToPartyMenuInBattle(taskId);
}
// Unused. Sacred Ash cannot be used in battle
static void BattleUseFunc_SacredAsh(u8 taskId)
{
gItemUseCB = ItemUseCB_SacredAsh;
ItemUse_SwitchToPartyMenuInBattle(taskId);
}
void BattleUseFunc_Ether(u8 taskId)
{
gItemUseCB = ItemUseCB_TryRestorePP;
ItemUse_SwitchToPartyMenuInBattle(taskId);
}
void BattleUseFunc_PokeDoll(u8 taskId)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
{
RemoveUsedItem();
ItemUse_SetQuestLogEvent(QL_EVENT_USED_ITEM, 0, gSpecialVar_ItemId, 0xFFFF);
DisplayItemMessageInBag(taskId, FONT_NORMAL, gStringVar4, ItemMenu_StartFadeToExitCallback);
}
else
PrintNotTheTimeToUseThat(taskId, 0);
}
void ItemUseOutOfBattle_EnigmaBerry(u8 taskId)
{
switch (GetItemEffectType(gSpecialVar_ItemId))
{
case ITEM_EFFECT_HEAL_HP:
case ITEM_EFFECT_CURE_POISON:
case ITEM_EFFECT_CURE_SLEEP:
case ITEM_EFFECT_CURE_BURN:
case ITEM_EFFECT_CURE_FREEZE:
case ITEM_EFFECT_CURE_PARALYSIS:
case ITEM_EFFECT_CURE_ALL_STATUS:
case ITEM_EFFECT_ATK_EV:
case ITEM_EFFECT_HP_EV:
case ITEM_EFFECT_SPATK_EV:
case ITEM_EFFECT_SPDEF_EV:
case ITEM_EFFECT_SPEED_EV:
case ITEM_EFFECT_DEF_EV:
gTasks[taskId].data[4] = 1;
FieldUseFunc_Medicine(taskId);
break;
case ITEM_EFFECT_SACRED_ASH:
gTasks[taskId].data[4] = 1;
FieldUseFunc_SacredAsh(taskId);
break;
case ITEM_EFFECT_RAISE_LEVEL:
gTasks[taskId].data[4] = 1;
FieldUseFunc_RareCandy(taskId);
break;
case ITEM_EFFECT_PP_UP:
case ITEM_EFFECT_PP_MAX:
gTasks[taskId].data[4] = 1;
FieldUseFunc_PpUp(taskId);
break;
case ITEM_EFFECT_HEAL_PP:
gTasks[taskId].data[4] = 1;
FieldUseFunc_Ether(taskId);
break;
default:
gTasks[taskId].data[4] = 4;
FieldUseFunc_OakStopsYou(taskId);
}
}
void ItemUseInBattle_EnigmaBerry(u8 taskId)
{
switch (GetItemEffectType(gSpecialVar_ItemId))
{
case ITEM_EFFECT_X_ITEM:
BattleUseFunc_StatBooster(taskId);
break;
case ITEM_EFFECT_HEAL_HP:
case ITEM_EFFECT_CURE_POISON:
case ITEM_EFFECT_CURE_SLEEP:
case ITEM_EFFECT_CURE_BURN:
case ITEM_EFFECT_CURE_FREEZE:
case ITEM_EFFECT_CURE_PARALYSIS:
case ITEM_EFFECT_CURE_CONFUSION:
case ITEM_EFFECT_CURE_INFATUATION:
case ITEM_EFFECT_CURE_ALL_STATUS:
BattleUseFunc_Medicine(taskId);
break;
case ITEM_EFFECT_HEAL_PP:
BattleUseFunc_Ether(taskId);
break;
default:
FieldUseFunc_OakStopsYou(taskId);
}
}
void FieldUseFunc_OakStopsYou(u8 taskId)
{
if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_BERRY_POUCH)
{
StringExpandPlaceholders(gStringVar4, gText_OakForbidsUseOfItemHere);
DisplayItemMessageInBerryPouch(taskId, FONT_MALE, gStringVar4, Task_BerryPouch_DestroyDialogueWindowAndRefreshListMenu);
}
else
PrintNotTheTimeToUseThat(taskId, gTasks[taskId].data[3]);
}
void ItemUse_SetQuestLogEvent(u8 eventId, struct Pokemon *pokemon, u16 itemId, u16 param)
{
struct QuestLogEvent_Item *data = Alloc(sizeof(*data));
data->itemId = itemId;
data->itemParam = param;
if (pokemon != NULL)
data->species = GetMonData(pokemon, MON_DATA_SPECIES_OR_EGG);
else
data->species = 0xFFFF;
SetQuestLogEvent(eventId, (void *)data);
Free(data);
}