mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-18 12:37:38 +01:00
7632 lines
235 KiB
C
Executable File
7632 lines
235 KiB
C
Executable File
#include "global.h"
|
|
#include "malloc.h"
|
|
#include "battle.h"
|
|
#include "battle_anim.h"
|
|
#include "battle_controllers.h"
|
|
#include "battle_gfx_sfx_util.h"
|
|
#include "battle_interface.h"
|
|
#include "battle_pike.h"
|
|
#include "battle_pyramid.h"
|
|
#include "battle_pyramid_bag.h"
|
|
#include "bg.h"
|
|
#include "contest.h"
|
|
#include "data.h"
|
|
#include "decompress.h"
|
|
#include "easy_chat.h"
|
|
#include "event_data.h"
|
|
#include "evolution_scene.h"
|
|
#include "field_control_avatar.h"
|
|
#include "field_effect.h"
|
|
#include "field_player_avatar.h"
|
|
#include "field_screen_effect.h"
|
|
#include "field_specials.h"
|
|
#include "field_weather.h"
|
|
#include "fieldmap.h"
|
|
#include "fldeff.h"
|
|
#include "fldeff_misc.h"
|
|
#include "frontier_util.h"
|
|
#include "gpu_regs.h"
|
|
#include "graphics.h"
|
|
#include "international_string_util.h"
|
|
#include "item.h"
|
|
#include "item_menu.h"
|
|
#include "item_use.h"
|
|
#include "link.h"
|
|
#include "link_rfu.h"
|
|
#include "mail.h"
|
|
#include "main.h"
|
|
#include "menu.h"
|
|
#include "menu_helpers.h"
|
|
#include "menu_specialized.h"
|
|
#include "metatile_behavior.h"
|
|
#include "overworld.h"
|
|
#include "palette.h"
|
|
#include "party_menu.h"
|
|
#include "player_pc.h"
|
|
#include "pokemon.h"
|
|
#include "pokemon_icon.h"
|
|
#include "pokemon_jump.h"
|
|
#include "pokemon_storage_system.h"
|
|
#include "pokemon_summary_screen.h"
|
|
#include "region_map.h"
|
|
#include "reshow_battle_screen.h"
|
|
#include "scanline_effect.h"
|
|
#include "script.h"
|
|
#include "sound.h"
|
|
#include "sprite.h"
|
|
#include "start_menu.h"
|
|
#include "string_util.h"
|
|
#include "strings.h"
|
|
#include "task.h"
|
|
#include "text.h"
|
|
#include "text_window.h"
|
|
#include "trade.h"
|
|
#include "union_room.h"
|
|
#include "window.h"
|
|
#include "constants/battle.h"
|
|
#include "constants/battle_frontier.h"
|
|
#include "constants/easy_chat.h"
|
|
#include "constants/field_effects.h"
|
|
#include "constants/flags.h"
|
|
#include "constants/item_effects.h"
|
|
#include "constants/items.h"
|
|
#include "constants/maps.h"
|
|
#include "constants/moves.h"
|
|
#include "constants/party_menu.h"
|
|
#include "constants/rgb.h"
|
|
#include "constants/songs.h"
|
|
#include "constants/species.h"
|
|
#include "constants/vars.h"
|
|
|
|
#define PARTY_PAL_SELECTED (1 << 0)
|
|
#define PARTY_PAL_FAINTED (1 << 1)
|
|
#define PARTY_PAL_TO_SWITCH (1 << 2)
|
|
#define PARTY_PAL_MULTI_ALT (1 << 3)
|
|
#define PARTY_PAL_SWITCHING (1 << 4)
|
|
#define PARTY_PAL_TO_SOFTBOIL (1 << 5)
|
|
#define PARTY_PAL_NO_MON (1 << 6)
|
|
#define PARTY_PAL_UNUSED (1 << 7)
|
|
|
|
enum
|
|
{
|
|
CAN_LEARN_MOVE,
|
|
CANNOT_LEARN_MOVE,
|
|
ALREADY_KNOWS_MOVE,
|
|
CANNOT_LEARN_MOVE_IS_EGG
|
|
};
|
|
|
|
struct PartyMenuBoxInfoRects
|
|
{
|
|
void (*blitFunc)(u8, u8, u8, u8, u8, u8);
|
|
u8 dimensions[24];
|
|
u8 descTextLeft;
|
|
u8 descTextTop;
|
|
u8 descTextWidth;
|
|
u8 descTextHeight;
|
|
};
|
|
|
|
struct PartyMenuInternal
|
|
{
|
|
TaskFunc task;
|
|
MainCallback exitCallback;
|
|
u32 chooseHalf:1;
|
|
u32 unk8_1:3;
|
|
u32 spriteIdConfirmPokeball:7;
|
|
u32 spriteIdCancelPokeball:7;
|
|
u32 messageId:14;
|
|
u8 windowId[3];
|
|
u8 actions[8];
|
|
u8 numActions;
|
|
// In vanilla Emerald, only the first 0xB0 hwords (0x160 bytes) are actually used.
|
|
// However, a full 0x100 hwords (0x200 bytes) are allocated.
|
|
// It is likely that the 0x160 value used below is a constant defined by
|
|
// bin2c, the utility used to encode the compressed palette data.
|
|
u16 palBuffer[BG_PLTT_SIZE / sizeof(u16)];
|
|
s16 data[16];
|
|
};
|
|
|
|
struct PartyMenuBox
|
|
{
|
|
const struct PartyMenuBoxInfoRects *infoRects;
|
|
const u8 *spriteCoords;
|
|
u8 windowId;
|
|
u8 monSpriteId;
|
|
u8 itemSpriteId;
|
|
u8 pokeballSpriteId;
|
|
u8 statusSpriteId;
|
|
};
|
|
|
|
// EWRAM vars
|
|
static EWRAM_DATA struct PartyMenuInternal *sPartyMenuInternal = NULL;
|
|
EWRAM_DATA struct PartyMenu gPartyMenu = {0};
|
|
static EWRAM_DATA struct PartyMenuBox *sPartyMenuBoxes = NULL;
|
|
static EWRAM_DATA u8 *sPartyBgGfxTilemap = NULL;
|
|
static EWRAM_DATA u8 *sPartyBgTilemapBuffer = NULL;
|
|
EWRAM_DATA bool8 gUnknown_0203CEE8 = 0; // executed party action -ish
|
|
EWRAM_DATA u8 gUnknown_0203CEE9 = 0; // party id for something
|
|
EWRAM_DATA MainCallback gPostMenuFieldCallback = NULL;
|
|
static EWRAM_DATA u16 *sSlot1TilemapBuffer = 0; // for switching party slots
|
|
static EWRAM_DATA u16 *sSlot2TilemapBuffer = 0; //
|
|
EWRAM_DATA u8 gSelectedOrderFromParty[4] = {0};
|
|
static EWRAM_DATA u16 sPartyMenuItemId = 0;
|
|
static EWRAM_DATA u16 sUnused_0203CEFE = 0;
|
|
EWRAM_DATA u8 gBattlePartyCurrentOrder[3] = {0}; // bits 0-3 are the current pos of Slot 1, 4-7 are Slot 2, and so on
|
|
|
|
// IWRAM common
|
|
void (*gItemUseCB)(u8, TaskFunc);
|
|
|
|
static void ResetPartyMenu(void);
|
|
static void CB2_InitPartyMenu(void);
|
|
static bool8 ShowPartyMenu(void);
|
|
static void SetPartyMonsAllowedInMinigame(void);
|
|
static void ExitPartyMenu(void);
|
|
static bool8 AllocPartyMenuBg(void);
|
|
static bool8 AllocPartyMenuBgGfx(void);
|
|
static void InitPartyMenuWindows(u8);
|
|
static void InitPartyMenuBoxes(u8);
|
|
static void LoadPartyMenuPokeballGfx(void);
|
|
static void LoadPartyMenuAilmentGfx(void);
|
|
static bool8 party_menu_add_per_mon_objects(void);
|
|
static bool8 RenderPartyMenuBoxes(void);
|
|
static void CreateCancelConfirmPokeballSprites(void);
|
|
static void sub_81B2428(u8);
|
|
static void Task_ExitPartyMenu(u8);
|
|
static void FreePartyPointers(void);
|
|
static void PartyPaletteBufferCopy(u8);
|
|
static void DisplayPartyPokemonDataForMultiBattle(u8);
|
|
static void LoadPartyBoxPalette(struct PartyMenuBox *, u8);
|
|
static void DrawEmptySlot(u8 windowId);
|
|
static void DisplayPartyPokemonDataForRelearner(u8);
|
|
static void DisplayPartyPokemonDataForContest(u8);
|
|
static void DisplayPartyPokemonDataForChooseHalf(u8);
|
|
static void DisplayPartyPokemonDataForWirelessMinigame(u8);
|
|
static void DisplayPartyPokemonDataForBattlePyramidHeldItem(u8);
|
|
static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8);
|
|
static void DisplayPartyPokemonData(u8);
|
|
static void DisplayPartyPokemonNickname(struct Pokemon *, struct PartyMenuBox *, u8);
|
|
static void DisplayPartyPokemonLevelCheck(struct Pokemon *, struct PartyMenuBox *, u8);
|
|
static void DisplayPartyPokemonGenderNidoranCheck(struct Pokemon *, struct PartyMenuBox *, u8);
|
|
static void DisplayPartyPokemonHPCheck(struct Pokemon *, struct PartyMenuBox *, u8);
|
|
static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *, struct PartyMenuBox *, u8);
|
|
static void DisplayPartyPokemonHPBarCheck(struct Pokemon *, struct PartyMenuBox *);
|
|
static void DisplayPartyPokemonDescriptionText(u8, struct PartyMenuBox *, u8);
|
|
static bool8 IsMonAllowedInMinigame(u8);
|
|
static void DisplayPartyPokemonDataToTeachMove(u8, u16, u8);
|
|
static u8 CanMonLearnTMTutor(struct Pokemon *, u16, u8);
|
|
static void DisplayPartyPokemonBarDetail(u8, const u8*, u8, const u8*);
|
|
static void DisplayPartyPokemonLevel(u8, struct PartyMenuBox *);
|
|
static void DisplayPartyPokemonGender(u8, u16, u8*, struct PartyMenuBox *);
|
|
static void DisplayPartyPokemonHP(u16, struct PartyMenuBox *);
|
|
static void DisplayPartyPokemonMaxHP(u16, struct PartyMenuBox *);
|
|
static void DisplayPartyPokemonHPBar(u16, u16, struct PartyMenuBox *);
|
|
static void party_menu_link_mon_icon_anim(u16, u32, struct PartyMenuBox *, u8, u32);
|
|
static void party_menu_link_mon_held_item_object(u16, u16, struct PartyMenuBox *);
|
|
static void party_menu_link_mon_pokeball_object(u16, struct PartyMenuBox *);
|
|
static void party_menu_link_mon_status_condition_object(u16, u8, struct PartyMenuBox *);
|
|
static void party_menu_held_item_object(struct Pokemon *, struct PartyMenuBox *);
|
|
static void party_menu_pokeball_object(struct Pokemon *, struct PartyMenuBox *);
|
|
static void party_menu_icon_anim(struct Pokemon *, struct PartyMenuBox *, u32);
|
|
static void party_menu_status_condition_object(struct Pokemon *, struct PartyMenuBox *);
|
|
static u8 CreateMenuPokeballSprite(u8, u8);
|
|
static void sub_81B120C(void);
|
|
static u8 CreateCancelPokeballSprite(u8, u8);
|
|
static void AnimateSelectedPartyIcon(u8, u8);
|
|
static void PartyMenuStartSpriteAnim(u8, u8);
|
|
static u8 GetPartyBoxPaletteFlags(u8, u8);
|
|
static bool8 PartyBoxPal_ParnterOrDisqualifiedInArena(u8);
|
|
static u8 GetPartyIdFromBattleSlot(u8);
|
|
static void Task_ClosePartyMenuAndSetCB2(u8);
|
|
static void UpdatePartyToFieldOrder(void);
|
|
static void sub_81B4F88(void);
|
|
static void HandleChooseMonCancel(u8, s8*);
|
|
static void HandleChooseMonSelection(u8, s8*);
|
|
static u16 PartyMenuButtonHandler(s8*);
|
|
static s8* GetCurrentPartySlotPtr(void);
|
|
static bool8 IsSelectedMonNotEgg(u8*);
|
|
static void PartyMenuRemoveWindow(u8*);
|
|
static void CB2_SetUpExitToBattleScreen(void);
|
|
static void Task_ClosePartyMenuAfterText(u8);
|
|
static void TryTutorSelectedMon(u8);
|
|
static void TryGiveMailToSelectedMon(u8);
|
|
static void TryGiveItemToSelectedMon(u8);
|
|
static void SwitchSelectedMons(u8);
|
|
static void TryEnterMonForMinigame(u8, u8);
|
|
static void Task_TryCreateSelectionWindow(u8);
|
|
static void FinishTwoMonAction(u8);
|
|
static void CancelParticipationPrompt(u8);
|
|
static bool8 DisplayCancelChooseMonYesNo(u8);
|
|
static const u8* GetFacilityCancelString(void);
|
|
static void Task_CancelChooseMonYesNo(u8);
|
|
static void PartyMenuDisplayYesNoMenu(void);
|
|
static void Task_HandleCancelChooseMonYesNoInput(u8);
|
|
static void Task_ReturnToChooseMonAfterText(u8);
|
|
static void UpdateCurrentPartySelection(s8*, s8);
|
|
static void UpdatePartySelectionSingleLayout(s8*, s8);
|
|
static void UpdatePartySelectionDoubleLayout(s8*, s8);
|
|
static s8 sub_81B1B00(s8, s8);
|
|
static void PartyMenuPrintText(const u8*);
|
|
static void Task_PrintAndWaitForText(u8);
|
|
static bool16 IsMonAllowedInPokemonJump(struct Pokemon*);
|
|
static bool16 IsMonAllowedInDodrioBerryPicking(struct Pokemon*);
|
|
static void Task_CancelParticipationYesNo(u8);
|
|
static void Task_HandleCancelParticipationYesNoInput(u8);
|
|
static bool8 CanLearnTutorMove(u16, u8);
|
|
static u16 GetTutorMove(u8);
|
|
static bool8 sub_81B314C(void);
|
|
static void SetPartyMonFieldSelectionActions(struct Pokemon*, u8);
|
|
static u8 GetPartyMenuActionsTypeInBattle(struct Pokemon*);
|
|
static u8 GetPartySlotEntryStatus(s8);
|
|
static void Task_UpdateHeldItemSprite(u8);
|
|
static void Task_HandleSelectionMenuInput(u8);
|
|
static void CB2_ShowPokemonSummaryScreen(void);
|
|
static void UpdatePartyToBattleOrder(void);
|
|
static void CB2_ReturnToPartyMenuFromSummaryScreen(void);
|
|
static void SlidePartyMenuBoxOneStep(u8);
|
|
static void Task_SlideSelectedSlotsOffscreen(u8);
|
|
static void SwitchPartyMon(void);
|
|
static void Task_SlideSelectedSlotsOnscreen(u8);
|
|
static void CB2_SelectBagItemToGive(void);
|
|
static void CB2_GiveHoldItem(void);
|
|
static void CB2_WriteMailToGiveMon(void);
|
|
static void Task_SwitchHoldItemsPrompt(u8);
|
|
static void Task_GiveHoldItem(u8);
|
|
static void Task_SwitchItemsYesNo(u8);
|
|
static void Task_HandleSwitchItemsYesNoInput(u8);
|
|
static void Task_WriteMailToGiveMonAfterText(u8);
|
|
static void CB2_ReturnToPartyMenuFromWritingMail(void);
|
|
static void sub_81B4624(u8);
|
|
static void UpdatePartyMonHeldItemSprite(struct Pokemon*, struct PartyMenuBox*);
|
|
static void Task_TossHeldItemYesNo(u8 taskId);
|
|
static void Task_HandleTossHeldItemYesNoInput(u8);
|
|
static void Task_TossHeldItem(u8);
|
|
static void sub_81B4A98(void);
|
|
static void sub_81B4AE0(void);
|
|
static void sub_81B4B6C(u8);
|
|
static void sub_81B4BA0(u8);
|
|
static void sub_81B4C60(u8);
|
|
static void sub_81B4C94(u8);
|
|
static bool8 TrySwitchInPokemon(void);
|
|
static void Task_SpinTradeYesNo(u8);
|
|
static void Task_HandleSpinTradeYesNoInput(u8);
|
|
static void Task_CancelAfterAorBPress(u8);
|
|
static void DisplayFieldMoveExitAreaMessage(u8);
|
|
static void DisplayCantUseFlashMessage(void);
|
|
static void DisplayCantUseSurfMessage(void);
|
|
static void Task_FieldMoveExitAreaYesNo(u8);
|
|
static void Task_HandleFieldMoveExitAreaYesNoInput(u8);
|
|
static void Task_FieldMoveWaitForFade(u8);
|
|
static u16 GetFieldMoveMonSpecies(void);
|
|
static void UpdatePartyMonHPBar(u8, struct Pokemon*);
|
|
static void UpdatePartyMonIconFrame(struct Sprite*);
|
|
static void UpdatePartyMonIconFrameAndBounce(struct Sprite*);
|
|
static void ShowOrHideHeldItemSprite(u16, struct PartyMenuBox*);
|
|
static void CreateHeldItemSpriteForTrade(u8, bool8);
|
|
static void SpriteCB_HeldItem(struct Sprite*);
|
|
static void SetPartyMonAilmentGfx(struct Pokemon*, struct PartyMenuBox*);
|
|
static void UpdatePartyMonAilmentGfx(u8, struct PartyMenuBox*);
|
|
static u8 GetPartyLayoutFromBattleType(void);
|
|
static void sub_81B6280(u8);
|
|
static void CB2_ReturnToBagMenu(void);
|
|
static void Task_DisplayHPRestoredMessage(u8);
|
|
static u16 ItemEffectToMonEv(struct Pokemon*, u8);
|
|
static void ItemEffectToStatString(u8, u8*);
|
|
static void ReturnToUseOnWhichMon(u8);
|
|
static void SetSelectedMoveForPPItem(u8);
|
|
static void TryUsePPItem(u8);
|
|
static void Task_LearnedMove(u8);
|
|
static void Task_ReplaceMoveYesNo(u8);
|
|
static void Task_DoLearnedMoveFanfareAfterText(u8);
|
|
static void Task_LearnNextMoveOrClosePartyMenu(u8);
|
|
static void Task_TryLearningNextMove(u8);
|
|
static void Task_HandleReplaceMoveYesNoInput(u8);
|
|
static void Task_ShowSummaryScreenToForgetMove(u8);
|
|
static void StopLearningMovePrompt(u8);
|
|
static void CB2_ShowSummaryScreenToForgetMove(void);
|
|
static void CB2_ReturnToPartyMenuWhileLearningMove(void);
|
|
static void Task_ReturnToPartyMenuWhileLearningMove(u8);
|
|
static void DisplayPartyMenuForgotMoveMessage(u8);
|
|
static void Task_PartyMenuReplaceMove(u8);
|
|
static void Task_StopLearningMoveYesNo(u8);
|
|
static void Task_HandleStopLearningMoveYesNoInput(u8);
|
|
static void Task_TryLearningNextMoveAfterText(u8);
|
|
static void BufferMonStatsToTaskData(struct Pokemon*, s16*);
|
|
static void UpdateMonDisplayInfoAfterRareCandy(u8, struct Pokemon*);
|
|
static void Task_DisplayLevelUpStatsPg1(u8);
|
|
static void DisplayLevelUpStatsPg1(u8);
|
|
static void Task_DisplayLevelUpStatsPg2(u8);
|
|
static void DisplayLevelUpStatsPg2(u8);
|
|
static void Task_TryLearnNewMoves(u8);
|
|
static void PartyMenuTryEvolution(u8);
|
|
static void DisplayMonNeedsToReplaceMove(u8);
|
|
static void DisplayMonLearnedMove(u8, u16);
|
|
static void sub_81B7A28(u8);
|
|
static void task_sacred_ash_party_loop(u8);
|
|
static void Task_SacredAshDisplayHPRestored(u8);
|
|
static void GiveItemToSelectedMon(u8);
|
|
static void sub_81B83B8(u8);
|
|
static void sub_81B82A0(u8);
|
|
static void RemoveItemToGiveFromBag(u16);
|
|
static void CB2_WriteMailToGiveMonFromBag(void);
|
|
static void sub_81B8088(u8);
|
|
static void Task_UpdateHeldItemSpriteAndClosePartyMenu(u8);
|
|
static void CB2_ReturnToPartyOrBagMenuFromWritingMail(void);
|
|
static bool8 sub_81B841C(u16);
|
|
static void sub_81B8230(u8);
|
|
static void sub_81B82D4(u8);
|
|
static void Task_ValidateChosenHalfParty(u8);
|
|
static bool8 GetBattleEntryEligibility(struct Pokemon*);
|
|
static bool8 HasPartySlotAlreadyBeenSelected(u8);
|
|
static u8 GetBattleEntryLevelCap(void);
|
|
static u8 GetMaxBattleEntries(void);
|
|
static u8 GetMinBattleEntries(void);
|
|
static void Task_ContinueChoosingHalfParty(u8);
|
|
static void sub_81B8C88(u8*, bool8);
|
|
static void sub_81B8D88(u8*, u8, u8);
|
|
static void Task_InitMultiPartnerPartySlideIn(u8);
|
|
static void Task_MultiPartnerPartySlideIn(u8);
|
|
static void SlideMultiPartyMenuBoxSpritesOneStep(u8);
|
|
static void Task_WaitAfterMultiPartnerPartySlideIn(u8);
|
|
static void BufferMonSelection(void);
|
|
static void Task_PartyMenuWaitForFade(u8 taskId);
|
|
static void Task_ChooseContestMon(u8 taskId);
|
|
static void CB2_ChooseContestMon(void);
|
|
static void Task_ChoosePartyMon(u8 taskId);
|
|
static void Task_ChooseMonForMoveRelearner(u8 taskId);
|
|
static void CB2_ChooseMonForMoveRelearner(void);
|
|
static void Task_BattlePyramidChooseMonHeldItems(u8 taskId);
|
|
static void ShiftMoveSlot(struct Pokemon*, u8, u8);
|
|
static void BlitBitmapToPartyWindow_LeftColumn(u8 windowId, u8 x, u8 y, u8 width, u8 height, u8 f);
|
|
static void BlitBitmapToPartyWindow_RightColumn(u8 windowId, u8 x, u8 y, u8 width, u8 height, u8 f);
|
|
static void CursorCb_Summary(u8 taskId);
|
|
static void CursorCb_Switch(u8 taskId);
|
|
static void CursorCb_Cancel1(u8 taskId);
|
|
static void CursorCb_Item(u8 taskId);
|
|
static void CursorCb_Give(u8 taskId);
|
|
static void CursorCb_TakeItem(u8 taskId);
|
|
static void CursorCb_Mail(u8 taskId);
|
|
static void CursorCb_Read(u8 taskId);
|
|
static void CursorCb_TakeMail(u8 taskId);
|
|
static void CursorCb_Cancel2(u8 taskId);
|
|
static void CursorCb_SendMon(u8 taskId);
|
|
static void CursorCb_Enter(u8 taskId);
|
|
static void CursorCb_NoEntry(u8 taskId);
|
|
static void CursorCb_Store(u8 taskId);
|
|
static void CursorCb_Register(u8 taskId);
|
|
static void CursorCb_Trade1(u8 taskId);
|
|
static void CursorCb_Trade2(u8 taskId);
|
|
static void CursorCb_Toss(u8 taskId);
|
|
static void CursorCb_FieldMove(u8 taskId);
|
|
static bool8 SetUpFieldMove_Surf(void);
|
|
static bool8 SetUpFieldMove_Fly(void);
|
|
static bool8 SetUpFieldMove_Waterfall(void);
|
|
static bool8 SetUpFieldMove_Dive(void);
|
|
|
|
// static const data
|
|
#include "data/pokemon/tutor_learnsets.h"
|
|
|
|
static const struct BgTemplate sPartyMenuBgTemplates[] =
|
|
{
|
|
{
|
|
.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 = 2,
|
|
.baseTile = 0
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.charBaseIndex = 0,
|
|
.mapBaseIndex = 28,
|
|
.screenSize = 1,
|
|
.paletteMode = 0,
|
|
.priority = 0,
|
|
.baseTile = 0
|
|
},
|
|
};
|
|
|
|
enum
|
|
{
|
|
PARTY_BOX_LEFT_COLUMN,
|
|
PARTY_BOX_RIGHT_COLUMN
|
|
};
|
|
|
|
static const struct PartyMenuBoxInfoRects sPartyBoxInfoRects[] =
|
|
{
|
|
[PARTY_BOX_LEFT_COLUMN] =
|
|
{
|
|
BlitBitmapToPartyWindow_LeftColumn,
|
|
{
|
|
//The below are the x, y, width, and height for each of the following info
|
|
24, 11, 40, 13, // Nickname
|
|
32, 20, 32, 8, // Level
|
|
64, 20, 8, 8, // Gender
|
|
38, 37, 24, 8, // HP
|
|
53, 37, 24, 8, // Max HP
|
|
24, 35, 48, 3 // HP bar
|
|
},
|
|
12, 34, 64, 16 // Description text (e.g. NO USE)
|
|
},
|
|
[PARTY_BOX_RIGHT_COLUMN] =
|
|
{
|
|
BlitBitmapToPartyWindow_RightColumn,
|
|
{
|
|
// See above comment
|
|
22, 3, 40, 13, // Nickname
|
|
30, 12, 32, 8, // Level
|
|
62, 12, 8, 8, // Gender
|
|
102, 12, 24, 8, // HP
|
|
117, 12, 24, 8, // Max HP
|
|
88, 10, 48, 3 // HP bar
|
|
},
|
|
77, 4, 64, 16 // Description text
|
|
},
|
|
};
|
|
|
|
|
|
// Each layout array has the sprite coords for each of the party mons in the following order
|
|
// Pokemon icon (x, y), held item (x, y), status condition (x, y), menu pokeball (x, y)
|
|
static const u8 sPartyMenuSpriteCoords[PARTY_LAYOUT_COUNT][PARTY_SIZE][4 * 2] =
|
|
{
|
|
[PARTY_LAYOUT_SINGLE] =
|
|
{
|
|
{ 16, 40, 20, 50, 50, 52, 16, 34},
|
|
{104, 18, 108, 28, 136, 27, 102, 25},
|
|
{104, 42, 108, 52, 136, 51, 102, 49},
|
|
{104, 66, 108, 76, 136, 75, 102, 73},
|
|
{104, 90, 108, 100, 136, 99, 102, 97},
|
|
{104, 114, 108, 124, 136, 123, 102, 121},
|
|
},
|
|
[PARTY_LAYOUT_DOUBLE] =
|
|
{
|
|
{16, 24, 20, 34, 50, 36, 16, 18},
|
|
{16, 80, 20, 90, 50, 92, 16, 74},
|
|
{104, 18, 108, 28, 136, 27, 102, 25},
|
|
{104, 50, 108, 60, 136, 59, 102, 57},
|
|
{104, 82, 108, 92, 136, 91, 102, 89},
|
|
{104, 114, 108, 124, 136, 123, 102, 121},
|
|
},
|
|
[PARTY_LAYOUT_MULTI] =
|
|
{
|
|
{16, 24, 20, 34, 50, 36, 16, 18},
|
|
{16, 80, 20, 90, 50, 92, 16, 74},
|
|
{104, 26, 106, 36, 136, 35, 102, 33},
|
|
{104, 50, 106, 60, 136, 59, 102, 57},
|
|
{104, 82, 106, 92, 136, 91, 102, 89},
|
|
{104, 106, 106, 116, 136, 115, 102, 113},
|
|
},
|
|
[PARTY_LAYOUT_MULTI_SHOWCASE] =
|
|
{
|
|
{16, 32, 20, 42, 50, 44, 16, 26},
|
|
{104, 34, 106, 44, 136, 43, 102, 41},
|
|
{104, 58, 106, 68, 136, 67, 102, 65},
|
|
{16, 104, 20, 114, 50, 116, 16, 98},
|
|
{104, 106, 106, 116, 136, 115, 102, 113},
|
|
{104, 130, 106, 140, 136, 139, 102, 137},
|
|
},
|
|
};
|
|
|
|
static const u32 sConfirmButtonPokeball_Tilemap[] = INCBIN_U32("graphics/interface/unknown_6157C4.bin");
|
|
static const u32 sCancelButtonPokeball_Tilemap[] = INCBIN_U32("graphics/interface/unknown_6157E0.bin");
|
|
|
|
static const u8 sFontColorTable[][3] =
|
|
{
|
|
{0, 3, 2},
|
|
{0, 1, 6},
|
|
{0, 11, 12},
|
|
{1, 2, 3},
|
|
{1, 8, 9},
|
|
{0, 1, 2},
|
|
};
|
|
|
|
static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 3,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x63,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 1,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 4,
|
|
.baseBlock = 0xA9,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 4,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 5,
|
|
.baseBlock = 0xDF,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 7,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 6,
|
|
.baseBlock = 0x115,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 10,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 7,
|
|
.baseBlock = 0x14B,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 13,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 8,
|
|
.baseBlock = 0x181,
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 15,
|
|
.width = 28,
|
|
.height = 4,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x1DF,
|
|
},
|
|
DUMMY_WIN_TEMPLATE
|
|
};
|
|
|
|
static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 1,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x63,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 8,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 4,
|
|
.baseBlock = 0xA9,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 1,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 5,
|
|
.baseBlock = 0xEF,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 5,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 6,
|
|
.baseBlock = 0x125,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 9,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 7,
|
|
.baseBlock = 0x15B,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 13,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 8,
|
|
.baseBlock = 0x191,
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 15,
|
|
.width = 28,
|
|
.height = 4,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x1DF,
|
|
},
|
|
DUMMY_WIN_TEMPLATE
|
|
};
|
|
|
|
static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 1,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x63,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 8,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 4,
|
|
.baseBlock = 0xA9,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 2,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 5,
|
|
.baseBlock = 0xEF,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 5,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 6,
|
|
.baseBlock = 0x125,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 9,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 7,
|
|
.baseBlock = 0x15B,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 12,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 8,
|
|
.baseBlock = 0x191,
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 15,
|
|
.width = 28,
|
|
.height = 4,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x1DF,
|
|
},
|
|
DUMMY_WIN_TEMPLATE
|
|
};
|
|
|
|
static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 2,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x63,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 3,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 5,
|
|
.baseBlock = 0xA9,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 6,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 6,
|
|
.baseBlock = 0xDF,
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 11,
|
|
.width = 10,
|
|
.height = 7,
|
|
.paletteNum = 4,
|
|
.baseBlock = 0x115,
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 12,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 7,
|
|
.baseBlock = 0x16B,
|
|
},
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 12,
|
|
.tilemapTop = 15,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 8,
|
|
.baseBlock = 0x1A1,
|
|
},
|
|
DUMMY_WIN_TEMPLATE
|
|
};
|
|
|
|
static const struct WindowTemplate gUnknown_08615908 =
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 24,
|
|
.tilemapTop = 17,
|
|
.width = 6,
|
|
.height = 2,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x1C7,
|
|
};
|
|
|
|
static const struct WindowTemplate gUnknown_08615910 =
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 24,
|
|
.tilemapTop = 18,
|
|
.width = 6,
|
|
.height = 2,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x1C7,
|
|
};
|
|
|
|
static const struct WindowTemplate gUnknown_08615918 =
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 24,
|
|
.tilemapTop = 16,
|
|
.width = 6,
|
|
.height = 2,
|
|
.paletteNum = 3,
|
|
.baseBlock = 0x1D3,
|
|
};
|
|
|
|
static const struct WindowTemplate sDefaultPartyMsgWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 17,
|
|
.width = 21,
|
|
.height = 2,
|
|
.paletteNum = 15,
|
|
.baseBlock = 0x24F,
|
|
};
|
|
|
|
static const struct WindowTemplate sDoWhatWithMonMsgWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 17,
|
|
.width = 16,
|
|
.height = 2,
|
|
.paletteNum = 15,
|
|
.baseBlock = 0x279,
|
|
};
|
|
|
|
static const struct WindowTemplate sDoWhatWithItemMsgWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 17,
|
|
.width = 20,
|
|
.height = 2,
|
|
.paletteNum = 15,
|
|
.baseBlock = 0x299,
|
|
};
|
|
|
|
static const struct WindowTemplate sDoWhatWithMailMsgWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 17,
|
|
.width = 18,
|
|
.height = 2,
|
|
.paletteNum = 15,
|
|
.baseBlock = 0x299,
|
|
};
|
|
|
|
static const struct WindowTemplate sWhichMoveMsgWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 17,
|
|
.width = 16,
|
|
.height = 2,
|
|
.paletteNum = 15,
|
|
.baseBlock = 0x299,
|
|
};
|
|
|
|
static const struct WindowTemplate sAlreadyHoldingOneMsgWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 15,
|
|
.width = 20,
|
|
.height = 4,
|
|
.paletteNum = 15,
|
|
.baseBlock = 0x299,
|
|
};
|
|
|
|
static const struct WindowTemplate sItemGiveTakeWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 23,
|
|
.tilemapTop = 13,
|
|
.width = 6,
|
|
.height = 6,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x39D,
|
|
};
|
|
|
|
static const struct WindowTemplate sMailReadTakeWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 21,
|
|
.tilemapTop = 13,
|
|
.width = 8,
|
|
.height = 6,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x39D,
|
|
};
|
|
|
|
static const struct WindowTemplate sMoveSelectWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 19,
|
|
.tilemapTop = 11,
|
|
.width = 10,
|
|
.height = 8,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x2E9,
|
|
};
|
|
|
|
static const struct WindowTemplate sPartyMenuYesNoWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 21,
|
|
.tilemapTop = 9,
|
|
.width = 5,
|
|
.height = 4,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x2E9,
|
|
};
|
|
|
|
static const struct WindowTemplate sLevelUpStatsWindowTemplate =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 19,
|
|
.tilemapTop = 1,
|
|
.width = 10,
|
|
.height = 11,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x2E9,
|
|
};
|
|
|
|
static const struct WindowTemplate sUnusedWindowTemplate_08615978 =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 2,
|
|
.tilemapTop = 15,
|
|
.width = 27,
|
|
.height = 4,
|
|
.paletteNum = 14,
|
|
.baseBlock = 0x1DF,
|
|
};
|
|
|
|
static const struct WindowTemplate sUnusedWindowTemplate_08615980 =
|
|
{
|
|
.bg = 2,
|
|
.tilemapLeft = 0,
|
|
.tilemapTop = 13,
|
|
.width = 18,
|
|
.height = 3,
|
|
.paletteNum = 12,
|
|
.baseBlock = 0x39D,
|
|
};
|
|
|
|
// Tile nums
|
|
static const u8 sMainSlotTileNums[] = {24, 25, 25, 25, 25, 25, 25, 25, 25, 26,
|
|
32, 33, 33, 33, 33, 33, 33, 33, 33, 34,
|
|
32, 33, 33, 33, 33, 33, 33, 33, 33, 34,
|
|
32, 33, 33, 33, 33, 33, 33, 33, 33, 34,
|
|
40, 59, 60, 58, 58, 58, 58, 58, 58, 61,
|
|
15, 16, 16, 16, 16, 16, 16, 16, 16, 17,
|
|
46, 47, 47, 47, 47, 47, 47, 47, 47, 48};
|
|
|
|
static const u8 sMainSlotTileNums_Egg[] = {24, 25, 25, 25, 25, 25, 25, 25, 25, 26,
|
|
32, 33, 33, 33, 33, 33, 33, 33, 33, 34,
|
|
32, 33, 33, 33, 33, 33, 33, 33, 33, 34,
|
|
32, 33, 33, 33, 33, 33, 33, 33, 33, 34,
|
|
40, 41, 41, 41, 41, 41, 41, 41, 41, 42,
|
|
15, 16, 16, 16, 16, 16, 16, 16, 16, 17,
|
|
46, 47, 47, 47, 47, 47, 47, 47, 47, 48};
|
|
|
|
static const u8 sOtherSlotsTileNums[] = {43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45,
|
|
49, 33, 33, 33, 33, 33, 33, 33, 33, 52, 53, 51, 51, 51, 51, 51, 51, 54,
|
|
55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57};
|
|
|
|
static const u8 sOtherSlotsTileNums_Egg[] = {43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45,
|
|
49, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 50,
|
|
55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57};
|
|
|
|
static const u8 sEmptySlotTileNums[] = {21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
|
|
30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31,
|
|
37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39};
|
|
|
|
// Palette offsets
|
|
static const u8 sGenderPalOffsets[] = {11, 12};
|
|
static const u8 sHPBarPalOffsets[] = {9, 10};
|
|
static const u8 sPartyBoxPalOffsets1[] = {4, 5, 6};
|
|
static const u8 sPartyBoxPalOffsets2[] = {1, 7, 8};
|
|
static const u8 sPartyBoxNoMonPalOffsets[] = {1, 11, 12};
|
|
|
|
// Palette ids
|
|
static const u8 sGenderMalePalIds[] = {59, 60};
|
|
static const u8 sGenderFemalePalIds[] = {75, 76};
|
|
static const u8 sHPBarGreenPalIds[] = {57, 58};
|
|
static const u8 sHPBarYellowPalIds[] = {73, 74};
|
|
static const u8 sHPBarRedPalIds[] = {89, 90};
|
|
static const u8 sPartyBoxEmptySlotPalIds1[] = {52, 53, 54};
|
|
static const u8 sPartyBoxMultiPalIds1[] = {68, 69, 70};
|
|
static const u8 sPartyBoxFaintedPalIds1[] = {84, 85, 86};
|
|
static const u8 sPartyBoxCurrSelectionPalIds1[] = {116, 117, 118};
|
|
static const u8 sPartyBoxCurrSelectionMultiPalIds[] = {132, 133, 134};
|
|
static const u8 sPartyBoxCurrSelectionFaintedPalIds[] = {148, 149, 150};
|
|
static const u8 sPartyBoxSelectedForActionPalIds1[] = {100, 101, 102};
|
|
static const u8 sPartyBoxEmptySlotPalIds2[] = {49, 55, 56};
|
|
static const u8 sPartyBoxMultiPalIds2[] = {65, 71, 72};
|
|
static const u8 sPartyBoxFaintedPalIds2[] = {81, 87, 88};
|
|
static const u8 sPartyBoxCurrSelectionPalIds2[] = {97, 103, 104};
|
|
static const u8 sPartyBoxSelectedForActionPalIds2[] = {161, 167, 168};
|
|
static const u8 sPartyBoxNoMonPalIds[] = {17, 27, 28};
|
|
|
|
//TOOD: IDs?
|
|
static const u8 *const sActionStringTable[] =
|
|
{
|
|
gText_ChoosePokemon,
|
|
gText_ChoosePokemonCancel,
|
|
gText_ChoosePokemonConfirm,
|
|
gText_MoveToWhere,
|
|
gText_TeachWhichPokemon,
|
|
gText_UseOnWhichPokemon,
|
|
gText_GiveToWhichPokemon,
|
|
gText_NothingToCut,
|
|
gText_CantSurfHere,
|
|
gText_AlreadySurfing,
|
|
gText_CurrentIsTooFast,
|
|
gText_EnjoyCycling,
|
|
gText_InUseAlready_PM,
|
|
gText_CantUseHere,
|
|
gText_NoPokemonForBattle,
|
|
gText_ChoosePokemon2,
|
|
gText_NotEnoughHp,
|
|
gText_PokemonAreNeeded,
|
|
gText_PokemonCantBeSame,
|
|
gText_NoIdenticalHoldItems,
|
|
gText_EmptyString2,
|
|
gText_DoWhatWithPokemon,
|
|
gText_RestoreWhichMove,
|
|
gText_BoostPp,
|
|
gText_DoWhatWithItem,
|
|
gText_DoWhatWithMail,
|
|
gText_AlreadyHoldingOne,
|
|
};
|
|
|
|
static const u8 *const sDescriptionStringTable[] =
|
|
{
|
|
[PARTYBOX_DESC_NO_USE] = gText_NoUse,
|
|
[PARTYBOX_DESC_ABLE_3] = gText_Able,
|
|
[PARTYBOX_DESC_FIRST] = gText_First_PM,
|
|
[PARTYBOX_DESC_SECOND] = gText_Second_PM,
|
|
[PARTYBOX_DESC_THIRD] = gText_Third_PM,
|
|
[PARTYBOX_DESC_FOURTH] = gText_Fourth,
|
|
[PARTYBOX_DESC_ABLE] = gText_Able2,
|
|
[PARTYBOX_DESC_NOT_ABLE] = gText_NotAble,
|
|
[PARTYBOX_DESC_ABLE_2] = gText_Able3,
|
|
[PARTYBOX_DESC_NOT_ABLE_2] = gText_NotAble2,
|
|
[PARTYBOX_DESC_LEARNED] = gText_Learned,
|
|
[PARTYBOX_DESC_HAVE] = gText_Have,
|
|
[PARTYBOX_DESC_DONT_HAVE] = gText_DontHave,
|
|
};
|
|
|
|
static const u16 sUnused_08615B94[] =
|
|
{
|
|
0x0108, 0x0151, 0x0160, 0x015b, 0x002e, 0x005c, 0x0102, 0x0153, 0x014b, 0x00ed, 0x00f1, 0x010d, 0x003a, 0x003b, 0x003f, 0x0071,
|
|
0x00b6, 0x00f0, 0x00ca, 0x00db, 0x00da, 0x004c, 0x00e7, 0x0055, 0x0057, 0x0059, 0x00d8, 0x005b, 0x005e, 0x00f7, 0x0118, 0x0068,
|
|
0x0073, 0x015f, 0x0035, 0x00bc, 0x00c9, 0x007e, 0x013d, 0x014c, 0x0103, 0x0107, 0x0122, 0x009c, 0x00d5, 0x00a8, 0x00d3, 0x011d,
|
|
0x0121, 0x013b, 0x000f, 0x0013, 0x0039, 0x0046, 0x0094, 0x00f9, 0x007f, 0x0123,
|
|
};
|
|
|
|
enum
|
|
{
|
|
MENU_SUMMARY,
|
|
MENU_SWITCH,
|
|
MENU_CANCEL1,
|
|
MENU_ITEM,
|
|
MENU_GIVE,
|
|
MENU_TAKE_ITEM,
|
|
MENU_MAIL,
|
|
MENU_TAKE_MAIL,
|
|
MENU_READ,
|
|
MENU_CANCEL2,
|
|
MENU_SHIFT,
|
|
MENU_SEND_OUT,
|
|
MENU_ENTER,
|
|
MENU_NO_ENTRY,
|
|
MENU_STORE,
|
|
MENU_REGISTER,
|
|
MENU_TRADE1,
|
|
MENU_TRADE2,
|
|
MENU_TOSS,
|
|
MENU_FIELD_MOVES,
|
|
};
|
|
|
|
enum
|
|
{
|
|
FIELD_MOVE_CUT,
|
|
FIELD_MOVE_FLASH,
|
|
FIELD_MOVE_ROCK_SMASH,
|
|
FIELD_MOVE_STRENGTH,
|
|
FIELD_MOVE_SURF,
|
|
FIELD_MOVE_FLY,
|
|
FIELD_MOVE_DIVE,
|
|
FIELD_MOVE_WATERFALL,
|
|
FIELD_MOVE_TELEPORT,
|
|
FIELD_MOVE_DIG,
|
|
FIELD_MOVE_SECRET_POWER,
|
|
FIELD_MOVE_MILK_DRINK,
|
|
FIELD_MOVE_SOFT_BOILED,
|
|
FIELD_MOVE_SWEET_SCENT,
|
|
};
|
|
|
|
// What a weird choice of table termination;
|
|
#define FIELD_MOVE_TERMINATOR MOVE_SWORDS_DANCE
|
|
|
|
struct
|
|
{
|
|
const u8 *text;
|
|
TaskFunc func;
|
|
} static const sCursorOptions[] =
|
|
{
|
|
[MENU_SUMMARY] = {gText_Summary5, CursorCb_Summary},
|
|
[MENU_SWITCH] = {gText_Switch2, CursorCb_Switch},
|
|
[MENU_CANCEL1] = {gText_Cancel2, CursorCb_Cancel1},
|
|
[MENU_ITEM] = {gText_Item, CursorCb_Item},
|
|
[MENU_GIVE] = {gMenuText_Give, CursorCb_Give},
|
|
[MENU_TAKE_ITEM] = {gText_Take, CursorCb_TakeItem},
|
|
[MENU_MAIL] = {gText_Mail, CursorCb_Mail},
|
|
[MENU_TAKE_MAIL] = {gText_Take2, CursorCb_TakeMail},
|
|
[MENU_READ] = {gText_Read2, CursorCb_Read},
|
|
[MENU_CANCEL2] = {gText_Cancel2, CursorCb_Cancel2},
|
|
[MENU_SHIFT] = {gText_Shift, CursorCb_SendMon},
|
|
[MENU_SEND_OUT] = {gText_SendOut, CursorCb_SendMon},
|
|
[MENU_ENTER] = {gText_Enter, CursorCb_Enter},
|
|
[MENU_NO_ENTRY] = {gText_NoEntry, CursorCb_NoEntry},
|
|
[MENU_STORE] = {gText_Store, CursorCb_Store},
|
|
[MENU_REGISTER] = {gText_Register, CursorCb_Register},
|
|
[MENU_TRADE1] = {gText_Trade4, CursorCb_Trade1},
|
|
[MENU_TRADE2] = {gText_Trade4, CursorCb_Trade2},
|
|
[MENU_TOSS] = {gMenuText_Toss, CursorCb_Toss},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_CUT] = {gMoveNames[MOVE_CUT], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_FLASH] = {gMoveNames[MOVE_FLASH], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_ROCK_SMASH] = {gMoveNames[MOVE_ROCK_SMASH], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_STRENGTH] = {gMoveNames[MOVE_STRENGTH], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_SURF] = {gMoveNames[MOVE_SURF], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_FLY] = {gMoveNames[MOVE_FLY], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_DIVE] = {gMoveNames[MOVE_DIVE], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_WATERFALL] = {gMoveNames[MOVE_WATERFALL], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_TELEPORT] = {gMoveNames[MOVE_TELEPORT], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_DIG] = {gMoveNames[MOVE_DIG], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_SECRET_POWER] = {gMoveNames[MOVE_SECRET_POWER], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_MILK_DRINK] = {gMoveNames[MOVE_MILK_DRINK], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_SOFT_BOILED] = {gMoveNames[MOVE_SOFT_BOILED], CursorCb_FieldMove},
|
|
[MENU_FIELD_MOVES + FIELD_MOVE_SWEET_SCENT] = {gMoveNames[MOVE_SWEET_SCENT], CursorCb_FieldMove},
|
|
};
|
|
|
|
static const u8 sPartyMenuAction_SummarySwitchCancel[] = {MENU_SUMMARY, MENU_SWITCH, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_ShiftSummaryCancel[] = {MENU_SHIFT, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_SendOutSummaryCancel[] = {MENU_SEND_OUT, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_SummaryCancel[] = {MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_EnterSummaryCancel[] = {MENU_ENTER, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_NoEntrySummaryCancel[] = {MENU_NO_ENTRY, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_StoreSummaryCancel[] = {MENU_STORE, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_GiveTakeItemCancel[] = {MENU_GIVE, MENU_TAKE_ITEM, MENU_CANCEL2};
|
|
static const u8 sPartyMenuAction_ReadTakeMailCancel[] = {MENU_READ, MENU_TAKE_MAIL, MENU_CANCEL2};
|
|
static const u8 sPartyMenuAction_RegisterSummaryCancel[] = {MENU_REGISTER, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_TradeSummaryCancel1[] = {MENU_TRADE1, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_TradeSummaryCancel2[] = {MENU_TRADE2, MENU_SUMMARY, MENU_CANCEL1};
|
|
static const u8 sPartyMenuAction_TakeItemTossCancel[] = {MENU_TAKE_ITEM, MENU_TOSS, MENU_CANCEL1};
|
|
|
|
// IDs for the action lists that appear when a party mon is selected
|
|
enum
|
|
{
|
|
ACTIONS_NONE,
|
|
ACTIONS_SWITCH,
|
|
ACTIONS_SHIFT,
|
|
ACTIONS_SEND_OUT,
|
|
ACTIONS_ENTER,
|
|
ACTIONS_NO_ENTRY,
|
|
ACTIONS_STORE,
|
|
ACTIONS_SUMMARY_ONLY,
|
|
ACTIONS_ITEM,
|
|
ACTIONS_MAIL,
|
|
ACTIONS_REGISTER,
|
|
ACTIONS_TRADE,
|
|
ACTIONS_SPIN_TRADE,
|
|
ACTIONS_TAKEITEM_TOSS
|
|
};
|
|
|
|
static const u8 *const sPartyMenuActions[] =
|
|
{
|
|
[ACTIONS_NONE] = NULL,
|
|
[ACTIONS_SWITCH] = sPartyMenuAction_SummarySwitchCancel,
|
|
[ACTIONS_SHIFT] = sPartyMenuAction_ShiftSummaryCancel,
|
|
[ACTIONS_SEND_OUT] = sPartyMenuAction_SendOutSummaryCancel,
|
|
[ACTIONS_ENTER] = sPartyMenuAction_EnterSummaryCancel,
|
|
[ACTIONS_NO_ENTRY] = sPartyMenuAction_NoEntrySummaryCancel,
|
|
[ACTIONS_STORE] = sPartyMenuAction_StoreSummaryCancel,
|
|
[ACTIONS_SUMMARY_ONLY] = sPartyMenuAction_SummaryCancel,
|
|
[ACTIONS_ITEM] = sPartyMenuAction_GiveTakeItemCancel,
|
|
[ACTIONS_MAIL] = sPartyMenuAction_ReadTakeMailCancel,
|
|
[ACTIONS_REGISTER] = sPartyMenuAction_RegisterSummaryCancel,
|
|
[ACTIONS_TRADE] = sPartyMenuAction_TradeSummaryCancel1,
|
|
[ACTIONS_SPIN_TRADE] = sPartyMenuAction_TradeSummaryCancel2,
|
|
[ACTIONS_TAKEITEM_TOSS] = sPartyMenuAction_TakeItemTossCancel,
|
|
};
|
|
|
|
static const u8 sPartyMenuActionCounts[] =
|
|
{
|
|
[ACTIONS_NONE] = 0,
|
|
[ACTIONS_SWITCH] = ARRAY_COUNT(sPartyMenuAction_SummarySwitchCancel),
|
|
[ACTIONS_SHIFT] = ARRAY_COUNT(sPartyMenuAction_ShiftSummaryCancel),
|
|
[ACTIONS_SEND_OUT] = ARRAY_COUNT(sPartyMenuAction_SendOutSummaryCancel),
|
|
[ACTIONS_ENTER] = ARRAY_COUNT(sPartyMenuAction_EnterSummaryCancel),
|
|
[ACTIONS_NO_ENTRY] = ARRAY_COUNT(sPartyMenuAction_NoEntrySummaryCancel),
|
|
[ACTIONS_STORE] = ARRAY_COUNT(sPartyMenuAction_StoreSummaryCancel),
|
|
[ACTIONS_SUMMARY_ONLY] = ARRAY_COUNT(sPartyMenuAction_SummaryCancel),
|
|
[ACTIONS_ITEM] = ARRAY_COUNT(sPartyMenuAction_GiveTakeItemCancel),
|
|
[ACTIONS_MAIL] = ARRAY_COUNT(sPartyMenuAction_ReadTakeMailCancel),
|
|
[ACTIONS_REGISTER] = ARRAY_COUNT(sPartyMenuAction_RegisterSummaryCancel),
|
|
[ACTIONS_TRADE] = ARRAY_COUNT(sPartyMenuAction_TradeSummaryCancel1),
|
|
[ACTIONS_SPIN_TRADE] = ARRAY_COUNT(sPartyMenuAction_TradeSummaryCancel2),
|
|
[ACTIONS_TAKEITEM_TOSS] = ARRAY_COUNT(sPartyMenuAction_TakeItemTossCancel)
|
|
};
|
|
|
|
static const u16 sFieldMoves[] =
|
|
{
|
|
MOVE_CUT, MOVE_FLASH, MOVE_ROCK_SMASH, MOVE_STRENGTH, MOVE_SURF, MOVE_FLY, MOVE_DIVE, MOVE_WATERFALL, MOVE_TELEPORT,
|
|
MOVE_DIG, MOVE_SECRET_POWER, MOVE_MILK_DRINK, MOVE_SOFT_BOILED, MOVE_SWEET_SCENT, FIELD_MOVE_TERMINATOR
|
|
};
|
|
|
|
struct
|
|
{
|
|
bool8 (*fieldMoveFunc)(void);
|
|
u8 msgId;
|
|
} static const sFieldMoveCursorCallbacks[] =
|
|
{
|
|
[FIELD_MOVE_CUT] = {SetUpFieldMove_Cut, PARTY_MSG_NOTHING_TO_CUT},
|
|
[FIELD_MOVE_FLASH] = {SetUpFieldMove_Flash, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_ROCK_SMASH] = {SetUpFieldMove_RockSmash, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_STRENGTH] = {SetUpFieldMove_Strength, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_SURF] = {SetUpFieldMove_Surf, PARTY_MSG_CANT_SURF_HERE},
|
|
[FIELD_MOVE_FLY] = {SetUpFieldMove_Fly, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_DIVE] = {SetUpFieldMove_Dive, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_WATERFALL] = {SetUpFieldMove_Waterfall, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_TELEPORT] = {SetUpFieldMove_Teleport, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_DIG] = {SetUpFieldMove_Dig, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_SECRET_POWER] = {SetUpFieldMove_SecretPower, PARTY_MSG_CANT_USE_HERE},
|
|
[FIELD_MOVE_MILK_DRINK] = {SetUpFieldMove_SoftBoiled, PARTY_MSG_NOT_ENOUGH_HP},
|
|
[FIELD_MOVE_SOFT_BOILED] = {SetUpFieldMove_SoftBoiled, PARTY_MSG_NOT_ENOUGH_HP},
|
|
[FIELD_MOVE_SWEET_SCENT] = {SetUpFieldMove_SweetScent, PARTY_MSG_CANT_USE_HERE},
|
|
};
|
|
|
|
static const u8 *const sUnionRoomTradeMessages[] =
|
|
{
|
|
[UR_TRADE_MSG_NOT_MON_PARTNER_WANTS - 1] = gText_NotPkmnOtherTrainerWants,
|
|
[UR_TRADE_MSG_NOT_EGG - 1] = gText_ThatIsntAnEgg,
|
|
[UR_TRADE_MSG_MON_CANT_BE_TRADED_1 - 1] = gText_PkmnCantBeTradedNow,
|
|
[UR_TRADE_MSG_MON_CANT_BE_TRADED_2 - 1] = gText_PkmnCantBeTradedNow,
|
|
[UR_TRADE_MSG_PARTNERS_MON_CANT_BE_TRADED - 1] = gText_OtherTrainersPkmnCantBeTraded,
|
|
[UR_TRADE_MSG_EGG_CANT_BE_TRADED -1] = gText_EggCantBeTradedNow,
|
|
[UR_TRADE_MSG_PARTNER_CANT_ACCEPT_MON - 1] = gText_OtherTrainerCantAcceptPkmn,
|
|
[UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_1 - 1] = gText_CantTradeWithTrainer,
|
|
[UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_2 - 1] = gText_CantTradeWithTrainer,
|
|
};
|
|
|
|
static const u32 sHeldItemGfx[] = INCBIN_U32("graphics/interface/hold_icons.4bpp");
|
|
static const u16 sHeldItemPalette[] = INCBIN_U16("graphics/interface/hold_icons.gbapal");
|
|
|
|
static const struct OamData sOamData_HeldItem =
|
|
{
|
|
.y = 0,
|
|
.affineMode = 0,
|
|
.objMode = 0,
|
|
.mosaic = 0,
|
|
.bpp = 0,
|
|
.shape = SPRITE_SHAPE(8x8),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(8x8),
|
|
.tileNum = 0,
|
|
.priority = 1,
|
|
.paletteNum = 0,
|
|
.affineParam = 0,
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_HeldItem[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 1),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_HeldMail[] =
|
|
{
|
|
ANIMCMD_FRAME(1, 1),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd *const sSpriteAnimTable_HeldItem[] =
|
|
{
|
|
sSpriteAnim_HeldItem,
|
|
sSpriteAnim_HeldMail,
|
|
};
|
|
|
|
static const struct SpriteSheet sSpriteSheet_HeldItem =
|
|
{
|
|
sHeldItemGfx, sizeof(sHeldItemGfx), 0xd750
|
|
};
|
|
|
|
static const struct SpritePalette sSpritePalette_HeldItem =
|
|
{
|
|
sHeldItemPalette, 0xd750
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpriteTemplate_HeldItem =
|
|
{
|
|
0xd750,
|
|
0xd750,
|
|
&sOamData_HeldItem,
|
|
sSpriteAnimTable_HeldItem,
|
|
NULL,
|
|
gDummySpriteAffineAnimTable,
|
|
SpriteCallbackDummy
|
|
};
|
|
|
|
static const struct OamData sOamData_MenuPokeball =
|
|
{
|
|
.y = 0,
|
|
.affineMode = 0,
|
|
.objMode = 0,
|
|
.mosaic = 0,
|
|
.bpp = 0,
|
|
.shape = SPRITE_SHAPE(32x32),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(32x32),
|
|
.tileNum = 0,
|
|
.priority = 1,
|
|
.paletteNum = 0,
|
|
.affineParam = 0
|
|
};
|
|
|
|
static const union AnimCmd sPokeballAnim_Closed[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sPokeballAnim_Open[] =
|
|
{
|
|
ANIMCMD_FRAME(16, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd *const sSpriteAnimTable_Pokeball[] =
|
|
{
|
|
sPokeballAnim_Closed,
|
|
sPokeballAnim_Open
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sSpriteSheet_MenuPokeball =
|
|
{
|
|
gPartyMenuPokeball_Gfx, 0x400, 0x04b0
|
|
};
|
|
|
|
static const struct CompressedSpritePalette sSpritePalette_MenuPokeball =
|
|
{
|
|
gPartyMenuPokeball_Pal, 0x04b0
|
|
};
|
|
|
|
// TODO: menu pokeball is vague, these are mon menu pokeballs, but not confirm/cancel pokeballs
|
|
static const struct SpriteTemplate sSpriteTemplate_MenuPokeball =
|
|
{
|
|
.tileTag = 0x04b0,
|
|
.paletteTag = 0x04b0,
|
|
.oam = &sOamData_MenuPokeball,
|
|
.anims = sSpriteAnimTable_Pokeball,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCallbackDummy,
|
|
};
|
|
|
|
static const struct OamData sOamData_8615F20 =
|
|
{
|
|
.y = 0,
|
|
.affineMode = 0,
|
|
.objMode = 0,
|
|
.mosaic = 0,
|
|
.bpp = 0,
|
|
.shape = SPRITE_SHAPE(16x16),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(16x16),
|
|
.tileNum = 0,
|
|
.priority = 2,
|
|
.paletteNum = 0,
|
|
.affineParam = 0
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_8615F28[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_8615F30[] =
|
|
{
|
|
ANIMCMD_FRAME(4, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_8615F38[] =
|
|
{
|
|
ANIMCMD_FRAME(8, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_8615F40[] =
|
|
{
|
|
ANIMCMD_FRAME(12, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_8615F48[] =
|
|
{
|
|
ANIMCMD_FRAME(16, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_8615F50[] =
|
|
{
|
|
ANIMCMD_FRAME(20, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd *const sSpriteAnimTable_8615F58[] =
|
|
{
|
|
sSpriteAnim_8615F28,
|
|
sSpriteAnim_8615F30,
|
|
sSpriteAnim_8615F38,
|
|
sSpriteAnim_8615F40,
|
|
sSpriteAnim_8615F48,
|
|
sSpriteAnim_8615F50
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sSpriteSheet_MenuPokeballSmall =
|
|
{
|
|
gPartyMenuPokeballSmall_Gfx, 0x0300, 0x04b1
|
|
};
|
|
|
|
static const struct SpriteTemplate gSpriteTemplate_8615F78 =
|
|
{
|
|
.tileTag = 1201,
|
|
.paletteTag = 1200,
|
|
.oam = &sOamData_8615F20,
|
|
.anims = sSpriteAnimTable_8615F58,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCallbackDummy,
|
|
};
|
|
|
|
static const struct OamData sOamData_StatusCondition =
|
|
{
|
|
.y = 0,
|
|
.affineMode = 0,
|
|
.objMode = 0,
|
|
.mosaic = 0,
|
|
.bpp = 0,
|
|
.shape = SPRITE_SHAPE(32x8),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(32x8),
|
|
.tileNum = 0,
|
|
.priority = 1,
|
|
.paletteNum = 0,
|
|
.affineParam = 0
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusPoison[] =
|
|
{
|
|
ANIMCMD_FRAME(0, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusParalyzed[] =
|
|
{
|
|
ANIMCMD_FRAME(4, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusSleep[] =
|
|
{
|
|
ANIMCMD_FRAME(8, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusFrozen[] =
|
|
{
|
|
ANIMCMD_FRAME(12, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusBurn[] =
|
|
{
|
|
ANIMCMD_FRAME(16, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusPokerus[] =
|
|
{
|
|
ANIMCMD_FRAME(20, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_StatusFaint[] =
|
|
{
|
|
ANIMCMD_FRAME(24, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd sSpriteAnim_Blank[] =
|
|
{
|
|
ANIMCMD_FRAME(28, 0),
|
|
ANIMCMD_END
|
|
};
|
|
|
|
static const union AnimCmd *const sSpriteTemplate_StatusCondition[] =
|
|
{
|
|
sSpriteAnim_StatusPoison,
|
|
sSpriteAnim_StatusParalyzed,
|
|
sSpriteAnim_StatusSleep,
|
|
sSpriteAnim_StatusFrozen,
|
|
sSpriteAnim_StatusBurn,
|
|
sSpriteAnim_StatusPokerus,
|
|
sSpriteAnim_StatusFaint,
|
|
sSpriteAnim_Blank
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sSpriteSheet_StatusIcons =
|
|
{
|
|
gStatusGfx_Icons, 0x400, 1202
|
|
};
|
|
|
|
static const struct CompressedSpritePalette sSpritePalette_StatusIcons =
|
|
{
|
|
gStatusPal_Icons, 1202
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpriteTemplate_StatusIcons =
|
|
{
|
|
.tileTag = 1202,
|
|
.paletteTag = 1202,
|
|
.oam = &sOamData_StatusCondition,
|
|
.anims = sSpriteTemplate_StatusCondition,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCallbackDummy,
|
|
};
|
|
|
|
// Mask for the partners party in a multi battle
|
|
// TRUE if in the partners party, FALSE otherwise
|
|
// The last two slots after the 6 party members are Confirm/Cancel TODO: this doesnt make sense, if confirm/cancel are present the partners party isnt either
|
|
static const bool8 sMultiBattlePartnersPartyMask[PARTY_SIZE + 2] =
|
|
{
|
|
FALSE,
|
|
TRUE,
|
|
FALSE,
|
|
FALSE,
|
|
TRUE,
|
|
TRUE,
|
|
FALSE,
|
|
FALSE
|
|
};
|
|
|
|
static const u8 *const sUnused_StatStrings[] =
|
|
{
|
|
gText_HP4,
|
|
gText_Attack3,
|
|
gText_Defense3,
|
|
gText_SpAtk4,
|
|
gText_SpDef4,
|
|
gText_Speed2
|
|
};
|
|
|
|
static const u16 sTMHMMoves[] =
|
|
{
|
|
MOVE_FOCUS_PUNCH,
|
|
MOVE_DRAGON_CLAW,
|
|
MOVE_WATER_PULSE,
|
|
MOVE_CALM_MIND,
|
|
MOVE_ROAR,
|
|
MOVE_TOXIC,
|
|
MOVE_HAIL,
|
|
MOVE_BULK_UP,
|
|
MOVE_BULLET_SEED,
|
|
MOVE_HIDDEN_POWER,
|
|
MOVE_SUNNY_DAY,
|
|
MOVE_TAUNT,
|
|
MOVE_ICE_BEAM,
|
|
MOVE_BLIZZARD,
|
|
MOVE_HYPER_BEAM,
|
|
MOVE_LIGHT_SCREEN,
|
|
MOVE_PROTECT,
|
|
MOVE_RAIN_DANCE,
|
|
MOVE_GIGA_DRAIN,
|
|
MOVE_SAFEGUARD,
|
|
MOVE_FRUSTRATION,
|
|
MOVE_SOLAR_BEAM,
|
|
MOVE_IRON_TAIL,
|
|
MOVE_THUNDERBOLT,
|
|
MOVE_THUNDER,
|
|
MOVE_EARTHQUAKE,
|
|
MOVE_RETURN,
|
|
MOVE_DIG,
|
|
MOVE_PSYCHIC,
|
|
MOVE_SHADOW_BALL,
|
|
MOVE_BRICK_BREAK,
|
|
MOVE_DOUBLE_TEAM,
|
|
MOVE_REFLECT,
|
|
MOVE_SHOCK_WAVE,
|
|
MOVE_FLAMETHROWER,
|
|
MOVE_SLUDGE_BOMB,
|
|
MOVE_SANDSTORM,
|
|
MOVE_FIRE_BLAST,
|
|
MOVE_ROCK_TOMB,
|
|
MOVE_AERIAL_ACE,
|
|
MOVE_TORMENT,
|
|
MOVE_FACADE,
|
|
MOVE_SECRET_POWER,
|
|
MOVE_REST,
|
|
MOVE_ATTRACT,
|
|
MOVE_THIEF,
|
|
MOVE_STEEL_WING,
|
|
MOVE_SKILL_SWAP,
|
|
MOVE_SNATCH,
|
|
MOVE_OVERHEAT,
|
|
MOVE_CUT,
|
|
MOVE_FLY,
|
|
MOVE_SURF,
|
|
MOVE_STRENGTH,
|
|
MOVE_FLASH,
|
|
MOVE_ROCK_SMASH,
|
|
MOVE_WATERFALL,
|
|
MOVE_DIVE,
|
|
};
|
|
|
|
// code
|
|
static void InitPartyMenu(u8 menuType, u8 layout, u8 partyAction, bool8 keepCursorPos, u8 messageId, TaskFunc task, MainCallback callback)
|
|
{
|
|
u16 i;
|
|
|
|
ResetPartyMenu();
|
|
sPartyMenuInternal = Alloc(sizeof(struct PartyMenuInternal));
|
|
if (sPartyMenuInternal == NULL)
|
|
{
|
|
SetMainCallback2(callback);
|
|
}
|
|
else
|
|
{
|
|
gPartyMenu.menuType = menuType;
|
|
gPartyMenu.exitCallback = callback;
|
|
gPartyMenu.action = partyAction;
|
|
sPartyMenuInternal->messageId = messageId;
|
|
sPartyMenuInternal->task = task;
|
|
sPartyMenuInternal->exitCallback = NULL;
|
|
sPartyMenuInternal->unk8_1 = 0;
|
|
sPartyMenuInternal->spriteIdConfirmPokeball = 0x7F;
|
|
sPartyMenuInternal->spriteIdCancelPokeball = 0x7F;
|
|
|
|
if (menuType == PARTY_MENU_TYPE_CHOOSE_HALF)
|
|
sPartyMenuInternal->chooseHalf = TRUE;
|
|
else
|
|
sPartyMenuInternal->chooseHalf = FALSE;
|
|
|
|
if (layout != KEEP_PARTY_LAYOUT)
|
|
gPartyMenu.layout = layout;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sPartyMenuInternal->data); i++)
|
|
sPartyMenuInternal->data[i] = 0;
|
|
for (i = 0; i < ARRAY_COUNT(sPartyMenuInternal->windowId); i++)
|
|
sPartyMenuInternal->windowId[i] = 0xFF;
|
|
|
|
if (!keepCursorPos)
|
|
gPartyMenu.slotId = 0;
|
|
else if (gPartyMenu.slotId > PARTY_SIZE - 1 || GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES) == SPECIES_NONE)
|
|
gPartyMenu.slotId = 0;
|
|
|
|
gTextFlags.autoScroll = 0;
|
|
CalculatePlayerPartyCount();
|
|
SetMainCallback2(CB2_InitPartyMenu);
|
|
}
|
|
}
|
|
|
|
static void CB2_UpdatePartyMenu(void)
|
|
{
|
|
RunTasks();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
do_scheduled_bg_tilemap_copies_to_vram();
|
|
UpdatePaletteFade();
|
|
}
|
|
|
|
static void VBlankCB_PartyMenu(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
TransferPlttBuffer();
|
|
}
|
|
|
|
static void CB2_InitPartyMenu(void)
|
|
{
|
|
while (TRUE)
|
|
{
|
|
if (sub_81221EC() == TRUE || ShowPartyMenu() == TRUE || sub_81221AC() == TRUE)
|
|
break;
|
|
}
|
|
}
|
|
|
|
static bool8 ShowPartyMenu(void)
|
|
{
|
|
switch (gMain.state)
|
|
{
|
|
case 0:
|
|
SetVBlankHBlankCallbacksToNull();
|
|
ResetVramOamAndBgCntRegs();
|
|
clear_scheduled_bg_copies_to_vram();
|
|
gMain.state++;
|
|
break;
|
|
case 1:
|
|
ScanlineEffect_Stop();
|
|
gMain.state++;
|
|
break;
|
|
case 2:
|
|
ResetPaletteFade();
|
|
gPaletteFade.bufferTransferDisabled = TRUE;
|
|
gMain.state++;
|
|
break;
|
|
case 3:
|
|
ResetSpriteData();
|
|
gMain.state++;
|
|
break;
|
|
case 4:
|
|
FreeAllSpritePalettes();
|
|
gMain.state++;
|
|
break;
|
|
case 5:
|
|
if (!sub_81221AC())
|
|
ResetTasks();
|
|
gMain.state++;
|
|
break;
|
|
case 6:
|
|
SetPartyMonsAllowedInMinigame();
|
|
gMain.state++;
|
|
break;
|
|
case 7:
|
|
if (!AllocPartyMenuBg())
|
|
{
|
|
ExitPartyMenu();
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
sPartyMenuInternal->data[0] = 0;
|
|
gMain.state++;
|
|
}
|
|
break;
|
|
case 8:
|
|
if (AllocPartyMenuBgGfx())
|
|
gMain.state++;
|
|
break;
|
|
case 9:
|
|
InitPartyMenuWindows(gPartyMenu.layout);
|
|
gMain.state++;
|
|
break;
|
|
case 10:
|
|
InitPartyMenuBoxes(gPartyMenu.layout);
|
|
sPartyMenuInternal->data[0] = 0;
|
|
gMain.state++;
|
|
break;
|
|
case 11:
|
|
LoadHeldItemIcons();
|
|
gMain.state++;
|
|
break;
|
|
case 12:
|
|
LoadPartyMenuPokeballGfx();
|
|
gMain.state++;
|
|
break;
|
|
case 13:
|
|
LoadPartyMenuAilmentGfx();
|
|
gMain.state++;
|
|
break;
|
|
case 14:
|
|
LoadMonIconPalettes();
|
|
gMain.state++;
|
|
break;
|
|
case 15:
|
|
if (party_menu_add_per_mon_objects())
|
|
{
|
|
sPartyMenuInternal->data[0] = 0;
|
|
gMain.state++;
|
|
}
|
|
break;
|
|
case 16:
|
|
if (RenderPartyMenuBoxes())
|
|
{
|
|
sPartyMenuInternal->data[0] = 0;
|
|
gMain.state++;
|
|
}
|
|
break;
|
|
case 17:
|
|
CreateCancelConfirmPokeballSprites();
|
|
gMain.state++;
|
|
break;
|
|
case 18:
|
|
sub_81B2428(sPartyMenuInternal->chooseHalf);
|
|
gMain.state++;
|
|
break;
|
|
case 19:
|
|
gMain.state++;
|
|
break;
|
|
case 20:
|
|
CreateTask(sPartyMenuInternal->task, 0);
|
|
DisplayPartyMenuStdMessage(sPartyMenuInternal->messageId);
|
|
gMain.state++;
|
|
break;
|
|
case 21:
|
|
BlendPalettes(0xFFFFFFFF, 16, 0);
|
|
gPaletteFade.bufferTransferDisabled = FALSE;
|
|
gMain.state++;
|
|
break;
|
|
case 22:
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
|
|
gMain.state++;
|
|
break;
|
|
default:
|
|
SetVBlankCallback(VBlankCB_PartyMenu);
|
|
SetMainCallback2(CB2_UpdatePartyMenu);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void ExitPartyMenu(void)
|
|
{
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
|
|
CreateTask(Task_ExitPartyMenu, 0);
|
|
SetVBlankCallback(VBlankCB_PartyMenu);
|
|
SetMainCallback2(CB2_UpdatePartyMenu);
|
|
}
|
|
|
|
static void Task_ExitPartyMenu(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
SetMainCallback2(gPartyMenu.exitCallback);
|
|
FreePartyPointers();
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
static void ResetPartyMenu(void)
|
|
{
|
|
sPartyMenuInternal = NULL;
|
|
sPartyBgTilemapBuffer = NULL;
|
|
sPartyMenuBoxes = NULL;
|
|
sPartyBgGfxTilemap = NULL;
|
|
}
|
|
|
|
static bool8 AllocPartyMenuBg(void)
|
|
{
|
|
sPartyBgTilemapBuffer = Alloc(0x800);
|
|
if (sPartyBgTilemapBuffer == NULL)
|
|
return FALSE;
|
|
|
|
memset(sPartyBgTilemapBuffer, 0, 0x800);
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
InitBgsFromTemplates(0, sPartyMenuBgTemplates, ARRAY_COUNT(sPartyMenuBgTemplates));
|
|
SetBgTilemapBuffer(1, sPartyBgTilemapBuffer);
|
|
ResetAllBgsCoordinates();
|
|
schedule_bg_copy_tilemap_to_vram(1);
|
|
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
|
|
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
|
ShowBg(0);
|
|
ShowBg(1);
|
|
ShowBg(2);
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 AllocPartyMenuBgGfx(void)
|
|
{
|
|
u32 sizeout;
|
|
|
|
switch (sPartyMenuInternal->data[0])
|
|
{
|
|
case 0:
|
|
sPartyBgGfxTilemap = malloc_and_decompress(gPartyMenuBg_Gfx, &sizeout);
|
|
LoadBgTiles(1, sPartyBgGfxTilemap, sizeout, 0);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
case 1:
|
|
if (!IsDma3ManagerBusyWithBgCopy())
|
|
{
|
|
LZDecompressWram(gPartyMenuBg_Tilemap, sPartyBgTilemapBuffer);
|
|
sPartyMenuInternal->data[0]++;
|
|
}
|
|
break;
|
|
case 2:
|
|
LoadCompressedPalette(gPartyMenuBg_Pal, 0, 0x160);
|
|
CpuCopy16(gPlttBufferUnfaded, sPartyMenuInternal->palBuffer, 0x160);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
case 3:
|
|
PartyPaletteBufferCopy(4);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
case 4:
|
|
PartyPaletteBufferCopy(5);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
case 5:
|
|
PartyPaletteBufferCopy(6);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
case 6:
|
|
PartyPaletteBufferCopy(7);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
case 7:
|
|
PartyPaletteBufferCopy(8);
|
|
sPartyMenuInternal->data[0]++;
|
|
break;
|
|
default:
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void PartyPaletteBufferCopy(u8 offset)
|
|
{
|
|
offset *= 16;
|
|
CpuCopy16(&gPlttBufferUnfaded[0x30], &gPlttBufferUnfaded[offset], 32);
|
|
CpuCopy16(&gPlttBufferUnfaded[0x30], &gPlttBufferFaded[offset], 32);
|
|
}
|
|
|
|
static void FreePartyPointers(void)
|
|
{
|
|
if (sPartyMenuInternal)
|
|
Free(sPartyMenuInternal);
|
|
if (sPartyBgTilemapBuffer)
|
|
Free(sPartyBgTilemapBuffer);
|
|
if (sPartyBgGfxTilemap)
|
|
Free(sPartyBgGfxTilemap);
|
|
if (sPartyMenuBoxes)
|
|
Free(sPartyMenuBoxes);
|
|
FreeAllWindowBuffers();
|
|
}
|
|
|
|
static void InitPartyMenuBoxes(u8 layout)
|
|
{
|
|
u8 i;
|
|
|
|
sPartyMenuBoxes = Alloc(sizeof(struct PartyMenuBox[PARTY_SIZE]));
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
sPartyMenuBoxes[i].infoRects = &sPartyBoxInfoRects[PARTY_BOX_RIGHT_COLUMN];
|
|
sPartyMenuBoxes[i].spriteCoords = sPartyMenuSpriteCoords[layout][i];
|
|
sPartyMenuBoxes[i].windowId = i;
|
|
sPartyMenuBoxes[i].monSpriteId = 0xFF;
|
|
sPartyMenuBoxes[i].itemSpriteId = 0xFF;
|
|
sPartyMenuBoxes[i].pokeballSpriteId = 0xFF;
|
|
sPartyMenuBoxes[i].statusSpriteId = 0xFF;
|
|
}
|
|
// The first party mon goes in the left column
|
|
sPartyMenuBoxes[0].infoRects = &sPartyBoxInfoRects[PARTY_BOX_LEFT_COLUMN];
|
|
|
|
if (layout == PARTY_LAYOUT_MULTI_SHOWCASE)
|
|
sPartyMenuBoxes[3].infoRects = &sPartyBoxInfoRects[PARTY_BOX_LEFT_COLUMN];
|
|
else if (layout != PARTY_LAYOUT_SINGLE)
|
|
sPartyMenuBoxes[1].infoRects = &sPartyBoxInfoRects[PARTY_BOX_LEFT_COLUMN];
|
|
}
|
|
|
|
static void RenderPartyMenuBox(u8 slot)
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_MULTI_BATTLE && slot > 2)
|
|
{
|
|
DisplayPartyPokemonDataForMultiBattle(slot);
|
|
if (gMultiPartnerParty[slot - 3].species == SPECIES_NONE)
|
|
LoadPartyBoxPalette(&sPartyMenuBoxes[slot], PARTY_PAL_NO_MON);
|
|
else
|
|
LoadPartyBoxPalette(&sPartyMenuBoxes[slot], PARTY_PAL_MULTI_ALT);
|
|
CopyWindowToVram(sPartyMenuBoxes[slot].windowId, 2);
|
|
PutWindowTilemap(sPartyMenuBoxes[slot].windowId);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
else
|
|
{
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_SPECIES) == SPECIES_NONE)
|
|
{
|
|
DrawEmptySlot(sPartyMenuBoxes[slot].windowId);
|
|
LoadPartyBoxPalette(&sPartyMenuBoxes[slot], PARTY_PAL_NO_MON);
|
|
CopyWindowToVram(sPartyMenuBoxes[slot].windowId, 2);
|
|
}
|
|
else
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_MOVE_RELEARNER)
|
|
DisplayPartyPokemonDataForRelearner(slot);
|
|
else if (gPartyMenu.menuType == PARTY_MENU_TYPE_CONTEST)
|
|
DisplayPartyPokemonDataForContest(slot);
|
|
else if (gPartyMenu.menuType == PARTY_MENU_TYPE_CHOOSE_HALF)
|
|
DisplayPartyPokemonDataForChooseHalf(slot);
|
|
else if (gPartyMenu.menuType == PARTY_MENU_TYPE_MINIGAME)
|
|
DisplayPartyPokemonDataForWirelessMinigame(slot);
|
|
else if (gPartyMenu.menuType == PARTY_MENU_TYPE_STORE_PYRAMID_HELD_ITEMS)
|
|
DisplayPartyPokemonDataForBattlePyramidHeldItem(slot);
|
|
else if (!DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(slot))
|
|
DisplayPartyPokemonData(slot);
|
|
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_MULTI_BATTLE)
|
|
AnimatePartySlot(slot, 0);
|
|
else if (gPartyMenu.slotId == slot)
|
|
AnimatePartySlot(slot, 1);
|
|
else
|
|
AnimatePartySlot(slot, 0);
|
|
}
|
|
PutWindowTilemap(sPartyMenuBoxes[slot].windowId);
|
|
schedule_bg_copy_tilemap_to_vram(0);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonData(u8 slot)
|
|
{
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_IS_EGG))
|
|
{
|
|
sPartyMenuBoxes[slot].infoRects->blitFunc(sPartyMenuBoxes[slot].windowId, 0, 0, 0, 0, TRUE);
|
|
DisplayPartyPokemonNickname(&gPlayerParty[slot], &sPartyMenuBoxes[slot], 0);
|
|
}
|
|
else
|
|
{
|
|
sPartyMenuBoxes[slot].infoRects->blitFunc(sPartyMenuBoxes[slot].windowId, 0, 0, 0, 0, FALSE);
|
|
DisplayPartyPokemonNickname(&gPlayerParty[slot], &sPartyMenuBoxes[slot], 0);
|
|
DisplayPartyPokemonLevelCheck(&gPlayerParty[slot], &sPartyMenuBoxes[slot], 0);
|
|
DisplayPartyPokemonGenderNidoranCheck(&gPlayerParty[slot], &sPartyMenuBoxes[slot], 0);
|
|
DisplayPartyPokemonHPCheck(&gPlayerParty[slot], &sPartyMenuBoxes[slot], 0);
|
|
DisplayPartyPokemonMaxHPCheck(&gPlayerParty[slot], &sPartyMenuBoxes[slot], 0);
|
|
DisplayPartyPokemonHPBarCheck(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonDescriptionData(u8 slot, u8 stringID)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[slot];
|
|
|
|
sPartyMenuBoxes[slot].infoRects->blitFunc(sPartyMenuBoxes[slot].windowId, 0, 0, 0, 0, TRUE);
|
|
DisplayPartyPokemonNickname(mon, &sPartyMenuBoxes[slot], 0);
|
|
if (!GetMonData(mon, MON_DATA_IS_EGG))
|
|
{
|
|
DisplayPartyPokemonLevelCheck(mon, &sPartyMenuBoxes[slot], 0);
|
|
DisplayPartyPokemonGenderNidoranCheck(mon, &sPartyMenuBoxes[slot], 0);
|
|
}
|
|
DisplayPartyPokemonDescriptionText(stringID, &sPartyMenuBoxes[slot], 0);
|
|
}
|
|
|
|
static void DisplayPartyPokemonDataForChooseHalf(u8 slot)
|
|
{
|
|
u8 i;
|
|
struct Pokemon *mon = &gPlayerParty[slot];
|
|
u8 *order = gSelectedOrderFromParty;
|
|
|
|
if (!GetBattleEntryEligibility(mon))
|
|
{
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < GetMaxBattleEntries(); i++)
|
|
{
|
|
if (order[i] != 0 && (order[i] - 1) == slot)
|
|
{
|
|
DisplayPartyPokemonDescriptionData(slot, i + PARTYBOX_DESC_FIRST);
|
|
return;
|
|
}
|
|
}
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE_3);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonDataForContest(u8 slot)
|
|
{
|
|
switch (GetContestEntryEligibility(&gPlayerParty[slot]))
|
|
{
|
|
case CANT_ENTER_CONTEST:
|
|
case CANT_ENTER_CONTEST_EGG:
|
|
case CANT_ENTER_CONTEST_FAINTED:
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE);
|
|
break;
|
|
case CAN_ENTER_CONTEST_EQUAL_RANK:
|
|
case CAN_ENTER_CONTEST_HIGH_RANK:
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonDataForRelearner(u8 slot)
|
|
{
|
|
if (GetNumberOfRelearnableMoves(&gPlayerParty[slot]) == 0)
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE_2);
|
|
else
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE_2);
|
|
}
|
|
|
|
static void DisplayPartyPokemonDataForWirelessMinigame(u8 slot)
|
|
{
|
|
if (IsMonAllowedInMinigame(slot) == TRUE)
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE);
|
|
else
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE);
|
|
}
|
|
|
|
static void DisplayPartyPokemonDataForBattlePyramidHeldItem(u8 slot)
|
|
{
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_HELD_ITEM))
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_HAVE);
|
|
else
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_DONT_HAVE);
|
|
}
|
|
|
|
// Returns TRUE if teaching move or cant evolve with item (i.e. description data is shown), FALSE otherwise
|
|
static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8 slot)
|
|
{
|
|
struct Pokemon *currentPokemon = &gPlayerParty[slot];
|
|
u16 item = gSpecialVar_ItemId;
|
|
|
|
if (gPartyMenu.action == PARTY_ACTION_MOVE_TUTOR)
|
|
{
|
|
gSpecialVar_Result = FALSE;
|
|
DisplayPartyPokemonDataToTeachMove(slot, 0, gSpecialVar_0x8005);
|
|
}
|
|
else
|
|
{
|
|
if (gPartyMenu.action != PARTY_ACTION_USE_ITEM)
|
|
return FALSE;
|
|
|
|
switch (CheckIfItemIsTMHMOrEvolutionStone(item))
|
|
{
|
|
default:
|
|
return FALSE;
|
|
case 1: // TM/HM
|
|
DisplayPartyPokemonDataToTeachMove(slot, item, 0);
|
|
break;
|
|
case 2: // Evolution stone
|
|
if (!GetMonData(currentPokemon, MON_DATA_IS_EGG) && GetEvolutionTargetSpecies(currentPokemon, 3, item) != SPECIES_NONE)
|
|
return FALSE;
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NO_USE);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void DisplayPartyPokemonDataToTeachMove(u8 slot, u16 item, u8 tutor)
|
|
{
|
|
switch (CanMonLearnTMTutor(&gPlayerParty[slot], item, tutor))
|
|
{
|
|
case CANNOT_LEARN_MOVE:
|
|
case CANNOT_LEARN_MOVE_IS_EGG:
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE_2);
|
|
break;
|
|
case ALREADY_KNOWS_MOVE:
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_LEARNED);
|
|
break;
|
|
default:
|
|
DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE_2);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// TODO: sort out unknowns
|
|
static void DisplayPartyPokemonDataForMultiBattle(u8 slot)
|
|
{
|
|
struct PartyMenuBox *menuBox = &sPartyMenuBoxes[slot];
|
|
u8 actualSlot = slot - (3);
|
|
|
|
if (gMultiPartnerParty[actualSlot].species == SPECIES_NONE)
|
|
{
|
|
DrawEmptySlot(menuBox->windowId);
|
|
}
|
|
else
|
|
{
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, 0, 0, 0, 0, FALSE);
|
|
StringCopy(gStringVar1, gMultiPartnerParty[actualSlot].nickname);
|
|
StringGetEnd10(gStringVar1);
|
|
sub_81DB52C(gStringVar1);
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, menuBox->infoRects->dimensions);
|
|
DisplayPartyPokemonLevel(gMultiPartnerParty[actualSlot].level, menuBox);
|
|
DisplayPartyPokemonGender(gMultiPartnerParty[actualSlot].gender, gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].nickname, menuBox);
|
|
DisplayPartyPokemonHP(gMultiPartnerParty[actualSlot].hp, menuBox);
|
|
DisplayPartyPokemonMaxHP(gMultiPartnerParty[actualSlot].maxhp, menuBox);
|
|
DisplayPartyPokemonHPBar(gMultiPartnerParty[actualSlot].hp, gMultiPartnerParty[actualSlot].maxhp, menuBox);
|
|
}
|
|
}
|
|
|
|
static bool8 RenderPartyMenuBoxes(void)
|
|
{
|
|
RenderPartyMenuBox(sPartyMenuInternal->data[0]);
|
|
if (++sPartyMenuInternal->data[0] == PARTY_SIZE)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static u8* GetPartyMenuBgTile(u16 tileId)
|
|
{
|
|
return &sPartyBgGfxTilemap[tileId << 5];
|
|
}
|
|
|
|
//TODO: rename and all related functions
|
|
static void party_menu_add_per_mon_objects_internal(u8 slot)
|
|
{
|
|
u8 actualSlot;
|
|
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_MULTI_BATTLE && slot > 2)
|
|
{
|
|
u8 status;
|
|
actualSlot = slot - 3;
|
|
|
|
if (gMultiPartnerParty[actualSlot].species != SPECIES_NONE)
|
|
{
|
|
party_menu_link_mon_icon_anim(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].personality, &sPartyMenuBoxes[slot], 0, 0);
|
|
party_menu_link_mon_held_item_object(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].heldItem, &sPartyMenuBoxes[slot]);
|
|
party_menu_link_mon_pokeball_object(gMultiPartnerParty[actualSlot].species, &sPartyMenuBoxes[slot]);
|
|
if (gMultiPartnerParty[actualSlot].hp == 0)
|
|
status = AILMENT_FNT;
|
|
else
|
|
status = GetAilmentFromStatus(gMultiPartnerParty[actualSlot].status);
|
|
party_menu_link_mon_status_condition_object(gMultiPartnerParty[actualSlot].species, status, &sPartyMenuBoxes[slot]);
|
|
}
|
|
}
|
|
else if (GetMonData(&gPlayerParty[slot], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
party_menu_icon_anim(&gPlayerParty[slot], &sPartyMenuBoxes[slot], slot);
|
|
party_menu_held_item_object(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
|
|
party_menu_pokeball_object(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
|
|
party_menu_status_condition_object(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
|
|
}
|
|
}
|
|
|
|
static bool8 party_menu_add_per_mon_objects(void)
|
|
{
|
|
party_menu_add_per_mon_objects_internal(sPartyMenuInternal->data[0]);
|
|
if (++sPartyMenuInternal->data[0] == PARTY_SIZE)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
// TODO Fix name, first if doesnt do that
|
|
static void CreateCancelConfirmPokeballSprites(void)
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_MULTI_BATTLE)
|
|
{
|
|
FillBgTilemapBufferRect(1, 14, 23, 17, 7, 2, 1);
|
|
}
|
|
else
|
|
{
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
{
|
|
sPartyMenuInternal->spriteIdConfirmPokeball = CreateMenuPokeballSprite(0xBF, 0x88);
|
|
sub_81B120C();
|
|
sPartyMenuInternal->spriteIdCancelPokeball = CreateMenuPokeballSprite(0xBF, 0x98);
|
|
}
|
|
else
|
|
{
|
|
sPartyMenuInternal->spriteIdCancelPokeball = CreateCancelPokeballSprite(198, 148);
|
|
}
|
|
AnimatePartySlot(gPartyMenu.slotId, 1);
|
|
}
|
|
}
|
|
|
|
void AnimatePartySlot(u8 slot, u8 animNum)
|
|
{
|
|
u8 spriteId;
|
|
|
|
switch (slot)
|
|
{
|
|
default:
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
LoadPartyBoxPalette(&sPartyMenuBoxes[slot], GetPartyBoxPaletteFlags(slot, animNum));
|
|
AnimateSelectedPartyIcon(sPartyMenuBoxes[slot].monSpriteId, animNum);
|
|
PartyMenuStartSpriteAnim(sPartyMenuBoxes[slot].pokeballSpriteId, animNum);
|
|
}
|
|
return;
|
|
case PARTY_SIZE:
|
|
if (animNum == 0)
|
|
sub_8199C30(1, 23, 16, 7, 2, 1);
|
|
else
|
|
sub_8199C30(1, 23, 16, 7, 2, 2);
|
|
spriteId = sPartyMenuInternal->spriteIdConfirmPokeball;
|
|
break;
|
|
case PARTY_SIZE + 1: // Cancel
|
|
if (!sPartyMenuInternal->chooseHalf)
|
|
{
|
|
if (animNum == 0)
|
|
sub_8199C30(1, 23, 17, 7, 2, 1);
|
|
else
|
|
sub_8199C30(1, 23, 17, 7, 2, 2);
|
|
}
|
|
else if (animNum == 0)
|
|
{
|
|
sub_8199C30(1, 23, 18, 7, 2, 1);
|
|
}
|
|
else
|
|
{
|
|
sub_8199C30(1, 23, 18, 7, 2, 2);
|
|
}
|
|
spriteId = sPartyMenuInternal->spriteIdCancelPokeball;
|
|
break;
|
|
}
|
|
PartyMenuStartSpriteAnim(spriteId, animNum);
|
|
schedule_bg_copy_tilemap_to_vram(1);
|
|
}
|
|
|
|
static u8 GetPartyBoxPaletteFlags(u8 slot, u8 animNum)
|
|
{
|
|
u8 palFlags = 0;
|
|
|
|
if (animNum == 1)
|
|
palFlags |= PARTY_PAL_SELECTED;
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_HP) == 0)
|
|
palFlags |= PARTY_PAL_FAINTED;
|
|
if (PartyBoxPal_ParnterOrDisqualifiedInArena(slot) == TRUE)
|
|
palFlags |= PARTY_PAL_MULTI_ALT;
|
|
if (gPartyMenu.action == PARTY_ACTION_SWITCHING)
|
|
palFlags |= PARTY_PAL_SWITCHING;
|
|
if (gPartyMenu.action == PARTY_ACTION_SWITCH)
|
|
{
|
|
if (slot == gPartyMenu.slotId || slot == gPartyMenu.slotId2)
|
|
palFlags |= PARTY_PAL_TO_SWITCH;
|
|
}
|
|
if (gPartyMenu.action == PARTY_ACTION_SOFTBOILED && slot == gPartyMenu.slotId )
|
|
palFlags |= PARTY_PAL_TO_SOFTBOIL;
|
|
|
|
return palFlags;
|
|
}
|
|
|
|
static bool8 PartyBoxPal_ParnterOrDisqualifiedInArena(u8 slot)
|
|
{
|
|
if (gPartyMenu.layout == PARTY_LAYOUT_MULTI && (slot == 1 || slot == 4 || slot == 5))
|
|
return TRUE;
|
|
|
|
if (slot < 3 && (gBattleTypeFlags & BATTLE_TYPE_ARENA) && gMain.inBattle && (gBattleStruct->arenaLostPlayerMons >> GetPartyIdFromBattleSlot(slot) & 1))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//TODO: tilemaps for confirm/cancel buttons in choose 3, double check
|
|
static void sub_81B120C(void)
|
|
{
|
|
CopyToBgTilemapBufferRect_ChangePalette(1, sConfirmButtonPokeball_Tilemap, 23, 16, 7, 2, 17);
|
|
CopyToBgTilemapBufferRect_ChangePalette(1, sCancelButtonPokeball_Tilemap, 23, 18, 7, 2, 17);
|
|
schedule_bg_copy_tilemap_to_vram(1);
|
|
}
|
|
|
|
bool8 IsMultiBattle(void)
|
|
{
|
|
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleTypeFlags & BATTLE_TYPE_TRAINER && gMain.inBattle)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void SwapPartyPokemon(struct Pokemon *mon1, struct Pokemon *mon2)
|
|
{
|
|
struct Pokemon *temp = Alloc(sizeof(struct Pokemon));
|
|
|
|
*temp = *mon1;
|
|
*mon1 = *mon2;
|
|
*mon2 = *temp;
|
|
|
|
Free(temp);
|
|
}
|
|
|
|
static void Task_ClosePartyMenu(u8 taskId)
|
|
{
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
|
|
gTasks[taskId].func = Task_ClosePartyMenuAndSetCB2;
|
|
}
|
|
|
|
static void Task_ClosePartyMenuAndSetCB2(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
|
|
UpdatePartyToFieldOrder();
|
|
|
|
if (sPartyMenuInternal->exitCallback != NULL)
|
|
SetMainCallback2(sPartyMenuInternal->exitCallback);
|
|
else
|
|
SetMainCallback2(gPartyMenu.exitCallback);
|
|
|
|
ResetSpriteData();
|
|
FreePartyPointers();
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
u8 GetCursorSelectionMonId(void)
|
|
{
|
|
return gPartyMenu.slotId;
|
|
}
|
|
|
|
u8 GetPartyMenuType(void)
|
|
{
|
|
return gPartyMenu.menuType;
|
|
}
|
|
|
|
void Task_HandleChooseMonInput(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active && sub_81221EC() != TRUE)
|
|
{
|
|
s8 *slotPtr = GetCurrentPartySlotPtr();
|
|
|
|
switch (PartyMenuButtonHandler(slotPtr))
|
|
{
|
|
case 1: // Selected mon
|
|
HandleChooseMonSelection(taskId, slotPtr);
|
|
break;
|
|
case 2: // Selected Cancel
|
|
HandleChooseMonCancel(taskId, slotPtr);
|
|
break;
|
|
case 8: // Start button
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
sub_81B4F88();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static s8* GetCurrentPartySlotPtr(void)
|
|
{
|
|
if (gPartyMenu.action == PARTY_ACTION_SWITCH || gPartyMenu.action == PARTY_ACTION_SOFTBOILED)
|
|
return &gPartyMenu.slotId2;
|
|
else
|
|
return &gPartyMenu.slotId;
|
|
}
|
|
|
|
static void HandleChooseMonSelection(u8 taskId, s8 *slotPtr)
|
|
{
|
|
if (*slotPtr == PARTY_SIZE)
|
|
{
|
|
gPartyMenu.task(taskId);
|
|
}
|
|
else
|
|
{
|
|
switch (gPartyMenu.action - 3)
|
|
{
|
|
case PARTY_ACTION_SOFTBOILED - 3:
|
|
if (IsSelectedMonNotEgg((u8*)slotPtr))
|
|
{
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
Task_TryUseSoftboiledOnPartyMon(taskId);
|
|
}
|
|
break;
|
|
case PARTY_ACTION_USE_ITEM - 3:
|
|
if (IsSelectedMonNotEgg((u8*)slotPtr))
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
|
|
sPartyMenuInternal->exitCallback = CB2_SetUpExitToBattleScreen;
|
|
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
gItemUseCB(taskId, Task_ClosePartyMenuAfterText);
|
|
}
|
|
break;
|
|
case PARTY_ACTION_MOVE_TUTOR - 3:
|
|
if (IsSelectedMonNotEgg((u8*)slotPtr))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
TryTutorSelectedMon(taskId);
|
|
}
|
|
break;
|
|
case PARTY_ACTION_GIVE_MAILBOX_MAIL - 3:
|
|
if (IsSelectedMonNotEgg((u8*)slotPtr))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
TryGiveMailToSelectedMon(taskId);
|
|
}
|
|
break;
|
|
case PARTY_ACTION_GIVE_ITEM - 3:
|
|
case PARTY_ACTION_GIVE_PC_ITEM - 3:
|
|
if (IsSelectedMonNotEgg((u8*)slotPtr))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
TryGiveItemToSelectedMon(taskId);
|
|
}
|
|
break;
|
|
case PARTY_ACTION_SWITCH - 3:
|
|
PlaySE(SE_SELECT);
|
|
SwitchSelectedMons(taskId);
|
|
break;
|
|
case PARTY_ACTION_CHOOSE_AND_CLOSE - 3:
|
|
PlaySE(SE_SELECT);
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
case PARTY_ACTION_MINIGAME - 3:
|
|
if (IsSelectedMonNotEgg((u8*)slotPtr))
|
|
{
|
|
TryEnterMonForMinigame(taskId, (u8)*slotPtr);
|
|
}
|
|
break;
|
|
default:
|
|
case PARTY_ACTION_ABILITY_PREVENTS - 3:
|
|
case PARTY_ACTION_SWITCHING - 3:
|
|
PlaySE(SE_SELECT);
|
|
Task_TryCreateSelectionWindow(taskId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool8 IsSelectedMonNotEgg(u8 *slotPtr)
|
|
{
|
|
if (GetMonData(&gPlayerParty[*slotPtr], MON_DATA_IS_EGG) == TRUE)
|
|
{
|
|
PlaySE(SE_HAZURE);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void HandleChooseMonCancel(u8 taskId, s8 *slotPtr)
|
|
{
|
|
switch (gPartyMenu.action)
|
|
{
|
|
case PARTY_ACTION_SEND_OUT:
|
|
PlaySE(SE_HAZURE);
|
|
break;
|
|
case PARTY_ACTION_SWITCH:
|
|
case PARTY_ACTION_SOFTBOILED:
|
|
PlaySE(SE_SELECT);
|
|
FinishTwoMonAction(taskId);
|
|
break;
|
|
case PARTY_ACTION_MINIGAME:
|
|
PlaySE(SE_SELECT);
|
|
CancelParticipationPrompt(taskId);
|
|
break;
|
|
default:
|
|
PlaySE(SE_SELECT);
|
|
if (DisplayCancelChooseMonYesNo(taskId) != TRUE)
|
|
{
|
|
if (!sub_81221AC())
|
|
gSpecialVar_0x8004 = PARTY_SIZE + 1;
|
|
gUnknown_0203CEE8 = FALSE;
|
|
*slotPtr = PARTY_SIZE + 1;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static bool8 DisplayCancelChooseMonYesNo(u8 taskId)
|
|
{
|
|
const u8* stringPtr = NULL;
|
|
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_CONTEST)
|
|
stringPtr = gText_CancelParticipation;
|
|
else if (gPartyMenu.menuType == PARTY_MENU_TYPE_CHOOSE_HALF)
|
|
stringPtr = GetFacilityCancelString();
|
|
|
|
if (stringPtr == NULL)
|
|
return FALSE;
|
|
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
StringExpandPlaceholders(gStringVar4, stringPtr);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_CancelChooseMonYesNo;
|
|
return TRUE;
|
|
}
|
|
|
|
static void Task_CancelChooseMonYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleCancelChooseMonYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleCancelChooseMonYesNoInput(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
gUnknown_0203CEE8 = FALSE;
|
|
gPartyMenu.slotId = PARTY_SIZE + 1;
|
|
ClearSelectedPartyOrder();
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
Task_ReturnToChooseMonAfterText(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static u16 PartyMenuButtonHandler(s8 *slotPtr)
|
|
{
|
|
s8 movementDir;
|
|
|
|
switch (gMain.newAndRepeatedKeys)
|
|
{
|
|
case DPAD_UP:
|
|
movementDir = -1;
|
|
break;
|
|
case DPAD_DOWN:
|
|
movementDir = 1;
|
|
break;
|
|
case DPAD_LEFT:
|
|
movementDir = -2;
|
|
break;
|
|
case DPAD_RIGHT:
|
|
movementDir = 2;
|
|
break;
|
|
default:
|
|
switch (GetLRKeysPressedAndHeld())
|
|
{
|
|
case MENU_L_PRESSED:
|
|
movementDir = -1;
|
|
break;
|
|
case MENU_R_PRESSED:
|
|
movementDir = 1;
|
|
break;
|
|
default:
|
|
movementDir = 0;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (gMain.newKeys & START_BUTTON)
|
|
return 8;
|
|
|
|
if (movementDir)
|
|
{
|
|
UpdateCurrentPartySelection(slotPtr, movementDir);
|
|
return 0;
|
|
}
|
|
|
|
// Pressed Cancel
|
|
if ((gMain.newKeys & A_BUTTON) && *slotPtr == PARTY_SIZE + 1)
|
|
return 2;
|
|
|
|
return gMain.newKeys & (A_BUTTON | B_BUTTON);
|
|
}
|
|
|
|
static void UpdateCurrentPartySelection(s8 *slotPtr, s8 movementDir)
|
|
{
|
|
s8 newSlotId = *slotPtr;
|
|
u8 layout = gPartyMenu.layout;
|
|
|
|
if (layout == PARTY_LAYOUT_SINGLE)
|
|
UpdatePartySelectionSingleLayout(slotPtr, movementDir);
|
|
else // remaining double/multi layouts handle movement the same way
|
|
UpdatePartySelectionDoubleLayout(slotPtr, movementDir);
|
|
|
|
if (*slotPtr != newSlotId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
AnimatePartySlot(newSlotId, 0);
|
|
AnimatePartySlot(*slotPtr, 1);
|
|
}
|
|
}
|
|
|
|
// TODO: clean up
|
|
static void UpdatePartySelectionSingleLayout(s8 *slotPtr, s8 movementDir)
|
|
{
|
|
// PARTY_SIZE + 1 is Cancel, the 7th party menu selection
|
|
switch (movementDir)
|
|
{
|
|
case -1:
|
|
if (*slotPtr == 0)
|
|
{
|
|
*slotPtr = PARTY_SIZE + 1;
|
|
}
|
|
else if (*slotPtr == PARTY_SIZE)
|
|
{
|
|
*slotPtr = gPlayerPartyCount - 1;
|
|
}
|
|
else if (*slotPtr == PARTY_SIZE + 1)
|
|
{
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
*slotPtr = PARTY_SIZE;
|
|
else
|
|
*slotPtr = gPlayerPartyCount - 1;
|
|
}
|
|
else
|
|
{
|
|
(*slotPtr)--;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (*slotPtr == PARTY_SIZE + 1)
|
|
{
|
|
*slotPtr = 0;
|
|
}
|
|
else
|
|
{
|
|
if (*slotPtr == gPlayerPartyCount - 1)
|
|
{
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
*slotPtr = PARTY_SIZE;
|
|
else
|
|
*slotPtr = PARTY_SIZE + 1;
|
|
}
|
|
else
|
|
{
|
|
(*slotPtr)++;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
if (gPlayerPartyCount != 1 && *slotPtr == 0)
|
|
{
|
|
if (sPartyMenuInternal->unk8_1 == 0)
|
|
*slotPtr = 1;
|
|
else
|
|
*slotPtr = sPartyMenuInternal->unk8_1;
|
|
}
|
|
break;
|
|
case -2:
|
|
if (*slotPtr != 0 && *slotPtr != PARTY_SIZE && *slotPtr != PARTY_SIZE + 1)
|
|
{
|
|
sPartyMenuInternal->unk8_1 = *slotPtr;
|
|
*slotPtr = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// TODO: clean up
|
|
static void UpdatePartySelectionDoubleLayout(s8 *slotPtr, s8 movementDir)
|
|
{
|
|
// PARTY_SIZE + 1 is Cancel, the 7th party menu selection
|
|
s8 unk2 = movementDir;
|
|
|
|
switch (movementDir)
|
|
{
|
|
case -1:
|
|
if (*slotPtr == 0)
|
|
{
|
|
*slotPtr = PARTY_SIZE + 1;
|
|
break;
|
|
}
|
|
else if (*slotPtr == PARTY_SIZE)
|
|
{
|
|
*slotPtr = gPlayerPartyCount - 1;
|
|
break;
|
|
}
|
|
else if (*slotPtr == PARTY_SIZE + 1)
|
|
{
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
{
|
|
*slotPtr = PARTY_SIZE;
|
|
break;
|
|
}
|
|
(*slotPtr)--;
|
|
}
|
|
unk2 = sub_81B1B00(*slotPtr, unk2);
|
|
if (unk2 != -1)
|
|
*slotPtr = unk2;
|
|
break;
|
|
case 1:
|
|
if (*slotPtr == PARTY_SIZE)
|
|
{
|
|
*slotPtr = PARTY_SIZE + 1;
|
|
}
|
|
else if (*slotPtr == PARTY_SIZE + 1)
|
|
{
|
|
*slotPtr = 0;
|
|
}
|
|
else
|
|
{
|
|
unk2 = sub_81B1B00(*slotPtr, 1);
|
|
if (unk2 == -1)
|
|
{
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
*slotPtr = PARTY_SIZE;
|
|
else
|
|
*slotPtr = PARTY_SIZE + 1;
|
|
}
|
|
else
|
|
{
|
|
*slotPtr = unk2;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
if (*slotPtr == 0)
|
|
{
|
|
if (sPartyMenuInternal->unk8_1 == 3)
|
|
{
|
|
if (GetMonData(&gPlayerParty[3], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
*slotPtr = 3;
|
|
}
|
|
else if (GetMonData(&gPlayerParty[2], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
*slotPtr = 2;
|
|
}
|
|
}
|
|
else if (*slotPtr == 1)
|
|
{
|
|
if (sPartyMenuInternal->unk8_1 == 5)
|
|
{
|
|
if (GetMonData(&gPlayerParty[5], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
*slotPtr = 5;
|
|
}
|
|
else if (GetMonData(&gPlayerParty[4], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
*slotPtr = 4;
|
|
}
|
|
}
|
|
break;
|
|
case -2:
|
|
if (*slotPtr == 2 || *slotPtr == 3)
|
|
{
|
|
sPartyMenuInternal->unk8_1 = *slotPtr;
|
|
*slotPtr = 0;
|
|
}
|
|
else if (*slotPtr == 4 || *slotPtr == 5)
|
|
{
|
|
sPartyMenuInternal->unk8_1 = *slotPtr;
|
|
*slotPtr = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static s8 sub_81B1B00(s8 slotId, s8 b)
|
|
{
|
|
while (TRUE)
|
|
{
|
|
slotId += b;
|
|
if ((u8)slotId >= PARTY_SIZE)
|
|
return -1;
|
|
if (GetMonData(&gPlayerParty[slotId], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
return slotId;
|
|
}
|
|
}
|
|
|
|
u8* GetMonNickname(struct Pokemon *mon, u8 *dest)
|
|
{
|
|
GetMonData(mon, MON_DATA_NICKNAME, dest);
|
|
return StringGetEnd10(dest);
|
|
}
|
|
|
|
#define tKeepOpen data[0]
|
|
|
|
u8 DisplayPartyMenuMessage(const u8* str, bool8 keepOpen)
|
|
{
|
|
u8 taskId;
|
|
|
|
PartyMenuPrintText(str);
|
|
taskId = CreateTask(Task_PrintAndWaitForText, 1);
|
|
gTasks[taskId].tKeepOpen = keepOpen;
|
|
return taskId;
|
|
}
|
|
|
|
static void Task_PrintAndWaitForText(u8 taskId)
|
|
{
|
|
if (RunTextPrintersRetIsActive(6) != TRUE)
|
|
{
|
|
if (gTasks[taskId].tKeepOpen == FALSE)
|
|
{
|
|
ClearStdWindowAndFrameToTransparent(6, 0);
|
|
ClearWindowTilemap(6);
|
|
}
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
#undef tKeepOpen
|
|
|
|
bool8 IsPartyMenuTextPrinterActive(void)
|
|
{
|
|
return FuncIsActiveTask(Task_PrintAndWaitForText);
|
|
}
|
|
|
|
static void Task_WaitForLinkAndReturnToChooseMon(u8 taskId)
|
|
{
|
|
if (sub_81221EC() != TRUE)
|
|
{
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
}
|
|
|
|
static void Task_ReturnToChooseMonAfterText(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
ClearStdWindowAndFrameToTransparent(6, 0);
|
|
ClearWindowTilemap(6);
|
|
if (sub_81221AC() == TRUE)
|
|
{
|
|
gTasks[taskId].func = Task_WaitForLinkAndReturnToChooseMon;
|
|
}
|
|
else
|
|
{
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DisplayGaveHeldItemMessage(struct Pokemon *mon, u16 item, bool8 keepOpen, u8 unused)
|
|
{
|
|
GetMonNickname(mon, gStringVar1);
|
|
CopyItemName(item, gStringVar2);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnWasGivenItem);
|
|
DisplayPartyMenuMessage(gStringVar4, keepOpen);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void DisplayTookHeldItemMessage(struct Pokemon *mon, u16 item, bool8 keepOpen)
|
|
{
|
|
GetMonNickname(mon, gStringVar1);
|
|
CopyItemName(item, gStringVar2);
|
|
StringExpandPlaceholders(gStringVar4, gText_ReceivedItemFromPkmn);
|
|
DisplayPartyMenuMessage(gStringVar4, keepOpen);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void DisplayAlreadyHoldingItemSwitchMessage(struct Pokemon *mon, u16 item, bool8 keepOpen)
|
|
{
|
|
GetMonNickname(mon, gStringVar1);
|
|
CopyItemName(item, gStringVar2);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnAlreadyHoldingItemSwitch);
|
|
DisplayPartyMenuMessage(gStringVar4, keepOpen);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void DisplaySwitchedHeldItemMessage(u16 item, u16 item2, bool8 keepOpen)
|
|
{
|
|
CopyItemName(item, gStringVar1);
|
|
CopyItemName(item2, gStringVar2);
|
|
StringExpandPlaceholders(gStringVar4, gText_SwitchedPkmnItem);
|
|
DisplayPartyMenuMessage(gStringVar4, keepOpen);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void GiveItemToMon(struct Pokemon *mon, u16 item)
|
|
{
|
|
u8 itemBytes[2];
|
|
|
|
if (ItemIsMail(item) == TRUE)
|
|
{
|
|
if (GiveMailToMon(mon, item) == 0xFF)
|
|
return;
|
|
}
|
|
itemBytes[0] = item;
|
|
itemBytes[1] = item >> 8;
|
|
SetMonData(mon, MON_DATA_HELD_ITEM, itemBytes);
|
|
}
|
|
|
|
static u8 TryTakeMonItem(struct Pokemon* mon)
|
|
{
|
|
u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
|
|
|
|
if (item == ITEM_NONE)
|
|
return 0;
|
|
if (AddBagItem(item, 1) == FALSE)
|
|
return 1;
|
|
|
|
item = ITEM_NONE;
|
|
SetMonData(mon, MON_DATA_HELD_ITEM, &item);
|
|
return 2;
|
|
}
|
|
|
|
static void BufferBagFullCantTakeItemMessage(u16 itemUnused)
|
|
{
|
|
StringExpandPlaceholders(gStringVar4, gText_BagFullCouldNotRemoveItem);
|
|
}
|
|
|
|
#define tHP data[0]
|
|
#define tMaxHP data[1]
|
|
#define tHPIncrement data[2]
|
|
#define tHPToAdd data[3]
|
|
#define tPartyId data[4]
|
|
#define tStartHP data[5]
|
|
|
|
static void Task_PartyMenuModifyHP(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
tHP += tHPIncrement;
|
|
tHPToAdd--;
|
|
SetMonData(&gPlayerParty[tPartyId], MON_DATA_HP, &tHP);
|
|
DisplayPartyPokemonHPCheck(&gPlayerParty[tPartyId], &sPartyMenuBoxes[tPartyId], 1);
|
|
DisplayPartyPokemonHPBarCheck(&gPlayerParty[tPartyId], &sPartyMenuBoxes[tPartyId]);
|
|
if (tHPToAdd == 0 || tHP == 0 || tHP == tMaxHP)
|
|
{
|
|
// If HP was recovered, buffer the amount recovered
|
|
if (tHP > tStartHP)
|
|
ConvertIntToDecimalStringN(gStringVar2, tHP - tStartHP, STR_CONV_MODE_LEFT_ALIGN, 3);
|
|
|
|
SwitchTaskToFollowupFunc(taskId);
|
|
}
|
|
}
|
|
|
|
void PartyMenuModifyHP(u8 taskId, u8 slot, s8 hpIncrement, s16 hpDifference, TaskFunc followUpFunc)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[slot];
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
tHP = GetMonData(mon, MON_DATA_HP);
|
|
tMaxHP = GetMonData(mon, MON_DATA_MAX_HP);
|
|
tHPIncrement = hpIncrement;
|
|
tHPToAdd = hpDifference;
|
|
tPartyId = slot;
|
|
tStartHP = tHP;
|
|
SetTaskFuncWithFollowupFunc(taskId, Task_PartyMenuModifyHP, followUpFunc);
|
|
}
|
|
|
|
// The usage of hp in this function is mostly nonsense
|
|
// Because caseId is always passed 0, none of the other cases ever occur
|
|
static void ResetHPTaskData(u8 taskId, u8 caseId, u32 hp)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
switch (caseId) // always zero
|
|
{
|
|
case 0:
|
|
tHP = hp;
|
|
tStartHP = hp;
|
|
break;
|
|
case 1:
|
|
tMaxHP = hp;
|
|
break;
|
|
case 2:
|
|
tHPIncrement = hp;
|
|
break;
|
|
case 3:
|
|
tHPToAdd = hp;
|
|
break;
|
|
case 4:
|
|
tPartyId = hp;
|
|
break;
|
|
case 5:
|
|
SetTaskFuncWithFollowupFunc(taskId, Task_PartyMenuModifyHP, (TaskFunc)hp); // >casting hp as a taskfunc
|
|
break;
|
|
}
|
|
}
|
|
|
|
#undef tHP
|
|
#undef tMaxHP
|
|
#undef tHPIncrement
|
|
#undef tHPToAdd
|
|
#undef tPartyId
|
|
#undef tStartHP
|
|
|
|
u8 GetAilmentFromStatus(u32 status)
|
|
{
|
|
if (status & STATUS1_PSN_ANY)
|
|
return AILMENT_PSN;
|
|
if (status & STATUS1_PARALYSIS)
|
|
return AILMENT_PRZ;
|
|
if (status & STATUS1_SLEEP)
|
|
return AILMENT_SLP;
|
|
if (status & STATUS1_FREEZE)
|
|
return AILMENT_FRZ;
|
|
if (status & STATUS1_BURN)
|
|
return AILMENT_BRN;
|
|
return AILMENT_NONE;
|
|
}
|
|
|
|
u8 GetMonAilment(struct Pokemon *mon)
|
|
{
|
|
u8 ailment;
|
|
|
|
if (GetMonData(mon, MON_DATA_HP) == 0)
|
|
return AILMENT_FNT;
|
|
ailment = GetAilmentFromStatus(GetMonData(mon, MON_DATA_STATUS));
|
|
if (ailment != AILMENT_NONE)
|
|
return ailment;
|
|
if (CheckPartyPokerus(mon, 0))
|
|
return AILMENT_PKRS;
|
|
return AILMENT_NONE;
|
|
}
|
|
|
|
static void SetPartyMonsAllowedInMinigame(void)
|
|
{
|
|
u16 *ptr;
|
|
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_MINIGAME)
|
|
{
|
|
u8 i;
|
|
|
|
ptr = &gPartyMenu.unkE;
|
|
gPartyMenu.unkE = 0;
|
|
if (gSpecialVar_0x8005 == 0)
|
|
{
|
|
for (i = 0; i < gPlayerPartyCount; i++)
|
|
*ptr += IsMonAllowedInPokemonJump(&gPlayerParty[i]) << i;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < gPlayerPartyCount; i++)
|
|
*ptr += IsMonAllowedInDodrioBerryPicking(&gPlayerParty[i]) << i;
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool16 IsMonAllowedInPokemonJump(struct Pokemon *mon)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_IS_EGG) != TRUE && IsSpeciesAllowedInPokemonJump(GetMonData(mon, MON_DATA_SPECIES)))
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static bool16 IsMonAllowedInDodrioBerryPicking(struct Pokemon *mon)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_IS_EGG) != TRUE && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_DODRIO)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 IsMonAllowedInMinigame(u8 slot)
|
|
{
|
|
if (!((gPartyMenu.unkE >> slot) & 1))
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
static void TryEnterMonForMinigame(u8 taskId, u8 slot)
|
|
{
|
|
if (IsMonAllowedInMinigame(slot) == TRUE)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
gSpecialVar_0x8004 = slot;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
else
|
|
{
|
|
PlaySE(SE_HAZURE);
|
|
DisplayPartyMenuMessage(gText_PkmnCantParticipate, FALSE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
}
|
|
|
|
static void CancelParticipationPrompt(u8 taskId)
|
|
{
|
|
DisplayPartyMenuMessage(gText_CancelParticipation, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_CancelParticipationYesNo;
|
|
}
|
|
|
|
static void Task_CancelParticipationYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleCancelParticipationYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleCancelParticipationYesNoInput(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
gSpecialVar_0x8004 = PARTY_SIZE + 1;
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static u8 CanMonLearnTMTutor(struct Pokemon *mon, u16 item, u8 tutor)
|
|
{
|
|
u16 move;
|
|
|
|
if (GetMonData(mon, MON_DATA_IS_EGG))
|
|
return CANNOT_LEARN_MOVE_IS_EGG;
|
|
|
|
if (item >= ITEM_TM01_FOCUS_PUNCH)
|
|
{
|
|
if (CanMonLearnTMHM(mon, item - ITEM_TM01_FOCUS_PUNCH))
|
|
move = ItemIdToBattleMoveId(item);
|
|
else
|
|
return CANNOT_LEARN_MOVE;
|
|
do {} while (0); // :morphon:
|
|
}
|
|
else if (CanLearnTutorMove(GetMonData(mon, MON_DATA_SPECIES), tutor) == FALSE)
|
|
{
|
|
return CANNOT_LEARN_MOVE;
|
|
}
|
|
else
|
|
{
|
|
move = GetTutorMove(tutor);
|
|
}
|
|
|
|
if (MonKnowsMove(mon, move) == TRUE)
|
|
return ALREADY_KNOWS_MOVE;
|
|
else
|
|
return CAN_LEARN_MOVE;
|
|
}
|
|
|
|
static u16 GetTutorMove(u8 tutor)
|
|
{
|
|
return gTutorMoves[tutor];
|
|
}
|
|
|
|
static bool8 CanLearnTutorMove(u16 species, u8 tutor)
|
|
{
|
|
if (sTutorLearnsets[species] & (1 << tutor))
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void InitPartyMenuWindows(u8 layout)
|
|
{
|
|
u8 i;
|
|
|
|
switch (layout)
|
|
{
|
|
case PARTY_LAYOUT_SINGLE:
|
|
InitWindows(sSinglePartyMenuWindowTemplate);
|
|
break;
|
|
case PARTY_LAYOUT_DOUBLE:
|
|
InitWindows(sDoublePartyMenuWindowTemplate);
|
|
break;
|
|
case PARTY_LAYOUT_MULTI:
|
|
InitWindows(sMultiPartyMenuWindowTemplate);
|
|
break;
|
|
default: // PARTY_LAYOUT_MULTI_SHOWCASE
|
|
InitWindows(sShowcaseMultiPartyMenuWindowTemplate);
|
|
break;
|
|
}
|
|
DeactivateAllTextPrinters();
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
FillWindowPixelBuffer(i, PIXEL_FILL(0));
|
|
LoadUserWindowBorderGfx(0, 0x4F, 0xD0);
|
|
LoadPalette(GetOverworldTextboxPalettePtr(), 0xE0, 0x20);
|
|
LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
|
|
}
|
|
|
|
// TODO
|
|
static void sub_81B2428(bool8 chooseHalf)
|
|
{
|
|
u8 firstWindowId;
|
|
u8 windowId;
|
|
u8 offset;
|
|
u8 mainOffset;
|
|
|
|
if (gPartyMenu.menuType != PARTY_MENU_TYPE_IN_MULTI_BATTLE)
|
|
{
|
|
if (chooseHalf == TRUE)
|
|
{
|
|
firstWindowId = AddWindow(&gUnknown_08615918);
|
|
FillWindowPixelBuffer(firstWindowId, PIXEL_FILL(0));
|
|
mainOffset = GetStringCenterAlignXOffset(0, gMenuText_Confirm, 48);
|
|
AddTextPrinterParameterized4(firstWindowId, 0, mainOffset, 1, 0, 0, sFontColorTable[0], -1, gMenuText_Confirm);
|
|
PutWindowTilemap(firstWindowId);
|
|
CopyWindowToVram(firstWindowId, 2);
|
|
windowId = AddWindow(&gUnknown_08615910);
|
|
offset = 0;
|
|
}
|
|
else
|
|
{
|
|
windowId = AddWindow(&gUnknown_08615908);
|
|
offset = 3;
|
|
}
|
|
FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
|
|
if (gPartyMenu.menuType != PARTY_MENU_TYPE_SPIN_TRADE)
|
|
{
|
|
mainOffset = GetStringCenterAlignXOffset(0, gText_Cancel, 48);
|
|
AddTextPrinterParameterized3(windowId, 0, mainOffset + offset, 1, sFontColorTable[0], -1, gText_Cancel);
|
|
}
|
|
else
|
|
{
|
|
// Identical to above, Spin Trade wasnt implemented
|
|
mainOffset = GetStringCenterAlignXOffset(0, gText_Cancel2, 48);
|
|
AddTextPrinterParameterized3(windowId, 0, mainOffset + offset, 1, sFontColorTable[0], -1, gText_Cancel2);
|
|
}
|
|
PutWindowTilemap(windowId);
|
|
CopyWindowToVram(windowId, 2);
|
|
schedule_bg_copy_tilemap_to_vram(0);
|
|
}
|
|
}
|
|
|
|
static u16* GetPartyMenuPalBufferPtr(u8 paletteId)
|
|
{
|
|
return &sPartyMenuInternal->palBuffer[paletteId];
|
|
}
|
|
|
|
static void BlitBitmapToPartyWindow(u8 windowId, const u8 *b, u8 c, u8 x, u8 y, u8 width, u8 height)
|
|
{
|
|
u8 *pixels = AllocZeroed(height * width * 32);
|
|
u8 i, j;
|
|
|
|
if (pixels != NULL)
|
|
{
|
|
for (i = 0; i < height; i++)
|
|
{
|
|
for (j = 0; j < width; j++)
|
|
CpuCopy16(GetPartyMenuBgTile(b[x + j + ((y + i) * c)]), &pixels[(i * width + j) * 32], 32);
|
|
}
|
|
BlitBitmapToWindow(windowId, pixels, x * 8, y * 8, width * 8, height * 8);
|
|
Free(pixels);
|
|
}
|
|
}
|
|
|
|
static void BlitBitmapToPartyWindow_LeftColumn(u8 windowId, u8 x, u8 y, u8 width, u8 height, u8 isEgg)
|
|
{
|
|
if (width == 0 && height == 0)
|
|
{
|
|
width = 10;
|
|
height = 7;
|
|
}
|
|
if (isEgg == FALSE)
|
|
BlitBitmapToPartyWindow(windowId, sMainSlotTileNums, 10, x, y, width, height);
|
|
else
|
|
BlitBitmapToPartyWindow(windowId, sMainSlotTileNums_Egg, 10, x, y, width, height);
|
|
}
|
|
|
|
static void BlitBitmapToPartyWindow_RightColumn(u8 windowId, u8 x, u8 y, u8 width, u8 height, u8 isEgg)
|
|
{
|
|
if (width == 0 && height == 0)
|
|
{
|
|
width = 18;
|
|
height = 3;
|
|
}
|
|
if (isEgg == FALSE)
|
|
BlitBitmapToPartyWindow(windowId, sOtherSlotsTileNums, 18, x, y, width, height);
|
|
else
|
|
BlitBitmapToPartyWindow(windowId, sOtherSlotsTileNums_Egg, 18, x, y, width, height);
|
|
}
|
|
|
|
static void DrawEmptySlot(u8 windowId)
|
|
{
|
|
BlitBitmapToPartyWindow(windowId, sEmptySlotTileNums, 18, 0, 0, 18, 3);
|
|
}
|
|
|
|
// If LoadPartyBoxPalette is too dense, this macro could be used to replace the LoadPalette triplets
|
|
#define LOAD_PARTY_BOX_PAL(paletteIds, paletteOffsets) \
|
|
{ \
|
|
LoadPalette(GetPartyMenuPalBufferPtr(paletteIds[0]), paletteOffsets[0] + palNum, 2); \
|
|
LoadPalette(GetPartyMenuPalBufferPtr(paletteIds[1]), paletteOffsets[1] + palNum, 2); \
|
|
LoadPalette(GetPartyMenuPalBufferPtr(paletteIds[2]), paletteOffsets[2] + palNum, 2); \
|
|
}
|
|
|
|
static void LoadPartyBoxPalette(struct PartyMenuBox *menuBox, u8 palFlags)
|
|
{
|
|
u8 palNum = GetWindowAttribute(menuBox->windowId, WINDOW_PALETTE_NUM) * 16;
|
|
|
|
if (palFlags & PARTY_PAL_NO_MON)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxNoMonPalIds[0]), sPartyBoxNoMonPalOffsets[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxNoMonPalIds[1]), sPartyBoxNoMonPalOffsets[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxNoMonPalIds[2]), sPartyBoxNoMonPalOffsets[2] + palNum, 2);
|
|
}
|
|
else if (palFlags & PARTY_PAL_TO_SOFTBOIL)
|
|
{
|
|
if (palFlags & PARTY_PAL_SELECTED)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
else
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
}
|
|
else if (palFlags & PARTY_PAL_SWITCHING)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
else if (palFlags & PARTY_PAL_TO_SWITCH)
|
|
{
|
|
if (palFlags & PARTY_PAL_SELECTED)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
else
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxSelectedForActionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
}
|
|
else if (palFlags & PARTY_PAL_FAINTED)
|
|
{
|
|
if (palFlags & PARTY_PAL_SELECTED)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionFaintedPalIds[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionFaintedPalIds[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionFaintedPalIds[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
else
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxFaintedPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxFaintedPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxFaintedPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxFaintedPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxFaintedPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxFaintedPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
}
|
|
else if (palFlags & PARTY_PAL_MULTI_ALT)
|
|
{
|
|
if (palFlags & PARTY_PAL_SELECTED)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionMultiPalIds[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionMultiPalIds[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionMultiPalIds[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
else
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxMultiPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxMultiPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxMultiPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxMultiPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxMultiPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxMultiPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
}
|
|
else if (palFlags & PARTY_PAL_SELECTED)
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxCurrSelectionPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
else
|
|
{
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxEmptySlotPalIds1[0]), sPartyBoxPalOffsets1[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxEmptySlotPalIds1[1]), sPartyBoxPalOffsets1[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxEmptySlotPalIds1[2]), sPartyBoxPalOffsets1[2] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxEmptySlotPalIds2[0]), sPartyBoxPalOffsets2[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxEmptySlotPalIds2[1]), sPartyBoxPalOffsets2[1] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sPartyBoxEmptySlotPalIds2[2]), sPartyBoxPalOffsets2[2] + palNum, 2);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonBarDetail(u8 windowId, const u8 *str, u8 color, const u8 *align)
|
|
{
|
|
AddTextPrinterParameterized3(windowId, 0, align[0], align[1], sFontColorTable[color], 0, str);
|
|
}
|
|
|
|
static void DisplayPartyPokemonNickname(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c)
|
|
{
|
|
u8 nickname[POKEMON_NAME_LENGTH + 1];
|
|
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
if (c == 1)
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->dimensions[0] >> 3, menuBox->infoRects->dimensions[1] >> 3, menuBox->infoRects->dimensions[2] >> 3, menuBox->infoRects->dimensions[3] >> 3, FALSE);
|
|
GetMonNickname(mon, nickname);
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, nickname, 0, menuBox->infoRects->dimensions);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonLevelCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
u8 ailment = GetMonAilment(mon);
|
|
if (ailment == AILMENT_NONE || ailment == AILMENT_PKRS)
|
|
{
|
|
if (c != 0)
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->dimensions[4] >> 3, (menuBox->infoRects->dimensions[5] >> 3) + 1, menuBox->infoRects->dimensions[6] >> 3, menuBox->infoRects->dimensions[7] >> 3, FALSE);
|
|
if (c != 2)
|
|
DisplayPartyPokemonLevel(GetMonData(mon, MON_DATA_LEVEL), menuBox);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonLevel(u8 level, struct PartyMenuBox *menuBox)
|
|
{
|
|
ConvertIntToDecimalStringN(gStringVar2, level, STR_CONV_MODE_LEFT_ALIGN, 3);
|
|
StringCopy(gStringVar1, gText_LevelSymbol);
|
|
StringAppend(gStringVar1, gStringVar2);
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[4]);
|
|
}
|
|
|
|
static void DisplayPartyPokemonGenderNidoranCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c)
|
|
{
|
|
u8 nickname[POKEMON_NAME_LENGTH + 1];
|
|
|
|
if (c == 1)
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->dimensions[8] >> 3, (menuBox->infoRects->dimensions[9] >> 3) + 1, menuBox->infoRects->dimensions[10] >> 3, menuBox->infoRects->dimensions[11] >> 3, FALSE);
|
|
GetMonNickname(mon, nickname);
|
|
DisplayPartyPokemonGender(GetMonGender(mon), GetMonData(mon, MON_DATA_SPECIES), nickname, menuBox);
|
|
}
|
|
|
|
static void DisplayPartyPokemonGender(u8 gender, u16 species, u8 *nickname, struct PartyMenuBox *menuBox)
|
|
{
|
|
u8 palNum = GetWindowAttribute(menuBox->windowId, WINDOW_PALETTE_NUM) * 16;
|
|
|
|
if (species == SPECIES_NONE)
|
|
return;
|
|
if ((species == SPECIES_NIDORAN_M || species == SPECIES_NIDORAN_F) && StringCompare(nickname, gSpeciesNames[species]) == 0)
|
|
return;
|
|
switch (gender)
|
|
{
|
|
case MON_MALE:
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sGenderMalePalIds[0]), sGenderPalOffsets[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sGenderMalePalIds[1]), sGenderPalOffsets[1] + palNum, 2);
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, gText_MaleSymbol, 2, &menuBox->infoRects->dimensions[8]);
|
|
break;
|
|
case MON_FEMALE:
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sGenderFemalePalIds[0]), sGenderPalOffsets[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sGenderFemalePalIds[1]), sGenderPalOffsets[1] + palNum, 2);
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, gText_FemaleSymbol, 2, &menuBox->infoRects->dimensions[8]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonHPCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
if (c != 0)
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->dimensions[12] >> 3, (menuBox->infoRects->dimensions[13] >> 3) + 1, menuBox->infoRects->dimensions[14] >> 3, menuBox->infoRects->dimensions[15] >> 3, FALSE);
|
|
if (c != 2)
|
|
DisplayPartyPokemonHP(GetMonData(mon, MON_DATA_HP), menuBox);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonHP(u16 hp, struct PartyMenuBox *menuBox)
|
|
{
|
|
u8 *strOut = ConvertIntToDecimalStringN(gStringVar1, hp, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
|
|
strOut[0] = CHAR_SLASH;
|
|
strOut[1] = EOS;
|
|
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[12]);
|
|
}
|
|
|
|
static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
if (c != 0)
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, (menuBox->infoRects->dimensions[16] >> 3) + 1, (menuBox->infoRects->dimensions[17] >> 3) + 1, menuBox->infoRects->dimensions[18] >> 3, menuBox->infoRects->dimensions[19] >> 3, FALSE);
|
|
if (c != 2)
|
|
DisplayPartyPokemonMaxHP(GetMonData(mon, MON_DATA_MAX_HP), menuBox);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyPokemonMaxHP(u16 maxhp, struct PartyMenuBox *menuBox)
|
|
{
|
|
ConvertIntToDecimalStringN(gStringVar2, maxhp, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
StringCopy(gStringVar1, gText_Slash);
|
|
StringAppend(gStringVar1, gStringVar2);
|
|
DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[16]);
|
|
}
|
|
|
|
static void DisplayPartyPokemonHPBarCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
DisplayPartyPokemonHPBar(GetMonData(mon, MON_DATA_HP), GetMonData(mon, MON_DATA_MAX_HP), menuBox);
|
|
}
|
|
|
|
static void DisplayPartyPokemonHPBar(u16 hp, u16 maxhp, struct PartyMenuBox *menuBox)
|
|
{
|
|
u8 palNum = GetWindowAttribute(menuBox->windowId, WINDOW_PALETTE_NUM) * 16;
|
|
u8 hpFraction;
|
|
|
|
switch (GetHPBarLevel(hp, maxhp))
|
|
{
|
|
case HP_BAR_GREEN:
|
|
case HP_BAR_FULL:
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sHPBarGreenPalIds[0]), sHPBarPalOffsets[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sHPBarGreenPalIds[1]), sHPBarPalOffsets[1] + palNum, 2);
|
|
break;
|
|
case HP_BAR_YELLOW:
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sHPBarYellowPalIds[0]), sHPBarPalOffsets[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sHPBarYellowPalIds[1]), sHPBarPalOffsets[1] + palNum, 2);
|
|
break;
|
|
default:
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sHPBarRedPalIds[0]), sHPBarPalOffsets[0] + palNum, 2);
|
|
LoadPalette(GetPartyMenuPalBufferPtr(sHPBarRedPalIds[1]), sHPBarPalOffsets[1] + palNum, 2);
|
|
break;
|
|
}
|
|
|
|
hpFraction = GetScaledHPFraction(hp, maxhp, menuBox->infoRects->dimensions[22]);
|
|
FillWindowPixelRect(menuBox->windowId, sHPBarPalOffsets[1], menuBox->infoRects->dimensions[20], menuBox->infoRects->dimensions[21], hpFraction, 1);
|
|
FillWindowPixelRect(menuBox->windowId, sHPBarPalOffsets[0], menuBox->infoRects->dimensions[20], menuBox->infoRects->dimensions[21] + 1, hpFraction, 2);
|
|
if (hpFraction != menuBox->infoRects->dimensions[22])
|
|
{
|
|
// This appears to be an alternating fill
|
|
FillWindowPixelRect(menuBox->windowId, 0x0D, menuBox->infoRects->dimensions[20] + hpFraction, menuBox->infoRects->dimensions[21], menuBox->infoRects->dimensions[22] - hpFraction, 1);
|
|
FillWindowPixelRect(menuBox->windowId, 0x02, menuBox->infoRects->dimensions[20] + hpFraction, menuBox->infoRects->dimensions[21] + 1, menuBox->infoRects->dimensions[22] - hpFraction, 2);
|
|
}
|
|
CopyWindowToVram(menuBox->windowId, 2);
|
|
}
|
|
|
|
static void DisplayPartyPokemonDescriptionText(u8 stringID, struct PartyMenuBox *menuBox, u8 c)
|
|
{
|
|
if (c)
|
|
{
|
|
int width = ((menuBox->infoRects->descTextLeft % 8) + menuBox->infoRects->descTextWidth + 7) / 8;
|
|
int height = ((menuBox->infoRects->descTextTop % 8) + menuBox->infoRects->descTextHeight + 7) / 8;
|
|
menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->descTextLeft >> 3, menuBox->infoRects->descTextTop >> 3, width, height, TRUE);
|
|
}
|
|
if (c != 2)
|
|
AddTextPrinterParameterized3(menuBox->windowId, 1, menuBox->infoRects->descTextLeft, menuBox->infoRects->descTextTop, sFontColorTable[0], 0, sDescriptionStringTable[stringID]);
|
|
}
|
|
|
|
static void PartyMenuRemoveWindow(u8 *ptr)
|
|
{
|
|
if (*ptr != 0xFF)
|
|
{
|
|
ClearStdWindowAndFrameToTransparent(*ptr, 0);
|
|
RemoveWindow(*ptr);
|
|
*ptr = 0xFF;
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
}
|
|
|
|
void DisplayPartyMenuStdMessage(u32 stringID)
|
|
{
|
|
u8 *windowPtr = &sPartyMenuInternal->windowId[1];
|
|
|
|
if (*windowPtr != 0xFF)
|
|
PartyMenuRemoveWindow(windowPtr);
|
|
|
|
if (stringID != PARTY_MSG_NONE)
|
|
{
|
|
switch (stringID)
|
|
{
|
|
case PARTY_MSG_DO_WHAT_WITH_MON:
|
|
*windowPtr = AddWindow(&sDoWhatWithMonMsgWindowTemplate);
|
|
break;
|
|
case PARTY_MSG_DO_WHAT_WITH_ITEM:
|
|
*windowPtr = AddWindow(&sDoWhatWithItemMsgWindowTemplate);
|
|
break;
|
|
case PARTY_MSG_DO_WHAT_WITH_MAIL:
|
|
*windowPtr = AddWindow(&sDoWhatWithMailMsgWindowTemplate);
|
|
break;
|
|
case PARTY_MSG_RESTORE_WHICH_MOVE:
|
|
case PARTY_MSG_BOOST_PP_WHICH_MOVE:
|
|
*windowPtr = AddWindow(&sWhichMoveMsgWindowTemplate);
|
|
break;
|
|
case PARTY_MSG_ALREADY_HOLDING_ONE:
|
|
*windowPtr = AddWindow(&sAlreadyHoldingOneMsgWindowTemplate);
|
|
break;
|
|
default:
|
|
*windowPtr = AddWindow(&sDefaultPartyMsgWindowTemplate);
|
|
break;
|
|
}
|
|
if (stringID == PARTY_MSG_CHOOSE_MON)
|
|
{
|
|
if (sPartyMenuInternal->chooseHalf)
|
|
stringID = PARTY_MSG_CHOOSE_MON_AND_CONFIRM;
|
|
else if (sub_81B314C() == FALSE)
|
|
stringID = PARTY_MSG_CHOOSE_MON_OR_CANCEL;
|
|
}
|
|
DrawStdFrameWithCustomTileAndPalette(*windowPtr, FALSE, 0x4F, 0xD);
|
|
StringExpandPlaceholders(gStringVar4, sActionStringTable[stringID]);
|
|
AddTextPrinterParameterized(*windowPtr, 1, gStringVar4, 0, 1, 0, 0);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
}
|
|
|
|
// TOOD: TRUE if should be forced to choose mon, but why when nummons > 1
|
|
static bool8 sub_81B314C(void)
|
|
{
|
|
struct Pokemon *party = gPlayerParty;
|
|
u8 i;
|
|
u8 numAliveMons = 0;
|
|
|
|
if (gPartyMenu.action == PARTY_ACTION_SEND_OUT)
|
|
return TRUE;
|
|
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE && (GetMonData(&party[i], MON_DATA_HP) != 0 || GetMonData(&party[i], MON_DATA_IS_EGG)))
|
|
numAliveMons++;
|
|
if (numAliveMons > 1)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static u8 DisplaySelectionWindow(u8 windowType)
|
|
{
|
|
struct WindowTemplate window;
|
|
u8 cursorDimension;
|
|
u8 fontAttribute;
|
|
u8 i;
|
|
|
|
switch (windowType)
|
|
{
|
|
case SELECTWINDOW_ACTIONS:
|
|
SetWindowTemplateFields(&window, 2, 19, 19 - (sPartyMenuInternal->numActions * 2), 10, sPartyMenuInternal->numActions * 2, 14, 0x2E9);
|
|
break;
|
|
case SELECTWINDOW_ITEM:
|
|
window = sItemGiveTakeWindowTemplate;
|
|
break;
|
|
case SELECTWINDOW_MAIL:
|
|
window = sMailReadTakeWindowTemplate;
|
|
break;
|
|
default: // SELECTWINDOW_MOVES
|
|
window = sMoveSelectWindowTemplate;
|
|
break;
|
|
}
|
|
|
|
sPartyMenuInternal->windowId[0] = AddWindow(&window);
|
|
DrawStdFrameWithCustomTileAndPalette(sPartyMenuInternal->windowId[0], FALSE, 0x4F, 13);
|
|
if (windowType == 3)
|
|
return sPartyMenuInternal->windowId[0];
|
|
cursorDimension = GetMenuCursorDimensionByFont(1, 0);
|
|
fontAttribute = GetFontAttribute(1, 2);
|
|
|
|
for (i = 0; i < sPartyMenuInternal->numActions; i++)
|
|
{
|
|
u8 unk = (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) ? 4 : 3;
|
|
AddTextPrinterParameterized4(sPartyMenuInternal->windowId[0], 1, cursorDimension, (i * 16) + 1, fontAttribute, 0, sFontColorTable[unk], 0, sCursorOptions[sPartyMenuInternal->actions[i]].text);
|
|
}
|
|
|
|
InitMenuInUpperLeftCorner(sPartyMenuInternal->windowId[0], sPartyMenuInternal->numActions, 0, 1);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
|
|
return sPartyMenuInternal->windowId[0];
|
|
}
|
|
|
|
static void PartyMenuPrintText(const u8 *text)
|
|
{
|
|
DrawStdFrameWithCustomTileAndPalette(6, FALSE, 0x4F, 13);
|
|
gTextFlags.canABSpeedUpPrint = TRUE;
|
|
AddTextPrinterParameterized2(6, 1, text, GetPlayerTextSpeedDelay(), 0, 2, 1, 3);
|
|
}
|
|
|
|
static void PartyMenuDisplayYesNoMenu(void)
|
|
{
|
|
CreateYesNoMenu(&sPartyMenuYesNoWindowTemplate, 0x4F, 13, 0);
|
|
}
|
|
|
|
static u8 CreateLevelUpStatsWindow(void)
|
|
{
|
|
sPartyMenuInternal->windowId[0] = AddWindow(&sLevelUpStatsWindowTemplate);
|
|
DrawStdFrameWithCustomTileAndPalette(sPartyMenuInternal->windowId[0], FALSE, 0x4F, 13);
|
|
return sPartyMenuInternal->windowId[0];
|
|
}
|
|
|
|
static void RemoveLevelUpStatsWindow(void)
|
|
{
|
|
ClearWindowTilemap(sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
}
|
|
|
|
static void SetPartyMonSelectionActions(struct Pokemon *mons, u8 slotId, u8 action)
|
|
{
|
|
u8 i;
|
|
|
|
if (action == ACTIONS_NONE)
|
|
{
|
|
SetPartyMonFieldSelectionActions(mons, slotId);
|
|
}
|
|
else
|
|
{
|
|
sPartyMenuInternal->numActions = sPartyMenuActionCounts[action];
|
|
for (i = 0; i < sPartyMenuInternal->numActions; i++)
|
|
sPartyMenuInternal->actions[i] = sPartyMenuActions[action][i];
|
|
}
|
|
}
|
|
|
|
static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId)
|
|
{
|
|
u8 i, j;
|
|
|
|
sPartyMenuInternal->numActions = 0;
|
|
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SUMMARY);
|
|
|
|
// Add field moves to action list
|
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
|
{
|
|
for (j = 0; sFieldMoves[j] != FIELD_MOVE_TERMINATOR; j++)
|
|
{
|
|
if (GetMonData(&mons[slotId], i + MON_DATA_MOVE1) == sFieldMoves[j])
|
|
{
|
|
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, j + MENU_FIELD_MOVES);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!InBattlePike())
|
|
{
|
|
if (GetMonData(&mons[1], MON_DATA_SPECIES) != SPECIES_NONE)
|
|
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SWITCH);
|
|
if (ItemIsMail(GetMonData(&mons[slotId], MON_DATA_HELD_ITEM)))
|
|
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_MAIL);
|
|
else
|
|
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_ITEM);
|
|
}
|
|
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_CANCEL1);
|
|
}
|
|
|
|
static u8 GetPartyMenuActionsType(struct Pokemon *mon)
|
|
{
|
|
u32 actionType;
|
|
|
|
switch (gPartyMenu.menuType)
|
|
{
|
|
case PARTY_MENU_TYPE_FIELD:
|
|
if (InMultiBattleRoom() == TRUE || GetMonData(mon, MON_DATA_IS_EGG))
|
|
actionType = ACTIONS_SWITCH;
|
|
else
|
|
actionType = ACTIONS_NONE; // actions populated by SetPartyMonFieldSelectionActions
|
|
break;
|
|
case PARTY_MENU_TYPE_IN_BATTLE:
|
|
actionType = GetPartyMenuActionsTypeInBattle(mon);
|
|
break;
|
|
case PARTY_MENU_TYPE_CHOOSE_HALF:
|
|
switch (GetPartySlotEntryStatus(gPartyMenu.slotId))
|
|
{
|
|
default: // Not eligible
|
|
actionType = ACTIONS_SUMMARY_ONLY;
|
|
break;
|
|
case 0: // Eligible
|
|
actionType = ACTIONS_ENTER;
|
|
break;
|
|
case 1: // Already selected
|
|
actionType = ACTIONS_NO_ENTRY;
|
|
break;
|
|
}
|
|
break;
|
|
case PARTY_MENU_TYPE_DAYCARE:
|
|
actionType = (GetMonData(mon, MON_DATA_IS_EGG)) ? ACTIONS_SUMMARY_ONLY : ACTIONS_STORE;
|
|
break;
|
|
case PARTY_MENU_TYPE_UNION_ROOM_REGISTER:
|
|
actionType = ACTIONS_REGISTER;
|
|
break;
|
|
case PARTY_MENU_TYPE_UNION_ROOM_TRADE:
|
|
actionType = ACTIONS_TRADE;
|
|
break;
|
|
case PARTY_MENU_TYPE_SPIN_TRADE:
|
|
actionType = ACTIONS_SPIN_TRADE;
|
|
break;
|
|
case PARTY_MENU_TYPE_STORE_PYRAMID_HELD_ITEMS:
|
|
actionType = ACTIONS_TAKEITEM_TOSS;
|
|
break;
|
|
// The following have no selection actions because they exit immediately upon selection
|
|
// PARTY_MENU_TYPE_CONTEST
|
|
// PARTY_MENU_TYPE_CHOOSE_MON
|
|
// PARTY_MENU_TYPE_IN_MULTI_BATTLE ?? TODO
|
|
// PARTY_MENU_TYPE_MOVE_RELEARNER
|
|
// PARTY_MENU_TYPE_MINIGAME
|
|
default:
|
|
actionType = ACTIONS_NONE;
|
|
break;
|
|
}
|
|
return actionType;
|
|
}
|
|
|
|
static bool8 CreateSelectionWindow(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item;
|
|
|
|
GetMonNickname(mon, gStringVar1);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
if (gPartyMenu.menuType != PARTY_MENU_TYPE_STORE_PYRAMID_HELD_ITEMS)
|
|
{
|
|
SetPartyMonSelectionActions(gPlayerParty, gPartyMenu.slotId, GetPartyMenuActionsType(mon));
|
|
DisplaySelectionWindow(SELECTWINDOW_ACTIONS);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_DO_WHAT_WITH_MON);
|
|
}
|
|
else
|
|
{
|
|
item = GetMonData(mon, MON_DATA_HELD_ITEM);
|
|
if (item != ITEM_NONE)
|
|
{
|
|
SetPartyMonSelectionActions(gPlayerParty, gPartyMenu.slotId, GetPartyMenuActionsType(mon));
|
|
DisplaySelectionWindow(SELECTWINDOW_ITEM);
|
|
CopyItemName(item, gStringVar2);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_ALREADY_HOLDING_ONE);
|
|
}
|
|
else
|
|
{
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnNotHolding);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void Task_TryCreateSelectionWindow(u8 taskId)
|
|
{
|
|
if (CreateSelectionWindow(taskId))
|
|
{
|
|
gTasks[taskId].data[0] = 0xFF;
|
|
gTasks[taskId].func = Task_HandleSelectionMenuInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleSelectionMenuInput(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active && sub_81221EC() != TRUE)
|
|
{
|
|
s8 input;
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
if (sPartyMenuInternal->numActions <= 3)
|
|
input = Menu_ProcessInputNoWrapAround_other();
|
|
else
|
|
input = ProcessMenuInput_other();
|
|
|
|
data[0] = Menu_GetCursorPos();
|
|
switch (input)
|
|
{
|
|
case MENU_NOTHING_CHOSEN:
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[2]);
|
|
sCursorOptions[sPartyMenuInternal->actions[sPartyMenuInternal->numActions - 1]].func(taskId);
|
|
break;
|
|
default:
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[2]);
|
|
sCursorOptions[sPartyMenuInternal->actions[input]].func(taskId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CursorCb_Summary(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
sPartyMenuInternal->exitCallback = CB2_ShowPokemonSummaryScreen;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
|
|
static void CB2_ShowPokemonSummaryScreen(void)
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
|
|
{
|
|
UpdatePartyToBattleOrder();
|
|
ShowPokemonSummaryScreen(PSS_MODE_UNK1, gPlayerParty, gPartyMenu.slotId, gPlayerPartyCount - 1, CB2_ReturnToPartyMenuFromSummaryScreen);
|
|
}
|
|
else
|
|
{
|
|
ShowPokemonSummaryScreen(PSS_MODE_NORMAL, gPlayerParty, gPartyMenu.slotId, gPlayerPartyCount - 1, CB2_ReturnToPartyMenuFromSummaryScreen);
|
|
}
|
|
}
|
|
|
|
static void CB2_ReturnToPartyMenuFromSummaryScreen(void)
|
|
{
|
|
gPaletteFade.bufferTransferDisabled = TRUE;
|
|
gPartyMenu.slotId = gLastViewedMonIndex;
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_DO_WHAT_WITH_MON, Task_TryCreateSelectionWindow, gPartyMenu.exitCallback);
|
|
}
|
|
|
|
static void CursorCb_Switch(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
gPartyMenu.action = PARTY_ACTION_SWITCH;
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_MOVE_TO_WHERE);
|
|
AnimatePartySlot(gPartyMenu.slotId, 1);
|
|
gPartyMenu.slotId2 = gPartyMenu.slotId;
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
|
|
#define tSlot1Left data[0]
|
|
#define tSlot1Top data[1]
|
|
#define tSlot1Width data[2]
|
|
#define tSlot1Height data[3]
|
|
#define tSlot2Left data[4]
|
|
#define tSlot2Top data[5]
|
|
#define tSlot2Width data[6]
|
|
#define tSlot2Height data[7]
|
|
#define tSlot1Offset data[8]
|
|
#define tSlot2Offset data[9]
|
|
#define tSlot1SlideDir data[10]
|
|
#define tSlot2SlideDir data[11]
|
|
|
|
static void SwitchSelectedMons(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
u8 windowIds[2];
|
|
|
|
if (gPartyMenu.slotId2 == gPartyMenu.slotId)
|
|
{
|
|
FinishTwoMonAction(taskId);
|
|
}
|
|
else
|
|
{
|
|
// Initialize switching party mons slide animation
|
|
windowIds[0] = sPartyMenuBoxes[gPartyMenu.slotId].windowId;
|
|
tSlot1Left = GetWindowAttribute(windowIds[0], WINDOW_TILEMAP_LEFT);
|
|
tSlot1Top = GetWindowAttribute(windowIds[0], WINDOW_TILEMAP_TOP);
|
|
tSlot1Width = GetWindowAttribute(windowIds[0], WINDOW_WIDTH);
|
|
tSlot1Height = GetWindowAttribute(windowIds[0], WINDOW_HEIGHT);
|
|
tSlot1Offset = 0;
|
|
if (tSlot1Width == 10)
|
|
tSlot1SlideDir = -1;
|
|
else
|
|
tSlot1SlideDir = 1;
|
|
windowIds[1] = sPartyMenuBoxes[gPartyMenu.slotId2].windowId;
|
|
tSlot2Left = GetWindowAttribute(windowIds[1], WINDOW_TILEMAP_LEFT);
|
|
tSlot2Top = GetWindowAttribute(windowIds[1], WINDOW_TILEMAP_TOP);
|
|
tSlot2Width = GetWindowAttribute(windowIds[1], WINDOW_WIDTH);
|
|
tSlot2Height = GetWindowAttribute(windowIds[1], WINDOW_HEIGHT);
|
|
tSlot2Offset = 0;
|
|
if (tSlot2Width == 10)
|
|
tSlot2SlideDir = -1;
|
|
else
|
|
tSlot2SlideDir = 1;
|
|
sSlot1TilemapBuffer = Alloc(tSlot1Width * (tSlot1Height << 1));
|
|
sSlot2TilemapBuffer = Alloc(tSlot2Width * (tSlot2Height << 1));
|
|
CopyToBufferFromBgTilemap(0, sSlot1TilemapBuffer, tSlot1Left, tSlot1Top, tSlot1Width, tSlot1Height);
|
|
CopyToBufferFromBgTilemap(0, sSlot2TilemapBuffer, tSlot2Left, tSlot2Top, tSlot2Width, tSlot2Height);
|
|
ClearWindowTilemap(windowIds[0]);
|
|
ClearWindowTilemap(windowIds[1]);
|
|
gPartyMenu.action = PARTY_ACTION_SWITCHING;
|
|
AnimatePartySlot(gPartyMenu.slotId, 1);
|
|
AnimatePartySlot(gPartyMenu.slotId2, 1);
|
|
SlidePartyMenuBoxOneStep(taskId);
|
|
gTasks[taskId].func = Task_SlideSelectedSlotsOffscreen;
|
|
}
|
|
}
|
|
|
|
// returns FALSE if the slot has slid fully offscreen / back onscreen
|
|
static bool8 TryMovePartySlot(s16 a, s16 srcWidth, u8 *srcX, u8 *srcHeight, u8 *destY)
|
|
{
|
|
if ((a + srcWidth) < 0)
|
|
return FALSE;
|
|
if (a > 31)
|
|
return FALSE;
|
|
|
|
if (a < 0)
|
|
{
|
|
*srcX = a * -1;
|
|
*srcHeight = 0;
|
|
*destY = srcWidth + a;
|
|
}
|
|
else
|
|
{
|
|
*srcX = 0;
|
|
*srcHeight = a;
|
|
if ((a + srcWidth) > 31)
|
|
*destY = 32 - a;
|
|
else
|
|
*destY = srcWidth;
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void MoveAndBufferPartySlot(const void *rectSrc, s16 a, s16 destX, s16 srcWidth, s16 rectWidth, s16 offset)
|
|
{
|
|
u8 srcX, srcHeight, destY;
|
|
|
|
if (TryMovePartySlot(a, srcWidth, &srcX, &srcHeight, &destY))
|
|
{
|
|
FillBgTilemapBufferRect_Palette0(0, 0, srcHeight, destX, destY, rectWidth);
|
|
if (TryMovePartySlot(a + offset, srcWidth, &srcX, &srcHeight, &destY))
|
|
CopyRectToBgTilemapBufferRect(0, rectSrc, srcX, 0, srcWidth, rectWidth, srcHeight, destX, destY, rectWidth, 17, 0, 0);
|
|
}
|
|
}
|
|
|
|
static void MovePartyMenuBoxSprites(struct PartyMenuBox *menuBox, s16 offset)
|
|
{
|
|
gSprites[menuBox->pokeballSpriteId].pos2.x += offset * 8;
|
|
gSprites[menuBox->itemSpriteId].pos2.x += offset * 8;
|
|
gSprites[menuBox->monSpriteId].pos2.x += offset * 8;
|
|
gSprites[menuBox->statusSpriteId].pos2.x += offset * 8;
|
|
}
|
|
|
|
static void SlidePartyMenuBoxSpritesOneStep(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
if (tSlot1SlideDir != 0)
|
|
MovePartyMenuBoxSprites(&sPartyMenuBoxes[gPartyMenu.slotId], tSlot1SlideDir);
|
|
if (tSlot2SlideDir != 0)
|
|
MovePartyMenuBoxSprites(&sPartyMenuBoxes[gPartyMenu.slotId2], tSlot2SlideDir);
|
|
}
|
|
|
|
static void SlidePartyMenuBoxOneStep(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
if (tSlot1SlideDir != 0)
|
|
MoveAndBufferPartySlot(sSlot1TilemapBuffer, tSlot1Left + tSlot1Offset, tSlot1Top, tSlot1Width, tSlot1Height, tSlot1SlideDir);
|
|
if (tSlot2SlideDir != 0)
|
|
MoveAndBufferPartySlot(sSlot2TilemapBuffer, tSlot2Left + tSlot2Offset, tSlot2Top, tSlot2Width, tSlot2Height, tSlot2SlideDir);
|
|
schedule_bg_copy_tilemap_to_vram(0);
|
|
}
|
|
|
|
static void Task_SlideSelectedSlotsOffscreen(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
u16 slidingSlotPositions[2];
|
|
|
|
SlidePartyMenuBoxOneStep(taskId);
|
|
SlidePartyMenuBoxSpritesOneStep(taskId);
|
|
tSlot1Offset += tSlot1SlideDir;
|
|
tSlot2Offset += tSlot2SlideDir;
|
|
slidingSlotPositions[0] = tSlot1Left + tSlot1Offset;
|
|
slidingSlotPositions[1] = tSlot2Left + tSlot2Offset;
|
|
|
|
// Both slots have slid offscreen
|
|
if (slidingSlotPositions[0] > 33 && slidingSlotPositions[1] > 33)
|
|
{
|
|
tSlot1SlideDir *= -1;
|
|
tSlot2SlideDir *= -1;
|
|
SwitchPartyMon();
|
|
DisplayPartyPokemonData(gPartyMenu.slotId);
|
|
DisplayPartyPokemonData(gPartyMenu.slotId2);
|
|
PutWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId].windowId);
|
|
PutWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId2].windowId);
|
|
CopyToBufferFromBgTilemap(0, sSlot1TilemapBuffer, tSlot1Left, tSlot1Top, tSlot1Width, tSlot1Height);
|
|
CopyToBufferFromBgTilemap(0, sSlot2TilemapBuffer, tSlot2Left, tSlot2Top, tSlot2Width, tSlot2Height);
|
|
ClearWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId].windowId);
|
|
ClearWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId2].windowId);
|
|
gTasks[taskId].func = Task_SlideSelectedSlotsOnscreen;
|
|
}
|
|
}
|
|
|
|
static void Task_SlideSelectedSlotsOnscreen(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
SlidePartyMenuBoxOneStep(taskId);
|
|
SlidePartyMenuBoxSpritesOneStep(taskId);
|
|
|
|
// Both slots have slid back onscreen
|
|
if (tSlot1SlideDir == 0 && tSlot2SlideDir == 0)
|
|
{
|
|
PutWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId].windowId);
|
|
PutWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId2].windowId);
|
|
schedule_bg_copy_tilemap_to_vram(0);
|
|
Free(sSlot1TilemapBuffer);
|
|
Free(sSlot2TilemapBuffer);
|
|
FinishTwoMonAction(taskId);
|
|
}
|
|
// Continue sliding
|
|
else
|
|
{
|
|
tSlot1Offset += tSlot1SlideDir;
|
|
tSlot2Offset += tSlot2SlideDir;
|
|
if (tSlot1Offset == 0)
|
|
tSlot1SlideDir = 0;
|
|
if (tSlot2Offset == 0)
|
|
tSlot2SlideDir = 0;
|
|
}
|
|
}
|
|
|
|
static void SwitchMenuBoxSprites(u8 *spriteIdPtr1, u8 *spriteIdPtr2)
|
|
{
|
|
u8 spriteIdBuffer = *spriteIdPtr1;
|
|
u16 xBuffer1, yBuffer1, xBuffer2, yBuffer2;
|
|
|
|
*spriteIdPtr1 = *spriteIdPtr2;
|
|
*spriteIdPtr2 = spriteIdBuffer;
|
|
xBuffer1 = gSprites[*spriteIdPtr1].pos1.x;
|
|
yBuffer1 = gSprites[*spriteIdPtr1].pos1.y;
|
|
xBuffer2 = gSprites[*spriteIdPtr1].pos2.x;
|
|
yBuffer2 = gSprites[*spriteIdPtr1].pos2.y;
|
|
gSprites[*spriteIdPtr1].pos1.x = gSprites[*spriteIdPtr2].pos1.x;
|
|
gSprites[*spriteIdPtr1].pos1.y = gSprites[*spriteIdPtr2].pos1.y;
|
|
gSprites[*spriteIdPtr1].pos2.x = gSprites[*spriteIdPtr2].pos2.x;
|
|
gSprites[*spriteIdPtr1].pos2.y = gSprites[*spriteIdPtr2].pos2.y;
|
|
gSprites[*spriteIdPtr2].pos1.x = xBuffer1;
|
|
gSprites[*spriteIdPtr2].pos1.y = yBuffer1;
|
|
gSprites[*spriteIdPtr2].pos2.x = xBuffer2;
|
|
gSprites[*spriteIdPtr2].pos2.y = yBuffer2;
|
|
}
|
|
|
|
static void SwitchPartyMon(void)
|
|
{
|
|
struct PartyMenuBox *menuBoxes[2];
|
|
struct Pokemon *mon1, *mon2;
|
|
struct Pokemon *monBuffer;
|
|
|
|
menuBoxes[0] = &sPartyMenuBoxes[gPartyMenu.slotId];
|
|
menuBoxes[1] = &sPartyMenuBoxes[gPartyMenu.slotId2];
|
|
mon1 = &gPlayerParty[gPartyMenu.slotId];
|
|
mon2 = &gPlayerParty[gPartyMenu.slotId2];
|
|
monBuffer = Alloc(sizeof(struct Pokemon));
|
|
*monBuffer = *mon1;
|
|
*mon1 = *mon2;
|
|
*mon2 = *monBuffer;
|
|
Free(monBuffer);
|
|
SwitchMenuBoxSprites(&menuBoxes[0]->pokeballSpriteId, &menuBoxes[1]->pokeballSpriteId);
|
|
SwitchMenuBoxSprites(&menuBoxes[0]->itemSpriteId, &menuBoxes[1]->itemSpriteId);
|
|
SwitchMenuBoxSprites(&menuBoxes[0]->monSpriteId, &menuBoxes[1]->monSpriteId);
|
|
SwitchMenuBoxSprites(&menuBoxes[0]->statusSpriteId, &menuBoxes[1]->statusSpriteId);
|
|
}
|
|
|
|
// Finish switching mons or using Softboiled
|
|
static void FinishTwoMonAction(u8 taskId)
|
|
{
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
gPartyMenu.action = PARTY_ACTION_CHOOSE_MON;
|
|
AnimatePartySlot(gPartyMenu.slotId, 0);
|
|
gPartyMenu.slotId = gPartyMenu.slotId2;
|
|
AnimatePartySlot(gPartyMenu.slotId2, 1);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
|
|
#undef tSlot1Left
|
|
#undef tSlot1Top
|
|
#undef tSlot1Width
|
|
#undef tSlot1Height
|
|
#undef tSlot2Left
|
|
#undef tSlot2Top
|
|
#undef tSlot2Width
|
|
#undef tSlot2Height
|
|
#undef tSlot1Offset
|
|
#undef tSlot2Offset
|
|
#undef tSlot1SlideDir
|
|
#undef tSlot2SlideDir
|
|
|
|
static void CursorCb_Cancel1(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_DAYCARE)
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON_2);
|
|
else
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
|
|
static void CursorCb_Item(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
SetPartyMonSelectionActions(gPlayerParty, gPartyMenu.slotId, ACTIONS_ITEM);
|
|
DisplaySelectionWindow(SELECTWINDOW_ITEM);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_DO_WHAT_WITH_ITEM);
|
|
gTasks[taskId].data[0] = 0xFF;
|
|
gTasks[taskId].func = Task_HandleSelectionMenuInput;
|
|
}
|
|
|
|
static void CursorCb_Give(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
sPartyMenuInternal->exitCallback = CB2_SelectBagItemToGive;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
|
|
static void CB2_SelectBagItemToGive(void)
|
|
{
|
|
if (InBattlePyramid() == FALSE)
|
|
GoToBagMenu(RETURN_LOCATION_POKEMON_LIST, POCKETS_COUNT, CB2_GiveHoldItem);
|
|
else
|
|
GoToBattlePyramidBagMenu(2, CB2_GiveHoldItem);
|
|
}
|
|
|
|
static void CB2_GiveHoldItem(void)
|
|
{
|
|
if (gSpecialVar_ItemId == ITEM_NONE)
|
|
{
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_NONE, Task_TryCreateSelectionWindow, gPartyMenu.exitCallback);
|
|
}
|
|
else
|
|
{
|
|
sPartyMenuItemId = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_HELD_ITEM);
|
|
|
|
// Already holding item
|
|
if (sPartyMenuItemId != ITEM_NONE)
|
|
{
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_NONE, Task_SwitchHoldItemsPrompt, gPartyMenu.exitCallback);
|
|
}
|
|
// Give mail
|
|
else if (ItemIsMail(gSpecialVar_ItemId))
|
|
{
|
|
RemoveBagItem(gSpecialVar_ItemId, 1);
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId);
|
|
CB2_WriteMailToGiveMon();
|
|
}
|
|
// Give item
|
|
else
|
|
{
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_NONE, Task_GiveHoldItem, gPartyMenu.exitCallback);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_GiveHoldItem(u8 taskId)
|
|
{
|
|
u16 item;
|
|
|
|
if (!gPaletteFade.active)
|
|
{
|
|
item = gSpecialVar_ItemId;
|
|
DisplayGaveHeldItemMessage(&gPlayerParty[gPartyMenu.slotId], item, FALSE, 0);
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], item);
|
|
RemoveBagItem(item, 1);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
}
|
|
|
|
static void Task_SwitchHoldItemsPrompt(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
DisplayAlreadyHoldingItemSwitchMessage(&gPlayerParty[gPartyMenu.slotId], sPartyMenuItemId, TRUE);
|
|
gTasks[taskId].func = Task_SwitchItemsYesNo;
|
|
}
|
|
}
|
|
|
|
static void Task_SwitchItemsYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleSwitchItemsYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleSwitchItemsYesNoInput(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0: // Yes, switch items
|
|
RemoveBagItem(gSpecialVar_ItemId, 1);
|
|
|
|
// No room to return held item to bag
|
|
if (AddBagItem(sPartyMenuItemId, 1) == FALSE)
|
|
{
|
|
AddBagItem(gSpecialVar_ItemId, 1);
|
|
BufferBagFullCantTakeItemMessage(sPartyMenuItemId);
|
|
DisplayPartyMenuMessage(gStringVar4, FALSE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
// Giving mail
|
|
else if (ItemIsMail(gSpecialVar_ItemId))
|
|
{
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId);
|
|
gTasks[taskId].func = Task_WriteMailToGiveMonAfterText;
|
|
}
|
|
// Giving item
|
|
else
|
|
{
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId);
|
|
DisplaySwitchedHeldItemMessage(gSpecialVar_ItemId, sPartyMenuItemId, TRUE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1: // No
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void Task_WriteMailToGiveMonAfterText(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
sPartyMenuInternal->exitCallback = CB2_WriteMailToGiveMon;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
|
|
static void CB2_WriteMailToGiveMon(void)
|
|
{
|
|
u8 mail = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_MAIL);
|
|
|
|
DoEasyChatScreen(
|
|
EASY_CHAT_TYPE_MAIL,
|
|
gSaveBlock1Ptr->mail[mail].words,
|
|
CB2_ReturnToPartyMenuFromWritingMail,
|
|
EASY_CHAT_PERSON_DISPLAY_NONE);
|
|
}
|
|
|
|
static void CB2_ReturnToPartyMenuFromWritingMail(void)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
|
|
|
|
if (gSpecialVar_Result == FALSE)
|
|
{
|
|
TakeMailFromMon(mon);
|
|
SetMonData(mon, MON_DATA_HELD_ITEM, &sPartyMenuItemId);
|
|
RemoveBagItem(sPartyMenuItemId, 1);
|
|
AddBagItem(item, 1);
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_CHOOSE_MON, Task_TryCreateSelectionWindow, gPartyMenu.exitCallback);
|
|
}
|
|
else
|
|
{
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_NONE, sub_81B4624, gPartyMenu.exitCallback);
|
|
}
|
|
}
|
|
|
|
static void sub_81B4624(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
if (sPartyMenuItemId == ITEM_NONE)
|
|
DisplayGaveHeldItemMessage(&gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId, FALSE, 0);
|
|
else
|
|
DisplaySwitchedHeldItemMessage(gSpecialVar_ItemId, sPartyMenuItemId, FALSE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
}
|
|
|
|
static void Task_UpdateHeldItemSprite(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
UpdatePartyMonHeldItemSprite(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_STORE_PYRAMID_HELD_ITEMS)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_HELD_ITEM) != ITEM_NONE)
|
|
DisplayPartyPokemonDescriptionText(PARTYBOX_DESC_HAVE, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
else
|
|
DisplayPartyPokemonDescriptionText(PARTYBOX_DESC_DONT_HAVE, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
}
|
|
Task_ReturnToChooseMonAfterText(taskId);
|
|
}
|
|
}
|
|
|
|
static void CursorCb_TakeItem(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
|
|
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
switch (TryTakeMonItem(mon))
|
|
{
|
|
case 0: // Not holding item
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnNotHolding);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
break;
|
|
case 1: // No room to take item
|
|
BufferBagFullCantTakeItemMessage(item);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
break;
|
|
default: // Took item
|
|
DisplayTookHeldItemMessage(mon, item, TRUE);
|
|
break;
|
|
}
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
|
|
static void CursorCb_Toss(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
|
|
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
if (item == ITEM_NONE)
|
|
{
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnNotHolding);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
else
|
|
{
|
|
CopyItemName(item, gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_ThrowAwayItem);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_TossHeldItemYesNo;
|
|
}
|
|
}
|
|
|
|
static void Task_TossHeldItemYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleTossHeldItemYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleTossHeldItemYesNoInput(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
CopyItemName(GetMonData(mon, MON_DATA_HELD_ITEM), gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_ItemThrownAway);
|
|
DisplayPartyMenuMessage(gStringVar4, FALSE);
|
|
gTasks[taskId].func = Task_TossHeldItem;
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void Task_TossHeldItem(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
u16 item = ITEM_NONE;
|
|
|
|
SetMonData(mon, MON_DATA_HELD_ITEM, &item);
|
|
UpdatePartyMonHeldItemSprite(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
|
|
DisplayPartyPokemonDescriptionText(PARTYBOX_DESC_DONT_HAVE, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
}
|
|
|
|
static void CursorCb_Mail(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
SetPartyMonSelectionActions(gPlayerParty, gPartyMenu.slotId, ACTIONS_MAIL);
|
|
DisplaySelectionWindow(SELECTWINDOW_MAIL);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_DO_WHAT_WITH_MAIL);
|
|
gTasks[taskId].data[0] = 0xFF;
|
|
gTasks[taskId].func = Task_HandleSelectionMenuInput;
|
|
}
|
|
|
|
static void CursorCb_Read(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
sPartyMenuInternal->exitCallback = sub_81B4A98;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
|
|
static void sub_81B4A98(void)
|
|
{
|
|
ReadMail(&gSaveBlock1Ptr->mail[GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_MAIL)], sub_81B4AE0, 1);
|
|
}
|
|
|
|
static void sub_81B4AE0(void)
|
|
{
|
|
gPaletteFade.bufferTransferDisabled = TRUE;
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_DO_WHAT_WITH_MON, Task_TryCreateSelectionWindow, gPartyMenu.exitCallback);
|
|
}
|
|
|
|
static void CursorCb_TakeMail(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
DisplayPartyMenuMessage(gText_SendMailToPC, TRUE);
|
|
gTasks[taskId].func = sub_81B4B6C;
|
|
}
|
|
|
|
static void sub_81B4B6C(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = sub_81B4BA0;
|
|
}
|
|
}
|
|
|
|
static void sub_81B4BA0(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
if (TakeMailFromMon2(&gPlayerParty[gPartyMenu.slotId]) != 0xFF)
|
|
{
|
|
DisplayPartyMenuMessage(gText_MailSentToPC, FALSE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
else
|
|
{
|
|
DisplayPartyMenuMessage(gText_PCMailboxFull, FALSE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
DisplayPartyMenuMessage(gText_MailMessageWillBeLost, TRUE);
|
|
gTasks[taskId].func = sub_81B4C60;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void sub_81B4C60(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = sub_81B4C94;
|
|
}
|
|
}
|
|
|
|
static void sub_81B4C94(u8 taskId)
|
|
{
|
|
u16 item;
|
|
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
item = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_HELD_ITEM);
|
|
if (AddBagItem(item, 1) == TRUE)
|
|
{
|
|
TakeMailFromMon(&gPlayerParty[gPartyMenu.slotId]);
|
|
DisplayPartyMenuMessage(gText_MailTakenFromPkmn, FALSE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
|
}
|
|
else
|
|
{
|
|
BufferBagFullCantTakeItemMessage(item);
|
|
DisplayPartyMenuMessage(gStringVar4, FALSE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void CursorCb_Cancel2(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
SetPartyMonSelectionActions(gPlayerParty, gPartyMenu.slotId, GetPartyMenuActionsType(mon));
|
|
if (gPartyMenu.menuType != PARTY_MENU_TYPE_STORE_PYRAMID_HELD_ITEMS)
|
|
{
|
|
DisplaySelectionWindow(SELECTWINDOW_ACTIONS);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_DO_WHAT_WITH_MON);
|
|
}
|
|
else
|
|
{
|
|
DisplaySelectionWindow(SELECTWINDOW_ITEM);
|
|
CopyItemName(GetMonData(mon, MON_DATA_HELD_ITEM), gStringVar2);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_ALREADY_HOLDING_ONE);
|
|
}
|
|
gTasks[taskId].data[0] = 0xFF;
|
|
gTasks[taskId].func = Task_HandleSelectionMenuInput;
|
|
}
|
|
|
|
static void CursorCb_SendMon(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
if (TrySwitchInPokemon() == TRUE)
|
|
{
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
else
|
|
{
|
|
// gStringVar4 below is the error message buffered by TrySwitchInPokemon
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
}
|
|
|
|
static void CursorCb_Enter(u8 taskId)
|
|
{
|
|
u8 maxBattlers;
|
|
u8 i;
|
|
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
maxBattlers = GetMaxBattleEntries();
|
|
for (i = 0; i < maxBattlers; i++)
|
|
{
|
|
if (gSelectedOrderFromParty[i] == 0)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
gSelectedOrderFromParty[i] = gPartyMenu.slotId + 1;
|
|
DisplayPartyPokemonDescriptionText(i + PARTYBOX_DESC_FIRST, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
if (i == (maxBattlers - 1))
|
|
sub_81B4F88();
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
return;
|
|
}
|
|
}
|
|
ConvertIntToDecimalStringN(gStringVar1, maxBattlers, STR_CONV_MODE_LEFT_ALIGN, 1);
|
|
StringExpandPlaceholders(gStringVar4, gText_NoMoreThanVar1Pkmn);
|
|
PlaySE(SE_HAZURE);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
|
|
static void sub_81B4F88(void)
|
|
{
|
|
AnimatePartySlot(gPartyMenu.slotId, 0);
|
|
gPartyMenu.slotId = PARTY_SIZE;
|
|
AnimatePartySlot(gPartyMenu.slotId, 1);
|
|
}
|
|
|
|
static void CursorCb_NoEntry(u8 taskId)
|
|
{
|
|
u8 maxBattlers;
|
|
u8 i, j;
|
|
|
|
PlaySE(SE_SELECT);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
maxBattlers = GetMaxBattleEntries();
|
|
for (i = 0; i < maxBattlers; i++)
|
|
{
|
|
if (gSelectedOrderFromParty[i] == (gPartyMenu.slotId + 1))
|
|
{
|
|
for (j = i; j < (maxBattlers - 1); j++)
|
|
gSelectedOrderFromParty[j] = gSelectedOrderFromParty[j + 1];
|
|
gSelectedOrderFromParty[j] = 0;
|
|
break;
|
|
}
|
|
}
|
|
DisplayPartyPokemonDescriptionText(PARTYBOX_DESC_ABLE_3, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
for (i = 0; i < (maxBattlers - 1); i++)
|
|
{
|
|
if (gSelectedOrderFromParty[i] != 0)
|
|
DisplayPartyPokemonDescriptionText(i + PARTYBOX_DESC_FIRST, &sPartyMenuBoxes[gSelectedOrderFromParty[i] - 1], 1);
|
|
}
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
|
|
static void CursorCb_Store(u8 taskId)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
|
|
// Register mon for the Trading Board in Union Room
|
|
static void CursorCb_Register(u8 taskId)
|
|
{
|
|
u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2);
|
|
u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
|
|
u8 obedience = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_OBEDIENCE);
|
|
|
|
switch (CanRegisterMonForTradingBoard(*(struct UnkLinkRfuStruct_02022B14Substruct *)sub_800F7DC(), species2, species, obedience))
|
|
{
|
|
case CANT_REGISTER_MON:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow);
|
|
break;
|
|
case CANT_REGISTER_EGG:
|
|
StringExpandPlaceholders(gStringVar4, gText_EggCantBeTradedNow);
|
|
break;
|
|
default:
|
|
PlaySE(SE_SELECT);
|
|
Task_ClosePartyMenu(taskId);
|
|
return;
|
|
}
|
|
PlaySE(SE_HAZURE);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
StringAppend(gStringVar4, gText_PauseUntilPress);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
|
|
static void CursorCb_Trade1(u8 taskId)
|
|
{
|
|
u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2);
|
|
u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
|
|
u8 obedience = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_OBEDIENCE);
|
|
u32 stringId = GetUnionRoomTradeMessageId(*(struct UnkLinkRfuStruct_02022B14Substruct *)sub_800F7DC(), gUnknown_02022C38, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, obedience);
|
|
|
|
if (stringId != UR_TRADE_MSG_NONE)
|
|
{
|
|
StringExpandPlaceholders(gStringVar4, sUnionRoomTradeMessages[stringId - 1]);
|
|
PlaySE(SE_HAZURE);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
StringAppend(gStringVar4, gText_PauseUntilPress);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
else
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
|
|
// Spin Trade (based on the translation of the Japanese trade prompt)
|
|
// Not fully implemented, and normally unreachable because PARTY_MENU_TYPE_SPIN_TRADE is never used
|
|
static void CursorCb_Trade2(u8 taskId)
|
|
{
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
switch (CanSpinTradeMon(gPlayerParty, gPartyMenu.slotId))
|
|
{
|
|
case CANT_TRADE_LAST_MON:
|
|
StringExpandPlaceholders(gStringVar4, gText_OnlyPkmnForBattle);
|
|
break;
|
|
case CANT_TRADE_NATIONAL:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow);
|
|
break;
|
|
case CANT_TRADE_EGG_YET:
|
|
StringExpandPlaceholders(gStringVar4, gText_EggCantBeTradedNow);
|
|
break;
|
|
default: // CAN_TRADE_MON
|
|
PlaySE(SE_SELECT);
|
|
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gJPText_AreYouSureYouWantToSpinTradeMon);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_SpinTradeYesNo;
|
|
return;
|
|
}
|
|
PlaySE(SE_HAZURE);
|
|
StringAppend(gStringVar4, gText_PauseUntilPress);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
|
|
static void Task_SpinTradeYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleSpinTradeYesNoInput;
|
|
}
|
|
}
|
|
|
|
// See comment on CursorCb_Trade2. Selecting YES (0) to spin trade just closes the party menu
|
|
static void Task_HandleSpinTradeYesNoInput(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
Task_ReturnToChooseMonAfterText(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void CursorCb_FieldMove(u8 taskId)
|
|
{
|
|
u8 fieldMove = sPartyMenuInternal->actions[Menu_GetCursorPos()] - MENU_FIELD_MOVES;
|
|
const struct MapHeader *mapHeader;
|
|
|
|
PlaySE(SE_SELECT);
|
|
if (sFieldMoveCursorCallbacks[fieldMove].fieldMoveFunc == NULL)
|
|
return;
|
|
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
if (sub_81221AC() == TRUE || InUnionRoom() == TRUE)
|
|
{
|
|
if (fieldMove == FIELD_MOVE_MILK_DRINK || fieldMove == FIELD_MOVE_SOFT_BOILED)
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CANT_USE_HERE);
|
|
else
|
|
DisplayPartyMenuStdMessage(sFieldMoveCursorCallbacks[fieldMove].msgId);
|
|
|
|
gTasks[taskId].func = Task_CancelAfterAorBPress;
|
|
}
|
|
else
|
|
{
|
|
// All field moves before WATERFALL are HMs.
|
|
if (fieldMove <= FIELD_MOVE_WATERFALL && FlagGet(FLAG_BADGE01_GET + fieldMove) != TRUE)
|
|
{
|
|
DisplayPartyMenuMessage(gText_CantUseUntilNewBadge, TRUE);
|
|
gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
|
|
}
|
|
else if (sFieldMoveCursorCallbacks[fieldMove].fieldMoveFunc() == TRUE)
|
|
{
|
|
switch (fieldMove)
|
|
{
|
|
case FIELD_MOVE_MILK_DRINK:
|
|
case FIELD_MOVE_SOFT_BOILED:
|
|
ChooseMonForSoftboiled(taskId);
|
|
break;
|
|
case FIELD_MOVE_TELEPORT:
|
|
mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->lastHealLocation.mapGroup, gSaveBlock1Ptr->lastHealLocation.mapNum);
|
|
GetMapNameGeneric(gStringVar1, mapHeader->regionMapSectionId);
|
|
StringExpandPlaceholders(gStringVar4, gText_ReturnToHealingSpot);
|
|
DisplayFieldMoveExitAreaMessage(taskId);
|
|
sPartyMenuInternal->data[0] = fieldMove;
|
|
break;
|
|
case FIELD_MOVE_DIG:
|
|
mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->escapeWarp.mapGroup, gSaveBlock1Ptr->escapeWarp.mapNum);
|
|
GetMapNameGeneric(gStringVar1, mapHeader->regionMapSectionId);
|
|
StringExpandPlaceholders(gStringVar4, gText_EscapeFromHere);
|
|
DisplayFieldMoveExitAreaMessage(taskId);
|
|
sPartyMenuInternal->data[0] = fieldMove;
|
|
break;
|
|
case FIELD_MOVE_FLY:
|
|
gPartyMenu.exitCallback = MCB2_FlyMap;
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
default:
|
|
gPartyMenu.exitCallback = CB2_ReturnToField;
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
}
|
|
}
|
|
// Cant use Field Move
|
|
else
|
|
{
|
|
switch (fieldMove)
|
|
{
|
|
case FIELD_MOVE_SURF:
|
|
DisplayCantUseSurfMessage();
|
|
break;
|
|
case FIELD_MOVE_FLASH:
|
|
DisplayCantUseFlashMessage();
|
|
break;
|
|
default:
|
|
DisplayPartyMenuStdMessage(sFieldMoveCursorCallbacks[fieldMove].msgId);
|
|
break;
|
|
}
|
|
gTasks[taskId].func = Task_CancelAfterAorBPress;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DisplayFieldMoveExitAreaMessage(u8 taskId)
|
|
{
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
gTasks[taskId].func = Task_FieldMoveExitAreaYesNo;
|
|
}
|
|
|
|
static void Task_FieldMoveExitAreaYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleFieldMoveExitAreaYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleFieldMoveExitAreaYesNoInput(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
gPartyMenu.exitCallback = CB2_ReturnToField;
|
|
Task_ClosePartyMenu(taskId);
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
gFieldCallback2 = NULL;
|
|
gPostMenuFieldCallback = NULL;
|
|
Task_ReturnToChooseMonAfterText(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool8 FieldCallback_PrepareFadeInFromMenu(void)
|
|
{
|
|
pal_fill_black();
|
|
CreateTask(Task_FieldMoveWaitForFade, 8);
|
|
return TRUE;
|
|
}
|
|
|
|
static void Task_FieldMoveWaitForFade(u8 taskId)
|
|
{
|
|
if (IsWeatherNotFadingIn() == TRUE)
|
|
{
|
|
gFieldEffectArguments[0] = GetFieldMoveMonSpecies();
|
|
gPostMenuFieldCallback();
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
static u16 GetFieldMoveMonSpecies(void)
|
|
{
|
|
return GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
|
|
}
|
|
|
|
static void Task_CancelAfterAorBPress(u8 taskId)
|
|
{
|
|
if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
|
|
CursorCb_Cancel1(taskId);
|
|
}
|
|
|
|
static void DisplayCantUseFlashMessage(void)
|
|
{
|
|
if (FlagGet(FLAG_SYS_USE_FLASH) == TRUE)
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_ALREADY_IN_USE);
|
|
else
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CANT_USE_HERE);
|
|
}
|
|
|
|
static void FieldCallback_Surf(void)
|
|
{
|
|
gFieldEffectArguments[0] = GetCursorSelectionMonId();
|
|
FieldEffectStart(FLDEFF_USE_SURF);
|
|
}
|
|
|
|
static bool8 SetUpFieldMove_Surf(void)
|
|
{
|
|
if (PartyHasMonWithSurf() == TRUE && IsPlayerFacingSurfableFishableWater() == TRUE)
|
|
{
|
|
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
|
|
gPostMenuFieldCallback = FieldCallback_Surf;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void DisplayCantUseSurfMessage(void)
|
|
{
|
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_ALREADY_SURFING);
|
|
else
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CANT_SURF_HERE);
|
|
}
|
|
|
|
static bool8 SetUpFieldMove_Fly(void)
|
|
{
|
|
if (Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
void CB2_ReturnToPartyMenuFromFlyMap(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, TRUE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, CB2_ReturnToFieldWithOpenMenu);
|
|
}
|
|
|
|
static void FieldCallback_Waterfall(void)
|
|
{
|
|
gFieldEffectArguments[0] = GetCursorSelectionMonId();
|
|
FieldEffectStart(FLDEFF_USE_WATERFALL);
|
|
}
|
|
|
|
static bool8 SetUpFieldMove_Waterfall(void)
|
|
{
|
|
s16 x, y;
|
|
|
|
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
|
if (MetatileBehavior_IsWaterfall(MapGridGetMetatileBehaviorAt(x, y)) == TRUE && IsPlayerSurfingNorth() == TRUE)
|
|
{
|
|
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
|
|
gPostMenuFieldCallback = FieldCallback_Waterfall;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void FieldCallback_Dive(void)
|
|
{
|
|
gFieldEffectArguments[0] = GetCursorSelectionMonId();
|
|
FieldEffectStart(FLDEFF_USE_DIVE);
|
|
}
|
|
|
|
static bool8 SetUpFieldMove_Dive(void)
|
|
{
|
|
gFieldEffectArguments[1] = TrySetDiveWarp();
|
|
if (gFieldEffectArguments[1] != 0)
|
|
{
|
|
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
|
|
gPostMenuFieldCallback = FieldCallback_Dive;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void party_menu_icon_anim(struct Pokemon *mon, struct PartyMenuBox *menuBox, u32 slot)
|
|
{
|
|
bool32 bit = 1;
|
|
u16 species2;
|
|
|
|
if (IsMultiBattle() == TRUE && gMain.inBattle)
|
|
bit = (sMultiBattlePartnersPartyMask[slot] ^ bit) ? 1 : 0;
|
|
species2 = GetMonData(mon, MON_DATA_SPECIES2);
|
|
party_menu_link_mon_icon_anim(species2, GetMonData(mon, MON_DATA_PERSONALITY), menuBox, 1, bit);
|
|
UpdatePartyMonHPBar(menuBox->monSpriteId, mon);
|
|
}
|
|
|
|
static void party_menu_link_mon_icon_anim(u16 species, u32 pid, struct PartyMenuBox *menuBox, u8 priority, bool32 bit)
|
|
{
|
|
if (species != SPECIES_NONE)
|
|
{
|
|
menuBox->monSpriteId = CreateMonIcon(species, UpdateTradeMonIconFrame, menuBox->spriteCoords[0], menuBox->spriteCoords[1], 4, pid, bit);
|
|
gSprites[menuBox->monSpriteId].oam.priority = priority;
|
|
}
|
|
}
|
|
|
|
static void UpdateHPBar(u8 spriteId, u16 hp, u16 maxhp)
|
|
{
|
|
switch (GetHPBarLevel(hp, maxhp))
|
|
{
|
|
case HP_BAR_FULL:
|
|
SetPartyHPBarSprite(&gSprites[spriteId], 0);
|
|
break;
|
|
case HP_BAR_GREEN:
|
|
SetPartyHPBarSprite(&gSprites[spriteId], 1);
|
|
break;
|
|
case HP_BAR_YELLOW:
|
|
SetPartyHPBarSprite(&gSprites[spriteId], 2);
|
|
break;
|
|
case HP_BAR_RED:
|
|
SetPartyHPBarSprite(&gSprites[spriteId], 3);
|
|
break;
|
|
default:
|
|
SetPartyHPBarSprite(&gSprites[spriteId], 4);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void UpdatePartyMonHPBar(u8 spriteId, struct Pokemon *mon)
|
|
{
|
|
UpdateHPBar(spriteId, GetMonData(mon, MON_DATA_HP), GetMonData(mon, MON_DATA_MAX_HP));
|
|
}
|
|
|
|
static void AnimateSelectedPartyIcon(u8 spriteId, u8 animNum)
|
|
{
|
|
gSprites[spriteId].data[0] = 0;
|
|
if (animNum == 0)
|
|
{
|
|
if (gSprites[spriteId].pos1.x == 16)
|
|
{
|
|
gSprites[spriteId].pos2.x = 0;
|
|
gSprites[spriteId].pos2.y = -4;
|
|
}
|
|
else
|
|
{
|
|
gSprites[spriteId].pos2.x = -4;
|
|
gSprites[spriteId].pos2.y = 0;
|
|
}
|
|
gSprites[spriteId].callback = UpdatePartyMonIconFrame;
|
|
}
|
|
else
|
|
{
|
|
gSprites[spriteId].pos2.x = 0;
|
|
gSprites[spriteId].pos2.y = 0;
|
|
gSprites[spriteId].callback = UpdatePartyMonIconFrameAndBounce;
|
|
}
|
|
}
|
|
|
|
static void UpdatePartyMonIconFrameAndBounce(struct Sprite *sprite)
|
|
{
|
|
u8 unk = UpdateMonIconFrame(sprite);
|
|
|
|
if (unk != 0)
|
|
{
|
|
if (unk & 1)
|
|
sprite->pos2.y = -3;
|
|
else
|
|
sprite->pos2.y = 1;
|
|
}
|
|
}
|
|
|
|
static void UpdatePartyMonIconFrame(struct Sprite *sprite)
|
|
{
|
|
UpdateMonIconFrame(sprite);
|
|
}
|
|
|
|
static void party_menu_held_item_object(struct Pokemon *mon, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
menuBox->itemSpriteId = CreateSprite(&sSpriteTemplate_HeldItem, menuBox->spriteCoords[2], menuBox->spriteCoords[3], 0);
|
|
UpdatePartyMonHeldItemSprite(mon, menuBox);
|
|
}
|
|
}
|
|
|
|
static void party_menu_link_mon_held_item_object(u16 species, u16 item, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (species != SPECIES_NONE)
|
|
{
|
|
menuBox->itemSpriteId = CreateSprite(&sSpriteTemplate_HeldItem, menuBox->spriteCoords[2], menuBox->spriteCoords[3], 0);
|
|
gSprites[menuBox->itemSpriteId].oam.priority = 0;
|
|
ShowOrHideHeldItemSprite(item, menuBox);
|
|
}
|
|
}
|
|
|
|
static void UpdatePartyMonHeldItemSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox)
|
|
{
|
|
ShowOrHideHeldItemSprite(GetMonData(mon, MON_DATA_HELD_ITEM), menuBox);
|
|
}
|
|
|
|
static void ShowOrHideHeldItemSprite(u16 item, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (item == ITEM_NONE)
|
|
{
|
|
gSprites[menuBox->itemSpriteId].invisible = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (ItemIsMail(item))
|
|
StartSpriteAnim(&gSprites[menuBox->itemSpriteId], 1);
|
|
else
|
|
StartSpriteAnim(&gSprites[menuBox->itemSpriteId], 0);
|
|
gSprites[menuBox->itemSpriteId].invisible = FALSE;
|
|
}
|
|
}
|
|
|
|
void LoadHeldItemIcons(void)
|
|
{
|
|
LoadSpriteSheet(&sSpriteSheet_HeldItem);
|
|
LoadSpritePalette(&sSpritePalette_HeldItem);
|
|
}
|
|
|
|
void DrawHeldItemIconsForTrade(u8 *partyCounts, u8 *partySpriteIds, u8 whichParty)
|
|
{
|
|
u16 i;
|
|
u16 item;
|
|
|
|
switch (whichParty)
|
|
{
|
|
case TRADE_PLAYER:
|
|
for (i = 0; i < partyCounts[TRADE_PLAYER]; i++)
|
|
{
|
|
item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
|
|
if (item != ITEM_NONE)
|
|
CreateHeldItemSpriteForTrade(partySpriteIds[i], ItemIsMail(item));
|
|
}
|
|
break;
|
|
case TRADE_PARTNER:
|
|
for (i = 0; i < partyCounts[TRADE_PARTNER]; i++)
|
|
{
|
|
item = GetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM);
|
|
if (item != ITEM_NONE)
|
|
CreateHeldItemSpriteForTrade(partySpriteIds[i + PARTY_SIZE], ItemIsMail(item));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void CreateHeldItemSpriteForTrade(u8 spriteId, bool8 isMail)
|
|
{
|
|
u8 subpriority = gSprites[spriteId].subpriority;
|
|
u8 newSpriteId = CreateSprite(&sSpriteTemplate_HeldItem, 250, 170, subpriority - 1);
|
|
|
|
gSprites[newSpriteId].pos2.x = 4;
|
|
gSprites[newSpriteId].pos2.y = 10;
|
|
gSprites[newSpriteId].callback = SpriteCB_HeldItem;
|
|
gSprites[newSpriteId].data[7] = spriteId;
|
|
StartSpriteAnim(&gSprites[newSpriteId], isMail);
|
|
gSprites[newSpriteId].callback(&gSprites[newSpriteId]);
|
|
}
|
|
|
|
static void SpriteCB_HeldItem(struct Sprite *sprite)
|
|
{
|
|
u8 otherSpriteId = sprite->data[7];
|
|
|
|
if (gSprites[otherSpriteId].invisible)
|
|
{
|
|
sprite->invisible = TRUE;
|
|
}
|
|
else
|
|
{
|
|
sprite->invisible = FALSE;
|
|
sprite->pos1.x = gSprites[otherSpriteId].pos1.x + gSprites[otherSpriteId].pos2.x;
|
|
sprite->pos1.y = gSprites[otherSpriteId].pos1.y + gSprites[otherSpriteId].pos2.y;
|
|
}
|
|
}
|
|
|
|
static void party_menu_pokeball_object(struct Pokemon *mon, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
menuBox->pokeballSpriteId = CreateSprite(&sSpriteTemplate_MenuPokeball, menuBox->spriteCoords[6], menuBox->spriteCoords[7], 8);
|
|
}
|
|
|
|
static void party_menu_link_mon_pokeball_object(u16 species, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (species != SPECIES_NONE)
|
|
{
|
|
menuBox->pokeballSpriteId = CreateSprite(&sSpriteTemplate_MenuPokeball, menuBox->spriteCoords[6], menuBox->spriteCoords[7], 8);
|
|
gSprites[menuBox->pokeballSpriteId].oam.priority = 0;
|
|
}
|
|
}
|
|
|
|
static u8 CreateCancelPokeballSprite(u8 x, u8 y)
|
|
{
|
|
u8 spriteId = CreateSprite(&sSpriteTemplate_MenuPokeball, x, y, 8);
|
|
|
|
gSprites[spriteId].oam.priority = 2;
|
|
return spriteId;
|
|
}
|
|
|
|
// For Confirm and Cancel in Choose 3 party menus
|
|
static u8 CreateMenuPokeballSprite(u8 x, u8 y)
|
|
{
|
|
return CreateSprite(&gSpriteTemplate_8615F78, x, y, 8);
|
|
}
|
|
|
|
static void PartyMenuStartSpriteAnim(u8 spriteId, u8 animNum)
|
|
{
|
|
StartSpriteAnim(&gSprites[spriteId], animNum);
|
|
}
|
|
|
|
static void sub_81B5FBC(u8 spriteId, u8 spriteId2, u8 a)
|
|
{
|
|
if (a == 0)
|
|
{
|
|
StartSpriteAnim(&gSprites[spriteId], 2);
|
|
StartSpriteAnim(&gSprites[spriteId2], 4);
|
|
gSprites[spriteId].pos2.y = 0;
|
|
gSprites[spriteId2].pos2.y = 0;
|
|
}
|
|
else
|
|
{
|
|
StartSpriteAnim(&gSprites[spriteId], 3);
|
|
StartSpriteAnim(&gSprites[spriteId2], 5);
|
|
gSprites[spriteId].pos2.y = -4;
|
|
gSprites[spriteId2].pos2.y = 4;
|
|
}
|
|
}
|
|
|
|
static void LoadPartyMenuPokeballGfx(void)
|
|
{
|
|
LoadCompressedSpriteSheet(&sSpriteSheet_MenuPokeball);
|
|
LoadCompressedSpriteSheet(&sSpriteSheet_MenuPokeballSmall);
|
|
LoadCompressedSpritePalette(&sSpritePalette_MenuPokeball);
|
|
}
|
|
|
|
static void party_menu_status_condition_object(struct Pokemon *mon, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE)
|
|
{
|
|
menuBox->statusSpriteId = CreateSprite(&sSpriteTemplate_StatusIcons, menuBox->spriteCoords[4], menuBox->spriteCoords[5], 0);
|
|
SetPartyMonAilmentGfx(mon, menuBox);
|
|
}
|
|
}
|
|
|
|
static void party_menu_link_mon_status_condition_object(u16 species, u8 status, struct PartyMenuBox *menuBox)
|
|
{
|
|
if (species != SPECIES_NONE)
|
|
{
|
|
menuBox->statusSpriteId = CreateSprite(&sSpriteTemplate_StatusIcons, menuBox->spriteCoords[4], menuBox->spriteCoords[5], 0);
|
|
UpdatePartyMonAilmentGfx(status, menuBox);
|
|
gSprites[menuBox->statusSpriteId].oam.priority = 0;
|
|
}
|
|
}
|
|
|
|
static void SetPartyMonAilmentGfx(struct Pokemon *mon, struct PartyMenuBox *menuBox)
|
|
{
|
|
UpdatePartyMonAilmentGfx(GetMonAilment(mon), menuBox);
|
|
}
|
|
|
|
static void UpdatePartyMonAilmentGfx(u8 status, struct PartyMenuBox *menuBox)
|
|
{
|
|
switch (status)
|
|
{
|
|
case AILMENT_NONE:
|
|
case AILMENT_PKRS:
|
|
gSprites[menuBox->statusSpriteId].invisible = TRUE;
|
|
break;
|
|
default:
|
|
StartSpriteAnim(&gSprites[menuBox->statusSpriteId], status - 1);
|
|
gSprites[menuBox->statusSpriteId].invisible = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void LoadPartyMenuAilmentGfx(void)
|
|
{
|
|
LoadCompressedSpriteSheet(&sSpriteSheet_StatusIcons);
|
|
LoadCompressedSpritePalette(&sSpritePalette_StatusIcons);
|
|
}
|
|
|
|
void CB2_ShowPartyMenuForItemUse(void)
|
|
{
|
|
MainCallback callback = CB2_ReturnToBagMenu;
|
|
u8 partyLayout;
|
|
u8 menuType;
|
|
u8 i;
|
|
u8 msgId;
|
|
TaskFunc task;
|
|
|
|
if (gMain.inBattle)
|
|
{
|
|
menuType = PARTY_MENU_TYPE_IN_BATTLE;
|
|
partyLayout = GetPartyLayoutFromBattleType();
|
|
}
|
|
else
|
|
{
|
|
menuType = PARTY_MENU_TYPE_FIELD;
|
|
partyLayout = PARTY_LAYOUT_SINGLE;
|
|
}
|
|
|
|
if (GetItemEffectType(gSpecialVar_ItemId) == ITEM_EFFECT_SACRED_ASH)
|
|
{
|
|
gPartyMenu.slotId = 0;
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != SPECIES_NONE && GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0)
|
|
{
|
|
gPartyMenu.slotId = i;
|
|
break;
|
|
}
|
|
}
|
|
task = sub_81B6280;
|
|
msgId = PARTY_MSG_NONE;
|
|
}
|
|
else
|
|
{
|
|
if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_TM_HM)
|
|
msgId = PARTY_MSG_TEACH_WHICH_MON;
|
|
else
|
|
msgId = PARTY_MSG_USE_ON_WHICH_MON;
|
|
|
|
task = Task_HandleChooseMonInput;
|
|
}
|
|
|
|
InitPartyMenu(menuType, partyLayout, PARTY_ACTION_USE_ITEM, TRUE, msgId, task, callback);
|
|
}
|
|
|
|
static void CB2_ReturnToBagMenu(void)
|
|
{
|
|
if (InBattlePyramid() == FALSE)
|
|
GoToBagMenu(RETURN_LOCATION_UNCHANGED, POCKETS_COUNT, NULL);
|
|
else
|
|
GoToBattlePyramidBagMenu(4, gPyramidBagCursorData.callback);
|
|
}
|
|
|
|
static void sub_81B6280(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
|
|
sPartyMenuInternal->exitCallback = CB2_SetUpExitToBattleScreen;
|
|
gItemUseCB(taskId, Task_ClosePartyMenuAfterText);
|
|
}
|
|
}
|
|
|
|
static bool8 IsHPRecoveryItem(u16 item)
|
|
{
|
|
const u8 *effect;
|
|
|
|
if (item == ITEM_ENIGMA_BERRY)
|
|
effect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
|
else
|
|
effect = gItemEffectTable[item - ITEM_POTION];
|
|
|
|
if (effect[4] & ITEM4_HEAL_HP)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void GetMedicineItemEffectMessage(u16 item)
|
|
{
|
|
switch (GetItemEffectType(item))
|
|
{
|
|
case ITEM_EFFECT_CURE_POISON:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnCuredOfPoison);
|
|
break;
|
|
case ITEM_EFFECT_CURE_SLEEP:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnWokeUp2);
|
|
break;
|
|
case ITEM_EFFECT_CURE_BURN:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBurnHealed);
|
|
break;
|
|
case ITEM_EFFECT_CURE_FREEZE:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnThawedOut);
|
|
break;
|
|
case ITEM_EFFECT_CURE_PARALYSIS:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnCuredOfParalysis);
|
|
break;
|
|
case ITEM_EFFECT_CURE_CONFUSION:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnSnappedOutOfConfusion);
|
|
break;
|
|
case ITEM_EFFECT_CURE_INFATUATION:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnGotOverInfatuation);
|
|
break;
|
|
case ITEM_EFFECT_CURE_ALL_STATUS:
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBecameHealthy);
|
|
break;
|
|
case ITEM_EFFECT_HP_EV:
|
|
StringCopy(gStringVar2, gText_HP3);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBaseVar2StatIncreased);
|
|
break;
|
|
case ITEM_EFFECT_ATK_EV:
|
|
StringCopy(gStringVar2, gText_Attack3);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBaseVar2StatIncreased);
|
|
break;
|
|
case ITEM_EFFECT_DEF_EV:
|
|
StringCopy(gStringVar2, gText_Defense3);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBaseVar2StatIncreased);
|
|
break;
|
|
case ITEM_EFFECT_SPEED_EV:
|
|
StringCopy(gStringVar2, gText_Speed2);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBaseVar2StatIncreased);
|
|
break;
|
|
case ITEM_EFFECT_SPATK_EV:
|
|
StringCopy(gStringVar2, gText_SpAtk3);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBaseVar2StatIncreased);
|
|
break;
|
|
case ITEM_EFFECT_SPDEF_EV:
|
|
StringCopy(gStringVar2, gText_SpDef3);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnBaseVar2StatIncreased);
|
|
break;
|
|
case ITEM_EFFECT_PP_UP:
|
|
case ITEM_EFFECT_PP_MAX:
|
|
StringExpandPlaceholders(gStringVar4, gText_MovesPPIncreased);
|
|
break;
|
|
case ITEM_EFFECT_HEAL_PP:
|
|
StringExpandPlaceholders(gStringVar4, gText_PPWasRestored);
|
|
break;
|
|
default:
|
|
StringExpandPlaceholders(gStringVar4, gText_WontHaveEffect);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static bool8 NotUsingHPEVItemOnShedinja(struct Pokemon *mon, u16 item)
|
|
{
|
|
if (GetItemEffectType(item) == ITEM_EFFECT_HP_EV && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_SHEDINJA)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 IsItemFlute(u16 item)
|
|
{
|
|
if (item == ITEM_BLUE_FLUTE || item == ITEM_RED_FLUTE || item == ITEM_YELLOW_FLUTE)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 ExecuteTableBasedItemEffect_(u8 partyMonIndex, u16 item, u8 monMoveIndex)
|
|
{
|
|
if (gMain.inBattle)
|
|
return ExecuteTableBasedItemEffect(&gPlayerParty[partyMonIndex], item, GetPartyIdFromBattleSlot(partyMonIndex), monMoveIndex);
|
|
else
|
|
return ExecuteTableBasedItemEffect(&gPlayerParty[partyMonIndex], item, partyMonIndex, monMoveIndex);
|
|
}
|
|
|
|
void ItemUseCB_Medicine(u8 taskId, TaskFunc task)
|
|
{
|
|
u16 hp = 0;
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item = gSpecialVar_ItemId;
|
|
bool8 canHeal;
|
|
|
|
if (NotUsingHPEVItemOnShedinja(mon, item))
|
|
{
|
|
canHeal = IsHPRecoveryItem(item);
|
|
if (canHeal == TRUE)
|
|
{
|
|
hp = GetMonData(mon, MON_DATA_HP);
|
|
if (hp == GetMonData(mon, MON_DATA_MAX_HP))
|
|
canHeal = FALSE;
|
|
}
|
|
if (ExecuteTableBasedItemEffect_(gPartyMenu.slotId, item, 0))
|
|
{
|
|
iTriedHonestlyIDid:
|
|
gUnknown_0203CEE8 = FALSE;
|
|
PlaySE(SE_SELECT);
|
|
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
goto iTriedHonestlyIDid; //TODO: resolve this goto
|
|
}
|
|
gUnknown_0203CEE8 = TRUE;
|
|
if (!IsItemFlute(item))
|
|
{
|
|
PlaySE(SE_KAIFUKU);
|
|
if (gPartyMenu.action != PARTY_ACTION_REUSABLE_ITEM)
|
|
RemoveBagItem(item, 1);
|
|
}
|
|
else
|
|
{
|
|
PlaySE(SE_BIDORO);
|
|
}
|
|
SetPartyMonAilmentGfx(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
|
|
if (gSprites[sPartyMenuBoxes[gPartyMenu.slotId].statusSpriteId].invisible)
|
|
DisplayPartyPokemonLevelCheck(mon, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
if (canHeal == TRUE)
|
|
{
|
|
if (hp == 0)
|
|
AnimatePartySlot(gPartyMenu.slotId, 1);
|
|
PartyMenuModifyHP(taskId, gPartyMenu.slotId, 1, GetMonData(mon, MON_DATA_HP) - hp, Task_DisplayHPRestoredMessage);
|
|
ResetHPTaskData(taskId, 0, hp);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
GetMonNickname(mon, gStringVar1);
|
|
GetMedicineItemEffectMessage(item);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task;
|
|
}
|
|
}
|
|
|
|
static void Task_DisplayHPRestoredMessage(u8 taskId)
|
|
{
|
|
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2);
|
|
DisplayPartyMenuMessage(gStringVar4, FALSE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
HandleBattleLowHpMusicChange();
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
}
|
|
|
|
static void Task_ClosePartyMenuAfterText(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
if (gUnknown_0203CEE8 == FALSE)
|
|
sPartyMenuInternal->exitCallback = NULL;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
|
|
void ItemUseCB_ReduceEV(u8 taskId, TaskFunc task)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item = gSpecialVar_ItemId;
|
|
u8 effectType = GetItemEffectType(item);
|
|
u16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP);
|
|
u16 ev = ItemEffectToMonEv(mon, effectType);
|
|
bool8 cannotUseEffect = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, item, 0);
|
|
u16 newFriendship = GetMonData(mon, MON_DATA_FRIENDSHIP);
|
|
u16 newEv = ItemEffectToMonEv(mon, effectType);
|
|
|
|
if (cannotUseEffect || (friendship == newFriendship && ev == newEv))
|
|
{
|
|
gUnknown_0203CEE8 = FALSE;
|
|
PlaySE(SE_SELECT);
|
|
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task;
|
|
}
|
|
else
|
|
{
|
|
gUnknown_0203CEE8 = TRUE;
|
|
PlaySE(SE_KAIFUKU);
|
|
RemoveBagItem(item, 1);
|
|
GetMonNickname(mon, gStringVar1);
|
|
ItemEffectToStatString(effectType, gStringVar2);
|
|
if (friendship != newFriendship)
|
|
{
|
|
if (ev != newEv)
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnFriendlyBaseVar2Fell);
|
|
else
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnFriendlyBaseVar2CantFall);
|
|
}
|
|
else
|
|
{
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnAdoresBaseVar2Fell);
|
|
}
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task;
|
|
}
|
|
}
|
|
|
|
static u16 ItemEffectToMonEv(struct Pokemon *mon, u8 effectType)
|
|
{
|
|
switch (effectType)
|
|
{
|
|
case ITEM_EFFECT_HP_EV:
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_SHEDINJA)
|
|
return GetMonData(mon, MON_DATA_HP_EV);
|
|
break;
|
|
case ITEM_EFFECT_ATK_EV:
|
|
return GetMonData(mon, MON_DATA_ATK_EV);
|
|
case ITEM_EFFECT_DEF_EV:
|
|
return GetMonData(mon, MON_DATA_DEF_EV);
|
|
case ITEM_EFFECT_SPEED_EV:
|
|
return GetMonData(mon, MON_DATA_SPEED_EV);
|
|
case ITEM_EFFECT_SPATK_EV:
|
|
return GetMonData(mon, MON_DATA_SPATK_EV);
|
|
case ITEM_EFFECT_SPDEF_EV:
|
|
return GetMonData(mon, MON_DATA_SPDEF_EV);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void ItemEffectToStatString(u8 effectType, u8 *dest)
|
|
{
|
|
switch (effectType)
|
|
{
|
|
case ITEM_EFFECT_HP_EV:
|
|
StringCopy(dest, gText_HP3);
|
|
break;
|
|
case ITEM_EFFECT_ATK_EV:
|
|
StringCopy(dest, gText_Attack3);
|
|
break;
|
|
case ITEM_EFFECT_DEF_EV:
|
|
StringCopy(dest, gText_Defense3);
|
|
break;
|
|
case ITEM_EFFECT_SPEED_EV:
|
|
StringCopy(dest, gText_Speed2);
|
|
break;
|
|
case ITEM_EFFECT_SPATK_EV:
|
|
StringCopy(dest, gText_SpAtk3);
|
|
break;
|
|
case ITEM_EFFECT_SPDEF_EV:
|
|
StringCopy(dest, gText_SpDef3);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ShowMoveSelectWindow(u8 slot)
|
|
{
|
|
u8 i;
|
|
u8 moveCount = 0;
|
|
u8 fontId = 1;
|
|
u8 windowId = DisplaySelectionWindow(SELECTWINDOW_MOVES);
|
|
u16 move;
|
|
|
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
|
{
|
|
move = GetMonData(&gPlayerParty[slot], MON_DATA_MOVE1 + i);
|
|
AddTextPrinterParameterized(windowId, fontId, gMoveNames[move], 8, (i * 16) + 1, TEXT_SPEED_FF, NULL);
|
|
if (move != MOVE_NONE)
|
|
moveCount++;
|
|
}
|
|
InitMenuInUpperLeftCornerPlaySoundWhenAPressed(windowId, moveCount, 0);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void Task_HandleWhichMoveInput(u8 taskId)
|
|
{
|
|
s8 input = Menu_ProcessInput();
|
|
|
|
if (input != MENU_NOTHING_CHOSEN)
|
|
{
|
|
if (input == MENU_B_PRESSED)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
ReturnToUseOnWhichMon(taskId);
|
|
}
|
|
else
|
|
{
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
|
SetSelectedMoveForPPItem(taskId);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ItemUseCB_PPRecovery(u8 taskId, TaskFunc task)
|
|
{
|
|
const u8 *effect;
|
|
u16 item = gSpecialVar_ItemId;
|
|
|
|
if (item == ITEM_ENIGMA_BERRY)
|
|
effect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
|
else
|
|
effect = gItemEffectTable[item - ITEM_POTION];
|
|
|
|
if (!(effect[4] & ITEM4_HEAL_PP_ONE))
|
|
{
|
|
gPartyMenu.unkE = 0;
|
|
TryUsePPItem(taskId);
|
|
}
|
|
else
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_RESTORE_WHICH_MOVE);
|
|
ShowMoveSelectWindow(gPartyMenu.slotId);
|
|
gTasks[taskId].func = Task_HandleWhichMoveInput;
|
|
}
|
|
}
|
|
|
|
static void SetSelectedMoveForPPItem(u8 taskId)
|
|
{
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
gPartyMenu.unkE = Menu_GetCursorPos();
|
|
TryUsePPItem(taskId);
|
|
}
|
|
|
|
static void ReturnToUseOnWhichMon(u8 taskId)
|
|
{
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
sPartyMenuInternal->exitCallback = NULL;
|
|
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_USE_ON_WHICH_MON);
|
|
}
|
|
|
|
static void TryUsePPItem(u8 taskId)
|
|
{
|
|
u16 move = MOVE_NONE;
|
|
s16 *moveSlot = &gPartyMenu.unkE;
|
|
u16 item = gSpecialVar_ItemId;
|
|
struct PartyMenu *ptr = &gPartyMenu;
|
|
struct Pokemon *mon;
|
|
|
|
if (ExecuteTableBasedItemEffect_(ptr->slotId, item, *moveSlot))
|
|
{
|
|
gUnknown_0203CEE8 = FALSE;
|
|
PlaySE(SE_SELECT);
|
|
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
}
|
|
else
|
|
{
|
|
gUnknown_0203CEE8 = TRUE;
|
|
mon = &gPlayerParty[ptr->slotId];
|
|
PlaySE(SE_KAIFUKU);
|
|
RemoveBagItem(item, 1);
|
|
move = GetMonData(mon, MON_DATA_MOVE1 + *moveSlot);
|
|
StringCopy(gStringVar1, gMoveNames[move]);
|
|
GetMedicineItemEffectMessage(item);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
}
|
|
}
|
|
|
|
void ItemUseCB_PPUp(u8 taskId, TaskFunc task)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_BOOST_PP_WHICH_MOVE);
|
|
ShowMoveSelectWindow(gPartyMenu.slotId);
|
|
gTasks[taskId].func = Task_HandleWhichMoveInput;
|
|
}
|
|
|
|
u16 ItemIdToBattleMoveId(u16 item)
|
|
{
|
|
u16 tmNumber = item - ITEM_TM01_FOCUS_PUNCH;
|
|
return sTMHMMoves[tmNumber];
|
|
}
|
|
|
|
bool8 IsMoveHm(u16 move)
|
|
{
|
|
u8 i;
|
|
|
|
for (i = 0; i < NUM_HIDDEN_MACHINES; i++)
|
|
{
|
|
if (sTMHMMoves[i + NUM_TECHNICAL_MACHINES] == move)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 MonKnowsMove(struct Pokemon *mon, u16 move)
|
|
{
|
|
u8 i;
|
|
|
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
|
{
|
|
if (GetMonData(mon, MON_DATA_MOVE1 + i) == move)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void DisplayLearnMoveMessage(const u8 *str)
|
|
{
|
|
StringExpandPlaceholders(gStringVar4, str);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void DisplayLearnMoveMessageAndClose(u8 taskId, const u8 *str)
|
|
{
|
|
DisplayLearnMoveMessage(str);
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
}
|
|
|
|
// move[1] doesn't use constants cause I don't know if it's actually a move ID storage
|
|
|
|
void ItemUseCB_TMHM(u8 taskId, TaskFunc task)
|
|
{
|
|
struct Pokemon *mon;
|
|
s16 *move;
|
|
u16 item;
|
|
|
|
PlaySE(SE_SELECT);
|
|
mon = &gPlayerParty[gPartyMenu.slotId];
|
|
move = &gPartyMenu.unkE;
|
|
item = gSpecialVar_ItemId;
|
|
GetMonNickname(mon, gStringVar1);
|
|
move[0] = ItemIdToBattleMoveId(item);
|
|
StringCopy(gStringVar2, gMoveNames[move[0]]);
|
|
move[1] = 0;
|
|
|
|
switch (CanMonLearnTMTutor(mon, item, 0))
|
|
{
|
|
case CANNOT_LEARN_MOVE:
|
|
DisplayLearnMoveMessageAndClose(taskId, gText_PkmnCantLearnMove);
|
|
return;
|
|
case ALREADY_KNOWS_MOVE:
|
|
DisplayLearnMoveMessageAndClose(taskId, gText_PkmnAlreadyKnows);
|
|
return;
|
|
}
|
|
|
|
if (GiveMoveToMon(mon, move[0]) != MON_HAS_MAX_MOVES)
|
|
{
|
|
gTasks[taskId].func = Task_LearnedMove;
|
|
}
|
|
else
|
|
{
|
|
DisplayLearnMoveMessage(gText_PkmnNeedsToReplaceMove);
|
|
gTasks[taskId].func = Task_ReplaceMoveYesNo;
|
|
}
|
|
}
|
|
|
|
static void Task_LearnedMove(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
s16 *move = &gPartyMenu.unkE;
|
|
u16 item = gSpecialVar_ItemId;
|
|
|
|
if (move[1] == 0)
|
|
{
|
|
AdjustFriendship(mon, 4);
|
|
if (item < ITEM_HM01_CUT)
|
|
RemoveBagItem(item, 1);
|
|
}
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[move[0]]);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnLearnedMove3);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_DoLearnedMoveFanfareAfterText;
|
|
}
|
|
|
|
static void Task_DoLearnedMoveFanfareAfterText(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PlayFanfare(MUS_FANFA1);
|
|
gTasks[taskId].func = Task_LearnNextMoveOrClosePartyMenu;
|
|
}
|
|
}
|
|
|
|
static void Task_LearnNextMoveOrClosePartyMenu(u8 taskId)
|
|
{
|
|
if (IsFanfareTaskInactive() && ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON)))
|
|
{
|
|
if (gPartyMenu.learnMoveState == 1)
|
|
Task_TryLearningNextMove(taskId);
|
|
else
|
|
{
|
|
if (gPartyMenu.learnMoveState == 2) // never occurs
|
|
gSpecialVar_Result = TRUE;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_ReplaceMoveYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleReplaceMoveYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleReplaceMoveYesNoInput(u8 taskId)
|
|
{
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
DisplayPartyMenuMessage(gText_WhichMoveToForget, TRUE);
|
|
gTasks[taskId].func = Task_ShowSummaryScreenToForgetMove;
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
StopLearningMovePrompt(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void Task_ShowSummaryScreenToForgetMove(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
sPartyMenuInternal->exitCallback = CB2_ShowSummaryScreenToForgetMove;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
|
|
static void CB2_ShowSummaryScreenToForgetMove(void)
|
|
{
|
|
ShowSelectMovePokemonSummaryScreen(gPlayerParty, gPartyMenu.slotId, gPlayerPartyCount - 1, CB2_ReturnToPartyMenuWhileLearningMove, gPartyMenu.unkE);
|
|
}
|
|
|
|
static void CB2_ReturnToPartyMenuWhileLearningMove(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, TRUE, PARTY_MSG_NONE, Task_ReturnToPartyMenuWhileLearningMove, gPartyMenu.exitCallback);
|
|
}
|
|
|
|
static void Task_ReturnToPartyMenuWhileLearningMove(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
if (GetMoveSlotToReplace() != MAX_MON_MOVES)
|
|
DisplayPartyMenuForgotMoveMessage(taskId);
|
|
else
|
|
StopLearningMovePrompt(taskId);
|
|
}
|
|
}
|
|
|
|
static void DisplayPartyMenuForgotMoveMessage(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 move = GetMonData(mon, MON_DATA_MOVE1 + GetMoveSlotToReplace());
|
|
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[move]);
|
|
DisplayLearnMoveMessage(gText_12PoofForgotMove);
|
|
gTasks[taskId].func = Task_PartyMenuReplaceMove;
|
|
}
|
|
|
|
static void Task_PartyMenuReplaceMove(u8 taskId)
|
|
{
|
|
struct Pokemon *mon;
|
|
u16 move;
|
|
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
mon = &gPlayerParty[gPartyMenu.slotId];
|
|
RemoveMonPPBonus(mon, GetMoveSlotToReplace());
|
|
move = gPartyMenu.unkE;
|
|
SetMonMoveSlot(mon, move, GetMoveSlotToReplace());
|
|
Task_LearnedMove(taskId);
|
|
}
|
|
}
|
|
|
|
static void StopLearningMovePrompt(u8 taskId)
|
|
{
|
|
StringCopy(gStringVar2, gMoveNames[gPartyMenu.unkE]);
|
|
StringExpandPlaceholders(gStringVar4, gText_StopLearningMove2);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_StopLearningMoveYesNo;
|
|
}
|
|
|
|
static void Task_StopLearningMoveYesNo(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = Task_HandleStopLearningMoveYesNoInput;
|
|
}
|
|
}
|
|
|
|
static void Task_HandleStopLearningMoveYesNoInput(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[gPartyMenu.unkE]);
|
|
StringExpandPlaceholders(gStringVar4, gText_MoveNotLearned);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
if (gPartyMenu.learnMoveState == 1)
|
|
{
|
|
gTasks[taskId].func = Task_TryLearningNextMoveAfterText;
|
|
}
|
|
else
|
|
{
|
|
if (gPartyMenu.learnMoveState == 2) // never occurs
|
|
gSpecialVar_Result = FALSE;
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
}
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[gPartyMenu.unkE]);
|
|
DisplayLearnMoveMessage(gText_PkmnNeedsToReplaceMove);
|
|
gTasks[taskId].func = Task_ReplaceMoveYesNo;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void Task_TryLearningNextMoveAfterText(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
Task_TryLearningNextMove(taskId);
|
|
}
|
|
|
|
void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
struct PartyMenuInternal *ptr = sPartyMenuInternal;
|
|
s16 *arrayPtr = ptr->data;
|
|
u16 *itemPtr = &gSpecialVar_ItemId;
|
|
bool8 cannotUseEffect;
|
|
|
|
if (GetMonData(mon, MON_DATA_LEVEL) != MAX_LEVEL)
|
|
{
|
|
BufferMonStatsToTaskData(mon, arrayPtr);
|
|
cannotUseEffect = ExecuteTableBasedItemEffect_(gPartyMenu.slotId, *itemPtr, 0);
|
|
BufferMonStatsToTaskData(mon, &ptr->data[6]);
|
|
}
|
|
else
|
|
{
|
|
cannotUseEffect = TRUE;
|
|
}
|
|
PlaySE(SE_SELECT);
|
|
if (cannotUseEffect)
|
|
{
|
|
gUnknown_0203CEE8 = FALSE;
|
|
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task;
|
|
}
|
|
else
|
|
{
|
|
gUnknown_0203CEE8 = TRUE;
|
|
PlayFanfareByFanfareNum(0);
|
|
UpdateMonDisplayInfoAfterRareCandy(gPartyMenu.slotId, mon);
|
|
RemoveBagItem(gSpecialVar_ItemId, 1);
|
|
GetMonNickname(mon, gStringVar1);
|
|
ConvertIntToDecimalStringN(gStringVar2, GetMonData(mon, MON_DATA_LEVEL), STR_CONV_MODE_LEFT_ALIGN, 3);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnElevatedToLvVar2);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_DisplayLevelUpStatsPg1;
|
|
}
|
|
}
|
|
|
|
static void UpdateMonDisplayInfoAfterRareCandy(u8 slot, struct Pokemon *mon)
|
|
{
|
|
SetPartyMonAilmentGfx(mon, &sPartyMenuBoxes[slot]);
|
|
if (gSprites[sPartyMenuBoxes[slot].statusSpriteId].invisible)
|
|
DisplayPartyPokemonLevelCheck(mon, &sPartyMenuBoxes[slot], 1);
|
|
DisplayPartyPokemonHPCheck(mon, &sPartyMenuBoxes[slot], 1);
|
|
DisplayPartyPokemonMaxHPCheck(mon, &sPartyMenuBoxes[slot], 1);
|
|
DisplayPartyPokemonHPBarCheck(mon, &sPartyMenuBoxes[slot]);
|
|
UpdatePartyMonHPBar(sPartyMenuBoxes[slot].monSpriteId, mon);
|
|
AnimatePartySlot(slot, 1);
|
|
schedule_bg_copy_tilemap_to_vram(0);
|
|
}
|
|
|
|
static void Task_DisplayLevelUpStatsPg1(u8 taskId)
|
|
{
|
|
if (WaitFanfare(FALSE) && IsPartyMenuTextPrinterActive() != TRUE && ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON)))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
DisplayLevelUpStatsPg1(taskId);
|
|
gTasks[taskId].func = Task_DisplayLevelUpStatsPg2;
|
|
}
|
|
}
|
|
|
|
static void Task_DisplayLevelUpStatsPg2(u8 taskId)
|
|
{
|
|
if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
DisplayLevelUpStatsPg2(taskId);
|
|
gTasks[taskId].func = Task_TryLearnNewMoves;
|
|
}
|
|
}
|
|
|
|
static void DisplayLevelUpStatsPg1(u8 taskId)
|
|
{
|
|
s16 *arrayPtr = sPartyMenuInternal->data;
|
|
|
|
arrayPtr[12] = CreateLevelUpStatsWindow();
|
|
DrawLevelUpWindowPg1(arrayPtr[12], arrayPtr, &arrayPtr[6], 1, 2, 3);
|
|
CopyWindowToVram(arrayPtr[12], 2);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void DisplayLevelUpStatsPg2(u8 taskId)
|
|
{
|
|
s16 *arrayPtr = sPartyMenuInternal->data;
|
|
|
|
DrawLevelUpWindowPg2(arrayPtr[12], &arrayPtr[6], 1, 2, 3);
|
|
CopyWindowToVram(arrayPtr[12], 2);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
|
|
static void Task_TryLearnNewMoves(u8 taskId)
|
|
{
|
|
u16 learnMove;
|
|
|
|
if (WaitFanfare(0) && ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON)))
|
|
{
|
|
RemoveLevelUpStatsWindow();
|
|
learnMove = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], TRUE);
|
|
gPartyMenu.learnMoveState = 1;
|
|
switch (learnMove)
|
|
{
|
|
case 0: // No moves to learn
|
|
PartyMenuTryEvolution(taskId);
|
|
break;
|
|
case MON_HAS_MAX_MOVES:
|
|
DisplayMonNeedsToReplaceMove(taskId);
|
|
break;
|
|
case MON_ALREADY_KNOWS_MOVE:
|
|
gTasks[taskId].func = Task_TryLearningNextMove;
|
|
break;
|
|
default:
|
|
DisplayMonLearnedMove(taskId, learnMove);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_TryLearningNextMove(u8 taskId)
|
|
{
|
|
u16 result = MonTryLearningNewMove(&gPlayerParty[gPartyMenu.slotId], FALSE);
|
|
|
|
switch (result)
|
|
{
|
|
case 0: // No moves to learn
|
|
PartyMenuTryEvolution(taskId);
|
|
break;
|
|
case MON_HAS_MAX_MOVES:
|
|
DisplayMonNeedsToReplaceMove(taskId);
|
|
break;
|
|
case MON_ALREADY_KNOWS_MOVE:
|
|
return;
|
|
default:
|
|
DisplayMonLearnedMove(taskId, result);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void PartyMenuTryEvolution(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 targetSpecies = GetEvolutionTargetSpecies(mon, 0, 0);
|
|
|
|
if (targetSpecies != SPECIES_NONE)
|
|
{
|
|
FreePartyPointers();
|
|
gCB2_AfterEvolution = gPartyMenu.exitCallback;
|
|
BeginEvolutionScene(mon, targetSpecies, 1, gPartyMenu.slotId);
|
|
DestroyTask(taskId);
|
|
}
|
|
else
|
|
{
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
}
|
|
}
|
|
|
|
static void DisplayMonNeedsToReplaceMove(u8 taskId)
|
|
{
|
|
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[gMoveToLearn]);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnNeedsToReplaceMove);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gPartyMenu.unkE = gMoveToLearn;
|
|
gTasks[taskId].func = Task_ReplaceMoveYesNo;
|
|
}
|
|
|
|
static void DisplayMonLearnedMove(u8 taskId, u16 move)
|
|
{
|
|
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[move]);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnLearnedMove3);
|
|
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gPartyMenu.unkE = move;
|
|
gTasks[taskId].func = Task_DoLearnedMoveFanfareAfterText;
|
|
}
|
|
|
|
static void BufferMonStatsToTaskData(struct Pokemon *mon, s16 *data)
|
|
{
|
|
data[0] = GetMonData(mon, MON_DATA_MAX_HP);
|
|
data[1] = GetMonData(mon, MON_DATA_ATK);
|
|
data[2] = GetMonData(mon, MON_DATA_DEF);
|
|
data[4] = GetMonData(mon, MON_DATA_SPATK);
|
|
data[5] = GetMonData(mon, MON_DATA_SPDEF);
|
|
data[3] = GetMonData(mon, MON_DATA_SPEED);
|
|
}
|
|
|
|
void ItemUseCB_SacredAsh(u8 taskId, TaskFunc task)
|
|
{
|
|
sPartyMenuInternal->data[0] = 0;
|
|
sPartyMenuInternal->data[1] = 0;
|
|
sPartyMenuInternal->data[2] = gPartyMenu.slotId;
|
|
sub_81B7A28(taskId);
|
|
}
|
|
|
|
static void sub_81B7A28(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 hp;
|
|
|
|
if (GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NONE)
|
|
{
|
|
gTasks[taskId].func = task_sacred_ash_party_loop;
|
|
return;
|
|
}
|
|
|
|
hp = GetMonData(mon, MON_DATA_HP);
|
|
if (ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0))
|
|
{
|
|
gTasks[taskId].func = task_sacred_ash_party_loop;
|
|
return;
|
|
}
|
|
|
|
PlaySE(SE_KAIFUKU);
|
|
SetPartyMonAilmentGfx(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
|
|
if (gSprites[sPartyMenuBoxes[gPartyMenu.slotId].statusSpriteId].invisible)
|
|
DisplayPartyPokemonLevelCheck(mon, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
|
AnimatePartySlot(sPartyMenuInternal->data[2], 0);
|
|
AnimatePartySlot(gPartyMenu.slotId, 1);
|
|
PartyMenuModifyHP(taskId, gPartyMenu.slotId, 1, GetMonData(mon, MON_DATA_HP) - hp, Task_SacredAshDisplayHPRestored);
|
|
ResetHPTaskData(taskId, 0, hp);
|
|
sPartyMenuInternal->data[0] = 1;
|
|
sPartyMenuInternal->data[1] = 1;
|
|
}
|
|
|
|
static void task_sacred_ash_party_loop(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
if (sPartyMenuInternal->data[0] == 1)
|
|
{
|
|
sPartyMenuInternal->data[0] = 0;
|
|
sPartyMenuInternal->data[2] = gPartyMenu.slotId;
|
|
}
|
|
if (++(gPartyMenu.slotId) == PARTY_SIZE)
|
|
{
|
|
if (sPartyMenuInternal->data[1] == 0)
|
|
{
|
|
gUnknown_0203CEE8 = FALSE;
|
|
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
}
|
|
else
|
|
{
|
|
gUnknown_0203CEE8 = TRUE;
|
|
RemoveBagItem(gSpecialVar_ItemId, 1);
|
|
}
|
|
gTasks[taskId].func = Task_ClosePartyMenuAfterText;
|
|
gPartyMenu.slotId = 0;
|
|
}
|
|
else
|
|
{
|
|
sub_81B7A28(taskId);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_SacredAshDisplayHPRestored(u8 taskId)
|
|
{
|
|
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2);
|
|
DisplayPartyMenuMessage(gStringVar4, FALSE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task_sacred_ash_party_loop;
|
|
}
|
|
|
|
void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
gCB2_AfterEvolution = gPartyMenu.exitCallback;
|
|
if (ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0))
|
|
{
|
|
gUnknown_0203CEE8 = FALSE;
|
|
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = task;
|
|
}
|
|
else
|
|
{
|
|
RemoveBagItem(gSpecialVar_ItemId, 1);
|
|
FreePartyPointers();
|
|
}
|
|
}
|
|
|
|
u8 GetItemEffectType(u16 item)
|
|
{
|
|
const u8 *itemEffect;
|
|
u32 statusCure;
|
|
|
|
if (!ITEM_HAS_EFFECT(item))
|
|
return ITEM_EFFECT_NONE;
|
|
|
|
// Read the item's effect properties.
|
|
if (item == ITEM_ENIGMA_BERRY)
|
|
itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
|
|
else
|
|
itemEffect = gItemEffectTable[item - ITEM_POTION];
|
|
|
|
if ((itemEffect[0] & (ITEM0_HIGH_CRIT | ITEM0_X_ATTACK)) || itemEffect[1] || itemEffect[2] || (itemEffect[3] & ITEM3_MIST))
|
|
return ITEM_EFFECT_X_ITEM;
|
|
else if (itemEffect[0] & ITEM0_SACRED_ASH)
|
|
return ITEM_EFFECT_SACRED_ASH;
|
|
else if (itemEffect[3] & ITEM3_LEVEL_UP)
|
|
return ITEM_EFFECT_RAISE_LEVEL;
|
|
|
|
statusCure = itemEffect[3] & ITEM3_STATUS_ALL;
|
|
if (statusCure || (itemEffect[0] >> 7))
|
|
{
|
|
if (statusCure == ITEM3_SLEEP)
|
|
return ITEM_EFFECT_CURE_SLEEP;
|
|
else if (statusCure == ITEM3_POISON)
|
|
return ITEM_EFFECT_CURE_POISON;
|
|
else if (statusCure == ITEM3_BURN)
|
|
return ITEM_EFFECT_CURE_BURN;
|
|
else if (statusCure == ITEM3_FREEZE)
|
|
return ITEM_EFFECT_CURE_FREEZE;
|
|
else if (statusCure == ITEM3_PARALYSIS)
|
|
return ITEM_EFFECT_CURE_PARALYSIS;
|
|
else if (statusCure == ITEM3_CONFUSION)
|
|
return ITEM_EFFECT_CURE_CONFUSION;
|
|
else if (itemEffect[0] >> 7 && !statusCure)
|
|
return ITEM_EFFECT_CURE_INFATUATION;
|
|
else
|
|
return ITEM_EFFECT_CURE_ALL_STATUS;
|
|
}
|
|
|
|
if (itemEffect[4] & (ITEM4_REVIVE | ITEM4_HEAL_HP))
|
|
return ITEM_EFFECT_HEAL_HP;
|
|
else if (itemEffect[4] & ITEM4_EV_ATK)
|
|
return ITEM_EFFECT_ATK_EV;
|
|
else if (itemEffect[4] & ITEM4_EV_HP)
|
|
return ITEM_EFFECT_HP_EV;
|
|
else if (itemEffect[5] & ITEM5_EV_SPATK)
|
|
return ITEM_EFFECT_SPATK_EV;
|
|
else if (itemEffect[5] & ITEM5_EV_SPDEF)
|
|
return ITEM_EFFECT_SPDEF_EV;
|
|
else if (itemEffect[5] & ITEM5_EV_SPEED)
|
|
return ITEM_EFFECT_SPEED_EV;
|
|
else if (itemEffect[5] & ITEM5_EV_DEF)
|
|
return ITEM_EFFECT_DEF_EV;
|
|
else if (itemEffect[4] & ITEM4_EVO_STONE)
|
|
return ITEM_EFFECT_EVO_STONE;
|
|
else if (itemEffect[4] & ITEM4_PP_UP)
|
|
return ITEM_EFFECT_PP_UP;
|
|
else if (itemEffect[5] & ITEM5_PP_MAX)
|
|
return ITEM_EFFECT_PP_MAX;
|
|
else if (itemEffect[4] & (ITEM4_HEAL_PP_ALL | ITEM4_HEAL_PP_ONE))
|
|
return ITEM_EFFECT_HEAL_PP;
|
|
else
|
|
return ITEM_EFFECT_NONE;
|
|
}
|
|
|
|
static void TryTutorSelectedMon(u8 taskId)
|
|
{
|
|
struct Pokemon *mon;
|
|
s16 *move;
|
|
|
|
if (!gPaletteFade.active)
|
|
{
|
|
mon = &gPlayerParty[gPartyMenu.slotId];
|
|
move = &gPartyMenu.unkE;
|
|
GetMonNickname(mon, gStringVar1);
|
|
gPartyMenu.unkE = GetTutorMove(gSpecialVar_0x8005);
|
|
StringCopy(gStringVar2, gMoveNames[gPartyMenu.unkE]);
|
|
move[1] = 2;
|
|
switch (CanMonLearnTMTutor(mon, 0, gSpecialVar_0x8005))
|
|
{
|
|
case CANNOT_LEARN_MOVE:
|
|
DisplayLearnMoveMessageAndClose(taskId, gText_PkmnCantLearnMove);
|
|
return;
|
|
case ALREADY_KNOWS_MOVE:
|
|
DisplayLearnMoveMessageAndClose(taskId, gText_PkmnAlreadyKnows);
|
|
return;
|
|
default:
|
|
if (GiveMoveToMon(mon, gPartyMenu.unkE) != MON_HAS_MAX_MOVES)
|
|
{
|
|
Task_LearnedMove(taskId);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
DisplayLearnMoveMessage(gText_PkmnNeedsToReplaceMove);
|
|
gTasks[taskId].func = Task_ReplaceMoveYesNo;
|
|
}
|
|
}
|
|
|
|
void CB2_PartyMenuFromStartMenu(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, CB2_ReturnToFieldWithOpenMenu);
|
|
}
|
|
|
|
// Giving an item by selecting Give from the bag menu
|
|
// As opposted to by selecting Give in the party menu, which is handled by CursorCb_Give
|
|
void CB2_ChooseMonToGiveItem(void)
|
|
{
|
|
MainCallback callback = (InBattlePyramid() == FALSE) ? CB2_ReturnToBagMenu : CB2_ReturnToPyramidBagMenu;
|
|
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_GIVE_ITEM, FALSE, PARTY_MSG_GIVE_TO_WHICH_MON, Task_HandleChooseMonInput, callback);
|
|
gPartyMenu.bagItem = gSpecialVar_ItemId;
|
|
}
|
|
|
|
//TODO next
|
|
static void TryGiveItemToSelectedMon(u8 taskId)
|
|
{
|
|
sPartyMenuItemId = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_HELD_ITEM);
|
|
if (sPartyMenuItemId == ITEM_NONE)
|
|
{
|
|
GiveItemToSelectedMon(taskId);
|
|
}
|
|
else if (ItemIsMail(sPartyMenuItemId))
|
|
{
|
|
sub_81B83B8(taskId);
|
|
}
|
|
else
|
|
{
|
|
DisplayAlreadyHoldingItemSwitchMessage(&gPlayerParty[gPartyMenu.slotId], sPartyMenuItemId, TRUE);
|
|
gTasks[taskId].func = sub_81B82A0;
|
|
}
|
|
}
|
|
|
|
static void GiveItemToSelectedMon(u8 taskId)
|
|
{
|
|
if (ItemIsMail(gPartyMenu.bagItem))
|
|
{
|
|
RemoveItemToGiveFromBag(gPartyMenu.bagItem);
|
|
sPartyMenuInternal->exitCallback = CB2_WriteMailToGiveMonFromBag;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
else
|
|
{
|
|
sub_81B8088(taskId);
|
|
}
|
|
}
|
|
|
|
static void sub_81B8088(u8 taskId)
|
|
{
|
|
u16 item;
|
|
|
|
if (!gPaletteFade.active)
|
|
{
|
|
item = gPartyMenu.bagItem;
|
|
DisplayGaveHeldItemMessage(&gPlayerParty[gPartyMenu.slotId], item, FALSE, 1);
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], item);
|
|
RemoveItemToGiveFromBag(item);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
}
|
|
}
|
|
|
|
static void Task_UpdateHeldItemSpriteAndClosePartyMenu(u8 taskId)
|
|
{
|
|
s8 slot = gPartyMenu.slotId;
|
|
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
UpdatePartyMonHeldItemSprite(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
|
|
static void CB2_WriteMailToGiveMonFromBag(void)
|
|
{
|
|
u8 mail;
|
|
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], gPartyMenu.bagItem);
|
|
mail = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_MAIL);
|
|
DoEasyChatScreen(
|
|
EASY_CHAT_TYPE_MAIL,
|
|
gSaveBlock1Ptr->mail[mail].words,
|
|
CB2_ReturnToPartyOrBagMenuFromWritingMail,
|
|
EASY_CHAT_PERSON_DISPLAY_NONE);
|
|
}
|
|
|
|
static void CB2_ReturnToPartyOrBagMenuFromWritingMail(void)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
|
|
|
|
if (gSpecialVar_Result == FALSE)
|
|
{
|
|
TakeMailFromMon(mon);
|
|
SetMonData(mon, MON_DATA_HELD_ITEM, &sPartyMenuItemId);
|
|
RemoveBagItem(sPartyMenuItemId, 1);
|
|
sub_81B841C(item);
|
|
SetMainCallback2(gPartyMenu.exitCallback);
|
|
}
|
|
else
|
|
{
|
|
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_NONE, sub_81B8230, gPartyMenu.exitCallback);
|
|
}
|
|
}
|
|
|
|
static void sub_81B8230(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
if (sPartyMenuItemId != ITEM_NONE)
|
|
DisplaySwitchedHeldItemMessage(gPartyMenu.bagItem, sPartyMenuItemId, FALSE);
|
|
else
|
|
DisplayGaveHeldItemMessage(&gPlayerParty[gPartyMenu.slotId], gPartyMenu.bagItem, FALSE, 1);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
}
|
|
}
|
|
|
|
static void sub_81B82A0(u8 taskId)
|
|
{
|
|
if (IsPartyMenuTextPrinterActive() != TRUE)
|
|
{
|
|
PartyMenuDisplayYesNoMenu();
|
|
gTasks[taskId].func = sub_81B82D4;
|
|
}
|
|
}
|
|
|
|
static void sub_81B82D4(u8 taskId)
|
|
{
|
|
u16 item;
|
|
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
|
{
|
|
case 0:
|
|
item = gPartyMenu.bagItem;
|
|
RemoveItemToGiveFromBag(item);
|
|
if (AddBagItem(sPartyMenuItemId, 1) == FALSE)
|
|
{
|
|
sub_81B841C(item);
|
|
BufferBagFullCantTakeItemMessage(sPartyMenuItemId);
|
|
DisplayPartyMenuMessage(gStringVar4, FALSE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
}
|
|
else if (ItemIsMail(item))
|
|
{
|
|
sPartyMenuInternal->exitCallback = CB2_WriteMailToGiveMonFromBag;
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
else
|
|
{
|
|
GiveItemToMon(&gPlayerParty[gPartyMenu.slotId], item);
|
|
DisplaySwitchedHeldItemMessage(item, sPartyMenuItemId, TRUE);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
}
|
|
break;
|
|
case MENU_B_PRESSED:
|
|
PlaySE(SE_SELECT);
|
|
// fallthrough
|
|
case 1:
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void sub_81B83B8(u8 taskId)
|
|
{
|
|
DisplayPartyMenuMessage(gText_RemoveMailBeforeItem, TRUE);
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
}
|
|
|
|
static void RemoveItemToGiveFromBag(u16 item)
|
|
{
|
|
if (gPartyMenu.action == PARTY_ACTION_GIVE_PC_ITEM) // Unused, never occurs
|
|
RemovePCItem(item, 1);
|
|
else
|
|
RemoveBagItem(item, 1);
|
|
}
|
|
|
|
static bool8 sub_81B841C(u16 item)
|
|
{
|
|
if (gPartyMenu.action == PARTY_ACTION_GIVE_ITEM)
|
|
return AddBagItem(item, 1);
|
|
else
|
|
return AddPCItem(item, 1);
|
|
}
|
|
|
|
void ChooseMonToGiveMailFromMailbox(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_GIVE_MAILBOX_MAIL, FALSE, PARTY_MSG_GIVE_TO_WHICH_MON, Task_HandleChooseMonInput, Mailbox_ReturnToMailListAfterDeposit);
|
|
}
|
|
|
|
static void TryGiveMailToSelectedMon(u8 taskId)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
|
struct MailStruct *mail;
|
|
|
|
gUnknown_0203CEE8 = FALSE;
|
|
mail = &gSaveBlock1Ptr->mail[playerPCItemPageInfo.itemsAbove + 6 + playerPCItemPageInfo.cursorPos];
|
|
if (GetMonData(mon, MON_DATA_HELD_ITEM) != ITEM_NONE)
|
|
{
|
|
DisplayPartyMenuMessage(gText_PkmnHoldingItemCantHoldMail, TRUE);
|
|
}
|
|
else
|
|
{
|
|
GiveMailToMon2(mon, mail);
|
|
ClearMailStruct(mail);
|
|
DisplayPartyMenuMessage(gText_MailTransferredFromMailbox, TRUE);
|
|
}
|
|
schedule_bg_copy_tilemap_to_vram(2);
|
|
gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
|
|
}
|
|
|
|
void InitChooseHalfPartyForBattle(u8 unused)
|
|
{
|
|
ClearSelectedPartyOrder();
|
|
InitPartyMenu(PARTY_MENU_TYPE_CHOOSE_HALF, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, gMain.savedCallback);
|
|
gPartyMenu.task = Task_ValidateChosenHalfParty;
|
|
}
|
|
|
|
void ClearSelectedPartyOrder(void)
|
|
{
|
|
memset(gSelectedOrderFromParty, 0, sizeof(gSelectedOrderFromParty));
|
|
}
|
|
|
|
static u8 GetPartySlotEntryStatus(s8 slot)
|
|
{
|
|
if (GetBattleEntryEligibility(&gPlayerParty[slot]) == FALSE)
|
|
return 2;
|
|
if (HasPartySlotAlreadyBeenSelected(slot + 1) == TRUE)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
static bool8 GetBattleEntryEligibility(struct Pokemon *mon)
|
|
{
|
|
u16 i = 0;
|
|
u16 species;
|
|
|
|
if (GetMonData(mon, MON_DATA_IS_EGG)
|
|
|| GetMonData(mon, MON_DATA_LEVEL) > GetBattleEntryLevelCap()
|
|
|| (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY)
|
|
&& gSaveBlock1Ptr->location.mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY)
|
|
&& GetMonData(mon, MON_DATA_HELD_ITEM) != ITEM_NONE))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
switch (VarGet(VAR_FRONTIER_FACILITY))
|
|
{
|
|
case FACILITY_MULTI_OR_EREADER:
|
|
if (GetMonData(mon, MON_DATA_HP) != 0)
|
|
return TRUE;
|
|
return FALSE;
|
|
case FACILITY_UNION_ROOM:
|
|
return TRUE;
|
|
default: // Battle Frontier
|
|
species = GetMonData(mon, MON_DATA_SPECIES);
|
|
for (; gFrontierBannedSpecies[i] != 0xFFFF; i++)
|
|
{
|
|
if (gFrontierBannedSpecies[i] == species)
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
static u8 CheckBattleEntriesAndGetMessage(void)
|
|
{
|
|
u8 maxBattlers;
|
|
u8 i, j;
|
|
u8 facility;
|
|
struct Pokemon *party = gPlayerParty;
|
|
u8 minBattlers = GetMinBattleEntries();
|
|
u8 *order = gSelectedOrderFromParty;
|
|
|
|
if (order[minBattlers - 1] == 0)
|
|
{
|
|
if (minBattlers == 1)
|
|
return PARTY_MSG_NO_MON_FOR_BATTLE;
|
|
ConvertIntToDecimalStringN(gStringVar1, minBattlers, STR_CONV_MODE_LEFT_ALIGN, 1);
|
|
return PARTY_MSG_X_MONS_ARE_NEEDED;
|
|
}
|
|
|
|
facility = VarGet(VAR_FRONTIER_FACILITY);
|
|
if (facility == FACILITY_UNION_ROOM || facility == FACILITY_MULTI_OR_EREADER)
|
|
return 0xFF;
|
|
|
|
maxBattlers = GetMaxBattleEntries();
|
|
for (i = 0; i < maxBattlers - 1; i++)
|
|
{
|
|
u16 species = GetMonData(&party[order[i] - 1], MON_DATA_SPECIES);
|
|
u16 item = GetMonData(&party[order[i] - 1], MON_DATA_HELD_ITEM);
|
|
for (j = i + 1; j < maxBattlers; j++)
|
|
{
|
|
if (species == GetMonData(&party[order[j] - 1], MON_DATA_SPECIES))
|
|
return PARTY_MSG_MONS_CANT_BE_SAME;
|
|
if (item != ITEM_NONE && item == GetMonData(&party[order[j] - 1], MON_DATA_HELD_ITEM))
|
|
return PARTY_MSG_NO_SAME_HOLD_ITEMS;
|
|
}
|
|
}
|
|
|
|
return 0xFF;
|
|
}
|
|
|
|
static bool8 HasPartySlotAlreadyBeenSelected(u8 slot)
|
|
{
|
|
u8 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSelectedOrderFromParty); i++)
|
|
{
|
|
if (gSelectedOrderFromParty[i] == slot)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static void Task_ValidateChosenHalfParty(u8 taskId)
|
|
{
|
|
u8 msgId = CheckBattleEntriesAndGetMessage();
|
|
|
|
if (msgId != 0xFF)
|
|
{
|
|
PlaySE(SE_HAZURE);
|
|
DisplayPartyMenuStdMessage(msgId);
|
|
gTasks[taskId].func = Task_ContinueChoosingHalfParty;
|
|
}
|
|
else
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
}
|
|
|
|
static void Task_ContinueChoosingHalfParty(u8 taskId)
|
|
{
|
|
if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
|
|
gTasks[taskId].func = Task_HandleChooseMonInput;
|
|
}
|
|
}
|
|
|
|
static u8 GetMaxBattleEntries(void)
|
|
{
|
|
switch (VarGet(VAR_FRONTIER_FACILITY))
|
|
{
|
|
case FACILITY_MULTI_OR_EREADER:
|
|
return 3;
|
|
case FACILITY_UNION_ROOM:
|
|
return 2;
|
|
default: // Battle Frontier
|
|
return gSpecialVar_0x8005;
|
|
}
|
|
}
|
|
|
|
static u8 GetMinBattleEntries(void)
|
|
{
|
|
switch (VarGet(VAR_FRONTIER_FACILITY))
|
|
{
|
|
case FACILITY_MULTI_OR_EREADER:
|
|
return 1;
|
|
case FACILITY_UNION_ROOM:
|
|
return 2;
|
|
default: // Battle Frontier
|
|
return gSpecialVar_0x8005;
|
|
}
|
|
}
|
|
|
|
static u8 GetBattleEntryLevelCap(void)
|
|
{
|
|
switch (VarGet(VAR_FRONTIER_FACILITY))
|
|
{
|
|
case FACILITY_MULTI_OR_EREADER:
|
|
return MAX_LEVEL;
|
|
case FACILITY_UNION_ROOM:
|
|
return 30;
|
|
default: // Battle Frontier
|
|
if (gSpecialVar_0x8004 == FRONTIER_LVL_50)
|
|
return 50;
|
|
return MAX_LEVEL;
|
|
}
|
|
}
|
|
|
|
static const u8* GetFacilityCancelString(void)
|
|
{
|
|
u8 facilityNum = VarGet(VAR_FRONTIER_FACILITY);
|
|
|
|
if (!(facilityNum != FACILITY_UNION_ROOM && facilityNum != FACILITY_MULTI_OR_EREADER))
|
|
return gText_CancelBattle;
|
|
else if (facilityNum == FRONTIER_FACILITY_DOME && gSpecialVar_0x8005 == 2)
|
|
return gText_ReturnToWaitingRoom;
|
|
else
|
|
return gText_CancelChallenge;
|
|
}
|
|
|
|
void ChooseMonForTradingBoard(u8 initArg, MainCallback callback)
|
|
{
|
|
InitPartyMenu(initArg, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, callback);
|
|
}
|
|
|
|
void ChooseMonForMoveTutor(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_FIELD, PARTY_LAYOUT_SINGLE, PARTY_ACTION_MOVE_TUTOR, FALSE, PARTY_MSG_TEACH_WHICH_MON, Task_HandleChooseMonInput, CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
|
}
|
|
|
|
void ChooseMonForWirelessMinigame(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_MINIGAME, PARTY_LAYOUT_SINGLE, PARTY_ACTION_MINIGAME, FALSE, PARTY_MSG_CHOOSE_MON_OR_CANCEL, Task_HandleChooseMonInput, CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
|
}
|
|
|
|
static u8 GetPartyLayoutFromBattleType(void)
|
|
{
|
|
if (IsDoubleBattle() == FALSE)
|
|
return PARTY_LAYOUT_SINGLE;
|
|
if (IsMultiBattle() == TRUE)
|
|
return PARTY_LAYOUT_MULTI;
|
|
return PARTY_LAYOUT_DOUBLE;
|
|
}
|
|
|
|
void OpenPartyMenuInBattle(u8 partyAction)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE, GetPartyLayoutFromBattleType(), partyAction, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, CB2_SetUpReshowBattleScreenAfterMenu);
|
|
nullsub_35();
|
|
UpdatePartyToBattleOrder();
|
|
}
|
|
|
|
void ChooseMonForInBattleItem(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE, GetPartyLayoutFromBattleType(), PARTY_ACTION_USE_ITEM, FALSE, PARTY_MSG_USE_ON_WHICH_MON, Task_HandleChooseMonInput, CB2_ReturnToBagMenu);
|
|
nullsub_35();
|
|
UpdatePartyToBattleOrder();
|
|
}
|
|
|
|
static u8 GetPartyMenuActionsTypeInBattle(struct Pokemon *mon)
|
|
{
|
|
if (GetMonData(&gPlayerParty[1], MON_DATA_SPECIES) != SPECIES_NONE && GetMonData(mon, MON_DATA_IS_EGG) == FALSE)
|
|
{
|
|
if (gPartyMenu.action == PARTY_ACTION_SEND_OUT)
|
|
return ACTIONS_SEND_OUT;
|
|
if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA))
|
|
return ACTIONS_SHIFT;
|
|
}
|
|
return ACTIONS_SUMMARY_ONLY;
|
|
}
|
|
|
|
static bool8 TrySwitchInPokemon(void)
|
|
{
|
|
u8 slot = GetCursorSelectionMonId();
|
|
u8 newSlot;
|
|
u8 i;
|
|
|
|
// In a multi battle, slots 1, 4, and 5 are the partner's pokemon
|
|
if (IsMultiBattle() == TRUE && (slot == 1 || slot == 4 || slot == 5))
|
|
{
|
|
StringCopy(gStringVar1, GetTrainerPartnerName());
|
|
StringExpandPlaceholders(gStringVar4, gText_CantSwitchWithAlly);
|
|
return FALSE;
|
|
}
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_HP) == 0)
|
|
{
|
|
GetMonNickname(&gPlayerParty[slot], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnHasNoEnergy);
|
|
return FALSE;
|
|
}
|
|
for (i = 0; i < gBattlersCount; i++)
|
|
{
|
|
if (GetBattlerSide(i) == B_SIDE_PLAYER && GetPartyIdFromBattleSlot(slot) == gBattlerPartyIndexes[i])
|
|
{
|
|
GetMonNickname(&gPlayerParty[slot], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnAlreadyInBattle);
|
|
return FALSE;
|
|
}
|
|
}
|
|
if (GetMonData(&gPlayerParty[slot], MON_DATA_IS_EGG))
|
|
{
|
|
StringExpandPlaceholders(gStringVar4, gText_EggCantBattle);
|
|
return FALSE;
|
|
}
|
|
if (GetPartyIdFromBattleSlot(slot) == gBattleStruct->field_8B)
|
|
{
|
|
GetMonNickname(&gPlayerParty[slot], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnAlreadySelected);
|
|
return FALSE;
|
|
}
|
|
if (gPartyMenu.action == PARTY_ACTION_ABILITY_PREVENTS)
|
|
{
|
|
SetMonPreventsSwitchingString();
|
|
return FALSE;
|
|
}
|
|
if (gPartyMenu.action == PARTY_ACTION_CANT_SWITCH)
|
|
{
|
|
u8 currBattler = gBattlerInMenuId;
|
|
GetMonNickname(&gPlayerParty[GetBattlerPartyId(gBattlerPartyIndexes[currBattler])], gStringVar1);
|
|
StringExpandPlaceholders(gStringVar4, gText_PkmnCantSwitchOut);
|
|
return FALSE;
|
|
}
|
|
gUnknown_0203CEE9 = GetPartyIdFromBattleSlot(slot);
|
|
gUnknown_0203CEE8 = TRUE;
|
|
newSlot = GetBattlerPartyId(gBattlerPartyIndexes[gBattlerInMenuId]);
|
|
SwitchPartyMonSlots(newSlot, slot);
|
|
SwapPartyPokemon(&gPlayerParty[newSlot], &gPlayerParty[slot]);
|
|
return TRUE;
|
|
}
|
|
|
|
void sub_81B8C68(void)
|
|
{
|
|
sub_81B8C88(gBattlePartyCurrentOrder, sub_806D7EC());
|
|
}
|
|
|
|
static void sub_81B8C88(u8 *partyBattleOrder, bool8 multiplayerFlag)
|
|
{
|
|
u8 partyIndexes[PARTY_SIZE];
|
|
int i, j;
|
|
|
|
if (IsMultiBattle() == TRUE)
|
|
{
|
|
if (multiplayerFlag)
|
|
{
|
|
partyBattleOrder[0] = 0 | (3 << 4);
|
|
partyBattleOrder[1] = 5 | (4 << 4);
|
|
partyBattleOrder[2] = 2 | (1 << 4);
|
|
}
|
|
else
|
|
{
|
|
partyBattleOrder[0] = 3 | (0 << 4);
|
|
partyBattleOrder[1] = 2 | (1 << 4);
|
|
partyBattleOrder[2] = 5 | (4 << 4);
|
|
}
|
|
return;
|
|
}
|
|
else if (IsDoubleBattle() == FALSE)
|
|
{
|
|
j = 1;
|
|
partyIndexes[0] = gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)];
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (i != partyIndexes[0])
|
|
{
|
|
partyIndexes[j] = i;
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
j = 2;
|
|
partyIndexes[0] = gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)];
|
|
partyIndexes[1] = gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)];
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (i != partyIndexes[0] && i != partyIndexes[1])
|
|
{
|
|
partyIndexes[j] = i;
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); i++)
|
|
partyBattleOrder[i] = (partyIndexes[0 + (i * 2)] << 4) | partyIndexes[1 + (i * 2)];
|
|
}
|
|
|
|
void sub_81B8D64(u8 battlerId, u8 multiplayerFlag)
|
|
{
|
|
sub_81B8D88(gBattleStruct->field_60[battlerId], multiplayerFlag, battlerId);
|
|
}
|
|
|
|
static void sub_81B8D88(u8 *ptr, bool8 multiplayerFlag, u8 battlerId)
|
|
{
|
|
u8 partyIndexes[PARTY_SIZE];
|
|
int i, j;
|
|
u8 leftBattler;
|
|
u8 rightBattler;
|
|
|
|
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
|
|
{
|
|
leftBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
|
rightBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
|
}
|
|
else
|
|
{
|
|
leftBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
|
rightBattler = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
|
}
|
|
|
|
if (IsMultiBattle() == TRUE)
|
|
{
|
|
if (multiplayerFlag)
|
|
{
|
|
ptr[0] = 0 | (3 << 4);
|
|
ptr[1] = 5 | (4 << 4);
|
|
ptr[2] = 2 | (1 << 4);
|
|
}
|
|
else
|
|
{
|
|
ptr[0] = 3 | (0 << 4);
|
|
ptr[1] = 2 | (1 << 4);
|
|
ptr[2] = 5 | (4 << 4);
|
|
}
|
|
return;
|
|
}
|
|
else if (IsDoubleBattle() == FALSE)
|
|
{
|
|
j = 1;
|
|
partyIndexes[0] = gBattlerPartyIndexes[leftBattler];
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (i != partyIndexes[0])
|
|
{
|
|
partyIndexes[j] = i;
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
j = 2;
|
|
partyIndexes[0] = gBattlerPartyIndexes[leftBattler];
|
|
partyIndexes[1] = gBattlerPartyIndexes[rightBattler];
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (i != partyIndexes[0] && i != partyIndexes[1])
|
|
{
|
|
partyIndexes[j] = i;
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 3; i++)
|
|
ptr[i] = (partyIndexes[0 + (i * 2)] << 4) | partyIndexes[1 + (i * 2)];
|
|
}
|
|
|
|
void sub_81B8E80(u8 battlerId, u8 unk, u8 arrayIndex)
|
|
{
|
|
u8 possiblePartyIndexes[PARTY_SIZE];
|
|
u8 unk2 = 0;
|
|
int i, j;
|
|
u8 *battleStructRelated;
|
|
u8 possiblePartyIndexBuffer;
|
|
|
|
if (IsMultiBattle())
|
|
{
|
|
battleStructRelated = gBattleStruct->field_60[battlerId];
|
|
for (i = j = 0; i < 3; j++, i++)
|
|
{
|
|
possiblePartyIndexes[j] = battleStructRelated[i] >> 4;
|
|
j++;
|
|
possiblePartyIndexes[j] = battleStructRelated[i] & 0xF;
|
|
}
|
|
possiblePartyIndexBuffer = possiblePartyIndexes[arrayIndex];
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
if (possiblePartyIndexes[i] == unk)
|
|
{
|
|
unk2 = possiblePartyIndexes[i];
|
|
possiblePartyIndexes[i] = possiblePartyIndexBuffer;
|
|
break;
|
|
}
|
|
}
|
|
if (i != PARTY_SIZE)
|
|
{
|
|
possiblePartyIndexes[arrayIndex] = unk2;
|
|
battleStructRelated[0] = (possiblePartyIndexes[0] << 4) | possiblePartyIndexes[1];
|
|
battleStructRelated[1] = (possiblePartyIndexes[2] << 4) | possiblePartyIndexes[3];
|
|
battleStructRelated[2] = (possiblePartyIndexes[4] << 4) | possiblePartyIndexes[5];
|
|
}
|
|
}
|
|
}
|
|
|
|
static u8 GetPartyIdFromBattleSlot(u8 slot)
|
|
{
|
|
u8 modResult = slot & 1;
|
|
u8 retVal;
|
|
|
|
slot /= 2;
|
|
if (modResult != 0)
|
|
retVal = gBattlePartyCurrentOrder[slot] & 0xF;
|
|
else
|
|
retVal = gBattlePartyCurrentOrder[slot] >> 4;
|
|
return retVal;
|
|
}
|
|
|
|
static void SetPartyIdAtBattleSlot(u8 slot, u8 setVal)
|
|
{
|
|
bool32 modResult = slot & 1;
|
|
|
|
slot /= 2;
|
|
if (modResult != 0)
|
|
gBattlePartyCurrentOrder[slot] = (gBattlePartyCurrentOrder[slot] & 0xF0) | setVal;
|
|
else
|
|
gBattlePartyCurrentOrder[slot] = (gBattlePartyCurrentOrder[slot] & 0xF) | (setVal << 4);
|
|
}
|
|
|
|
void SwitchPartyMonSlots(u8 slot, u8 slot2)
|
|
{
|
|
u8 partyId = GetPartyIdFromBattleSlot(slot);
|
|
SetPartyIdAtBattleSlot(slot, GetPartyIdFromBattleSlot(slot2));
|
|
SetPartyIdAtBattleSlot(slot2, partyId);
|
|
}
|
|
|
|
// TODO: rename? get party id from battle party id?
|
|
u8 GetBattlerPartyId(u8 slot)
|
|
{
|
|
u8 i, j;
|
|
|
|
for (j = i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); j++, i++)
|
|
{
|
|
if ((gBattlePartyCurrentOrder[i] >> 4) != slot)
|
|
{
|
|
j++;
|
|
if ((gBattlePartyCurrentOrder[i] & 0xF) == slot)
|
|
return j;
|
|
}
|
|
else
|
|
{
|
|
return j;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void UpdatePartyToBattleOrder(void)
|
|
{
|
|
struct Pokemon *partyBuffer = Alloc(sizeof(gPlayerParty));
|
|
u8 i;
|
|
|
|
memcpy(partyBuffer, gPlayerParty, sizeof(gPlayerParty));
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
memcpy(&gPlayerParty[GetBattlerPartyId(i)], &partyBuffer[i], sizeof(struct Pokemon));
|
|
Free(partyBuffer);
|
|
}
|
|
|
|
static void UpdatePartyToFieldOrder(void)
|
|
{
|
|
struct Pokemon *partyBuffer = Alloc(sizeof(gPlayerParty));
|
|
u8 i;
|
|
|
|
memcpy(partyBuffer, gPlayerParty, sizeof(gPlayerParty));
|
|
for (i = 0; i < PARTY_SIZE; i++)
|
|
memcpy(&gPlayerParty[GetPartyIdFromBattleSlot(i)], &partyBuffer[i], sizeof(struct Pokemon));
|
|
Free(partyBuffer);
|
|
}
|
|
|
|
// Unused
|
|
static void SwitchAliveMonIntoLeadSlot(void)
|
|
{
|
|
u8 i;
|
|
struct Pokemon *mon;
|
|
u8 partyId;
|
|
|
|
for (i = 1; i < PARTY_SIZE; i++)
|
|
{
|
|
mon = &gPlayerParty[GetPartyIdFromBattleSlot(i)];
|
|
if (GetMonData(mon, MON_DATA_SPECIES) != SPECIES_NONE && GetMonData(mon, MON_DATA_HP) != 0)
|
|
{
|
|
partyId = GetPartyIdFromBattleSlot(0);
|
|
SwitchPartyMonSlots(0, i);
|
|
SwapPartyPokemon(&gPlayerParty[partyId], mon);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CB2_SetUpExitToBattleScreen(void)
|
|
{
|
|
SetMainCallback2(CB2_SetUpReshowBattleScreenAfterMenu);
|
|
}
|
|
|
|
void ShowPartyMenuToShowcaseMultiBattleParty(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_IN_MULTI_BATTLE, PARTY_LAYOUT_MULTI_SHOWCASE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_NONE, Task_InitMultiPartnerPartySlideIn, gMain.savedCallback);
|
|
}
|
|
|
|
#define tXPos data[0]
|
|
|
|
// set up multi party partner slide
|
|
static void Task_InitMultiPartnerPartySlideIn(u8 taskId)
|
|
{
|
|
// The first slide step also sets the sprites offscreen
|
|
gTasks[taskId].tXPos = 256;
|
|
SlideMultiPartyMenuBoxSpritesOneStep(taskId);
|
|
ChangeBgX(2, 0x10000, 0);
|
|
gTasks[taskId].func = Task_MultiPartnerPartySlideIn;
|
|
}
|
|
|
|
static void Task_MultiPartnerPartySlideIn(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
u8 i;
|
|
|
|
if (!gPaletteFade.active)
|
|
{
|
|
tXPos -= 8;
|
|
SlideMultiPartyMenuBoxSpritesOneStep(taskId);
|
|
if (tXPos == 0)
|
|
{
|
|
for (i = 3; i < PARTY_SIZE; i++)
|
|
{
|
|
if (gMultiPartnerParty[i - 3].species != SPECIES_NONE)
|
|
AnimateSelectedPartyIcon(sPartyMenuBoxes[i].monSpriteId, 0);
|
|
}
|
|
PlaySE(SE_W231); // The Harden SE plays once the partners party mons have slid on screen
|
|
gTasks[taskId].func = Task_WaitAfterMultiPartnerPartySlideIn;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void Task_WaitAfterMultiPartnerPartySlideIn(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
// data[0] used as a timer afterwards rather than the x pos
|
|
if (++data[0] == 256)
|
|
Task_ClosePartyMenu(taskId);
|
|
}
|
|
|
|
static void MoveMultiPartyMenuBoxSprite(u8 spriteId, s16 x)
|
|
{
|
|
if (x >= 0)
|
|
gSprites[spriteId].pos2.x = x;
|
|
}
|
|
|
|
static void SlideMultiPartyMenuBoxSpritesOneStep(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
u8 i;
|
|
|
|
for (i = 3; i < PARTY_SIZE; i++)
|
|
{
|
|
if (gMultiPartnerParty[i - 3].species != SPECIES_NONE)
|
|
{
|
|
MoveMultiPartyMenuBoxSprite(sPartyMenuBoxes[i].monSpriteId, tXPos - 8);
|
|
MoveMultiPartyMenuBoxSprite(sPartyMenuBoxes[i].itemSpriteId, tXPos - 8);
|
|
MoveMultiPartyMenuBoxSprite(sPartyMenuBoxes[i].pokeballSpriteId, tXPos - 8);
|
|
MoveMultiPartyMenuBoxSprite(sPartyMenuBoxes[i].statusSpriteId, tXPos - 8);
|
|
}
|
|
}
|
|
ChangeBgX(2, 0x800, 1);
|
|
}
|
|
|
|
#undef tXpos
|
|
|
|
void ChooseMonForDaycare(void)
|
|
{
|
|
InitPartyMenu(PARTY_MENU_TYPE_DAYCARE, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON_2, Task_HandleChooseMonInput, BufferMonSelection);
|
|
}
|
|
|
|
// Unused
|
|
static void ChoosePartyMonByMenuType(u8 menuType)
|
|
{
|
|
gFieldCallback2 = CB2_FadeFromPartyMenu;
|
|
InitPartyMenu(menuType, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_AND_CLOSE, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, CB2_ReturnToField);
|
|
}
|
|
|
|
static void BufferMonSelection(void)
|
|
{
|
|
gSpecialVar_0x8004 = GetCursorSelectionMonId();
|
|
if (gSpecialVar_0x8004 >= PARTY_SIZE)
|
|
gSpecialVar_0x8004 = 0xFF;
|
|
gFieldCallback2 = CB2_FadeFromPartyMenu;
|
|
SetMainCallback2(CB2_ReturnToField);
|
|
}
|
|
|
|
bool8 CB2_FadeFromPartyMenu(void)
|
|
{
|
|
pal_fill_black();
|
|
CreateTask(Task_PartyMenuWaitForFade, 10);
|
|
return TRUE;
|
|
}
|
|
|
|
static void Task_PartyMenuWaitForFade(u8 taskId)
|
|
{
|
|
if (IsWeatherNotFadingIn())
|
|
{
|
|
DestroyTask(taskId);
|
|
ScriptContext2_Disable();
|
|
EnableBothScriptContexts();
|
|
}
|
|
}
|
|
|
|
void ChooseContestMon(void)
|
|
{
|
|
ScriptContext2_Enable();
|
|
FadeScreen(FADE_TO_BLACK, 0);
|
|
CreateTask(Task_ChooseContestMon, 10);
|
|
}
|
|
|
|
static void Task_ChooseContestMon(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
CleanupOverworldWindowsAndTilemaps();
|
|
InitPartyMenu(PARTY_MENU_TYPE_CONTEST, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_AND_CLOSE, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, CB2_ChooseContestMon);
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
static void CB2_ChooseContestMon(void)
|
|
{
|
|
gContestMonPartyIndex = GetCursorSelectionMonId();
|
|
if (gContestMonPartyIndex >= PARTY_SIZE)
|
|
gContestMonPartyIndex = 0xFF;
|
|
gSpecialVar_0x8004 = gContestMonPartyIndex;
|
|
gFieldCallback2 = CB2_FadeFromPartyMenu;
|
|
SetMainCallback2(CB2_ReturnToField);
|
|
}
|
|
|
|
// Used as a script special for showing a party mon to various npcs (e.g. in-game trades, move deleter)
|
|
void ChoosePartyMon(void)
|
|
{
|
|
ScriptContext2_Enable();
|
|
FadeScreen(FADE_TO_BLACK, 0);
|
|
CreateTask(Task_ChoosePartyMon, 10);
|
|
}
|
|
|
|
static void Task_ChoosePartyMon(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
CleanupOverworldWindowsAndTilemaps();
|
|
InitPartyMenu(PARTY_MENU_TYPE_CHOOSE_MON, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_AND_CLOSE, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, BufferMonSelection);
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
void ChooseMonForMoveRelearner(void)
|
|
{
|
|
ScriptContext2_Enable();
|
|
FadeScreen(FADE_TO_BLACK, 0);
|
|
CreateTask(Task_ChooseMonForMoveRelearner, 10);
|
|
}
|
|
|
|
static void Task_ChooseMonForMoveRelearner(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
CleanupOverworldWindowsAndTilemaps();
|
|
InitPartyMenu(PARTY_MENU_TYPE_MOVE_RELEARNER, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_AND_CLOSE, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, CB2_ChooseMonForMoveRelearner);
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
static void CB2_ChooseMonForMoveRelearner(void)
|
|
{
|
|
gSpecialVar_0x8004 = GetCursorSelectionMonId();
|
|
if (gSpecialVar_0x8004 >= PARTY_SIZE)
|
|
gSpecialVar_0x8004 = 0xFF;
|
|
else
|
|
gSpecialVar_0x8005 = GetNumberOfRelearnableMoves(&gPlayerParty[gSpecialVar_0x8004]);
|
|
gFieldCallback2 = CB2_FadeFromPartyMenu;
|
|
SetMainCallback2(CB2_ReturnToField);
|
|
}
|
|
|
|
void DoBattlePyramidMonsHaveHeldItem(void)
|
|
{
|
|
u8 i;
|
|
|
|
gSpecialVar_Result = FALSE;
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
if (GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) != ITEM_NONE)
|
|
{
|
|
gSpecialVar_Result = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Can be called if the Battle Pyramid Bag is full on exiting and at least one party mon still has held items
|
|
// The player can then select to toss items from the bag or take/toss held items from the party
|
|
void BattlePyramidChooseMonHeldItems(void)
|
|
{
|
|
ScriptContext2_Enable();
|
|
FadeScreen(FADE_TO_BLACK, 0);
|
|
CreateTask(Task_BattlePyramidChooseMonHeldItems, 10);
|
|
}
|
|
|
|
static void Task_BattlePyramidChooseMonHeldItems(u8 taskId)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
CleanupOverworldWindowsAndTilemaps();
|
|
InitPartyMenu(PARTY_MENU_TYPE_STORE_PYRAMID_HELD_ITEMS, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, BufferMonSelection);
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
void MoveDeleterChooseMoveToForget(void)
|
|
{
|
|
ShowPokemonSummaryScreen(PSS_MODE_SELECT_MOVE, gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, CB2_ReturnToField);
|
|
gFieldCallback = FieldCallback_ReturnToEventScript2;
|
|
}
|
|
|
|
void GetNumMovesSelectedMonHas(void)
|
|
{
|
|
u8 i;
|
|
|
|
gSpecialVar_Result = 0;
|
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
|
{
|
|
if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_MOVE1 + i) != MOVE_NONE)
|
|
gSpecialVar_Result++;
|
|
}
|
|
}
|
|
|
|
void BufferMoveDeleterNicknameAndMove(void)
|
|
{
|
|
struct Pokemon *mon = &gPlayerParty[gSpecialVar_0x8004];
|
|
u16 move = GetMonData(mon, MON_DATA_MOVE1 + gSpecialVar_0x8005);
|
|
|
|
GetMonNickname(mon, gStringVar1);
|
|
StringCopy(gStringVar2, gMoveNames[move]);
|
|
}
|
|
|
|
void MoveDeleterForgetMove(void)
|
|
{
|
|
u16 i;
|
|
|
|
SetMonMoveSlot(&gPlayerParty[gSpecialVar_0x8004], MOVE_NONE, gSpecialVar_0x8005);
|
|
RemoveMonPPBonus(&gPlayerParty[gSpecialVar_0x8004], gSpecialVar_0x8005);
|
|
for (i = gSpecialVar_0x8005; i < MAX_MON_MOVES - 1; i++)
|
|
ShiftMoveSlot(&gPlayerParty[gSpecialVar_0x8004], i, i + 1);
|
|
}
|
|
|
|
static void ShiftMoveSlot(struct Pokemon *mon, u8 slotTo, u8 slotFrom)
|
|
{
|
|
u16 move1 = GetMonData(mon, MON_DATA_MOVE1 + slotTo);
|
|
u16 move0 = GetMonData(mon, MON_DATA_MOVE1 + slotFrom);
|
|
u8 pp1 = GetMonData(mon, MON_DATA_PP1 + slotTo);
|
|
u8 pp0 = GetMonData(mon, MON_DATA_PP1 + slotFrom);
|
|
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES);
|
|
u8 ppBonusMask1 = gPPUpGetMask[slotTo];
|
|
u8 ppBonusMove1 = (ppBonuses & ppBonusMask1) >> (slotTo * 2);
|
|
u8 ppBonusMask2 = gPPUpGetMask[slotFrom];
|
|
u8 ppBonusMove2 = (ppBonuses & ppBonusMask2) >> (slotFrom * 2);
|
|
ppBonuses &= ~ppBonusMask1;
|
|
ppBonuses &= ~ppBonusMask2;
|
|
ppBonuses |= (ppBonusMove1 << (slotFrom * 2)) + (ppBonusMove2 << (slotTo * 2));
|
|
SetMonData(mon, MON_DATA_MOVE1 + slotTo, &move0);
|
|
SetMonData(mon, MON_DATA_MOVE1 + slotFrom, &move1);
|
|
SetMonData(mon, MON_DATA_PP1 + slotTo, &pp0);
|
|
SetMonData(mon, MON_DATA_PP1 + slotFrom, &pp1);
|
|
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
|
|
}
|
|
|
|
void IsSelectedMonEgg(void)
|
|
{
|
|
if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_IS_EGG))
|
|
gSpecialVar_Result = TRUE;
|
|
else
|
|
gSpecialVar_Result = FALSE;
|
|
}
|
|
|
|
void IsLastMonThatKnowsSurf(void)
|
|
{
|
|
u16 move;
|
|
u32 i, j;
|
|
|
|
gSpecialVar_Result = FALSE;
|
|
move = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_MOVE1 + gSpecialVar_0x8005);
|
|
if (move == MOVE_SURF)
|
|
{
|
|
for (i = 0; i < CalculatePlayerPartyCount(); i++)
|
|
{
|
|
if (i != gSpecialVar_0x8004)
|
|
{
|
|
for (j = 0; j < MAX_MON_MOVES; j++)
|
|
{
|
|
if (GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j) == MOVE_SURF)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (AnyStorageMonWithMove(move) != TRUE)
|
|
gSpecialVar_Result = TRUE;
|
|
}
|
|
}
|