Add "Move Item" option in party menu (#6758)
This commit is contained in:
parent
e92d48aee9
commit
96650ffd27
@ -83,6 +83,7 @@
|
||||
#define PARTY_MSG_CHOOSE_SECOND_FUSION 28
|
||||
#define PARTY_MSG_NO_POKEMON 29
|
||||
#define PARTY_MSG_CHOOSE_MON_FOR_BOX 30
|
||||
#define PARTY_MSG_MOVE_ITEM_WHERE 31
|
||||
|
||||
#define PARTY_MSG_NONE 127
|
||||
|
||||
|
||||
@ -1573,6 +1573,9 @@ extern const u8 gText_ChoosePokemon[];
|
||||
extern const u8 gText_ChoosePokemonCancel[];
|
||||
extern const u8 gText_ChoosePokemonConfirm[];
|
||||
extern const u8 gText_SendWhichMonToPC[];
|
||||
extern const u8 gText_MoveItemWhere[];
|
||||
extern const u8 gText_XsYAnd[];
|
||||
extern const u8 gText_XsYWereSwapped[];
|
||||
extern const u8 gText_MoveToWhere[];
|
||||
extern const u8 gText_TeachWhichPokemon[];
|
||||
extern const u8 gText_UseOnWhichPokemon[];
|
||||
|
||||
@ -497,9 +497,9 @@ static const struct WindowTemplate sItemGiveTakeWindowTemplate =
|
||||
{
|
||||
.bg = 2,
|
||||
.tilemapLeft = 23,
|
||||
.tilemapTop = 13,
|
||||
.tilemapTop = 11,
|
||||
.width = 6,
|
||||
.height = 6,
|
||||
.height = 8,
|
||||
.paletteNum = 14,
|
||||
.baseBlock = 0x39D,
|
||||
};
|
||||
@ -661,6 +661,7 @@ static const u8 *const sActionStringTable[] =
|
||||
[PARTY_MSG_CHOOSE_SECOND_FUSION] = gText_NextFusionMon,
|
||||
[PARTY_MSG_NO_POKEMON] = COMPOUND_STRING("You have no POKéMON."),
|
||||
[PARTY_MSG_CHOOSE_MON_FOR_BOX] = gText_SendWhichMonToPC,
|
||||
[PARTY_MSG_MOVE_ITEM_WHERE] = gText_MoveItemWhere,
|
||||
};
|
||||
|
||||
static const u8 *const sDescriptionStringTable[] =
|
||||
@ -696,33 +697,34 @@ struct
|
||||
TaskFunc func;
|
||||
} static const sCursorOptions[MENU_FIELD_MOVES] =
|
||||
{
|
||||
[MENU_SUMMARY] = {COMPOUND_STRING("SUMMARY"), CursorCb_Summary},
|
||||
[MENU_SWITCH] = {COMPOUND_STRING("SWITCH"), CursorCb_Switch},
|
||||
[MENU_CANCEL1] = {gText_Cancel2, CursorCb_Cancel1},
|
||||
[MENU_ITEM] = {COMPOUND_STRING("ITEM"), CursorCb_Item},
|
||||
[MENU_GIVE] = {gMenuText_Give, CursorCb_Give},
|
||||
[MENU_TAKE_ITEM] = {COMPOUND_STRING("TAKE"), CursorCb_TakeItem},
|
||||
[MENU_MAIL] = {COMPOUND_STRING("MAIL"), CursorCb_Mail},
|
||||
[MENU_TAKE_MAIL] = {COMPOUND_STRING("TAKE"), CursorCb_TakeMail},
|
||||
[MENU_READ] = {COMPOUND_STRING("READ"), CursorCb_Read},
|
||||
[MENU_CANCEL2] = {gText_Cancel2, CursorCb_Cancel2},
|
||||
[MENU_SHIFT] = {COMPOUND_STRING("SHIFT"), CursorCb_SendMon},
|
||||
[MENU_SEND_OUT] = {COMPOUND_STRING("SEND OUT"), CursorCb_SendMon},
|
||||
[MENU_ENTER] = {COMPOUND_STRING("ENTER"), CursorCb_Enter},
|
||||
[MENU_NO_ENTRY] = {COMPOUND_STRING("NO ENTRY"), CursorCb_NoEntry},
|
||||
[MENU_STORE] = {COMPOUND_STRING("STORE"), CursorCb_Store},
|
||||
[MENU_REGISTER] = {gText_Register, CursorCb_Register},
|
||||
[MENU_TRADE1] = {sText_Trade4, CursorCb_Trade1},
|
||||
[MENU_TRADE2] = {sText_Trade4, CursorCb_Trade2},
|
||||
[MENU_TOSS] = {gMenuText_Toss, CursorCb_Toss},
|
||||
[MENU_CATALOG_BULB] = {COMPOUND_STRING("Light bulb"), CursorCb_CatalogBulb},
|
||||
[MENU_CATALOG_OVEN] = {COMPOUND_STRING("Microwave oven"), CursorCb_CatalogOven},
|
||||
[MENU_SUMMARY] = {COMPOUND_STRING("SUMMARY"), CursorCb_Summary},
|
||||
[MENU_SWITCH] = {COMPOUND_STRING("SWITCH"), CursorCb_Switch},
|
||||
[MENU_CANCEL1] = {gText_Cancel2, CursorCb_Cancel1},
|
||||
[MENU_ITEM] = {COMPOUND_STRING("ITEM"), CursorCb_Item},
|
||||
[MENU_GIVE] = {gMenuText_Give, CursorCb_Give},
|
||||
[MENU_TAKE_ITEM] = {COMPOUND_STRING("TAKE"), CursorCb_TakeItem},
|
||||
[MENU_MOVE_ITEM] = {COMPOUND_STRING("MOVE"), CursorCb_MoveItem},
|
||||
[MENU_MAIL] = {COMPOUND_STRING("MAIL"), CursorCb_Mail},
|
||||
[MENU_TAKE_MAIL] = {COMPOUND_STRING("TAKE"), CursorCb_TakeMail},
|
||||
[MENU_READ] = {COMPOUND_STRING("READ"), CursorCb_Read},
|
||||
[MENU_CANCEL2] = {gText_Cancel2, CursorCb_Cancel2},
|
||||
[MENU_SHIFT] = {COMPOUND_STRING("SHIFT"), CursorCb_SendMon},
|
||||
[MENU_SEND_OUT] = {COMPOUND_STRING("SEND OUT"), CursorCb_SendMon},
|
||||
[MENU_ENTER] = {COMPOUND_STRING("ENTER"), CursorCb_Enter},
|
||||
[MENU_NO_ENTRY] = {COMPOUND_STRING("NO ENTRY"), CursorCb_NoEntry},
|
||||
[MENU_STORE] = {COMPOUND_STRING("STORE"), CursorCb_Store},
|
||||
[MENU_REGISTER] = {gText_Register, CursorCb_Register},
|
||||
[MENU_TRADE1] = {sText_Trade4, CursorCb_Trade1},
|
||||
[MENU_TRADE2] = {sText_Trade4, CursorCb_Trade2},
|
||||
[MENU_TOSS] = {gMenuText_Toss, CursorCb_Toss},
|
||||
[MENU_CATALOG_BULB] = {COMPOUND_STRING("Light bulb"), CursorCb_CatalogBulb},
|
||||
[MENU_CATALOG_OVEN] = {COMPOUND_STRING("Microwave oven"), CursorCb_CatalogOven},
|
||||
[MENU_CATALOG_WASHING] = {COMPOUND_STRING("Washing machine"), CursorCb_CatalogWashing},
|
||||
[MENU_CATALOG_FRIDGE] = {COMPOUND_STRING("Refrigerator"), CursorCb_CatalogFridge},
|
||||
[MENU_CATALOG_FAN] = {COMPOUND_STRING("Electric fan"), CursorCb_CatalogFan},
|
||||
[MENU_CATALOG_MOWER] = {COMPOUND_STRING("Lawn mower"), CursorCb_CatalogMower},
|
||||
[MENU_CHANGE_FORM] = {COMPOUND_STRING("Change form"), CursorCb_ChangeForm},
|
||||
[MENU_CHANGE_ABILITY] = {COMPOUND_STRING("Change Ability"), CursorCb_ChangeAbility},
|
||||
[MENU_CATALOG_FRIDGE] = {COMPOUND_STRING("Refrigerator"), CursorCb_CatalogFridge},
|
||||
[MENU_CATALOG_FAN] = {COMPOUND_STRING("Electric fan"), CursorCb_CatalogFan},
|
||||
[MENU_CATALOG_MOWER] = {COMPOUND_STRING("Lawn mower"), CursorCb_CatalogMower},
|
||||
[MENU_CHANGE_FORM] = {COMPOUND_STRING("Change form"), CursorCb_ChangeForm},
|
||||
[MENU_CHANGE_ABILITY] = {COMPOUND_STRING("Change Ability"), CursorCb_ChangeAbility},
|
||||
};
|
||||
|
||||
static const u8 sPartyMenuAction_SummarySwitchCancel[] = {MENU_SUMMARY, MENU_SWITCH, MENU_CANCEL1};
|
||||
@ -732,7 +734,7 @@ 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_GiveTakeItemCancel[] = {MENU_GIVE, MENU_TAKE_ITEM, MENU_MOVE_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};
|
||||
|
||||
125
src/party_menu.c
125
src/party_menu.c
@ -84,6 +84,7 @@ enum {
|
||||
MENU_ITEM,
|
||||
MENU_GIVE,
|
||||
MENU_TAKE_ITEM,
|
||||
MENU_MOVE_ITEM,
|
||||
MENU_MAIL,
|
||||
MENU_TAKE_MAIL,
|
||||
MENU_READ,
|
||||
@ -491,6 +492,7 @@ static void CursorCb_Cancel1(u8);
|
||||
static void CursorCb_Item(u8);
|
||||
static void CursorCb_Give(u8);
|
||||
static void CursorCb_TakeItem(u8);
|
||||
static void CursorCb_MoveItem(u8);
|
||||
static void CursorCb_Mail(u8);
|
||||
static void CursorCb_Read(u8);
|
||||
static void CursorCb_TakeMail(u8);
|
||||
@ -516,7 +518,7 @@ static bool8 SetUpFieldMove_Surf(void);
|
||||
static bool8 SetUpFieldMove_Fly(void);
|
||||
static bool8 SetUpFieldMove_Waterfall(void);
|
||||
static bool8 SetUpFieldMove_Dive(void);
|
||||
void TryItemHoldFormChange(struct Pokemon *mon);
|
||||
void TryItemHoldFormChange(struct Pokemon *mon, s8 slotId);
|
||||
static void ShowMoveSelectWindow(u8 slot);
|
||||
static void Task_HandleWhichMoveInput(u8 taskId);
|
||||
static void Task_HideFollowerNPCForTeleport(u8);
|
||||
@ -2043,7 +2045,7 @@ static void GiveItemToMon(struct Pokemon *mon, u16 item)
|
||||
itemBytes[0] = item;
|
||||
itemBytes[1] = item >> 8;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, itemBytes);
|
||||
TryItemHoldFormChange(&gPlayerParty[gPartyMenu.slotId]);
|
||||
TryItemHoldFormChange(&gPlayerParty[gPartyMenu.slotId], gPartyMenu.slotId);
|
||||
}
|
||||
|
||||
static u8 TryTakeMonItem(struct Pokemon *mon)
|
||||
@ -2057,7 +2059,7 @@ static u8 TryTakeMonItem(struct Pokemon *mon)
|
||||
|
||||
item = ITEM_NONE;
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &item);
|
||||
TryItemHoldFormChange(&gPlayerParty[gPartyMenu.slotId]);
|
||||
TryItemHoldFormChange(&gPlayerParty[gPartyMenu.slotId], gPartyMenu.slotId);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -6717,7 +6719,7 @@ static void CursorCb_ChangeAbility(u8 taskId)
|
||||
TryMultichoiceFormChange(taskId);
|
||||
}
|
||||
|
||||
void TryItemHoldFormChange(struct Pokemon *mon)
|
||||
void TryItemHoldFormChange(struct Pokemon *mon, s8 slotId)
|
||||
{
|
||||
u32 currentSpecies = GetMonData(mon, MON_DATA_SPECIES);
|
||||
u32 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_HOLD, 0);
|
||||
@ -6725,10 +6727,10 @@ void TryItemHoldFormChange(struct Pokemon *mon)
|
||||
{
|
||||
PlayCry_NormalNoDucking(targetSpecies, 0, CRY_VOLUME_RS, CRY_VOLUME_RS);
|
||||
SetMonData(mon, MON_DATA_SPECIES, &targetSpecies);
|
||||
FreeAndDestroyMonIconSprite(&gSprites[sPartyMenuBoxes[gPartyMenu.slotId].monSpriteId]);
|
||||
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), &sPartyMenuBoxes[gPartyMenu.slotId], 1);
|
||||
FreeAndDestroyMonIconSprite(&gSprites[sPartyMenuBoxes[slotId].monSpriteId]);
|
||||
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), &sPartyMenuBoxes[slotId], 1);
|
||||
CalculateMonStats(mon);
|
||||
UpdatePartyMonHeldItemSprite(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
|
||||
UpdatePartyMonHeldItemSprite(mon, &sPartyMenuBoxes[slotId]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7916,3 +7918,112 @@ void IsLastMonThatKnowsSurf(void)
|
||||
gSpecialVar_Result = !P_CAN_FORGET_HIDDEN_MOVE;
|
||||
}
|
||||
}
|
||||
|
||||
void CursorCb_MoveItemCallback(u8 taskId)
|
||||
{
|
||||
u16 item1, item2;
|
||||
u8 buffer[100];
|
||||
|
||||
if (gPaletteFade.active || MenuHelpers_ShouldWaitForLinkRecv())
|
||||
return;
|
||||
|
||||
switch (PartyMenuButtonHandler(&gPartyMenu.slotId2))
|
||||
{
|
||||
case 2: // User hit B or A while on Cancel
|
||||
HandleChooseMonCancel(taskId, &gPartyMenu.slotId2);
|
||||
break;
|
||||
case 1: // User hit A on a Pokemon
|
||||
// Pokemon can't give away items to eggs or themselves
|
||||
if (GetMonData(&gPlayerParty[gPartyMenu.slotId2], MON_DATA_IS_EGG)
|
||||
|| gPartyMenu.slotId == gPartyMenu.slotId2)
|
||||
{
|
||||
PlaySE(SE_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
PlaySE(SE_SELECT);
|
||||
gPartyMenu.action = PARTY_ACTION_CHOOSE_MON;
|
||||
|
||||
// look up held items
|
||||
item1 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_HELD_ITEM);
|
||||
item2 = GetMonData(&gPlayerParty[gPartyMenu.slotId2], MON_DATA_HELD_ITEM);
|
||||
|
||||
// swap the held items
|
||||
SetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_HELD_ITEM, &item2);
|
||||
SetMonData(&gPlayerParty[gPartyMenu.slotId2], MON_DATA_HELD_ITEM, &item1);
|
||||
|
||||
TryItemHoldFormChange(&gPlayerParty[gPartyMenu.slotId], gPartyMenu.slotId);
|
||||
TryItemHoldFormChange(&gPlayerParty[gPartyMenu.slotId2], gPartyMenu.slotId2);
|
||||
|
||||
// update the held item icons
|
||||
UpdatePartyMonHeldItemSprite(&gPlayerParty[gPartyMenu.slotId], &sPartyMenuBoxes[gPartyMenu.slotId]);
|
||||
UpdatePartyMonHeldItemSprite(&gPlayerParty[gPartyMenu.slotId2], &sPartyMenuBoxes[gPartyMenu.slotId2]);
|
||||
|
||||
// create the string describing the move
|
||||
if (item2 == ITEM_NONE)
|
||||
{
|
||||
GetMonNickname(&gPlayerParty[gPartyMenu.slotId2], gStringVar1);
|
||||
CopyItemName(item1, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, gText_PkmnWasGivenItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
|
||||
CopyItemName(item1, gStringVar2);
|
||||
StringExpandPlaceholders(buffer, gText_XsYAnd);
|
||||
|
||||
StringAppend(buffer, gText_XsYWereSwapped);
|
||||
GetMonNickname(&gPlayerParty[gPartyMenu.slotId2], gStringVar1);
|
||||
CopyItemName(item2, gStringVar2);
|
||||
StringExpandPlaceholders(gStringVar4, buffer);
|
||||
}
|
||||
|
||||
// display the string
|
||||
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
||||
|
||||
// update colors of selected boxes
|
||||
AnimatePartySlot(gPartyMenu.slotId2, 0);
|
||||
AnimatePartySlot(gPartyMenu.slotId, 1);
|
||||
|
||||
// return to the main party menu
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CursorCb_MoveItem(u8 taskId)
|
||||
{
|
||||
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
|
||||
|
||||
PlaySE(SE_SELECT);
|
||||
|
||||
// delete old windows
|
||||
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
|
||||
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
|
||||
|
||||
if (GetMonData(mon, MON_DATA_HELD_ITEM) != ITEM_NONE)
|
||||
{
|
||||
gPartyMenu.action = PARTY_ACTION_SWITCH;
|
||||
|
||||
// show "Move item to where" in bottom left
|
||||
DisplayPartyMenuStdMessage(PARTY_MSG_MOVE_ITEM_WHERE);
|
||||
// update color of first selected box
|
||||
AnimatePartySlot(gPartyMenu.slotId, 1);
|
||||
|
||||
// set up callback
|
||||
gPartyMenu.slotId2 = gPartyMenu.slotId;
|
||||
gTasks[taskId].func = CursorCb_MoveItemCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create and display string about lack of hold item
|
||||
GetMonNickname(mon, gStringVar1);
|
||||
StringExpandPlaceholders(gStringVar4, gText_PkmnNotHolding);
|
||||
DisplayPartyMenuMessage(gStringVar4, TRUE);
|
||||
|
||||
// return to the main party menu
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
gTasks[taskId].func = Task_UpdateHeldItemSprite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,6 +320,9 @@ const u8 gText_DoWhatWithMail[] = _("Do what with the MAIL?");
|
||||
const u8 gText_ChoosePokemonCancel[] = _("Choose POKéMON or CANCEL.");
|
||||
const u8 gText_ChoosePokemonConfirm[] = _("Choose POKéMON and confirm.");
|
||||
const u8 gText_SendWhichMonToPC[] = _("Send which POKéMON to the PC?");
|
||||
const u8 gText_MoveItemWhere[] = _("Move item to where?");
|
||||
const u8 gText_XsYAnd[] = _("{STR_VAR_1}'s {STR_VAR_2} and\n");
|
||||
const u8 gText_XsYWereSwapped[] = _("{STR_VAR_1}'s {STR_VAR_2} were swapped!{PAUSE_UNTIL_PRESS}");
|
||||
const u8 gText_EnjoyCycling[] = _("Let's enjoy cycling!");
|
||||
const u8 gText_InUseAlready_PM[] = _("This is in use already.");
|
||||
const u8 gText_AlreadyHoldingOne[] = _("{STR_VAR_1} is already holding\none {STR_VAR_2}.");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user