import from github
This commit is contained in:
3404
src/item_menu.c
Executable file
3404
src/item_menu.c
Executable file
@ -0,0 +1,3404 @@
|
||||
#include "global.h"
|
||||
#include "item_menu.h"
|
||||
#include "battle.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "battle_pyramid.h"
|
||||
#include "frontier_util.h"
|
||||
#include "battle_pyramid_bag.h"
|
||||
#include "berry_tag_screen.h"
|
||||
#include "bg.h"
|
||||
#include "data.h"
|
||||
#include "decompress.h"
|
||||
#include "event_data.h"
|
||||
#include "event_object_movement.h"
|
||||
#include "event_scripts.h"
|
||||
#include "field_player_avatar.h"
|
||||
#include "field_specials.h"
|
||||
#include "graphics.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "international_string_util.h"
|
||||
#include "item.h"
|
||||
#include "item_menu_icons.h"
|
||||
#include "item_use.h"
|
||||
#include "lilycove_lady.h"
|
||||
#include "list_menu.h"
|
||||
#include "link.h"
|
||||
#include "mail.h"
|
||||
#include "main.h"
|
||||
#include "malloc.h"
|
||||
#include "map_name_popup.h"
|
||||
#include "menu.h"
|
||||
#include "money.h"
|
||||
#include "overworld.h"
|
||||
#include "palette.h"
|
||||
#include "party_menu.h"
|
||||
#include "player_pc.h"
|
||||
#include "pokemon.h"
|
||||
#include "pokemon_summary_screen.h"
|
||||
#include "scanline_effect.h"
|
||||
#include "script.h"
|
||||
#include "shop.h"
|
||||
#include "sound.h"
|
||||
#include "sprite.h"
|
||||
#include "strings.h"
|
||||
#include "string_util.h"
|
||||
#include "task.h"
|
||||
#include "text_window.h"
|
||||
#include "menu_helpers.h"
|
||||
#include "window.h"
|
||||
#include "apprentice.h"
|
||||
#include "battle_pike.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "constants/songs.h"
|
||||
|
||||
#define TAG_POCKET_SCROLL_ARROW 110
|
||||
#define TAG_BAG_SCROLL_ARROW 111
|
||||
|
||||
// The buffer for the bag item list needs to be large enough to hold the maximum
|
||||
// number of item slots that could fit in a single pocket, + 1 for Cancel.
|
||||
// This constant picks the max of the existing pocket sizes.
|
||||
// By default, the largest pocket is BAG_TMHM_COUNT at 64.
|
||||
#define MAX_POCKET_ITEMS ((max(BAG_TMHM_COUNT, \
|
||||
max(BAG_BERRIES_COUNT, \
|
||||
max(BAG_ITEMS_COUNT, \
|
||||
max(BAG_KEYITEMS_COUNT, \
|
||||
BAG_POKEBALLS_COUNT))))) + 1)
|
||||
|
||||
// Up to 8 item slots can be visible at a time
|
||||
#define MAX_ITEMS_SHOWN 8
|
||||
|
||||
enum {
|
||||
SWITCH_POCKET_NONE,
|
||||
SWITCH_POCKET_LEFT,
|
||||
SWITCH_POCKET_RIGHT
|
||||
};
|
||||
|
||||
enum {
|
||||
ACTION_USE,
|
||||
ACTION_TOSS,
|
||||
ACTION_REGISTER,
|
||||
ACTION_GIVE,
|
||||
ACTION_CANCEL,
|
||||
ACTION_BATTLE_USE,
|
||||
ACTION_CHECK,
|
||||
ACTION_WALK,
|
||||
ACTION_DESELECT,
|
||||
ACTION_CHECK_TAG,
|
||||
ACTION_CONFIRM,
|
||||
ACTION_SHOW,
|
||||
ACTION_GIVE_FAVOR_LADY,
|
||||
ACTION_CONFIRM_QUIZ_LADY,
|
||||
ACTION_BY_NAME,
|
||||
ACTION_BY_TYPE,
|
||||
ACTION_BY_AMOUNT,
|
||||
ACTION_DUMMY,
|
||||
};
|
||||
|
||||
enum {
|
||||
WIN_ITEM_LIST,
|
||||
WIN_DESCRIPTION,
|
||||
WIN_POCKET_NAME,
|
||||
WIN_TMHM_INFO_ICONS,
|
||||
WIN_TMHM_INFO,
|
||||
WIN_MESSAGE, // Identical to ITEMWIN_MESSAGE. Unused?
|
||||
};
|
||||
|
||||
// Item list ID for toSwapPos to indicate an item is not currently being swapped
|
||||
#define NOT_SWAPPING 0xFF
|
||||
|
||||
struct ListBuffer1 {
|
||||
struct ListMenuItem subBuffers[MAX_POCKET_ITEMS];
|
||||
};
|
||||
|
||||
struct ListBuffer2 {
|
||||
s8 name[MAX_POCKET_ITEMS][ITEM_NAME_LENGTH + 10];
|
||||
};
|
||||
|
||||
struct TempWallyBag {
|
||||
struct ItemSlot bagPocket_Items[BAG_ITEMS_COUNT];
|
||||
struct ItemSlot bagPocket_PokeBalls[BAG_POKEBALLS_COUNT];
|
||||
u16 cursorPosition[POCKETS_COUNT];
|
||||
u16 scrollPosition[POCKETS_COUNT];
|
||||
u16 unused;
|
||||
u16 pocket;
|
||||
};
|
||||
|
||||
static void CB2_Bag(void);
|
||||
static bool8 SetupBagMenu(void);
|
||||
static void BagMenu_InitBGs(void);
|
||||
static bool8 LoadBagMenu_Graphics(void);
|
||||
static void LoadBagMenuTextWindows(void);
|
||||
static void AllocateBagItemListBuffers(void);
|
||||
static void LoadBagItemListBuffers(u8);
|
||||
static void PrintPocketNames(const u8*, const u8*);
|
||||
static void CopyPocketNameToWindow(u32);
|
||||
static void DrawPocketIndicatorSquare(u8, bool8);
|
||||
static void CreatePocketScrollArrowPair(void);
|
||||
static void CreatePocketSwitchArrowPair(void);
|
||||
static void DestroyPocketSwitchArrowPair(void);
|
||||
static void PrepareTMHMMoveWindow(void);
|
||||
static bool8 IsWallysBag(void);
|
||||
static void Task_WallyTutorialBagMenu(u8);
|
||||
static void Task_BagMenu_HandleInput(u8);
|
||||
static void GetItemName(s8*, u16);
|
||||
static void PrintItemDescription(int);
|
||||
static void BagMenu_PrintCursorAtPos(u8, u8);
|
||||
static void BagMenu_Print(u8, u8, const u8*, u8, u8, u8, u8, u8, u8);
|
||||
static void Task_CloseBagMenu(u8);
|
||||
static u8 AddItemMessageWindow(u8);
|
||||
static void RemoveItemMessageWindow(u8);
|
||||
static void ReturnToItemList(u8);
|
||||
static void PrintItemQuantity(u8, s16);
|
||||
|
||||
static u8 BagMenu_AddWindow(u8);
|
||||
static u8 GetSwitchBagPocketDirection(void);
|
||||
static void SwitchBagPocket(u8, s16, bool16);
|
||||
static bool8 CanSwapItems(void);
|
||||
static void StartItemSwap(u8 taskId);
|
||||
static void Task_SwitchBagPocket(u8);
|
||||
static void Task_HandleSwappingItemsInput(u8);
|
||||
static void DoItemSwap(u8);
|
||||
static void CancelItemSwap(u8);
|
||||
static void PrintTMHMMoveData(u16);
|
||||
static void PrintContextMenuItems(u8);
|
||||
static void PrintContextMenuItemGrid(u8, u8, u8);
|
||||
static void Task_ItemContext_SingleRow(u8);
|
||||
static void Task_ItemContext_MultipleRows(u8);
|
||||
static bool8 IsValidContextMenuPos(s8);
|
||||
static void BagMenu_RemoveWindow(u8);
|
||||
static void PrintThereIsNoPokemon(u8);
|
||||
static void Task_ChooseHowManyToToss(u8);
|
||||
static void AskTossItems(u8);
|
||||
static void Task_RemoveItemFromBag(u8);
|
||||
static void ItemMenu_Cancel(u8);
|
||||
static void HandleErrorMessage(u8);
|
||||
static void PrintItemCantBeHeld(u8);
|
||||
static void DisplayCurrentMoneyWindow(void);
|
||||
static void DisplaySellItemPriceAndConfirm(u8);
|
||||
static void InitSellHowManyInput(u8);
|
||||
static void AskSellItems(u8);
|
||||
static void RemoveMoneyWindow(void);
|
||||
static void Task_ChooseHowManyToSell(u8);
|
||||
static void SellItem(u8);
|
||||
static void WaitAfterItemSell(u8);
|
||||
static void TryDepositItem(u8);
|
||||
static void Task_ChooseHowManyToDeposit(u8 taskId);
|
||||
|
||||
// .rodata
|
||||
static void WaitDepositErrorMessage(u8);
|
||||
static void CB2_ApprenticeExitBagMenu(void);
|
||||
static void CB2_FavorLadyExitBagMenu(void);
|
||||
static void CB2_QuizLadyExitBagMenu(void);
|
||||
static void UpdatePocketItemLists(void);
|
||||
static void InitPocketListPositions(void);
|
||||
static void InitPocketScrollPositions(void);
|
||||
static u8 CreateBagInputHandlerTask(u8);
|
||||
static void DrawItemListBgRow(u8);
|
||||
static void BagMenu_MoveCursorCallback(s32, bool8, struct ListMenu*);
|
||||
static void BagMenu_ItemPrintCallback(u8, u32, u8);
|
||||
static void ItemMenu_UseOutOfBattle(u8);
|
||||
static void ItemMenu_Toss(u8);
|
||||
static void ItemMenu_Register(u8);
|
||||
static void ItemMenu_Give(u8);
|
||||
static void ItemMenu_Cancel(u8);
|
||||
static void ItemMenu_UseInBattle(u8);
|
||||
static void ItemMenu_CheckTag(u8);
|
||||
static void ItemMenu_Show(u8);
|
||||
static void ItemMenu_GiveFavorLady(u8);
|
||||
static void ItemMenu_ConfirmQuizLady(u8);
|
||||
static void Task_ItemContext_Normal(u8);
|
||||
static void Task_ItemContext_GiveToParty(u8);
|
||||
static void Task_ItemContext_Sell(u8);
|
||||
static void Task_ItemContext_Deposit(u8);
|
||||
static void Task_ItemContext_GiveToPC(u8);
|
||||
static void ConfirmToss(u8);
|
||||
static void CancelToss(u8);
|
||||
static void ConfirmSell(u8);
|
||||
static void CancelSell(u8);
|
||||
|
||||
//bag sort
|
||||
static void Task_LoadBagSortOptions(u8 taskId);
|
||||
static void ItemMenu_SortByName(u8 taskId);
|
||||
static void ItemMenu_SortByType(u8 taskId);
|
||||
static void ItemMenu_SortByAmount(u8 taskId);
|
||||
static void SortBagItems(u8 taskId);
|
||||
static void Task_SortFinish(u8 taskId);
|
||||
static void SortItemsInBag(u8 pocket, u8 type);
|
||||
static void MergeSort(struct ItemSlot* array, u32 low, u32 high, s8 (*comparator)(struct ItemSlot*, struct ItemSlot*));
|
||||
static void Merge(struct ItemSlot* array, u32 low, u32 mid, u32 high, s8 (*comparator)(struct ItemSlot*, struct ItemSlot*));
|
||||
static s8 CompareItemsAlphabetically(struct ItemSlot* itemSlot1, struct ItemSlot* itemSlot2);
|
||||
static s8 CompareItemsByMost(struct ItemSlot* itemSlot1, struct ItemSlot* itemSlot2);
|
||||
static s8 CompareItemsByType(struct ItemSlot* itemSlot1, struct ItemSlot* itemSlot2);
|
||||
|
||||
static const struct BgTemplate sBgTemplates_ItemMenu[] =
|
||||
{
|
||||
{
|
||||
.bg = 0,
|
||||
.charBaseIndex = 0,
|
||||
.mapBaseIndex = 31,
|
||||
.screenSize = 0,
|
||||
.paletteMode = 0,
|
||||
.priority = 1,
|
||||
.baseTile = 0,
|
||||
},
|
||||
{
|
||||
.bg = 1,
|
||||
.charBaseIndex = 0,
|
||||
.mapBaseIndex = 30,
|
||||
.screenSize = 0,
|
||||
.paletteMode = 0,
|
||||
.priority = 0,
|
||||
.baseTile = 0,
|
||||
},
|
||||
{
|
||||
.bg = 2,
|
||||
.charBaseIndex = 3,
|
||||
.mapBaseIndex = 29,
|
||||
.screenSize = 0,
|
||||
.paletteMode = 0,
|
||||
.priority = 2,
|
||||
.baseTile = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sItemListMenu =
|
||||
{
|
||||
.items = NULL,
|
||||
.moveCursorFunc = BagMenu_MoveCursorCallback,
|
||||
.itemPrintFunc = BagMenu_ItemPrintCallback,
|
||||
.totalItems = 0,
|
||||
.maxShowed = 0,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 1,
|
||||
.cursorPal = 1,
|
||||
.fillValue = 0,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 0,
|
||||
.itemVerticalPadding = 0,
|
||||
.scrollMultiple = 0,
|
||||
.fontId = FONT_NARROW,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const u8 sMenuText_ByName[] = _("Name");
|
||||
static const u8 sMenuText_ByType[] = _("Type");
|
||||
static const u8 sMenuText_ByAmount[] = _("Amount");
|
||||
static const u8 sMenuText_ByNumber[] = _("Number");
|
||||
static const u8 sText_NothingToSort[] = _("There's nothing to sort!");
|
||||
static const struct MenuAction sItemMenuActions[] = {
|
||||
[ACTION_USE] = {gMenuText_Use, ItemMenu_UseOutOfBattle},
|
||||
[ACTION_TOSS] = {gMenuText_Toss, ItemMenu_Toss},
|
||||
[ACTION_REGISTER] = {gMenuText_Register, ItemMenu_Register},
|
||||
[ACTION_GIVE] = {gMenuText_Give, ItemMenu_Give},
|
||||
[ACTION_CANCEL] = {gText_Cancel2, ItemMenu_Cancel},
|
||||
[ACTION_BATTLE_USE] = {gMenuText_Use, ItemMenu_UseInBattle},
|
||||
[ACTION_CHECK] = {gMenuText_Check, ItemMenu_UseOutOfBattle},
|
||||
[ACTION_WALK] = {gMenuText_Walk, ItemMenu_UseOutOfBattle},
|
||||
[ACTION_DESELECT] = {gMenuText_Deselect, ItemMenu_Register},
|
||||
[ACTION_CHECK_TAG] = {gMenuText_CheckTag, ItemMenu_CheckTag},
|
||||
[ACTION_CONFIRM] = {gMenuText_Confirm, Task_FadeAndCloseBagMenu},
|
||||
[ACTION_SHOW] = {gMenuText_Show, ItemMenu_Show},
|
||||
[ACTION_GIVE_FAVOR_LADY] = {gMenuText_Give2, ItemMenu_GiveFavorLady},
|
||||
[ACTION_CONFIRM_QUIZ_LADY] = {gMenuText_Confirm, ItemMenu_ConfirmQuizLady},
|
||||
[ACTION_BY_NAME] = {sMenuText_ByName, ItemMenu_SortByName},
|
||||
[ACTION_BY_TYPE] = {sMenuText_ByType, ItemMenu_SortByType},
|
||||
[ACTION_BY_AMOUNT] = {sMenuText_ByAmount, ItemMenu_SortByAmount},
|
||||
[ACTION_DUMMY] = {gText_EmptyString2, NULL}
|
||||
};
|
||||
|
||||
// these are all 2D arrays with a width of 2 but are represented as 1D arrays
|
||||
// ACTION_DUMMY is used to represent blank spaces
|
||||
static const u8 sContextMenuItems_ItemsPocket[] = {
|
||||
ACTION_USE, ACTION_GIVE,
|
||||
ACTION_TOSS, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_KeyItemsPocket[] = {
|
||||
ACTION_USE, ACTION_REGISTER,
|
||||
ACTION_DUMMY, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_BallsPocket[] = {
|
||||
ACTION_GIVE, ACTION_DUMMY,
|
||||
ACTION_TOSS, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_TmHmPocket[] = {
|
||||
ACTION_USE, ACTION_GIVE,
|
||||
ACTION_DUMMY, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_BerriesPocket[] = {
|
||||
ACTION_CHECK_TAG, ACTION_DUMMY,
|
||||
ACTION_USE, ACTION_GIVE,
|
||||
ACTION_TOSS, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_BattleUse[] = {
|
||||
ACTION_BATTLE_USE, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_Give[] = {
|
||||
ACTION_GIVE, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_Cancel[] = {
|
||||
ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_BerryBlenderCrush[] = {
|
||||
ACTION_CONFIRM, ACTION_CHECK_TAG,
|
||||
ACTION_DUMMY, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_Apprentice[] = {
|
||||
ACTION_SHOW, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_FavorLady[] = {
|
||||
ACTION_GIVE_FAVOR_LADY, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const u8 sContextMenuItems_QuizLady[] = {
|
||||
ACTION_CONFIRM_QUIZ_LADY, ACTION_CANCEL
|
||||
};
|
||||
|
||||
static const TaskFunc sContextMenuFuncs[] = {
|
||||
[ITEMMENULOCATION_FIELD] = Task_ItemContext_Normal,
|
||||
[ITEMMENULOCATION_BATTLE] = Task_ItemContext_Normal,
|
||||
[ITEMMENULOCATION_PARTY] = Task_ItemContext_GiveToParty,
|
||||
[ITEMMENULOCATION_SHOP] = Task_ItemContext_Sell,
|
||||
[ITEMMENULOCATION_BERRY_TREE] = Task_FadeAndCloseBagMenu,
|
||||
[ITEMMENULOCATION_BERRY_BLENDER_CRUSH] = Task_ItemContext_Normal,
|
||||
[ITEMMENULOCATION_ITEMPC] = Task_ItemContext_Deposit,
|
||||
[ITEMMENULOCATION_FAVOR_LADY] = Task_ItemContext_Normal,
|
||||
[ITEMMENULOCATION_QUIZ_LADY] = Task_ItemContext_Normal,
|
||||
[ITEMMENULOCATION_APPRENTICE] = Task_ItemContext_Normal,
|
||||
[ITEMMENULOCATION_WALLY] = NULL,
|
||||
[ITEMMENULOCATION_PCBOX] = Task_ItemContext_GiveToPC
|
||||
};
|
||||
|
||||
static const struct YesNoFuncTable sYesNoTossFunctions = {ConfirmToss, CancelToss};
|
||||
|
||||
static const struct YesNoFuncTable sYesNoSellItemFunctions = {ConfirmSell, CancelSell};
|
||||
|
||||
static const struct ScrollArrowsTemplate sBagScrollArrowsTemplate = {
|
||||
.firstArrowType = SCROLL_ARROW_LEFT,
|
||||
.firstX = 28,
|
||||
.firstY = 16,
|
||||
.secondArrowType = SCROLL_ARROW_RIGHT,
|
||||
.secondX = 100,
|
||||
.secondY = 16,
|
||||
.fullyUpThreshold = -1,
|
||||
.fullyDownThreshold = -1,
|
||||
.tileTag = TAG_BAG_SCROLL_ARROW,
|
||||
.palTag = TAG_BAG_SCROLL_ARROW,
|
||||
.palNum = 0,
|
||||
};
|
||||
|
||||
static const u8 sRegisteredSelect_Gfx[] = INCBIN_U8("graphics/interface/select_button.4bpp");
|
||||
|
||||
enum {
|
||||
COLORID_NORMAL,
|
||||
COLORID_POCKET_NAME,
|
||||
COLORID_GRAY_CURSOR,
|
||||
COLORID_UNUSED,
|
||||
COLORID_TMHM_INFO,
|
||||
COLORID_NONE = 0xFF
|
||||
};
|
||||
static const u8 sFontColorTable[][3] = {
|
||||
// bgColor, textColor, shadowColor
|
||||
[COLORID_NORMAL] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GRAY},
|
||||
[COLORID_POCKET_NAME] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_RED},
|
||||
[COLORID_GRAY_CURSOR] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_LIGHT_GRAY, TEXT_COLOR_GREEN},
|
||||
[COLORID_UNUSED] = {TEXT_COLOR_DARK_GRAY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GRAY},
|
||||
[COLORID_TMHM_INFO] = {TEXT_COLOR_TRANSPARENT, TEXT_DYNAMIC_COLOR_5, TEXT_DYNAMIC_COLOR_1}
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sDefaultBagWindows[] =
|
||||
{
|
||||
[WIN_ITEM_LIST] = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 14,
|
||||
.tilemapTop = 2,
|
||||
.width = 15,
|
||||
.height = 16,
|
||||
.paletteNum = 1,
|
||||
.baseBlock = 0x27,
|
||||
},
|
||||
[WIN_DESCRIPTION] = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 0,
|
||||
.tilemapTop = 13,
|
||||
.width = 14,
|
||||
.height = 6,
|
||||
.paletteNum = 1,
|
||||
.baseBlock = 0x117,
|
||||
},
|
||||
[WIN_POCKET_NAME] = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 4,
|
||||
.tilemapTop = 1,
|
||||
.width = 8,
|
||||
.height = 2,
|
||||
.paletteNum = 1,
|
||||
.baseBlock = 0x1A1,
|
||||
},
|
||||
[WIN_TMHM_INFO_ICONS] = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 13,
|
||||
.width = 5,
|
||||
.height = 6,
|
||||
.paletteNum = 12,
|
||||
.baseBlock = 0x16B,
|
||||
},
|
||||
[WIN_TMHM_INFO] = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 7,
|
||||
.tilemapTop = 13,
|
||||
.width = 4,
|
||||
.height = 6,
|
||||
.paletteNum = 12,
|
||||
.baseBlock = 0x189,
|
||||
},
|
||||
[WIN_MESSAGE] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 2,
|
||||
.tilemapTop = 15,
|
||||
.width = 27,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x1B1,
|
||||
},
|
||||
DUMMY_WIN_TEMPLATE,
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sContextMenuWindowTemplates[] =
|
||||
{
|
||||
[ITEMWIN_1x1] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 22,
|
||||
.tilemapTop = 17,
|
||||
.width = 7,
|
||||
.height = 2,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_1x2] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 22,
|
||||
.tilemapTop = 15,
|
||||
.width = 7,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_2x2] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 15,
|
||||
.tilemapTop = 15,
|
||||
.width = 14,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_2x3] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 15,
|
||||
.tilemapTop = 13,
|
||||
.width = 14,
|
||||
.height = 6,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_MESSAGE] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 2,
|
||||
.tilemapTop = 15,
|
||||
.width = 27,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x1B1,
|
||||
},
|
||||
[ITEMWIN_YESNO_LOW] = { // Yes/No tucked in corner, for toss confirm
|
||||
.bg = 1,
|
||||
.tilemapLeft = 24,
|
||||
.tilemapTop = 15,
|
||||
.width = 5,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_YESNO_HIGH] = { // Yes/No higher up, positioned above a lower message box
|
||||
.bg = 1,
|
||||
.tilemapLeft = 21,
|
||||
.tilemapTop = 9,
|
||||
.width = 5,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_QUANTITY] = { // Used for quantity of items to Toss/Deposit
|
||||
.bg = 1,
|
||||
.tilemapLeft = 24,
|
||||
.tilemapTop = 17,
|
||||
.width = 5,
|
||||
.height = 2,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x21D,
|
||||
},
|
||||
[ITEMWIN_QUANTITY_WIDE] = { // Used for quantity and price of items to Sell
|
||||
.bg = 1,
|
||||
.tilemapLeft = 18,
|
||||
.tilemapTop = 11,
|
||||
.width = 10,
|
||||
.height = 2,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x245,
|
||||
},
|
||||
[ITEMWIN_MONEY] = {
|
||||
.bg = 1,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 1,
|
||||
.width = 10,
|
||||
.height = 2,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x231,
|
||||
},
|
||||
};
|
||||
|
||||
EWRAM_DATA struct BagMenu *gBagMenu = 0;
|
||||
EWRAM_DATA struct BagPosition gBagPosition = {0};
|
||||
static EWRAM_DATA struct ListBuffer1 *sListBuffer1 = 0;
|
||||
static EWRAM_DATA struct ListBuffer2 *sListBuffer2 = 0;
|
||||
EWRAM_DATA u16 gSpecialVar_ItemId = 0;
|
||||
static EWRAM_DATA struct TempWallyBag *sTempWallyBag = 0;
|
||||
|
||||
void ResetBagScrollPositions(void)
|
||||
{
|
||||
gBagPosition.pocket = ITEMS_POCKET;
|
||||
memset(gBagPosition.cursorPosition, 0, sizeof(gBagPosition.cursorPosition));
|
||||
memset(gBagPosition.scrollPosition, 0, sizeof(gBagPosition.scrollPosition));
|
||||
}
|
||||
|
||||
void CB2_BagMenuFromStartMenu(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_FIELD, POCKETS_COUNT, CB2_ReturnToFieldWithOpenMenu);
|
||||
}
|
||||
|
||||
void CB2_BagMenuFromBattle(void)
|
||||
{
|
||||
if (!InBattlePyramid())
|
||||
GoToBagMenu(ITEMMENULOCATION_BATTLE, POCKETS_COUNT, CB2_SetUpReshowBattleScreenAfterMenu2);
|
||||
else
|
||||
GoToBattlePyramidBagMenu(PYRAMIDBAG_LOC_BATTLE, CB2_SetUpReshowBattleScreenAfterMenu2);
|
||||
}
|
||||
|
||||
// Choosing berry to plant
|
||||
void CB2_ChooseBerry(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_BERRY_TREE, BERRIES_POCKET, CB2_ReturnToFieldContinueScript);
|
||||
}
|
||||
|
||||
// Choosing berry for Berry Blender or Berry Crush
|
||||
void ChooseBerryForMachine(void (*exitCallback)(void))
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_BERRY_BLENDER_CRUSH, BERRIES_POCKET, exitCallback);
|
||||
}
|
||||
|
||||
void CB2_GoToSellMenu(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_SHOP, POCKETS_COUNT, CB2_ExitSellMenu);
|
||||
}
|
||||
|
||||
void CB2_GoToItemDepositMenu(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_ITEMPC, POCKETS_COUNT, CB2_PlayerPCExitBagMenu);
|
||||
}
|
||||
|
||||
void ApprenticeOpenBagMenu(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_APPRENTICE, POCKETS_COUNT, CB2_ApprenticeExitBagMenu);
|
||||
gSpecialVar_0x8005 = ITEM_NONE;
|
||||
gSpecialVar_Result = FALSE;
|
||||
}
|
||||
|
||||
void FavorLadyOpenBagMenu(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_FAVOR_LADY, POCKETS_COUNT, CB2_FavorLadyExitBagMenu);
|
||||
gSpecialVar_Result = FALSE;
|
||||
}
|
||||
|
||||
void QuizLadyOpenBagMenu(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_QUIZ_LADY, POCKETS_COUNT, CB2_QuizLadyExitBagMenu);
|
||||
gSpecialVar_Result = FALSE;
|
||||
}
|
||||
|
||||
void GoToBagMenu(u8 location, u8 pocket, void ( *exitCallback)())
|
||||
{
|
||||
gBagMenu = AllocZeroed(sizeof(*gBagMenu));
|
||||
if (gBagMenu == NULL)
|
||||
{
|
||||
// Alloc failed, exit
|
||||
SetMainCallback2(exitCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (location != ITEMMENULOCATION_LAST)
|
||||
gBagPosition.location = location;
|
||||
if (exitCallback)
|
||||
gBagPosition.exitCallback = exitCallback;
|
||||
if (pocket < POCKETS_COUNT)
|
||||
gBagPosition.pocket = pocket;
|
||||
if (gBagPosition.location == ITEMMENULOCATION_BERRY_TREE ||
|
||||
gBagPosition.location == ITEMMENULOCATION_BERRY_BLENDER_CRUSH)
|
||||
gBagMenu->pocketSwitchDisabled = TRUE;
|
||||
gBagMenu->newScreenCallback = NULL;
|
||||
gBagMenu->toSwapPos = NOT_SWAPPING;
|
||||
gBagMenu->pocketScrollArrowsTask = TASK_NONE;
|
||||
gBagMenu->pocketSwitchArrowsTask = TASK_NONE;
|
||||
memset(gBagMenu->spriteIds, SPRITE_NONE, sizeof(gBagMenu->spriteIds));
|
||||
memset(gBagMenu->windowIds, WINDOW_NONE, sizeof(gBagMenu->windowIds));
|
||||
SetMainCallback2(CB2_Bag);
|
||||
}
|
||||
}
|
||||
|
||||
void CB2_BagMenuRun(void)
|
||||
{
|
||||
RunTasks();
|
||||
AnimateSprites();
|
||||
BuildOamBuffer();
|
||||
DoScheduledBgTilemapCopiesToVram();
|
||||
UpdatePaletteFade();
|
||||
}
|
||||
|
||||
void VBlankCB_BagMenuRun(void)
|
||||
{
|
||||
LoadOam();
|
||||
ProcessSpriteCopyRequests();
|
||||
TransferPlttBuffer();
|
||||
}
|
||||
|
||||
#define tListTaskId data[0]
|
||||
#define tListPosition data[1]
|
||||
#define tQuantity data[2]
|
||||
#define tNeverRead data[3]
|
||||
#define tItemCount data[8]
|
||||
#define tMsgWindowId data[10]
|
||||
#define tPocketSwitchDir data[11]
|
||||
#define tPocketSwitchTimer data[12]
|
||||
#define tPocketSwitchState data[13]
|
||||
|
||||
static void CB2_Bag(void)
|
||||
{
|
||||
while(MenuHelpers_ShouldWaitForLinkRecv() != TRUE && SetupBagMenu() != TRUE && MenuHelpers_IsLinkActive() != TRUE)
|
||||
{};
|
||||
}
|
||||
|
||||
static bool8 SetupBagMenu(void)
|
||||
{
|
||||
u8 taskId;
|
||||
|
||||
switch (gMain.state)
|
||||
{
|
||||
case 0:
|
||||
SetVBlankHBlankCallbacksToNull();
|
||||
ClearScheduledBgCopiesToVram();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 1:
|
||||
ScanlineEffect_Stop();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 2:
|
||||
FreeAllSpritePalettes();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 3:
|
||||
ResetPaletteFade();
|
||||
gPaletteFade.bufferTransferDisabled = TRUE;
|
||||
gMain.state++;
|
||||
break;
|
||||
case 4:
|
||||
ResetSpriteData();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 5:
|
||||
gMain.state++;
|
||||
break;
|
||||
case 6:
|
||||
if (!MenuHelpers_IsLinkActive())
|
||||
ResetTasks();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 7:
|
||||
BagMenu_InitBGs();
|
||||
gBagMenu->graphicsLoadState = 0;
|
||||
gMain.state++;
|
||||
break;
|
||||
case 8:
|
||||
if (!LoadBagMenu_Graphics())
|
||||
break;
|
||||
gMain.state++;
|
||||
break;
|
||||
case 9:
|
||||
LoadBagMenuTextWindows();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 10:
|
||||
UpdatePocketItemLists();
|
||||
InitPocketListPositions();
|
||||
InitPocketScrollPositions();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 11:
|
||||
AllocateBagItemListBuffers();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 12:
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
gMain.state++;
|
||||
break;
|
||||
case 13:
|
||||
PrintPocketNames(gPocketNamesStringsTable[gBagPosition.pocket], 0);
|
||||
CopyPocketNameToWindow(0);
|
||||
DrawPocketIndicatorSquare(gBagPosition.pocket, TRUE);
|
||||
gMain.state++;
|
||||
break;
|
||||
case 14:
|
||||
taskId = CreateBagInputHandlerTask(gBagPosition.location);
|
||||
gTasks[taskId].tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, gBagPosition.scrollPosition[gBagPosition.pocket], gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
gTasks[taskId].tNeverRead = 0;
|
||||
gTasks[taskId].tItemCount = 0;
|
||||
gMain.state++;
|
||||
break;
|
||||
case 15:
|
||||
AddBagVisualSprite(gBagPosition.pocket);
|
||||
gMain.state++;
|
||||
break;
|
||||
case 16:
|
||||
CreateItemMenuSwapLine();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 17:
|
||||
CreatePocketScrollArrowPair();
|
||||
CreatePocketSwitchArrowPair();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 18:
|
||||
PrepareTMHMMoveWindow();
|
||||
gMain.state++;
|
||||
break;
|
||||
case 19:
|
||||
BlendPalettes(PALETTES_ALL, 16, 0);
|
||||
gMain.state++;
|
||||
break;
|
||||
case 20:
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
|
||||
gPaletteFade.bufferTransferDisabled = FALSE;
|
||||
gMain.state++;
|
||||
break;
|
||||
default:
|
||||
SetVBlankCallback(VBlankCB_BagMenuRun);
|
||||
SetMainCallback2(CB2_BagMenuRun);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void BagMenu_InitBGs(void)
|
||||
{
|
||||
ResetVramOamAndBgCntRegs();
|
||||
memset(gBagMenu->tilemapBuffer, 0, sizeof(gBagMenu->tilemapBuffer));
|
||||
ResetBgsAndClearDma3BusyFlags(0);
|
||||
InitBgsFromTemplates(0, sBgTemplates_ItemMenu, ARRAY_COUNT(sBgTemplates_ItemMenu));
|
||||
SetBgTilemapBuffer(2, gBagMenu->tilemapBuffer);
|
||||
ResetAllBgsCoordinates();
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
|
||||
ShowBg(0);
|
||||
ShowBg(1);
|
||||
ShowBg(2);
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
||||
}
|
||||
|
||||
static bool8 LoadBagMenu_Graphics(void)
|
||||
{
|
||||
switch (gBagMenu->graphicsLoadState)
|
||||
{
|
||||
case 0:
|
||||
ResetTempTileDataBuffers();
|
||||
DecompressAndCopyTileDataToVram(2, gBagScreen_Gfx, 0, 0, 0);
|
||||
gBagMenu->graphicsLoadState++;
|
||||
break;
|
||||
case 1:
|
||||
if (FreeTempTileDataBuffersIfPossible() != TRUE)
|
||||
{
|
||||
LZDecompressWram(gBagScreen_GfxTileMap, gBagMenu->tilemapBuffer);
|
||||
gBagMenu->graphicsLoadState++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (!IsWallysBag() && gSaveBlock2Ptr->playerGender != MALE)
|
||||
LoadCompressedPalette(gBagScreenFemale_Pal, 0, 0x40);
|
||||
else
|
||||
LoadCompressedPalette(gBagScreenMale_Pal, 0, 0x40);
|
||||
gBagMenu->graphicsLoadState++;
|
||||
break;
|
||||
case 3:
|
||||
if (IsWallysBag() == TRUE || gSaveBlock2Ptr->playerGender == MALE)
|
||||
LoadCompressedSpriteSheet(&gBagMaleSpriteSheet);
|
||||
else
|
||||
LoadCompressedSpriteSheet(&gBagFemaleSpriteSheet);
|
||||
gBagMenu->graphicsLoadState++;
|
||||
break;
|
||||
case 4:
|
||||
LoadCompressedSpritePalette(&gBagPaletteTable);
|
||||
gBagMenu->graphicsLoadState++;
|
||||
break;
|
||||
default:
|
||||
LoadListMenuSwapLineGfx();
|
||||
gBagMenu->graphicsLoadState = 0;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u8 CreateBagInputHandlerTask(u8 location)
|
||||
{
|
||||
u8 taskId;
|
||||
if (location == ITEMMENULOCATION_WALLY)
|
||||
taskId = CreateTask(Task_WallyTutorialBagMenu, 0);
|
||||
else
|
||||
taskId = CreateTask(Task_BagMenu_HandleInput, 0);
|
||||
return taskId;
|
||||
}
|
||||
|
||||
static void AllocateBagItemListBuffers(void)
|
||||
{
|
||||
sListBuffer1 = Alloc(sizeof(*sListBuffer1));
|
||||
sListBuffer2 = Alloc(sizeof(*sListBuffer2));
|
||||
}
|
||||
|
||||
static void LoadBagItemListBuffers(u8 pocketId)
|
||||
{
|
||||
u16 i;
|
||||
struct BagPocket *pocket = &gBagPockets[pocketId];
|
||||
struct ListMenuItem *subBuffer;
|
||||
|
||||
if (!gBagMenu->hideCloseBagText)
|
||||
{
|
||||
for (i = 0; i < gBagMenu->numItemStacks[pocketId] - 1; i++)
|
||||
{
|
||||
GetItemName(sListBuffer2->name[i], pocket->itemSlots[i].itemId);
|
||||
subBuffer = sListBuffer1->subBuffers;
|
||||
subBuffer[i].name = sListBuffer2->name[i];
|
||||
subBuffer[i].id = i;
|
||||
}
|
||||
StringCopy(sListBuffer2->name[i], gText_CloseBag);
|
||||
subBuffer = sListBuffer1->subBuffers;
|
||||
subBuffer[i].name = sListBuffer2->name[i];
|
||||
subBuffer[i].id = LIST_CANCEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < gBagMenu->numItemStacks[pocketId]; i++)
|
||||
{
|
||||
GetItemName(sListBuffer2->name[i], pocket->itemSlots[i].itemId);
|
||||
subBuffer = sListBuffer1->subBuffers;
|
||||
subBuffer[i].name = sListBuffer2->name[i];
|
||||
subBuffer[i].id = i;
|
||||
}
|
||||
}
|
||||
gMultiuseListMenuTemplate = sItemListMenu;
|
||||
gMultiuseListMenuTemplate.totalItems = gBagMenu->numItemStacks[pocketId];
|
||||
gMultiuseListMenuTemplate.items = sListBuffer1->subBuffers;
|
||||
gMultiuseListMenuTemplate.maxShowed = gBagMenu->numShownItems[pocketId];
|
||||
}
|
||||
|
||||
static void GetItemName(s8 *dest, u16 itemId)
|
||||
{
|
||||
switch (gBagPosition.pocket)
|
||||
{
|
||||
case TMHM_POCKET:
|
||||
StringCopy(gStringVar2, gMoveNames[ItemIdToBattleMoveId(itemId)]);
|
||||
if (itemId >= ITEM_HM01)
|
||||
{
|
||||
// Get HM number
|
||||
ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_HM01 + 1, STR_CONV_MODE_LEADING_ZEROS, 1);
|
||||
StringExpandPlaceholders(dest, gText_NumberItem_HM);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get TM number
|
||||
ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_TM01 + 1, STR_CONV_MODE_LEADING_ZEROS, 2);
|
||||
StringExpandPlaceholders(dest, gText_NumberItem_TMBerry);
|
||||
}
|
||||
break;
|
||||
case BERRIES_POCKET:
|
||||
ConvertIntToDecimalStringN(gStringVar1, itemId - FIRST_BERRY_INDEX + 1, STR_CONV_MODE_LEADING_ZEROS, 2);
|
||||
CopyItemName(itemId, gStringVar2);
|
||||
StringExpandPlaceholders(dest, gText_NumberItem_TMBerry);
|
||||
break;
|
||||
default:
|
||||
CopyItemName(itemId, dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void BagMenu_MoveCursorCallback(s32 itemIndex, bool8 onInit, struct ListMenu *list)
|
||||
{
|
||||
if (onInit != TRUE)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ShakeBagSprite();
|
||||
}
|
||||
if (gBagMenu->toSwapPos == NOT_SWAPPING)
|
||||
{
|
||||
RemoveBagItemIconSprite(gBagMenu->itemIconSlot ^ 1);
|
||||
if (itemIndex != LIST_CANCEL)
|
||||
AddBagItemIconSprite(BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, itemIndex), gBagMenu->itemIconSlot);
|
||||
else
|
||||
AddBagItemIconSprite(-1, gBagMenu->itemIconSlot);
|
||||
gBagMenu->itemIconSlot ^= 1;
|
||||
if (!gBagMenu->inhibitItemDescriptionPrint)
|
||||
PrintItemDescription(itemIndex);
|
||||
}
|
||||
}
|
||||
|
||||
static void BagMenu_ItemPrintCallback(u8 windowId, u32 itemIndex, u8 y)
|
||||
{
|
||||
u16 itemId;
|
||||
u16 itemQuantity;
|
||||
int offset;
|
||||
|
||||
if (itemIndex != LIST_CANCEL)
|
||||
{
|
||||
if (gBagMenu->toSwapPos != NOT_SWAPPING)
|
||||
{
|
||||
// Swapping items, draw cursor at original item's location
|
||||
if (gBagMenu->toSwapPos == (u8)itemIndex)
|
||||
BagMenu_PrintCursorAtPos(y, COLORID_GRAY_CURSOR);
|
||||
else
|
||||
BagMenu_PrintCursorAtPos(y, COLORID_NONE);
|
||||
}
|
||||
|
||||
itemId = BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, itemIndex);
|
||||
itemQuantity = BagGetQuantityByPocketPosition(gBagPosition.pocket + 1, itemIndex);
|
||||
|
||||
// Draw HM icon
|
||||
if (itemId >= ITEM_HM01 && itemId <= ITEM_HM08)
|
||||
BlitBitmapToWindow(windowId, gBagMenuHMIcon_Gfx, 8, y - 1, 16, 16);
|
||||
|
||||
if (gBagPosition.pocket == BERRIES_POCKET)
|
||||
{
|
||||
// Print berry quantity
|
||||
ConvertIntToDecimalStringN(gStringVar1, itemQuantity, STR_CONV_MODE_RIGHT_ALIGN, BERRY_CAPACITY_DIGITS);
|
||||
StringExpandPlaceholders(gStringVar4, gText_xVar1);
|
||||
offset = GetStringRightAlignXOffset(FONT_NARROW, gStringVar4, 119);
|
||||
BagMenu_Print(windowId, FONT_NARROW, gStringVar4, offset, y, 0, 0, TEXT_SKIP_DRAW, COLORID_NORMAL);
|
||||
}
|
||||
else if (gBagPosition.pocket != KEYITEMS_POCKET && ItemId_GetImportance(itemId) == FALSE)
|
||||
{
|
||||
// Print item quantity
|
||||
ConvertIntToDecimalStringN(gStringVar1, itemQuantity, STR_CONV_MODE_RIGHT_ALIGN, BAG_ITEM_CAPACITY_DIGITS);
|
||||
StringExpandPlaceholders(gStringVar4, gText_xVar1);
|
||||
offset = GetStringRightAlignXOffset(FONT_NARROW, gStringVar4, 119);
|
||||
BagMenu_Print(windowId, FONT_NARROW, gStringVar4, offset, y, 0, 0, TEXT_SKIP_DRAW, COLORID_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print registered icon
|
||||
if (gSaveBlock1Ptr->registeredItem && gSaveBlock1Ptr->registeredItem == itemId)
|
||||
BlitBitmapToWindow(windowId, sRegisteredSelect_Gfx, 96, y - 1, 24, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintItemDescription(int itemIndex)
|
||||
{
|
||||
const u8 *str;
|
||||
if (itemIndex != LIST_CANCEL)
|
||||
{
|
||||
str = ItemId_GetDescription(BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, itemIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print 'Cancel' description
|
||||
StringCopy(gStringVar1, gBagMenu_ReturnToStrings[gBagPosition.location]);
|
||||
StringExpandPlaceholders(gStringVar4, gText_ReturnToVar1);
|
||||
str = gStringVar4;
|
||||
}
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, str, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
}
|
||||
|
||||
static void BagMenu_PrintCursor(u8 listTaskId, u8 colorIndex)
|
||||
{
|
||||
BagMenu_PrintCursorAtPos(ListMenuGetYCoordForPrintingArrowCursor(listTaskId), colorIndex);
|
||||
}
|
||||
|
||||
static void BagMenu_PrintCursorAtPos(u8 y, u8 colorIndex)
|
||||
{
|
||||
if (colorIndex == COLORID_NONE)
|
||||
FillWindowPixelRect(WIN_ITEM_LIST, PIXEL_FILL(0), 0, y, GetMenuCursorDimensionByFont(FONT_NORMAL, 0), GetMenuCursorDimensionByFont(FONT_NORMAL, 1));
|
||||
else
|
||||
BagMenu_Print(WIN_ITEM_LIST, FONT_NORMAL, gText_SelectorArrow2, 0, y, 0, 0, 0, colorIndex);
|
||||
|
||||
}
|
||||
|
||||
static void CreatePocketScrollArrowPair(void)
|
||||
{
|
||||
if (gBagMenu->pocketScrollArrowsTask == TASK_NONE)
|
||||
gBagMenu->pocketScrollArrowsTask = AddScrollIndicatorArrowPairParameterized(
|
||||
SCROLL_ARROW_UP,
|
||||
172,
|
||||
12,
|
||||
148,
|
||||
gBagMenu->numItemStacks[gBagPosition.pocket] - gBagMenu->numShownItems[gBagPosition.pocket],
|
||||
TAG_POCKET_SCROLL_ARROW,
|
||||
TAG_POCKET_SCROLL_ARROW,
|
||||
&gBagPosition.scrollPosition[gBagPosition.pocket]);
|
||||
}
|
||||
|
||||
void BagDestroyPocketScrollArrowPair(void)
|
||||
{
|
||||
if (gBagMenu->pocketScrollArrowsTask != TASK_NONE)
|
||||
{
|
||||
RemoveScrollIndicatorArrowPair(gBagMenu->pocketScrollArrowsTask);
|
||||
gBagMenu->pocketScrollArrowsTask = TASK_NONE;
|
||||
}
|
||||
DestroyPocketSwitchArrowPair();
|
||||
}
|
||||
|
||||
static void CreatePocketSwitchArrowPair(void)
|
||||
{
|
||||
if (gBagMenu->pocketSwitchDisabled != TRUE && gBagMenu->pocketSwitchArrowsTask == TASK_NONE)
|
||||
gBagMenu->pocketSwitchArrowsTask = AddScrollIndicatorArrowPair(&sBagScrollArrowsTemplate, &gBagPosition.pocketSwitchArrowPos);
|
||||
}
|
||||
|
||||
static void DestroyPocketSwitchArrowPair(void)
|
||||
{
|
||||
if (gBagMenu->pocketSwitchArrowsTask != TASK_NONE)
|
||||
{
|
||||
RemoveScrollIndicatorArrowPair(gBagMenu->pocketSwitchArrowsTask);
|
||||
gBagMenu->pocketSwitchArrowsTask = TASK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void FreeBagMenu(void)
|
||||
{
|
||||
Free(sListBuffer2);
|
||||
Free(sListBuffer1);
|
||||
FreeAllWindowBuffers();
|
||||
Free(gBagMenu);
|
||||
}
|
||||
|
||||
void Task_FadeAndCloseBagMenu(u8 taskId)
|
||||
{
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
|
||||
gTasks[taskId].func = Task_CloseBagMenu;
|
||||
}
|
||||
|
||||
static void Task_CloseBagMenu(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
DestroyListMenuTask(tListTaskId, &gBagPosition.scrollPosition[gBagPosition.pocket], &gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
|
||||
// If ready for a new screen (e.g. party menu for giving an item) go to that screen
|
||||
// Otherwise exit the bag and use callback set up when the bag was first opened
|
||||
if (gBagMenu->newScreenCallback != NULL)
|
||||
SetMainCallback2(gBagMenu->newScreenCallback);
|
||||
else
|
||||
SetMainCallback2(gBagPosition.exitCallback);
|
||||
|
||||
BagDestroyPocketScrollArrowPair();
|
||||
ResetSpriteData();
|
||||
FreeAllSpritePalettes();
|
||||
FreeBagMenu();
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePocketItemList(u8 pocketId)
|
||||
{
|
||||
u16 i;
|
||||
struct BagPocket *pocket = &gBagPockets[pocketId];
|
||||
switch (pocketId)
|
||||
{
|
||||
case TMHM_POCKET:
|
||||
case BERRIES_POCKET:
|
||||
SortBerriesOrTMHMs(pocket);
|
||||
break;
|
||||
default:
|
||||
CompactItemsInBagPocket(pocket);
|
||||
break;
|
||||
}
|
||||
|
||||
gBagMenu->numItemStacks[pocketId] = 0;
|
||||
|
||||
for (i = 0; i < pocket->capacity && pocket->itemSlots[i].itemId; i++)
|
||||
gBagMenu->numItemStacks[pocketId]++;
|
||||
|
||||
if (!gBagMenu->hideCloseBagText)
|
||||
gBagMenu->numItemStacks[pocketId]++;
|
||||
|
||||
if (gBagMenu->numItemStacks[pocketId] > MAX_ITEMS_SHOWN)
|
||||
gBagMenu->numShownItems[pocketId] = MAX_ITEMS_SHOWN;
|
||||
else
|
||||
gBagMenu->numShownItems[pocketId] = gBagMenu->numItemStacks[pocketId];
|
||||
}
|
||||
|
||||
static void UpdatePocketItemLists(void)
|
||||
{
|
||||
u8 i;
|
||||
for (i = 0; i < POCKETS_COUNT; i++)
|
||||
UpdatePocketItemList(i);
|
||||
}
|
||||
|
||||
void UpdatePocketListPosition(u8 pocketId)
|
||||
{
|
||||
SetCursorWithinListBounds(&gBagPosition.scrollPosition[pocketId], &gBagPosition.cursorPosition[pocketId], gBagMenu->numShownItems[pocketId], gBagMenu->numItemStacks[pocketId]);
|
||||
}
|
||||
|
||||
static void InitPocketListPositions(void)
|
||||
{
|
||||
u8 i;
|
||||
for (i = 0; i < POCKETS_COUNT; i++)
|
||||
UpdatePocketListPosition(i);
|
||||
}
|
||||
|
||||
static void InitPocketScrollPositions(void)
|
||||
{
|
||||
u8 i;
|
||||
for (i = 0; i < POCKETS_COUNT; i++)
|
||||
SetCursorScrollWithinListBounds(&gBagPosition.scrollPosition[i], &gBagPosition.cursorPosition[i], gBagMenu->numShownItems[i], gBagMenu->numItemStacks[i], MAX_ITEMS_SHOWN);
|
||||
}
|
||||
|
||||
u8 GetItemListPosition(u8 pocketId)
|
||||
{
|
||||
return gBagPosition.scrollPosition[pocketId] + gBagPosition.cursorPosition[pocketId];
|
||||
}
|
||||
|
||||
void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, void (*callback)(u8 taskId))
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
tMsgWindowId = AddItemMessageWindow(ITEMWIN_MESSAGE);
|
||||
FillWindowPixelBuffer(tMsgWindowId, PIXEL_FILL(1));
|
||||
DisplayMessageAndContinueTask(taskId, tMsgWindowId, 10, 13, fontId, GetPlayerTextSpeedDelay(), str, callback);
|
||||
ScheduleBgCopyTilemapToVram(1);
|
||||
}
|
||||
|
||||
void CloseItemMessage(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
RemoveItemMessageWindow(ITEMWIN_MESSAGE);
|
||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||
UpdatePocketItemList(gBagPosition.pocket);
|
||||
UpdatePocketListPosition(gBagPosition.pocket);
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
|
||||
static void AddItemQuantityWindow(u8 windowType)
|
||||
{
|
||||
PrintItemQuantity(BagMenu_AddWindow(windowType), 1);
|
||||
}
|
||||
|
||||
static void PrintItemQuantity(u8 windowId, s16 quantity)
|
||||
{
|
||||
u8 numDigits = (gBagPosition.pocket == BERRIES_POCKET) ? BERRY_CAPACITY_DIGITS : BAG_ITEM_CAPACITY_DIGITS;
|
||||
ConvertIntToDecimalStringN(gStringVar1, quantity, STR_CONV_MODE_LEADING_ZEROS, numDigits);
|
||||
StringExpandPlaceholders(gStringVar4, gText_xVar1);
|
||||
AddTextPrinterParameterized(windowId, FONT_NORMAL, gStringVar4, GetStringCenterAlignXOffset(FONT_NORMAL, gStringVar4, 0x28), 2, 0, 0);
|
||||
}
|
||||
|
||||
// Prints the quantity of items to be sold and the amount that would be earned
|
||||
static void PrintItemSoldAmount(int windowId, int numSold, int moneyEarned)
|
||||
{
|
||||
u8 numDigits = (gBagPosition.pocket == BERRIES_POCKET) ? BERRY_CAPACITY_DIGITS : BAG_ITEM_CAPACITY_DIGITS;
|
||||
ConvertIntToDecimalStringN(gStringVar1, numSold, STR_CONV_MODE_LEADING_ZEROS, numDigits);
|
||||
StringExpandPlaceholders(gStringVar4, gText_xVar1);
|
||||
AddTextPrinterParameterized(windowId, FONT_NORMAL, gStringVar4, 0, 1, TEXT_SKIP_DRAW, 0);
|
||||
PrintMoneyAmount(windowId, 38, 1, moneyEarned, 0);
|
||||
}
|
||||
|
||||
static void Task_BagMenu_HandleInput(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
s32 listPosition;
|
||||
|
||||
if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE && !gPaletteFade.active)
|
||||
{
|
||||
switch (GetSwitchBagPocketDirection())
|
||||
{
|
||||
case SWITCH_POCKET_LEFT:
|
||||
SwitchBagPocket(taskId, MENU_CURSOR_DELTA_LEFT, FALSE);
|
||||
return;
|
||||
case SWITCH_POCKET_RIGHT:
|
||||
SwitchBagPocket(taskId, MENU_CURSOR_DELTA_RIGHT, FALSE);
|
||||
return;
|
||||
default:
|
||||
if (JOY_NEW(SELECT_BUTTON))
|
||||
{
|
||||
if (CanSwapItems() == TRUE)
|
||||
{
|
||||
ListMenuGetScrollAndRow(tListTaskId, scrollPos, cursorPos);
|
||||
if ((*scrollPos + *cursorPos) != gBagMenu->numItemStacks[gBagPosition.pocket] - 1)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
StartItemSwap(taskId);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (JOY_NEW(START_BUTTON))
|
||||
{
|
||||
if ((gBagMenu->numItemStacks[gBagPosition.pocket] - 1) <= 1) //can't sort with 0 or 1 item in bag
|
||||
{
|
||||
static const u8 sText_NothingToSort[] = _("There's nothing to sort!");
|
||||
PlaySE(SE_FAILURE);
|
||||
DisplayItemMessage(taskId, 1, sText_NothingToSort, HandleErrorMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
data[1] = GetItemListPosition(gBagPosition.pocket);
|
||||
data[2] = BagGetQuantityByPocketPosition(gBagPosition.pocket + 1, data[1]);
|
||||
if (gBagPosition.cursorPosition[gBagPosition.pocket] == gBagMenu->numItemStacks[gBagPosition.pocket] - 1)
|
||||
break;
|
||||
else
|
||||
gSpecialVar_ItemId = BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, data[1]);
|
||||
|
||||
PlaySE(SE_SELECT);
|
||||
BagDestroyPocketScrollArrowPair();
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_GRAY_CURSOR);
|
||||
ListMenuGetScrollAndRow(data[0], scrollPos, cursorPos);
|
||||
gTasks[taskId].func = Task_LoadBagSortOptions;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
listPosition = ListMenu_ProcessInput(tListTaskId);
|
||||
ListMenuGetScrollAndRow(tListTaskId, scrollPos, cursorPos);
|
||||
switch (listPosition)
|
||||
{
|
||||
case LIST_NOTHING_CHOSEN:
|
||||
break;
|
||||
case LIST_CANCEL:
|
||||
if (gBagPosition.location == ITEMMENULOCATION_BERRY_BLENDER_CRUSH)
|
||||
{
|
||||
PlaySE(SE_FAILURE);
|
||||
break;
|
||||
}
|
||||
PlaySE(SE_SELECT);
|
||||
gSpecialVar_ItemId = ITEM_NONE;
|
||||
gTasks[taskId].func = Task_FadeAndCloseBagMenu;
|
||||
break;
|
||||
default: // A_BUTTON
|
||||
PlaySE(SE_SELECT);
|
||||
BagDestroyPocketScrollArrowPair();
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_GRAY_CURSOR);
|
||||
tListPosition = listPosition;
|
||||
tQuantity = BagGetQuantityByPocketPosition(gBagPosition.pocket + 1, listPosition);
|
||||
gSpecialVar_ItemId = BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, listPosition);
|
||||
sContextMenuFuncs[gBagPosition.location](taskId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ReturnToItemList(u8 taskId)
|
||||
{
|
||||
CreatePocketScrollArrowPair();
|
||||
CreatePocketSwitchArrowPair();
|
||||
ClearWindowTilemap(WIN_TMHM_INFO_ICONS);
|
||||
ClearWindowTilemap(WIN_TMHM_INFO);
|
||||
PutWindowTilemap(WIN_DESCRIPTION);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
gTasks[taskId].func = Task_BagMenu_HandleInput;
|
||||
}
|
||||
|
||||
static u8 GetSwitchBagPocketDirection(void)
|
||||
{
|
||||
u8 LRKeys;
|
||||
if (gBagMenu->pocketSwitchDisabled)
|
||||
return SWITCH_POCKET_NONE;
|
||||
LRKeys = GetLRKeysPressed();
|
||||
if (JOY_NEW(DPAD_LEFT) || LRKeys == MENU_L_PRESSED)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
return SWITCH_POCKET_LEFT;
|
||||
}
|
||||
if (JOY_NEW(DPAD_RIGHT) || LRKeys == MENU_R_PRESSED)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
return SWITCH_POCKET_RIGHT;
|
||||
}
|
||||
return SWITCH_POCKET_NONE;
|
||||
}
|
||||
|
||||
static void ChangeBagPocketId(u8 *bagPocketId, s8 deltaBagPocketId)
|
||||
{
|
||||
if (deltaBagPocketId == MENU_CURSOR_DELTA_RIGHT && *bagPocketId == POCKETS_COUNT - 1)
|
||||
*bagPocketId = 0;
|
||||
else if (deltaBagPocketId == MENU_CURSOR_DELTA_LEFT && *bagPocketId == 0)
|
||||
*bagPocketId = POCKETS_COUNT - 1;
|
||||
else
|
||||
*bagPocketId += deltaBagPocketId;
|
||||
}
|
||||
|
||||
static void SwitchBagPocket(u8 taskId, s16 deltaBagPocketId, bool16 skipEraseList)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u8 newPocket;
|
||||
|
||||
tPocketSwitchState = 0;
|
||||
tPocketSwitchTimer = 0;
|
||||
tPocketSwitchDir = deltaBagPocketId;
|
||||
if (!skipEraseList)
|
||||
{
|
||||
ClearWindowTilemap(WIN_ITEM_LIST);
|
||||
ClearWindowTilemap(WIN_DESCRIPTION);
|
||||
DestroyListMenuTask(tListTaskId, &gBagPosition.scrollPosition[gBagPosition.pocket], &gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
gSprites[gBagMenu->spriteIds[ITEMMENUSPRITE_ITEM + (gBagMenu->itemIconSlot ^ 1)]].invisible = TRUE;
|
||||
BagDestroyPocketScrollArrowPair();
|
||||
}
|
||||
newPocket = gBagPosition.pocket;
|
||||
ChangeBagPocketId(&newPocket, deltaBagPocketId);
|
||||
if (deltaBagPocketId == MENU_CURSOR_DELTA_RIGHT)
|
||||
{
|
||||
PrintPocketNames(gPocketNamesStringsTable[gBagPosition.pocket], gPocketNamesStringsTable[newPocket]);
|
||||
CopyPocketNameToWindow(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintPocketNames(gPocketNamesStringsTable[newPocket], gPocketNamesStringsTable[gBagPosition.pocket]);
|
||||
CopyPocketNameToWindow(8);
|
||||
}
|
||||
DrawPocketIndicatorSquare(gBagPosition.pocket, FALSE);
|
||||
DrawPocketIndicatorSquare(newPocket, TRUE);
|
||||
FillBgTilemapBufferRect_Palette0(2, 11, 14, 2, 15, 16);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
SetBagVisualPocketId(newPocket, 1);
|
||||
RemoveBagSprite(ITEMMENUSPRITE_BALL);
|
||||
AddSwitchPocketRotatingBallSprite(deltaBagPocketId);
|
||||
SetTaskFuncWithFollowupFunc(taskId, Task_SwitchBagPocket, gTasks[taskId].func);
|
||||
}
|
||||
|
||||
static void Task_SwitchBagPocket(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (!MenuHelpers_IsLinkActive() && !IsWallysBag())
|
||||
{
|
||||
switch (GetSwitchBagPocketDirection())
|
||||
{
|
||||
case SWITCH_POCKET_LEFT:
|
||||
ChangeBagPocketId(&gBagPosition.pocket, tPocketSwitchDir);
|
||||
SwitchTaskToFollowupFunc(taskId);
|
||||
SwitchBagPocket(taskId, MENU_CURSOR_DELTA_LEFT, TRUE);
|
||||
return;
|
||||
case SWITCH_POCKET_RIGHT:
|
||||
ChangeBagPocketId(&gBagPosition.pocket, tPocketSwitchDir);
|
||||
SwitchTaskToFollowupFunc(taskId);
|
||||
SwitchBagPocket(taskId, MENU_CURSOR_DELTA_RIGHT, TRUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch (tPocketSwitchState)
|
||||
{
|
||||
case 0:
|
||||
DrawItemListBgRow(tPocketSwitchTimer);
|
||||
if (!(++tPocketSwitchTimer & 1))
|
||||
{
|
||||
if (tPocketSwitchDir == MENU_CURSOR_DELTA_RIGHT)
|
||||
CopyPocketNameToWindow((u8)(tPocketSwitchTimer >> 1));
|
||||
else
|
||||
CopyPocketNameToWindow((u8)(8 - (tPocketSwitchTimer >> 1)));
|
||||
}
|
||||
if (tPocketSwitchTimer == 16)
|
||||
tPocketSwitchState++;
|
||||
break;
|
||||
case 1:
|
||||
ChangeBagPocketId(&gBagPosition.pocket, tPocketSwitchDir);
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, gBagPosition.scrollPosition[gBagPosition.pocket], gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
PutWindowTilemap(WIN_DESCRIPTION);
|
||||
PutWindowTilemap(WIN_POCKET_NAME);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
CreatePocketScrollArrowPair();
|
||||
CreatePocketSwitchArrowPair();
|
||||
SwitchTaskToFollowupFunc(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
// The background of the item list is a lighter color than the surrounding menu
|
||||
// When the pocket is switched this lighter background is redrawn row by row
|
||||
static void DrawItemListBgRow(u8 y)
|
||||
{
|
||||
FillBgTilemapBufferRect_Palette0(2, 17, 14, y + 2, 15, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
}
|
||||
|
||||
static void DrawPocketIndicatorSquare(u8 x, bool8 isCurrentPocket)
|
||||
{
|
||||
if (!isCurrentPocket)
|
||||
FillBgTilemapBufferRect_Palette0(2, 0x1017, x + 5, 3, 1, 1);
|
||||
else
|
||||
FillBgTilemapBufferRect_Palette0(2, 0x102B, x + 5, 3, 1, 1);
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
}
|
||||
|
||||
static bool8 CanSwapItems(void)
|
||||
{
|
||||
// Swaps can only be done from the field or in battle (as opposed to while selling items, for example)
|
||||
if (gBagPosition.location == ITEMMENULOCATION_FIELD
|
||||
|| gBagPosition.location == ITEMMENULOCATION_BATTLE)
|
||||
{
|
||||
// TMHMs and berries are numbered, and so may not be swapped
|
||||
if (gBagPosition.pocket != TMHM_POCKET
|
||||
&& gBagPosition.pocket != BERRIES_POCKET)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void StartItemSwap(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
ListMenuSetUnkIndicatorsStructField(tListTaskId, 16, 1);
|
||||
tListPosition = gBagPosition.scrollPosition[gBagPosition.pocket] + gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
gBagMenu->toSwapPos = tListPosition;
|
||||
CopyItemName(BagGetItemIdByPocketPosition(gBagPosition.pocket + 1, tListPosition), gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_MoveVar1Where);
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
UpdateItemMenuSwapLinePos(tListPosition);
|
||||
DestroyPocketSwitchArrowPair();
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_GRAY_CURSOR);
|
||||
gTasks[taskId].func = Task_HandleSwappingItemsInput;
|
||||
}
|
||||
|
||||
static void Task_HandleSwappingItemsInput(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
|
||||
{
|
||||
if (JOY_NEW(SELECT_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ListMenuGetScrollAndRow(tListTaskId, &gBagPosition.scrollPosition[gBagPosition.pocket], &gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
DoItemSwap(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 input = ListMenu_ProcessInput(tListTaskId);
|
||||
ListMenuGetScrollAndRow(tListTaskId, &gBagPosition.scrollPosition[gBagPosition.pocket], &gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
SetItemMenuSwapLineInvisibility(FALSE);
|
||||
UpdateItemMenuSwapLinePos(gBagPosition.cursorPosition[gBagPosition.pocket]);
|
||||
switch (input)
|
||||
{
|
||||
case LIST_NOTHING_CHOSEN:
|
||||
break;
|
||||
case LIST_CANCEL:
|
||||
PlaySE(SE_SELECT);
|
||||
if (JOY_NEW(A_BUTTON))
|
||||
DoItemSwap(taskId);
|
||||
else
|
||||
CancelItemSwap(taskId);
|
||||
break;
|
||||
default:
|
||||
PlaySE(SE_SELECT);
|
||||
DoItemSwap(taskId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DoItemSwap(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
u16 realPos = (*scrollPos + *cursorPos);
|
||||
|
||||
if (tListPosition == realPos || tListPosition == realPos - 1)
|
||||
{
|
||||
// Position is the same as the original, cancel
|
||||
CancelItemSwap(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveItemSlotInList(gBagPockets[gBagPosition.pocket].itemSlots, tListPosition, realPos);
|
||||
gBagMenu->toSwapPos = NOT_SWAPPING;
|
||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||
if (tListPosition < realPos)
|
||||
gBagPosition.cursorPosition[gBagPosition.pocket]--;
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
SetItemMenuSwapLineInvisibility(TRUE);
|
||||
CreatePocketSwitchArrowPair();
|
||||
gTasks[taskId].func = Task_BagMenu_HandleInput;
|
||||
}
|
||||
}
|
||||
|
||||
static void CancelItemSwap(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
|
||||
gBagMenu->toSwapPos = NOT_SWAPPING;
|
||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||
if (tListPosition < *scrollPos + *cursorPos)
|
||||
gBagPosition.cursorPosition[gBagPosition.pocket]--;
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
SetItemMenuSwapLineInvisibility(TRUE);
|
||||
CreatePocketSwitchArrowPair();
|
||||
gTasks[taskId].func = Task_BagMenu_HandleInput;
|
||||
}
|
||||
|
||||
static void OpenContextMenu(u8 taskId)
|
||||
{
|
||||
switch (gBagPosition.location)
|
||||
{
|
||||
case ITEMMENULOCATION_BATTLE:
|
||||
case ITEMMENULOCATION_WALLY:
|
||||
if (ItemId_GetBattleUsage(gSpecialVar_ItemId))
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_BattleUse;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_BattleUse);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Cancel;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Cancel);
|
||||
}
|
||||
break;
|
||||
case ITEMMENULOCATION_BERRY_BLENDER_CRUSH:
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_BerryBlenderCrush;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_BerryBlenderCrush);
|
||||
break;
|
||||
case ITEMMENULOCATION_APPRENTICE:
|
||||
if (!ItemId_GetImportance(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY)
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Apprentice;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Apprentice);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Cancel;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Cancel);
|
||||
}
|
||||
break;
|
||||
case ITEMMENULOCATION_FAVOR_LADY:
|
||||
if (!ItemId_GetImportance(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY)
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_FavorLady;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_FavorLady);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Cancel;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Cancel);
|
||||
}
|
||||
break;
|
||||
case ITEMMENULOCATION_QUIZ_LADY:
|
||||
if (!ItemId_GetImportance(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY)
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_QuizLady;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_QuizLady);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Cancel;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Cancel);
|
||||
}
|
||||
break;
|
||||
case ITEMMENULOCATION_PARTY:
|
||||
case ITEMMENULOCATION_SHOP:
|
||||
case ITEMMENULOCATION_BERRY_TREE:
|
||||
case ITEMMENULOCATION_ITEMPC:
|
||||
default:
|
||||
if (MenuHelpers_IsLinkActive() == TRUE || InUnionRoom() == TRUE)
|
||||
{
|
||||
if (gBagPosition.pocket == KEYITEMS_POCKET || !IsHoldingItemAllowed(gSpecialVar_ItemId))
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Cancel;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_Give;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_Give);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (gBagPosition.pocket)
|
||||
{
|
||||
case ITEMS_POCKET:
|
||||
gBagMenu->contextMenuItemsPtr = gBagMenu->contextMenuItemsBuffer;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_ItemsPocket);
|
||||
memcpy(&gBagMenu->contextMenuItemsBuffer, &sContextMenuItems_ItemsPocket, sizeof(sContextMenuItems_ItemsPocket));
|
||||
if (ItemIsMail(gSpecialVar_ItemId) == TRUE)
|
||||
gBagMenu->contextMenuItemsBuffer[0] = ACTION_CHECK;
|
||||
break;
|
||||
case KEYITEMS_POCKET:
|
||||
gBagMenu->contextMenuItemsPtr = gBagMenu->contextMenuItemsBuffer;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_KeyItemsPocket);
|
||||
memcpy(&gBagMenu->contextMenuItemsBuffer, &sContextMenuItems_KeyItemsPocket, sizeof(sContextMenuItems_KeyItemsPocket));
|
||||
if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId)
|
||||
gBagMenu->contextMenuItemsBuffer[1] = ACTION_DESELECT;
|
||||
if (gSpecialVar_ItemId == ITEM_MACH_BIKE || gSpecialVar_ItemId == ITEM_ACRO_BIKE)
|
||||
{
|
||||
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
|
||||
gBagMenu->contextMenuItemsBuffer[0] = ACTION_WALK;
|
||||
}
|
||||
break;
|
||||
case BALLS_POCKET:
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_BallsPocket;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_BallsPocket);
|
||||
break;
|
||||
case TMHM_POCKET:
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_TmHmPocket;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_TmHmPocket);
|
||||
break;
|
||||
case BERRIES_POCKET:
|
||||
gBagMenu->contextMenuItemsPtr = sContextMenuItems_BerriesPocket;
|
||||
gBagMenu->contextMenuNumItems = ARRAY_COUNT(sContextMenuItems_BerriesPocket);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gBagPosition.pocket == TMHM_POCKET)
|
||||
{
|
||||
ClearWindowTilemap(WIN_DESCRIPTION);
|
||||
PrintTMHMMoveData(gSpecialVar_ItemId);
|
||||
PutWindowTilemap(WIN_TMHM_INFO_ICONS);
|
||||
PutWindowTilemap(WIN_TMHM_INFO);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_Var1IsSelected);
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
}
|
||||
if (gBagMenu->contextMenuNumItems == 1)
|
||||
PrintContextMenuItems(BagMenu_AddWindow(ITEMWIN_1x1));
|
||||
else if (gBagMenu->contextMenuNumItems == 2)
|
||||
PrintContextMenuItems(BagMenu_AddWindow(ITEMWIN_1x2));
|
||||
else if (gBagMenu->contextMenuNumItems == 4)
|
||||
PrintContextMenuItemGrid(BagMenu_AddWindow(ITEMWIN_2x2), 2, 2);
|
||||
else
|
||||
PrintContextMenuItemGrid(BagMenu_AddWindow(ITEMWIN_2x3), 2, 3);
|
||||
}
|
||||
|
||||
static void PrintContextMenuItems(u8 windowId)
|
||||
{
|
||||
PrintMenuActionTexts(windowId, FONT_NARROW, 8, 1, 0, 16, gBagMenu->contextMenuNumItems, sItemMenuActions, gBagMenu->contextMenuItemsPtr);
|
||||
InitMenuInUpperLeftCornerNormal(windowId, gBagMenu->contextMenuNumItems, 0);
|
||||
}
|
||||
|
||||
static void PrintContextMenuItemGrid(u8 windowId, u8 columns, u8 rows)
|
||||
{
|
||||
PrintMenuActionGrid(windowId, FONT_NARROW, 8, 1, 56, columns, rows, sItemMenuActions, gBagMenu->contextMenuItemsPtr);
|
||||
InitMenuActionGrid(windowId, 56, columns, rows, 0);
|
||||
}
|
||||
|
||||
static void Task_ItemContext_Normal(u8 taskId)
|
||||
{
|
||||
OpenContextMenu(taskId);
|
||||
|
||||
// Context menu width is never greater than 2 columns, so if
|
||||
// there are more than 2 items then there are multiple rows
|
||||
if (gBagMenu->contextMenuNumItems <= 2)
|
||||
gTasks[taskId].func = Task_ItemContext_SingleRow;
|
||||
else
|
||||
gTasks[taskId].func = Task_ItemContext_MultipleRows;
|
||||
}
|
||||
|
||||
static void Task_ItemContext_SingleRow(u8 taskId)
|
||||
{
|
||||
if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
|
||||
{
|
||||
s8 selection = Menu_ProcessInputNoWrap();
|
||||
switch (selection)
|
||||
{
|
||||
case MENU_NOTHING_CHOSEN:
|
||||
break;
|
||||
case MENU_B_PRESSED:
|
||||
PlaySE(SE_SELECT);
|
||||
sItemMenuActions[ACTION_CANCEL].func.void_u8(taskId);
|
||||
break;
|
||||
default:
|
||||
PlaySE(SE_SELECT);
|
||||
sItemMenuActions[gBagMenu->contextMenuItemsPtr[selection]].func.void_u8(taskId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_ItemContext_MultipleRows(u8 taskId)
|
||||
{
|
||||
if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
|
||||
{
|
||||
s8 cursorPos = Menu_GetCursorPos();
|
||||
if (JOY_NEW(DPAD_UP))
|
||||
{
|
||||
if (cursorPos > 0 && IsValidContextMenuPos(cursorPos - 2))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ChangeMenuGridCursorPosition(MENU_CURSOR_DELTA_NONE, MENU_CURSOR_DELTA_UP);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_DOWN))
|
||||
{
|
||||
if (cursorPos < (gBagMenu->contextMenuNumItems - 2) && IsValidContextMenuPos(cursorPos + 2))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ChangeMenuGridCursorPosition(MENU_CURSOR_DELTA_NONE, MENU_CURSOR_DELTA_DOWN);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_LEFT) || GetLRKeysPressed() == MENU_L_PRESSED)
|
||||
{
|
||||
if ((cursorPos & 1) && IsValidContextMenuPos(cursorPos - 1))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ChangeMenuGridCursorPosition(MENU_CURSOR_DELTA_LEFT, MENU_CURSOR_DELTA_NONE);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_RIGHT) || GetLRKeysPressed() == MENU_R_PRESSED)
|
||||
{
|
||||
if (!(cursorPos & 1) && IsValidContextMenuPos(cursorPos + 1))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ChangeMenuGridCursorPosition(MENU_CURSOR_DELTA_RIGHT, MENU_CURSOR_DELTA_NONE);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
sItemMenuActions[gBagMenu->contextMenuItemsPtr[cursorPos]].func.void_u8(taskId);
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
sItemMenuActions[ACTION_CANCEL].func.void_u8(taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool8 IsValidContextMenuPos(s8 cursorPos)
|
||||
{
|
||||
if (cursorPos < 0)
|
||||
return FALSE;
|
||||
if (cursorPos > gBagMenu->contextMenuNumItems)
|
||||
return FALSE;
|
||||
if (gBagMenu->contextMenuItemsPtr[cursorPos] == ACTION_DUMMY)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void RemoveContextWindow(void)
|
||||
{
|
||||
if (gBagMenu->contextMenuNumItems == 1)
|
||||
BagMenu_RemoveWindow(ITEMWIN_1x1);
|
||||
else if (gBagMenu->contextMenuNumItems == 2)
|
||||
BagMenu_RemoveWindow(ITEMWIN_1x2);
|
||||
else if (gBagMenu->contextMenuNumItems == 4)
|
||||
BagMenu_RemoveWindow(ITEMWIN_2x2);
|
||||
else
|
||||
BagMenu_RemoveWindow(ITEMWIN_2x3);
|
||||
}
|
||||
|
||||
static void ItemMenu_UseOutOfBattle(u8 taskId)
|
||||
{
|
||||
if (ItemId_GetFieldFunc(gSpecialVar_ItemId))
|
||||
{
|
||||
RemoveContextWindow();
|
||||
if (CalculatePlayerPartyCount() == 0 && ItemId_GetType(gSpecialVar_ItemId) == ITEM_USE_PARTY_MENU)
|
||||
{
|
||||
PrintThereIsNoPokemon(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
if (gBagPosition.pocket != BERRIES_POCKET)
|
||||
ItemId_GetFieldFunc(gSpecialVar_ItemId)(taskId);
|
||||
else
|
||||
ItemUseOutOfBattle_Berry(taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ItemMenu_Toss(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
RemoveContextWindow();
|
||||
tItemCount = 1;
|
||||
if (tQuantity == 1)
|
||||
{
|
||||
AskTossItems(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_TossHowManyVar1s);
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
AddItemQuantityWindow(ITEMWIN_QUANTITY);
|
||||
gTasks[taskId].func = Task_ChooseHowManyToToss;
|
||||
}
|
||||
}
|
||||
|
||||
static void AskTossItems(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
ConvertIntToDecimalStringN(gStringVar2, tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_ITEM_DIGITS);
|
||||
StringExpandPlaceholders(gStringVar4, gText_ConfirmTossItems);
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
BagMenu_YesNo(taskId, ITEMWIN_YESNO_LOW, &sYesNoTossFunctions);
|
||||
}
|
||||
|
||||
static void CancelToss(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
PrintItemDescription(tListPosition);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_NORMAL);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
|
||||
static void Task_ChooseHowManyToToss(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (AdjustQuantityAccordingToDPadInput(&tItemCount, tQuantity) == TRUE)
|
||||
{
|
||||
PrintItemQuantity(gBagMenu->windowIds[ITEMWIN_QUANTITY], tItemCount);
|
||||
}
|
||||
else if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
BagMenu_RemoveWindow(ITEMWIN_QUANTITY);
|
||||
AskTossItems(taskId);
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
BagMenu_RemoveWindow(ITEMWIN_QUANTITY);
|
||||
CancelToss(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void ConfirmToss(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
ConvertIntToDecimalStringN(gStringVar2, tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_ITEM_DIGITS);
|
||||
StringExpandPlaceholders(gStringVar4, gText_ThrewAwayVar2Var1s);
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
gTasks[taskId].func = Task_RemoveItemFromBag;
|
||||
}
|
||||
|
||||
// Remove selected item(s) from the bag and update list
|
||||
// For when items are tossed or deposited
|
||||
static void Task_RemoveItemFromBag(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
|
||||
if (JOY_NEW(A_BUTTON | B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
RemoveBagItem(gSpecialVar_ItemId, tItemCount);
|
||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||
UpdatePocketItemList(gBagPosition.pocket);
|
||||
UpdatePocketListPosition(gBagPosition.pocket);
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void ItemMenu_Register(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
|
||||
if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId)
|
||||
gSaveBlock1Ptr->registeredItem = 0;
|
||||
else
|
||||
gSaveBlock1Ptr->registeredItem = gSpecialVar_ItemId;
|
||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
ItemMenu_Cancel(taskId);
|
||||
}
|
||||
|
||||
static void ItemMenu_Give(u8 taskId)
|
||||
{
|
||||
RemoveContextWindow();
|
||||
if (!IsWritingMailAllowed(gSpecialVar_ItemId))
|
||||
{
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_CantWriteMail, HandleErrorMessage);
|
||||
}
|
||||
else if (!ItemId_GetImportance(gSpecialVar_ItemId))
|
||||
{
|
||||
if (CalculatePlayerPartyCount() == 0)
|
||||
{
|
||||
PrintThereIsNoPokemon(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBagMenu->newScreenCallback = CB2_ChooseMonToGiveItem;
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintItemCantBeHeld(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintThereIsNoPokemon(u8 taskId)
|
||||
{
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_NoPokemon, HandleErrorMessage);
|
||||
}
|
||||
|
||||
static void PrintItemCantBeHeld(u8 taskId)
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeld);
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, HandleErrorMessage);
|
||||
}
|
||||
|
||||
static void HandleErrorMessage(u8 taskId)
|
||||
{
|
||||
if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
CloseItemMessage(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void ItemMenu_CheckTag(u8 taskId)
|
||||
{
|
||||
gBagMenu->newScreenCallback = DoBerryTagScreen;
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
|
||||
static void ItemMenu_Cancel(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
RemoveContextWindow();
|
||||
PrintItemDescription(tListPosition);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
ScheduleBgCopyTilemapToVram(1);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_NORMAL);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
|
||||
static void ItemMenu_UseInBattle(u8 taskId)
|
||||
{
|
||||
if (ItemId_GetBattleFunc(gSpecialVar_ItemId))
|
||||
{
|
||||
RemoveContextWindow();
|
||||
ItemId_GetBattleFunc(gSpecialVar_ItemId)(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
void CB2_ReturnToBagMenuPocket(void)
|
||||
{
|
||||
GoToBagMenu(ITEMMENULOCATION_LAST, POCKETS_COUNT, NULL);
|
||||
}
|
||||
|
||||
static void Task_ItemContext_GiveToParty(u8 taskId)
|
||||
{
|
||||
if (!IsWritingMailAllowed(gSpecialVar_ItemId))
|
||||
{
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_CantWriteMail, HandleErrorMessage);
|
||||
}
|
||||
else if (!IsHoldingItemAllowed(gSpecialVar_ItemId))
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeldHere);
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, HandleErrorMessage);
|
||||
}
|
||||
else if (gBagPosition.pocket != KEYITEMS_POCKET && !ItemId_GetImportance(gSpecialVar_ItemId))
|
||||
{
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintItemCantBeHeld(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
// Selected item to give to a Pokémon in PC storage
|
||||
static void Task_ItemContext_GiveToPC(u8 taskId)
|
||||
{
|
||||
if (ItemIsMail(gSpecialVar_ItemId) == TRUE)
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_CantWriteMail, HandleErrorMessage);
|
||||
else if (gBagPosition.pocket != KEYITEMS_POCKET && !ItemId_GetImportance(gSpecialVar_ItemId))
|
||||
gTasks[taskId].func = Task_FadeAndCloseBagMenu;
|
||||
else
|
||||
PrintItemCantBeHeld(taskId);
|
||||
}
|
||||
|
||||
#define tUsingRegisteredKeyItem data[3] // See usage in item_use.c
|
||||
|
||||
bool8 UseRegisteredKeyItemOnField(void)
|
||||
{
|
||||
u8 taskId;
|
||||
|
||||
if (InUnionRoom() == TRUE || InBattlePyramid() || InBattlePike() || InMultiPartnerRoom() == TRUE)
|
||||
return FALSE;
|
||||
HideMapNamePopUpWindow();
|
||||
ChangeBgY_ScreenOff(0, 0, BG_COORD_SET);
|
||||
if (gSaveBlock1Ptr->registeredItem != ITEM_NONE)
|
||||
{
|
||||
if (CheckBagHasItem(gSaveBlock1Ptr->registeredItem, 1) == TRUE)
|
||||
{
|
||||
ScriptContext2_Enable();
|
||||
FreezeObjectEvents();
|
||||
PlayerFreeze();
|
||||
StopPlayerAvatar();
|
||||
gSpecialVar_ItemId = gSaveBlock1Ptr->registeredItem;
|
||||
taskId = CreateTask(ItemId_GetFieldFunc(gSaveBlock1Ptr->registeredItem), 8);
|
||||
gTasks[taskId].tUsingRegisteredKeyItem = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gSaveBlock1Ptr->registeredItem = ITEM_NONE;
|
||||
}
|
||||
}
|
||||
ScriptContext1_SetupScript(EventScript_SelectWithoutRegisteredItem);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef tUsingRegisteredKeyItem
|
||||
|
||||
static void Task_ItemContext_Sell(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (ItemId_GetPrice(gSpecialVar_ItemId) == 0 || ItemId_GetPocket(gSpecialVar_ItemId) == POCKET_TM_HM)
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, gText_CantBuyKeyItem);
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, CloseItemMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
tItemCount = 1;
|
||||
if (tQuantity == 1)
|
||||
{
|
||||
DisplayCurrentMoneyWindow();
|
||||
DisplaySellItemPriceAndConfirm(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, gText_HowManyToSell);
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, InitSellHowManyInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DisplaySellItemPriceAndConfirm(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
ConvertIntToDecimalStringN(gStringVar1, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * tItemCount, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
StringExpandPlaceholders(gStringVar4, gText_ICanPayVar1);
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, AskSellItems);
|
||||
}
|
||||
|
||||
static void AskSellItems(u8 taskId)
|
||||
{
|
||||
BagMenu_YesNo(taskId, ITEMWIN_YESNO_HIGH, &sYesNoSellItemFunctions);
|
||||
}
|
||||
|
||||
static void CancelSell(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
RemoveMoneyWindow();
|
||||
RemoveItemMessageWindow(ITEMWIN_MESSAGE);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_NORMAL);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
|
||||
static void InitSellHowManyInput(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u8 windowId = BagMenu_AddWindow(ITEMWIN_QUANTITY_WIDE);
|
||||
|
||||
PrintItemSoldAmount(windowId, 1, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * tItemCount);
|
||||
DisplayCurrentMoneyWindow();
|
||||
gTasks[taskId].func = Task_ChooseHowManyToSell;
|
||||
}
|
||||
|
||||
static void Task_ChooseHowManyToSell(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (AdjustQuantityAccordingToDPadInput(&tItemCount, tQuantity) == TRUE)
|
||||
{
|
||||
PrintItemSoldAmount(gBagMenu->windowIds[ITEMWIN_QUANTITY_WIDE], tItemCount, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * tItemCount);
|
||||
}
|
||||
else if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
BagMenu_RemoveWindow(ITEMWIN_QUANTITY_WIDE);
|
||||
DisplaySellItemPriceAndConfirm(taskId);
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_NORMAL);
|
||||
RemoveMoneyWindow();
|
||||
BagMenu_RemoveWindow(ITEMWIN_QUANTITY_WIDE);
|
||||
RemoveItemMessageWindow(ITEMWIN_MESSAGE);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void ConfirmSell(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar2);
|
||||
ConvertIntToDecimalStringN(gStringVar1, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * tItemCount, STR_CONV_MODE_LEFT_ALIGN, 6);
|
||||
StringExpandPlaceholders(gStringVar4, gText_TurnedOverVar1ForVar2);
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, SellItem);
|
||||
}
|
||||
|
||||
static void SellItem(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
u16* scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
|
||||
PlaySE(SE_SHOP);
|
||||
RemoveBagItem(gSpecialVar_ItemId, tItemCount);
|
||||
AddMoney(&gSaveBlock1Ptr->money, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * tItemCount);
|
||||
DestroyListMenuTask(tListTaskId, scrollPos, cursorPos);
|
||||
UpdatePocketItemList(gBagPosition.pocket);
|
||||
UpdatePocketListPosition(gBagPosition.pocket);
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_GRAY_CURSOR);
|
||||
PrintMoneyAmountInMoneyBox(gBagMenu->windowIds[ITEMWIN_MONEY], GetMoney(&gSaveBlock1Ptr->money), 0);
|
||||
gTasks[taskId].func = WaitAfterItemSell;
|
||||
}
|
||||
|
||||
static void WaitAfterItemSell(u8 taskId)
|
||||
{
|
||||
if (JOY_NEW(A_BUTTON | B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
RemoveMoneyWindow();
|
||||
CloseItemMessage(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_ItemContext_Deposit(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
tItemCount = 1;
|
||||
if (tQuantity == 1)
|
||||
{
|
||||
TryDepositItem(taskId);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_DepositHowManyVar1);
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
AddItemQuantityWindow(ITEMWIN_QUANTITY);
|
||||
gTasks[taskId].func = Task_ChooseHowManyToDeposit;
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_ChooseHowManyToDeposit(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (AdjustQuantityAccordingToDPadInput(&tItemCount, tQuantity) == TRUE)
|
||||
{
|
||||
PrintItemQuantity(gBagMenu->windowIds[ITEMWIN_QUANTITY], tItemCount);
|
||||
}
|
||||
else if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
BagMenu_RemoveWindow(ITEMWIN_QUANTITY);
|
||||
TryDepositItem(taskId);
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
PrintItemDescription(tListPosition);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_NORMAL);
|
||||
BagMenu_RemoveWindow(ITEMWIN_QUANTITY);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void TryDepositItem(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
|
||||
if (ItemId_GetImportance(gSpecialVar_ItemId))
|
||||
{
|
||||
// Can't deposit important items
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gText_CantStoreImportantItems, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
gTasks[taskId].func = WaitDepositErrorMessage;
|
||||
}
|
||||
else if (AddPCItem(gSpecialVar_ItemId, tItemCount) == TRUE)
|
||||
{
|
||||
// Successfully deposited
|
||||
CopyItemName(gSpecialVar_ItemId, gStringVar1);
|
||||
ConvertIntToDecimalStringN(gStringVar2, tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_ITEM_DIGITS);
|
||||
StringExpandPlaceholders(gStringVar4, gText_DepositedVar2Var1s);
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
gTasks[taskId].func = Task_RemoveItemFromBag;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No room to deposit
|
||||
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gText_NoRoomForItems, 3, 1, 0, 0, 0, COLORID_NORMAL);
|
||||
gTasks[taskId].func = WaitDepositErrorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
static void WaitDepositErrorMessage(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (JOY_NEW(A_BUTTON | B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
PrintItemDescription(tListPosition);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_NORMAL);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static bool8 IsWallysBag(void)
|
||||
{
|
||||
if (gBagPosition.location == ITEMMENULOCATION_WALLY)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void PrepareBagForWallyTutorial(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
sTempWallyBag = AllocZeroed(sizeof(*sTempWallyBag));
|
||||
memcpy(sTempWallyBag->bagPocket_Items, gSaveBlock1Ptr->bagPocket_Items, sizeof(gSaveBlock1Ptr->bagPocket_Items));
|
||||
memcpy(sTempWallyBag->bagPocket_PokeBalls, gSaveBlock1Ptr->bagPocket_PokeBalls, sizeof(gSaveBlock1Ptr->bagPocket_PokeBalls));
|
||||
sTempWallyBag->pocket = gBagPosition.pocket;
|
||||
for (i = 0; i < POCKETS_COUNT; i++)
|
||||
{
|
||||
sTempWallyBag->cursorPosition[i] = gBagPosition.cursorPosition[i];
|
||||
sTempWallyBag->scrollPosition[i] = gBagPosition.scrollPosition[i];
|
||||
}
|
||||
ClearItemSlots(gSaveBlock1Ptr->bagPocket_Items, BAG_ITEMS_COUNT);
|
||||
ClearItemSlots(gSaveBlock1Ptr->bagPocket_PokeBalls, BAG_POKEBALLS_COUNT);
|
||||
ResetBagScrollPositions();
|
||||
}
|
||||
|
||||
static void RestoreBagAfterWallyTutorial(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
memcpy(gSaveBlock1Ptr->bagPocket_Items, sTempWallyBag->bagPocket_Items, sizeof(sTempWallyBag->bagPocket_Items));
|
||||
memcpy(gSaveBlock1Ptr->bagPocket_PokeBalls, sTempWallyBag->bagPocket_PokeBalls, sizeof(sTempWallyBag->bagPocket_PokeBalls));
|
||||
gBagPosition.pocket = sTempWallyBag->pocket;
|
||||
for (i = 0; i < POCKETS_COUNT; i++)
|
||||
{
|
||||
gBagPosition.cursorPosition[i] = sTempWallyBag->cursorPosition[i];
|
||||
gBagPosition.scrollPosition[i] = sTempWallyBag->scrollPosition[i];
|
||||
}
|
||||
Free(sTempWallyBag);
|
||||
}
|
||||
|
||||
void DoWallyTutorialBagMenu(void)
|
||||
{
|
||||
PrepareBagForWallyTutorial();
|
||||
AddBagItem(ITEM_POTION, 1);
|
||||
AddBagItem(ITEM_POKE_BALL, 1);
|
||||
GoToBagMenu(ITEMMENULOCATION_WALLY, ITEMS_POCKET, CB2_SetUpReshowBattleScreenAfterMenu2);
|
||||
}
|
||||
|
||||
#define tTimer data[8]
|
||||
#define WALLY_BAG_DELAY 102 // The number of frames between each action Wally takes in the bag
|
||||
|
||||
static void Task_WallyTutorialBagMenu(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
switch (tTimer)
|
||||
{
|
||||
case WALLY_BAG_DELAY * 1:
|
||||
PlaySE(SE_SELECT);
|
||||
SwitchBagPocket(taskId, MENU_CURSOR_DELTA_RIGHT, FALSE);
|
||||
tTimer++;
|
||||
break;
|
||||
case WALLY_BAG_DELAY * 2:
|
||||
PlaySE(SE_SELECT);
|
||||
BagMenu_PrintCursor(tListTaskId, COLORID_GRAY_CURSOR);
|
||||
gSpecialVar_ItemId = ITEM_POKE_BALL;
|
||||
OpenContextMenu(taskId);
|
||||
tTimer++;
|
||||
break;
|
||||
case WALLY_BAG_DELAY * 3:
|
||||
PlaySE(SE_SELECT);
|
||||
RemoveContextWindow();
|
||||
DestroyListMenuTask(tListTaskId, 0, 0);
|
||||
RestoreBagAfterWallyTutorial();
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
break;
|
||||
default:
|
||||
tTimer++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef tTimer
|
||||
|
||||
// This action is used to show the Apprentice an item when
|
||||
// they ask what item they should make their Pokémon hold
|
||||
static void ItemMenu_Show(u8 taskId)
|
||||
{
|
||||
gSpecialVar_0x8005 = gSpecialVar_ItemId;
|
||||
gSpecialVar_Result = TRUE;
|
||||
RemoveContextWindow();
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
|
||||
static void CB2_ApprenticeExitBagMenu(void)
|
||||
{
|
||||
gFieldCallback = Apprentice_EnableBothScriptContexts;
|
||||
SetMainCallback2(CB2_ReturnToField);
|
||||
}
|
||||
|
||||
static void ItemMenu_GiveFavorLady(u8 taskId)
|
||||
{
|
||||
RemoveBagItem(gSpecialVar_ItemId, 1);
|
||||
gSpecialVar_Result = TRUE;
|
||||
RemoveContextWindow();
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
|
||||
static void CB2_FavorLadyExitBagMenu(void)
|
||||
{
|
||||
gFieldCallback = FieldCallback_FavorLadyEnableScriptContexts;
|
||||
SetMainCallback2(CB2_ReturnToField);
|
||||
}
|
||||
|
||||
// This action is used to confirm which item to use as
|
||||
// a prize for a custom quiz with the Lilycove Quiz Lady
|
||||
static void ItemMenu_ConfirmQuizLady(u8 taskId)
|
||||
{
|
||||
gSpecialVar_Result = TRUE;
|
||||
RemoveContextWindow();
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
|
||||
static void CB2_QuizLadyExitBagMenu(void)
|
||||
{
|
||||
gFieldCallback = FieldCallback_QuizLadyEnableScriptContexts;
|
||||
SetMainCallback2(CB2_ReturnToField);
|
||||
}
|
||||
|
||||
static void PrintPocketNames(const u8 *pocketName1, const u8 *pocketName2)
|
||||
{
|
||||
struct WindowTemplate window = {0};
|
||||
u16 windowId;
|
||||
int offset;
|
||||
|
||||
window.width = 16;
|
||||
window.height = 2;
|
||||
windowId = AddWindow(&window);
|
||||
FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
|
||||
offset = GetStringCenterAlignXOffset(FONT_NORMAL, pocketName1, 0x40);
|
||||
BagMenu_Print(windowId, FONT_NORMAL, pocketName1, offset, 1, 0, 0, TEXT_SKIP_DRAW, COLORID_POCKET_NAME);
|
||||
if (pocketName2)
|
||||
{
|
||||
offset = GetStringCenterAlignXOffset(FONT_NORMAL, pocketName2, 0x40);
|
||||
BagMenu_Print(windowId, FONT_NORMAL, pocketName2, offset + 0x40, 1, 0, 0, TEXT_SKIP_DRAW, COLORID_POCKET_NAME);
|
||||
}
|
||||
CpuCopy32((u8*)GetWindowAttribute(windowId, WINDOW_TILE_DATA), gBagMenu->pocketNameBuffer, sizeof(gBagMenu->pocketNameBuffer));
|
||||
RemoveWindow(windowId);
|
||||
}
|
||||
|
||||
static void CopyPocketNameToWindow(u32 a)
|
||||
{
|
||||
u8 (* tileDataBuffer)[32][32];
|
||||
u8* windowTileData;
|
||||
int b;
|
||||
if (a > 8)
|
||||
a = 8;
|
||||
tileDataBuffer = &gBagMenu->pocketNameBuffer;
|
||||
windowTileData = (u8*)GetWindowAttribute(2, WINDOW_TILE_DATA);
|
||||
CpuCopy32(tileDataBuffer[0][a], windowTileData, 0x100); // Top half of pocket name
|
||||
b = a + 16;
|
||||
CpuCopy32(tileDataBuffer[0][b], windowTileData + 0x100, 0x100); // Bottom half of pocket name
|
||||
CopyWindowToVram(WIN_POCKET_NAME, COPYWIN_GFX);
|
||||
}
|
||||
|
||||
static void LoadBagMenuTextWindows(void)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
InitWindows(sDefaultBagWindows);
|
||||
DeactivateAllTextPrinters();
|
||||
LoadUserWindowBorderGfx(0, 1, 0xE0);
|
||||
LoadMessageBoxGfx(0, 10, 0xD0);
|
||||
ListMenuLoadStdPalAt(0xC0, 1);
|
||||
LoadPalette(&gStandardMenuPalette, 0xF0, 0x20);
|
||||
for (i = 0; i <= WIN_POCKET_NAME; i++)
|
||||
{
|
||||
FillWindowPixelBuffer(i, PIXEL_FILL(0));
|
||||
PutWindowTilemap(i);
|
||||
}
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
ScheduleBgCopyTilemapToVram(1);
|
||||
}
|
||||
|
||||
static void BagMenu_Print(u8 windowId, u8 fontId, const u8 *str, u8 left, u8 top, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIndex)
|
||||
{
|
||||
AddTextPrinterParameterized4(windowId, fontId, left, top, letterSpacing, lineSpacing, sFontColorTable[colorIndex], speed, str);
|
||||
}
|
||||
|
||||
// Unused
|
||||
static u8 BagMenu_GetWindowId(u8 windowType)
|
||||
{
|
||||
return gBagMenu->windowIds[windowType];
|
||||
}
|
||||
|
||||
static u8 BagMenu_AddWindow(u8 windowType)
|
||||
{
|
||||
u8 *windowId = &gBagMenu->windowIds[windowType];
|
||||
if (*windowId == WINDOW_NONE)
|
||||
{
|
||||
*windowId = AddWindow(&sContextMenuWindowTemplates[windowType]);
|
||||
DrawStdFrameWithCustomTileAndPalette(*windowId, 0, 1, 14);
|
||||
ScheduleBgCopyTilemapToVram(1);
|
||||
}
|
||||
return *windowId;
|
||||
}
|
||||
|
||||
static void BagMenu_RemoveWindow(u8 windowType)
|
||||
{
|
||||
u8 *windowId = &gBagMenu->windowIds[windowType];
|
||||
if (*windowId != WINDOW_NONE)
|
||||
{
|
||||
ClearStdWindowAndFrameToTransparent(*windowId, FALSE);
|
||||
ClearWindowTilemap(*windowId);
|
||||
RemoveWindow(*windowId);
|
||||
ScheduleBgCopyTilemapToVram(1);
|
||||
*windowId = WINDOW_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 AddItemMessageWindow(u8 windowType)
|
||||
{
|
||||
u8 *windowId = &gBagMenu->windowIds[windowType];
|
||||
if (*windowId == WINDOW_NONE)
|
||||
*windowId = AddWindow(&sContextMenuWindowTemplates[windowType]);
|
||||
return *windowId;
|
||||
}
|
||||
|
||||
static void RemoveItemMessageWindow(u8 windowType)
|
||||
{
|
||||
u8 *windowId = &gBagMenu->windowIds[windowType];
|
||||
if (*windowId != WINDOW_NONE)
|
||||
{
|
||||
ClearDialogWindowAndFrameToTransparent(*windowId, FALSE);
|
||||
// This ClearWindowTilemap call is redundant, since ClearDialogWindowAndFrameToTransparent already calls it.
|
||||
ClearWindowTilemap(*windowId);
|
||||
RemoveWindow(*windowId);
|
||||
ScheduleBgCopyTilemapToVram(1);
|
||||
*windowId = WINDOW_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void BagMenu_YesNo(u8 taskId, u8 windowType, const struct YesNoFuncTable *funcTable)
|
||||
{
|
||||
CreateYesNoMenuWithCallbacks(taskId, &sContextMenuWindowTemplates[windowType], 1, 0, 2, 1, 14, funcTable);
|
||||
}
|
||||
|
||||
static void DisplayCurrentMoneyWindow(void)
|
||||
{
|
||||
u8 windowId = BagMenu_AddWindow(ITEMWIN_MONEY);
|
||||
PrintMoneyAmountInMoneyBoxWithBorder(windowId, 1, 14, GetMoney(&gSaveBlock1Ptr->money));
|
||||
AddMoneyLabelObject(19, 11);
|
||||
}
|
||||
|
||||
static void RemoveMoneyWindow(void)
|
||||
{
|
||||
BagMenu_RemoveWindow(ITEMWIN_MONEY);
|
||||
RemoveMoneyLabelObject();
|
||||
}
|
||||
|
||||
static void PrepareTMHMMoveWindow(void)
|
||||
{
|
||||
FillWindowPixelBuffer(WIN_TMHM_INFO_ICONS, PIXEL_FILL(0));
|
||||
BlitMenuInfoIcon(WIN_TMHM_INFO_ICONS, MENU_INFO_ICON_TYPE, 0, 0);
|
||||
BlitMenuInfoIcon(WIN_TMHM_INFO_ICONS, MENU_INFO_ICON_POWER, 0, 12);
|
||||
BlitMenuInfoIcon(WIN_TMHM_INFO_ICONS, MENU_INFO_ICON_ACCURACY, 0, 24);
|
||||
BlitMenuInfoIcon(WIN_TMHM_INFO_ICONS, MENU_INFO_ICON_PP, 0, 36);
|
||||
CopyWindowToVram(WIN_TMHM_INFO_ICONS, COPYWIN_GFX);
|
||||
}
|
||||
|
||||
static void PrintTMHMMoveData(u16 itemId)
|
||||
{
|
||||
u8 i;
|
||||
u16 moveId;
|
||||
const u8* text;
|
||||
|
||||
FillWindowPixelBuffer(WIN_TMHM_INFO, PIXEL_FILL(0));
|
||||
if (itemId == ITEM_NONE)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, gText_ThreeDashes, 7, i * 12, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
|
||||
CopyWindowToVram(WIN_TMHM_INFO, COPYWIN_GFX);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveId = ItemIdToBattleMoveId(itemId);
|
||||
BlitMenuInfoIcon(WIN_TMHM_INFO, gBattleMoves[moveId].type + 1, 0, 0);
|
||||
|
||||
// Print TMHM power
|
||||
if (gBattleMoves[moveId].power <= 1)
|
||||
{
|
||||
text = gText_ThreeDashes;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].power, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
text = gStringVar1;
|
||||
}
|
||||
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, text, 7, 12, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
|
||||
|
||||
// Print TMHM accuracy
|
||||
if (gBattleMoves[moveId].accuracy == 0)
|
||||
{
|
||||
text = gText_ThreeDashes;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
text = gStringVar1;
|
||||
}
|
||||
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, text, 7, 24, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
|
||||
|
||||
// Print TMHM pp
|
||||
ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].pp, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
||||
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, gStringVar1, 7, 36, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
|
||||
|
||||
CopyWindowToVram(WIN_TMHM_INFO, COPYWIN_GFX);
|
||||
}
|
||||
}
|
||||
|
||||
// bag sorting
|
||||
enum BagSortOptions
|
||||
{
|
||||
SORT_ALPHABETICALLY,
|
||||
SORT_BY_TYPE,
|
||||
SORT_BY_AMOUNT, //greatest->least
|
||||
};
|
||||
enum ItemSortType
|
||||
{
|
||||
ITEM_TYPE_FIELD_USE,
|
||||
ITEM_TYPE_HEALTH_RECOVERY,
|
||||
ITEM_TYPE_STATUS_RECOVERY,
|
||||
ITEM_TYPE_PP_RECOVERY,
|
||||
ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
ITEM_TYPE_EVOLUTION_STONE,
|
||||
ITEM_TYPE_EVOLUTION_ITEM,
|
||||
ITEM_TYPE_BATTLE_ITEM,
|
||||
ITEM_TYPE_FLUTE,
|
||||
ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
ITEM_TYPE_HELD_ITEM,
|
||||
ITEM_TYPE_GEM,
|
||||
ITEM_TYPE_PLATE,
|
||||
ITEM_TYPE_MEMORY,
|
||||
ITEM_TYPE_DRIVE,
|
||||
ITEM_TYPE_INCENSE,
|
||||
ITEM_TYPE_MEGA_STONE,
|
||||
ITEM_TYPE_Z_CRYSTAL,
|
||||
ITEM_TYPE_NECTAR,
|
||||
ITEM_TYPE_SELLABLE,
|
||||
ITEM_TYPE_RELIC,
|
||||
ITEM_TYPE_SHARD,
|
||||
ITEM_TYPE_FOSSIL,
|
||||
ITEM_TYPE_MAIL,
|
||||
};
|
||||
static const u8 sText_SortItemsHow[] = _("Sort items how?");
|
||||
static const u8 sText_Name[] = _("name");
|
||||
static const u8 sText_Type[] = _("type");
|
||||
static const u8 sText_Amount[] = _("amount");
|
||||
static const u8 sText_ItemsSorted[] = _("Items sorted by {STR_VAR_1}!");
|
||||
static const u8 *const sSortTypeStrings[] =
|
||||
{
|
||||
[SORT_ALPHABETICALLY] = sText_Name,
|
||||
[SORT_BY_TYPE] = sText_Type,
|
||||
[SORT_BY_AMOUNT] = sText_Amount,
|
||||
};
|
||||
|
||||
static const u8 sBagMenuSortItems[] =
|
||||
{
|
||||
ACTION_BY_NAME,
|
||||
ACTION_BY_TYPE,
|
||||
ACTION_BY_AMOUNT,
|
||||
ACTION_CANCEL,
|
||||
};
|
||||
|
||||
static const u8 sBagMenuSortKeyItems[] =
|
||||
{
|
||||
ACTION_BY_NAME,
|
||||
ACTION_CANCEL,
|
||||
};
|
||||
|
||||
static const u8 sBagMenuSortPokeBallsBerries[] =
|
||||
{
|
||||
ACTION_BY_NAME,
|
||||
ACTION_BY_AMOUNT,
|
||||
ACTION_DUMMY,
|
||||
ACTION_CANCEL,
|
||||
};
|
||||
|
||||
static const u16 sItemsByType[ITEMS_COUNT] =
|
||||
{
|
||||
[ITEM_REPEL] = ITEM_TYPE_FIELD_USE,
|
||||
[ITEM_SUPER_REPEL] = ITEM_TYPE_FIELD_USE,
|
||||
[ITEM_MAX_REPEL] = ITEM_TYPE_FIELD_USE,
|
||||
[ITEM_ESCAPE_ROPE] = ITEM_TYPE_FIELD_USE,
|
||||
[ITEM_HEART_SCALE] = ITEM_TYPE_FIELD_USE,
|
||||
|
||||
[ITEM_POTION] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_FULL_RESTORE] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_MAX_POTION] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_HYPER_POTION] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_SUPER_POTION] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_REVIVE] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_MAX_REVIVE] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_FRESH_WATER] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_SODA_POP] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_LEMONADE] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_MOOMOO_MILK] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_ENERGY_POWDER] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_ENERGY_ROOT] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_REVIVAL_HERB] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_BERRY_JUICE] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
[ITEM_SACRED_ASH] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
|
||||
[ITEM_ANTIDOTE] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_BURN_HEAL] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_ICE_HEAL] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_AWAKENING] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_PARALYZE_HEAL] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_FULL_HEAL] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_LAVA_COOKIE] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
|
||||
[ITEM_ETHER] = ITEM_TYPE_PP_RECOVERY,
|
||||
[ITEM_MAX_ETHER] = ITEM_TYPE_PP_RECOVERY,
|
||||
[ITEM_ELIXIR] = ITEM_TYPE_PP_RECOVERY,
|
||||
[ITEM_MAX_ELIXIR] = ITEM_TYPE_PP_RECOVERY,
|
||||
|
||||
[ITEM_HP_UP] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_PROTEIN] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_IRON] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_CARBOS] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_CALCIUM] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_RARE_CANDY] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_PP_UP] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_ZINC] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_PP_MAX] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
|
||||
[ITEM_MACHO_BRACE] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
|
||||
[ITEM_SUN_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_MOON_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_FIRE_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_THUNDER_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_WATER_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_LEAF_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
|
||||
[ITEM_KINGS_ROCK] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_DEEP_SEA_TOOTH] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_DEEP_SEA_SCALE] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_EVERSTONE] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_METAL_COAT] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_DRAGON_SCALE] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_UP_GRADE] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
|
||||
[ITEM_GUARD_SPEC] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_DIRE_HIT] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_X_ATTACK] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_X_DEFEND] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_X_SPEED] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_X_ACCURACY] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_X_SPECIAL] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_POKE_DOLL] = ITEM_TYPE_BATTLE_ITEM,
|
||||
[ITEM_FLUFFY_TAIL] = ITEM_TYPE_BATTLE_ITEM,
|
||||
|
||||
[ITEM_BRIGHT_POWDER] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_WHITE_HERB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_EXP_SHARE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_QUICK_CLAW] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SOOTHE_BELL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_MENTAL_HERB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_CHOICE_BAND] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SILVER_POWDER] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_AMULET_COIN] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_CLEANSE_TAG] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SOUL_DEW] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SMOKE_BALL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_FOCUS_BAND] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LUCKY_EGG] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SCOPE_LENS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LEFTOVERS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LIGHT_BALL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SOFT_SAND] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_HARD_STONE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_MIRACLE_SEED] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_BLACK_GLASSES] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_BLACK_BELT] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_MAGNET] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_MYSTIC_WATER] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SHARP_BEAK] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_POISON_BARB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_NEVER_MELT_ICE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SPELL_TAG] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_TWISTED_SPOON] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_CHARCOAL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_DRAGON_FANG] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SILK_SCARF] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SHELL_BELL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LUCKY_PUNCH] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_METAL_POWDER] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_THICK_CLUB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_STICK] = ITEM_TYPE_HELD_ITEM,
|
||||
|
||||
[ITEM_SEA_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_LAX_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
|
||||
[ITEM_RED_ORB] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_BLUE_ORB] = ITEM_TYPE_MEGA_STONE,
|
||||
|
||||
[ITEM_BLUE_FLUTE] = ITEM_TYPE_FLUTE,
|
||||
[ITEM_YELLOW_FLUTE] = ITEM_TYPE_FLUTE,
|
||||
[ITEM_RED_FLUTE] = ITEM_TYPE_FLUTE,
|
||||
[ITEM_BLACK_FLUTE] = ITEM_TYPE_FLUTE,
|
||||
[ITEM_WHITE_FLUTE] = ITEM_TYPE_FLUTE,
|
||||
|
||||
[ITEM_SHOAL_SALT] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_SHOAL_SHELL] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_TINY_MUSHROOM] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_BIG_MUSHROOM] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_PEARL] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_BIG_PEARL] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_STARDUST] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_STAR_PIECE] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_NUGGET] = ITEM_TYPE_SELLABLE,
|
||||
|
||||
[ITEM_RED_SHARD] = ITEM_TYPE_SHARD,
|
||||
[ITEM_BLUE_SHARD] = ITEM_TYPE_SHARD,
|
||||
[ITEM_YELLOW_SHARD] = ITEM_TYPE_SHARD,
|
||||
[ITEM_GREEN_SHARD] = ITEM_TYPE_SHARD,
|
||||
|
||||
[ITEM_HELIX_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_DOME_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_OLD_AMBER] = ITEM_TYPE_FOSSIL,
|
||||
|
||||
[ITEM_ORANGE_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_HARBOR_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_GLITTER_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_MECH_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_WOOD_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_WAVE_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_BEAD_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_SHADOW_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_TROPIC_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_DREAM_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_FAB_MAIL] = ITEM_TYPE_MAIL,
|
||||
[ITEM_RETRO_MAIL] = ITEM_TYPE_MAIL,
|
||||
|
||||
#ifdef ITEM_EXPANSION
|
||||
[ITEM_HONEY] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_BIG_MALASADA] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_CASTELIACONE] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_LUMIOSE_GALETTE] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_RAGE_CANDY_BAR] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_SHALOUR_SABLE] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_OLD_GATEAU] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
[ITEM_HEAL_POWDER] = ITEM_TYPE_STATUS_RECOVERY,
|
||||
|
||||
[ITEM_SWEET_HEART] = ITEM_TYPE_HEALTH_RECOVERY,
|
||||
|
||||
[ITEM_ADAMANT_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LUSTROUS_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_GRISEOUS_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_EXPERT_BELT] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_POWER_HERB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_WIDE_LENS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ZOOM_LENS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_DESTINY_KNOT] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SMOOTH_ROCK] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_DAMP_ROCK] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_HEAT_ROCK] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ICY_ROCK] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_BIG_ROOT] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LIGHT_CLAY] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SAFETY_GOGGLES] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ROCKY_HELMET] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_WEAKNESS_POLICY] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ASSAULT_VEST] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_EVIOLITE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ABSORB_BULB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_AIR_BALLOON] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ADRENALINE_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_BINDING_BAND] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_CELL_BATTERY] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_EJECT_BUTTON] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_FLOAT_STONE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_FOCUS_SASH] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_GRIP_CLAW] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_IRON_BALL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LAGGING_TAIL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LUMINOUS_MOSS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_QUICK_POWDER] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_METRONOME] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_MUSCLE_BAND] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_PROTECTIVE_PADS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_RED_CARD] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_RING_TARGET] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SHED_SHELL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_SNOWBALL] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_STICKY_BARB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_TERRAIN_EXTENDER] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_WISE_GLASSES] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ELECTRIC_SEED] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_GRASSY_SEED] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_MISTY_SEED] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_PSYCHIC_SEED] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_LIFE_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_TOXIC_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_FLAME_ORB] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_BLACK_SLUDGE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_CHOICE_SPECS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_CHOICE_SCARF] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_EJECT_PACK] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_ROOM_SERVICE] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_BLUNDER_POLICY] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_HEAVY_DUTY_BOOTS] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_UTILITY_UMBRELLA] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_THROAT_SPRAY] = ITEM_TYPE_HELD_ITEM,
|
||||
[ITEM_FIST_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_SKY_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_TOXIC_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_EARTH_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_STONE_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_INSECT_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_SPOOKY_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_IRON_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_FLAME_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_SPLASH_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_MEADOW_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_ZAP_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_MIND_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_ICICLE_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_DRACO_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_DREAD_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_PIXIE_PLATE] = ITEM_TYPE_PLATE,
|
||||
[ITEM_FIGHTING_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_FLYING_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_POISON_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_GROUND_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_ROCK_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_BUG_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_GHOST_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_STEEL_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_FIRE_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_WATER_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_GRASS_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_ELECTRIC_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_PSYCHIC_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_ICE_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_DRAGON_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_DARK_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_FAIRY_MEMORY] = ITEM_TYPE_MEMORY,
|
||||
[ITEM_BURN_DRIVE] = ITEM_TYPE_DRIVE,
|
||||
[ITEM_DOUSE_DRIVE] = ITEM_TYPE_DRIVE,
|
||||
[ITEM_SHOCK_DRIVE] = ITEM_TYPE_DRIVE,
|
||||
[ITEM_CHILL_DRIVE] = ITEM_TYPE_DRIVE,
|
||||
[ITEM_NORMAL_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_FIGHTING_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_FLYING_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_POISON_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_GROUND_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_ROCK_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_BUG_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_GHOST_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_STEEL_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_FIRE_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_WATER_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_GRASS_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_ELECTRIC_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_PSYCHIC_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_ICE_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_DRAGON_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_DARK_GEM] = ITEM_TYPE_GEM,
|
||||
[ITEM_FAIRY_GEM] = ITEM_TYPE_GEM,
|
||||
|
||||
[ITEM_LUCK_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_FULL_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_ODD_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_PURE_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_ROCK_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_ROSE_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
[ITEM_WAVE_INCENSE] = ITEM_TYPE_INCENSE,
|
||||
|
||||
[ITEM_VENUSAURITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_CHARIZARDITE_X] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_CHARIZARDITE_Y] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_BLASTOISINITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_BEEDRILLITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_PIDGEOTITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_ALAKAZITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SLOWBRONITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_GENGARITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_KANGASKHANITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_PINSIRITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_GYARADOSITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_AERODACTYLITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_MEWTWONITE_X] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_MEWTWONITE_Y] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_AMPHAROSITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_STEELIXITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SCIZORITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_HERACRONITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_HOUNDOOMINITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_TYRANITARITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SCEPTILITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_BLAZIKENITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SWAMPERTITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_GARDEVOIRITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SABLENITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_MAWILITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_AGGRONITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_MEDICHAMITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_MANECTITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SHARPEDONITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_CAMERUPTITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_ALTARIANITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_BANETTITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_ABSOLITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_GLALITITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_SALAMENCITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_METAGROSSITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_LATIASITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_LATIOSITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_LOPUNNITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_GARCHOMPITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_LUCARIONITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_ABOMASITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_GALLADITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_AUDINITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_DIANCITE] = ITEM_TYPE_MEGA_STONE,
|
||||
[ITEM_ULTRANECROZIUM_Z] = ITEM_TYPE_MEGA_STONE,
|
||||
|
||||
[ITEM_NORMALIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_FIGHTINIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_FLYINIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_POISONIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_GROUNDIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_ROCKIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_BUGINIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_GHOSTIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_STEELIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_FIRIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_WATERIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_GRASSIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_ELECTRIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_PSYCHIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_ICIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_DRAGONIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_DARKINIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_FAIRIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_ALORAICHIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_DECIDIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_EEVIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_INCINIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_KOMMONIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_LUNALIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_LYCANIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_MARSHADIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_MEWNIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_MIMIKIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_PIKANIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_PIKASHUNIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_PRIMARIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_SNORLIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_SOLGANIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
[ITEM_TAPUNIUM_Z] = ITEM_TYPE_Z_CRYSTAL,
|
||||
|
||||
[ITEM_RED_NECTAR] = ITEM_TYPE_NECTAR,
|
||||
[ITEM_YELLOW_NECTAR] = ITEM_TYPE_NECTAR,
|
||||
[ITEM_PINK_NECTAR] = ITEM_TYPE_NECTAR,
|
||||
[ITEM_PURPLE_NECTAR] = ITEM_TYPE_NECTAR,
|
||||
|
||||
[ITEM_ABILITY_CAPSULE] = ITEM_TYPE_STAT_BOOST_DRINK,
|
||||
[ITEM_HEALTH_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
[ITEM_MUSCLE_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
[ITEM_RESIST_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
[ITEM_GENIUS_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
[ITEM_CLEVER_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
[ITEM_SWIFT_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
[ITEM_PRETTY_FEATHER] = ITEM_TYPE_STAT_BOOST_FEATHER,
|
||||
|
||||
[ITEM_POWER_BRACER] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
[ITEM_POWER_BELT] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
[ITEM_POWER_LENS] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
[ITEM_POWER_BAND] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
[ITEM_POWER_ANKLET] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
[ITEM_POWER_WEIGHT] = ITEM_TYPE_STAT_BOOST_HELD_ITEM,
|
||||
|
||||
[ITEM_DAWN_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_DUSK_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_SHINY_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_ICE_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
[ITEM_OVAL_STONE] = ITEM_TYPE_EVOLUTION_STONE,
|
||||
|
||||
[ITEM_PROTECTOR] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_MAGMARIZER] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_PRISM_SCALE] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_SACHET] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_WHIPPED_DREAM] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_RAZOR_CLAW] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_RAZOR_FANG] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_REAPER_CLOTH] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_DUBIOUS_DISC] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
[ITEM_ELECTIRIZER] = ITEM_TYPE_EVOLUTION_ITEM,
|
||||
|
||||
[ITEM_RARE_BONE] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_PEARL_STRING] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_BIG_NUGGET] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_COMET_SHARD] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_BALM_MUSHROOM] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_ODD_KEYSTONE] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_BOTTLE_CAP] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_GOLD_BOTTLE_CAP] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_WISHING_PIECE] = ITEM_TYPE_SELLABLE,
|
||||
[ITEM_RELIC_COPPER] = ITEM_TYPE_RELIC,
|
||||
[ITEM_RELIC_SILVER] = ITEM_TYPE_RELIC,
|
||||
[ITEM_RELIC_GOLD] = ITEM_TYPE_RELIC,
|
||||
[ITEM_RELIC_VASE] = ITEM_TYPE_RELIC,
|
||||
[ITEM_RELIC_BAND] = ITEM_TYPE_RELIC,
|
||||
[ITEM_RELIC_STATUE] = ITEM_TYPE_RELIC,
|
||||
[ITEM_RELIC_CROWN] = ITEM_TYPE_RELIC,
|
||||
|
||||
[ITEM_ROOT_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_CLAW_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_SKULL_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_ARMOR_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_COVER_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_PLUME_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_JAW_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
[ITEM_SAIL_FOSSIL] = ITEM_TYPE_FOSSIL,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void AddBagSortSubMenu(void)
|
||||
{
|
||||
switch (gBagPosition.pocket + 1)
|
||||
{
|
||||
case POCKET_KEY_ITEMS:
|
||||
gBagMenu->contextMenuItemsPtr = sBagMenuSortKeyItems;
|
||||
memcpy(&gBagMenu->contextMenuItemsBuffer, &sBagMenuSortKeyItems, NELEMS(sBagMenuSortKeyItems));
|
||||
gBagMenu->contextMenuNumItems = NELEMS(sBagMenuSortKeyItems);
|
||||
break;
|
||||
case POCKET_POKE_BALLS:
|
||||
case POCKET_BERRIES:
|
||||
case POCKET_TM_HM:
|
||||
gBagMenu->contextMenuItemsPtr = sBagMenuSortPokeBallsBerries;
|
||||
memcpy(&gBagMenu->contextMenuItemsBuffer, &sBagMenuSortPokeBallsBerries, NELEMS(sBagMenuSortPokeBallsBerries));
|
||||
gBagMenu->contextMenuNumItems = NELEMS(sBagMenuSortPokeBallsBerries);
|
||||
break;
|
||||
default:
|
||||
gBagMenu->contextMenuItemsPtr = sBagMenuSortItems;
|
||||
memcpy(&gBagMenu->contextMenuItemsBuffer, &sBagMenuSortItems, NELEMS(sBagMenuSortItems));
|
||||
gBagMenu->contextMenuNumItems = NELEMS(sBagMenuSortItems);
|
||||
break;
|
||||
}
|
||||
|
||||
StringExpandPlaceholders(gStringVar4, sText_SortItemsHow);
|
||||
FillWindowPixelBuffer(1, PIXEL_FILL(0));
|
||||
BagMenu_Print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
|
||||
|
||||
if (gBagMenu->contextMenuNumItems == 2)
|
||||
PrintContextMenuItems(BagMenu_AddWindow(ITEMWIN_1x2));
|
||||
else if (gBagMenu->contextMenuNumItems == 4)
|
||||
PrintContextMenuItemGrid(BagMenu_AddWindow(ITEMWIN_2x2), 2, 2);
|
||||
else
|
||||
PrintContextMenuItemGrid(BagMenu_AddWindow(ITEMWIN_2x3), 2, 3);
|
||||
}
|
||||
|
||||
static void Task_LoadBagSortOptions(u8 taskId)
|
||||
{
|
||||
AddBagSortSubMenu();
|
||||
if (gBagMenu->contextMenuNumItems <= 2)
|
||||
gTasks[taskId].func = Task_ItemContext_SingleRow;
|
||||
else
|
||||
gTasks[taskId].func = Task_ItemContext_MultipleRows;
|
||||
}
|
||||
|
||||
#define tSortType data[2]
|
||||
static void ItemMenu_SortByName(u8 taskId)
|
||||
{
|
||||
gTasks[taskId].tSortType = SORT_ALPHABETICALLY;
|
||||
StringCopy(gStringVar1, sSortTypeStrings[SORT_ALPHABETICALLY]);
|
||||
gTasks[taskId].func = SortBagItems;
|
||||
}
|
||||
static void ItemMenu_SortByType(u8 taskId)
|
||||
{
|
||||
gTasks[taskId].tSortType = SORT_BY_TYPE;
|
||||
StringCopy(gStringVar1, sSortTypeStrings[SORT_BY_TYPE]);
|
||||
gTasks[taskId].func = SortBagItems;
|
||||
}
|
||||
static void ItemMenu_SortByAmount(u8 taskId)
|
||||
{
|
||||
gTasks[taskId].tSortType = SORT_BY_AMOUNT; //greatest->least
|
||||
StringCopy(gStringVar1, sSortTypeStrings[SORT_BY_AMOUNT]);
|
||||
gTasks[taskId].func = SortBagItems;
|
||||
}
|
||||
|
||||
static void SortBagItems(u8 taskId)
|
||||
{
|
||||
s16 *data = gTasks[taskId].data;
|
||||
u16 *scrollPos = &gBagPosition.scrollPosition[gBagPosition.pocket];
|
||||
u16 *cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
|
||||
|
||||
RemoveContextWindow();
|
||||
|
||||
SortItemsInBag(gBagPosition.pocket, tSortType);
|
||||
DestroyListMenuTask(data[0], scrollPos, cursorPos);
|
||||
UpdatePocketListPosition(gBagPosition.pocket);
|
||||
LoadBagItemListBuffers(gBagPosition.pocket);
|
||||
data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
|
||||
ScheduleBgCopyTilemapToVram(0);
|
||||
|
||||
StringCopy(gStringVar1, sSortTypeStrings[tSortType]);
|
||||
StringExpandPlaceholders(gStringVar4, sText_ItemsSorted);
|
||||
DisplayItemMessage(taskId, 1, gStringVar4, Task_SortFinish);
|
||||
}
|
||||
|
||||
static void Task_SortFinish(u8 taskId)
|
||||
{
|
||||
s16* data = gTasks[taskId].data;
|
||||
|
||||
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
|
||||
{
|
||||
RemoveItemMessageWindow(4);
|
||||
ReturnToItemList(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
static void SortItemsInBag(u8 pocket, u8 type)
|
||||
{
|
||||
struct ItemSlot* itemMem;
|
||||
u16 itemAmount;
|
||||
s8 (*func)(struct ItemSlot*, struct ItemSlot*);
|
||||
|
||||
switch (pocket)
|
||||
{
|
||||
case ITEMS_POCKET:
|
||||
itemMem = gSaveBlock1Ptr->bagPocket_Items;
|
||||
itemAmount = BAG_ITEMS_COUNT;
|
||||
break;
|
||||
case KEYITEMS_POCKET:
|
||||
itemMem = gSaveBlock1Ptr->bagPocket_KeyItems;
|
||||
itemAmount = BAG_KEYITEMS_COUNT;
|
||||
break;
|
||||
case BALLS_POCKET:
|
||||
itemMem = gSaveBlock1Ptr->bagPocket_PokeBalls;
|
||||
itemAmount = BAG_POKEBALLS_COUNT;
|
||||
break;
|
||||
case BERRIES_POCKET:
|
||||
itemMem = gSaveBlock1Ptr->bagPocket_Berries;
|
||||
itemAmount = BAG_BERRIES_COUNT;
|
||||
break;
|
||||
case TMHM_POCKET:
|
||||
itemMem = gSaveBlock1Ptr->bagPocket_TMHM;
|
||||
itemAmount = BAG_TMHM_COUNT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SORT_ALPHABETICALLY:
|
||||
MergeSort(itemMem, 0, itemAmount - 1, CompareItemsAlphabetically);
|
||||
break;
|
||||
case SORT_BY_AMOUNT:
|
||||
MergeSort(itemMem, 0, itemAmount - 1, CompareItemsByMost);
|
||||
break;
|
||||
default:
|
||||
MergeSort(itemMem, 0, itemAmount - 1, CompareItemsByType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void MergeSort(struct ItemSlot* array, u32 low, u32 high, s8 (*comparator)(struct ItemSlot*, struct ItemSlot*))
|
||||
{
|
||||
u32 mid;
|
||||
|
||||
if (high <= low)
|
||||
return;
|
||||
|
||||
mid = low + (high - low) / 2;
|
||||
MergeSort(array, low, mid, comparator); //Sort left half.
|
||||
MergeSort(array, mid + 1, high, comparator); //Sort right half.
|
||||
Merge(array, low, mid, high, comparator); //Merge results.
|
||||
}
|
||||
|
||||
static void Merge(struct ItemSlot* array, u32 low, u32 mid, u32 high, s8 (*comparator)(struct ItemSlot*, struct ItemSlot*))
|
||||
{
|
||||
u32 i = low;
|
||||
u32 j = mid + 1;
|
||||
u32 k;
|
||||
struct ItemSlot aux[high + 1];
|
||||
|
||||
for (k = low; k <= high; ++k)
|
||||
aux[k] = array[k];
|
||||
|
||||
for (k = low; k <= high; ++k)
|
||||
{ //Merge back to a[low..high]
|
||||
if (i > mid)
|
||||
array[k] = aux[j++];
|
||||
else if (j > high)
|
||||
array[k] = aux[i++];
|
||||
else if (comparator(&aux[j], &aux[i]) < 0)
|
||||
array[k] = aux[j++];
|
||||
else
|
||||
array[k] = aux[i++];
|
||||
}
|
||||
}
|
||||
|
||||
static s8 CompareItemsAlphabetically(struct ItemSlot* itemSlot1, struct ItemSlot* itemSlot2)
|
||||
{
|
||||
u16 item1 = itemSlot1->itemId;
|
||||
u16 item2 = itemSlot2->itemId;
|
||||
int i;
|
||||
const u8 *name1;
|
||||
const u8 *name2;
|
||||
|
||||
if (item1 == ITEM_NONE)
|
||||
return 1;
|
||||
else if (item2 == ITEM_NONE)
|
||||
return -1;
|
||||
|
||||
name1 = ItemId_GetName(item1);
|
||||
name2 = ItemId_GetName(item2);
|
||||
|
||||
for (i = 0; ; ++i)
|
||||
{
|
||||
if (name1[i] == EOS && name2[i] != EOS)
|
||||
return -1;
|
||||
else if (name1[i] != EOS && name2[i] == EOS)
|
||||
return 1;
|
||||
else if (name1[i] == EOS && name2[i] == EOS)
|
||||
return 0;
|
||||
|
||||
if (name1[i] < name2[i])
|
||||
return -1;
|
||||
else if (name1[i] > name2[i])
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0; //Will never be reached
|
||||
}
|
||||
|
||||
static s8 CompareItemsByMost(struct ItemSlot* itemSlot1, struct ItemSlot* itemSlot2)
|
||||
{
|
||||
u16 quantity1 = GetBagItemQuantity(&itemSlot1->quantity);
|
||||
u16 quantity2 = GetBagItemQuantity(&itemSlot2->quantity);
|
||||
|
||||
if (itemSlot1->itemId == ITEM_NONE)
|
||||
return 1;
|
||||
else if (itemSlot2->itemId == ITEM_NONE)
|
||||
return -1;
|
||||
|
||||
if (quantity1 < quantity2)
|
||||
return 1;
|
||||
else if (quantity1 > quantity2)
|
||||
return -1;
|
||||
|
||||
return CompareItemsAlphabetically(itemSlot1, itemSlot2); //Items have same quantity so sort alphabetically
|
||||
}
|
||||
|
||||
static s8 CompareItemsByType(struct ItemSlot* itemSlot1, struct ItemSlot* itemSlot2)
|
||||
{
|
||||
//Null items go last
|
||||
u8 type1 = (itemSlot1->itemId == ITEM_NONE) ? 0xFF : sItemsByType[itemSlot1->itemId];
|
||||
u8 type2 = (itemSlot2->itemId == ITEM_NONE) ? 0xFF : sItemsByType[itemSlot2->itemId];
|
||||
|
||||
if (type1 < type2)
|
||||
return -1;
|
||||
else if (type1 > type2)
|
||||
return 1;
|
||||
|
||||
return CompareItemsAlphabetically(itemSlot1, itemSlot2); //Items are of same type so sort alphabetically
|
||||
}
|
Reference in New Issue
Block a user