* Expanded the amount of max items per stack from 99 to 999 * Set Battle Pyramid Bag stack limit back to 99 This commit exists for archival purposes. People who may want to set the limit of item stacks in the Battle Pyramid's bag to 999 can refer to its code diff. * Reintroduced the Battle Pyramid changes through a MAX_PYRAMID_BAG_ITEM_CAPACITY constant * Gave 3 digit support to the Battle Pyramid's bag * Rewrote the comment for MAX_PYRAMID_BAG_ITEM_CAPACITY * Made DebugAction_Give_Item_SelectQuantity use MAX_ITEM_DIGITS * Ditched BERRY_CAPACITY_DIGITS and BAG_ITEM_CAPACITY_DIGITS * Removed MAX_BERRY_CAPACITY No point in keeping it if we're making all item stacks cap at 999. * Applied review corrections * Removed pointless local var in DebugAction_Give_Item_SelectQuantity * Defined a MAX_PYRAMID_ITEM_DIGITS * Cleaned up some of the functions in which MAX_ITEM_DIGITS is used Summary: -Removed pointless local variables in CheckBagHasSpace, AddBagItem, PrintItemQuantity and PrintItemSoldAmount. -Removed pointless brackets in an if statement of CheckBagHasSpace. -Initialized the pocket local variable of CheckBagHasSpace from the get go to save a few lines too. --------- Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com>
2628 lines
84 KiB
C
Executable File
2628 lines
84 KiB
C
Executable File
#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_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 {
|
|
u8 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(u8 *, 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);
|
|
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);
|
|
static void Task_FadeAndCloseBagMenuIfMulch(u8 taskId);
|
|
|
|
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 = WIN_ITEM_LIST,
|
|
.header_X = 0,
|
|
.item_X = 8,
|
|
.cursor_X = 0,
|
|
.upText_Y = 1,
|
|
.cursorPal = 1,
|
|
.fillValue = 0,
|
|
.cursorShadowPal = 3,
|
|
.lettersSpacing = 0,
|
|
.itemVerticalPadding = 0,
|
|
.scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
|
|
.fontId = FONT_NARROW,
|
|
.cursorKind = CURSOR_BLACK_ARROW
|
|
};
|
|
|
|
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_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,
|
|
[ITEMMENULOCATION_BERRY_TREE_MULCH] = Task_FadeAndCloseBagMenuIfMulch,
|
|
};
|
|
|
|
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/bag/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 mulch to use
|
|
void CB2_ChooseMulch(void)
|
|
{
|
|
GoToBagMenu(ITEMMENULOCATION_BERRY_TREE_MULCH, ITEMS_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 ||
|
|
gBagPosition.location == ITEMMENULOCATION_BERRY_TREE_MULCH)
|
|
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, BG_PLTT_ID(0), 2 * PLTT_SIZE_4BPP);
|
|
else
|
|
LoadCompressedPalette(gBagScreenMale_Pal, BG_PLTT_ID(0), 2 * PLTT_SIZE_4BPP);
|
|
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(u8 *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(ITEM_LIST_END, 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 != KEYITEMS_POCKET && ItemId_GetImportance(itemId) == FALSE)
|
|
{
|
|
// Print item quantity
|
|
ConvertIntToDecimalStringN(gStringVar1, itemQuantity, STR_CONV_MODE_RIGHT_ALIGN, MAX_ITEM_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 != ITEM_NONE && 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_FadeAndCloseBagMenuIfMulch(u8 taskId)
|
|
{
|
|
if (gSpecialVar_ItemId == ITEM_GROWTH_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_DAMP_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_STABLE_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_GOOEY_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_RICH_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_SURPRISE_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_BOOST_MULCH ||
|
|
gSpecialVar_ItemId == ITEM_AMAZE_MULCH)
|
|
{
|
|
Task_FadeAndCloseBagMenu(taskId);
|
|
return;
|
|
}
|
|
DisplayDadsAdviceCannotUseItemMessage(taskId, FALSE);
|
|
}
|
|
|
|
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)
|
|
{
|
|
ConvertIntToDecimalStringN(gStringVar1, quantity, STR_CONV_MODE_LEADING_ZEROS, MAX_ITEM_DIGITS);
|
|
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)
|
|
{
|
|
ConvertIntToDecimalStringN(gStringVar1, numSold, STR_CONV_MODE_LEADING_ZEROS, MAX_ITEM_DIGITS);
|
|
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;
|
|
}
|
|
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, TRUE);
|
|
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_E_READER)
|
|
{
|
|
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_E_READER)
|
|
{
|
|
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_E_READER)
|
|
{
|
|
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:
|
|
case ITEMMENULOCATION_BERRY_TREE_MULCH:
|
|
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 = ITEM_NONE;
|
|
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)
|
|
{
|
|
// Safety check
|
|
u16 type = ItemId_GetType(gSpecialVar_ItemId);
|
|
if (!ItemId_GetBattleUsage(gSpecialVar_ItemId))
|
|
return;
|
|
|
|
RemoveContextWindow();
|
|
if (type == ITEM_USE_BAG_MENU)
|
|
ItemUseInBattle_BagMenu(taskId);
|
|
else if (type == ITEM_USE_PARTY_MENU)
|
|
ItemUseInBattle_PartyMenu(taskId);
|
|
else if (type == ITEM_USE_PARTY_MENU_MOVES)
|
|
ItemUseInBattle_PartyMenuChooseMove(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)
|
|
{
|
|
LockPlayerFieldControls();
|
|
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;
|
|
}
|
|
}
|
|
ScriptContext_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_GetImportance(gSpecialVar_ItemId))
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if I_SELL_VALUE_FRACTION >= GEN_9
|
|
#define ITEM_SELL_FACTOR 4
|
|
#else
|
|
#define ITEM_SELL_FACTOR 2
|
|
#endif
|
|
|
|
static void DisplaySellItemPriceAndConfirm(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
ConvertIntToDecimalStringN(gStringVar1, (ItemId_GetPrice(gSpecialVar_ItemId) / ITEM_SELL_FACTOR) * 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) / ITEM_SELL_FACTOR) * 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) / ITEM_SELL_FACTOR) * 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) / ITEM_SELL_FACTOR) * 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) / ITEM_SELL_FACTOR) * 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_ScriptContext_Enable;
|
|
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, BG_PLTT_ID(14));
|
|
LoadMessageBoxGfx(0, 10, BG_PLTT_ID(13));
|
|
ListMenuLoadStdPalAt(BG_PLTT_ID(12), 1);
|
|
LoadPalette(&gStandardMenuPalette, BG_PLTT_ID(15), PLTT_SIZE_4BPP);
|
|
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);
|
|
}
|
|
|
|
static u8 UNUSED 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, FALSE, 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);
|
|
}
|
|
}
|