summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvan <eroelke@gmail.com>2019-11-26 13:55:24 -0700
committerEvan <eroelke@gmail.com>2019-11-26 13:55:24 -0700
commit31d8bfb04850a9a1c1639b40b7ff305a673b9c09 (patch)
treebba0c7d4e6230c2eecbb167b458bad89b8f01e04 /src
parentd1142b4290e8688a0d42bfc1b95b9d90b1721459 (diff)
parent19ecb1631b5fce1147077026a8eff890c6ec315a (diff)
fix merge conflicts
Diffstat (limited to 'src')
-rw-r--r--src/battle_controller_oak_old_man.c10
-rw-r--r--src/battle_controller_player.c10
-rw-r--r--src/battle_controller_pokedude.c10
-rw-r--r--src/battle_controllers.c6
-rw-r--r--src/battle_gfx_sfx_util.c6
-rw-r--r--src/battle_main.c52
-rw-r--r--src/battle_message.c2515
-rw-r--r--src/battle_script_commands.c14
-rw-r--r--src/berry_pouch.c6
-rw-r--r--src/data/party_menu.h1316
-rw-r--r--src/data/pokemon/tutor_learnsets.h2813
-rw-r--r--src/daycare.c2
-rw-r--r--src/field_fadetransition.c2
-rw-r--r--src/field_poison.c4
-rw-r--r--src/field_specials.c4
-rw-r--r--src/fieldmap.c4
-rw-r--r--src/fldeff_softboiled.c60
-rw-r--r--src/fldeff_sweetscent.c4
-rw-r--r--src/item.c2
-rw-r--r--src/item_pc.c8
-rw-r--r--src/item_use.c163
-rw-r--r--src/list_menu.c126
-rw-r--r--src/mailbox_pc.c4
-rw-r--r--src/map_preview_screen.c2
-rw-r--r--src/menu.c8
-rw-r--r--src/menu_helpers.c4
-rw-r--r--src/new_menu_helpers.c4
-rw-r--r--src/option_menu.c2
-rw-r--r--src/party_menu.c6381
-rw-r--r--src/player_pc.c32
-rw-r--r--src/pokemon.c20
-rw-r--r--src/pokemon_icon.c2
-rw-r--r--src/quest_log.c36
-rw-r--r--src/roamer.c2
-rw-r--r--src/save_menu_util.c2
-rw-r--r--src/sea_cottage_special_anim.c2
-rw-r--r--src/shop.c98
-rw-r--r--src/start_menu.c6
-rw-r--r--src/tm_case.c12
-rw-r--r--src/trade.c36
-rw-r--r--src/wild_pokemon_area.c2
41 files changed, 13407 insertions, 385 deletions
diff --git a/src/battle_controller_oak_old_man.c b/src/battle_controller_oak_old_man.c
index a6730cbbb..08c89ec1e 100644
--- a/src/battle_controller_oak_old_man.c
+++ b/src/battle_controller_oak_old_man.c
@@ -355,7 +355,7 @@ static void OpenPartyMenuToChooseMon(void)
caseId = gTasks[gUnknown_3004FFC[gActiveBattler]].data[0];
DestroyTask(gUnknown_3004FFC[gActiveBattler]);
FreeAllWindowBuffers();
- OpenPartyMenuInBattle(caseId);
+ OpenPartyMenuInTutorialBattle(caseId);
}
}
@@ -363,8 +363,8 @@ static void WaitForMonSelection(void)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
- if (gUnknown_203B0C0 == 1)
- BtlController_EmitChosenMonReturnValue(1, gUnknown_203B0C1, gUnknown_203B0DC);
+ if (gPartyMenuUseExitCallback == 1)
+ BtlController_EmitChosenMonReturnValue(1, gSelectedMonPartyId, gBattlePartyCurrentOrder);
else
BtlController_EmitChosenMonReturnValue(1, 6, NULL);
OakOldManBufferExecCompleted();
@@ -1879,7 +1879,7 @@ static void OakOldManHandleChooseItem(void)
gBattlerControllerFuncs[gActiveBattler] = OpenBagAndChooseItem;
gBattlerInMenuId = gActiveBattler;
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][i + 1];
+ gBattlePartyCurrentOrder[i] = gBattleBufferA[gActiveBattler][i + 1];
}
static void OakOldManHandleChoosePokemon(void)
@@ -1892,7 +1892,7 @@ static void OakOldManHandleChoosePokemon(void)
*(&gBattleStruct->field_8B) = gBattleBufferA[gActiveBattler][2];
*(&gBattleStruct->abilityPreventingSwitchout) = gBattleBufferA[gActiveBattler][3];
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][4 + i];
+ gBattlePartyCurrentOrder[i] = gBattleBufferA[gActiveBattler][4 + i];
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon;
gBattlerInMenuId = gActiveBattler;
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index 16bf1ec87..baa794f70 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -1305,7 +1305,7 @@ static void OpenPartyMenuToChooseMon(void)
caseId = gTasks[gUnknown_3004FFC[gActiveBattler]].data[0];
DestroyTask(gUnknown_3004FFC[gActiveBattler]);
FreeAllWindowBuffers();
- OpenPartyMenuInBattle(caseId);
+ OpenPartyMenuInTutorialBattle(caseId);
}
}
@@ -1313,8 +1313,8 @@ static void WaitForMonSelection(void)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
- if (gUnknown_203B0C0 == 1)
- BtlController_EmitChosenMonReturnValue(1, gUnknown_203B0C1, gUnknown_203B0DC);
+ if (gPartyMenuUseExitCallback == 1)
+ BtlController_EmitChosenMonReturnValue(1, gSelectedMonPartyId, gBattlePartyCurrentOrder);
else
BtlController_EmitChosenMonReturnValue(1, 6, NULL);
if ((gBattleBufferA[gActiveBattler][1] & 0xF) == 1)
@@ -2462,7 +2462,7 @@ static void PlayerHandleChooseItem(void)
gBattlerControllerFuncs[gActiveBattler] = OpenBagAndChooseItem;
gBattlerInMenuId = gActiveBattler;
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][1 + i];
+ gBattlePartyCurrentOrder[i] = gBattleBufferA[gActiveBattler][1 + i];
}
static void PlayerHandleChoosePokemon(void)
@@ -2475,7 +2475,7 @@ static void PlayerHandleChoosePokemon(void)
*(&gBattleStruct->field_8B) = gBattleBufferA[gActiveBattler][2];
*(&gBattleStruct->abilityPreventingSwitchout) = gBattleBufferA[gActiveBattler][3];
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][4 + i];
+ gBattlePartyCurrentOrder[i] = gBattleBufferA[gActiveBattler][4 + i];
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon;
gBattlerInMenuId = gActiveBattler;
diff --git a/src/battle_controller_pokedude.c b/src/battle_controller_pokedude.c
index 57a405f3c..0b71a92e8 100644
--- a/src/battle_controller_pokedude.c
+++ b/src/battle_controller_pokedude.c
@@ -706,7 +706,7 @@ static void OpenPartyMenuToChooseMon(void)
gBattlerControllerFuncs[gActiveBattler] = WaitForMonSelection;
DestroyTask(gUnknown_3004FFC[gActiveBattler]);
FreeAllWindowBuffers();
- sub_8127968();
+ OpenPartyMenuInBattle();
}
}
@@ -714,8 +714,8 @@ static void WaitForMonSelection(void)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
- if (gUnknown_203B0C0 == 1)
- BtlController_EmitChosenMonReturnValue(1, gUnknown_203B0C1, gUnknown_203B0DC);
+ if (gPartyMenuUseExitCallback == 1)
+ BtlController_EmitChosenMonReturnValue(1, gSelectedMonPartyId, gBattlePartyCurrentOrder);
else
BtlController_EmitChosenMonReturnValue(1, 6, NULL);
PokedudeBufferExecCompleted();
@@ -1985,7 +1985,7 @@ static void PokedudeHandleChooseItem(void)
gBattlerControllerFuncs[gActiveBattler] = OpenBagAndChooseItem;
gBattlerInMenuId = gActiveBattler;
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][i + 1];
+ gBattlePartyCurrentOrder[i] = gBattleBufferA[gActiveBattler][i + 1];
}
static void PokedudeHandleChoosePokemon(void)
@@ -1998,7 +1998,7 @@ static void PokedudeHandleChoosePokemon(void)
*(&gBattleStruct->field_8B) = gBattleBufferA[gActiveBattler][2];
*(&gBattleStruct->abilityPreventingSwitchout) = gBattleBufferA[gActiveBattler][3];
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][4 + i];
+ gBattlePartyCurrentOrder[i] = gBattleBufferA[gActiveBattler][4 + i];
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon;
gBattlerInMenuId = gActiveBattler;
diff --git a/src/battle_controllers.c b/src/battle_controllers.c
index 6fb090307..ca2ef0b22 100644
--- a/src/battle_controllers.c
+++ b/src/battle_controllers.c
@@ -75,7 +75,7 @@ void sub_800D30C(void)
SetBattlePartyIds();
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
for (i = 0; i < gBattlersCount; ++i)
- sub_8127DA8(i, 0);
+ BufferBattlePartyCurrentOrderBySide(i, 0);
}
static void InitSinglePlayerBtlControllers(void)
@@ -199,11 +199,11 @@ static void InitLinkBtlControllers(void)
{
case 0:
case 3:
- sub_8127DA8(gLinkPlayers[i].id, 0);
+ BufferBattlePartyCurrentOrderBySide(gLinkPlayers[i].id, 0);
break;
case 1:
case 2:
- sub_8127DA8(gLinkPlayers[i].id, 1);
+ BufferBattlePartyCurrentOrderBySide(gLinkPlayers[i].id, 1);
break;
}
if (i == multiplayerId)
diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c
index d2e728d0c..d7bccb298 100644
--- a/src/battle_gfx_sfx_util.c
+++ b/src/battle_gfx_sfx_util.c
@@ -620,7 +620,7 @@ bool8 BattleInitAllSprites(u8 *state, u8 *battlerId)
break;
case 6:
LoadAndCreateEnemyShadowSprites();
- sub_8127CAC();
+ BufferBattlePartyCurrentOrder();
retVal = TRUE;
break;
}
@@ -859,8 +859,8 @@ void HandleBattleLowHpMusicChange(void)
{
u8 playerBattler1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
u8 playerBattler2 = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
- u8 battler1PartyId = pokemon_order_func(gBattlerPartyIndexes[playerBattler1]);
- u8 battler2PartyId = pokemon_order_func(gBattlerPartyIndexes[playerBattler2]);
+ u8 battler1PartyId = GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[playerBattler1]);
+ u8 battler2PartyId = GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[playerBattler2]);
if (GetMonData(&gPlayerParty[battler1PartyId], MON_DATA_HP) != 0)
HandleLowHpMusicChange(&gPlayerParty[battler1PartyId], playerBattler1);
diff --git a/src/battle_main.c b/src/battle_main.c
index 1125a8d2d..d307d4f55 100644
--- a/src/battle_main.c
+++ b/src/battle_main.c
@@ -144,7 +144,7 @@ static EWRAM_DATA u32 gUnknown_2022AE8[25] = {0};
EWRAM_DATA u32 gBattleTypeFlags = 0;
EWRAM_DATA u8 gBattleTerrain = 0;
EWRAM_DATA u32 gUnknown_2022B54 = 0;
-EWRAM_DATA struct UnknownPokemonStruct4 gUnknown_2022B58[3] = {0};
+EWRAM_DATA struct UnknownPokemonStruct4 gMultiPartnerParty[3] = {0};
EWRAM_DATA u8 *gUnknown_2022BB8 = NULL;
EWRAM_DATA u8 *gUnknown_2022BBC = NULL;
EWRAM_DATA u16 *gUnknown_2022BC0 = NULL;
@@ -1078,16 +1078,16 @@ static void sub_80108C4(void)
for (i = 0; i < 3; ++i)
{
- gUnknown_2022B58[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES);
- gUnknown_2022B58[i].heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
- nick = gUnknown_2022B58[i].nickname;
+ gMultiPartnerParty[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES);
+ gMultiPartnerParty[i].heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
+ nick = gMultiPartnerParty[i].nickname;
GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nick);
- gUnknown_2022B58[i].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
- gUnknown_2022B58[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP);
- gUnknown_2022B58[i].maxhp = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP);
- gUnknown_2022B58[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS);
- gUnknown_2022B58[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY);
- gUnknown_2022B58[i].gender = GetMonGender(&gPlayerParty[i]);
+ gMultiPartnerParty[i].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
+ gMultiPartnerParty[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP);
+ gMultiPartnerParty[i].maxhp = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP);
+ gMultiPartnerParty[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS);
+ gMultiPartnerParty[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY);
+ gMultiPartnerParty[i].gender = GetMonGender(&gPlayerParty[i]);
StripExtCtrlCodes(nick);
if (GetMonData(&gPlayerParty[i], MON_DATA_LANGUAGE) != LANGUAGE_JAPANESE)
{
@@ -1098,7 +1098,7 @@ static void sub_80108C4(void)
cur[j] = EOS;
}
}
- memcpy(&gBattleStruct->field_184, gUnknown_2022B58, sizeof(gUnknown_2022B58));
+ memcpy(&gBattleStruct->field_184, gMultiPartnerParty, sizeof(gMultiPartnerParty));
}
static void CB2_PreInitMultiBattle(void)
@@ -1123,7 +1123,7 @@ static void CB2_PreInitMultiBattle(void)
if (gReceivedRemoteLinkPlayers != 0 && IsLinkTaskFinished())
{
sub_80108C4();
- SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_184, sizeof(gUnknown_2022B58));
+ SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_184, sizeof(gMultiPartnerParty));
++gBattleCommunication[MULTIUSE_STATE];
}
break;
@@ -1137,13 +1137,13 @@ static void CB2_PreInitMultiBattle(void)
continue;
if ((!(gLinkPlayers[i].id & 1) && !(gLinkPlayers[playerMultiplierId].id & 1))
|| (gLinkPlayers[i].id & 1 && gLinkPlayers[playerMultiplierId].id & 1))
- memcpy(gUnknown_2022B58, gBlockRecvBuffer[i], sizeof(gUnknown_2022B58));
+ memcpy(gMultiPartnerParty, gBlockRecvBuffer[i], sizeof(gMultiPartnerParty));
}
++gBattleCommunication[MULTIUSE_STATE];
*savedCallback = gMain.savedCallback;
*savedBattleTypeFlags = gBattleTypeFlags;
gMain.savedCallback = CB2_PreInitMultiBattle;
- sub_8128198();
+ ShowPartyMenuToShowcaseMultiBattleParty();
}
break;
case 2:
@@ -3004,22 +3004,22 @@ void sub_8013F6C(u8 battler)
u8 r4, r1;
for (i = 0; i < 3; ++i)
- gUnknown_203B0DC[i] = *(battler * 3 + i + (u8 *)(gBattleStruct->field_60));
- r4 = pokemon_order_func(gBattlerPartyIndexes[battler]);
- r1 = pokemon_order_func(*(gBattleStruct->monToSwitchIntoId + battler));
- sub_8127FF4(r4, r1);
+ gBattlePartyCurrentOrder[i] = *(battler * 3 + i + (u8 *)(gBattleStruct->field_60));
+ r4 = GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[battler]);
+ r1 = GetPartyIdFromBattlePartyId(*(gBattleStruct->monToSwitchIntoId + battler));
+ SwitchPartyMonSlots(r4, r1);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
for (i = 0; i < 3; ++i)
{
- *(battler * 3 + i + (u8 *)(gBattleStruct->field_60)) = gUnknown_203B0DC[i];
- *(BATTLE_PARTNER(battler) * 3 + i + (u8 *)(gBattleStruct->field_60)) = gUnknown_203B0DC[i];
+ *(battler * 3 + i + (u8 *)(gBattleStruct->field_60)) = gBattlePartyCurrentOrder[i];
+ *(BATTLE_PARTNER(battler) * 3 + i + (u8 *)(gBattleStruct->field_60)) = gBattlePartyCurrentOrder[i];
}
}
else
{
for (i = 0; i < 3; ++i)
- *(battler * 3 + i + (u8 *)(gBattleStruct->field_60)) = gUnknown_203B0DC[i];
+ *(battler * 3 + i + (u8 *)(gBattleStruct->field_60)) = gBattlePartyCurrentOrder[i];
}
}
@@ -3137,7 +3137,7 @@ static void HandleTurnActionSelectionState(void)
*(gBattleStruct->field_58 + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler];
if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION) || gStatuses3[gActiveBattler] & STATUS3_ROOTED)
{
- BtlController_EmitChoosePokemon(0, PARTY_CANT_SWITCH, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
+ BtlController_EmitChoosePokemon(0, PARTY_ACTION_CANT_SWITCH, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
}
else if ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_SHADOW_TAG))
|| ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_ARENA_TRAP))
@@ -3146,16 +3146,16 @@ static void HandleTurnActionSelectionState(void)
|| ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0))
&& IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)))
{
- BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]);
+ BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ACTION_ABILITY_PREVENTS, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]);
}
else
{
if (gActiveBattler == 2 && gChosenActionByBattler[0] == B_ACTION_SWITCH)
- BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 0), ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
+ BtlController_EmitChoosePokemon(0, PARTY_ACTION_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 0), ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
else if (gActiveBattler == 3 && gChosenActionByBattler[1] == B_ACTION_SWITCH)
- BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 1), ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
+ BtlController_EmitChoosePokemon(0, PARTY_ACTION_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 1), ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
else
- BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
+ BtlController_EmitChoosePokemon(0, PARTY_ACTION_CHOOSE_MON, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
}
MarkBattlerForControllerExec(gActiveBattler);
break;
diff --git a/src/battle_message.c b/src/battle_message.c
new file mode 100644
index 000000000..396c4c7f0
--- /dev/null
+++ b/src/battle_message.c
@@ -0,0 +1,2515 @@
+#include "global.h"
+#include "battle_string_ids.h"
+#include "battle.h"
+#include "palette.h"
+#include "battle_anim.h"
+#include "string_util.h"
+#include "text.h"
+#include "window.h"
+#include "strings.h"
+#include "battle_message.h"
+#include "link.h"
+#include "event_scripts.h"
+#include "event_data.h"
+#include "item.h"
+#include "battle_tower.h"
+#include "trainer_tower.h"
+#include "battle_setup.h"
+#include "field_specials.h"
+#include "new_menu_helpers.h"
+#include "battle_controllers.h"
+#include "graphics.h"
+#include "constants/moves.h"
+#include "constants/items.h"
+#include "constants/trainer_classes.h"
+
+struct BattleWindowText
+{
+ u8 fillValue;
+ u8 fontId;
+ u8 x;
+ u8 y;
+ u8 letterSpacing;
+ u8 lineSpacing;
+ u8 speed;
+ u8 fgColor;
+ u8 bgColor;
+ u8 shadowColor;
+};
+
+static EWRAM_DATA u8 sBattlerAbilities[MAX_BATTLERS_COUNT] = {};
+static EWRAM_DATA struct BattleMsgData *sBattleMsgDataPtr = NULL;
+
+static void ChooseMoveUsedParticle(u8 *textPtr);
+static void ChooseTypeOfMoveUsedString(u8 *textPtr);
+static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst);
+
+const u8 gUnknown_83FB218[] = _("");
+const u8 gUnknown_83FB219[] = _("{B_TRAINER1_LOSE_TEXT}");
+const u8 gUnknown_83FB21C[] = _("{B_TRAINER2_CLASS}");
+const u8 gUnknown_83FB21F[] = _("{B_TRAINER1_NAME}: {B_OPPONENT_MON1_NAME}, come back!");
+const u8 gUnknown_83FB232[] = _("{B_TRAINER1_WIN_TEXT}");
+const u8 gUnknown_83FB235[] = _("{B_TRAINER1_NAME}: {B_OPPONENT_MON2_NAME}, come back!");
+const u8 gUnknown_83FB248[] = _("{B_TRAINER1_NAME}: {B_OPPONENT_MON1_NAME} and\n{B_OPPONENT_MON2_NAME}, come back!");
+const u8 gUnknown_83FB262[] = _("{B_TRAINER2_NAME}");
+const u8 gUnknown_83FB265[] = _("{B_BUFF1} gained{B_BUFF2}\n{B_TRAINER2_LOSE_TEXT} EXP. Points!\p");
+const u8 gUnknown_83FB282[] = _("");
+const u8 gUnknown_83FB283[] = _(" a boosted");
+const u8 gUnknown_83FB28E[] = _("{B_BUFF1} grew to\nLV. {B_BUFF2}!{WAIT_SE}\p");
+const u8 gUnknown_83FB2A4[] = _("{B_BUFF1} learned\n{B_BUFF2}!{WAIT_SE}\p");
+const u8 gUnknown_83FB2B6[] = _("{B_BUFF1} is trying to\nlearn {B_BUFF2}.\p");
+const u8 gUnknown_83FB2D1[] = _("But, {B_BUFF1} can't learn\nmore than four moves.\p");
+const u8 gUnknown_83FB2FC[] = _("Delete a move to make\nroom for {B_BUFF2}?");
+const u8 gUnknown_83FB31F[] = _("{B_BUFF1} forgot\n{B_BUFF2}.\p");
+const u8 gUnknown_83FB32E[] = _("{PAUSE 32}Stop learning\n{B_BUFF2}?");
+const u8 gUnknown_83FB343[] = _("{B_BUFF1} did not learn\n{B_BUFF2}.\p");
+const u8 gUnknown_83FB359[] = _("Use next POKéMON?");
+const u8 gUnknown_83FB36B[] = _("{B_ATK_NAME_WITH_PREFIX}'s\nattack missed!");
+const u8 gUnknown_83FB37F[] = _("{B_DEF_NAME_WITH_PREFIX}\nprotected itself!");
+const u8 gUnknown_83FB394[] = _("{B_DEF_NAME_WITH_PREFIX} avoided\ndamage with {B_DEF_ABILITY}!");
+const u8 gUnknown_83FB3AF[] = _("{B_DEF_NAME_WITH_PREFIX} makes GROUND\nmoves miss with {B_DEF_ABILITY}!");
+const u8 gUnknown_83FB3D3[] = _("{B_DEF_NAME_WITH_PREFIX} avoided\nthe attack!");
+const u8 gUnknown_83FB3EA[] = _("It doesn't affect\n{B_DEF_NAME_WITH_PREFIX}…");
+const u8 gUnknown_83FB400[] = _("{B_ATK_NAME_WITH_PREFIX}\nfainted!\p");
+const u8 gUnknown_83FB40D[] = _("{B_DEF_NAME_WITH_PREFIX}\nfainted!\p");
+const u8 gUnknown_83FB41A[] = _("{B_PLAYER_NAME} got ¥{B_BUFF1}\nfor winning!\p");
+const u8 gUnknown_83FB433[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\p");
+const u8 gUnknown_83FB451[] = _("{B_PLAYER_NAME} panicked and lost ¥{B_BUFF1}…\p… … … …\p{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
+const u8 gUnknown_83FB484[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\pPlayer lost against\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!{PAUSE_UNTIL_PRESS}");
+const u8 gUnknown_83FB4BE[] = _("{B_PLAYER_NAME} paid ¥{B_BUFF1} as the prize\nmoney…\p… … … …\p{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
+const u8 gUnknown_83FB4F7[] = _("{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
+const u8 gUnknown_83FB508[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents\nescape with {B_SCR_ACTIVE_ABILITY}!\p");
+const u8 gUnknown_83FB525[] = _("Can't escape!\p");
+const u8 gUnknown_83FB534[] = _("{B_ATK_NAME_WITH_PREFIX} can't escape!");
+const u8 gUnknown_83FB545[] = _("Hit {B_BUFF1} time(s)!");
+const u8 gUnknown_83FB555[] = _("{B_EFF_NAME_WITH_PREFIX}\nfell asleep!");
+const u8 gUnknown_83FB565[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nmade {B_EFF_NAME_WITH_PREFIX} sleep!");
+const u8 gUnknown_83FB57C[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready asleep!");
+const u8 gUnknown_83FB592[] = _("{B_ATK_NAME_WITH_PREFIX} is\nalready asleep!");
+const u8 gUnknown_83FB5A8[] = _("{B_DEF_NAME_WITH_PREFIX}\nwasn't affected!");
+const u8 gUnknown_83FB5BC[] = _("{B_EFF_NAME_WITH_PREFIX}\nwas poisoned!");
+const u8 gUnknown_83FB5CD[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\npoisoned {B_EFF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FB5E2[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby poison!");
+const u8 gUnknown_83FB5F8[] = _("{B_DEF_NAME_WITH_PREFIX} is already\npoisoned.");
+const u8 gUnknown_83FB610[] = _("{B_EFF_NAME_WITH_PREFIX} is badly\npoisoned!");
+const u8 gUnknown_83FB626[] = _("{B_DEF_NAME_WITH_PREFIX} had its\nenergy drained!");
+const u8 gUnknown_83FB641[] = _("{B_EFF_NAME_WITH_PREFIX} was burned!");
+const u8 gUnknown_83FB650[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nburned {B_EFF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FB663[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby its burn!");
+const u8 gUnknown_83FB67B[] = _("{B_DEF_NAME_WITH_PREFIX} already\nhas a burn.");
+const u8 gUnknown_83FB692[] = _("{B_EFF_NAME_WITH_PREFIX} was\nfrozen solid!");
+const u8 gUnknown_83FB6A7[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nfroze {B_EFF_NAME_WITH_PREFIX} solid!");
+const u8 gUnknown_83FB6BF[] = _("{B_ATK_NAME_WITH_PREFIX} is\nfrozen solid!");
+const u8 gUnknown_83FB6D3[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndefrosted!");
+const u8 gUnknown_83FB6E5[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted!");
+const u8 gUnknown_83FB6F7[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted by {B_CURRENT_MOVE}!");
+const u8 gUnknown_83FB70F[] = _("{B_EFF_NAME_WITH_PREFIX} is paralyzed!\nIt may be unable to move!");
+const u8 gUnknown_83FB73A[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nparalyzed {B_EFF_NAME_WITH_PREFIX}!\lIt may be unable to move!");
+const u8 gUnknown_83FB76A[] = _("{B_ATK_NAME_WITH_PREFIX} is paralyzed!\nIt can't move!");
+const u8 gUnknown_83FB78A[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready paralyzed!");
+const u8 gUnknown_83FB7A3[] = _("{B_DEF_NAME_WITH_PREFIX} was\nhealed of paralysis!");
+const u8 gUnknown_83FB7BF[] = _("{B_DEF_NAME_WITH_PREFIX}'s\ndream was eaten!");
+const u8 gUnknown_83FB7D5[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1}\nwon't go higher!");
+const u8 gUnknown_83FB7EE[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}\nwon't go lower!");
+const u8 gUnknown_83FB806[] = _("Your team's {B_BUFF1}\nstopped working!");
+const u8 gUnknown_83FB826[] = _("The foe's {B_BUFF1}\nstopped working!");
+const u8 gUnknown_83FB844[] = _("{B_ATK_NAME_WITH_PREFIX} is\nconfused!");
+const u8 gUnknown_83FB854[] = _("{B_ATK_NAME_WITH_PREFIX} snapped\nout of confusion!");
+const u8 gUnknown_83FB871[] = _("{B_EFF_NAME_WITH_PREFIX} became\nconfused!");
+const u8 gUnknown_83FB885[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready confused!");
+const u8 gUnknown_83FB89D[] = _("{B_DEF_NAME_WITH_PREFIX}\nfell in love!");
+const u8 gUnknown_83FB8AE[] = _("{B_ATK_NAME_WITH_PREFIX} is in love\nwith {B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FB8C5[] = _("{B_ATK_NAME_WITH_PREFIX} is\nimmobilized by love!");
+const u8 gUnknown_83FB8E0[] = _("{B_DEF_NAME_WITH_PREFIX} was\nblown away!");
+const u8 gUnknown_83FB8F3[] = _("{B_ATK_NAME_WITH_PREFIX} transformed\ninto the {B_BUFF1} type!");
+const u8 gUnknown_83FB914[] = _("{B_ATK_NAME_WITH_PREFIX} flinched!");
+const u8 gUnknown_83FB921[] = _("{B_DEF_NAME_WITH_PREFIX} regained\nhealth!");
+const u8 gUnknown_83FB935[] = _("{B_DEF_NAME_WITH_PREFIX}'s\nHP is full!");
+const u8 gUnknown_83FB946[] = _("{B_ATK_PREFIX2}'s {B_CURRENT_MOVE}\nraised SP. DEF!");
+const u8 gUnknown_83FB95E[] = _("{B_ATK_PREFIX2}'s {B_CURRENT_MOVE}\nraised SP. DEF a little!");
+const u8 gUnknown_83FB97F[] = _("{B_ATK_PREFIX2}'s {B_CURRENT_MOVE}\nraised DEFENSE!");
+const u8 gUnknown_83FB997[] = _("{B_ATK_PREFIX2}'s {B_CURRENT_MOVE}\nraised DEFENSE a little!");
+const u8 gUnknown_83FB9B8[] = _("{B_ATK_PREFIX2}'s party is covered\nby a veil!");
+const u8 gUnknown_83FB9D9[] = _("{B_DEF_NAME_WITH_PREFIX}'s party is protected\nby SAFEGUARD!");
+const u8 gUnknown_83FB9FF[] = _("{B_ATK_PREFIX3}'s party is no longer\nprotected by SAFEGUARD!");
+const u8 gUnknown_83FBA2F[] = _("{B_ATK_NAME_WITH_PREFIX} went\nto sleep!");
+const u8 gUnknown_83FBA41[] = _("{B_ATK_NAME_WITH_PREFIX} slept and\nbecame healthy!");
+const u8 gUnknown_83FBA5E[] = _("{B_ATK_NAME_WITH_PREFIX} whipped\nup a whirlwind!");
+const u8 gUnknown_83FBA79[] = _("{B_ATK_NAME_WITH_PREFIX} took\nin sunlight!");
+const u8 gUnknown_83FBA8E[] = _("{B_ATK_NAME_WITH_PREFIX} lowered\nits head!");
+const u8 gUnknown_83FBAA3[] = _("{B_ATK_NAME_WITH_PREFIX} is glowing!");
+const u8 gUnknown_83FBAB2[] = _("{B_ATK_NAME_WITH_PREFIX} flew\nup high!");
+const u8 gUnknown_83FBAC3[] = _("{B_ATK_NAME_WITH_PREFIX} dug a hole!");
+const u8 gUnknown_83FBAD2[] = _("{B_ATK_NAME_WITH_PREFIX} hid\nunderwater!");
+const u8 gUnknown_83FBAE5[] = _("{B_ATK_NAME_WITH_PREFIX} sprang up!");
+const u8 gUnknown_83FBAF3[] = _("{B_DEF_NAME_WITH_PREFIX} was squeezed by\n{B_ATK_NAME_WITH_PREFIX}'s BIND!");
+const u8 gUnknown_83FBB11[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nin the vortex!");
+const u8 gUnknown_83FBB2F[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nby SAND TOMB!");
+const u8 gUnknown_83FBB4C[] = _("{B_DEF_NAME_WITH_PREFIX} was WRAPPED by\n{B_ATK_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FBB62[] = _("{B_ATK_NAME_WITH_PREFIX} CLAMPED\n{B_DEF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FBB71[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby {B_BUFF1}!");
+const u8 gUnknown_83FBB83[] = _("{B_ATK_NAME_WITH_PREFIX} was freed\nfrom {B_BUFF1}!");
+const u8 gUnknown_83FBB99[] = _("{B_ATK_NAME_WITH_PREFIX} kept going\nand crashed!");
+const u8 gBattleText_MistShroud[] = _("{B_ATK_PREFIX2} became\nshrouded in MIST!");
+const u8 gUnknown_83FBBD0[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected\nby MIST!");
+const u8 gBattleText_GetPumped[] = _("{B_ATK_NAME_WITH_PREFIX} is getting\npumped!");
+const u8 gUnknown_83FBBFF[] = _("{B_ATK_NAME_WITH_PREFIX} is hit\nwith recoil!");
+const u8 gUnknown_83FBC16[] = _("{B_ATK_NAME_WITH_PREFIX} protected\nitself!");
+const u8 gUnknown_83FBC2B[] = _("{B_ATK_NAME_WITH_PREFIX} is buffeted\nby the sandstorm!");
+const u8 gUnknown_83FBC4C[] = _("{B_ATK_NAME_WITH_PREFIX} is pelted\nby HAIL!");
+const u8 gUnknown_83FBC62[] = _("{B_ATK_PREFIX1}'s {B_BUFF1}\nwore off!");
+const u8 gUnknown_83FBC74[] = _("{B_DEF_NAME_WITH_PREFIX} was seeded!");
+const u8 gUnknown_83FBC83[] = _("{B_DEF_NAME_WITH_PREFIX} evaded\nthe attack!");
+const u8 gUnknown_83FBC99[] = _("{B_ATK_NAME_WITH_PREFIX}'s health is\nsapped by LEECH SEED!");
+const u8 gUnknown_83FBCBE[] = _("{B_ATK_NAME_WITH_PREFIX} is fast\nasleep.");
+const u8 gUnknown_83FBCD1[] = _("{B_ATK_NAME_WITH_PREFIX} woke up!");
+const u8 gUnknown_83FBCDD[] = _("But {B_SCR_ACTIVE_NAME_WITH_PREFIX}'s UPROAR\nkept it awake!");
+const u8 gUnknown_83FBCFC[] = _("{B_ATK_NAME_WITH_PREFIX} woke up\nin the UPROAR!");
+const u8 gUnknown_83FBD16[] = _("{B_ATK_NAME_WITH_PREFIX} caused\nan UPROAR!");
+const u8 gUnknown_83FBD2B[] = _("{B_ATK_NAME_WITH_PREFIX} is making\nan UPROAR!");
+const u8 gUnknown_83FBD43[] = _("{B_ATK_NAME_WITH_PREFIX} calmed down.");
+const u8 gUnknown_83FBD53[] = _("But {B_DEF_NAME_WITH_PREFIX} can't\nsleep in an UPROAR!");
+const u8 gUnknown_83FBD74[] = _("{B_ATK_NAME_WITH_PREFIX} STOCKPILED\n{B_BUFF1}!");
+const u8 gUnknown_83FBD86[] = _("{B_ATK_NAME_WITH_PREFIX} can't\nSTOCKPILE any more!");
+const u8 gUnknown_83FBDA3[] = _("But {B_DEF_NAME_WITH_PREFIX} can't\nsleep in an UPROAR!");
+const u8 gUnknown_83FBDC4[] = _("But the UPROAR kept\n{B_DEF_NAME_WITH_PREFIX} awake!");
+const u8 gUnknown_83FBDE2[] = _("{B_DEF_NAME_WITH_PREFIX} stayed awake\nusing its {B_DEF_ABILITY}!");
+const u8 gUnknown_83FBE00[] = _("{B_ATK_NAME_WITH_PREFIX} is storing\nenergy!");
+const u8 gUnknown_83FBE16[] = _("{B_ATK_NAME_WITH_PREFIX} unleashed\nenergy!");
+const u8 gUnknown_83FBE2B[] = _("{B_ATK_NAME_WITH_PREFIX} became\nconfused due to fatigue!");
+const u8 gUnknown_83FBE4E[] = _("{B_PLAYER_NAME} picked up\n¥{B_BUFF1}!\p");
+const u8 gUnknown_83FBE61[] = _("{B_DEF_NAME_WITH_PREFIX} is\nunaffected!");
+const u8 gUnknown_83FBE73[] = _("{B_ATK_NAME_WITH_PREFIX} transformed\ninto {B_BUFF1}!");
+const u8 gUnknown_83FBE8B[] = _("{B_ATK_NAME_WITH_PREFIX} made\na SUBSTITUTE!");
+const u8 gUnknown_83FBEA1[] = _("{B_ATK_NAME_WITH_PREFIX} already\nhas a SUBSTITUTE!");
+const u8 gUnknown_83FBEBE[] = _("The SUBSTITUTE took damage\nfor {B_DEF_NAME_WITH_PREFIX}!\p");
+const u8 gUnknown_83FBEE2[] = _("{B_DEF_NAME_WITH_PREFIX}'s\nSUBSTITUTE faded!\p");
+const u8 gUnknown_83FBEFA[] = _("{B_ATK_NAME_WITH_PREFIX} must\nrecharge!");
+const u8 gUnknown_83FBF0C[] = _("{B_DEF_NAME_WITH_PREFIX}'s RAGE\nis building!");
+const u8 gUnknown_83FBF23[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}\nwas disabled!");
+const u8 gUnknown_83FBF39[] = _("{B_ATK_NAME_WITH_PREFIX} is disabled\nno more!");
+const u8 gUnknown_83FBF51[] = _("{B_DEF_NAME_WITH_PREFIX} got\nan ENCORE!");
+const u8 gUnknown_83FBF63[] = _("{B_ATK_NAME_WITH_PREFIX}'s ENCORE\nended!");
+const u8 gUnknown_83FBF76[] = _("{B_ATK_NAME_WITH_PREFIX} took aim\nat {B_DEF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FBF89[] = _("{B_ATK_NAME_WITH_PREFIX} SKETCHED\n{B_BUFF1}!");
+const u8 gUnknown_83FBF99[] = _("{B_ATK_NAME_WITH_PREFIX} is trying\nto take its foe with it!");
+const u8 gUnknown_83FBFBF[] = _("{B_DEF_NAME_WITH_PREFIX} took\n{B_ATK_NAME_WITH_PREFIX} with it!");
+const u8 gUnknown_83FBFD3[] = _("Reduced {B_DEF_NAME_WITH_PREFIX}'s\n{B_BUFF1} by {B_BUFF2}!");
+const u8 gUnknown_83FBFEA[] = _("{B_ATK_NAME_WITH_PREFIX} stole\n{B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ITEM}!");
+const u8 gUnknown_83FBFFC[] = _("{B_DEF_NAME_WITH_PREFIX} can't\nescape now!");
+const u8 gUnknown_83FC011[] = _("{B_DEF_NAME_WITH_PREFIX} fell into\na NIGHTMARE!");
+const u8 gUnknown_83FC02B[] = _("{B_ATK_NAME_WITH_PREFIX} is locked\nin a NIGHTMARE!");
+const u8 gUnknown_83FC048[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP and\nlaid a CURSE on {B_DEF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FC072[] = _("{B_ATK_NAME_WITH_PREFIX} is afflicted\nby the CURSE!");
+const u8 gUnknown_83FC090[] = _("SPIKES were scattered all around\nthe opponent's side!");
+const u8 gUnknown_83FC0C6[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is hurt\nby SPIKES!");
+const u8 gUnknown_83FC0DC[] = _("{B_ATK_NAME_WITH_PREFIX} identified\n{B_DEF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FC0EE[] = _("{B_ATK_NAME_WITH_PREFIX}'s PERISH count\nfell to {B_BUFF1}!");
+const u8 gUnknown_83FC10C[] = _("{B_ATK_NAME_WITH_PREFIX} braced\nitself!");
+const u8 gUnknown_83FC11E[] = _("{B_DEF_NAME_WITH_PREFIX} ENDURED\nthe hit!");
+const u8 gUnknown_83FC132[] = _("MAGNITUDE {B_BUFF1}!");
+const u8 gUnknown_83FC140[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP\nand maximized ATTACK!");
+const u8 gUnknown_83FC168[] = _("{B_ATK_NAME_WITH_PREFIX} copied\n{B_DEF_NAME_WITH_PREFIX}'s stat changes!");
+const u8 gUnknown_83FC185[] = _("{B_ATK_NAME_WITH_PREFIX} got free of\n{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}!");
+const u8 gUnknown_83FC19D[] = _("{B_ATK_NAME_WITH_PREFIX} shed\nLEECH SEED!");
+const u8 gUnknown_83FC1B1[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nSPIKES!");
+const u8 gUnknown_83FC1C6[] = _("{B_ATK_NAME_WITH_PREFIX} fled from\nbattle!");
+const u8 gUnknown_83FC1DB[] = _("{B_ATK_NAME_WITH_PREFIX} foresaw\nan attack!");
+const u8 gUnknown_83FC1F1[] = _("{B_DEF_NAME_WITH_PREFIX} took the\n{B_BUFF1} attack!");
+const u8 gUnknown_83FC208[] = _("{B_ATK_NAME_WITH_PREFIX} chose\n{B_CURRENT_MOVE} as its destiny!");
+const u8 gUnknown_83FC224[] = _("{B_BUFF1}'s attack!");
+const u8 gUnknown_83FC231[] = _("{B_ATK_NAME_WITH_PREFIX} became the\ncenter of attention!");
+const u8 gUnknown_83FC254[] = _("{B_ATK_NAME_WITH_PREFIX} began\ncharging power!");
+const u8 gUnknown_83FC26D[] = _("NATURE POWER turned into\n{B_CURRENT_MOVE}!");
+const u8 gUnknown_83FC28A[] = _("{B_ATK_NAME_WITH_PREFIX}'s status\nreturned to normal!");
+const u8 gUnknown_83FC2AA[] = _("{B_DEF_NAME_WITH_PREFIX} was subjected\nto TORMENT!");
+const u8 gUnknown_83FC2C7[] = _("{B_ATK_NAME_WITH_PREFIX} is tightening\nits focus!");
+const u8 gUnknown_83FC2E3[] = _("{B_DEF_NAME_WITH_PREFIX} fell for\nthe TAUNT!");
+const u8 gUnknown_83FC2FA[] = _("{B_ATK_NAME_WITH_PREFIX} is ready to\nhelp {B_DEF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FC312[] = _("{B_ATK_NAME_WITH_PREFIX} switched\nitems with its opponent!");
+const u8 gUnknown_83FC337[] = _("{B_ATK_NAME_WITH_PREFIX} obtained\n{B_BUFF1}.");
+const u8 gUnknown_83FC347[] = _("{B_DEF_NAME_WITH_PREFIX} obtained\n{B_BUFF2}.");
+const u8 gUnknown_83FC357[] = _("{B_ATK_NAME_WITH_PREFIX} obtained\n{B_BUFF1}.\p{B_DEF_NAME_WITH_PREFIX} obtained\n{B_BUFF2}.");
+const u8 gUnknown_83FC377[] = _("{B_ATK_NAME_WITH_PREFIX} copied\n{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}!");
+const u8 gUnknown_83FC38A[] = _("{B_ATK_NAME_WITH_PREFIX} made a WISH!");
+const u8 gUnknown_83FC39A[] = _("{B_BUFF1}'s WISH\ncame true!");
+const u8 gUnknown_83FC3AF[] = _("{B_ATK_NAME_WITH_PREFIX} planted its roots!");
+const u8 gUnknown_83FC3C5[] = _("{B_ATK_NAME_WITH_PREFIX} absorbed\nnutrients with its roots!");
+const u8 gUnknown_83FC3EB[] = _("{B_DEF_NAME_WITH_PREFIX} anchored\nitself with its roots!");
+const u8 gUnknown_83FC40E[] = _("{B_ATK_NAME_WITH_PREFIX} made\n{B_DEF_NAME_WITH_PREFIX} drowsy!");
+const u8 gUnknown_83FC421[] = _("{B_ATK_NAME_WITH_PREFIX} knocked off\n{B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ITEM}!");
+const u8 gUnknown_83FC439[] = _("{B_ATK_NAME_WITH_PREFIX} swapped abilities\nwith its opponent!");
+const u8 gUnknown_83FC461[] = _("{B_ATK_NAME_WITH_PREFIX} sealed the\nopponent's moveシsス!");
+const u8 gUnknown_83FC483[] = _("{B_ATK_NAME_WITH_PREFIX} wants the\nopponent to bear a GRUDGE!");
+const u8 gUnknown_83FC4AB[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} lost\nall its PP due to the GRUDGE!");
+const u8 gUnknown_83FC4D6[] = _("{B_ATK_NAME_WITH_PREFIX} shrouded\nitself in {B_CURRENT_MOVE}!");
+const u8 gUnknown_83FC4F0[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE}\nwas bounced back by MAGIC COAT!");
+const u8 gUnknown_83FC518[] = _("{B_ATK_NAME_WITH_PREFIX} waits for its foe\nto make a move!");
+const u8 gUnknown_83FC53D[] = _("{B_DEF_NAME_WITH_PREFIX} SNATCHED\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s move!");
+const u8 gUnknown_83FC554[] = _("Electricity's power was\nweakened!");
+const u8 gUnknown_83FC576[] = _("Fire's power was\nweakened!");
+const u8 gUnknown_83FC591[] = _("{B_ATK_NAME_WITH_PREFIX} found\none {B_LAST_ITEM}!");
+const u8 gUnknown_83FC5A2[] = _("A soothing aroma wafted\nthrough the area!");
+const u8 gUnknown_83FC5CC[] = _("Items can't be used now.{PAUSE 64}");
+const u8 gUnknown_83FC5E8[] = _("For {B_SCR_ACTIVE_NAME_WITH_PREFIX},\n{B_LAST_ITEM} {B_BUFF1}");
+const u8 gUnknown_83FC5F6[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used\n{B_LAST_ITEM} to hustle!");
+const u8 gUnknown_83FC60C[] = _("{B_ATK_NAME_WITH_PREFIX} lost its\nfocus and couldn't move!");
+const u8 gUnknown_83FC631[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndragged out!\p");
+const u8 gUnknown_83FC646[] = _("The wall shattered!");
+const u8 gUnknown_83FC65A[] = _("But it had no effect!");
+const u8 gUnknown_83FC670[] = _("{B_ACTIVE_NAME_WITH_PREFIX} has no\nmoves left!\p");
+const u8 gUnknown_83FC687[] = _("{B_ACTIVE_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE}\nis disabled!\p");
+const u8 gUnknown_83FC69D[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use the same\nmove in a row due to the TORMENT!\p");
+const u8 gUnknown_83FC6D6[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use\n{B_CURRENT_MOVE} after the TAUNT!\p");
+const u8 gUnknown_83FC6F8[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can't use the\nsealed {B_CURRENT_MOVE}!\p");
+const u8 gUnknown_83FC715[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nmade it rain!");
+const u8 gUnknown_83FC72B[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nraised its SPEED!");
+const u8 gUnknown_83FC745[] = _("{B_DEF_NAME_WITH_PREFIX} was protected\nby {B_DEF_ABILITY}!");
+const u8 gUnknown_83FC75D[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nprevents {B_ATK_NAME_WITH_PREFIX}\lfrom using {B_CURRENT_MOVE}!");
+const u8 gUnknown_83FC780[] = _("{B_DEF_NAME_WITH_PREFIX} restored HP\nusing its {B_DEF_ABILITY}!");
+const u8 gUnknown_83FC79D[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} useless!");
+const u8 gUnknown_83FC7B6[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nmade it the {B_BUFF1} type!");
+const u8 gUnknown_83FC7D3[] = _("{B_EFF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nprevents paralysis!");
+const u8 gUnknown_83FC7EF[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nprevents romance!");
+const u8 gUnknown_83FC809[] = _("{B_EFF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nprevents poisoning!");
+const u8 gUnknown_83FC825[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nprevents confusion!");
+const u8 gUnknown_83FC841[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nraised its FIRE power!");
+const u8 gUnknown_83FC860[] = _("{B_DEF_NAME_WITH_PREFIX} anchors\nitself with {B_DEF_ABILITY}!");
+const u8 gUnknown_83FC87B[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\ncuts {B_DEF_NAME_WITH_PREFIX}'s ATTACK!");
+const u8 gUnknown_83FC895[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nprevents stat loss!");
+const u8 gUnknown_83FC8B1[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nhurt {B_ATK_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FC8C2[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} TRACED\n{B_BUFF1}'s {B_BUFF2}!");
+const u8 gUnknown_83FC8D5[] = _("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY}\nprevents burns!");
+const u8 gUnknown_83FC8ED[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nblocks {B_CURRENT_MOVE}!");
+const u8 gUnknown_83FC900[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nblocks {B_CURRENT_MOVE}!");
+const u8 gUnknown_83FC913[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nrestored its HP a little!");
+const u8 gUnknown_83FC935[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nwhipped up a sandstorm!");
+const u8 gUnknown_83FC955[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nintensified the sun's rays!");
+const u8 gUnknown_83FC979[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nprevents {B_BUFF1} loss!");
+const u8 gUnknown_83FC993[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\ninfatuated {B_ATK_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FC9AA[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} ineffective!");
+const u8 gUnknown_83FC9C7[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!");
+const u8 gUnknown_83FC9E5[] = _("It sucked up the\nLIQUID OOZE!");
+const u8 gUnknown_83FCA03[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} transformed!");
+const u8 gUnknown_83FCA13[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\ntook the attack!");
+const u8 gText_PkmnsXPreventsSwitching[] = _("{B_BUFF1}'s {B_LAST_ABILITY}\nprevents switching!\p");
+const u8 gUnknown_83FCA49[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nprevented {B_SCR_ACTIVE_NAME_WITH_PREFIX}'s\l{B_BUFF1} from working!");
+const u8 gUnknown_83FCA71[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nmade it ineffective!");
+const u8 gUnknown_83FCA8E[] = _("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY}\nprevents flinching!");
+const u8 gUnknown_83FCAAA[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nprevents {B_DEF_NAME_WITH_PREFIX}'s\l{B_DEF_ABILITY} from working!");
+const u8 gUnknown_83FCAD1[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!");
+const u8 gUnknown_83FCAEF[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nhad no effect on {B_EFF_NAME_WITH_PREFIX}!");
+const u8 gUnknown_83FCB0C[] = _("{B_ATK_NAME_WITH_PREFIX} is too scared to move!");
+const u8 gUnknown_83FCB26[] = _("GHOST: Get out…… Get out……");
+const u8 gUnknown_83FCB41[] = _("sharply ");
+const u8 gBattleText_Rose[] = _("rose!");
+const u8 gUnknown_83FCB50[] = _("harshly ");
+const u8 gUnknown_83FCB59[] = _("fell!");
+const u8 gUnknown_83FCB5F[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1}\n{B_BUFF2}");
+const u8 gBattleText_UnknownString3[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}\n{B_BUFF2}");
+const u8 gUnknown_83FCB75[] = _("Using {B_LAST_ITEM}, the {B_BUFF1}\nof {B_SCR_ACTIVE_NAME_WITH_PREFIX} {B_BUFF2}");
+const u8 gUnknown_83FCB8F[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1}\n{B_BUFF2}");
+const u8 gUnknown_83FCB9A[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1}\n{B_BUFF2}");
+const u8 gUnknown_83FCBA5[] = _("{B_ATK_NAME_WITH_PREFIX}'s stats won't\ngo any higher!");
+const u8 gUnknown_83FCBC5[] = _("{B_DEF_NAME_WITH_PREFIX}'s stats won't\ngo any lower!");
+const u8 gUnknown_83FCBE4[] = _("A critical hit!");
+const u8 gUnknown_83FCBF4[] = _("It's a one-hit KO!");
+const u8 gUnknown_83FCC07[] = _("{PAUSE 32}1, {PAUSE 15}2, and{PAUSE 15}… {PAUSE 15}… {PAUSE 15}… {PAUSE 15}{PLAY_SE SE_KON}Poof!\p");
+const u8 gUnknown_83FCC33[] = _("And…\p");
+const u8 gUnknown_83FCC39[] = _("HM moves can't be\nforgotten now.\p");
+const u8 gUnknown_83FCC5B[] = _("It's not very effective…");
+const u8 gUnknown_83FCC74[] = _("It's super effective!");
+static const u8 sText_GotAwaySafely[] = _("{PLAY_SE SE_NIGERU}Got away safely!\p");
+const u8 gUnknown_83FCCA0[] = _("{PLAY_SE SE_NIGERU}{B_ATK_NAME_WITH_PREFIX} fled\nusing its {B_LAST_ITEM}!\p");
+const u8 gUnknown_83FCCBB[] = _("{PLAY_SE SE_NIGERU}{B_ATK_NAME_WITH_PREFIX} fled\nusing {B_ATK_ABILITY}!\p");
+const u8 gUnknown_83FCCD2[] = _("{PLAY_SE SE_NIGERU}Wild {B_BUFF1} fled!");
+static const u8 sText_PlayerDefeatedLinkTrainer[] = _("Player defeated\n{B_LINK_OPPONENT1_NAME}!");
+static const u8 sText_TwoLinkTrainersDefeated[] = _("Player beat {B_LINK_OPPONENT1_NAME}\nand {B_LINK_OPPONENT2_NAME}!");
+static const u8 sText_PlayerLostAgainstLinkTrainer[] = _("Player lost against\n{B_LINK_OPPONENT1_NAME}!");
+static const u8 sText_PlayerLostToTwo[] = _("Player lost to {B_LINK_OPPONENT1_NAME}\nand {B_LINK_OPPONENT2_NAME}!");
+static const u8 sText_PlayerBattledToDrawLinkTrainer[] = _("Player battled to a draw against\n{B_LINK_OPPONENT1_NAME}!");
+static const u8 sText_PlayerBattledToDrawVsTwo[] = _("Player battled to a draw against\n{B_LINK_OPPONENT1_NAME} and {B_LINK_OPPONENT2_NAME}!");
+const u8 gUnknown_83FCD92[] = _("{PLAY_SE SE_NIGERU}{B_LINK_OPPONENT1_NAME} fled!");
+static const u8 sText_TwoWildFled[] = _("{PLAY_SE SE_NIGERU}{B_LINK_OPPONENT1_NAME} and\n{B_LINK_OPPONENT2_NAME} fled!");
+const u8 gUnknown_83FCDB3[] = _("No! There's no running\nfrom a TRAINER battle!\p");
+const u8 gUnknown_83FCDE2[] = _("Can't escape!\p");
+const u8 gUnknown_83FCDF1[] = _("");
+const u8 gUnknown_83FCDF2[] = _("But nothing happened!");
+const u8 gUnknown_83FCE08[] = _("But it failed!");
+const u8 gUnknown_83FCE17[] = _("It hurt itself in its\nconfusion!");
+const u8 gUnknown_83FCE38[] = _("The MIRROR MOVE failed!");
+const u8 gUnknown_83FCE50[] = _("It started to rain!");
+const u8 gUnknown_83FCE64[] = _("A downpour started!");
+const u8 gUnknown_83FCE78[] = _("Rain continues to fall.");
+const u8 gUnknown_83FCE90[] = _("The downpour continues.");
+const u8 gUnknown_83FCEA8[] = _("The rain stopped.");
+const u8 gUnknown_83FCEBA[] = _("A sandstorm brewed!");
+const u8 gUnknown_83FCECE[] = _("The sandstorm rages.");
+const u8 gUnknown_83FCEE3[] = _("The sandstorm subsided.");
+const u8 gUnknown_83FCEFB[] = _("The sunlight got bright!");
+const u8 gUnknown_83FCF14[] = _("The sunlight is strong.");
+const u8 gUnknown_83FCF2C[] = _("The sunlight faded.");
+const u8 gUnknown_83FCF40[] = _("It started to hail!");
+const u8 gUnknown_83FCF54[] = _("Hail continues to fall.");
+const u8 gUnknown_83FCF6C[] = _("The hail stopped.");
+const u8 gUnknown_83FCF7E[] = _("But it failed to SPIT UP\na thing!");
+const u8 gUnknown_83FCFA0[] = _("But it failed to SWALLOW\na thing!");
+const u8 gUnknown_83FCFC2[] = _("The wind turned into a\nHEAT WAVE!");
+const u8 gUnknown_83FCFE4[] = _("All stat changes were\neliminated!");
+const u8 gUnknown_83FD006[] = _("Coins scattered everywhere!");
+const u8 gUnknown_83FD022[] = _("It was too weak to make\na SUBSTITUTE!");
+const u8 gUnknown_83FD048[] = _("The battlers shared\ntheir pain!");
+const u8 gUnknown_83FD068[] = _("A bell chimed!");
+const u8 gUnknown_83FD077[] = _("All affected POKéMON will\nfaint in three turns!");
+const u8 gUnknown_83FD0A7[] = _("There's no PP left for\nthis move!\p");
+const u8 gUnknown_83FD0CA[] = _("But there was no PP left\nfor the move!");
+const u8 gUnknown_83FD0F1[] = _("{B_ATK_NAME_WITH_PREFIX} ignored\norders while asleep!");
+const u8 gUnknown_83FD111[] = _("{B_ATK_NAME_WITH_PREFIX} ignored\norders!");
+const u8 gUnknown_83FD124[] = _("{B_ATK_NAME_WITH_PREFIX} began to nap!");
+const u8 gUnknown_83FD135[] = _("{B_ATK_NAME_WITH_PREFIX} is\nloafing around!");
+const u8 gUnknown_83FD14B[] = _("{B_ATK_NAME_WITH_PREFIX} won't\nobey!");
+const u8 gUnknown_83FD15A[] = _("{B_ATK_NAME_WITH_PREFIX} turned away!");
+const u8 gUnknown_83FD16A[] = _("{B_ATK_NAME_WITH_PREFIX} pretended\nnot to notice!");
+const u8 gUnknown_83FD186[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} is\nabout to use {B_BUFF2}.\pWill {B_PLAYER_NAME} change\nPOKéMON?");
+const u8 gUnknown_83FD1B8[] = _("{B_ATK_NAME_WITH_PREFIX} learned\n{B_BUFF1}!");
+static const u8 sText_PlayerDefeatedLinkTrainerTrainer1[] = _("Player defeated\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!\p");
+const u8 gUnknown_83FD1DF[] = _("{B_PLAYER_NAME} threw a ROCK\nat the {B_OPPONENT_MON1_NAME}!");
+const u8 gUnknown_83FD1FA[] = _("{B_PLAYER_NAME} threw some BAIT\nat the {B_OPPONENT_MON1_NAME}!");
+const u8 gUnknown_83FD218[] = _("{B_OPPONENT_MON1_NAME} is watching\ncarefully!");
+const u8 gUnknown_83FD232[] = _("{B_OPPONENT_MON1_NAME} is angry!");
+const u8 gUnknown_83FD23F[] = _("{B_OPPONENT_MON1_NAME} is eating!");
+const u8 gUnknown_83FD24D[] = _("{PLAY_SE SE_PINPON}ANNOUNCER: You're out of\nSAFARI BALLS! Game over!\p");
+static const u8 sText_WildPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
+static const u8 sText_WildPkmnAppeared2[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
+static const u8 sText_WildPkmnAppearedPause[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!{PAUSE 127}");
+static const u8 sText_TwoWildPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} and\n{B_OPPONENT_MON2_NAME} appeared!\p");
+const u8 gUnknown_83FD2D9[] = _("The GHOST appeared!\pDarn!\nThe GHOST can't be ID'd!\p");
+const u8 gUnknown_83FD30D[] = _("The GHOST appeared!\p");
+const u8 gUnknown_83FD322[] = _("SILPH SCOPE unveiled the GHOST's\nidentity!");
+const u8 gUnknown_83FD34D[] = _("The GHOST was MAROWAK!\p\n");
+static const u8 sText_Trainer1WantsToBattle[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nwould like to battle!\p");
+static const u8 sText_LinkTrainerWantsToBattle[] = _("{B_LINK_OPPONENT1_NAME}\nwants to battle!");
+static const u8 sText_TwoLinkTrainersWantToBattle[] = _("{B_LINK_OPPONENT1_NAME} and {B_LINK_OPPONENT2_NAME}\nwant to battle!");
+static const u8 sText_Trainer1SentOutPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME}!{PAUSE 60}");
+static const u8 sText_Trainer1SentOutTwoPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!{PAUSE 60}");
+static const u8 sText_Trainer1SentOutPkmn2[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_BUFF1}!");
+static const u8 sText_LinkTrainerSentOutPkmn[] = _("{B_LINK_OPPONENT1_NAME} sent out\n{B_OPPONENT_MON1_NAME}!");
+static const u8 sText_LinkTrainerSentOutTwoPkmn[] = _("{B_LINK_OPPONENT1_NAME} sent out\n{B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!");
+static const u8 sText_TwoLinkTrainersSentOutPkmn[] = _("{B_LINK_OPPONENT1_NAME} sent out {B_LINK_OPPONENT_MON1_NAME}!\n{B_LINK_OPPONENT2_NAME} sent out {B_LINK_OPPONENT_MON2_NAME}!");
+static const u8 sText_LinkTrainerSentOutPkmn2[] = _("{B_LINK_OPPONENT1_NAME} sent out\n{B_BUFF1}!");
+static const u8 sText_LinkTrainerMultiSentOutPkmn[] = _("{B_LINK_SCR_TRAINER_NAME} sent out\n{B_BUFF1}!");
+static const u8 sText_GoPkmn[] = _("Go! {B_PLAYER_MON1_NAME}!");
+static const u8 sText_GoTwoPkmn[] = _("Go! {B_PLAYER_MON1_NAME} and\n{B_PLAYER_MON2_NAME}!");
+static const u8 sText_GoPkmn2[] = _("Go! {B_BUFF1}!");
+static const u8 sText_DoItPkmn[] = _("Do it! {B_BUFF1}!");
+static const u8 sText_GoForItPkmn[] = _("Go for it, {B_BUFF1}!");
+static const u8 sText_YourFoesWeakGetEmPkmn[] = _("Your foe's weak!\nGet 'em, {B_BUFF1}!");
+static const u8 sText_LinkPartnerSentOutPkmnGoPkmn[] = _("{B_LINK_PARTNER_NAME} sent out {B_LINK_PLAYER_MON2_NAME}!\nGo! {B_LINK_PLAYER_MON1_NAME}!");
+static const u8 sText_PkmnThatsEnough[] = _("{B_BUFF1}, that's enough!\nCome back!");
+static const u8 sText_PkmnComeBack[] = _("{B_BUFF1}, come back!");
+static const u8 sText_PkmnOkComeBack[] = _("{B_BUFF1}, OK!\nCome back!");
+const u8 sText_PkmnGoodComeBack[] = _("{B_BUFF1}, good!\nCome back!");
+static const u8 sText_Trainer1WithdrewPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nwithdrew {B_BUFF1}!");
+static const u8 sText_LinkTrainer1WithdrewPkmn[] = _("{B_LINK_OPPONENT1_NAME} withdrew\n{B_BUFF1}!");
+static const u8 sText_LinkTrainer2WithdrewPkmn[] = _("{B_LINK_SCR_TRAINER_NAME} withdrew\n{B_BUFF1}!");
+static const u8 sText_WildPkmnPrefix[] = _("Wild ");
+static const u8 sText_FoePkmnPrefix[] = _("Foe ");
+static const u8 sText_FoePkmnPrefix2[] = _("Foe");
+static const u8 sText_AllyPkmnPrefix[] = _("Ally");
+static const u8 sText_FoePkmnPrefix3[] = _("Foe");
+static const u8 sText_AllyPkmnPrefix2[] = _("Ally");
+static const u8 sText_FoePkmnPrefix4[] = _("Foe");
+static const u8 sText_AllyPkmnPrefix3[] = _("Ally");
+static const u8 sText_AttackerUsedX[] = _("{B_ATK_NAME_WITH_PREFIX} used\n{B_BUFF2}");
+static const u8 sText_ExclamationMark[] = _("!");
+static const u8 sText_ExclamationMark2[] = _("!");
+static const u8 sText_ExclamationMark3[] = _("!");
+static const u8 sText_ExclamationMark4[] = _("!");
+static const u8 sText_ExclamationMark5[] = _("!");
+
+static const u8 sText_HP2[] = _("HP");
+static const u8 sText_Attack2[] = _("ATTACK");
+static const u8 sText_Defense2[] = _("DEFENSE");
+static const u8 sText_Speed[] = _("SPEED");
+static const u8 sText_SpAtk2[] = _("SP. ATK");
+static const u8 sText_SpDef2[] = _("SP. DEF");
+static const u8 sText_Accuracy[] = _("accuracy");
+static const u8 sText_Evasiveness[] = _("evasiveness");
+
+const u8 *const gStatNamesTable[] = {
+ sText_HP2,
+ sText_Attack2,
+ sText_Defense2,
+ sText_Speed,
+ sText_SpAtk2,
+ sText_SpDef2,
+ sText_Accuracy,
+ sText_Evasiveness
+};
+
+static const u8 sText_PokeblockWasTooSpicy[] = _("was too spicy!"); //
+static const u8 sText_PokeblockWasTooDry[] = _("was too dry!");
+static const u8 sText_PokeblockWasTooSweet[] = _("was too sweet!");
+static const u8 sText_PokeblockWasTooBitter[] = _("was too bitter!");
+static const u8 sText_PokeblockWasTooSour[] = _("was too sour!");
+
+const u8 *const gPokeblockWasTooXStringTable[] = {
+ sText_PokeblockWasTooSpicy,
+ sText_PokeblockWasTooDry,
+ sText_PokeblockWasTooSweet,
+ sText_PokeblockWasTooBitter,
+ sText_PokeblockWasTooSour
+};
+
+static const u8 sText_PlayerUsedItem[] = _("{B_PLAYER_NAME} used\n{B_LAST_ITEM}!");
+static const u8 sText_OldManUsedItem[] = _("The old man used\n{B_LAST_ITEM}!");
+static const u8 sText_PokeDudeUsedItem[] = _("The POKé DUDE used\n{B_LAST_ITEM}!");
+static const u8 sText_Trainer1UsedItem[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nused {B_LAST_ITEM}!");
+static const u8 sText_TrainerBlockedBall[] = _("The TRAINER blocked the BALL!");
+static const u8 sText_DontBeAThief[] = _("Don't be a thief!");
+static const u8 sText_ItDodgedBall[] = _("It dodged the thrown BALL!\nThis POKéMON can't be caught!");
+static const u8 sText_YouMissedPkmn[] = _("You missed the POKéMON!");
+static const u8 sText_PkmnBrokeFree[] = _("Oh, no!\nThe POKéMON broke free!");
+static const u8 sText_ItAppearedCaught[] = _("Aww!\nIt appeared to be caught!");
+static const u8 sText_AarghAlmostHadIt[] = _("Aargh!\nAlmost had it!");
+static const u8 sText_ShootSoClose[] = _("Shoot!\nIt was so close, too!");
+const u8 gUnknown_83FD78A[] = _("よけられた!\nこいつは つかまりそうにないぞ!");
+static const u8 sText_GotchaPkmnCaught[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{WAIT_SE}{PLAY_BGM MUS_GET_YASEI}\p");
+static const u8 sText_GotchaPkmnCaught2[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{WAIT_SE}{PLAY_BGM MUS_GET_YASEI}{PAUSE 127}");
+static const u8 sText_GiveNicknameCaptured[] = _("Give a nickname to the\ncaptured {B_OPPONENT_MON1_NAME}?");
+static const u8 sText_PkmnSentToPC[] = _("{B_OPPONENT_MON1_NAME} was sent to\n{B_PC_CREATOR_NAME} PC.");
+static const u8 sText_Someones[] = _("someone's");
+static const u8 sText_Bills[] = _("BILL's");
+const u8 gUnknown_83FD82B[] = _("{B_OPPONENT_MON1_NAME}'s data was\nadded to the POKéDEX.\p");
+const u8 gUnknown_83FD850[] = _("It is raining.");
+const u8 gUnknown_83FD85F[] = _("A sandstorm is raging.");
+const u8 gUnknown_83FD876[] = _("The BOX is full!\nYou can't catch any more!\p");
+static const u8 sText_EnigmaBerry[] = _("ENIGMA BERRY");
+static const u8 sText_BerrySuffix[] = _(" BERRY");
+const u8 gUnknown_83FD8B6[] = _("ナゾ");
+const u8 gUnknown_83FD8B9[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ncured paralysis!");
+const u8 gUnknown_83FD8D2[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ncured poison!");
+const u8 gUnknown_83FD8E8[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nhealed its burn!");
+const u8 gUnknown_83FD901[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ndefrosted it!");
+const u8 gUnknown_83FD917[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nwoke it from its sleep!");
+const u8 gUnknown_83FD937[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nsnapped it out of confusion!");
+const u8 gUnknown_83FD95C[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\ncured its {B_BUFF1} problem!");
+const u8 gUnknown_83FD97A[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nnormalized its status!");
+const u8 gUnknown_83FD999[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nrestored health!");
+const u8 gUnknown_83FD9B2[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nrestored {B_BUFF1}'s PP!");
+const u8 gUnknown_83FD9CC[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nrestored its status!");
+const u8 gUnknown_83FD9E9[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM}\nrestored its HP a little!");
+const u8 gUnknown_83FDA0B[] = _("{B_LAST_ITEM}'s effect allows only\n{B_CURRENT_MOVE} to be used!\p");
+const u8 gUnknown_83FDA33[] = _("{B_DEF_NAME_WITH_PREFIX} hung on\nusing its {B_LAST_ITEM}!");
+const u8 gUnknown_83FDA4C[] = _("");
+const u8 gUnknown_83FDA4D[] = _("{B_PLAYER_NAME} played the {B_LAST_ITEM}.\pNow, that's a catchy tune!");
+const u8 gUnknown_83FDA7A[] = _("{B_PLAYER_NAME} played the\n{B_LAST_ITEM}.");
+const u8 gUnknown_83FDA8C[] = _("The POKéMON hearing the FLUTE\nawoke!");
+const u8 gUnknown_83FDAB1[] = _("You throw a BALL now, right?\nI… I'll do my best!");
+const u8 gUnknown_83FDAE2[] = _("OAK: Oh, for Pete's sake…\nSo pushy, as always.\p{B_PLAYER_NAME}.\pYou've never had a POKéMON battle\nbefore, have you?\pA POKéMON battle is when TRAINERS\npit their POKéMON against each\lother.\p");
+const u8 gUnknown_83FDB92[] = _("The TRAINER that makes the other\nTRAINER's POKéMON faint by lowering\ltheir HP to “0,” wins.\p");
+const u8 gUnknown_83FDBEF[] = _("But rather than talking about it,\nyou'll learn more from experience.\pTry battling and see for yourself.\p");
+const u8 gUnknown_83FDC58[] = _("OAK: Inflicting damage on the foe\nis the key to any battle.\p");
+const u8 gUnknown_83FDC95[] = _("OAK: Lowering the foe's stats\nwill put you at an advantage.\p");
+const u8 gUnknown_83FDCD2[] = _("OAK: Keep your eyes on your\nPOKéMON's HP.\pIt will faint if the HP drops to\n“0.”\p");
+const u8 gUnknown_83FDD23[] = _("OAK: No! There's no running away\nfrom a TRAINER POKéMON battle!\p");
+const u8 gUnknown_83FDD64[] = _("OAK: Hm! Excellent!\pIf you win, you earn prize money,\nand your POKéMON will grow!\pBattle other TRAINERS and make\nyour POKéMON strong!\p");
+const u8 gUnknown_83FDDEB[] = _("OAK: Hm…\nHow disappointing…\pIf you win, you earn prize money,\nand your POKéMON grow.\pBut if you lose, {B_PLAYER_NAME}, you end\nup paying prize money…\pHowever, since you had no warning\nthis time, I'll pay for you.\pBut things won't be this way once\nyou step outside these doors.\pThat's why you must strengthen your\nPOKéMON by battling wild POKéMON.\p");
+
+const u8 *const gBattleStringsTable[] = {
+ gUnknown_83FB219,
+ gUnknown_83FB265,
+ gUnknown_83FB28E,
+ gUnknown_83FB2A4,
+ gUnknown_83FB2B6,
+ gUnknown_83FB2D1,
+ gUnknown_83FB2FC,
+ gUnknown_83FB31F,
+ gUnknown_83FB32E,
+ gUnknown_83FB343,
+ gUnknown_83FD1B8,
+ gUnknown_83FB36B,
+ gUnknown_83FB37F,
+ gUnknown_83FCBA5,
+ gUnknown_83FB394,
+ gUnknown_83FB3EA,
+ gUnknown_83FB400,
+ gUnknown_83FB40D,
+ gUnknown_83FB41A,
+ gUnknown_83FB433,
+ gUnknown_83FB451,
+ gUnknown_83FB508,
+ gUnknown_83FB545,
+ gUnknown_83FB555,
+ gUnknown_83FB565,
+ gUnknown_83FB57C,
+ gUnknown_83FB592,
+ gUnknown_83FB5A8,
+ gUnknown_83FB5BC,
+ gUnknown_83FB5CD,
+ gUnknown_83FB5E2,
+ gUnknown_83FB5F8,
+ gUnknown_83FB610,
+ gUnknown_83FB626,
+ gUnknown_83FB641,
+ gUnknown_83FB650,
+ gUnknown_83FB663,
+ gUnknown_83FB692,
+ gUnknown_83FB6A7,
+ gUnknown_83FB6BF,
+ gUnknown_83FB6D3,
+ gUnknown_83FB6E5,
+ gUnknown_83FB6F7,
+ gUnknown_83FB70F,
+ gUnknown_83FB73A,
+ gUnknown_83FB76A,
+ gUnknown_83FB78A,
+ gUnknown_83FB7A3,
+ gUnknown_83FB7BF,
+ gUnknown_83FB7D5,
+ gUnknown_83FB7EE,
+ gUnknown_83FB806,
+ gUnknown_83FB826,
+ gUnknown_83FB844,
+ gUnknown_83FB854,
+ gUnknown_83FB871,
+ gUnknown_83FB885,
+ gUnknown_83FB89D,
+ gUnknown_83FB8AE,
+ gUnknown_83FB8C5,
+ gUnknown_83FB8E0,
+ gUnknown_83FB8F3,
+ gUnknown_83FB914,
+ gUnknown_83FB921,
+ gUnknown_83FB935,
+ gUnknown_83FB946,
+ gUnknown_83FB97F,
+ gUnknown_83FB9B8,
+ gUnknown_83FB9D9,
+ gUnknown_83FB9FF,
+ gUnknown_83FBA2F,
+ gUnknown_83FBA41,
+ gUnknown_83FBA5E,
+ gUnknown_83FBA79,
+ gUnknown_83FBA8E,
+ gUnknown_83FBAA3,
+ gUnknown_83FBAB2,
+ gUnknown_83FBAC3,
+ gUnknown_83FBAF3,
+ gUnknown_83FBB11,
+ gUnknown_83FBB4C,
+ gUnknown_83FBB62,
+ gUnknown_83FBB71,
+ gUnknown_83FBB83,
+ gUnknown_83FBB99,
+ gBattleText_MistShroud,
+ gUnknown_83FBBD0,
+ gBattleText_GetPumped,
+ gUnknown_83FBBFF,
+ gUnknown_83FBC16,
+ gUnknown_83FBC2B,
+ gUnknown_83FBC4C,
+ gUnknown_83FBC74,
+ gUnknown_83FBC83,
+ gUnknown_83FBC99,
+ gUnknown_83FBCBE,
+ gUnknown_83FBCD1,
+ gUnknown_83FBCDD,
+ gUnknown_83FBCFC,
+ gUnknown_83FBD16,
+ gUnknown_83FBD2B,
+ gUnknown_83FBD43,
+ gUnknown_83FBD53,
+ gUnknown_83FBD74,
+ gUnknown_83FBD86,
+ gUnknown_83FBDA3,
+ gUnknown_83FBDC4,
+ gUnknown_83FBDE2,
+ gUnknown_83FBE00,
+ gUnknown_83FBE16,
+ gUnknown_83FBE2B,
+ gUnknown_83FBE4E,
+ gUnknown_83FBE61,
+ gUnknown_83FBE73,
+ gUnknown_83FBE8B,
+ gUnknown_83FBEA1,
+ gUnknown_83FBEBE,
+ gUnknown_83FBEE2,
+ gUnknown_83FBEFA,
+ gUnknown_83FBF0C,
+ gUnknown_83FBF23,
+ gUnknown_83FC687,
+ gUnknown_83FBF39,
+ gUnknown_83FBF51,
+ gUnknown_83FBF63,
+ gUnknown_83FBF76,
+ gUnknown_83FBF89,
+ gUnknown_83FBF99,
+ gUnknown_83FBFBF,
+ gUnknown_83FBFD3,
+ gUnknown_83FBFEA,
+ gUnknown_83FBFFC,
+ gUnknown_83FC011,
+ gUnknown_83FC02B,
+ gUnknown_83FC048,
+ gUnknown_83FC072,
+ gUnknown_83FC090,
+ gUnknown_83FC0C6,
+ gUnknown_83FC0DC,
+ gUnknown_83FC0EE,
+ gUnknown_83FC10C,
+ gUnknown_83FC11E,
+ gUnknown_83FC132,
+ gUnknown_83FC140,
+ gUnknown_83FC168,
+ gUnknown_83FC185,
+ gUnknown_83FC19D,
+ gUnknown_83FC1B1,
+ gUnknown_83FC1C6,
+ gUnknown_83FC1DB,
+ gUnknown_83FC1F1,
+ gUnknown_83FC224,
+ gUnknown_83FC231,
+ gUnknown_83FC254,
+ gUnknown_83FC26D,
+ gUnknown_83FC28A,
+ gUnknown_83FC670,
+ gUnknown_83FC2AA,
+ gUnknown_83FC69D,
+ gUnknown_83FC2C7,
+ gUnknown_83FC2E3,
+ gUnknown_83FC6D6,
+ gUnknown_83FC2FA,
+ gUnknown_83FC312,
+ gUnknown_83FC377,
+ gUnknown_83FC38A,
+ gUnknown_83FC39A,
+ gUnknown_83FC3AF,
+ gUnknown_83FC3C5,
+ gUnknown_83FC3EB,
+ gUnknown_83FC40E,
+ gUnknown_83FC421,
+ gUnknown_83FC439,
+ gUnknown_83FC461,
+ gUnknown_83FC6F8,
+ gUnknown_83FC483,
+ gUnknown_83FC4AB,
+ gUnknown_83FC4D6,
+ gUnknown_83FC4F0,
+ gUnknown_83FC518,
+ gUnknown_83FC53D,
+ gUnknown_83FC715,
+ gUnknown_83FC72B,
+ gUnknown_83FC745,
+ gUnknown_83FC75D,
+ gUnknown_83FC780,
+ gUnknown_83FC7B6,
+ gUnknown_83FC7D3,
+ gUnknown_83FC7EF,
+ gUnknown_83FC809,
+ gUnknown_83FC825,
+ gUnknown_83FC841,
+ gUnknown_83FC860,
+ gUnknown_83FC87B,
+ gUnknown_83FC895,
+ gUnknown_83FC8B1,
+ gUnknown_83FC8C2,
+ gUnknown_83FCB41,
+ gBattleText_Rose,
+ gUnknown_83FCB50,
+ gUnknown_83FCB59,
+ gUnknown_83FCB5F,
+ gBattleText_UnknownString3,
+ gUnknown_83FCB8F,
+ gUnknown_83FCB9A,
+ gUnknown_83FCBE4,
+ gUnknown_83FCBF4,
+ gUnknown_83FCC07,
+ gUnknown_83FCC33,
+ gUnknown_83FCC5B,
+ gUnknown_83FCC74,
+ sText_GotAwaySafely,
+ gUnknown_83FCCD2,
+ gUnknown_83FCDB3,
+ gUnknown_83FCDE2,
+ gUnknown_83FCDF1,
+ gUnknown_83FCDF2,
+ gUnknown_83FCE08,
+ gUnknown_83FCE17,
+ gUnknown_83FCE38,
+ gUnknown_83FCE50,
+ gUnknown_83FCE64,
+ gUnknown_83FCE78,
+ gUnknown_83FCE90,
+ gUnknown_83FCEA8,
+ gUnknown_83FCEBA,
+ gUnknown_83FCECE,
+ gUnknown_83FCEE3,
+ gUnknown_83FCEFB,
+ gUnknown_83FCF14,
+ gUnknown_83FCF2C,
+ gUnknown_83FCF40,
+ gUnknown_83FCF54,
+ gUnknown_83FCF6C,
+ gUnknown_83FCF7E,
+ gUnknown_83FCFA0,
+ gUnknown_83FCFC2,
+ gUnknown_83FCFE4,
+ gUnknown_83FD006,
+ gUnknown_83FD022,
+ gUnknown_83FD048,
+ gUnknown_83FD068,
+ gUnknown_83FD077,
+ gUnknown_83FD0A7,
+ gUnknown_83FD0CA,
+ sText_PlayerUsedItem,
+ sText_OldManUsedItem,
+ sText_TrainerBlockedBall,
+ sText_DontBeAThief,
+ sText_ItDodgedBall,
+ sText_YouMissedPkmn,
+ sText_PkmnBrokeFree,
+ sText_ItAppearedCaught,
+ sText_AarghAlmostHadIt,
+ sText_ShootSoClose,
+ sText_GotchaPkmnCaught,
+ sText_GotchaPkmnCaught2,
+ sText_GiveNicknameCaptured,
+ sText_PkmnSentToPC,
+ gUnknown_83FD82B,
+ gUnknown_83FD850,
+ gUnknown_83FD85F,
+ gUnknown_83FB525,
+ gUnknown_83FD0F1,
+ gUnknown_83FD111,
+ gUnknown_83FD124,
+ gUnknown_83FD135,
+ gUnknown_83FD14B,
+ gUnknown_83FD15A,
+ gUnknown_83FD16A,
+ gUnknown_83FD186,
+ gUnknown_83FD1DF,
+ gUnknown_83FD1FA,
+ gUnknown_83FD218,
+ gUnknown_83FD232,
+ gUnknown_83FD23F,
+ gUnknown_83FB218,
+ gUnknown_83FB218,
+ gUnknown_83FD24D,
+ gUnknown_83FD8B9,
+ gUnknown_83FD8D2,
+ gUnknown_83FD8E8,
+ gUnknown_83FD901,
+ gUnknown_83FD917,
+ gUnknown_83FD937,
+ gUnknown_83FD95C,
+ gUnknown_83FD999,
+ gUnknown_83FD9B2,
+ gUnknown_83FD9CC,
+ gUnknown_83FD9E9,
+ gUnknown_83FDA0B,
+ gUnknown_83FDA33,
+ gUnknown_83FDA4C,
+ gUnknown_83FC8D5,
+ gUnknown_83FC8ED,
+ gUnknown_83FC913,
+ gUnknown_83FC935,
+ gUnknown_83FC979,
+ gUnknown_83FC993,
+ gUnknown_83FC9AA,
+ gUnknown_83FC9C7,
+ gUnknown_83FC9E5,
+ gUnknown_83FCA03,
+ gUnknown_83FC554,
+ gUnknown_83FC576,
+ gUnknown_83FBAD2,
+ gUnknown_83FBAE5,
+ gUnknown_83FCC39,
+ gUnknown_83FC591,
+ sText_PlayerDefeatedLinkTrainerTrainer1,
+ gUnknown_83FC5A2,
+ gUnknown_83FC5CC,
+ gUnknown_83FC5E8,
+ gUnknown_83FCB75,
+ gUnknown_83FC5F6,
+ gUnknown_83FC79D,
+ gUnknown_83FBB2F,
+ gUnknown_83FB282,
+ gUnknown_83FB283,
+ gUnknown_83FC955,
+ gUnknown_83FB3AF,
+ gUnknown_83FDAB1,
+ gUnknown_83FCA13,
+ gUnknown_83FC208,
+ gUnknown_83FC60C,
+ gUnknown_83FB359,
+ gUnknown_83FCCA0,
+ gUnknown_83FCCBB,
+ gUnknown_83FC631,
+ gUnknown_83FCA49,
+ gUnknown_83FD97A,
+ sText_Trainer1UsedItem,
+ gUnknown_83FD876,
+ gUnknown_83FB3D3,
+ gUnknown_83FCA71,
+ gUnknown_83FCA8E,
+ gUnknown_83FB67B,
+ gUnknown_83FCBC5,
+ gUnknown_83FC900,
+ gUnknown_83FBC62,
+ gUnknown_83FB997,
+ gUnknown_83FB95E,
+ gUnknown_83FC646,
+ gUnknown_83FCAAA,
+ gUnknown_83FCAD1,
+ gUnknown_83FB534,
+ gUnknown_83FC337,
+ gUnknown_83FC347,
+ gUnknown_83FC357,
+ gUnknown_83FC65A,
+ gUnknown_83FCAEF,
+ gUnknown_83FDD64,
+ gUnknown_83FDDEB,
+ gUnknown_83FB484,
+ gUnknown_83FB4BE,
+ Text_1A5CF1,
+ Text_1A5D31,
+ Text_1A5D6E,
+ Text_1A5DB1,
+ sText_PokeDudeUsedItem,
+ gUnknown_83FDA4D,
+ gUnknown_83FDA7A,
+ gUnknown_83FDA8C,
+ gUnknown_83FB21C,
+ gUnknown_83FB262,
+ gUnknown_83FB4F7,
+ gUnknown_83FCB0C,
+ gUnknown_83FCB26,
+ gUnknown_83FD322,
+ gUnknown_83FD34D,
+ gUnknown_83FB21F,
+ gUnknown_83FB232,
+ gUnknown_83FB235,
+ gUnknown_83FB248
+};
+
+const u16 gMissStringIds[] = {
+ STRINGID_ATTACKMISSED,
+ STRINGID_PKMNPROTECTEDITSELF,
+ STRINGID_PKMNAVOIDEDATTACK,
+ STRINGID_AVOIDEDDAMAGE,
+ STRINGID_PKMNMAKESGROUNDMISS
+};
+
+const u16 gNoEscapeStringIds[] = {
+ STRINGID_CANTESCAPE,
+ STRINGID_DONTLEAVEBIRCH,
+ STRINGID_PREVENTSESCAPE,
+ STRINGID_CANTESCAPE2,
+ STRINGID_ATTACKERCANTESCAPE
+};
+
+const u16 gMoveWeatherChangeStringIds[] = {
+ STRINGID_STARTEDTORAIN,
+ STRINGID_DOWNPOURSTARTED,
+ STRINGID_BUTITFAILED,
+ STRINGID_SANDSTORMBREWED,
+ STRINGID_SUNLIGHTGOTBRIGHT,
+ STRINGID_STARTEDHAIL
+};
+
+const u16 gSandstormHailContinuesStringIds[] = {
+ STRINGID_SANDSTORMRAGES,
+ STRINGID_HAILCONTINUES
+};
+
+const u16 gSandstormHailDmgStringIds[] = {
+ STRINGID_PKMNBUFFETEDBYSANDSTORM,
+ STRINGID_PKMNPELTEDBYHAIL
+};
+
+const u16 gSandstormHailEndStringIds[] = {
+ STRINGID_SANDSTORMSUBSIDED,
+ STRINGID_HAILSTOPPED
+};
+
+const u16 gRainContinuesStringIds[] = {
+ STRINGID_RAINCONTINUES,
+ STRINGID_DOWNPOURCONTINUES,
+ STRINGID_RAINSTOPPED
+};
+
+const u16 gProtectLikeUsedStringIds[] = {
+ STRINGID_PKMNPROTECTEDITSELF2,
+ STRINGID_PKMNBRACEDITSELF,
+ STRINGID_BUTITFAILED
+};
+
+const u16 gReflectLightScreenSafeguardStringIds[] = {
+ STRINGID_BUTITFAILED,
+ STRINGID_PKMNRAISEDDEF,
+ STRINGID_PKMNRAISEDDEFALITTLE,
+ STRINGID_PKMNRAISEDSPDEF,
+ STRINGID_PKMNRAISEDSPDEFALITTLE,
+ STRINGID_PKMNCOVEREDBYVEIL
+};
+
+const u16 gLeechSeedStringIds[] = {
+ STRINGID_PKMNSEEDED,
+ STRINGID_PKMNEVADEDATTACK,
+ STRINGID_ITDOESNTAFFECT,
+ STRINGID_PKMNSAPPEDBYLEECHSEED,
+ STRINGID_ITSUCKEDLIQUIDOOZE
+};
+
+const u16 gRestUsedStringIds[] = {
+ STRINGID_PKMNWENTTOSLEEP,
+ STRINGID_PKMNSLEPTHEALTHY
+};
+
+const u16 gUproarOverTurnStringIds[] = {
+ STRINGID_PKMNMAKINGUPROAR,
+ STRINGID_PKMNCALMEDDOWN
+};
+
+const u16 gStockpileUsedStringIds[] = {
+ STRINGID_PKMNSTOCKPILED,
+ STRINGID_PKMNCANTSTOCKPILE
+};
+
+const u16 gWokeUpStringIds[] = {
+ STRINGID_PKMNWOKEUP,
+ STRINGID_PKMNWOKEUPINUPROAR
+};
+
+const u16 gSwallowFailStringIds[] = {
+ STRINGID_FAILEDTOSWALLOW,
+ STRINGID_PKMNHPFULL
+};
+
+const u16 gUproarAwakeStringIds[] = {
+ STRINGID_PKMNCANTSLEEPINUPROAR2,
+ STRINGID_UPROARKEPTPKMNAWAKE,
+ STRINGID_PKMNSTAYEDAWAKEUSING
+};
+
+const u16 gStatUpStringIds[] = {
+ STRINGID_PKMNSSTATCHANGED,
+ STRINGID_PKMNSSTATCHANGED2,
+ STRINGID_STATSWONTINCREASE,
+ STRINGID_EMPTYSTRING3,
+ STRINGID_USINGXTHEYOFZN,
+ STRINGID_PKMNUSEDXTOGETPUMPED
+};
+
+const u16 gStatDownStringIds[] = {
+ STRINGID_PKMNSSTATCHANGED3,
+ STRINGID_PKMNSSTATCHANGED4,
+ STRINGID_STATSWONTDECREASE,
+ STRINGID_EMPTYSTRING3
+};
+
+const u16 gFirstTurnOfTwoStringIds[] = {
+ STRINGID_PKMNWHIPPEDWHIRLWIND,
+ STRINGID_PKMNTOOKSUNLIGHT,
+ STRINGID_PKMNLOWEREDHEAD,
+ STRINGID_PKMNISGLOWING,
+ STRINGID_PKMNFLEWHIGH,
+ STRINGID_PKMNDUGHOLE,
+ STRINGID_PKMNHIDUNDERWATER,
+ STRINGID_PKMNSPRANGUP
+};
+
+const u16 gWrappedStringIds[] = {
+ STRINGID_PKMNSQUEEZEDBYBIND,
+ STRINGID_PKMNWRAPPEDBY,
+ STRINGID_PKMNTRAPPEDINVORTEX,
+ STRINGID_PKMNCLAMPED,
+ STRINGID_PKMNTRAPPEDINVORTEX,
+ STRINGID_PKMNTRAPPEDBYSANDTOMB
+};
+
+const u16 gMistUsedStringIds[] = {
+ STRINGID_PKMNSHROUDEDINMIST,
+ STRINGID_BUTITFAILED
+};
+
+const u16 gFocusEnergyUsedStringIds[] = {
+ STRINGID_PKMNGETTINGPUMPED,
+ STRINGID_BUTITFAILED
+};
+
+const u16 gTransformUsedStringIds[] = {
+ STRINGID_PKMNTRANSFORMEDINTO,
+ STRINGID_BUTITFAILED
+};
+
+const u16 gSubsituteUsedStringIds[] = {
+ STRINGID_PKMNMADESUBSTITUTE,
+ STRINGID_TOOWEAKFORSUBSTITUTE
+};
+
+const u16 gGotPoisonedStringIds[] = {
+ STRINGID_PKMNWASPOISONED,
+ STRINGID_PKMNPOISONEDBY
+};
+
+const u16 gGotParalyzedStringIds[] = {
+ STRINGID_PKMNWASPARALYZED,
+ STRINGID_PKMNWASPARALYZEDBY
+};
+
+const u16 gFellAsleepStringIds[] = {
+ STRINGID_PKMNFELLASLEEP,
+ STRINGID_PKMNMADESLEEP
+};
+
+const u16 gGotBurnedStringIds[] = {
+ STRINGID_PKMNWASBURNED,
+ STRINGID_PKMNBURNEDBY
+};
+
+const u16 gGotFrozenStringIds[] = {
+ STRINGID_PKMNWASFROZEN,
+ STRINGID_PKMNFROZENBY
+};
+
+const u16 gGotDefrostedStringIds[] = {
+ STRINGID_PKMNWASDEFROSTED2,
+ STRINGID_PKMNWASDEFROSTEDBY
+};
+
+const u16 gKOFailedStringIds[] = {
+ STRINGID_ATTACKMISSED,
+ STRINGID_PKMNUNAFFECTED
+};
+
+const u16 gAttractUsedStringIds[] = {
+ STRINGID_PKMNFELLINLOVE,
+ STRINGID_PKMNSXINFATUATEDY
+};
+
+const u16 gLeechSeedDrainStringIds[] = {
+ STRINGID_PKMNENERGYDRAINED,
+ STRINGID_ITSUCKEDLIQUIDOOZE
+};
+
+const u16 gSportsUsedStringIds[] = {
+ STRINGID_ELECTRICITYWEAKENED,
+ STRINGID_FIREWEAKENED
+};
+
+const u16 gPartyStatusHealStringIds[] = {
+ STRINGID_BELLCHIMED,
+ STRINGID_BELLCHIMED,
+ STRINGID_BELLCHIMED,
+ STRINGID_BELLCHIMED,
+ STRINGID_SOOTHINGAROMA
+};
+
+const u16 gFutureMoveUsedStringIds[] = {
+ STRINGID_PKMNFORESAWATTACK,
+ STRINGID_PKMNCHOSEXASDESTINY
+};
+
+const u16 gBallEscapeStringIds[] = {
+ STRINGID_PKMNBROKEFREE,
+ STRINGID_ITAPPEAREDCAUGHT,
+ STRINGID_AARGHALMOSTHADIT,
+ STRINGID_SHOOTSOCLOSE
+};
+
+const u16 gWeatherContinuesStringIds[] = {
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_SANDSTORMISRAGING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_SUNLIGHTSTRONG,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING,
+ STRINGID_ITISRAINING
+};
+
+const u16 gInobedientStringIds[] = {
+ STRINGID_PKMNLOAFING,
+ STRINGID_PKMNWONTOBEY,
+ STRINGID_PKMNTURNEDAWAY,
+ STRINGID_PKMNPRETENDNOTNOTICE
+};
+
+const u16 gSafariPokeblockResultStringIds[] = {
+ STRINGID_PKMNWATCHINGCAREFULLY,
+ STRINGID_PKMNANGRY,
+ STRINGID_PKMNEATING
+};
+
+const u16 gTrainerItemCuredStatusStringIds[] = {
+ STRINGID_PKMNSITEMSNAPPEDOUT,
+ STRINGID_PKMNSITEMCUREDPARALYSIS,
+ STRINGID_PKMNSITEMDEFROSTEDIT,
+ STRINGID_PKMNSITEMHEALEDBURN,
+ STRINGID_PKMNSITEMCUREDPOISON,
+ STRINGID_PKMNSITEMWOKEIT
+};
+
+const u16 gBerryEffectStringIds[] = {
+ STRINGID_PKMNSITEMCUREDPROBLEM,
+ STRINGID_PKMNSITEMNORMALIZEDSTATUS
+};
+
+const u16 gBRNPreventionStringIds[] = {
+ STRINGID_PKMNSXPREVENTSBURNS,
+ STRINGID_PKMNSXPREVENTSYSZ,
+ STRINGID_PKMNSXHADNOEFFECTONY
+};
+
+const u16 gPRLZPreventionStringIds[] = {
+ STRINGID_PKMNPREVENTSPARALYSISWITH,
+ STRINGID_PKMNSXPREVENTSYSZ,
+ STRINGID_PKMNSXHADNOEFFECTONY
+};
+
+const u16 gPSNPreventionStringIds[] = {
+ STRINGID_PKMNPREVENTSPOISONINGWITH,
+ STRINGID_PKMNSXPREVENTSYSZ,
+ STRINGID_PKMNSXHADNOEFFECTONY
+};
+
+const u16 gItemSwapStringIds[] = {
+ STRINGID_PKMNOBTAINEDX,
+ STRINGID_PKMNOBTAINEDX2,
+ STRINGID_PKMNOBTAINEDXYOBTAINEDZ
+};
+
+const u16 gFlashFireStringIds[] = {
+ STRINGID_PKMNRAISEDFIREPOWERWITH,
+ STRINGID_PKMNSXMADEYINEFFECTIVE
+};
+
+const u16 gCaughtMonStringIds[] = {
+ STRINGID_PKMNTRANSFERREDSOMEONESPC,
+ STRINGID_PKMNTRANSFERREDBILLSPC,
+ STRINGID_PKMNBOXSOMEONESPCFULL,
+ STRINGID_PKMNBOXBILLSPCFULL
+};
+
+const u16 gDoubleBattleRecallStrings[] = {
+ STRINGID_TRAINER1MON1COMEBACK,
+ STRINGID_TRAINER1MON1COMEBACK,
+ STRINGID_TRAINER1MON2COMEBACK,
+ STRINGID_TRAINER1MON1AND2COMEBACK
+};
+
+const u16 gTrappingMoves[] = {
+ MOVE_BIND,
+ MOVE_WRAP,
+ MOVE_FIRE_SPIN,
+ MOVE_CLAMP,
+ MOVE_WHIRLPOOL,
+ MOVE_SAND_TOMB,
+ 0xFFFF
+};
+
+const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!");
+const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p");
+const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p");
+const u8 gText_EllipsisQuestionMark[] = _("……?\p");
+const u8 gText_WhatWillPkmnDo[] = _("What will\n{B_ACTIVE_NAME_WITH_PREFIX} do?");
+const u8 gUnknown_83FE6E6[] = _("What will {B_PLAYER_NAME}\nthrow?");
+const u8 gUnknown_83FE6FA[] = _("What will the\nold man do?");
+const u8 gText_LinkStandby[] = _("{PAUSE 16}Link standby…");
+const u8 gUnknown_83FE725[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}FIGHT{CLEAR_TO 56}BAG\nPOKéMON{CLEAR_TO 56}RUN");
+const u8 gUnknown_83FE747[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}BALL{CLEAR_TO 56}BAIT\nROCK{CLEAR_TO 56}RUN");
+const u8 gText_MoveInterfacePP[] = _("PP ");
+const u8 gText_MoveInterfaceType[] = _("TYPE/");
+const u8 gUnknown_83FE770[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}");
+const u8 gUnknown_83FE779[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}どの わざを\nわすれさせたい?");
+const u8 gText_BattleYesNoChoice[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}Yes\nNo");
+const u8 gText_BattleSwitchWhich[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}Switch\nwhich?");
+const u8 gUnknown_83FE7B6[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}");
+const u8 gUnknown_83FE7BF[] = _("{RIGHT_ARROW_2}");
+const u8 gUnknown_83FE7C2[] = _("{PLUS}");
+const u8 gUnknown_83FE7C5[] = _("-");
+
+const u8 gUnknown_83FE7C7[] = _("{SIZE 0}Max{SIZE 2} HP");
+const u8 gUnknown_83FE7D4[] = _("ATTACK ");
+const u8 gUnknown_83FE7DC[] = _("DEFENSE");
+const u8 gUnknown_83FE7E4[] = _("SP. ATK");
+const u8 gUnknown_83FE7EC[] = _("SP. DEF");
+
+const u8 *const gUnknown_83FE7F4[] = {
+ gUnknown_83FE7C7,
+ gUnknown_83FE7E4,
+ gUnknown_83FE7D4,
+ gUnknown_83FE7EC,
+ gUnknown_83FE7DC,
+ sText_Speed
+};
+
+const u8 gUnknown_83FE80C[] = _("{HIGHLIGHT 2}SAFARI BALLS"); //
+const u8 gText_HighlightRed_Left[] = _("{HIGHLIGHT 2}Left: ");
+const u8 gText_HighlightRed[] = _("{HIGHLIGHT 2}");
+const u8 gText_Sleep[] = _("sleep");
+const u8 gText_Poison[] = _("poison");
+const u8 gText_Burn[] = _("burn");
+const u8 gText_Paralysis[] = _("paralysis");
+const u8 gText_Ice[] = _("ice");
+const u8 gText_Confusion[] = _("confusion");
+const u8 gText_Love[] = _("love");
+const u8 gUnknown_83FE859[] = _(" ");
+const u8 gUnknown_83FE85C[] = _("\n");
+const u8 gUnknown_83FE85E[] = _("\n");
+const u8 gUnknown_83FE860[] = _(" is");
+const u8 gUnknown_83FE864[] = _(" is");
+const u8 gText_BadEgg[] = _("Bad EGG");
+const u8 gUnknown_83FE870[] = _("ミツル");
+const u8 gUnknown_83FE874[] = _("{HIGHLIGHT 0}Win");
+const u8 gUnknown_83FE87B[] = _("{HIGHLIGHT 0}Loss");
+const u8 gUnknown_83FE883[] = _("{HIGHLIGHT 0}Draw");
+static const u8 sText_SpaceIs[] = _(" is");
+static const u8 sText_ApostropheS[] = _("'s");
+const u8 gUnknown_83FE892[] = _("a NORMAL move");
+const u8 gUnknown_83FE8A0[] = _("a FIGHTING move");
+const u8 gUnknown_83FE8B0[] = _("a FLYING move");
+const u8 gUnknown_83FE8BE[] = _("a POISON move");
+const u8 gUnknown_83FE8CC[] = _("a GROUND move");
+const u8 gUnknown_83FE8DA[] = _("a ROCK move");
+const u8 gUnknown_83FE8E6[] = _("a BUG move");
+const u8 gUnknown_83FE8F1[] = _("a GHOST move");
+const u8 gUnknown_83FE8FE[] = _("a STEEL move");
+const u8 gUnknown_83FE90B[] = _("a ??? move");
+const u8 gUnknown_83FE916[] = _("a FIRE move");
+const u8 gUnknown_83FE922[] = _("a WATER move");
+const u8 gUnknown_83FE92F[] = _("a GRASS move");
+const u8 gUnknown_83FE93C[] = _("an ELECTRIC move");
+const u8 gUnknown_83FE94D[] = _("a PSYCHIC move");
+const u8 gUnknown_83FE95C[] = _("an ICE move");
+const u8 gUnknown_83FE968[] = _("a DRAGON move");
+const u8 gUnknown_83FE976[] = _("a DARK move");
+const u8 gUnknown_83FE982[] = _("TIME BOARD");
+const u8 gUnknown_83FE98D[] = _("CLEAR TIME");
+const u8 gUnknown_83FE998[] = _("{STR_VAR_1}MIN. {STR_VAR_2}.{STR_VAR_3}SEC.");
+const u8 gUnknown_83FE9A9[] = _("1F");
+const u8 gUnknown_83FE9AC[] = _("2F");
+const u8 gUnknown_83FE9AF[] = _("3F");
+const u8 gUnknown_83FE9B2[] = _("4F");
+const u8 gUnknown_83FE9B5[] = _("5F");
+const u8 gUnknown_83FE9B8[] = _("6F");
+const u8 gUnknown_83FE9BB[] = _("7F");
+const u8 gUnknown_83FE9BE[] = _("8F");
+
+const u8 *const gUnknown_83FE9C4[] = {
+ gOtherText_Single,
+ gOtherText_Double,
+ gOtherText_Knockout,
+ gOtherText_Mixed
+};
+
+const u8 gUnknown_83FE9D4[] = _("{PLAY_SE SE_NIGERU}{B_TRAINER1_CLASS} {B_TRAINER1_NAME} fled!"); //
+static const u8 sText_PlayerLostAgainstTrainer1[] = _("Player lost against\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!");
+static const u8 sText_PlayerBattledToDrawTrainer1[] = _("Player battled to a draw against\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!");
+
+static const u8 *const sATypeMove_Table[] = {
+ gUnknown_83FE892,
+ gUnknown_83FE8A0,
+ gUnknown_83FE8B0,
+ gUnknown_83FE8BE,
+ gUnknown_83FE8CC,
+ gUnknown_83FE8DA,
+ gUnknown_83FE8E6,
+ gUnknown_83FE8F1,
+ gUnknown_83FE8FE,
+ gUnknown_83FE90B,
+ gUnknown_83FE916,
+ gUnknown_83FE922,
+ gUnknown_83FE92F,
+ gUnknown_83FE93C,
+ gUnknown_83FE94D,
+ gUnknown_83FE95C,
+ gUnknown_83FE968,
+ gUnknown_83FE976
+};
+
+static const u16 sGrammarMoveUsedTable[] = {
+ MOVE_SWORDS_DANCE,
+ MOVE_STRENGTH,
+ MOVE_GROWTH,
+ MOVE_HARDEN,
+ MOVE_MINIMIZE,
+ MOVE_SMOKESCREEN,
+ MOVE_WITHDRAW,
+ MOVE_DEFENSE_CURL,
+ MOVE_EGG_BOMB,
+ MOVE_SMOG,
+ MOVE_BONE_CLUB,
+ MOVE_FLASH,
+ MOVE_SPLASH,
+ MOVE_ACID_ARMOR,
+ MOVE_BONEMERANG,
+ MOVE_REST,
+ MOVE_SHARPEN,
+ MOVE_SUBSTITUTE,
+ MOVE_MIND_READER,
+ MOVE_SNORE,
+ MOVE_PROTECT,
+ MOVE_SPIKES,
+ MOVE_ENDURE,
+ MOVE_ROLLOUT,
+ MOVE_SWAGGER,
+ MOVE_SLEEP_TALK,
+ MOVE_HIDDEN_POWER,
+ MOVE_PSYCH_UP,
+ MOVE_EXTREME_SPEED,
+ MOVE_FOLLOW_ME,
+ MOVE_TRICK,
+ MOVE_ASSIST,
+ MOVE_INGRAIN,
+ MOVE_KNOCK_OFF,
+ MOVE_CAMOUFLAGE,
+ MOVE_ASTONISH,
+ MOVE_ODOR_SLEUTH,
+ MOVE_GRASS_WHISTLE,
+ MOVE_SHEER_COLD,
+ MOVE_MUDDY_WATER,
+ MOVE_IRON_DEFENSE,
+ MOVE_BOUNCE,
+ MOVE_NONE,
+
+ MOVE_TELEPORT,
+ MOVE_RECOVER,
+ MOVE_BIDE,
+ MOVE_AMNESIA,
+ MOVE_FLAIL,
+ MOVE_TAUNT,
+ MOVE_BULK_UP,
+ MOVE_NONE,
+
+ MOVE_MEDITATE,
+ MOVE_AGILITY,
+ MOVE_MIMIC,
+ MOVE_DOUBLE_TEAM,
+ MOVE_BARRAGE,
+ MOVE_TRANSFORM,
+ MOVE_STRUGGLE,
+ MOVE_SCARY_FACE,
+ MOVE_CHARGE,
+ MOVE_WISH,
+ MOVE_BRICK_BREAK,
+ MOVE_YAWN,
+ MOVE_FEATHER_DANCE,
+ MOVE_TEETER_DANCE,
+ MOVE_MUD_SPORT,
+ MOVE_FAKE_TEARS,
+ MOVE_WATER_SPORT,
+ MOVE_CALM_MIND,
+ MOVE_NONE,
+
+ MOVE_POUND,
+ MOVE_SCRATCH,
+ MOVE_VICE_GRIP,
+ MOVE_WING_ATTACK,
+ MOVE_FLY,
+ MOVE_BIND,
+ MOVE_SLAM,
+ MOVE_HORN_ATTACK,
+ MOVE_WRAP,
+ MOVE_THRASH,
+ MOVE_TAIL_WHIP,
+ MOVE_LEER,
+ MOVE_BITE,
+ MOVE_GROWL,
+ MOVE_ROAR,
+ MOVE_SING,
+ MOVE_PECK,
+ MOVE_ABSORB,
+ MOVE_STRING_SHOT,
+ MOVE_EARTHQUAKE,
+ MOVE_FISSURE,
+ MOVE_DIG,
+ MOVE_TOXIC,
+ MOVE_SCREECH,
+ MOVE_METRONOME,
+ MOVE_LICK,
+ MOVE_CLAMP,
+ MOVE_CONSTRICT,
+ MOVE_POISON_GAS,
+ MOVE_BUBBLE,
+ MOVE_SLASH,
+ MOVE_SPIDER_WEB,
+ MOVE_NIGHTMARE,
+ MOVE_CURSE,
+ MOVE_FORESIGHT,
+ MOVE_CHARM,
+ MOVE_ATTRACT,
+ MOVE_ROCK_SMASH,
+ MOVE_UPROAR,
+ MOVE_SPIT_UP,
+ MOVE_SWALLOW,
+ MOVE_TORMENT,
+ MOVE_FLATTER,
+ MOVE_ROLE_PLAY,
+ MOVE_ENDEAVOR,
+ MOVE_TICKLE,
+ MOVE_COVET,
+ MOVE_NONE
+};
+
+// code
+void BufferStringBattle(u16 stringId)
+{
+ s32 i;
+ const u8 *stringPtr = NULL;
+
+ sBattleMsgDataPtr = (struct BattleMsgData*)(&gBattleBufferA[gActiveBattler][4]);
+ gLastUsedItem = sBattleMsgDataPtr->lastItem;
+ gLastUsedAbility = sBattleMsgDataPtr->lastAbility;
+ gBattleScripting.battler = sBattleMsgDataPtr->scrActive;
+ *(&gBattleStruct->field_52) = sBattleMsgDataPtr->unk1605E;
+ *(&gBattleStruct->hpScale) = sBattleMsgDataPtr->hpScale;
+ gPotentialItemEffectBattler = sBattleMsgDataPtr->itemEffectBattler;
+ *(&gBattleStruct->stringMoveType) = sBattleMsgDataPtr->moveType;
+
+ for (i = 0; i < MAX_BATTLERS_COUNT; i++)
+ {
+ sBattlerAbilities[i] = sBattleMsgDataPtr->abilities[i];
+ }
+ for (i = 0; i < TEXT_BUFF_ARRAY_COUNT; i++)
+ {
+ gBattleTextBuff1[i] = sBattleMsgDataPtr->textBuffs[0][i];
+ gBattleTextBuff2[i] = sBattleMsgDataPtr->textBuffs[1][i];
+ gBattleTextBuff3[i] = sBattleMsgDataPtr->textBuffs[2][i];
+ }
+
+ switch (stringId)
+ {
+ case STRINGID_INTROMSG: // first battle msg
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ stringPtr = sText_TwoLinkTrainersWantToBattle;
+ }
+ else
+ {
+ if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ stringPtr = sText_Trainer1WantsToBattle;
+ else
+ stringPtr = sText_LinkTrainerWantsToBattle;
+ }
+ }
+ else
+ {
+ stringPtr = sText_Trainer1WantsToBattle;
+ }
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_GHOST)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY)
+ stringPtr = gUnknown_83FD30D;
+ else
+ stringPtr = gUnknown_83FD2D9;
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY)
+ stringPtr = sText_WildPkmnAppeared2;
+ else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles
+ stringPtr = sText_TwoWildPkmnAppeared;
+ else if (gBattleTypeFlags & BATTLE_TYPE_OLD_MAN_TUTORIAL)
+ stringPtr = sText_WildPkmnAppearedPause;
+ else
+ stringPtr = sText_WildPkmnAppeared;
+ }
+ break;
+ case STRINGID_INTROSENDOUT: // poke first send-out
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ stringPtr = sText_LinkPartnerSentOutPkmnGoPkmn;
+ else
+ stringPtr = sText_GoTwoPkmn;
+ }
+ else
+ {
+ stringPtr = sText_GoPkmn;
+ }
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ stringPtr = sText_TwoLinkTrainersSentOutPkmn;
+ else if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ stringPtr = sText_LinkTrainerSentOutTwoPkmn;
+ else
+ stringPtr = sText_Trainer1SentOutTwoPkmn;
+ }
+ else
+ {
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
+ stringPtr = sText_Trainer1SentOutPkmn;
+ else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ stringPtr = sText_Trainer1SentOutPkmn;
+ else
+ stringPtr = sText_LinkTrainerSentOutPkmn;
+ }
+ }
+ break;
+ case STRINGID_RETURNMON: // sending poke to ball msg
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ if (*(&gBattleStruct->hpScale) == 0)
+ stringPtr = sText_PkmnThatsEnough;
+ else if (*(&gBattleStruct->hpScale) == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ stringPtr = sText_PkmnComeBack;
+ else if (*(&gBattleStruct->hpScale) == 2)
+ stringPtr = sText_PkmnOkComeBack;
+ else
+ stringPtr = sText_PkmnGoodComeBack;
+ }
+ else
+ {
+ if (gTrainerBattleOpponent_A == TRAINER_LINK_OPPONENT)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ stringPtr = sText_LinkTrainer2WithdrewPkmn;
+ else
+ stringPtr = sText_LinkTrainer1WithdrewPkmn;
+ }
+ else
+ {
+ stringPtr = sText_Trainer1WithdrewPkmn;
+ }
+ }
+ break;
+ case STRINGID_SWITCHINMON: // switch-in msg
+ if (GetBattlerSide(gBattleScripting.battler) == B_SIDE_PLAYER)
+ {
+ if (*(&gBattleStruct->hpScale) == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ stringPtr = sText_GoPkmn2;
+ else if (*(&gBattleStruct->hpScale) == 1)
+ stringPtr = sText_DoItPkmn;
+ else if (*(&gBattleStruct->hpScale) == 2)
+ stringPtr = sText_GoForItPkmn;
+ else
+ stringPtr = sText_YourFoesWeakGetEmPkmn;
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ stringPtr = sText_LinkTrainerMultiSentOutPkmn;
+ else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ stringPtr = sText_Trainer1SentOutPkmn2;
+ else
+ stringPtr = sText_LinkTrainerSentOutPkmn2;
+ }
+ else
+ {
+ stringPtr = sText_Trainer1SentOutPkmn2;
+ }
+ }
+ break;
+ case STRINGID_USEDMOVE: // pokemon used a move msg
+ ChooseMoveUsedParticle(gBattleTextBuff1); // buff1 doesn't appear in the string, leftover from japanese move names
+
+ if (sBattleMsgDataPtr->currentMove >= MOVES_COUNT)
+ StringCopy(gBattleTextBuff2, sATypeMove_Table[*(&gBattleStruct->stringMoveType)]);
+ else
+ StringCopy(gBattleTextBuff2, gMoveNames[sBattleMsgDataPtr->currentMove]);
+
+ ChooseTypeOfMoveUsedString(gBattleTextBuff2);
+ stringPtr = sText_AttackerUsedX;
+ break;
+ case STRINGID_BATTLEEND: // battle end
+ if (gBattleTextBuff1[0] & B_OUTCOME_LINK_BATTLE_RAN)
+ {
+ gBattleTextBuff1[0] &= ~(B_OUTCOME_LINK_BATTLE_RAN);
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT && gBattleTextBuff1[0] != B_OUTCOME_DREW)
+ gBattleTextBuff1[0] ^= (B_OUTCOME_LOST | B_OUTCOME_WON);
+
+ if (gBattleTextBuff1[0] == B_OUTCOME_LOST || gBattleTextBuff1[0] == B_OUTCOME_DREW)
+ stringPtr = sText_GotAwaySafely;
+ else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ stringPtr = sText_TwoWildFled;
+ else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ stringPtr = gUnknown_83FE9D4;
+ else
+ stringPtr = gUnknown_83FCD92;
+ }
+ else
+ {
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT && gBattleTextBuff1[0] != B_OUTCOME_DREW)
+ gBattleTextBuff1[0] ^= (B_OUTCOME_LOST | B_OUTCOME_WON);
+
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ switch (gBattleTextBuff1[0])
+ {
+ case B_OUTCOME_WON:
+ stringPtr = sText_TwoLinkTrainersDefeated;
+ break;
+ case B_OUTCOME_LOST:
+ stringPtr = sText_PlayerLostToTwo;
+ break;
+ case B_OUTCOME_DREW:
+ stringPtr = sText_PlayerBattledToDrawVsTwo;
+ break;
+ }
+ }
+ else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ {
+ switch (gBattleTextBuff1[0])
+ {
+ case B_OUTCOME_WON:
+ stringPtr = sText_PlayerDefeatedLinkTrainerTrainer1;
+ break;
+ case B_OUTCOME_LOST:
+ stringPtr = sText_PlayerLostAgainstTrainer1;
+ break;
+ case B_OUTCOME_DREW:
+ stringPtr = sText_PlayerBattledToDrawTrainer1;
+ break;
+ }
+ }
+ else
+ {
+ switch (gBattleTextBuff1[0])
+ {
+ case B_OUTCOME_WON:
+ stringPtr = sText_PlayerDefeatedLinkTrainer;
+ break;
+ case B_OUTCOME_LOST:
+ stringPtr = sText_PlayerLostAgainstLinkTrainer;
+ break;
+ case B_OUTCOME_DREW:
+ stringPtr = sText_PlayerBattledToDrawLinkTrainer;
+ break;
+ }
+ }
+ }
+ break;
+ default: // load a string from the table
+ if (stringId >= BATTLESTRINGS_COUNT + BATTLESTRINGS_ID_ADDER)
+ {
+ gDisplayedStringBattle[0] = EOS;
+ return;
+ }
+ else
+ {
+ stringPtr = gBattleStringsTable[stringId - BATTLESTRINGS_ID_ADDER];
+ }
+ break;
+ }
+
+ BattleStringExpandPlaceholdersToDisplayedString(stringPtr);
+}
+
+u32 BattleStringExpandPlaceholdersToDisplayedString(const u8* src)
+{
+ BattleStringExpandPlaceholders(src, gDisplayedStringBattle);
+}
+
+static const u8* TryGetStatusString(u8 *src)
+{
+ u32 i;
+ u8 status[] = _("$$$$$$$");
+ u32 chars1, chars2;
+ u8* statusPtr;
+
+ statusPtr = status;
+ for (i = 0; i < 8; i++)
+ {
+ if (*src == EOS)
+ break;
+ *statusPtr = *src;
+ src++;
+ statusPtr++;
+ }
+
+ chars1 = *(u32*)(&status[0]);
+ chars2 = *(u32*)(&status[4]);
+
+ for (i = 0; i < NELEMS(gStatusConditionStringsTable); i++)
+ {
+ if (chars1 == *(u32*)(&gStatusConditionStringsTable[i][0][0])
+ && chars2 == *(u32*)(&gStatusConditionStringsTable[i][0][4]))
+ return gStatusConditionStringsTable[i][1];
+ }
+ return NULL;
+}
+
+#define HANDLE_NICKNAME_STRING_CASE(battlerId, monIndex) \
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) \
+ { \
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \
+ toCpy = sText_FoePkmnPrefix; \
+ else \
+ toCpy = sText_WildPkmnPrefix; \
+ while (*toCpy != EOS) \
+ { \
+ dst[dstId] = *toCpy; \
+ dstId++; \
+ toCpy++; \
+ } \
+ GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \
+ } \
+ else \
+ { \
+ GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \
+ } \
+ StringGetEnd10(text); \
+ toCpy = text;
+
+u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
+{
+ u32 dstId = 0; // if they used dstId, why not use srcId as well?
+ const u8 *toCpy = NULL;
+ u8 text[30];
+ u8 multiplayerId;
+ s32 i;
+
+ multiplayerId = GetMultiplayerId();
+
+ while (*src != EOS)
+ {
+ if (*src == PLACEHOLDER_BEGIN)
+ {
+ src++;
+ switch (*src)
+ {
+ case B_TXT_BUFF1:
+ if (gBattleTextBuff1[0] == B_BUFF_PLACEHOLDER_BEGIN)
+ {
+ ExpandBattleTextBuffPlaceholders(gBattleTextBuff1, gStringVar1);
+ toCpy = gStringVar1;
+ }
+ else
+ {
+ toCpy = TryGetStatusString(gBattleTextBuff1);
+ if (toCpy == NULL)
+ toCpy = gBattleTextBuff1;
+ }
+ break;
+ case B_TXT_BUFF2:
+ if (gBattleTextBuff2[0] == B_BUFF_PLACEHOLDER_BEGIN)
+ {
+ ExpandBattleTextBuffPlaceholders(gBattleTextBuff2, gStringVar2);
+ toCpy = gStringVar2;
+ }
+ else
+ toCpy = gBattleTextBuff2;
+ break;
+ case B_TXT_BUFF3:
+ if (gBattleTextBuff3[0] == B_BUFF_PLACEHOLDER_BEGIN)
+ {
+ ExpandBattleTextBuffPlaceholders(gBattleTextBuff3, gStringVar3);
+ toCpy = gStringVar3;
+ }
+ else
+ toCpy = gBattleTextBuff3;
+ break;
+ case B_TXT_COPY_VAR_1:
+ toCpy = gStringVar1;
+ break;
+ case B_TXT_COPY_VAR_2:
+ toCpy = gStringVar2;
+ break;
+ case B_TXT_COPY_VAR_3:
+ toCpy = gStringVar3;
+ break;
+ case B_TXT_PLAYER_MON1_NAME: // first player poke name
+ GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_OPPONENT_MON1_NAME: // first enemy poke name
+ GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_PLAYER_MON2_NAME: // second player poke name
+ GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_OPPONENT_MON2_NAME: // second enemy poke name
+ GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_LINK_PLAYER_MON1_NAME: // link first player poke name
+ GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_LINK_OPPONENT_MON1_NAME: // link first opponent poke name
+ GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id ^ 1]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_LINK_PLAYER_MON2_NAME: // link second player poke name
+ GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id ^ 2]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_LINK_OPPONENT_MON2_NAME: // link second opponent poke name
+ GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id ^ 3]],
+ MON_DATA_NICKNAME, text);
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_ATK_NAME_WITH_PREFIX_MON1: // attacker name with prefix, only battlerId 0/1
+ HANDLE_NICKNAME_STRING_CASE(gBattlerAttacker,
+ gBattlerPartyIndexes[GetBattlerAtPosition(GET_BATTLER_SIDE(gBattlerAttacker))])
+ break;
+ case B_TXT_ATK_PARTNER_NAME: // attacker partner name
+ if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
+ GetMonData(
+ &gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(GET_BATTLER_SIDE(gBattlerAttacker)) +
+ 2]], MON_DATA_NICKNAME, text);
+ else
+ GetMonData(
+ &gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(GET_BATTLER_SIDE(gBattlerAttacker)) +
+ 2]], MON_DATA_NICKNAME, text);
+
+ StringGetEnd10(text);
+ toCpy = text;
+ break;
+ case B_TXT_ATK_NAME_WITH_PREFIX: // attacker name with prefix
+ HANDLE_NICKNAME_STRING_CASE(gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker])
+ break;
+ case B_TXT_DEF_NAME_WITH_PREFIX: // target name with prefix
+ HANDLE_NICKNAME_STRING_CASE(gBattlerTarget, gBattlerPartyIndexes[gBattlerTarget])
+ break;
+ case B_TXT_EFF_NAME_WITH_PREFIX: // effect battlerId name with prefix
+ HANDLE_NICKNAME_STRING_CASE(gEffectBattler, gBattlerPartyIndexes[gEffectBattler])
+ break;
+ case B_TXT_ACTIVE_NAME_WITH_PREFIX: // active battlerId name with prefix
+ HANDLE_NICKNAME_STRING_CASE(gActiveBattler, gBattlerPartyIndexes[gActiveBattler])
+ break;
+ case B_TXT_SCR_ACTIVE_NAME_WITH_PREFIX: // scripting active battlerId name with prefix
+ HANDLE_NICKNAME_STRING_CASE(gBattleScripting.battler, gBattlerPartyIndexes[gBattleScripting.battler])
+ break;
+ case B_TXT_CURRENT_MOVE: // current move name
+ if (sBattleMsgDataPtr->currentMove >= MOVES_COUNT)
+ toCpy = (const u8 *)&sATypeMove_Table[gBattleStruct->stringMoveType];
+ else
+ toCpy = gMoveNames[sBattleMsgDataPtr->currentMove];
+ break;
+ case B_TXT_LAST_MOVE: // originally used move name
+ if (sBattleMsgDataPtr->originallyUsedMove >= MOVES_COUNT)
+ toCpy = (const u8 *)&sATypeMove_Table[gBattleStruct->stringMoveType];
+ else
+ toCpy = gMoveNames[sBattleMsgDataPtr->originallyUsedMove];
+ break;
+ case B_TXT_LAST_ITEM: // last used item
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ if (gLastUsedItem == ITEM_ENIGMA_BERRY)
+ {
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ {
+ if ((gBattleStruct->multiplayerId != 0 && (gPotentialItemEffectBattler & BIT_SIDE))
+ || (gBattleStruct->multiplayerId == 0 && !(gPotentialItemEffectBattler & BIT_SIDE)))
+ {
+ StringCopy(text, gEnigmaBerries[gPotentialItemEffectBattler].name);
+ StringAppend(text, sText_BerrySuffix);
+ toCpy = text;
+ }
+ else
+ {
+ toCpy = sText_EnigmaBerry;
+ }
+ }
+ else
+ {
+ if (gLinkPlayers[gBattleStruct->multiplayerId].id == gPotentialItemEffectBattler)
+ {
+ StringCopy(text, gEnigmaBerries[gPotentialItemEffectBattler].name);
+ StringAppend(text, sText_BerrySuffix);
+ toCpy = text;
+ }
+ else
+ toCpy = sText_EnigmaBerry;
+ }
+ }
+ else
+ {
+ CopyItemName(gLastUsedItem, text);
+ toCpy = text;
+ }
+ }
+ else
+ {
+ CopyItemName(gLastUsedItem, text);
+ toCpy = text;
+ }
+ break;
+ case B_TXT_LAST_ABILITY: // last used ability
+ toCpy = gAbilityNames[gLastUsedAbility];
+ break;
+ case B_TXT_ATK_ABILITY: // attacker ability
+ toCpy = gAbilityNames[sBattlerAbilities[gBattlerAttacker]];
+ break;
+ case B_TXT_DEF_ABILITY: // target ability
+ toCpy = gAbilityNames[sBattlerAbilities[gBattlerTarget]];
+ break;
+ case B_TXT_SCR_ACTIVE_ABILITY: // scripting active ability
+ toCpy = gAbilityNames[sBattlerAbilities[gBattleScripting.battler]];
+ break;
+ case B_TXT_EFF_ABILITY: // effect battlerId ability
+ toCpy = gAbilityNames[sBattlerAbilities[gEffectBattler]];
+ break;
+ case B_TXT_TRAINER1_CLASS: // trainer class name
+ if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()];
+ else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ toCpy = gTrainerClassNames[sub_80447F0()];
+ else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
+ toCpy = gTrainerClassNames[GetBattleTowerTrainerClassNameId()];
+ else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
+ toCpy = gTrainerClassNames[sub_815DA10()];
+ else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
+ toCpy = gTrainerClassNames[GetEreaderTrainerClassId()];
+ else
+ toCpy = gTrainerClassNames[gTrainers[gTrainerBattleOpponent_A].trainerClass];
+ break;
+ case B_TXT_TRAINER1_NAME: // trainer1 name
+ if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ {
+ for (i = 0; i < (s32)NELEMS(gBattleResources->secretBase->trainerName); i++)
+ text[i] = gBattleResources->secretBase->trainerName[i];
+ text[i] = EOS;
+ toCpy = text;
+ }
+ if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
+ {
+ toCpy = gLinkPlayers[multiplayerId ^ BIT_SIDE].name;
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
+ {
+ GetBattleTowerTrainerName(text);
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
+ {
+ sub_815DA28(text);
+ toCpy = text;
+ }
+ else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
+ {
+ CopyEReaderTrainerName5(text);
+ toCpy = text;
+ }
+ else
+ {
+ if (gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_RIVAL
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_RIVAL_2
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == CLASS_CHAMPION_2)
+ toCpy = GetExpandedPlaceholder(6);
+ else
+ toCpy = gTrainers[gTrainerBattleOpponent_A].trainerName;
+ }
+ break;
+ case B_TXT_LINK_PLAYER_NAME: // link player name
+ toCpy = gLinkPlayers[multiplayerId].name;
+ break;
+ case B_TXT_LINK_PARTNER_NAME: // link partner name
+ toCpy = gLinkPlayers[GetBattlerMultiplayerId(BATTLE_PARTNER(gLinkPlayers[multiplayerId].id))].name;
+ break;
+ case B_TXT_LINK_OPPONENT1_NAME: // link opponent 1 name
+ toCpy = gLinkPlayers[GetBattlerMultiplayerId(BATTLE_OPPOSITE(gLinkPlayers[multiplayerId].id))].name;
+ break;
+ case B_TXT_LINK_OPPONENT2_NAME: // link opponent 2 name
+ toCpy = gLinkPlayers[GetBattlerMultiplayerId(
+ BATTLE_PARTNER(BATTLE_OPPOSITE(gLinkPlayers[multiplayerId].id)))].name;
+ break;
+ case B_TXT_LINK_SCR_TRAINER_NAME: // link scripting active name
+ toCpy = gLinkPlayers[GetBattlerMultiplayerId(gBattleScripting.battler)].name;
+ break;
+ case B_TXT_PLAYER_NAME: // player name
+ toCpy = gSaveBlock2Ptr->playerName;
+ break;
+ case B_TXT_TRAINER1_LOSE_TEXT: // trainerA lose text
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
+ {
+ sub_815DC40(gStringVar4, 0);
+ toCpy = gStringVar4;
+ }
+ else
+ {
+ toCpy = GetTrainerALoseText();
+ }
+ break;
+ case B_TXT_TRAINER1_WIN_TEXT: // trainerA win text
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
+ {
+ sub_815DBF4(gStringVar4, 0);
+ toCpy = gStringVar4;
+ }
+ else
+ {
+ toCpy = GetTrainerWonSpeech();
+ }
+ break;
+ case B_TXT_TRAINER2_LOSE_TEXT:
+ sub_815DC40(gStringVar4, 1);
+ toCpy = gStringVar4;
+ break;
+ case B_TXT_TRAINER2_WIN_TEXT:
+ sub_815DBF4(gStringVar4, 1);
+ toCpy = gStringVar4;
+ break;
+ case B_TXT_26: // ?
+ HANDLE_NICKNAME_STRING_CASE(gBattleScripting.battler, *(&gBattleStruct->field_52))
+ break;
+ case B_TXT_PC_CREATOR_NAME: // lanette pc
+ if (FlagGet(FLAG_SYS_NOT_SOMEONES_PC))
+ toCpy = sText_Bills;
+ else
+ toCpy = sText_Someones;
+ break;
+ case B_TXT_ATK_PREFIX2:
+ if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
+ toCpy = sText_AllyPkmnPrefix2;
+ else
+ toCpy = sText_FoePkmnPrefix3;
+ break;
+ case B_TXT_DEF_PREFIX2:
+ if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
+ toCpy = sText_AllyPkmnPrefix2;
+ else
+ toCpy = sText_FoePkmnPrefix3;
+ break;
+ case B_TXT_ATK_PREFIX1:
+ if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
+ toCpy = sText_AllyPkmnPrefix;
+ else
+ toCpy = sText_FoePkmnPrefix2;
+ break;
+ case B_TXT_DEF_PREFIX1:
+ if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
+ toCpy = sText_AllyPkmnPrefix;
+ else
+ toCpy = sText_FoePkmnPrefix2;
+ break;
+ case B_TXT_ATK_PREFIX3:
+ if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
+ toCpy = sText_AllyPkmnPrefix3;
+ else
+ toCpy = sText_FoePkmnPrefix4;
+ break;
+ case B_TXT_DEF_PREFIX3:
+ if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
+ toCpy = sText_AllyPkmnPrefix3;
+ else
+ toCpy = sText_FoePkmnPrefix4;
+ break;
+ }
+
+ // missing if (toCpy != NULL) check
+ while (*toCpy != EOS)
+ {
+ dst[dstId] = *toCpy;
+ dstId++;
+ toCpy++;
+ }
+ if (*src == B_TXT_TRAINER1_LOSE_TEXT || *src == B_TXT_TRAINER1_WIN_TEXT
+ || *src == B_TXT_TRAINER2_LOSE_TEXT || *src == B_TXT_TRAINER2_WIN_TEXT)
+ {
+ dst[dstId] = EXT_CTRL_CODE_BEGIN;
+ dstId++;
+ dst[dstId] = 9;
+ dstId++;
+ }
+ }
+ else
+ {
+ dst[dstId] = *src;
+ dstId++;
+ }
+ src++;
+ }
+
+ dst[dstId] = *src;
+ dstId++;
+
+ return dstId;
+}
+
+static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
+{
+ u32 srcId = 1;
+ u32 value = 0;
+ u8 text[12];
+ u16 hword;
+
+ *dst = EOS;
+ while (src[srcId] != B_BUFF_EOS)
+ {
+ switch (src[srcId])
+ {
+ case B_BUFF_STRING: // battle string
+ hword = T1_READ_16(&src[srcId + 1]);
+ StringAppend(dst, gBattleStringsTable[hword - BATTLESTRINGS_ID_ADDER]);
+ srcId += 3;
+ break;
+ case B_BUFF_NUMBER: // int to string
+ switch (src[srcId + 1])
+ {
+ case 1:
+ value = src[srcId + 3];
+ break;
+ case 2:
+ value = T1_READ_16(&src[srcId + 3]);
+ break;
+ case 4:
+ value = T1_READ_32(&src[srcId + 3]);
+ break;
+ }
+ ConvertIntToDecimalStringN(dst, value, STR_CONV_MODE_LEFT_ALIGN, src[srcId + 2]);
+ srcId += src[srcId + 1] + 3;
+ break;
+ case B_BUFF_MOVE: // move name
+ StringAppend(dst, gMoveNames[T1_READ_16(&src[srcId + 1])]);
+ srcId += 3;
+ break;
+ case B_BUFF_TYPE: // type name
+ StringAppend(dst, gTypeNames[src[srcId + 1]]);
+ srcId += 2;
+ break;
+ case B_BUFF_MON_NICK_WITH_PREFIX: // poke nick with prefix
+ if (GetBattlerSide(src[srcId + 1]) == B_SIDE_PLAYER)
+ {
+ GetMonData(&gPlayerParty[src[srcId + 2]], MON_DATA_NICKNAME, text);
+ }
+ else
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ StringAppend(dst, sText_FoePkmnPrefix);
+ else
+ StringAppend(dst, sText_WildPkmnPrefix);
+
+ GetMonData(&gEnemyParty[src[srcId + 2]], MON_DATA_NICKNAME, text);
+ }
+ StringGetEnd10(text);
+ StringAppend(dst, text);
+ srcId += 3;
+ break;
+ case B_BUFF_STAT: // stats
+ StringAppend(dst, gStatNamesTable[src[srcId + 1]]);
+ srcId += 2;
+ break;
+ case B_BUFF_SPECIES: // species name
+ GetSpeciesName(dst, T1_READ_16(&src[srcId + 1]));
+ srcId += 3;
+ break;
+ case B_BUFF_MON_NICK: // poke nick without prefix
+ if (GetBattlerSide(src[srcId + 1]) == B_SIDE_PLAYER)
+ GetMonData(&gPlayerParty[src[srcId + 2]], MON_DATA_NICKNAME, dst);
+ else
+ GetMonData(&gEnemyParty[src[srcId + 2]], MON_DATA_NICKNAME, dst);
+ StringGetEnd10(dst);
+ srcId += 3;
+ break;
+ case B_BUFF_NEGATIVE_FLAVOR: // flavor table
+ StringAppend(dst, gPokeblockWasTooXStringTable[src[srcId + 1]]);
+ srcId += 2;
+ break;
+ case B_BUFF_ABILITY: // ability names
+ StringAppend(dst, gAbilityNames[src[srcId + 1]]);
+ srcId += 2;
+ break;
+ case B_BUFF_ITEM: // item name
+ hword = T1_READ_16(&src[srcId + 1]);
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ if (hword == ITEM_ENIGMA_BERRY)
+ {
+ if (gLinkPlayers[gBattleStruct->multiplayerId].id == gPotentialItemEffectBattler)
+ {
+ StringCopy(dst, gEnigmaBerries[gPotentialItemEffectBattler].name);
+ StringAppend(dst, sText_BerrySuffix);
+ }
+ else
+ {
+ StringAppend(dst, sText_EnigmaBerry);
+ }
+ }
+ else
+ {
+ CopyItemName(hword, dst);
+ }
+ }
+ else
+ {
+ CopyItemName(hword, dst);
+ }
+ srcId += 3;
+ break;
+ }
+ }
+}
+
+// Loads one of two text strings into the provided buffer. This is functionally
+// unused, since the value loaded into the buffer is not read; it loaded one of
+// two particles (either "は" or "の") which works in tandem with ChooseTypeOfMoveUsedString
+// below to effect changes in the meaning of the line.
+static void ChooseMoveUsedParticle(u8* textBuff)
+{
+ s32 counter = 0;
+ u32 i = 0;
+
+ while (counter != MAX_MON_MOVES)
+ {
+ if (sGrammarMoveUsedTable[i] == 0)
+ counter++;
+ if (sGrammarMoveUsedTable[i++] == sBattleMsgDataPtr->currentMove)
+ break;
+ }
+
+ if (counter >= 0)
+ {
+ if (counter <= 2)
+ StringCopy(textBuff, sText_SpaceIs); // is
+ else if (counter <= MAX_MON_MOVES)
+ StringCopy(textBuff, sText_ApostropheS); // 's
+ }
+}
+
+// Appends "!" to the text buffer `dst`. In the original Japanese this looked
+// into the table of moves at sGrammarMoveUsedTable and varied the line accordingly.
+//
+// sText_ExclamationMark was a plain "!", used for any attack not on the list.
+// It resulted in the translation "<NAME>'s <ATTACK>!".
+//
+// sText_ExclamationMark2 was "を つかった!". This resulted in the translation
+// "<NAME> used <ATTACK>!", which was used for all attacks in English.
+//
+// sText_ExclamationMark3 was "した!". This was used for those moves whose
+// names were verbs, such as Recover, and resulted in translations like "<NAME>
+// recovered itself!".
+//
+// sText_ExclamationMark4 was "を した!" This resulted in a translation of
+// "<NAME> did an <ATTACK>!".
+//
+// sText_ExclamationMark5 was " こうげき!" This resulted in a translation of
+// "<NAME>'s <ATTACK> attack!".
+static void ChooseTypeOfMoveUsedString(u8* dst)
+{
+ s32 counter = 0;
+ s32 i = 0;
+
+ while (*dst != EOS)
+ dst++;
+
+ while (counter != MAX_MON_MOVES)
+ {
+ if (sGrammarMoveUsedTable[i] == MOVE_NONE)
+ counter++;
+ if (sGrammarMoveUsedTable[i++] == sBattleMsgDataPtr->currentMove)
+ break;
+ }
+
+ switch (counter)
+ {
+ case 0:
+ StringCopy(dst, sText_ExclamationMark);
+ break;
+ case 1:
+ StringCopy(dst, sText_ExclamationMark2);
+ break;
+ case 2:
+ StringCopy(dst, sText_ExclamationMark3);
+ break;
+ case 3:
+ StringCopy(dst, sText_ExclamationMark4);
+ break;
+ case 4:
+ StringCopy(dst, sText_ExclamationMark5);
+ break;
+ }
+}
+
+static const struct BattleWindowText sTextOnWindowsInfo_Normal[] = {
+ {PIXEL_FILL(0xf), 2, 0x02, 2, 0, 2, 1, 0x1, 0xf, 0x6},
+ {PIXEL_FILL(0xf), 2, 0x02, 2, 0, 2, 0, 0x1, 0xf, 0x6},
+ {PIXEL_FILL(0xe), 1, 0x00, 2, 0, 2, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 0, 0x00, 1, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 0, 0x00, 1, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 0, 0x00, 1, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 0, 0x00, 1, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 0, 0x00, 2, 0, 0, 0, 0xc, 0xe, 0xb},
+ {PIXEL_FILL(0xe), 0, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 1, 0x0a, 2, 0, 2, 0, 0xc, 0xe, 0xb},
+ {PIXEL_FILL(0xe), 1, 0x00, 2, 0, 2, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 1, 0x00, 2, 0, 2, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 0, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0x0), 0, 0x20, 0, 0, 0, 0, 0x1, 0x0, 0x2},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 1, 2, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0xe), 2, 0x00, 2, 0, 0, 0, 0xd, 0xe, 0xf},
+ {PIXEL_FILL(0x0), 2, 0x00, 2, 0, 0, 0, 0x1, 0x0, 0x6},
+ {PIXEL_FILL(0x0), 2, 0x00, 2, 0, 0, 0, 0x1, 0x0, 0x6},
+ {PIXEL_FILL(0x0), 2, 0x00, 2, 0, 0, 0, 0x1, 0x0, 0x6},
+ {PIXEL_FILL(0x1), 4, 0x00, 1, 0, 1, 1, 0x2, 0x1, 0x3}
+};
+
+const u8 gUnknown_83FEC90[] = {0x04, 0x05, 0x02, 0x02};
+
+void BattlePutTextOnWindow(const u8 *text, u8 windowId) {
+ bool32 copyToVram;
+ struct TextPrinterTemplate printerTemplate;
+ u8 speed;
+ int x;
+ u8 context;
+
+ u8 textFlags = windowId & 0xC0;
+ windowId &= 0x3F;
+ if (!(textFlags & 0x80))
+ FillWindowPixelBuffer(windowId, sTextOnWindowsInfo_Normal[windowId].fillValue);
+ if (textFlags & 0x40) {
+ context = ContextNpcGetTextColor();
+ printerTemplate.fontId = gUnknown_83FEC90[context];
+ }
+ else {
+ printerTemplate.fontId = sTextOnWindowsInfo_Normal[windowId].fontId;
+ }
+ switch (windowId)
+ {
+ case 15 ... 20:
+ x = (48 - GetStringWidth(sTextOnWindowsInfo_Normal[windowId].fontId, text,
+ sTextOnWindowsInfo_Normal[windowId].letterSpacing)) / 2;
+ break;
+ case 21 ... 23:
+ x = (64 - GetStringWidth(sTextOnWindowsInfo_Normal[windowId].fontId, text,
+ sTextOnWindowsInfo_Normal[windowId].letterSpacing)) / 2;
+ break;
+ default:
+ x = sTextOnWindowsInfo_Normal[windowId].x;
+ break;
+ }
+ if (x < 0)
+ x = 0;
+ printerTemplate.currentChar = text;
+ printerTemplate.windowId = windowId;
+ printerTemplate.x = x;
+ printerTemplate.y = sTextOnWindowsInfo_Normal[windowId].y;
+ printerTemplate.currentX = printerTemplate.x;
+ printerTemplate.currentY = printerTemplate.y;
+ printerTemplate.letterSpacing = sTextOnWindowsInfo_Normal[windowId].letterSpacing;
+ printerTemplate.lineSpacing = sTextOnWindowsInfo_Normal[windowId].lineSpacing;
+ printerTemplate.unk = 0;
+ printerTemplate.fgColor = sTextOnWindowsInfo_Normal[windowId].fgColor;
+ printerTemplate.bgColor = sTextOnWindowsInfo_Normal[windowId].bgColor;
+ printerTemplate.shadowColor = sTextOnWindowsInfo_Normal[windowId].shadowColor;
+ if (windowId == 24)
+ gTextFlags.useAlternateDownArrow = FALSE;
+ else
+ gTextFlags.useAlternateDownArrow = TRUE;
+
+ if ((gBattleTypeFlags & BATTLE_TYPE_LINK) || ((gBattleTypeFlags & BATTLE_TYPE_POKEDUDE) && windowId != 24))
+ gTextFlags.autoScroll = TRUE;
+ else
+ gTextFlags.autoScroll = FALSE;
+
+ if (windowId == 0 || windowId == 24)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ speed = 1;
+ else
+ speed = GetTextSpeedSetting();
+ gTextFlags.canABSpeedUpPrint = TRUE;
+ }
+ else
+ {
+ speed = sTextOnWindowsInfo_Normal[windowId].speed;
+ gTextFlags.canABSpeedUpPrint = FALSE;
+ }
+
+ AddTextPrinter(&printerTemplate, speed, NULL);
+ if (!(textFlags & 0x80))
+ {
+ PutWindowTilemap(windowId);
+ CopyWindowToVram(windowId, 3);
+ }
+}
+
+bool8 sub_80D89B0(u16 stringId)
+{
+ if (stringId == STRINGID_TRAINER1LOSETEXT || stringId == STRINGID_TRAINER2CLASS || stringId == STRINGID_TRAINER1WINTEXT || stringId == STRINGID_TRAINER2NAME)
+ return TRUE;
+ return FALSE;
+}
+
+void SetPpNumbersPaletteInMoveSelection(void)
+{
+ struct ChooseMoveStruct *chooseMoveStruct = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBattler][4]);
+ const u16 *palPtr = gUnknown_8D2FBB4;
+ u8 var = GetCurrentPpToMaxPpState(chooseMoveStruct->currentPp[gMoveSelectionCursor[gActiveBattler]],
+ chooseMoveStruct->maxPp[gMoveSelectionCursor[gActiveBattler]]);
+
+ gPlttBufferUnfaded[92] = palPtr[(var * 2) + 0];
+ gPlttBufferUnfaded[91] = palPtr[(var * 2) + 1];
+
+ CpuCopy16(&gPlttBufferUnfaded[92], &gPlttBufferFaded[92], sizeof(u16));
+ CpuCopy16(&gPlttBufferUnfaded[91], &gPlttBufferFaded[91], sizeof(u16));
+}
+
+u8 GetCurrentPpToMaxPpState(u8 currentPp, u8 maxPp)
+{
+ if (maxPp == currentPp)
+ {
+ return 3;
+ }
+ else if (maxPp <= 2)
+ {
+ if (currentPp > 1)
+ return 3;
+ else
+ return 2 - currentPp;
+ }
+ else if (maxPp <= 7)
+ {
+ if (currentPp > 2)
+ return 3;
+ else
+ return 2 - currentPp;
+ }
+ else
+ {
+ if (currentPp == 0)
+ return 2;
+ if (currentPp <= maxPp / 4)
+ return 1;
+ if (currentPp > maxPp / 2)
+ return 3;
+ }
+
+ return 0;
+}
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 8a0e32ba8..a20f47ad4 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -4504,7 +4504,7 @@ static void atk4F_jumpifcantswitch(void)
static void sub_8024398(u8 arg0)
{
*(gBattleStruct->field_58 + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler];
- BtlController_EmitChoosePokemon(0, PARTY_MUST_CHOOSE_MON, arg0, 0, gBattleStruct->field_60[gActiveBattler]);
+ BtlController_EmitChoosePokemon(0, PARTY_ACTION_SEND_OUT, arg0, 0, gBattleStruct->field_60[gActiveBattler]);
MarkBattlerForControllerExec(gActiveBattler);
}
@@ -4739,9 +4739,9 @@ static void atk50_openpartyscreen(void)
else
{
if (gBattlescriptCurrInstr[1] & OPEN_PARTY_ALLOW_CANCEL)
- hitmarkerFaintBits = PARTY_CHOOSE_MON; // Used here as the caseId for the EmitChoose function.
+ hitmarkerFaintBits = PARTY_ACTION_CHOOSE_MON; // Used here as the caseId for the EmitChoose function.
else
- hitmarkerFaintBits = PARTY_MUST_CHOOSE_MON;
+ hitmarkerFaintBits = PARTY_ACTION_SEND_OUT;
battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(OPEN_PARTY_ALLOW_CANCEL));
if (gSpecialStatuses[battlerId].flag40)
{
@@ -5831,7 +5831,7 @@ static void DrawLevelUpWindow1(void)
{
u16 currStats[NUM_STATS];
- GetMonLevelUpWindowStats(&gPlayerParty[gBattleStruct->expGetterMonId], currStats);
+ BufferMonStatsToTaskData(&gPlayerParty[gBattleStruct->expGetterMonId], currStats);
DrawLevelUpWindowPg1(12, gBattleResources->beforeLvlUp->stats, currStats, 0xE, 0xD, 0xF);
}
@@ -5839,7 +5839,7 @@ static void DrawLevelUpWindow2(void)
{
u16 currStats[NUM_STATS];
- GetMonLevelUpWindowStats(&gPlayerParty[gBattleStruct->expGetterMonId], currStats);
+ BufferMonStatsToTaskData(&gPlayerParty[gBattleStruct->expGetterMonId], currStats);
DrawLevelUpWindowPg2(12, currStats, 0xE, 0xD, 0xF);
}
@@ -7140,8 +7140,8 @@ static void atk8F_forcerandomswitch(void)
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = i;
if (!IsMultiBattle())
sub_8013F6C(gBattlerTarget);
- sub_8127EC4(gBattlerTarget, i, 0);
- sub_8127EC4(gBattlerTarget ^ 2, i, 1);
+ SwitchPartyOrderLinkMulti(gBattlerTarget, i, 0);
+ SwitchPartyOrderLinkMulti(gBattlerTarget ^ 2, i, 1);
}
}
else
diff --git a/src/berry_pouch.c b/src/berry_pouch.c
index 0ecf43b45..711a17768 100644
--- a/src/berry_pouch.c
+++ b/src/berry_pouch.c
@@ -765,7 +765,7 @@ static void PrintSelectedBerryDescription(s32 itemIdx)
static void SetDescriptionWindowBorderPalette(s32 pal)
{
- SetBgRectPal(1, 0, 16, 30, 4, pal + 1);
+ SetBgTilemapPalette(1, 0, 16, 30, 4, pal + 1);
ScheduleBgCopyTilemapToVram(1);
}
@@ -1194,7 +1194,7 @@ static void Task_BerryPouch_Give(u8 taskId)
Task_Give_PrintThereIsNoPokemon(taskId);
else
{
- sResources->exitCallback = sub_8126EDC;
+ sResources->exitCallback = CB2_ChooseMonToGiveItem;
gTasks[taskId].func = BerryPouch_StartFadeToExitCallback;
}
}
@@ -1251,7 +1251,7 @@ static void Task_ContextMenu_FromPartyGiveMenu(u8 taskId)
}
else
{
- sResources->exitCallback = c2_8123744;
+ sResources->exitCallback = CB2_GiveHoldItem;
gTasks[taskId].func = BerryPouch_StartFadeToExitCallback;
}
}
diff --git a/src/data/party_menu.h b/src/data/party_menu.h
new file mode 100644
index 000000000..fa74d1ad8
--- /dev/null
+++ b/src/data/party_menu.h
@@ -0,0 +1,1316 @@
+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, 36, 24, 8, // HP
+ 53, 36, 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,
+ {
+ // The below are the x, y, width, and height for each of the following info
+ 22, 3, 40, 13, // Nickname
+ 32, 12, 32, 8, // Level
+ 64, 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
+ },
+};
+
+static const u8 sPartyMenuSpriteCoords[PARTY_LAYOUT_COUNT][PARTY_SIZE][4 * 2] =
+{
+ [PARTY_LAYOUT_SINGLE] =
+ {
+ { 16, 40, 20, 50, 56, 52, 16, 34},
+ {104, 18, 108, 28, 144, 27, 102, 25},
+ {104, 42, 108, 52, 144, 51, 102, 49},
+ {104, 66, 108, 76, 144, 75, 102, 73},
+ {104, 90, 108, 100, 144, 99, 102, 97},
+ {104, 114, 108, 124, 144, 123, 102, 121},
+ },
+ [PARTY_LAYOUT_DOUBLE] =
+ {
+ { 16, 24, 20, 34, 56, 36, 16, 18},
+ { 16, 80, 20, 90, 56, 92, 16, 74},
+ {104, 18, 108, 28, 144, 27, 102, 25},
+ {104, 50, 108, 60, 144, 59, 102, 57},
+ {104, 82, 108, 92, 144, 91, 102, 89},
+ {104, 114, 108, 124, 144, 123, 102, 121},
+ },
+ [PARTY_LAYOUT_MULTI] =
+ {
+ { 16, 24, 20, 34, 56, 36, 16, 18},
+ { 16, 80, 20, 90, 56, 92, 16, 74},
+ {104, 26, 106, 36, 144, 35, 102, 33},
+ {104, 50, 106, 60, 144, 59, 102, 57},
+ {104, 82, 106, 92, 144, 91, 102, 89},
+ {104, 106, 106, 116, 144, 115, 102, 113},
+ },
+ [PARTY_LAYOUT_MULTI_SHOWCASE] =
+ {
+ { 16, 32, 20, 42, 56, 44, 16, 26},
+ {104, 34, 106, 44, 144, 43, 102, 41},
+ {104, 58, 106, 68, 144, 67, 102, 65},
+ { 16, 104, 20, 114, 56, 116, 16, 98},
+ {104, 106, 106, 116, 144, 115, 102, 113},
+ {104, 130, 106, 140, 144, 139, 102, 137},
+ },
+};
+
+static const u32 sConfirmButton_Tilemap[] = INCBIN_U32("graphics/interface/party_menu_confirm_button.bin");
+static const u32 sCancelButton_Tilemap[] = INCBIN_U32("graphics/interface/party_menu_cancel_button.bin");
+
+static const u8 sFontColorTable[][3] =
+{
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_LIGHT_GREY, TEXT_COLOR_DARK_GREY}, // Default
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_GREEN}, // Unused
+ {TEXT_COLOR_TRANSPARENT, TEXT_DYNAMIC_COLOR_2, TEXT_DYNAMIC_COLOR_3}, // Gender symbol
+ {TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GREY, TEXT_COLOR_LIGHT_GREY}, // Selection actions
+ {TEXT_COLOR_WHITE, TEXT_COLOR_BLUE, TEXT_COLOR_LIGHT_BLUE}, // Field moves
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GREY}, // Unused
+};
+
+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 sCancelButtonWindowTemplate =
+{
+ .bg = 0,
+ .tilemapLeft = 24,
+ .tilemapTop = 17,
+ .width = 6,
+ .height = 2,
+ .paletteNum = 3,
+ .baseBlock = 0x1C7,
+};
+
+static const struct WindowTemplate sMultiCancelButtonWindowTemplate =
+{
+ .bg = 0,
+ .tilemapLeft = 24,
+ .tilemapTop = 18,
+ .width = 6,
+ .height = 2,
+ .paletteNum = 3,
+ .baseBlock = 0x1C7,
+};
+
+static const struct WindowTemplate sConfirmButtonWindowTemplate =
+{
+ .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 = 19,
+ .height = 2,
+ .paletteNum = 15,
+ .baseBlock = 0x299,
+};
+
+static const struct WindowTemplate sDoWhatWithMailMsgWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 1,
+ .tilemapTop = 17,
+ .width = 16,
+ .height = 2,
+ .paletteNum = 15,
+ .baseBlock = 0x299,
+};
+
+static const struct WindowTemplate sWhichMoveMsgWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 1,
+ .tilemapTop = 17,
+ .width = 15,
+ .height = 2,
+ .paletteNum = 15,
+ .baseBlock = 0x299,
+};
+
+static const struct WindowTemplate sItemGiveTakeWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 22,
+ .tilemapTop = 13,
+ .width = 7,
+ .height = 6,
+ .paletteNum = 14,
+ .baseBlock = 0x373,
+};
+
+static const struct WindowTemplate sMailReadTakeWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 19,
+ .tilemapTop = 13,
+ .width = 10,
+ .height = 6,
+ .paletteNum = 14,
+ .baseBlock = 0x373,
+};
+
+static const struct WindowTemplate sMoveSelectWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 18,
+ .tilemapTop = 11,
+ .width = 11,
+ .height = 8,
+ .paletteNum = 14,
+ .baseBlock = 0x2BF,
+};
+
+static const struct WindowTemplate sPartyMenuYesNoWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 21,
+ .tilemapTop = 9,
+ .width = 6,
+ .height = 4,
+ .paletteNum = 14,
+ .baseBlock = 0x2BF,
+};
+
+static const struct WindowTemplate sLevelUpStatsWindowTemplate =
+{
+ .bg = 2,
+ .tilemapLeft = 19,
+ .tilemapTop = 1,
+ .width = 10,
+ .height = 11,
+ .paletteNum = 14,
+ .baseBlock = 0x2BF,
+};
+
+static const struct WindowTemplate gUnknown_845A170 =
+{
+ .bg = 2,
+ .tilemapLeft = 2,
+ .tilemapTop = 15,
+ .width = 26,
+ .height = 4,
+ .paletteNum = 14,
+ .baseBlock = 0x1DF,
+};
+
+static const struct WindowTemplate gUnknown_845A178 =
+{
+ .bg = 2,
+ .tilemapLeft = 0,
+ .tilemapTop = 13,
+ .width = 18,
+ .height = 3,
+ .paletteNum = 12,
+ .baseBlock = 0x373,
+};
+
+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,
+};
+
+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 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 *const sActionStringTable[] =
+{
+ [PARTY_MSG_CHOOSE_MON] = gText_ChoosePokemon,
+ [PARTY_MSG_CHOOSE_MON_OR_CANCEL] = gText_ChoosePokemonCancel,
+ [PARTY_MSG_CHOOSE_MON_AND_CONFIRM] = gText_ChoosePokemonConfirm,
+ [PARTY_MSG_MOVE_TO_WHERE] = gText_MoveToWhere,
+ [PARTY_MSG_TEACH_WHICH_MON] = gText_TeachWhichPokemon,
+ [PARTY_MSG_USE_ON_WHICH_MON] = gText_UseOnWhichPokemon,
+ [PARTY_MSG_GIVE_TO_WHICH_MON] = gText_GiveToWhichPokemon,
+ [PARTY_MSG_NOTHING_TO_CUT] = gText_NothingToCut,
+ [PARTY_MSG_CANT_SURF_HERE] = gText_CantSurfHere,
+ [PARTY_MSG_ALREADY_SURFING] = gText_AlreadySurfing,
+ [PARTY_MSG_CURRENT_TOO_FAST] = gText_CurrentIsTooFast,
+ [PARTY_MSG_ENJOY_CYCLING] = gText_EnjoyCycling,
+ [PARTY_MSG_ALREADY_IN_USE] = gText_InUseAlready_PM,
+ [PARTY_MSG_CANT_USE_HERE] = gText_CantUseHere,
+ [PARTY_MSG_NO_MON_FOR_BATTLE] = gText_NoPokemonForBattle,
+ [PARTY_MSG_CHOOSE_MON_2] = gText_ChoosePokemon2,
+ [PARTY_MSG_NOT_ENOUGH_HP] = gText_NotEnoughHp,
+ [PARTY_MSG_THREE_MONS_ARE_NEEDED] = gText_ThreePkmnAreNeeded,
+ [PARTY_MSG_TWO_MONS_ARE_NEEDED] = gText_TwoPokemonAreNeeded,
+ [PARTY_MSG_MONS_CANT_BE_SAME] = gText_PokemonCantBeSame,
+ [PARTY_MSG_NO_SAME_HOLD_ITEMS] = gText_NoIdenticalHoldItems,
+ [PARTY_MSG_UNUSED] = gString_Dummy,
+ [PARTY_MSG_DO_WHAT_WITH_MON] = gText_DoWhatWithPokemon,
+ [PARTY_MSG_RESTORE_WHICH_MOVE] = gText_RestoreWhichMove,
+ [PARTY_MSG_BOOST_PP_WHICH_MOVE] = gText_BoostPp,
+ [PARTY_MSG_DO_WHAT_WITH_ITEM] = gText_DoWhatWithItem,
+ [PARTY_MSG_DO_WHAT_WITH_MAIL] = gText_DoWhatWithMail,
+};
+
+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_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,
+};
+
+static const u8 *const sHMDescriptionTable[] =
+{
+ gText_LightUpDarkness,
+ gText_CutATreeOrGrass,
+ gText_FlyToAKnownTown,
+ gText_MoveHeavyBoulders,
+ gText_TravelOnWater,
+ gText_ShatterACrackedRock,
+ gText_ClimbAWaterfall,
+ gText_ReturnToAHealingSpot,
+ gText_EscapeFromHere,
+ gText_ShareHp,
+ gText_ShareHp,
+ gText_LureWildPokemon,
+};
+
+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_MenuPokeball[] =
+{
+ sPokeballAnim_Closed,
+ sPokeballAnim_Open,
+};
+
+static const struct CompressedSpriteSheet sSpriteSheet_MenuPokeball =
+{
+ gPartyMenuPokeball_Gfx, 0x400, 0x04b0
+};
+
+static const struct CompressedSpritePalette sSpritePalette_MenuPokeball =
+{
+ gPartyMenuPokeball_Pal, 0x04b0
+};
+
+// Used for the pokeball sprite on each party slot / Cancel button
+static const struct SpriteTemplate sSpriteTemplate_MenuPokeball =
+{
+ .tileTag = 0x04b0,
+ .paletteTag = 0x04b0,
+ .oam = &sOamData_MenuPokeball,
+ .anims = sSpriteAnimTable_MenuPokeball,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const struct OamData sOamData_MenuPokeballSmall =
+{
+ .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 sSmallPokeballAnim_Closed[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSmallPokeballAnim_Open[] =
+{
+ ANIMCMD_FRAME(4, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSmallPokeballAnim_Blank1[] =
+{
+ ANIMCMD_FRAME(8, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSmallPokeballAnim_Blank2[] =
+{
+ ANIMCMD_FRAME(12, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSmallPokeballAnim_Blank3[] =
+{
+ ANIMCMD_FRAME(16, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSmallPokeballAnim_Blank4[] =
+{
+ ANIMCMD_FRAME(20, 0),
+ ANIMCMD_END
+};
+
+// The blanks below are never used. See SpriteCB_BounceConfirmCancelButton, where they were intended to be used
+static const union AnimCmd *const sSpriteAnimTable_MenuPokeballSmall[] =
+{
+ sSmallPokeballAnim_Closed,
+ sSmallPokeballAnim_Open,
+ sSmallPokeballAnim_Blank1,
+ sSmallPokeballAnim_Blank2,
+ sSmallPokeballAnim_Blank3,
+ sSmallPokeballAnim_Blank4,
+};
+
+static const struct CompressedSpriteSheet sSpriteSheet_MenuPokeballSmall =
+{
+ gPartyMenuPokeballSmall_Gfx, 0x0300, 0x04b1
+};
+
+// Used for the pokeball sprite next to Cancel and Confirm when both are present, otherwise sSpriteTemplate_MenuPokeball is used
+static const struct SpriteTemplate sSpriteTemplate_MenuPokeballSmall =
+{
+ .tileTag = 1201,
+ .paletteTag = 1200,
+ .oam = &sOamData_MenuPokeballSmall,
+ .anims = sSpriteAnimTable_MenuPokeballSmall,
+ .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,
+};
+
+static const bool8 sMultiBattlePartnersPartyMask[PARTY_SIZE + 2] =
+{
+ FALSE,
+ TRUE,
+ FALSE,
+ FALSE,
+ TRUE,
+ TRUE,
+ FALSE,
+};
+
+static const u16 sTMHMMoves_Duplicate[] =
+{
+ 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,
+};
+
+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_FIELD_MOVES,
+};
+
+enum
+{
+ FIELD_MOVE_FLASH,
+ FIELD_MOVE_CUT,
+ FIELD_MOVE_FLY,
+ FIELD_MOVE_STRENGTH,
+ FIELD_MOVE_SURF,
+ FIELD_MOVE_ROCK_SMASH,
+ FIELD_MOVE_WATERFALL,
+ FIELD_MOVE_TELEPORT,
+ FIELD_MOVE_DIG,
+ FIELD_MOVE_MILK_DRINK,
+ FIELD_MOVE_SOFT_BOILED,
+ FIELD_MOVE_SWEET_SCENT,
+ FIELD_MOVE_END,
+};
+
+static struct
+{
+ const u8 *text;
+ TaskFunc func;
+} const sCursorOptions[] =
+{
+ [MENU_SUMMARY] = {gText_Summary5, CursorCB_Summary},
+ [MENU_SWITCH] = {gText_Switch2, CursorCB_Switch},
+ [MENU_CANCEL1] = {gFameCheckerText_Cancel, CursorCB_Cancel1},
+ [MENU_ITEM] = {gText_Item, CursorCB_Item},
+ [MENU_GIVE] = {gOtherText_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] = {gFameCheckerText_Cancel, 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_FIELD_MOVES + FIELD_MOVE_FLASH] = {gMoveNames[MOVE_FLASH], CursorCB_FieldMove},
+ [MENU_FIELD_MOVES + FIELD_MOVE_CUT] = {gMoveNames[MOVE_CUT], CursorCB_FieldMove},
+ [MENU_FIELD_MOVES + FIELD_MOVE_FLY] = {gMoveNames[MOVE_FLY], 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_ROCK_SMASH] = {gMoveNames[MOVE_ROCK_SMASH], 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_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};
+
+// 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,
+};
+
+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,
+};
+
+static const u8 sPartyMenuActionCounts[] =
+{
+ [ACTIONS_NONE] = 0,
+ [ACTIONS_SWITCH] = NELEMS(sPartyMenuAction_SummarySwitchCancel),
+ [ACTIONS_SHIFT] = NELEMS(sPartyMenuAction_ShiftSummaryCancel),
+ [ACTIONS_SEND_OUT] = NELEMS(sPartyMenuAction_SendOutSummaryCancel),
+ [ACTIONS_ENTER] = NELEMS(sPartyMenuAction_EnterSummaryCancel),
+ [ACTIONS_NO_ENTRY] = NELEMS(sPartyMenuAction_NoEntrySummaryCancel),
+ [ACTIONS_STORE] = NELEMS(sPartyMenuAction_StoreSummaryCancel),
+ [ACTIONS_SUMMARY_ONLY] = NELEMS(sPartyMenuAction_SummaryCancel),
+ [ACTIONS_ITEM] = NELEMS(sPartyMenuAction_GiveTakeItemCancel),
+ [ACTIONS_MAIL] = NELEMS(sPartyMenuAction_ReadTakeMailCancel),
+ [ACTIONS_REGISTER] = NELEMS(sPartyMenuAction_RegisterSummaryCancel),
+ [ACTIONS_TRADE] = NELEMS(sPartyMenuAction_TradeSummaryCancel1),
+ [ACTIONS_SPIN_TRADE] = NELEMS(sPartyMenuAction_TradeSummaryCancel2),
+};
+
+static const u16 sFieldMoves[] =
+{
+ MOVE_FLASH, MOVE_CUT, MOVE_FLY, MOVE_STRENGTH, MOVE_SURF, MOVE_ROCK_SMASH, MOVE_WATERFALL, MOVE_TELEPORT,
+ MOVE_DIG, MOVE_MILK_DRINK, MOVE_SOFT_BOILED, MOVE_SWEET_SCENT, FIELD_MOVE_END // this may be misuse of enum. same in emerald
+};
+
+static struct
+{
+ bool8 (*fieldMoveFunc)(void);
+ u8 msgId;
+} const sFieldMoveCursorCallbacks[] =
+{
+ [FIELD_MOVE_FLASH] = {SetUpFieldMove_Flash, PARTY_MSG_CANT_USE_HERE},
+ [FIELD_MOVE_CUT] = {SetUpFieldMove_Cut, PARTY_MSG_NOTHING_TO_CUT},
+ [FIELD_MOVE_FLY] = {SetUpFieldMove_Fly, 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_ROCK_SMASH] = {SetUpFieldMove_RockSmash, 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_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 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,
+};
diff --git a/src/data/pokemon/tutor_learnsets.h b/src/data/pokemon/tutor_learnsets.h
new file mode 100644
index 000000000..5396c1ecc
--- /dev/null
+++ b/src/data/pokemon/tutor_learnsets.h
@@ -0,0 +1,2813 @@
+static const u16 sTutorMoves[TUTOR_MOVE_COUNT] =
+{
+ [TUTOR_MOVE_MEGA_PUNCH] = MOVE_MEGA_PUNCH,
+ [TUTOR_MOVE_SWORDS_DANCE] = MOVE_SWORDS_DANCE,
+ [TUTOR_MOVE_MEGA_KICK] = MOVE_MEGA_KICK,
+ [TUTOR_MOVE_BODY_SLAM] = MOVE_BODY_SLAM,
+ [TUTOR_MOVE_DOUBLE_EDGE] = MOVE_DOUBLE_EDGE,
+ [TUTOR_MOVE_COUNTER] = MOVE_COUNTER,
+ [TUTOR_MOVE_SEISMIC_TOSS] = MOVE_SEISMIC_TOSS,
+ [TUTOR_MOVE_MIMIC] = MOVE_MIMIC,
+ [TUTOR_MOVE_METRONOME] = MOVE_METRONOME,
+ [TUTOR_MOVE_SOFT_BOILED] = MOVE_SOFT_BOILED,
+ [TUTOR_MOVE_DREAM_EATER] = MOVE_DREAM_EATER,
+ [TUTOR_MOVE_THUNDER_WAVE] = MOVE_THUNDER_WAVE,
+ [TUTOR_MOVE_EXPLOSION] = MOVE_EXPLOSION,
+ [TUTOR_MOVE_ROCK_SLIDE] = MOVE_ROCK_SLIDE,
+ [TUTOR_MOVE_SUBSTITUTE] = MOVE_SUBSTITUTE,
+};
+
+#define TUTOR(move) (1 << (TUTOR_##move))
+
+static const u16 sTutorLearnsets[] =
+{
+ [SPECIES_NONE] = 0,
+
+ [SPECIES_BULBASAUR] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_IVYSAUR] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VENUSAUR] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHARMANDER] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHARMELEON] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHARIZARD] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SQUIRTLE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WARTORTLE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BLASTOISE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CATERPIE] = 0,
+
+ [SPECIES_METAPOD] = 0,
+
+ [SPECIES_BUTTERFREE] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WEEDLE] = 0,
+
+ [SPECIES_KAKUNA] = 0,
+
+ [SPECIES_BEEDRILL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PIDGEY] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PIDGEOTTO] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PIDGEOT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RATTATA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RATICATE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SPEAROW] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FEAROW] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_EKANS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ARBOK] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PIKACHU] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RAICHU] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SANDSHREW] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SANDSLASH] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NIDORAN_F] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NIDORINA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NIDOQUEEN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NIDORAN_M] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NIDORINO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NIDOKING] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CLEFAIRY] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CLEFABLE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VULPIX] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NINETALES] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_JIGGLYPUFF] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WIGGLYTUFF] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ZUBAT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GOLBAT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ODDISH] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GLOOM] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VILEPLUME] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PARAS] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PARASECT] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VENONAT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VENOMOTH] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DIGLETT] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DUGTRIO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MEOWTH] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PERSIAN] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PSYDUCK] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GOLDUCK] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MANKEY] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PRIMEAPE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GROWLITHE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ARCANINE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_POLIWAG] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_POLIWHIRL] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_POLIWRATH] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ABRA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KADABRA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ALAKAZAM] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MACHOP] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MACHOKE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MACHAMP] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BELLSPROUT] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WEEPINBELL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VICTREEBEL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TENTACOOL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TENTACRUEL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GEODUDE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GRAVELER] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GOLEM] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PONYTA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RAPIDASH] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SLOWPOKE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SLOWBRO] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAGNEMITE] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAGNETON] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FARFETCHD] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DODUO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DODRIO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SEEL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DEWGONG] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GRIMER] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MUK] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHELLDER] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CLOYSTER] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GASTLY] = TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HAUNTER] = TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GENGAR] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ONIX] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DROWZEE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HYPNO] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KRABBY] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KINGLER] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VOLTORB] = TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ELECTRODE] = TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_EXEGGCUTE] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_EXEGGUTOR] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CUBONE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAROWAK] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HITMONLEE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HITMONCHAN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LICKITUNG] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KOFFING] = TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WEEZING] = TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RHYHORN] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RHYDON] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHANSEY] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TANGELA] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KANGASKHAN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HORSEA] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SEADRA] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GOLDEEN] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SEAKING] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_STARYU] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_STARMIE] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MR_MIME] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SCYTHER] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_JYNX] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ELECTABUZZ] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAGMAR] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PINSIR] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TAUROS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAGIKARP] = 0,
+
+ [SPECIES_GYARADOS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LAPRAS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DITTO] = 0,
+
+ [SPECIES_EEVEE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VAPOREON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_JOLTEON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FLAREON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PORYGON] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_OMANYTE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_OMASTAR] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KABUTO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KABUTOPS] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_AERODACTYL] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SNORLAX] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ARTICUNO] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ZAPDOS] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MOLTRES] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DRATINI] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DRAGONAIR] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DRAGONITE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MEWTWO] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MEW] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHIKORITA] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BAYLEEF] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MEGANIUM] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CYNDAQUIL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_QUILAVA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TYPHLOSION] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TOTODILE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CROCONAW] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FERALIGATR] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SENTRET] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FURRET] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HOOTHOOT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NOCTOWL] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LEDYBA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LEDIAN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SPINARAK] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ARIADOS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CROBAT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHINCHOU] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LANTURN] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PICHU] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CLEFFA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_IGGLYBUFF] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TOGEPI] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TOGETIC] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NATU] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_XATU] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAREEP] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FLAAFFY] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_AMPHAROS] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BELLOSSOM] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MARILL] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_AZUMARILL] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SUDOWOODO] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_POLITOED] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HOPPIP] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SKIPLOOM] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_JUMPLUFF] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_AIPOM] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SUNKERN] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SUNFLORA] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_YANMA] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WOOPER] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_QUAGSIRE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ESPEON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_UMBREON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MURKROW] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SLOWKING] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MISDREAVUS] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_UNOWN] = 0,
+
+ [SPECIES_WOBBUFFET] = 0,
+
+ [SPECIES_GIRAFARIG] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PINECO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FORRETRESS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DUNSPARCE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GLIGAR] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_STEELIX] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SNUBBULL] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GRANBULL] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_QWILFISH] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SCIZOR] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHUCKLE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HERACROSS] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SNEASEL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TEDDIURSA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_URSARING] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SLUGMA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAGCARGO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SWINUB] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PILOSWINE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CORSOLA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_REMORAID] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_OCTILLERY] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DELIBIRD] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MANTINE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SKARMORY] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HOUNDOUR] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HOUNDOOM] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KINGDRA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PHANPY] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DONPHAN] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PORYGON2] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_STANTLER] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SMEARGLE] = 0,
+
+ [SPECIES_TYROGUE] = TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HITMONTOP] = TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SMOOCHUM] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ELEKID] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAGBY] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MILTANK] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BLISSEY] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SOFT_BOILED)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RAIKOU] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ENTEI] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SUICUNE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LARVITAR] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PUPITAR] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TYRANITAR] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LUGIA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HO_OH] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CELEBI] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TREECKO] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GROVYLE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SCEPTILE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TORCHIC] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_COMBUSKEN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BLAZIKEN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MUDKIP] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MARSHTOMP] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SWAMPERT] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_POOCHYENA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MIGHTYENA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ZIGZAGOON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LINOONE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WURMPLE] = 0,
+
+ [SPECIES_SILCOON] = 0,
+
+ [SPECIES_BEAUTIFLY] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CASCOON] = 0,
+
+ [SPECIES_DUSTOX] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LOTAD] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LOMBRE] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LUDICOLO] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SEEDOT] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NUZLEAF] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHIFTRY] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NINCADA] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NINJASK] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHEDINJA] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TAILLOW] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SWELLOW] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHROOMISH] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BRELOOM] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SPINDA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WINGULL] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PELIPPER] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SURSKIT] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MASQUERAIN] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WAILMER] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WAILORD] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SKITTY] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DELCATTY] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KECLEON] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BALTOY] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CLAYDOL] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NOSEPASS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TORKOAL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SABLEYE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BARBOACH] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WHISCASH] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LUVDISC] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CORPHISH] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CRAWDAUNT] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FEEBAS] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MILOTIC] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CARVANHA] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHARPEDO] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TRAPINCH] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VIBRAVA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_FLYGON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAKUHITA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HARIYAMA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ELECTRIKE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MANECTRIC] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_NUMEL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CAMERUPT] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SPHEAL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SEALEO] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WALREIN] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CACNEA] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CACTURNE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SNORUNT] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GLALIE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LUNATONE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SOLROCK] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_AZURILL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SPOINK] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GRUMPIG] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_PLUSLE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MINUN] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MAWILE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MEDITITE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_MEDICHAM] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SWABLU] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ALTARIA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WYNAUT] = 0,
+
+ [SPECIES_DUSKULL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DUSCLOPS] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ROSELIA] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SLAKOTH] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VIGOROTH] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SLAKING] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GULPIN] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SWALOT] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_TROPIUS] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_WHISMUR] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LOUDRED] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_EXPLOUD] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CLAMPERL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_HUNTAIL] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GOREBYSS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ABSOL] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHUPPET] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BANETTE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SEVIPER] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ZANGOOSE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RELICANTH] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ARON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LAIRON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_AGGRON] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CASTFORM] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_VOLBEAT] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ILLUMISE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LILEEP] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CRADILY] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ANORITH] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_ARMALDO] = TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RALTS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KIRLIA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GARDEVOIR] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BAGON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SHELGON] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_SALAMENCE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_BELDUM] = 0,
+
+ [SPECIES_METANG] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_METAGROSS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_REGIROCK] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_REGICE] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_REGISTEEL] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_EXPLOSION)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_KYOGRE] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_GROUDON] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_SWORDS_DANCE)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_RAYQUAZA] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LATIAS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_LATIOS] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_JIRACHI] = TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_METRONOME)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_DEOXYS] = TUTOR(MOVE_MEGA_PUNCH)
+ | TUTOR(MOVE_MEGA_KICK)
+ | TUTOR(MOVE_BODY_SLAM)
+ | TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_COUNTER)
+ | TUTOR(MOVE_SEISMIC_TOSS)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_THUNDER_WAVE)
+ | TUTOR(MOVE_ROCK_SLIDE)
+ | TUTOR(MOVE_SUBSTITUTE),
+
+ [SPECIES_CHIMECHO] = TUTOR(MOVE_DOUBLE_EDGE)
+ | TUTOR(MOVE_MIMIC)
+ | TUTOR(MOVE_DREAM_EATER)
+ | TUTOR(MOVE_SUBSTITUTE),
+};
diff --git a/src/daycare.c b/src/daycare.c
index f034bc220..8862dfda9 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -1582,7 +1582,7 @@ void ShowDaycareLevelMenu(void)
void ChooseSendDaycareMon(void)
{
- sub_8128370();
+ ChooseMonForDaycare();
gMain.savedCallback = CB2_ReturnToField;
}
diff --git a/src/field_fadetransition.c b/src/field_fadetransition.c
index 58caad509..d6bf4ea07 100644
--- a/src/field_fadetransition.c
+++ b/src/field_fadetransition.c
@@ -522,7 +522,7 @@ static bool32 sub_807E40C(void)
bool32 sub_807E418(void)
{
- if (field_weather_is_fade_finished() == TRUE && sub_80F83B0())
+ if (IsWeatherNotFadingIn() == TRUE && sub_80F83B0())
return TRUE;
else
return FALSE;
diff --git a/src/field_poison.c b/src/field_poison.c
index 474fbcd69..07c2b763f 100644
--- a/src/field_poison.c
+++ b/src/field_poison.c
@@ -43,7 +43,7 @@ static void FaintFromFieldPoison(u8 partyIdx)
static bool32 MonFaintedFromPoison(u8 partyIdx)
{
struct Pokemon *pokemon = gPlayerParty + partyIdx;
- if (IsMonValidSpecies(pokemon) && !GetMonData(pokemon, MON_DATA_HP) && pokemon_ailments_get_primary(GetMonData(pokemon, MON_DATA_STATUS)) == AILMENT_PSN)
+ if (IsMonValidSpecies(pokemon) && !GetMonData(pokemon, MON_DATA_HP) && GetAilmentFromStatus(GetMonData(pokemon, MON_DATA_STATUS)) == AILMENT_PSN)
return TRUE;
return FALSE;
}
@@ -97,7 +97,7 @@ s32 DoPoisonFieldEffect(void)
u32 numFainted = 0;
for (i = 0; i < PARTY_SIZE; i++)
{
- if (GetMonData(pokemon, MON_DATA_SANITY_HAS_SPECIES) && pokemon_ailments_get_primary(GetMonData(pokemon, MON_DATA_STATUS)) == AILMENT_PSN)
+ if (GetMonData(pokemon, MON_DATA_SANITY_HAS_SPECIES) && GetAilmentFromStatus(GetMonData(pokemon, MON_DATA_STATUS)) == AILMENT_PSN)
{
hp = GetMonData(pokemon, MON_DATA_HP);
if (hp == 0 || --hp == 0)
diff --git a/src/field_specials.c b/src/field_specials.c
index 617faa017..374c74f3c 100644
--- a/src/field_specials.c
+++ b/src/field_specials.c
@@ -1863,7 +1863,7 @@ void sub_80CC59C(void)
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE22) && (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE22) || gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE23)))
{
- sp0.unk0 = get_mapheader_by_bank_and_number(sInsideOutsidePairs[r5].grp, sInsideOutsidePairs[r5].num)->regionMapSectionId;
+ sp0.unk0 = Overworld_GetMapHeaderByGroupAndId(sInsideOutsidePairs[r5].grp, sInsideOutsidePairs[r5].num)->regionMapSectionId;
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE22))
sp0.unk1 = r5;
else
@@ -1875,7 +1875,7 @@ void sub_80CC59C(void)
}
if (gSaveBlock1Ptr->location.mapGroup == sInsideOutsidePairs[r5].grp2 && gSaveBlock1Ptr->location.mapNum == sInsideOutsidePairs[r5].num2)
{
- sp0.unk0 = get_mapheader_by_bank_and_number(sInsideOutsidePairs[r5].grp, sInsideOutsidePairs[r5].num)->regionMapSectionId;
+ sp0.unk0 = Overworld_GetMapHeaderByGroupAndId(sInsideOutsidePairs[r5].grp, sInsideOutsidePairs[r5].num)->regionMapSectionId;
sp0.unk1 = r5;
if (r5 == 22)
{
diff --git a/src/fieldmap.c b/src/fieldmap.c
index 000b8105b..e5901c149 100644
--- a/src/fieldmap.c
+++ b/src/fieldmap.c
@@ -60,7 +60,7 @@ const u8 gUnknown_8352F10[] = {
const struct MapHeader * mapconnection_get_mapheader(struct MapConnection * connection)
{
- return get_mapheader_by_bank_and_number(connection->mapGroup, connection->mapNum);
+ return Overworld_GetMapHeaderByGroupAndId(connection->mapGroup, connection->mapNum);
}
void not_trainer_hill_battle_pyramid(void)
@@ -463,7 +463,7 @@ u32 MapGridGetMetatileBehaviorAt(s32 x, s32 y)
return sub_8058F48(x, y, 0);
}
-u8 MapGridGetMetatileLayerTypeAt(s32 x, s32 y)
+u8 MapGridGetMetatileLayerTypeAt(s16 x, s16 y)
{
return sub_8058F48(x, y, 6);
}
diff --git a/src/fldeff_softboiled.c b/src/fldeff_softboiled.c
index 400a1d382..60437c125 100644
--- a/src/fldeff_softboiled.c
+++ b/src/fldeff_softboiled.c
@@ -13,9 +13,9 @@ static void sub_80E58A0(u8 taskId);
static void sub_80E5934(u8 taskId);
extern const u8 gUnknown_84169F8[];
-extern const u8 gUnknown_8416F27[];
+extern const u8 gText_PkmnHPRestoredByVar2[];
-bool8 hm_prepare_dive_probably(void)
+bool8 SetUpFieldMove_SoftBoiled(void)
{
u16 maxHp = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_MAX_HP);
u16 curHp = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_HP);
@@ -26,27 +26,27 @@ bool8 hm_prepare_dive_probably(void)
return FALSE;
}
-void sub_80E56DC(u8 taskId)
+void ChooseMonForSoftboiled(u8 taskId)
{
- gUnknown_203B0A0.unkB = 10;
- gUnknown_203B0A0.unkA = gUnknown_203B0A0.unk9;
- sub_811F818(GetCursorSelectionMonId(), 1);
- sub_8121D0C(5);
- gTasks[taskId].func = sub_811FB28;
+ gPartyMenu.action = 10;
+ gPartyMenu.slotId2 = gPartyMenu.slotId;
+ AnimatePartySlot(GetCursorSelectionMonId(), 1);
+ DisplayPartyMenuStdMessage(5);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
}
-void sub_80E5724(u8 taskId)
+void Task_TryUseSoftboiledOnPartyMon(u8 taskId)
{
- u8 r8 = gUnknown_203B0A0.unk9;
- u8 r5 = gUnknown_203B0A0.unkA;
+ u8 r8 = gPartyMenu.slotId;
+ u8 r5 = gPartyMenu.slotId2;
u16 curHp;
s16 delta;
if (r5 > 6)
{
- gUnknown_203B0A0.unkB = 0;
- sub_8121D0C(0);
- gTasks[taskId].func = sub_811FB28;
+ gPartyMenu.action = 0;
+ DisplayPartyMenuStdMessage(0);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
}
else
{
@@ -58,7 +58,7 @@ void sub_80E5724(u8 taskId)
else
{
PlaySE(SE_KAIFUKU);
- sub_8120760(taskId, r8, -1, GetMonData(&gPlayerParty[r8], MON_DATA_MAX_HP) / 5, sub_80E57E8);
+ PartyMenuModifyHP(taskId, r8, -1, GetMonData(&gPlayerParty[r8], MON_DATA_MAX_HP) / 5, sub_80E57E8);
}
}
}
@@ -66,46 +66,46 @@ void sub_80E5724(u8 taskId)
static void sub_80E57E8(u8 taskId)
{
PlaySE(SE_KAIFUKU);
- sub_8120760(taskId, gUnknown_203B0A0.unkA, 1, GetMonData(&gPlayerParty[gUnknown_203B0A0.unk9], MON_DATA_MAX_HP) / 5, sub_80E583C);
+ PartyMenuModifyHP(taskId, gPartyMenu.slotId2, 1, GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_MAX_HP) / 5, sub_80E583C);
}
static void sub_80E583C(u8 taskId)
{
- GetMonNickname(&gPlayerParty[gUnknown_203B0A0.unkA], gStringVar1);
- StringExpandPlaceholders(gStringVar4, gUnknown_8416F27);
- sub_81202F8(gStringVar4, 0);
+ GetMonNickname(&gPlayerParty[gPartyMenu.slotId2], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2);
+ DisplayPartyMenuMessage(gStringVar4, 0);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = sub_80E58A0;
}
static void sub_80E58A0(u8 taskId)
{
- if (sub_8120370() != TRUE)
+ if (IsPartyMenuTextPrinterActive() != TRUE)
{
- gUnknown_203B0A0.unkB = 0;
- sub_811F818(gUnknown_203B0A0.unk9, 0);
- gUnknown_203B0A0.unk9 = gUnknown_203B0A0.unkA;
- sub_811F818(gUnknown_203B0A0.unkA, 1);
+ gPartyMenu.action = 0;
+ AnimatePartySlot(gPartyMenu.slotId, 0);
+ gPartyMenu.slotId = gPartyMenu.slotId2;
+ AnimatePartySlot(gPartyMenu.slotId2, 1);
ClearStdWindowAndFrameToTransparent(6, 0);
ClearWindowTilemap(6);
- sub_8121D0C(0);
- gTasks[taskId].func = sub_811FB28;
+ DisplayPartyMenuStdMessage(0);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
}
}
static void sub_80E5900(u8 taskId)
{
- if (sub_8120370() != TRUE)
+ if (IsPartyMenuTextPrinterActive() != TRUE)
{
- sub_8121D0C(5);
- gTasks[taskId].func = sub_811FB28;
+ DisplayPartyMenuStdMessage(5);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
}
}
static void sub_80E5934(u8 taskId)
{
PlaySE(SE_SELECT);
- sub_81202F8(gUnknown_84169F8, 0);
+ DisplayPartyMenuMessage(gUnknown_84169F8, 0);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = sub_80E5900;
}
diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c
index 114bf0b57..943d8504c 100644
--- a/src/fldeff_sweetscent.c
+++ b/src/fldeff_sweetscent.c
@@ -13,6 +13,8 @@
#include "wild_encounter.h"
#include "constants/songs.h"
+static EWRAM_DATA u8 *gUnknown_203AAB0 = NULL;
+
static void FieldCallback_SweetScent(void);
static void StartSweetScentFieldEffect(void);
static void TrySweetScentEncounter(u8 taskId);
@@ -20,7 +22,7 @@ static void FailSweetScentEncounter(u8 taskId);
static void Unused_StartSweetscentFldeff(void)
{
- gUnknown_203B0A0.unk9 = 0;
+ gPartyMenu.slotId = 0;
FieldCallback_SweetScent();
}
diff --git a/src/item.c b/src/item.c
index 677c13ad7..e16d5055c 100644
--- a/src/item.c
+++ b/src/item.c
@@ -412,7 +412,7 @@ bool8 AddPCItem(u16 itemId, u16 count)
return TRUE;
}
-void RemoveItemFromPC(u16 itemId, u16 count)
+void RemovePCItem(u16 itemId, u16 count)
{
u32 i;
u16 quantity;
diff --git a/src/item_pc.c b/src/item_pc.c
index 60a74ac59..3e0c50b60 100644
--- a/src/item_pc.c
+++ b/src/item_pc.c
@@ -709,7 +709,7 @@ static void ItemPc_SetScrollPosition(void)
static void ItemPc_SetMessageWindowPalette(int a0)
{
- SetBgRectPal(1, 0, 14, 30, 6, a0 + 1);
+ SetBgTilemapPalette(1, 0, 14, 30, 6, a0 + 1);
ScheduleBgCopyTilemapToVram(1);
}
@@ -926,7 +926,7 @@ static void Task_ItemPcWaitButtonAndFinishWithdrawMultiple(u8 taskId)
{
PlaySE(SE_SELECT);
itemId = ItemPc_GetItemIdBySlotId(data[1]);
- RemoveItemFromPC(itemId, data[8]);
+ RemovePCItem(itemId, data[8]);
ItemPcCompaction();
Task_ItemPcCleanUpWithdraw(taskId);
}
@@ -1029,8 +1029,8 @@ static void Task_ItemPcGive(u8 taskId)
static void ItemPc_CB2_SwitchToPartyMenu(void)
{
- PartyMenuInit(0, 0, 6, 0, 6, sub_811FB28, ItemPc_CB2_ReturnFromPartyMenu);
- gUnknown_203B0A0.unkC = ItemPc_GetItemIdBySlotId(ItemPc_GetCursorPosition());
+ InitPartyMenu(0, 0, 6, 0, 6, Task_HandleChooseMonInput, ItemPc_CB2_ReturnFromPartyMenu);
+ gPartyMenu.bagItem = ItemPc_GetItemIdBySlotId(ItemPc_GetCursorPosition());
}
static void ItemPc_CB2_ReturnFromPartyMenu(void)
diff --git a/src/item_use.c b/src/item_use.c
index db0475370..256711463 100644
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -44,37 +44,36 @@
#include "constants/songs.h"
#include "constants/map_types.h"
-EWRAM_DATA void (*sItemUseOnFieldCB)(u8 taskId) = NULL;
-
-void sub_80A1084(void);
-void sub_80A109C(u8 taskId);
-void sub_80A112C(u8 taskId);
-void sub_80A11C0(u8 taskId);
-bool8 sub_80A1194(void);
-void sub_80A1208(void);
-void ItemUseOnFieldCB_Bicycle(u8 taskId);
-bool8 ItemUseCheckFunc_Rod(void);
-void ItemUseOnFieldCB_Rod(u8 taskId);
-void FieldUseFunc_EvoItem(u8 taskId);
-void sub_80A1648(u8 taskId);
-void sub_80A1674(u8 taskId);
-void InitTMCaseFromBag(void);
-void Task_InitTMCaseFromField(u8 taskId);
-void InitBerryPouchFromBag(void);
-void Task_InitBerryPouchFromField(u8 taskId);
-void InitBerryPouchFromBattle(void);
-void InitTeachyTvFromBag(void);
-void Task_InitTeachyTvFromField(u8 taskId);
-void sub_80A19E8(u8 taskId);
-void sub_80A1A44(void);
-void sub_80A1B48(u8 taskId);
-void sub_80A1C08(u8 taskId);
-void sub_80A1CAC(void);
-void sub_80A1CC0(u8 taskId);
-void sub_80A1D58(void);
-void sub_80A1D68(u8 taskId);
-void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId);
-void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId);
+static EWRAM_DATA void (*sItemUseOnFieldCB)(u8 taskId) = NULL;
+
+static void sub_80A1084(void);
+static void sub_80A109C(u8 taskId);
+static void sub_80A112C(u8 taskId);
+static void sub_80A11C0(u8 taskId);
+static bool8 sub_80A1194(void);
+static void sub_80A1208(void);
+static void ItemUseOnFieldCB_Bicycle(u8 taskId);
+static bool8 ItemUseCheckFunc_Rod(void);
+static void ItemUseOnFieldCB_Rod(u8 taskId);
+static void sub_80A1648(u8 taskId);
+static void sub_80A1674(u8 taskId);
+static void InitTMCaseFromBag(void);
+static void Task_InitTMCaseFromField(u8 taskId);
+static void InitBerryPouchFromBag(void);
+static void Task_InitBerryPouchFromField(u8 taskId);
+static void InitBerryPouchFromBattle(void);
+static void InitTeachyTvFromBag(void);
+static void Task_InitTeachyTvFromField(u8 taskId);
+static void sub_80A19E8(u8 taskId);
+static void sub_80A1A44(void);
+static void sub_80A1B48(u8 taskId);
+static void sub_80A1C08(u8 taskId);
+static void sub_80A1CAC(void);
+static void sub_80A1CC0(u8 taskId);
+static void sub_80A1D58(void);
+static void sub_80A1D68(u8 taskId);
+static void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId);
+static void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId);
// No clue what this is
static const u8 sUnref_83E27B4[] = {
@@ -132,14 +131,14 @@ static const u8 sUnref_83E27B4[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-void (*const gUnknown_83E2954[])(void) = {
- sub_8124C8C,
+static void (*const gUnknown_83E2954[])(void) = {
+ CB2_ShowPartyMenuForItemUse,
CB2_ReturnToField,
NULL,
NULL
};
-void sub_80A0FBC(u8 taskId)
+static void sub_80A0FBC(u8 taskId)
{
u8 itemType;
if (gSpecialVar_ItemId == ITEM_ENIGMA_BERRY)
@@ -160,7 +159,7 @@ void sub_80A0FBC(u8 taskId)
}
}
-void sub_80A103C(u8 taskId)
+static void sub_80A103C(u8 taskId)
{
if (gTasks[taskId].data[3] != 1)
{
@@ -171,21 +170,21 @@ void sub_80A103C(u8 taskId)
sItemUseOnFieldCB(taskId);
}
-void sub_80A1084(void)
+static void sub_80A1084(void)
{
sub_807DC00();
CreateTask(sub_80A109C, 8);
}
-void sub_80A109C(u8 taskId)
+static void sub_80A109C(u8 taskId)
{
- if (field_weather_is_fade_finished() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
sItemUseOnFieldCB(taskId);
}
}
-void sub_80A10C4(u8 taskId, bool8 a1, u8 a2, const u8 * str)
+static void sub_80A10C4(u8 taskId, bool8 a1, u8 a2, const u8 * str)
{
StringExpandPlaceholders(gStringVar4, str);
if (a1 == FALSE)
@@ -194,12 +193,12 @@ void sub_80A10C4(u8 taskId, bool8 a1, u8 a2, const u8 * str)
DisplayItemMessageOnField(taskId, a2, gStringVar4, sub_80A112C);
}
-void sub_80A1110(u8 taskId, bool8 a1)
+static void sub_80A1110(u8 taskId, bool8 a1)
{
sub_80A10C4(taskId, a1, 4, gUnknown_8416425);
}
-void sub_80A112C(u8 taskId)
+static void sub_80A112C(u8 taskId)
{
ClearDialogWindowAndFrame(0, 1);
DestroyTask(taskId);
@@ -207,7 +206,7 @@ void sub_80A112C(u8 taskId)
ScriptContext2_Disable();
}
-u8 GetItemCompatibilityRule(u16 itemId)
+u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId)
{
if (ItemId_GetPocket(itemId) == POCKET_TM_CASE)
return 1;
@@ -217,12 +216,12 @@ u8 GetItemCompatibilityRule(u16 itemId)
return 0;
}
-void sub_80A1184(void)
+static void sub_80A1184(void)
{
gFieldCallback2 = sub_80A1194;
}
-bool8 sub_80A1194(void)
+static bool8 sub_80A1194(void)
{
FreezeEventObjects();
ScriptContext2_Enable();
@@ -232,9 +231,9 @@ bool8 sub_80A1194(void)
return TRUE;
}
-void sub_80A11C0(u8 taskId)
+static void sub_80A11C0(u8 taskId)
{
- if (field_weather_is_fade_finished() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
UnfreezeMapObjects();
ScriptContext2_Disable();
@@ -248,7 +247,7 @@ void FieldUseFunc_OrangeMail(u8 taskId)
ItemMenu_StartFadeToExitCallback(taskId);
}
-void sub_80A1208(void)
+static void sub_80A1208(void)
{
struct MailStruct mail;
@@ -279,7 +278,7 @@ void FieldUseFunc_MachBike(u8 taskId)
sub_80A1110(taskId, gTasks[taskId].data[3]);
}
-void ItemUseOnFieldCB_Bicycle(u8 taskId)
+static void ItemUseOnFieldCB_Bicycle(u8 taskId)
{
if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
PlaySE(SE_JITENSYA);
@@ -300,7 +299,7 @@ void FieldUseFunc_OldRod(u8 taskId)
sub_80A1110(taskId, gTasks[taskId].data[3]);
}
-bool8 ItemUseCheckFunc_Rod(void)
+static bool8 ItemUseCheckFunc_Rod(void)
{
s16 x, y;
u16 behavior;
@@ -327,7 +326,7 @@ bool8 ItemUseCheckFunc_Rod(void)
return FALSE;
}
-void ItemUseOnFieldCB_Rod(u8 taskId)
+static void ItemUseOnFieldCB_Rod(u8 taskId)
{
sub_805D2C0(ItemId_GetSecondaryId(gSpecialVar_ItemId));
DestroyTask(taskId);
@@ -391,13 +390,13 @@ void FieldUseFunc_PokeFlute(u8 taskId)
}
}
-void sub_80A1648(u8 taskId)
+static void sub_80A1648(u8 taskId)
{
PlayFanfareByFanfareNum(FANFARE_POKEFLUTE);
gTasks[taskId].func = sub_80A1674;
}
-void sub_80A1674(u8 taskId)
+static void sub_80A1674(u8 taskId)
{
if (WaitFanfare(FALSE))
{
@@ -408,44 +407,44 @@ void sub_80A1674(u8 taskId)
}
}
-void sub_80A16D0(u8 taskId)
+static void sub_80A16D0(u8 taskId)
{
sub_80A0FBC(taskId);
}
void FieldUseFunc_Medicine(u8 taskId)
{
- gUnknown_3005E98 = sub_81252D0;
+ gItemUseCB = ItemUseCB_Medicine;
sub_80A16D0(taskId);
}
void FieldUseFunc_Ether(u8 taskId)
{
- gUnknown_3005E98 = ItemUseCB_PpRestore;
+ gItemUseCB = ItemUseCB_PPRecovery;
sub_80A16D0(taskId);
}
void FieldUseFunc_PpUp(u8 taskId)
{
- gUnknown_3005E98 = dp05_pp_up;
+ gItemUseCB = ItemUseCB_PPUp;
sub_80A16D0(taskId);
}
void FieldUseFunc_RareCandy(u8 taskId)
{
- gUnknown_3005E98 = dp05_rare_candy;
+ gItemUseCB = ItemUseCB_RareCandy;
sub_80A16D0(taskId);
}
void FieldUseFunc_EvoItem(u8 taskId)
{
- gUnknown_3005E98 = sub_8126B60;
+ gItemUseCB = ItemUseCB_EvolutionStone;
sub_80A16D0(taskId);
}
void FieldUseFunc_SacredAsh(u8 taskId)
{
- gUnknown_3005E98 = sub_8126894;
+ gItemUseCB = ItemUseCB_SacredAsh;
sub_80A0FBC(taskId);
}
@@ -464,12 +463,12 @@ void FieldUseFunc_TmCase(u8 taskId)
}
}
-void InitTMCaseFromBag(void)
+static void InitTMCaseFromBag(void)
{
InitTMCase(0, CB2_BagMenuFromStartMenu, 0);
}
-void Task_InitTMCaseFromField(u8 taskId)
+static void Task_InitTMCaseFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
@@ -495,12 +494,12 @@ void FieldUseFunc_BerryPouch(u8 taskId)
}
}
-void InitBerryPouchFromBag(void)
+static void InitBerryPouchFromBag(void)
{
InitBerryPouch(BERRYPOUCH_FROMFIELD, CB2_BagMenuFromStartMenu, 0);
}
-void Task_InitBerryPouchFromField(u8 taskId)
+static void Task_InitBerryPouchFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
@@ -517,7 +516,7 @@ void BattleUseFunc_BerryPouch(u8 taskId)
ItemMenu_StartFadeToExitCallback(taskId);
}
-void InitBerryPouchFromBattle(void)
+static void InitBerryPouchFromBattle(void)
{
InitBerryPouch(BERRYPOUCH_FROMBATTLE, sub_8107ECC, 0);
}
@@ -538,12 +537,12 @@ void FieldUseFunc_TeachyTv(u8 taskId)
}
}
-void InitTeachyTvFromBag(void)
+static void InitTeachyTvFromBag(void)
{
InitTeachyTvController(0, CB2_BagMenuFromStartMenu);
}
-void Task_InitTeachyTvFromField(u8 taskId)
+static void Task_InitTeachyTvFromField(u8 taskId)
{
if (!gPaletteFade.active)
{
@@ -566,7 +565,7 @@ void FieldUseFunc_SuperRepel(u8 taskId)
DisplayItemMessageInBag(taskId, 2, gUnknown_841659E, sub_810A1F8);
}
-void sub_80A19E8(u8 taskId)
+static void sub_80A19E8(u8 taskId)
{
if (!IsSEPlaying())
{
@@ -577,7 +576,7 @@ void sub_80A19E8(u8 taskId)
}
}
-void sub_80A1A44(void)
+static void sub_80A1A44(void)
{
RemoveBagItem(gSpecialVar_ItemId, 1);
sub_8108DC8(ItemId_GetPocket(gSpecialVar_ItemId));
@@ -609,7 +608,7 @@ void FieldUseFunc_BlackFlute(u8 taskId)
}
}
-void sub_80A1B48(u8 taskId)
+static void sub_80A1B48(u8 taskId)
{
if (++gTasks[taskId].data[8] > 7)
{
@@ -638,7 +637,7 @@ void ItemUseOutOfBattle_EscapeRope(u8 taskId)
sub_80A1110(taskId, gTasks[taskId].data[3]);
}
-void sub_80A1C08(u8 taskId)
+static void sub_80A1C08(u8 taskId)
{
Overworld_ResetStateAfterDigEscRope();
sub_80A1A44();
@@ -668,12 +667,12 @@ void FieldUseFunc_TownMap(u8 taskId)
}
}
-void sub_80A1CAC(void)
+static void sub_80A1CAC(void)
{
sub_80BFF50(0, CB2_BagMenuFromStartMenu);
}
-void sub_80A1CC0(u8 taskId)
+static void sub_80A1CC0(u8 taskId)
{
if (!gPaletteFade.active)
{
@@ -700,12 +699,12 @@ void FieldUseFunc_FameChecker(u8 taskId)
}
}
-void sub_80A1D58(void)
+static void sub_80A1D58(void)
{
UseFameChecker(CB2_BagMenuFromStartMenu);
}
-void sub_80A1D68(u8 taskId)
+static void sub_80A1D68(u8 taskId)
{
if (!gPaletteFade.active)
{
@@ -765,7 +764,7 @@ void BattleUseFunc_GuardSpec(u8 taskId)
{
if (ExecuteTableBasedItemEffect(&gPlayerParty[gBattlerPartyIndexes[gBattlerInMenuId]], gSpecialVar_ItemId, gBattlerPartyIndexes[gBattlerInMenuId], 0))
{
- DisplayItemMessageInBag(taskId, 2, gUnknown_84169DC, sub_810A1F8);
+ DisplayItemMessageInBag(taskId, 2, gText_WontHaveEffect, sub_810A1F8);
}
else
{
@@ -774,7 +773,7 @@ void BattleUseFunc_GuardSpec(u8 taskId)
}
}
-void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId)
+static void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId)
{
s16 * data = gTasks[taskId].data;
@@ -787,7 +786,7 @@ void Task_BattleUse_StatBooster_DelayAndPrint(u8 taskId)
}
}
-void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId)
+static void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId)
{
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
{
@@ -796,7 +795,7 @@ void Task_BattleUse_StatBooster_WaitButton_ReturnToBattle(u8 taskId)
}
}
-void ItemUse_SwitchToPartyMenuInBattle(u8 taskId)
+static void ItemUse_SwitchToPartyMenuInBattle(u8 taskId)
{
if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_BERRY_POUCH)
{
@@ -812,19 +811,19 @@ void ItemUse_SwitchToPartyMenuInBattle(u8 taskId)
void BattleUseFunc_Medicine(u8 taskId)
{
- gUnknown_3005E98 = ItemUseCB_Medicine;
+ gItemUseCB = ItemUseCB_MedicineStep;
ItemUse_SwitchToPartyMenuInBattle(taskId);
}
-void sub_80A1FD8(u8 taskId)
+static void sub_80A1FD8(u8 taskId)
{
- gUnknown_3005E98 = sub_8126894;
+ gItemUseCB = ItemUseCB_SacredAsh;
ItemUse_SwitchToPartyMenuInBattle(taskId);
}
void BattleUseFunc_Ether(u8 taskId)
{
- gUnknown_3005E98 = ItemUseCB_PpRestore;
+ gItemUseCB = ItemUseCB_PPRecovery;
ItemUse_SwitchToPartyMenuInBattle(taskId);
}
diff --git a/src/list_menu.c b/src/list_menu.c
index d25eb3faf..484da31ad 100644
--- a/src/list_menu.c
+++ b/src/list_menu.c
@@ -70,7 +70,7 @@ static EWRAM_DATA struct MysteryGiftLinkMenuStruct sMysteryGiftLinkMenu = {0};
struct ListMenuOverride gListMenuOverride;
struct ListMenuTemplate gMultiuseListMenuTemplate;
-static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow);
+static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 cursorPos, u16 itemsAbove);
static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAndCallCallback, u8 count, bool8 movingDown);
static void ListMenuPrintEntries(struct ListMenu *list, u16 startIndex, u16 yOffset, u16 count);
static void ListMenuDrawCursor(struct ListMenu *list);
@@ -172,18 +172,18 @@ s32 DoMysteryGiftListMenu(const struct WindowTemplate *windowTemplate, const str
return LIST_NOTHING_CHOSEN;
}
-u8 ListMenuInit(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow)
+u8 ListMenuInit(struct ListMenuTemplate *listMenuTemplate, u16 cursorPos, u16 itemsAbove)
{
- u8 taskId = ListMenuInitInternal(listMenuTemplate, scrollOffset, selectedRow);
+ u8 taskId = ListMenuInitInternal(listMenuTemplate, cursorPos, itemsAbove);
PutWindowTilemap(listMenuTemplate->windowId);
CopyWindowToVram(listMenuTemplate->windowId, 2);
return taskId;
}
-u8 ListMenuInitInRect(struct ListMenuTemplate *listMenuTemplate, struct ListMenuWindowRect *rect, u16 scrollOffset, u16 selectedRow)
+u8 ListMenuInitInRect(struct ListMenuTemplate *listMenuTemplate, struct ListMenuWindowRect *rect, u16 cursorPos, u16 itemsAbove)
{
s32 i;
- u8 taskId = ListMenuInitInternal(listMenuTemplate, scrollOffset, selectedRow);
+ u8 taskId = ListMenuInitInternal(listMenuTemplate, cursorPos, itemsAbove);
for (i = 0; rect[i].palNum != 0xFF; i++)
PutWindowRectTilemapOverridePalette(listMenuTemplate->windowId, rect[i].x, rect[i].y, rect[i].width, rect[i].height, rect[i].palNum);
@@ -197,7 +197,7 @@ s32 ListMenu_ProcessInput(u8 listTaskId)
if (JOY_NEW(A_BUTTON))
{
- return list->template.items[list->scrollOffset + list->selectedRow].index;
+ return list->template.items[list->cursorPos + list->itemsAbove].index;
}
else if (JOY_NEW(B_BUTTON))
{
@@ -249,14 +249,14 @@ s32 ListMenu_ProcessInput(u8 listTaskId)
}
}
-void DestroyListMenuTask(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow)
+void DestroyListMenuTask(u8 listTaskId, u16 *cursorPos, u16 *itemsAbove)
{
struct ListMenu *list = (struct ListMenu *)gTasks[listTaskId].data;
- if (scrollOffset != NULL)
- *scrollOffset = list->scrollOffset;
- if (selectedRow != NULL)
- *selectedRow = list->selectedRow;
+ if (cursorPos != NULL)
+ *cursorPos = list->cursorPos;
+ if (itemsAbove != NULL)
+ *itemsAbove = list->itemsAbove;
if (list->taskId != TASK_NONE)
ListMenuRemoveCursorObject(list->taskId, list->template.cursorKind - 2);
@@ -269,7 +269,7 @@ void RedrawListMenu(u8 listTaskId)
struct ListMenu *list = (struct ListMenu *)gTasks[listTaskId].data;
FillWindowPixelBuffer(list->template.windowId, PIXEL_FILL(list->template.fillValue));
- ListMenuPrintEntries(list, list->scrollOffset, 0, list->template.maxShowed);
+ ListMenuPrintEntries(list, list->cursorPos, 0, list->template.maxShowed);
ListMenuDrawCursor(list);
CopyWindowToVram(list->template.windowId, 2);
}
@@ -291,13 +291,13 @@ static void ChangeListMenuCoords(u8 listTaskId, u8 x, u8 y)
SetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_TOP, y);
}
-static s32 ListMenuTestInput(struct ListMenuTemplate *template, u32 scrollOffset, u32 selectedRow, u16 keys, u16 *newScrollOffset, u16 *newSelectedRow)
+static s32 ListMenuTestInput(struct ListMenuTemplate *template, u32 cursorPos, u32 itemsAbove, u16 keys, u16 *newCursorPos, u16 *newItemsAbove)
{
struct ListMenu list;
list.template = *template;
- list.scrollOffset = scrollOffset;
- list.selectedRow = selectedRow;
+ list.cursorPos = cursorPos;
+ list.itemsAbove = itemsAbove;
list.unk_1C = 0;
list.unk_1D = 0;
if (keys == DPAD_UP)
@@ -305,10 +305,10 @@ static s32 ListMenuTestInput(struct ListMenuTemplate *template, u32 scrollOffset
if (keys == DPAD_DOWN)
ListMenuChangeSelection(&list, FALSE, 1, TRUE);
- if (newScrollOffset != NULL)
- *newScrollOffset = list.scrollOffset;
- if (newSelectedRow != NULL)
- *newSelectedRow = list.selectedRow;
+ if (newCursorPos != NULL)
+ *newCursorPos = list.cursorPos;
+ if (newItemsAbove != NULL)
+ *newItemsAbove = list.itemsAbove;
return LIST_NOTHING_CHOSEN;
}
@@ -317,17 +317,17 @@ static void ListMenuGetCurrentItemArrayId(u8 listTaskId, u16 *arrayId)
struct ListMenu *list = (struct ListMenu *)gTasks[listTaskId].data;
if (arrayId != NULL)
- *arrayId = list->scrollOffset + list->selectedRow;
+ *arrayId = list->cursorPos + list->itemsAbove;
}
-void ListMenuGetScrollAndRow(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow)
+void ListMenuGetScrollAndRow(u8 listTaskId, u16 *cursorPos, u16 *itemsAbove)
{
struct ListMenu *list = (struct ListMenu *)gTasks[listTaskId].data;
- if (scrollOffset != NULL)
- *scrollOffset = list->scrollOffset;
- if (selectedRow != NULL)
- *selectedRow = list->selectedRow;
+ if (cursorPos != NULL)
+ *cursorPos = list->cursorPos;
+ if (itemsAbove != NULL)
+ *itemsAbove = list->itemsAbove;
}
u16 ListMenuGetYCoordForPrintingArrowCursor(u8 listTaskId)
@@ -335,17 +335,17 @@ u16 ListMenuGetYCoordForPrintingArrowCursor(u8 listTaskId)
struct ListMenu *list = (struct ListMenu *)gTasks[listTaskId].data;
u8 yMultiplier = GetFontAttribute(list->template.fontId, FONTATTR_MAX_LETTER_HEIGHT) + list->template.itemVerticalPadding;
- return list->selectedRow * yMultiplier + list->template.upText_Y;
+ return list->itemsAbove * yMultiplier + list->template.upText_Y;
}
-static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow)
+static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 cursorPos, u16 itemsAbove)
{
u8 listTaskId = CreateTask(ListMenuDummyTask, 0);
struct ListMenu *list = (struct ListMenu *)gTasks[listTaskId].data;
list->template = *listMenuTemplate;
- list->scrollOffset = scrollOffset;
- list->selectedRow = selectedRow;
+ list->cursorPos = cursorPos;
+ list->itemsAbove = itemsAbove;
list->unk_1C = 0;
list->unk_1D = 0;
list->taskId = TASK_NONE;
@@ -359,7 +359,7 @@ static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 sc
if (list->template.totalItems < list->template.maxShowed)
list->template.maxShowed = list->template.totalItems;
FillWindowPixelBuffer(list->template.windowId, PIXEL_FILL(list->template.fillValue));
- ListMenuPrintEntries(list, list->scrollOffset, 0, list->template.maxShowed);
+ ListMenuPrintEntries(list, list->cursorPos, 0, list->template.maxShowed);
ListMenuDrawCursor(list);
ListMenuCallSelectionChangedCallback(list, TRUE);
@@ -410,7 +410,7 @@ static void ListMenuDrawCursor(struct ListMenu *list)
{
u8 yMultiplier = GetFontAttribute(list->template.fontId, FONTATTR_MAX_LETTER_HEIGHT) + list->template.itemVerticalPadding;
u8 x = list->template.cursor_X;
- u8 y = list->selectedRow * yMultiplier + list->template.upText_Y;
+ u8 y = list->itemsAbove * yMultiplier + list->template.upText_Y;
switch (list->template.cursorKind)
{
@@ -446,7 +446,7 @@ static u8 ListMenuAddCursorObject(struct ListMenu *list, u32 cursorKind)
return ListMenuAddCursorObjectInternal(&cursor, cursorKind);
}
-static void ListMenuErasePrintedCursor(struct ListMenu *list, u16 selectedRow)
+static void ListMenuErasePrintedCursor(struct ListMenu *list, u16 itemsAbove)
{
u8 cursorKind = list->template.cursorKind;
if (cursorKind == 0)
@@ -457,7 +457,7 @@ static void ListMenuErasePrintedCursor(struct ListMenu *list, u16 selectedRow)
FillWindowPixelRect(list->template.windowId,
PIXEL_FILL(list->template.fillValue),
list->template.cursor_X,
- selectedRow * yMultiplier + list->template.upText_Y,
+ itemsAbove * yMultiplier + list->template.upText_Y,
width,
height);
}
@@ -465,8 +465,8 @@ static void ListMenuErasePrintedCursor(struct ListMenu *list, u16 selectedRow)
static u8 ListMenuUpdateSelectedRowIndexAndScrollOffset(struct ListMenu *list, bool8 movingDown)
{
- u16 selectedRow = list->selectedRow;
- u16 scrollOffset = list->scrollOffset;
+ u16 itemsAbove = list->itemsAbove;
+ u16 cursorPos = list->cursorPos;
u16 newRow;
u32 newScroll;
@@ -477,14 +477,14 @@ static u8 ListMenuUpdateSelectedRowIndexAndScrollOffset(struct ListMenu *list, b
else
newRow = list->template.maxShowed - ((list->template.maxShowed / 2) + (list->template.maxShowed % 2)) - 1;
- if (scrollOffset == 0)
+ if (cursorPos == 0)
{
- while (selectedRow != 0)
+ while (itemsAbove != 0)
{
- selectedRow--;
- if (list->template.items[scrollOffset + selectedRow].index != LIST_HEADER)
+ itemsAbove--;
+ if (list->template.items[cursorPos + itemsAbove].index != LIST_HEADER)
{
- list->selectedRow = selectedRow;
+ list->itemsAbove = itemsAbove;
return 1;
}
}
@@ -492,16 +492,16 @@ static u8 ListMenuUpdateSelectedRowIndexAndScrollOffset(struct ListMenu *list, b
}
else
{
- while (selectedRow > newRow)
+ while (itemsAbove > newRow)
{
- selectedRow--;
- if (list->template.items[scrollOffset + selectedRow].index != LIST_HEADER)
+ itemsAbove--;
+ if (list->template.items[cursorPos + itemsAbove].index != LIST_HEADER)
{
- list->selectedRow = selectedRow;
+ list->itemsAbove = itemsAbove;
return 1;
}
}
- newScroll = scrollOffset - 1;
+ newScroll = cursorPos - 1;
}
}
else
@@ -511,14 +511,14 @@ static u8 ListMenuUpdateSelectedRowIndexAndScrollOffset(struct ListMenu *list, b
else
newRow = ((list->template.maxShowed / 2) + (list->template.maxShowed % 2));
- if (scrollOffset == list->template.totalItems - list->template.maxShowed)
+ if (cursorPos == list->template.totalItems - list->template.maxShowed)
{
- while (selectedRow < list->template.maxShowed - 1)
+ while (itemsAbove < list->template.maxShowed - 1)
{
- selectedRow++;
- if (list->template.items[scrollOffset + selectedRow].index != LIST_HEADER)
+ itemsAbove++;
+ if (list->template.items[cursorPos + itemsAbove].index != LIST_HEADER)
{
- list->selectedRow = selectedRow;
+ list->itemsAbove = itemsAbove;
return 1;
}
}
@@ -526,20 +526,20 @@ static u8 ListMenuUpdateSelectedRowIndexAndScrollOffset(struct ListMenu *list, b
}
else
{
- while (selectedRow < newRow)
+ while (itemsAbove < newRow)
{
- selectedRow++;
- if (list->template.items[scrollOffset + selectedRow].index != LIST_HEADER)
+ itemsAbove++;
+ if (list->template.items[cursorPos + itemsAbove].index != LIST_HEADER)
{
- list->selectedRow = selectedRow;
+ list->itemsAbove = itemsAbove;
return 1;
}
}
- newScroll = scrollOffset + 1;
+ newScroll = cursorPos + 1;
}
}
- list->selectedRow = newRow;
- list->scrollOffset = newScroll;
+ list->itemsAbove = newRow;
+ list->cursorPos = newScroll;
return 2;
}
@@ -548,7 +548,7 @@ static void ListMenuScroll(struct ListMenu *list, u8 count, bool8 movingDown)
if (count >= list->template.maxShowed)
{
FillWindowPixelBuffer(list->template.windowId, PIXEL_FILL(list->template.fillValue));
- ListMenuPrintEntries(list, list->scrollOffset, 0, list->template.maxShowed);
+ ListMenuPrintEntries(list, list->cursorPos, 0, list->template.maxShowed);
}
else
{
@@ -559,7 +559,7 @@ static void ListMenuScroll(struct ListMenu *list, u8 count, bool8 movingDown)
u16 y, width, height;
ScrollWindow(list->template.windowId, 1, count * yMultiplier, PIXEL_FILL(list->template.fillValue));
- ListMenuPrintEntries(list, list->scrollOffset, 0, count);
+ ListMenuPrintEntries(list, list->cursorPos, 0, count);
y = (list->template.maxShowed * yMultiplier) + list->template.upText_Y;
width = GetWindowAttribute(list->template.windowId, WINDOW_WIDTH) * 8;
@@ -573,7 +573,7 @@ static void ListMenuScroll(struct ListMenu *list, u8 count, bool8 movingDown)
u16 width;
ScrollWindow(list->template.windowId, 0, count * yMultiplier, PIXEL_FILL(list->template.fillValue));
- ListMenuPrintEntries(list, list->scrollOffset + (list->template.maxShowed - count), list->template.maxShowed - count, count);
+ ListMenuPrintEntries(list, list->cursorPos + (list->template.maxShowed - count), list->template.maxShowed - count, count);
width = GetWindowAttribute(list->template.windowId, WINDOW_WIDTH) * 8;
FillWindowPixelRect(list->template.windowId,
@@ -588,7 +588,7 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
u16 oldSelectedRow;
u8 selectionChange, i, cursorCount;
- oldSelectedRow = list->selectedRow;
+ oldSelectedRow = list->itemsAbove;
cursorCount = 0;
selectionChange = 0;
for (i = 0; i < count; i++)
@@ -602,7 +602,7 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
break;
cursorCount++;
}
- while (list->template.items[list->scrollOffset + list->selectedRow].index == LIST_HEADER);
+ while (list->template.items[list->cursorPos + list->itemsAbove].index == LIST_HEADER);
}
if (updateCursorAndCallCallback)
@@ -634,7 +634,7 @@ static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAn
static void ListMenuCallSelectionChangedCallback(struct ListMenu *list, u8 onInit)
{
if (list->template.moveCursorFunc != NULL)
- list->template.moveCursorFunc(list->template.items[list->scrollOffset + list->selectedRow].index, onInit, list);
+ list->template.moveCursorFunc(list->template.items[list->cursorPos + list->itemsAbove].index, onInit, list);
}
void ListMenuOverrideSetColors(u8 cursorPal, u8 fillValue, u8 cursorShadowPal)
diff --git a/src/mailbox_pc.c b/src/mailbox_pc.c
index 0a4535271..5489c4c4e 100644
--- a/src/mailbox_pc.c
+++ b/src/mailbox_pc.c
@@ -123,7 +123,7 @@ u8 MailboxPC_InitListMenu(struct PlayerPCItemPageStruct * playerPcStruct)
gMultiuseListMenuTemplate.itemPrintFunc = ItemPrintFunc;
gMultiuseListMenuTemplate.cursorKind = 0;
gMultiuseListMenuTemplate.scrollMultiple = 0;
- return ListMenuInit(&gMultiuseListMenuTemplate, playerPcStruct->scrollOffset, playerPcStruct->selectedRow);
+ return ListMenuInit(&gMultiuseListMenuTemplate, playerPcStruct->itemsAbove, playerPcStruct->cursorPos);
}
static void MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu * list)
@@ -134,7 +134,7 @@ static void MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu * list)
void MailboxPC_AddScrollIndicatorArrows(struct PlayerPCItemPageStruct * playerPcStruct)
{
- playerPcStruct->scrollIndicatorId = AddScrollIndicatorArrowPairParameterized(2, 0xC2, 0xC, 0x94, playerPcStruct->count - playerPcStruct->pageItems + 1, 110, 110, &playerPcStruct->scrollOffset);
+ playerPcStruct->scrollIndicatorId = AddScrollIndicatorArrowPairParameterized(2, 0xC2, 0xC, 0x94, playerPcStruct->count - playerPcStruct->pageItems + 1, 110, 110, &playerPcStruct->itemsAbove);
}
void MailboxPC_DestroyListMenuBuffer(void)
diff --git a/src/map_preview_screen.c b/src/map_preview_screen.c
index c465a5683..0747e8ade 100644
--- a/src/map_preview_screen.c
+++ b/src/map_preview_screen.c
@@ -495,7 +495,7 @@ static void sub_80F83D0(u8 taskId)
}
break;
case 2:
- if (field_weather_is_fade_finished())
+ if (IsWeatherNotFadingIn())
{
Overworld_PlaySpecialMapMusic();
data[0]++;
diff --git a/src/menu.c b/src/menu.c
index b8a68145c..5a0da28b9 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -815,13 +815,13 @@ static s8 sub_81106F4(void)
MultichoiceGrid_MoveCursor(0, 1);
return MENU_NOTHING_CHOSEN;
}
- else if (JOY_REPT(DPAD_ANY) == DPAD_LEFT || sub_80BF66C() == 1)
+ else if (JOY_REPT(DPAD_ANY) == DPAD_LEFT || GetLRKeysPressedAndHeld() == 1)
{
PlaySE(SE_SELECT);
MultichoiceGrid_MoveCursor(-1, 0);
return MENU_NOTHING_CHOSEN;
}
- else if (JOY_REPT(DPAD_ANY) == DPAD_RIGHT || sub_80BF66C() == 2)
+ else if (JOY_REPT(DPAD_ANY) == DPAD_RIGHT || GetLRKeysPressedAndHeld() == 2)
{
PlaySE(SE_SELECT);
MultichoiceGrid_MoveCursor(1, 0);
@@ -857,13 +857,13 @@ static s8 sub_81107A0(void)
PlaySE(SE_SELECT);
return MENU_NOTHING_CHOSEN;
}
- else if (JOY_REPT(DPAD_ANY) == DPAD_LEFT || sub_80BF66C() == 1)
+ else if (JOY_REPT(DPAD_ANY) == DPAD_LEFT || GetLRKeysPressedAndHeld() == 1)
{
if (oldPos != MultichoiceGrid_MoveCursorIfValid(-1, 0))
PlaySE(SE_SELECT);
return MENU_NOTHING_CHOSEN;
}
- else if (JOY_REPT(DPAD_ANY) == DPAD_RIGHT || sub_80BF66C() == 2)
+ else if (JOY_REPT(DPAD_ANY) == DPAD_RIGHT || GetLRKeysPressedAndHeld() == 2)
{
if (oldPos != MultichoiceGrid_MoveCursorIfValid(1, 0))
PlaySE(SE_SELECT);
diff --git a/src/menu_helpers.c b/src/menu_helpers.c
index f17bff0d0..905e3c1ea 100644
--- a/src/menu_helpers.c
+++ b/src/menu_helpers.c
@@ -83,7 +83,7 @@ u8 GetLRKeysState(void)
return 0;
}
-u8 sub_80BF66C(void)
+u8 GetLRKeysPressedAndHeld(void)
{
if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
{
@@ -149,7 +149,7 @@ void SetVBlankHBlankCallbacksToNull(void)
SetHBlankCallback(NULL);
}
-void ClearVramOamPltt(void)
+void ResetVramOamAndBgCntRegs(void)
{
ResetAllBgsCoordinatesAndBgCntRegs();
CpuFill16(0, (void*) VRAM, VRAM_SIZE);
diff --git a/src/new_menu_helpers.c b/src/new_menu_helpers.c
index f879e6810..d2421ed9f 100644
--- a/src/new_menu_helpers.c
+++ b/src/new_menu_helpers.c
@@ -343,7 +343,7 @@ static u16 CopyDecompressedTileDataToVram(u8 bgId, const void *src, u16 size, u1
return LoadBgTilemap(bgId, src, size, offset);
}
-void SetBgRectPal(u8 bgId, u8 left, u8 top, u8 width, u8 height, u8 palette)
+void SetBgTilemapPalette(u8 bgId, u8 left, u8 top, u8 width, u8 height, u8 palette)
{
u8 i, j;
u16 *ptr = GetBgTilemapBuffer(bgId);
@@ -357,7 +357,7 @@ void SetBgRectPal(u8 bgId, u8 left, u8 top, u8 width, u8 height, u8 palette)
}
}
-void CopyRectIntoAltRect(u8 bgId, u16 *dest, u8 left, u8 top, u8 width, u8 height)
+void CopyToBufferFromBgTilemap(u8 bgId, u16 *dest, u8 left, u8 top, u8 width, u8 height)
{
u8 i,j;
const u16 *src = GetBgTilemapBuffer(bgId);
diff --git a/src/option_menu.c b/src/option_menu.c
index 35fe957be..5453dfa9e 100644
--- a/src/option_menu.c
+++ b/src/option_menu.c
@@ -206,7 +206,7 @@ void CB2_OptionsMenuFromStartMenu(void)
u8 i;
if (gMain.savedCallback == NULL)
- gMain.savedCallback = CB2_ReturnToStartMenu;
+ gMain.savedCallback = CB2_ReturnToFieldWithOpenMenu;
sOptionMenuPtr = AllocZeroed(sizeof(struct OptionMenu));
sOptionMenuPtr->state3 = 0;
sOptionMenuPtr->state2 = 0;
diff --git a/src/party_menu.c b/src/party_menu.c
new file mode 100644
index 000000000..399794b2d
--- /dev/null
+++ b/src/party_menu.c
@@ -0,0 +1,6381 @@
+#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_tower.h"
+#include "berry_pouch.h"
+#include "bg.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 "gpu_regs.h"
+#include "graphics.h"
+#include "help_system.h"
+#include "item.h"
+#include "item_menu.h"
+#include "item_use.h"
+#include "link.h"
+#include "link_rfu.h"
+#include "load_save.h"
+#include "mail.h"
+#include "mail_data.h"
+#include "main.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "new_menu_helpers.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "player_pc.h"
+#include "pokedex.h"
+#include "pokemon.h"
+#include "pokemon_icon.h"
+#include "pokemon_jump.h"
+#include "pokemon_special_anim.h"
+#include "pokemon_storage_system.h"
+#include "pokemon_summary_screen.h"
+#include "quest_log.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 "teachy_tv.h"
+#include "text.h"
+#include "text_window.h"
+#include "tm_case.h"
+#include "trade.h"
+#include "union_room.h"
+#include "window.h"
+#include "constants/battle.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/pokemon.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)
+
+#define MENU_DIR_DOWN 1
+#define MENU_DIR_UP -1
+#define MENU_DIR_RIGHT 2
+#define MENU_DIR_LEFT -2
+
+enum
+{
+ CAN_LEARN_MOVE,
+ CANNOT_LEARN_MOVE,
+ ALREADY_KNOWS_MOVE,
+ CANNOT_LEARN_MOVE_IS_EGG
+};
+
+struct PartyMenuBoxInfoRects
+{
+ void (*blitFunc)(u8 windowId, u8 x, u8 y, u8 width, u8 height, bool8 isEgg);
+ u8 dimensions[24];
+ u8 descTextLeft;
+ u8 descTextTop;
+ u8 descTextWidth;
+ u8 descTextHeight;
+};
+
+struct PartyMenuInternal
+{
+ TaskFunc task;
+ MainCallback exitCallback;
+ u32 chooseHalf:1;
+ u32 lastSelectedSlot:3; // Used to return to same slot when going left/right bewtween columns
+ u32 spriteIdConfirmPokeball:7;
+ u32 spriteIdCancelPokeball:7;
+ u32 messageId:14;
+ u8 windowId[3];
+ u8 actions[8];
+ u8 numActions;
+ 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;
+};
+
+static void BlitBitmapToPartyWindow_LeftColumn(u8 windowId, u8 x, u8 y, u8 width, u8 height, bool8 isEgg);
+static void BlitBitmapToPartyWindow_RightColumn(u8 windowId, u8 x, u8 y, u8 width, u8 height, bool8 isEgg);
+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_FieldMove(u8 taskId);
+static bool8 SetUpFieldMove_Fly(void);
+static bool8 SetUpFieldMove_Waterfall(void);
+static bool8 SetUpFieldMove_Surf(void);
+static void CB2_InitPartyMenu(void);
+static void ResetPartyMenu(void);
+static bool8 ShowPartyMenu(void);
+static void SetPartyMonsAllowedInMinigame(void);
+static void ExitPartyMenu(void);
+static bool8 CreatePartyMonSpritesLoop(void);
+static bool8 AllocPartyMenuBg(void);
+static bool8 AllocPartyMenuBgGfx(void);
+static void InitPartyMenuWindows(u8 layout);
+static void InitPartyMenuBoxes(u8 layout);
+static void LoadPartyMenuPokeballGfx(void);
+static void LoadPartyMenuAilmentGfx(void);
+static bool8 RenderPartyMenuBoxes(void);
+static void CreateCancelConfirmPokeballSprites(void);
+static void CreateCancelConfirmWindows(bool8 chooseHalf);
+static void Task_ExitPartyMenu(u8 taskId);
+static void FreePartyPointers(void);
+static void PartyPaletteBufferCopy(u8 offset);
+static void DisplayPartyPokemonDataForMultiBattle(u8 slot);
+static void DisplayPartyPokemonDataForChooseHalf(u8 slot);
+static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8 slot);
+static void DisplayPartyPokemonData(u8 slot);
+static void DisplayPartyPokemonDataForWirelessMinigame(u8 slot);
+static void LoadPartyBoxPalette(struct PartyMenuBox *menuBox, u8 palFlags);
+static void DrawEmptySlot(u8 windowId);
+static void DisplayPartyPokemonNickname(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c);
+static void DisplayPartyPokemonLevelCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c);
+static void DisplayPartyPokemonGenderNidoranCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c);
+static void DisplayPartyPokemonHPCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c);
+static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c);
+static void DisplayPartyPokemonHPBarCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox);
+static void DisplayPartyPokemonDescriptionText(u8 stringId, struct PartyMenuBox *menuBox, u8 c);
+static bool8 GetBattleEntryEligibility(struct Pokemon *mon);
+static bool8 IsMonAllowedInMinigame(u8 slot);
+static void DisplayPartyPokemonDataToTeachMove(u8 slot, u16 item, u8 tutor);
+static u8 CanMonLearnTMTutor(struct Pokemon *mon, u16 item, u8 tutor);
+static void DisplayPartyPokemonBarDetail(u8 windowId, const u8 *str, u8 color, const u8 *align);
+static void DisplayPartyPokemonLevel(u8 level, struct PartyMenuBox *menuBox);
+static void DisplayPartyPokemonGender(u8 gender, u16 species, u8 *nickname, struct PartyMenuBox *menuBox);
+static void DisplayPartyPokemonHP(u16 hp, struct PartyMenuBox *menuBox);
+static void DisplayPartyPokemonMaxHP(u16 maxhp, struct PartyMenuBox *menuBox);
+static void DisplayPartyPokemonHPBar(u16 hp, u16 maxhp, struct PartyMenuBox *menuBox);
+static void CreatePartyMonIconSpriteParameterized(u16 species, u32 pid, struct PartyMenuBox *menuBox, u8 priority, bool32 handleDeoxys);
+static void CreatePartyMonHeldItemSpriteParameterized(u16 species, u16 item, struct PartyMenuBox *menuBox);
+static void CreatePartyMonPokeballSpriteParameterized(u16 species, struct PartyMenuBox *menuBox);
+static void CreatePartyMonStatusSpriteParameterized(u16 species, u8 status, struct PartyMenuBox *menuBox);
+static void CreatePartyMonIconSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox, u32 slot);
+static void CreatePartyMonHeldItemSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox);
+static void CreatePartyMonPokeballSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox);
+static void CreatePartyMonStatusSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox);
+static void CreateCancelConfirmPokeballSprites(void);
+static void DrawCancelConfirmButtons(void);
+static u8 CreatePokeballButtonSprite(u8 x, u8 y);
+static u8 CreateSmallPokeballButtonSprite(u8 x, u8 y);
+static u8 GetPartyBoxPaletteFlags(u8 slot, u8 animNum);
+static void AnimateSelectedPartyIcon(u8 spriteId, u8 animNum);
+static void PartyMenuStartSpriteAnim(u8 spriteId, u8 animNum);
+static void Task_ClosePartyMenuAndSetCB2(u8 taskId);
+static void UpdatePartyToFieldOrder(void);
+static s8 *GetCurrentPartySlotPtr(void);
+static u16 PartyMenuButtonHandler(s8 *slotPtr);
+static void HandleChooseMonSelection(u8 taskId, s8 *slotPtr);
+static void HandleChooseMonCancel(u8 taskId, s8 *slotPtr);
+static void MoveCursorToConfirm(void);
+static bool8 IsSelectedMonNotEgg(u8 *slotPtr);
+static void TryTutorSelectedMon(u8 taskId);
+static void TryGiveMailToSelectedMon(u8 taskId);
+static void SwitchSelectedMons(u8 taskId);
+static void TryEnterMonForMinigame(u8 taskId, u8 slot);
+static void Task_TryCreateSelectionWindow(u8 taskId);
+static void TryGiveItemOrMailToSelectedMon(u8 taskId);
+static void PartyMenuRemoveWindow(u8 *ptr);
+static void CB2_SetUpExitToBattleScreen(void);
+static void Task_ClosePartyMenuAfterText(u8 taskId);
+static void FinishTwoMonAction(u8 taskId);
+static void CancelParticipationPrompt(u8 taskId);
+static void DisplayCancelChooseMonYesNo(u8 taskId);
+static void Task_CancelChooseMonYesNo(u8 taskId);
+static void Task_HandleCancelChooseMonYesNoInput(u8 taskId);
+static void PartyMenuDisplayYesNoMenu(void);
+static void Task_ReturnToChooseMonAfterText(u8 taskId);
+static void UpdateCurrentPartySelection(s8 *slotPtr, s8 movementDir);
+static void UpdatePartySelectionSingleLayout(s8 *slotPtr, s8 movementDir);
+static void UpdatePartySelectionDoubleLayout(s8 *slotPtr, s8 movementDir);
+static s8 GetNewSlotDoubleLayout(s8 slotId, s8 movementDir);
+static void Task_PrintAndWaitForText(u8 taskId);
+static void PartyMenuPrintText(const u8 *text);
+static void sub_8124B60(struct Pokemon *mon, u16 item, u16 item2);
+static bool16 IsMonAllowedInPokemonJump(struct Pokemon *mon);
+static bool16 IsMonAllowedInDodrioBerryPicking(struct Pokemon *mon);
+static void Task_CancelParticipationYesNo(u8 taskId);
+static void Task_HandleCancelParticipationYesNoInput(u8 taskId);
+static void Task_TryCreateSelectionWindow(u8 taskId);
+static u16 GetTutorMove(u8 tutor);
+static bool8 CanLearnTutorMove(u16 species, u8 tutor);
+static void CreateSelectionWindow(void);
+static bool8 ShouldUseChooseMonText(void);
+static void UpdatePartyMonHPBar(u8 spriteId, struct Pokemon *mon);
+static void SpriteCB_UpdatePartyMonIcon(struct Sprite *sprite);
+static void SpriteCB_BouncePartyMonIcon(struct Sprite *sprite);
+static void SpriteCB_HeldItem(struct Sprite *sprite);
+static void UpdatePartyMonHeldItemSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox);
+static void ShowOrHideHeldItemSprite(u16 item, struct PartyMenuBox *menuBox);
+static void CreateHeldItemSpriteForTrade(u8 spriteId, bool8 isMail);
+static void SetPartyMonAilmentGfx(struct Pokemon *mon, struct PartyMenuBox *menuBox);
+static void UpdatePartyMonAilmentGfx(u8 status, struct PartyMenuBox *menuBox);
+static void SetPartyMonFieldSelectionActions(struct Pokemon *mons, u8 slotId);
+static u8 GetPartyMenuActionsTypeInBattle(struct Pokemon *mon);
+static u8 GetPartySlotEntryStatus(s8 slot);
+static void Task_HandleSelectionMenuInput(u8 taskId);
+static void CB2_ShowPokemonSummaryScreen(void);
+static void CB2_ReturnToPartyMenuFromSummaryScreen(void);
+static void UpdatePartyToBattleOrder(void);
+static void SlidePartyMenuBoxOneStep(u8 taskId);
+static void Task_SlideSelectedSlotsOffscreen(u8 taskId);
+static void SwitchPartyMon(void);
+static void Task_SlideSelectedSlotsOnscreen(u8 taskId);
+static void CB2_WriteMailToGiveMon(void);
+static void Task_SwitchHoldItemsPrompt(u8 taskId);
+static void Task_GiveHoldItem(u8 taskId);
+static void Task_UpdateHeldItemSprite(u8 taskId);
+static void Task_HandleSwitchItemsYesNoInput(u8 taskId);
+static void Task_SwitchItemsYesNo(u8 taskId);
+static void Task_WriteMailToGiveMonAfterText(u8 taskId);
+static void CB2_ReturnToPartyMenuFromWritingMail(void);
+static void CB2_ReturnToPartyMenuFromWritingMail(void);
+static void Task_DisplayGaveMailFromPartyMessage(u8 taskId);
+static void CB2_ReadHeldMail(void);
+static void CB2_ReturnToPartyMenuFromReadingMail(void);
+static void Task_SendMailToPCYesNo(u8 taskId);
+static void Task_HandleSendMailToPCYesNoInput(u8 taskId);
+static void Task_LoseMailMessageYesNo(u8 taskId);
+static void Task_HandleLoseMailMessageYesNoInput(u8 taskId);
+static bool8 TrySwitchInPokemon(void);
+static void DisplayCantUseFlashMessage(void);
+static void DisplayCantUseSurfMessage(void);
+static void Task_CancelAfterAorBPress(u8 taskId);
+static void DisplayFieldMoveExitAreaMessage(u8 taskId);
+static void Task_FieldMoveExitAreaYesNo(u8 taskId);
+static void Task_HandleFieldMoveExitAreaYesNoInput(u8 taskId);
+static void Task_FieldMoveWaitForFade(u8 taskId);
+static u16 GetFieldMoveMonSpecies(void);
+static u8 GetPartyLayoutFromBattleType(void);
+static void Task_SetSacredAshCB(u8 taskId);
+static void CB2_ReturnToBagMenu(void);
+static u8 GetPartyIdFromBattleSlot(u8 slot);
+static void Task_DisplayHPRestoredMessage(u8 taskId);
+static void SetSelectedMoveForPPItem(u8 taskId);
+static void ReturnToUseOnWhichMon(u8 taskId);
+static void TryUsePPItem(u8 taskId);
+static void ItemUseCB_LearnedMove(u8 taskId, UNUSED TaskFunc func);
+static void Task_LearnedMove(u8 taskId);
+static void Task_ReplaceMoveYesNo(u8 taskId);
+static void Task_DoLearnedMoveFanfareAfterText(u8 taskId);
+static void Task_TryLearningNextMove(u8 taskId);
+static void Task_LearnNextMoveOrClosePartyMenu(u8 taskId);
+static void Task_HandleReplaceMoveYesNoInput(u8 taskId);
+static void StopLearningMovePrompt(u8 taskId);
+static void Task_ShowSummaryScreenToForgetMove(u8 taskId);
+static void CB2_ShowSummaryScreenToForgetMove(void);
+static void CB2_ReturnToPartyMenuWhileLearningMove(void);
+static void Task_ReturnToPartyMenuWhileLearningMove(u8 taskId);
+static void DisplayPartyMenuForgotMoveMessage(u8 taskId);
+static void Task_PartyMenuReplaceMove(u8 taskId);
+static void Task_StopLearningMoveYesNo(u8 taskId);
+static void Task_HandleStopLearningMoveYesNoInput(u8 taskId);
+static void Task_TryLearningNextMoveAfterText(u8 taskId);
+static void ItemUseCB_RareCandyStep(u8 taskId, UNUSED TaskFunc func);
+static void Task_DisplayLevelUpStatsPg1(u8 taskId);
+static void Task_DisplayLevelUpStatsPg2(u8 taskId);
+static void UpdateMonDisplayInfoAfterRareCandy(u8 slot, struct Pokemon *mon);
+static void DisplayLevelUpStatsPg1(u8 taskId);
+static void DisplayLevelUpStatsPg2(u8 taskId);
+static void Task_TryLearnNewMoves(u8 taskId);
+static void PartyMenuTryEvolution(u8 taskId);
+static void DisplayMonNeedsToReplaceMove(u8 taskId);
+static void DisplayMonLearnedMove(u8 taskId, u16 move);
+static void Task_SacredAshDisplayHPRestored(u8 taskId);
+static void Task_SacredAshLoop(u8 taskId);
+static void UseSacredAsh(u8 taskId);
+static void CB2_ReturnToBerryPouchMenu(void);
+static void CB2_ReturnToTMCaseMenu(void);
+static void GiveItemOrMailToSelectedMon(u8 taskId);
+static void RemoveItemToGiveFromBag(u16 item);
+static void DisplayItemMustBeRemovedFirstMessage(u8 taskId);
+static void CB2_WriteMailToGiveMonFromBag(void);
+static void GiveItemToSelectedMon(u8 taskId);
+static void Task_UpdateHeldItemSpriteAndClosePartyMenu(u8 taskId);
+static void Task_SwitchItemsFromBagYesNo(u8 taskId);
+static void CB2_ReturnToPartyOrBagMenuFromWritingMail(void);
+static bool8 ReturnGiveItemToBagOrPC(u16 item);
+static void Task_DisplayGaveMailFromBagMessage(u8 taskId);
+static void Task_HandleSwitchItemsFromBagYesNoInput(u8 taskId);
+static void Task_ValidateChosenHalfParty(u8 taskId);
+static bool8 HasPartySlotAlreadyBeenSelected(u8 slot);
+static void Task_ContinueChoosingHalfParty(u8 taskId);
+static void BufferBattlePartyOrder(u8 *partyBattleOrder, u8 flankId);
+static void BufferBattlePartyOrderBySide(u8 *partyBattleOrder, u8 flankId, u8 battlerId);
+static void Task_InitMultiPartnerPartySlideIn(u8 taskId);
+static void Task_WaitAfterMultiPartnerPartySlideIn(u8 taskId);
+static void SlideMultiPartyMenuBoxSpritesOneStep(u8 taskId);
+static void Task_MultiPartnerPartySlideIn(u8 taskId);
+static bool8 CB2_FadeFromPartyMenu(void);
+static void Task_PartyMenuWaitForFade(u8 taskId);
+static void sub_8120C6C(u8 taskId);
+static void sub_8120CA8(u8 taskId);
+static void sub_8120CD8(u8 taskId);
+static void sub_8120D08(u8 taskId);
+static void sub_8120D40(u8 taskId);
+static void sub_8120D7C(u8 taskId);
+static void sub_8120DAC(u8 taskId);
+static void sub_8120DE0(u8 taskId);
+static void sub_8120E1C(u8 taskId);
+static void sub_8120E58(u8 taskId);
+static void sub_8120EE0(u8 taskId);
+static void sub_8120FF0(u8 taskId);
+static bool8 sub_8120F78(u8 taskId);
+static void sub_8120FB0(void);
+static void sub_8122084(u8 windowId, const u8 *str);
+static u8 sub_81220D4(void);
+static void sub_8122110(u8 windowId);
+static void sub_812358C(void);
+static void sub_8124BB0(struct Pokemon *mon, u8 fieldMove);
+static void sub_8124DE0(void);
+static void sub_8124E48(void);
+static void sub_812580C(u8 taskId);
+static void sub_8125898(u8 taskId, UNUSED TaskFunc func);
+static void sub_8125F4C(u8 taskId, UNUSED TaskFunc func);
+static void sub_8125F5C(u8 taskId);
+static void sub_8126BD4(void);
+static bool8 sub_8126C24(void);
+
+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 gPartyMenuUseExitCallback = FALSE;
+EWRAM_DATA u8 gSelectedMonPartyId = 0;
+EWRAM_DATA MainCallback gPostMenuFieldCallback = NULL;
+static EWRAM_DATA u16 *sSlot1TilemapBuffer = NULL; // for switching party slots
+static EWRAM_DATA u16 *sSlot2TilemapBuffer = NULL;
+static EWRAM_DATA struct Pokemon *sSacredAshQuestLogMonBackup = NULL;
+EWRAM_DATA u8 gSelectedOrderFromParty[3] = {0};
+static EWRAM_DATA u16 sPartyMenuItemId = ITEM_NONE;
+ALIGNED(4) EWRAM_DATA u8 gBattlePartyCurrentOrder[PARTY_SIZE / 2] = {0}; // bits 0-3 are the current pos of Slot 1, 4-7 are Slot 2, and so on
+
+void (*gItemUseCB)(u8, TaskFunc);
+
+#include "data/pokemon/tutor_learnsets.h"
+#include "data/party_menu.h"
+
+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->lastSelectedSlot = 0;
+ 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 < NELEMS(sPartyMenuInternal->data); ++i)
+ sPartyMenuInternal->data[i] = 0;
+ for (i = 0; i < NELEMS(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 = FALSE;
+ CalculatePlayerPartyCount();
+ SetMainCallback2(CB2_InitPartyMenu);
+ }
+}
+
+static void CB2_UpdatePartyMenu(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ DoScheduledBgTilemapCopiesToVram();
+ UpdatePaletteFade();
+}
+
+static void VBlankCB_PartyMenu(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void CB2_InitPartyMenu(void)
+{
+ while (TRUE)
+ {
+ if (sub_80BF748() == TRUE || ShowPartyMenu() == TRUE || MenuHelpers_LinkSomething() == TRUE)
+ break;
+ }
+}
+
+static bool8 ShowPartyMenu(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankHBlankCallbacksToNull();
+ ResetVramOamAndBgCntRegs();
+ ClearScheduledBgCopiesToVram();
+ ++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 (!MenuHelpers_LinkSomething())
+ 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 (CreatePartyMonSpritesLoop())
+ {
+ 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:
+ CreateCancelConfirmWindows(sPartyMenuInternal->chooseHalf);
+ ++gMain.state;
+ break;
+ case 19:
+ HelpSystem_SetSomeVariable2(5);
+ ++gMain.state;
+ break;
+ case 20:
+ CreateTask(sPartyMenuInternal->task, 0);
+ DisplayPartyMenuStdMessage(sPartyMenuInternal->messageId);
+ ++gMain.state;
+ break;
+ case 21:
+ BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK);
+ ++gMain.state;
+ break;
+ case 22:
+ BeginNormalPaletteFade(0xFFFFFFFF, -2, 16, 0, RGB_BLACK);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ ++gMain.state;
+ break;
+ default:
+ SetVBlankCallback(VBlankCB_PartyMenu);
+ SetMainCallback2(CB2_UpdatePartyMenu);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void ExitPartyMenu(void)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, -2, 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)
+{
+ ResetAllBgsCoordinatesAndBgCntRegs();
+ sPartyBgTilemapBuffer = Alloc(0x800);
+ if (sPartyBgTilemapBuffer == NULL)
+ return FALSE;
+ memset(sPartyBgTilemapBuffer, 0, 0x800);
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sPartyMenuBgTemplates, NELEMS(sPartyMenuBgTemplates));
+ SetBgTilemapBuffer(1, sPartyBgTilemapBuffer);
+ ScheduleBgCopyTilemapToVram(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 = MallocAndDecompress(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;
+ }
+ // 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_MULTI_SHOWCASE && slot >= MULTI_PARTY_SIZE)
+ {
+ DisplayPartyPokemonDataForMultiBattle(slot);
+ LoadPartyBoxPalette(&sPartyMenuBoxes[slot], PARTY_PAL_MULTI_ALT);
+ CopyWindowToVram(sPartyMenuBoxes[slot].windowId, 2);
+ PutWindowTilemap(sPartyMenuBoxes[slot].windowId);
+ ScheduleBgCopyTilemapToVram(2);
+ }
+ else
+ {
+ if (GetMonData(&gPlayerParty[slot], MON_DATA_SPECIES) == SPECIES_NONE)
+ {
+ DrawEmptySlot(sPartyMenuBoxes[slot].windowId);
+ CopyWindowToVram(sPartyMenuBoxes[slot].windowId, 2);
+ }
+ else
+ {
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_CHOOSE_HALF)
+ DisplayPartyPokemonDataForChooseHalf(slot);
+ else if (gPartyMenu.menuType == PARTY_MENU_TYPE_MINIGAME)
+ DisplayPartyPokemonDataForWirelessMinigame(slot);
+ else if (!DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(slot))
+ DisplayPartyPokemonData(slot);
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_MULTI_SHOWCASE)
+ AnimatePartySlot(slot, 0);
+ else if (gPartyMenu.slotId == slot)
+ AnimatePartySlot(slot, 1);
+ else
+ AnimatePartySlot(slot, 0);
+ }
+ PutWindowTilemap(sPartyMenuBoxes[slot].windowId);
+ ScheduleBgCopyTilemapToVram(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;
+ u8 maxBattlers;
+
+ if (!GetBattleEntryEligibility(mon))
+ {
+ DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE);
+ }
+ else
+ {
+ if (gPartyMenu.unk_8_6 == 2)
+ maxBattlers = 2;
+ else
+ maxBattlers = 3;
+ for (i = 0; i < maxBattlers; ++i)
+ {
+ if (order[i] != 0 && (order[i] - 1) == slot)
+ {
+ DisplayPartyPokemonDescriptionData(slot, i + PARTYBOX_DESC_FIRST);
+ return;
+ }
+ }
+ DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE_3);
+ }
+}
+
+static void DisplayPartyPokemonDataForWirelessMinigame(u8 slot)
+{
+ if (IsMonAllowedInMinigame(slot) == TRUE)
+ DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_ABLE);
+ else
+ DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NOT_ABLE);
+}
+
+// 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;
+ if (gSpecialVar_0x8005 > 14)
+ return 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;
+ }
+}
+
+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);
+ if (StringLength(gStringVar1) <= 5)
+ ConvertInternationalString(gStringVar1, 1);
+ 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];
+}
+
+static void CreatePartyMonSprites(u8 slot)
+{
+ u8 actualSlot;
+
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_MULTI_SHOWCASE && slot >= MULTI_PARTY_SIZE)
+ {
+ u8 status;
+
+ actualSlot = slot - MULTI_PARTY_SIZE;
+ if (gMultiPartnerParty[actualSlot].species != SPECIES_NONE)
+ {
+ CreatePartyMonIconSpriteParameterized(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].personality, &sPartyMenuBoxes[slot], 0, FALSE);
+ CreatePartyMonHeldItemSpriteParameterized(gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].heldItem, &sPartyMenuBoxes[slot]);
+ CreatePartyMonPokeballSpriteParameterized(gMultiPartnerParty[actualSlot].species, &sPartyMenuBoxes[slot]);
+ if (gMultiPartnerParty[actualSlot].hp == 0)
+ status = AILMENT_FNT;
+ else
+ status = GetAilmentFromStatus(gMultiPartnerParty[actualSlot].status);
+ CreatePartyMonStatusSpriteParameterized(gMultiPartnerParty[actualSlot].species, status, &sPartyMenuBoxes[slot]);
+ }
+ }
+ else if (GetMonData(&gPlayerParty[slot], MON_DATA_SPECIES) != SPECIES_NONE)
+ {
+ CreatePartyMonIconSprite(&gPlayerParty[slot], &sPartyMenuBoxes[slot], slot);
+ CreatePartyMonHeldItemSprite(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
+ CreatePartyMonPokeballSprite(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
+ CreatePartyMonStatusSprite(&gPlayerParty[slot], &sPartyMenuBoxes[slot]);
+ }
+}
+
+static bool8 CreatePartyMonSpritesLoop(void)
+{
+ CreatePartyMonSprites(sPartyMenuInternal->data[0]);
+ if (++sPartyMenuInternal->data[0] == PARTY_SIZE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void CreateCancelConfirmPokeballSprites(void)
+{
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_MULTI_SHOWCASE)
+ {
+ // The showcase has no Cancel/Confirm buttons
+ FillBgTilemapBufferRect(1, 14, 23, 17, 7, 2, 1);
+ }
+ else
+ {
+ if (sPartyMenuInternal->chooseHalf)
+ {
+ sPartyMenuInternal->spriteIdConfirmPokeball = CreateSmallPokeballButtonSprite(0xBF, 0x88);
+ DrawCancelConfirmButtons();
+ sPartyMenuInternal->spriteIdCancelPokeball = CreateSmallPokeballButtonSprite(0xBF, 0x98);
+ }
+ else
+ {
+ sPartyMenuInternal->spriteIdCancelPokeball = CreatePokeballButtonSprite(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: // Confirm
+ if (animNum == 0)
+ SetBgTilemapPalette(1, 23, 16, 7, 2, 1);
+ else
+ SetBgTilemapPalette(1, 23, 16, 7, 2, 2);
+ spriteId = sPartyMenuInternal->spriteIdConfirmPokeball;
+ break;
+ case PARTY_SIZE + 1: // Cancel
+ // The position of the Cancel button changes if Confirm is present
+ if (!sPartyMenuInternal->chooseHalf)
+ {
+ if (animNum == 0)
+ SetBgTilemapPalette(1, 23, 17, 7, 2, 1);
+ else
+ SetBgTilemapPalette(1, 23, 17, 7, 2, 2);
+ }
+ else if (animNum == 0)
+ {
+ SetBgTilemapPalette(1, 23, 18, 7, 2, 1);
+ }
+ else
+ {
+ SetBgTilemapPalette(1, 23, 18, 7, 2, 2);
+ }
+ spriteId = sPartyMenuInternal->spriteIdCancelPokeball;
+ break;
+ }
+ PartyMenuStartSpriteAnim(spriteId, animNum);
+ ScheduleBgCopyTilemapToVram(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 (gPartyMenu.layout == PARTY_LAYOUT_MULTI
+ && (slot == 1 || slot == 4 || slot == 5))
+ 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 void DrawCancelConfirmButtons(void)
+{
+ CopyToBgTilemapBufferRect_ChangePalette(1, sConfirmButton_Tilemap, 23, 16, 7, 2, 17);
+ CopyToBgTilemapBufferRect_ChangePalette(1, sCancelButton_Tilemap, 23, 18, 7, 2, 17);
+ ScheduleBgCopyTilemapToVram(1);
+}
+
+bool8 IsMultiBattle(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattleTypeFlags & BATTLE_TYPE_LINK)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void SwapPartyPokemon(struct Pokemon *mon1, struct Pokemon *mon2)
+{
+ struct Pokemon *buffer = Alloc(sizeof(struct Pokemon));
+
+ *buffer = *mon1;
+ *mon1 = *mon2;
+ *mon2 = *buffer;
+ Free(buffer);
+}
+
+static void Task_ClosePartyMenu(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, -2, 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);
+ FreePartyPointers();
+ DestroyTask(taskId);
+ }
+}
+
+u8 GetCursorSelectionMonId(void)
+{
+ return gPartyMenu.slotId;
+}
+
+u8 GetPartyMenuType(void)
+{
+ return gPartyMenu.menuType;
+}
+
+void Task_HandleChooseMonInput(u8 taskId)
+{
+ if (!gPaletteFade.active && sub_80BF748() != 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);
+ MoveCursorToConfirm();
+ }
+ 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)
+ {
+ case PARTY_ACTION_SOFTBOILED:
+ if (IsSelectedMonNotEgg((u8 *)slotPtr))
+ Task_TryUseSoftboiledOnPartyMon(taskId);
+ break;
+ case PARTY_ACTION_USE_ITEM:
+ if (IsSelectedMonNotEgg((u8 *)slotPtr))
+ {
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
+ sPartyMenuInternal->exitCallback = CB2_SetUpExitToBattleScreen;
+ gItemUseCB(taskId, Task_ClosePartyMenuAfterText);
+ }
+ break;
+ case PARTY_ACTION_MOVE_TUTOR:
+ if (IsSelectedMonNotEgg((u8 *)slotPtr))
+ {
+ PlaySE(SE_SELECT);
+ TryTutorSelectedMon(taskId);
+ }
+ break;
+ case PARTY_ACTION_GIVE_MAILBOX_MAIL:
+ if (IsSelectedMonNotEgg((u8 *)slotPtr))
+ {
+ PlaySE(SE_SELECT);
+ TryGiveMailToSelectedMon(taskId);
+ }
+ break;
+ case PARTY_ACTION_GIVE_ITEM:
+ case PARTY_ACTION_GIVE_PC_ITEM:
+ if (IsSelectedMonNotEgg((u8 *)slotPtr))
+ {
+ PlaySE(SE_SELECT);
+ TryGiveItemOrMailToSelectedMon(taskId);
+ }
+ break;
+ case PARTY_ACTION_SWITCH:
+ PlaySE(SE_SELECT);
+ SwitchSelectedMons(taskId);
+ break;
+ case PARTY_ACTION_CHOOSE_AND_CLOSE:
+ PlaySE(SE_SELECT);
+ gSpecialVar_0x8004 = *slotPtr;
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_MOVE_RELEARNER)
+ gSpecialVar_0x8005 = GetNumberOfRelearnableMoves(&gPlayerParty[*slotPtr]);
+ Task_ClosePartyMenu(taskId);
+ break;
+ case PARTY_ACTION_MINIGAME:
+ if (IsSelectedMonNotEgg((u8 *)slotPtr))
+ TryEnterMonForMinigame(taskId, (u8)*slotPtr);
+ break;
+ default:
+ case PARTY_ACTION_ABILITY_PREVENTS:
+ case PARTY_ACTION_SWITCHING:
+ 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 (gPartyMenu.menuType == PARTY_MENU_TYPE_CHOOSE_HALF)
+ {
+ DisplayCancelChooseMonYesNo(taskId);
+ }
+ else
+ {
+ if (!MenuHelpers_LinkSomething())
+ gSpecialVar_0x8004 = PARTY_SIZE + 1;
+ gPartyMenuUseExitCallback = FALSE;
+ *slotPtr = PARTY_SIZE + 1;
+ Task_ClosePartyMenu(taskId);
+ }
+ break;
+ }
+}
+
+static void DisplayCancelChooseMonYesNo(u8 taskId)
+{
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
+ StringExpandPlaceholders(gStringVar4, gUnknown_84176CF);
+ DisplayPartyMenuMessage(gStringVar4, TRUE);
+ gTasks[taskId].func = Task_CancelChooseMonYesNo;
+}
+
+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:
+ gPartyMenuUseExitCallback = 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 = MENU_DIR_UP;
+ break;
+ case DPAD_DOWN:
+ movementDir = MENU_DIR_DOWN;
+ break;
+ case DPAD_LEFT:
+ movementDir = MENU_DIR_LEFT;
+ break;
+ case DPAD_RIGHT:
+ movementDir = MENU_DIR_RIGHT;
+ break;
+ default:
+ switch (GetLRKeysPressedAndHeld())
+ {
+ case MENU_L_PRESSED:
+ movementDir = MENU_DIR_UP;
+ break;
+ case MENU_R_PRESSED:
+ movementDir = MENU_DIR_DOWN;
+ break;
+ default:
+ movementDir = 0;
+ break;
+ }
+ break;
+ }
+ if (JOY_NEW(START_BUTTON))
+ return 8;
+ if (movementDir)
+ {
+ UpdateCurrentPartySelection(slotPtr, movementDir);
+ return 0;
+ }
+ // Pressed Cancel
+ if (JOY_NEW(A_BUTTON) && *slotPtr == PARTY_SIZE + 1)
+ return 2;
+ return JOY_NEW(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
+ UpdatePartySelectionDoubleLayout(slotPtr, movementDir);
+ if (*slotPtr != newSlotId)
+ {
+ PlaySE(SE_SELECT);
+ AnimatePartySlot(newSlotId, 0);
+ AnimatePartySlot(*slotPtr, 1);
+ }
+}
+
+static void UpdatePartySelectionSingleLayout(s8 *slotPtr, s8 movementDir)
+{
+ // PARTY_SIZE + 1 is Cancel, PARTY_SIZE is Confirm
+ switch (movementDir)
+ {
+ case MENU_DIR_UP:
+ 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 MENU_DIR_DOWN:
+ 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 MENU_DIR_RIGHT:
+ if (gPlayerPartyCount != 1 && *slotPtr == 0)
+ {
+ if (sPartyMenuInternal->lastSelectedSlot == 0)
+ *slotPtr = 1;
+ else
+ *slotPtr = sPartyMenuInternal->lastSelectedSlot;
+ }
+ break;
+ case MENU_DIR_LEFT:
+ if (*slotPtr != 0 && *slotPtr != PARTY_SIZE && *slotPtr != PARTY_SIZE + 1)
+ {
+ sPartyMenuInternal->lastSelectedSlot = *slotPtr;
+ *slotPtr = 0;
+ }
+ break;
+ }
+}
+
+static void UpdatePartySelectionDoubleLayout(s8 *slotPtr, s8 movementDir)
+{
+ // PARTY_SIZE + 1 is Cancel, PARTY_SIZE is Confirm
+ // newSlot is used temporarily as a movement direction during its later assignment
+ s8 newSlot = movementDir;
+
+ switch (movementDir)
+ {
+ case MENU_DIR_UP:
+ 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;
+ }
+ newSlot = GetNewSlotDoubleLayout(*slotPtr, newSlot);
+ if (newSlot != -1)
+ *slotPtr = newSlot;
+ break;
+ case MENU_DIR_DOWN:
+ if (*slotPtr == PARTY_SIZE)
+ {
+ *slotPtr = PARTY_SIZE + 1;
+ }
+ else if (*slotPtr == PARTY_SIZE + 1)
+ {
+ *slotPtr = 0;
+ }
+ else
+ {
+ newSlot = GetNewSlotDoubleLayout(*slotPtr, MENU_DIR_DOWN);
+ if (newSlot == -1)
+ {
+ if (sPartyMenuInternal->chooseHalf)
+ *slotPtr = PARTY_SIZE;
+ else
+ *slotPtr = PARTY_SIZE + 1;
+ }
+ else
+ {
+ *slotPtr = newSlot;
+ }
+ }
+ break;
+ case MENU_DIR_RIGHT:
+ if (*slotPtr == 0)
+ {
+ if (sPartyMenuInternal->lastSelectedSlot == 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->lastSelectedSlot == 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 MENU_DIR_LEFT:
+ if (*slotPtr == 2 || *slotPtr == 3)
+ {
+ sPartyMenuInternal->lastSelectedSlot = *slotPtr;
+ *slotPtr = 0;
+ }
+ else if (*slotPtr == 4 || *slotPtr == 5)
+ {
+ sPartyMenuInternal->lastSelectedSlot = *slotPtr;
+ *slotPtr = 1;
+ }
+ break;
+ }
+}
+
+static s8 GetNewSlotDoubleLayout(s8 slotId, s8 movementDir)
+{
+ while (TRUE)
+ {
+ slotId += movementDir;
+ 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 (RunTextPrinters_CheckActive(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_80BF748() != 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 (MenuHelpers_LinkSomething() == 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 a4)
+{
+ if (!a4)
+ ItemUse_SetQuestLogEvent(5, mon, item, 0xFFFF);
+ else if (gPartyMenu.action == PARTY_ACTION_GIVE_PC_ITEM)
+ ItemUse_SetQuestLogEvent(7, mon, item, 0xFFFF);
+ else
+ ItemUse_SetQuestLogEvent(6, mon, item, 0xFFFF);
+ GetMonNickname(mon, gStringVar1);
+ CopyItemName(item, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnWasGivenItem);
+ DisplayPartyMenuMessage(gStringVar4, keepOpen);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void DisplayTookHeldItemMessage(struct Pokemon *mon, u16 item, bool8 keepOpen)
+{
+ ItemUse_SetQuestLogEvent(8, mon, item, 0xFFFF);
+ GetMonNickname(mon, gStringVar1);
+ CopyItemName(item, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gText_ReceivedItemFromPkmn);
+ DisplayPartyMenuMessage(gStringVar4, keepOpen);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void DisplayAlreadyHoldingItemSwitchMessage(struct Pokemon *mon, u16 item, bool8 keepOpen)
+{
+ GetMonNickname(mon, gStringVar1);
+ CopyItemName(item, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnAlreadyHoldingItemSwitch);
+ DisplayPartyMenuMessage(gStringVar4, keepOpen);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void DisplaySwitchedHeldItemMessage(u16 item, u16 item2, bool8 keepOpen)
+{
+ sub_8124B60(&gPlayerParty[gPartyMenu.slotId], item2, item);
+ CopyItemName(item, gStringVar1);
+ CopyItemName(item2, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gText_SwitchedPkmnItem);
+ DisplayPartyMenuMessage(gStringVar4, keepOpen);
+ ScheduleBgCopyTilemapToVram(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 itemId)
+{
+ const u8 *string;
+
+ switch (ItemId_GetPocket(itemId))
+ {
+ default:
+ string = gStartMenuText_Bag;
+ break;
+ case POCKET_TM_CASE:
+ string = ItemId_GetName(ITEM_TM_CASE);
+ break;
+ case POCKET_BERRY_POUCH:
+ string = ItemId_GetName(ITEM_BERRY_POUCH);
+ break;
+ }
+ StringCopy(gStringVar1, string);
+ 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 task)
+{
+ 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, task);
+}
+
+// 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.data1;
+ gPartyMenu.data1 = 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.data1 >> 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);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
+ }
+}
+
+static void CancelParticipationPrompt(u8 taskId)
+{
+ DisplayPartyMenuMessage(gText_CancelParticipation, TRUE);
+ ScheduleBgCopyTilemapToVram(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);
+ }
+ 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)
+{
+ switch (tutor)
+ {
+ case TUTOR_MOVE_FRENZY_PLANT:
+ return MOVE_FRENZY_PLANT;
+ case TUTOR_MOVE_BLAST_BURN:
+ return MOVE_BLAST_BURN;
+ case TUTOR_MOVE_HYDRO_CANNON:
+ return MOVE_HYDRO_CANNON;
+ default:
+ return sTutorMoves[tutor];
+ }
+}
+
+static bool8 CanLearnTutorMove(u16 species, u8 tutor)
+{
+ switch (tutor)
+ {
+ case TUTOR_MOVE_FRENZY_PLANT:
+ if (species == SPECIES_VENUSAUR)
+ return TRUE;
+ else
+ return FALSE;
+ case TUTOR_MOVE_BLAST_BURN:
+ if (species == SPECIES_CHARIZARD)
+ return TRUE;
+ else
+ return FALSE;
+ case TUTOR_MOVE_HYDRO_CANNON:
+ if (species == SPECIES_BLASTOISE)
+ return TRUE;
+ else
+ return FALSE;
+ default:
+ if (sTutorLearnsets[species] & (1 << tutor))
+ return TRUE;
+ else
+ return FALSE;
+ }
+}
+
+static void sub_8120C3C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = sub_8120C6C;
+}
+
+static void sub_8120C6C(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFF1FFF, 4, 0, 6, RGB_BLACK);
+ gTasks[taskId].func = sub_8120CA8;
+}
+
+static void sub_8120CA8(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = sub_8120CD8;
+}
+
+static void sub_8120CD8(u8 taskId)
+{
+ gTasks[taskId].data[0] = sub_81220D4();
+ gTasks[taskId].func = sub_8120D08;
+}
+
+static void sub_8120D08(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (RunTextPrinters_CheckActive((u8)data[0]) != TRUE)
+ gTasks[taskId].func = sub_8120D40;
+}
+
+static void sub_8120D40(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFF0008, 4, 6, 0, RGB_BLACK);
+ gTasks[taskId].func = sub_8120D7C;
+}
+
+static void sub_8120D7C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = sub_8120DAC;
+}
+
+static void sub_8120DAC(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ sub_8122084(data[0], gUnknown_8417494);
+ gTasks[taskId].func = sub_8120DE0;
+}
+
+static void sub_8120DE0(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (RunTextPrinters_CheckActive((u8)data[0]) != TRUE)
+ {
+ sub_8122110((u8)data[0]);
+ gTasks[taskId].func = sub_8120E1C;
+ }
+}
+
+static void sub_8120E1C(u8 taskId)
+{
+ BeginNormalPaletteFade(0x0000FFF7, 4, 6, 0, RGB_BLACK);
+ gTasks[taskId].func = sub_8120E58;
+}
+
+static void sub_8120E58(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ TextWindow_SetUserSelectedFrame(0, 0x4F, 0xD0);
+ TextWindow_SetStdFrame0_WithPal(0, 0x58, 0xF0);
+ if (gPartyMenu.action == PARTY_ACTION_USE_ITEM)
+ DisplayPartyMenuStdMessage(PARTY_MSG_USE_ON_WHICH_MON);
+ else
+ DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
+ }
+}
+
+static void sub_8120EBC(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ data[0] = 0;
+ gTasks[taskId].func = sub_8120EE0;
+}
+
+static void sub_8120EE0(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active && sub_8120F78(taskId) != TRUE)
+ {
+ switch (data[0])
+ {
+ case 80:
+ UpdateCurrentPartySelection(&gPartyMenu.slotId, 2);
+ break;
+ case 160:
+ PlaySE(SE_SELECT);
+ CreateSelectionWindow();
+ break;
+ case 240:
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[2]);
+ sCursorOptions[sPartyMenuInternal->actions[0]].func(taskId);
+ break;
+ }
+ ++data[0];
+ }
+}
+
+static bool8 sub_8120F78(u8 taskId)
+{
+ if (JOY_NEW(B_BUTTON))
+ {
+ sPartyMenuInternal->exitCallback = sub_8120FB0;
+ Task_ClosePartyMenu(taskId);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_8120FB0(void)
+{
+ FreeRestoreBattleData();
+ LoadPlayerParty();
+ SetTeachyTvControllerModeToResume();
+ SetMainCallback2(CB2_ReturnToTeachyTV);
+}
+
+static void sub_8120FCC(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ data[0] = 0;
+ gTasks[taskId].func = sub_8120FF0;
+}
+
+static void sub_8120FF0(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active && sub_8120F78(taskId) != TRUE)
+ {
+ if (data[0] != 80)
+ {
+ ++data[0];
+ }
+ else
+ {
+ sPartyMenuInternal->exitCallback = CB2_SetUpExitToBattleScreen;
+ gItemUseCB(taskId, Task_ClosePartyMenuAfterText);
+ }
+ }
+}
+
+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));
+ TextWindow_SetUserSelectedFrame(0, 0x4F, 0xD0);
+ TextWindow_SetStdFrame0_WithPal(0, 0x58, 0xF0);
+ LoadPalette(stdpal_get(2), 0xC0, 0x20);
+ LoadPalette(stdpal_get(0), 0xE0, 0x20);
+}
+
+static void CreateCancelConfirmWindows(bool8 chooseHalf)
+{
+ u8 confirmWindowId;
+ u8 cancelWindowId;
+ u8 offset;
+
+ if (gPartyMenu.menuType != PARTY_MENU_TYPE_MULTI_SHOWCASE)
+ {
+ if (chooseHalf == TRUE)
+ {
+ confirmWindowId = AddWindow(&sConfirmButtonWindowTemplate);
+ FillWindowPixelBuffer(confirmWindowId, PIXEL_FILL(0));
+ AddTextPrinterParameterized4(confirmWindowId, 0, (48 - GetStringWidth(0, gMenuText_Confirm, 0)) / 2u, 1, 0, 0, sFontColorTable[0], -1, gMenuText_Confirm);
+ PutWindowTilemap(confirmWindowId);
+ CopyWindowToVram(confirmWindowId, 2);
+ cancelWindowId = AddWindow(&sMultiCancelButtonWindowTemplate);
+ offset = 0;
+ }
+ else
+ {
+ cancelWindowId = AddWindow(&sCancelButtonWindowTemplate);
+ offset = 3;
+ }
+ FillWindowPixelBuffer(cancelWindowId, PIXEL_FILL(0));
+ // Branches are functionally identical. Second branch is never reached, Spin Trade wasnt fully implemented
+ if (gPartyMenu.menuType != PARTY_MENU_TYPE_SPIN_TRADE)
+ {
+ offset += (48 - GetStringWidth(0, gFameCheckerText_Cancel, 0)) / 2;
+ AddTextPrinterParameterized3(cancelWindowId, 0, offset, 1, sFontColorTable[0], -1, gFameCheckerText_Cancel);
+ }
+ else
+ {
+ offset += (48 - GetStringWidth(0, gOtherText_Exit, 0)) / 2;
+ AddTextPrinterParameterized3(cancelWindowId, 0, offset, 1, sFontColorTable[0], -1, gOtherText_Exit);
+ }
+ PutWindowTilemap(cancelWindowId);
+ CopyWindowToVram(cancelWindowId, 2);
+ ScheduleBgCopyTilemapToVram(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)
+ 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)
+ 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);
+}
+
+#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_TO_SOFTBOIL)
+ {
+ if (palFlags & PARTY_PAL_SELECTED)
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionPalIds2, sPartyBoxPalOffsets2);
+ }
+ else
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds2, sPartyBoxPalOffsets2);
+ }
+ }
+ else if (palFlags & PARTY_PAL_SWITCHING)
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds2, sPartyBoxPalOffsets2);
+ }
+ else if (palFlags & PARTY_PAL_TO_SWITCH)
+ {
+ if (palFlags & PARTY_PAL_SELECTED)
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionPalIds2, sPartyBoxPalOffsets2);
+ }
+ else
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxSelectedForActionPalIds2, sPartyBoxPalOffsets2);
+ }
+ }
+ else if (palFlags & PARTY_PAL_FAINTED)
+ {
+ if (palFlags & PARTY_PAL_SELECTED)
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionFaintedPalIds, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionPalIds2, sPartyBoxPalOffsets2);
+ }
+ else
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxFaintedPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxFaintedPalIds2, sPartyBoxPalOffsets2);
+ }
+ }
+ else if (palFlags & PARTY_PAL_MULTI_ALT)
+ {
+ if (palFlags & PARTY_PAL_SELECTED)
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionMultiPalIds, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionPalIds2, sPartyBoxPalOffsets2);
+ }
+ else
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxMultiPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxMultiPalIds2, sPartyBoxPalOffsets2);
+ }
+ }
+ else if (palFlags & PARTY_PAL_SELECTED)
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxCurrSelectionPalIds2, sPartyBoxPalOffsets2);
+ }
+ else
+ {
+ LOAD_PARTY_BOX_PAL(sPartyBoxEmptySlotPalIds1, sPartyBoxPalOffsets1);
+ LOAD_PARTY_BOX_PAL(sPartyBoxEmptySlotPalIds2, sPartyBoxPalOffsets2);
+ }
+}
+
+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_Lv);
+ 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 != 0)
+ menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->descTextLeft >> 3, menuBox->infoRects->descTextTop >> 3, menuBox->infoRects->descTextWidth >> 3, menuBox->infoRects->descTextHeight >> 3, 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;
+ ScheduleBgCopyTilemapToVram(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;
+ default:
+ *windowPtr = AddWindow(&sDefaultPartyMsgWindowTemplate);
+ break;
+ }
+
+ if (stringId == PARTY_MSG_CHOOSE_MON)
+ {
+ if (sPartyMenuInternal->chooseHalf)
+ stringId = PARTY_MSG_CHOOSE_MON_AND_CONFIRM;
+ else if (!ShouldUseChooseMonText())
+ stringId = PARTY_MSG_CHOOSE_MON_OR_CANCEL;
+ }
+ DrawStdFrameWithCustomTileAndPalette(*windowPtr, FALSE, 0x58, 0xF);
+ StringExpandPlaceholders(gStringVar4, sActionStringTable[stringId]);
+ AddTextPrinterParameterized(*windowPtr, 2, gStringVar4, 0, 2, 0, 0);
+ ScheduleBgCopyTilemapToVram(2);
+ }
+}
+
+static bool8 ShouldUseChooseMonText(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:
+ window = SetWindowTemplateFields(2, 19, 19 - (sPartyMenuInternal->numActions * 2), 10, sPartyMenuInternal->numActions * 2, 14, 0x2BF);
+ 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 == SELECTWINDOW_MOVES)
+ return sPartyMenuInternal->windowId[0];
+ cursorDimension = GetMenuCursorDimensionByFont(2, 0);
+ fontAttribute = GetFontAttribute(2, FONTATTR_LETTER_SPACING);
+ for (i = 0; i < sPartyMenuInternal->numActions; ++i)
+ {
+ u8 fontColorsId = (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) ? 4 : 3;
+
+ AddTextPrinterParameterized4(sPartyMenuInternal->windowId[0], 2, cursorDimension, (i * 16) + 2, fontAttribute, 0, sFontColorTable[fontColorsId], 0, sCursorOptions[sPartyMenuInternal->actions[i]].text);
+ }
+ Menu_InitCursorInternal(sPartyMenuInternal->windowId[0], 2, 0, 2, 16, sPartyMenuInternal->numActions, 0, 1);
+ ScheduleBgCopyTilemapToVram(2);
+ return sPartyMenuInternal->windowId[0];
+}
+
+static void PartyMenuPrintText(const u8 *text)
+{
+ DrawStdFrameWithCustomTileAndPalette(6, FALSE, 0x4F, 13);
+ gTextFlags.canABSpeedUpPrint = TRUE;
+ AddTextPrinterParameterized2(6, 2, text, GetTextSpeedSetting(), 0, 2, 1, 3);
+}
+
+static void PartyMenuDisplayYesNoMenu(void)
+{
+ CreateYesNoMenu(&sPartyMenuYesNoWindowTemplate, 2, 0, 2, 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 sub_8122084(u8 windowId, const u8 *str)
+{
+ StringExpandPlaceholders(gStringVar4, str);
+ gTextFlags.canABSpeedUpPrint = TRUE;
+ AddTextPrinterParameterized2(windowId, 4, gStringVar4, GetTextSpeedSetting(), 0, 2, 1, 3);
+}
+
+static bool8 sub_81220D4(void)
+{
+ u8 windowId = AddWindow(&gUnknown_845A170);
+
+ TextWindow_LoadResourcesStdFrame0(windowId, 0x4F, 0xE0);
+ DrawDialogFrameWithCustomTileAndPalette(windowId, 1, 0x4F, 0xE);
+ sub_8122084(windowId, gUnknown_8417457);
+ return windowId;
+}
+
+static void sub_8122110(u8 windowId)
+{
+ ClearWindowTilemap(windowId);
+ ClearDialogWindowAndFrameToTransparent(windowId, FALSE);
+ RemoveWindow(windowId);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void sub_8122138(u8 action)
+{
+ u8 attr;
+ struct PartyMenuInternal *ptr = sPartyMenuInternal;
+
+ if (action <= 17)
+ {
+ if (ptr->windowId[2] != 0xFF)
+ {
+ ClearWindowTilemap(ptr->windowId[2]);
+ RemoveWindow(ptr->windowId[2]);
+ ptr->windowId[2] = 0xFF;
+ ScheduleBgCopyTilemapToVram(2);
+ }
+ }
+ else
+ {
+ if (ptr->windowId[2] == 0xFF)
+ ptr->windowId[2] = AddWindow(&gUnknown_845A178);
+ sub_8112F18(ptr->windowId[2]);
+ attr = GetFontAttribute(2, FONTATTR_LETTER_SPACING);
+ AddTextPrinterParameterized4(ptr->windowId[2], 2, 3, 6, attr, 0, sFontColorTable[5], 0, sHMDescriptionTable[action - MENU_FIELD_MOVES]);
+ PutWindowTilemap(ptr->windowId[2]);
+ ScheduleBgCopyTilemapToVram(2);
+ }
+}
+
+static void CreatePartyMonIconSprite(struct Pokemon *mon, struct PartyMenuBox *menuBox, u32 slot)
+{
+ bool32 handleDeoxys = TRUE;
+ u16 species2;
+
+ // If in a multi battle, show partners Deoxys icon as Normal forme
+ if (IsMultiBattle() == TRUE && gMain.inBattle)
+ handleDeoxys = (sMultiBattlePartnersPartyMask[slot] ^ handleDeoxys) ? TRUE : FALSE;
+ species2 = GetMonData(mon, MON_DATA_SPECIES2);
+ CreatePartyMonIconSpriteParameterized(species2, GetMonData(mon, MON_DATA_PERSONALITY), menuBox, 1, handleDeoxys);
+ UpdatePartyMonHPBar(menuBox->monSpriteId, mon);
+}
+
+static void CreatePartyMonIconSpriteParameterized(u16 species, u32 pid, struct PartyMenuBox *menuBox, u8 priority, bool32 handleDeoxys)
+{
+ if (species != SPECIES_NONE)
+ {
+ menuBox->monSpriteId = CreateMonIcon(species, SpriteCB_MonIcon, menuBox->spriteCoords[0], menuBox->spriteCoords[1], 4, pid, handleDeoxys);
+ 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 = SpriteCB_UpdatePartyMonIcon;
+ }
+ else
+ {
+ gSprites[spriteId].pos2.x = 0;
+ gSprites[spriteId].pos2.y = 0;
+ gSprites[spriteId].callback = SpriteCB_BouncePartyMonIcon;
+ }
+}
+
+static void SpriteCB_BouncePartyMonIcon(struct Sprite *sprite)
+{
+ u8 animCmd = UpdateMonIconFrame(sprite);
+
+ if (animCmd != 0)
+ {
+ if (animCmd & 1) // % 2 also matches
+ sprite->pos2.y = -3;
+ else
+ sprite->pos2.y = 1;
+ }
+}
+
+static void SpriteCB_UpdatePartyMonIcon(struct Sprite *sprite)
+{
+ UpdateMonIconFrame(sprite);
+}
+
+static void CreatePartyMonHeldItemSprite(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 CreatePartyMonHeldItemSpriteParameterized(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 CreatePartyMonPokeballSprite(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 CreatePartyMonPokeballSpriteParameterized(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;
+ }
+}
+
+// For Cancel when Confirm isnt present
+static u8 CreatePokeballButtonSprite(u8 x, u8 y)
+{
+ u8 spriteId = CreateSprite(&sSpriteTemplate_MenuPokeball, x, y, 8);
+
+ gSprites[spriteId].oam.priority = 2;
+ return spriteId;
+}
+
+// For Confirm and Cancel when both are present
+static u8 CreateSmallPokeballButtonSprite(u8 x, u8 y)
+{
+ return CreateSprite(&sSpriteTemplate_MenuPokeballSmall, x, y, 8);
+}
+
+static void PartyMenuStartSpriteAnim(u8 spriteId, u8 animNum)
+{
+ StartSpriteAnim(&gSprites[spriteId], animNum);
+}
+
+// Unused. Might explain the large blank section in gPartyMenuPokeballSmall_Gfx
+// At the very least this is how the unused anim cmds for sSpriteAnimTable_MenuPokeballSmall were meant to be accessed
+void SpriteCB_BounceConfirmCancelButton(u8 spriteId, u8 spriteId2, u8 animNum)
+{
+ if (animNum == 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 CreatePartyMonStatusSprite(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 CreatePartyMonStatusSpriteParameterized(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);
+}
+
+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_END; ++j)
+ {
+ if (GetMonData(&mons[slotId], i + MON_DATA_MOVE1) == sFieldMoves[j])
+ {
+ AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, j + MENU_FIELD_MOVES);
+ break;
+ }
+ }
+ }
+ 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 (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;
+ // The following have no selection actions (i.e. they exit immediately upon selection)
+ // PARTY_MENU_TYPE_CONTEST
+ // PARTY_MENU_TYPE_CHOOSE_MON
+ // PARTY_MENU_TYPE_MULTI_SHOWCASE
+ // PARTY_MENU_TYPE_MOVE_RELEARNER
+ // PARTY_MENU_TYPE_MINIGAME
+ default:
+ actionType = ACTIONS_NONE;
+ break;
+ }
+ return actionType;
+}
+
+static void CreateSelectionWindow(void)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+
+ GetMonNickname(mon, gStringVar1);
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
+ SetPartyMonSelectionActions(gPlayerParty, gPartyMenu.slotId, GetPartyMenuActionsType(mon));
+ DisplaySelectionWindow(SELECTWINDOW_ACTIONS);
+ DisplayPartyMenuStdMessage(PARTY_MSG_DO_WHAT_WITH_MON);
+}
+
+static void Task_TryCreateSelectionWindow(u8 taskId)
+{
+ CreateSelectionWindow();
+ gTasks[taskId].data[0] = 0xFF;
+ gTasks[taskId].func = Task_HandleSelectionMenuInput;
+}
+
+static void Task_HandleSelectionMenuInput(u8 taskId)
+{
+ if (!gPaletteFade.active && sub_80BF748() != TRUE)
+ {
+ s8 input;
+ s16 *data = gTasks[taskId].data;
+
+ if (sPartyMenuInternal->numActions <= 3)
+ input = Menu_ProcessInputNoWrapAround_other();
+ else
+ input = Menu_ProcessInput_other();
+ if (data[0] != Menu_GetCursorPos())
+ sub_8122138(sPartyMenuInternal->actions[Menu_GetCursorPos()]);
+ 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(gPlayerParty, gPartyMenu.slotId, gPlayerPartyCount - 1, CB2_ReturnToPartyMenuFromSummaryScreen, 0);
+}
+
+static void CB2_ReturnToPartyMenuFromSummaryScreen(void)
+{
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ gPartyMenu.slotId = GetLastViewedMonIndex();
+ 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
+ sub_812358C();
+ 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 x, s16 width, u8 *leftMove, u8 *newX, u8 *newWidth)
+{
+ if ((x + width) < 0)
+ return FALSE;
+ if (x > 31)
+ return FALSE;
+ if (x < 0)
+ {
+ *leftMove = x * -1;
+ *newX = 0;
+ *newWidth = width + x;
+ }
+ else
+ {
+ *leftMove = 0;
+ *newX = x;
+ if ((x + width) > 31)
+ *newWidth = 32 - x;
+ else
+ *newWidth = width;
+ }
+ return TRUE;
+}
+
+static void MoveAndBufferPartySlot(const void *rectSrc, s16 x, s16 y, s16 width, s16 height, s16 dir)
+{
+ // The use of the dimension parameters here is a mess
+ u8 leftMove, newX, newWidth; // leftMove is used as a srcX, newX is used as both x and srcHeight, newWidth is used as both width and destY
+
+ if (TryMovePartySlot(x, width, &leftMove, &newX, &newWidth))
+ {
+ FillBgTilemapBufferRect_Palette0(0, 0, newX, y, newWidth, height);
+ if (TryMovePartySlot(x + dir, width, &leftMove, &newX, &newWidth))
+ CopyRectToBgTilemapBufferRect(0, rectSrc, leftMove, 0, width, height, newX, y, newWidth, height, 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);
+ ScheduleBgCopyTilemapToVram(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 slide back onscreen
+ if (tSlot1SlideDir == 0 && tSlot2SlideDir == 0)
+ {
+ PutWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId].windowId);
+ PutWindowTilemap(sPartyMenuBoxes[gPartyMenu.slotId2].windowId);
+ ScheduleBgCopyTilemapToVram(0);
+ // BUG: memory leak
+ // 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);
+}
+
+static void sub_812358C(void)
+{
+ u16 *buffer = Alloc(2 * sizeof(u16));
+
+ buffer[0] = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2);
+ buffer[1] = GetMonData(&gPlayerParty[gPartyMenu.slotId2], MON_DATA_SPECIES2);
+ sub_8113550(3, buffer);
+ Free(buffer);
+}
+
+// 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);
+}
+
+void CB2_SelectBagItemToGive(void)
+{
+ GoToBagMenu(1, 3, CB2_GiveHoldItem);
+}
+
+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);
+}
+
+static void CB2_ReturnToPartyMenuFromWritingMail(void)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
+
+ // Canceled writing mail
+ 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);
+ }
+ // Wrote mail
+ else
+ {
+ InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_CHOOSE_MON, Task_DisplayGaveMailFromPartyMessage, gPartyMenu.exitCallback);
+ }
+}
+
+// Nearly redundant with Task_DisplayGaveMailFromBagMessgae
+static void Task_DisplayGaveMailFromPartyMessage(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)
+{
+ s8 slotId = gPartyMenu.slotId;
+
+ if (IsPartyMenuTextPrinterActive() != TRUE)
+ {
+ UpdatePartyMonHeldItemSprite(&gPlayerParty[slotId], &sPartyMenuBoxes[slotId]);
+ 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;
+ }
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_UpdateHeldItemSprite;
+}
+
+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 = CB2_ReadHeldMail;
+ Task_ClosePartyMenu(taskId);
+}
+
+static void CB2_ReadHeldMail(void)
+{
+ ReadMail(&gSaveBlock1Ptr->mail[GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_MAIL)], CB2_ReturnToPartyMenuFromReadingMail, 1);
+}
+
+static void CB2_ReturnToPartyMenuFromReadingMail(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 = Task_SendMailToPCYesNo;
+}
+
+static void Task_SendMailToPCYesNo(u8 taskId)
+{
+ if (IsPartyMenuTextPrinterActive() != TRUE)
+ {
+ PartyMenuDisplayYesNoMenu();
+ gTasks[taskId].func = Task_HandleSendMailToPCYesNoInput;
+ }
+}
+
+static void Task_HandleSendMailToPCYesNoInput(u8 taskId)
+{
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case 0: // Yes, send to PC
+ 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 = Task_LoseMailMessageYesNo;
+ break;
+ }
+}
+
+static void Task_LoseMailMessageYesNo(u8 taskId)
+{
+ if (IsPartyMenuTextPrinterActive() != TRUE)
+ {
+ PartyMenuDisplayYesNoMenu();
+ gTasks[taskId].func = Task_HandleLoseMailMessageYesNoInput;
+ }
+}
+
+static void Task_HandleLoseMailMessageYesNoInput(u8 taskId)
+{
+ u16 item;
+
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case 0: // Yes, lose mail message
+ 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));
+ DisplaySelectionWindow(SELECTWINDOW_ACTIONS);
+ DisplayPartyMenuStdMessage(PARTY_MSG_DO_WHAT_WITH_MON);
+ 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;
+ const u8 *str;
+
+ if (gPartyMenu.unk_8_6 == 2)
+ {
+ maxBattlers = 2;
+ str = gUnknown_8416B3E;
+ }
+ else
+ {
+ maxBattlers = 3;
+ str = gUnknown_8416B16;
+ }
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
+ 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))
+ MoveCursorToConfirm();
+ DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
+ return;
+ }
+ }
+ PlaySE(SE_HAZURE);
+ DisplayPartyMenuMessage(str, TRUE);
+ gTasks[taskId].func = Task_ReturnToChooseMonAfterText;
+}
+
+static void MoveCursorToConfirm(void)
+{
+ AnimatePartySlot(gPartyMenu.slotId, 0);
+ gPartyMenu.slotId = PARTY_SIZE;
+ AnimatePartySlot(gPartyMenu.slotId, 1);
+}
+
+static void CursorCB_NoEntry(u8 taskId)
+{
+ u8 i;
+
+ PlaySE(SE_SELECT);
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
+ PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
+ for (i = 0; i < 3; ++i)
+ {
+ if (gSelectedOrderFromParty[i] == gPartyMenu.slotId + 1)
+ {
+ gSelectedOrderFromParty[i] = 0;
+ switch (i)
+ {
+ case 0:
+ gSelectedOrderFromParty[0] = gSelectedOrderFromParty[1];
+ gSelectedOrderFromParty[1] = gSelectedOrderFromParty[2];
+ gSelectedOrderFromParty[2] = 0;
+ break;
+ case 1:
+ gSelectedOrderFromParty[1] = gSelectedOrderFromParty[2];
+ gSelectedOrderFromParty[2] = 0;
+ break;
+ }
+ break;
+ }
+ }
+ DisplayPartyPokemonDescriptionText(PARTYBOX_DESC_ABLE_3, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
+ if (gSelectedOrderFromParty[0] != 0)
+ DisplayPartyPokemonDescriptionText(PARTYBOX_DESC_FIRST, &sPartyMenuBoxes[gSelectedOrderFromParty[0] - 1], 1);
+ if (gSelectedOrderFromParty[1] != 0)
+ DisplayPartyPokemonDescriptionText(1 + PARTYBOX_DESC_FIRST, &sPartyMenuBoxes[gSelectedOrderFromParty[1] - 1], 1);
+ DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
+}
+
+static void CursorCB_Store(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ gSpecialVar_0x8004 = gPartyMenu.slotId;
+ 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_80F9800(), 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_80F9800(), gUnknown_203B064, 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 implemented, and normally unreachable because PARTY_MENU_TYPE_SPIN_TRADE is never used
+static void CursorCB_Trade2(u8 taskId)
+{
+}
+
+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 (MenuHelpers_LinkSomething() == 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_EscapeFromHereAndReturnTo);
+ DisplayFieldMoveExitAreaMessage(taskId);
+ sPartyMenuInternal->data[0] = fieldMove;
+ break;
+ case FIELD_MOVE_FLY:
+ gPartyMenu.exitCallback = MCB2_FlyMap;
+ Task_ClosePartyMenu(taskId);
+ break;
+ default:
+ gPartyMenu.exitCallback = CB2_ReturnToField;
+ sub_8124BB0(&gPlayerParty[GetCursorSelectionMonId()], fieldMove);
+ 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;
+ sub_8124BB0(&gPlayerParty[GetCursorSelectionMonId()], sPartyMenuInternal->data[0]);
+ 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)
+{
+ sub_807DC00();
+ 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_FLASH_ACTIVE) == 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)
+{
+ s16 x, y;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ if (MetatileBehavior_IsSemiDeepWater(MapGridGetMetatileBehaviorAt(x, y)) != TRUE
+ && PartyHasMonWithSurf() == TRUE
+ && IsPlayerFacingSurfableFishableWater() == TRUE)
+ {
+ gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
+ gPostMenuFieldCallback = FieldCallback_Surf;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void DisplayCantUseSurfMessage(void)
+{
+ s16 x, y;
+
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ {
+ DisplayPartyMenuStdMessage(PARTY_MSG_ALREADY_SURFING);
+ }
+ else
+ {
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ if (MetatileBehavior_IsSemiDeepWater(MapGridGetMetatileBehaviorAt(x, y)) == TRUE)
+ DisplayPartyMenuStdMessage(PARTY_MSG_CURRENT_TOO_FAST);
+ else if ((gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE17))
+ && ((gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE17))
+ || (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE18))))
+ DisplayPartyMenuStdMessage(PARTY_MSG_ENJOY_CYCLING);
+ 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 sub_8124B60(struct Pokemon *mon, u16 item, u16 item2)
+{
+ u16 *ptr = Alloc(4 * sizeof(u16));
+
+ ptr[2] = GetMonData(mon, MON_DATA_SPECIES2);
+ ptr[0] = item;
+ ptr[1] = item2;
+ if (gPartyMenu.action == PARTY_ACTION_GIVE_PC_ITEM)
+ sub_8113550(10, ptr);
+ else
+ sub_8113550(9, ptr);
+ Free(ptr);
+}
+
+struct FieldMoveWarpParams
+{
+ u16 species;
+ u8 fieldMove;
+ u8 regionMapSectionId;
+};
+
+static void sub_8124BB0(struct Pokemon *mon, u8 fieldMove)
+{
+ struct FieldMoveWarpParams *ptr = Alloc(sizeof(*ptr));
+
+ ptr->species = GetMonData(mon, MON_DATA_SPECIES2);
+ ptr->fieldMove = fieldMove;
+ switch (ptr->fieldMove)
+ {
+ case FIELD_MOVE_TELEPORT:
+ ptr->regionMapSectionId = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->lastHealLocation.mapGroup, gSaveBlock1Ptr->lastHealLocation.mapNum)->regionMapSectionId;
+ break;
+ case FIELD_MOVE_DIG:
+ ptr->regionMapSectionId = gMapHeader.regionMapSectionId;
+ break;
+ default:
+ ptr->regionMapSectionId = 0xFF;
+ }
+ sub_8113550(36, (u16 *)ptr);
+ Free(ptr);
+}
+
+void sub_8124C1C(const u8 *healLocCtrlData) // TODO: confirm the type of data chunk at 0x83F2EE0
+{
+ const struct MapHeader *mapHeader;
+ struct FieldMoveWarpParams *ptr2;
+ struct
+ {
+ s8 mapGroup;
+ s8 mapNum;
+ u32 unk_4;
+ } *ptr = Alloc(sizeof(*ptr));
+
+ ptr->mapGroup = healLocCtrlData[0];
+ ptr->mapNum = healLocCtrlData[1];
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(ptr->mapGroup, ptr->mapNum);
+ Free(ptr);
+ ptr2 = Alloc(4);
+ ptr2->species = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_SPECIES2);
+ ptr2->fieldMove = FIELD_MOVE_FLY;
+ ptr2->regionMapSectionId = mapHeader->regionMapSectionId;
+ sub_8113550(36, (u16 *)ptr2);
+ Free(ptr2);
+}
+
+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;
+ }
+ }
+ if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_BERRY_POUCH)
+ callback = CB2_ReturnToBerryPouchMenu;
+ task = Task_SetSacredAshCB;
+ msgId = PARTY_MSG_NONE;
+ }
+ else
+ {
+ switch (GetPocketByItemId(gSpecialVar_ItemId))
+ {
+ default:
+ msgId = PARTY_MSG_USE_ON_WHICH_MON;
+ break;
+ case POCKET_TM_CASE:
+ msgId = PARTY_MSG_TEACH_WHICH_MON;
+ callback = CB2_ReturnToTMCaseMenu;
+ break;
+ case POCKET_BERRY_POUCH:
+ msgId = PARTY_MSG_USE_ON_WHICH_MON;
+ callback = CB2_ReturnToBerryPouchMenu;
+ break;
+ }
+ task = Task_HandleChooseMonInput;
+ }
+ InitPartyMenu(menuType, partyLayout, PARTY_ACTION_USE_ITEM, TRUE, msgId, task, callback);
+}
+
+static void CB2_ReturnToBagMenu(void)
+{
+ GoToBagMenu(11, 3, NULL);
+}
+
+static void CB2_ReturnToTMCaseMenu(void)
+{
+ InitTMCase(5, NULL, 0xFF);
+}
+
+static void CB2_ReturnToBerryPouchMenu(void)
+{
+ InitBerryPouch(BERRYPOUCH_NA, NULL, 0xFF);
+}
+
+static void sub_8124DC0(u8 taskId)
+{
+ sPartyMenuInternal->exitCallback = sub_8124DE0;
+ Task_ClosePartyMenu(taskId);
+}
+
+static void sub_8124DE0(void)
+{
+ if (CheckIfItemIsTMHMOrEvolutionStone(gSpecialVar_ItemId) == 2) // Evolution stone
+ {
+ if (sub_8126C24() == TRUE)
+ sub_811C540(gPartyMenu.slotId, gSpecialVar_ItemId, sub_8126BD4);
+ else
+ sub_811C5AC(gPartyMenu.slotId, gSpecialVar_ItemId, gPartyMenu.exitCallback);
+ }
+ else
+ {
+ sub_811C540(gPartyMenu.slotId, gSpecialVar_ItemId, sub_8124E48);
+ }
+}
+
+static void sub_8124E48(void)
+{
+ if (ItemId_GetPocket(gSpecialVar_ItemId) == POCKET_TM_CASE
+ && sub_811D178() == 1)
+ {
+ GiveMoveToMon(&gPlayerParty[gPartyMenu.slotId], ItemIdToBattleMoveId(gSpecialVar_ItemId));
+ AdjustFriendship(&gPlayerParty[gPartyMenu.slotId], 4);
+ if (gSpecialVar_ItemId <= ITEM_TM50)
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+ SetMainCallback2(gPartyMenu.exitCallback);
+ }
+ else
+ {
+ InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, PARTY_ACTION_CHOOSE_MON, gPartyMenu.slotId, PARTY_MSG_NONE, Task_SetSacredAshCB, gPartyMenu.exitCallback);
+ }
+}
+
+static void sub_8124EFC(void)
+{
+ if (sub_811D178() == 1)
+ {
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u8 moveIdx = GetMoveSlotToReplace();
+ u16 move = GetMonData(mon, moveIdx + MON_DATA_MOVE1);
+
+ RemoveMonPPBonus(mon, moveIdx);
+ SetMonMoveSlot(mon, ItemIdToBattleMoveId(gSpecialVar_ItemId), moveIdx);
+ AdjustFriendship(mon, 4);
+ ItemUse_SetQuestLogEvent(4, mon, gSpecialVar_ItemId, move);
+ if (gSpecialVar_ItemId <= ITEM_TM50)
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+ SetMainCallback2(gPartyMenu.exitCallback);
+ }
+ else
+ {
+ InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, gPartyMenu.slotId, PARTY_MSG_NONE, Task_SetSacredAshCB, gPartyMenu.exitCallback);
+ }
+}
+
+static void Task_SetSacredAshCB(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
+ sPartyMenuInternal->exitCallback = CB2_SetUpExitToBattleScreen;
+ gItemUseCB(taskId, Task_ClosePartyMenuAfterText); // ItemUseCB_SacredAsh in this case
+ }
+}
+
+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 func)
+{
+ u16 hp;
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u16 item = gSpecialVar_ItemId;
+ bool8 canHeal;
+
+ if (!NotUsingHPEVItemOnShedinja(mon, item))
+ {
+ canHeal = TRUE;
+ }
+ else
+ {
+ if (IsHPRecoveryItem(item) == TRUE)
+ {
+ hp = GetMonData(mon, MON_DATA_HP);
+ if (hp == GetMonData(mon, MON_DATA_MAX_HP))
+ canHeal = FALSE;
+ }
+ canHeal = PokemonItemUseNoEffect(mon, item, gPartyMenu.slotId, 0);
+ }
+ PlaySE(SE_SELECT);
+ if (canHeal)
+ {
+ gPartyMenuUseExitCallback = FALSE;
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = func;
+ }
+ else
+ {
+ ItemUse_SetQuestLogEvent(4, mon, item, 0xFFFF);
+ sub_8124DC0(taskId);
+ gItemUseCB = ItemUseCB_MedicineStep;
+ }
+}
+
+void ItemUseCB_MedicineStep(u8 taskId, TaskFunc func)
+{
+ 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))
+ {
+ WONT_HAVE_EFFECT:
+ gPartyMenuUseExitCallback = FALSE;
+ PlaySE(SE_SELECT);
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = func;
+ return;
+ }
+ }
+ else
+ {
+ goto WONT_HAVE_EFFECT; // even loop wrap won't work
+ }
+ gPartyMenuUseExitCallback = 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);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = func;
+ }
+}
+
+static void Task_DisplayHPRestoredMessage(u8 taskId)
+{
+ GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2);
+ DisplayPartyMenuMessage(gStringVar4, FALSE);
+ ScheduleBgCopyTilemapToVram(2);
+ HandleBattleLowHpMusicChange();
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+}
+
+static void Task_ClosePartyMenuAfterText(u8 taskId)
+{
+ if (IsPartyMenuTextPrinterActive() != TRUE)
+ {
+ if (gPartyMenuUseExitCallback == FALSE)
+ sPartyMenuInternal->exitCallback = NULL;
+ Task_ClosePartyMenu(taskId);
+ }
+}
+
+static void ShowMoveSelectWindow(u8 slot)
+{
+ u8 i;
+ u8 moveCount = 0;
+ u8 fontId = 2;
+ 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],
+ GetFontAttribute(fontId, FONTATTR_MAX_LETTER_WIDTH) + GetFontAttribute(fontId, FONTATTR_LETTER_SPACING),
+ (i * 16) + 2,
+ TEXT_SPEED_FF,
+ NULL);
+ if (move != MOVE_NONE)
+ ++moveCount;
+ }
+ Menu_InitCursor(windowId, fontId, 0, 2, 16, moveCount, FALSE);
+ ScheduleBgCopyTilemapToVram(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
+ {
+ SetSelectedMoveForPPItem(taskId);
+ }
+ }
+}
+
+void ItemUseCB_PPRecovery(u8 taskId, UNUSED TaskFunc func)
+{
+ 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.data1 = 0;
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
+ TryUsePPItem(taskId);
+ else
+ sub_812580C(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.data1 = Menu_GetCursorPos();
+ if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
+ TryUsePPItem(taskId);
+ else
+ sub_812580C(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 sub_812580C(u8 taskId)
+{
+ bool8 noEffect = PokemonItemUseNoEffect(&gPlayerParty[gPartyMenu.slotId],
+ gSpecialVar_ItemId,
+ gPartyMenu.slotId,
+ gPartyMenu.data1);
+ PlaySE(SE_SELECT);
+ if (noEffect)
+ {
+ gPartyMenuUseExitCallback = FALSE;
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+ }
+ else
+ {
+ sub_8124DC0(taskId);
+ gItemUseCB = sub_8125898;
+ }
+}
+
+static void sub_8125898(u8 taskId, UNUSED TaskFunc func)
+{
+ u16 move;
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+
+ ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, (u8)gPartyMenu.data1);
+ gPartyMenuUseExitCallback = TRUE;
+ ItemUse_SetQuestLogEvent(4, mon, gSpecialVar_ItemId, 0xFFFF);
+ PlaySE(SE_KAIFUKU);
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+ move = GetMonData(mon, gPartyMenu.data1 + MON_DATA_MOVE1);
+ StringCopy(gStringVar1, gMoveNames[move]);
+ GetMedicineItemEffectMessage(gSpecialVar_ItemId);
+ DisplayPartyMenuMessage(gStringVar4, 1);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+}
+
+static void TryUsePPItem(u8 taskId)
+{
+ u16 move = MOVE_NONE;
+ s16 *moveSlot = &gPartyMenu.data1;
+ u16 item = gSpecialVar_ItemId;
+ struct PartyMenu *ptr = &gPartyMenu;
+ struct Pokemon *mon;
+
+ if (ExecuteTableBasedItemEffect_(ptr->slotId, item, *moveSlot))
+ {
+ gPartyMenuUseExitCallback = FALSE;
+ PlaySE(SE_SELECT);
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+ }
+ else
+ {
+ gPartyMenuUseExitCallback = TRUE;
+ mon = &gPlayerParty[ptr->slotId];
+ ItemUse_SetQuestLogEvent(4, mon, item, 0xFFFF);
+ PlaySE(SE_KAIFUKU);
+ RemoveBagItem(item, 1);
+ move = GetMonData(mon, MON_DATA_MOVE1 + *moveSlot);
+ StringCopy(gStringVar1, gMoveNames[move]);
+ GetMedicineItemEffectMessage(item);
+ DisplayPartyMenuMessage(gStringVar4, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+ }
+}
+
+void ItemUseCB_PPUp(u8 taskId, UNUSED TaskFunc func)
+{
+ 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 - 1; ++i) // no dive
+ 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);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void DisplayLearnMoveMessageAndClose(u8 taskId, const u8 *str)
+{
+ DisplayLearnMoveMessage(str);
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+}
+
+void ItemUseCB_TMHM(u8 taskId, UNUSED TaskFunc func)
+{
+ struct Pokemon *mon;
+ s16 *move;
+ u16 item;
+
+ PlaySE(SE_SELECT);
+ mon = &gPlayerParty[gPartyMenu.slotId];
+ move = &gPartyMenu.data1;
+ 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)
+ {
+ ItemUse_SetQuestLogEvent(4, mon, item, 0xFFFF);
+ sub_8124DC0(taskId);
+ gItemUseCB = ItemUseCB_LearnedMove;
+ }
+ else
+ {
+ DisplayLearnMoveMessage(gText_PkmnNeedsToReplaceMove);
+ gTasks[taskId].func = Task_ReplaceMoveYesNo;
+ }
+}
+
+static void ItemUseCB_LearnedMove(u8 taskId, UNUSED TaskFunc func)
+{
+ Task_LearnedMove(taskId);
+}
+
+static void Task_LearnedMove(u8 taskId)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ s16 *move = &gPartyMenu.data1;
+ 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);
+ ScheduleBgCopyTilemapToVram(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.data1);
+}
+
+static void CB2_ReturnToPartyMenuWhileLearningMove(void)
+{
+ u8 moveIdx = GetMoveSlotToReplace();
+ u16 move;
+ s32 learnMoveState = gPartyMenu.learnMoveState;
+
+ if (learnMoveState == 0 && moveIdx != MAX_MON_MOVES)
+ {
+ move = GetMonData(&gPlayerParty[gPartyMenu.slotId], moveIdx + MON_DATA_MOVE1);
+ sub_811C568(gPartyMenu.slotId, gSpecialVar_ItemId, move, sub_8124EFC);
+ gItemUseCB = sub_8125F4C;
+ gPartyMenu.action = learnMoveState;
+ }
+ else
+ {
+ 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 sub_8125F4C(u8 taskId, UNUSED TaskFunc func)
+{
+ sub_8125F5C(taskId);
+}
+
+static void sub_8125F5C(u8 taskId)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u8 moveIdx = GetMoveSlotToReplace();
+ u16 move = GetMonData(mon, moveIdx + MON_DATA_MOVE1);
+
+ ItemUse_SetQuestLogEvent(4, mon, gSpecialVar_ItemId, move);
+ GetMonNickname(mon, gStringVar1);
+ StringCopy(gStringVar2, gMoveNames[move]);
+ RemoveMonPPBonus(mon, moveIdx);
+ SetMonMoveSlot(mon, gPartyMenu.data1, moveIdx);
+ Task_LearnedMove(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.data1;
+ SetMonMoveSlot(mon, move, GetMoveSlotToReplace());
+ Task_LearnedMove(taskId);
+ }
+}
+
+static void StopLearningMovePrompt(u8 taskId)
+{
+ StringCopy(gStringVar2, gMoveNames[gPartyMenu.data1]);
+ StringExpandPlaceholders(gStringVar4, gText_StopLearningMove2);
+ DisplayPartyMenuMessage(gStringVar4, TRUE);
+ ScheduleBgCopyTilemapToVram(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.data1]);
+ 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.data1]);
+ 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 func)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u16 item = gSpecialVar_ItemId;
+ bool8 noEffect;
+
+ if (GetMonData(mon, MON_DATA_LEVEL) != MAX_LEVEL)
+ noEffect = PokemonItemUseNoEffect(mon, item, gPartyMenu.slotId, 0);
+ else
+ noEffect = TRUE;
+ PlaySE(SE_SELECT);
+ if (noEffect)
+ {
+ gPartyMenuUseExitCallback = FALSE;
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = func;
+ }
+ else
+ {
+ sub_8124DC0(taskId);
+ gItemUseCB = ItemUseCB_RareCandyStep;
+ }
+}
+
+static void ItemUseCB_RareCandyStep(u8 taskId, UNUSED TaskFunc func)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ struct PartyMenuInternal *ptr = sPartyMenuInternal;
+ s16 *arrayPtr = ptr->data;
+ u8 level;
+
+ BufferMonStatsToTaskData(mon, arrayPtr);
+ ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0);
+ BufferMonStatsToTaskData(mon, &ptr->data[NUM_STATS]);
+ gPartyMenuUseExitCallback = TRUE;
+ ItemUse_SetQuestLogEvent(4, mon, gSpecialVar_ItemId, 0xFFFF);
+ PlayFanfareByFanfareNum(0);
+ UpdateMonDisplayInfoAfterRareCandy(gPartyMenu.slotId, mon);
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+ GetMonNickname(mon, gStringVar1);
+ level = GetMonData(mon, MON_DATA_LEVEL);
+ ConvertIntToDecimalStringN(gStringVar2, level, STR_CONV_MODE_LEFT_ALIGN, 3);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnElevatedToLvVar2);
+ DisplayPartyMenuMessage(gStringVar4, TRUE);
+ ScheduleBgCopyTilemapToVram(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);
+ ScheduleBgCopyTilemapToVram(0);
+}
+
+static void Task_DisplayLevelUpStatsPg1(u8 taskId)
+{
+ if (WaitFanfare(FALSE) && IsPartyMenuTextPrinterActive() != TRUE && (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)))
+ {
+ PlaySE(SE_SELECT);
+ DisplayLevelUpStatsPg1(taskId);
+ gTasks[taskId].func = Task_DisplayLevelUpStatsPg2;
+ }
+}
+
+static void Task_DisplayLevelUpStatsPg2(u8 taskId)
+{
+ if (JOY_NEW(A_BUTTON) || JOY_NEW(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);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void DisplayLevelUpStatsPg2(u8 taskId)
+{
+ s16 *arrayPtr = sPartyMenuInternal->data;
+
+ DrawLevelUpWindowPg2(arrayPtr[12], &arrayPtr[6], 1, 2, 3);
+ CopyWindowToVram(arrayPtr[12], 2);
+ ScheduleBgCopyTilemapToVram(2);
+}
+
+static void Task_TryLearnNewMoves(u8 taskId)
+{
+ u16 learnMove;
+
+ if (WaitFanfare(0) && (JOY_NEW(A_BUTTON) || JOY_NEW(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);
+ ScheduleBgCopyTilemapToVram(2);
+ gPartyMenu.data1 = 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);
+ ScheduleBgCopyTilemapToVram(2);
+ gPartyMenu.data1 = move;
+ gTasks[taskId].func = Task_DoLearnedMoveFanfareAfterText;
+}
+
+#define tUsedOnSlot data[0]
+#define tHadEffect data[1]
+#define tLastSlotUsed data[2]
+
+void ItemUseCB_SacredAsh(u8 taskId, UNUSED TaskFunc func)
+{
+ sPartyMenuInternal->tUsedOnSlot = FALSE;
+ sPartyMenuInternal->tHadEffect = FALSE;
+ sPartyMenuInternal->tLastSlotUsed = gPartyMenu.slotId;
+ UseSacredAsh(taskId);
+}
+
+static void UseSacredAsh(u8 taskId)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u16 hp;
+
+ if (GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NONE)
+ {
+ gTasks[taskId].func = Task_SacredAshLoop;
+ return;
+ }
+ hp = GetMonData(mon, MON_DATA_HP);
+ if (ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0))
+ {
+ gTasks[taskId].func = Task_SacredAshLoop;
+ return;
+ }
+ PlaySE(SE_KAIFUKU);
+ if (sPartyMenuInternal->tHadEffect == 0)
+ sSacredAshQuestLogMonBackup = mon;
+ SetPartyMonAilmentGfx(mon, &sPartyMenuBoxes[gPartyMenu.slotId]);
+ if (gSprites[sPartyMenuBoxes[gPartyMenu.slotId].statusSpriteId].invisible)
+ DisplayPartyPokemonLevelCheck(mon, &sPartyMenuBoxes[gPartyMenu.slotId], 1);
+ AnimatePartySlot(sPartyMenuInternal->tLastSlotUsed, 0);
+ AnimatePartySlot(gPartyMenu.slotId, 1);
+ PartyMenuModifyHP(taskId, gPartyMenu.slotId, 1, GetMonData(mon, MON_DATA_HP) - hp, Task_SacredAshDisplayHPRestored);
+ ResetHPTaskData(taskId, 0, hp);
+ sPartyMenuInternal->tUsedOnSlot = TRUE;
+ sPartyMenuInternal->tHadEffect = TRUE;
+}
+
+static void Task_SacredAshLoop(u8 taskId)
+{
+ if (IsPartyMenuTextPrinterActive() != TRUE)
+ {
+ if (sPartyMenuInternal->tUsedOnSlot == TRUE)
+ {
+ sPartyMenuInternal->tUsedOnSlot = FALSE;
+ sPartyMenuInternal->tLastSlotUsed = gPartyMenu.slotId;
+ }
+ if (++(gPartyMenu.slotId) == PARTY_SIZE)
+ {
+ if (sPartyMenuInternal->tHadEffect == FALSE)
+ {
+ gPartyMenuUseExitCallback = FALSE;
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ }
+ else
+ {
+ gPartyMenuUseExitCallback = TRUE;
+ if (gPartyMenu.menuType != PARTY_MENU_TYPE_IN_BATTLE)
+ ItemUse_SetQuestLogEvent(4, sSacredAshQuestLogMonBackup, gSpecialVar_ItemId, 0xFFFF);
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+ }
+ gTasks[taskId].func = Task_ClosePartyMenuAfterText;
+ gPartyMenu.slotId = 0;
+ }
+ else
+ {
+ UseSacredAsh(taskId);
+ }
+ }
+}
+
+static void Task_SacredAshDisplayHPRestored(u8 taskId)
+{
+ GetMonNickname(&gPlayerParty[gPartyMenu.slotId], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2);
+ DisplayPartyMenuMessage(gStringVar4, FALSE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_SacredAshLoop;
+}
+
+#undef tUsedOnSlot
+#undef tHadEffect
+#undef tLastSlotUsed
+
+void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc func)
+{
+ bool8 noEffect;
+
+ PlaySE(SE_SELECT);
+ noEffect = PokemonItemUseNoEffect(&gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId, gPartyMenu.slotId, 0);
+ if (noEffect)
+ {
+ gPartyMenuUseExitCallback = FALSE;
+ DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = func;
+ }
+ else
+ {
+ sub_8124DC0(taskId);
+ }
+}
+
+static void sub_8126BD4(void)
+{
+ gCB2_AfterEvolution = gPartyMenu.exitCallback;
+ ExecuteTableBasedItemEffect_(gPartyMenu.slotId, gSpecialVar_ItemId, 0);
+ ItemUse_SetQuestLogEvent(4, &gPlayerParty[gPartyMenu.slotId], gSpecialVar_ItemId, 0xFFFF);
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+}
+
+static bool8 sub_8126C24(void)
+{
+ if (!IsNationalPokedexEnabled()
+ && GetEvolutionTargetSpecies(&gPlayerParty[gPartyMenu.slotId], 2, gSpecialVar_ItemId) > KANTO_DEX_COUNT)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+u8 GetItemEffectType(u16 item)
+{
+ const u8 *itemEffect;
+ u32 statusCure;
+
+ if (!IS_POKEMON_ITEM(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.data1;
+ GetMonNickname(mon, gStringVar1);
+ gPartyMenu.data1 = GetTutorMove(gSpecialVar_0x8005);
+ StringCopy(gStringVar2, gMoveNames[gPartyMenu.data1]);
+ 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.data1) != 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;
+
+ switch (GetPocketByItemId(gSpecialVar_ItemId))
+ {
+ default:
+ callback = CB2_ReturnToBagMenu;
+ break;
+ case POCKET_TM_CASE:
+ callback = CB2_ReturnToTMCaseMenu;
+ break;
+ case POCKET_BERRY_POUCH:
+ callback = CB2_ReturnToBerryPouchMenu;
+ break;
+ }
+ 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;
+}
+
+static void TryGiveItemOrMailToSelectedMon(u8 taskId)
+{
+ sPartyMenuItemId = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_HELD_ITEM);
+ if (sPartyMenuItemId == ITEM_NONE)
+ {
+ GiveItemOrMailToSelectedMon(taskId);
+ }
+ else if (ItemIsMail(sPartyMenuItemId))
+ {
+ DisplayItemMustBeRemovedFirstMessage(taskId);
+ }
+ else
+ {
+ DisplayAlreadyHoldingItemSwitchMessage(&gPlayerParty[gPartyMenu.slotId], sPartyMenuItemId, TRUE);
+ gTasks[taskId].func = Task_SwitchItemsFromBagYesNo;
+ }
+}
+
+static void GiveItemOrMailToSelectedMon(u8 taskId)
+{
+ if (ItemIsMail(gPartyMenu.bagItem))
+ {
+ RemoveItemToGiveFromBag(gPartyMenu.bagItem);
+ sPartyMenuInternal->exitCallback = CB2_WriteMailToGiveMonFromBag;
+ Task_ClosePartyMenu(taskId);
+ }
+ else
+ {
+ GiveItemToSelectedMon(taskId);
+ }
+}
+
+static void GiveItemToSelectedMon(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);
+}
+
+static void CB2_ReturnToPartyOrBagMenuFromWritingMail(void)
+{
+ struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
+ u16 item = GetMonData(mon, MON_DATA_HELD_ITEM);
+
+ // Canceled writing mail
+ if (gSpecialVar_Result == FALSE)
+ {
+ TakeMailFromMon(mon);
+ SetMonData(mon, MON_DATA_HELD_ITEM, &sPartyMenuItemId);
+ RemoveBagItem(sPartyMenuItemId, 1);
+ ReturnGiveItemToBagOrPC(item);
+ SetMainCallback2(gPartyMenu.exitCallback);
+ }
+ // Wrote mail
+ else
+ {
+ InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_NONE, Task_DisplayGaveMailFromBagMessage, gPartyMenu.exitCallback);
+ }
+}
+
+static void Task_DisplayGaveMailFromBagMessage(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 Task_SwitchItemsFromBagYesNo(u8 taskId)
+{
+ if (IsPartyMenuTextPrinterActive() != TRUE)
+ {
+ PartyMenuDisplayYesNoMenu();
+ gTasks[taskId].func = Task_HandleSwitchItemsFromBagYesNoInput;
+ }
+}
+
+static void Task_HandleSwitchItemsFromBagYesNoInput(u8 taskId)
+{
+ u16 item;
+
+ switch (Menu_ProcessInputNoWrapClearOnChoose())
+ {
+ case 0: // Yes, switch items
+ item = gPartyMenu.bagItem;
+ RemoveItemToGiveFromBag(item);
+ if (AddBagItem(sPartyMenuItemId, 1) == FALSE)
+ {
+ ReturnGiveItemToBagOrPC(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: // No, dont switch items
+ gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
+ break;
+ }
+}
+
+static void DisplayItemMustBeRemovedFirstMessage(u8 taskId)
+{
+ DisplayPartyMenuMessage(gText_RemoveMailBeforeItem, TRUE);
+ ScheduleBgCopyTilemapToVram(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);
+}
+
+// Returns FALSE if there was no space to return the item
+// but there always should be, and the return is ignored in all uses
+static bool8 ReturnGiveItemToBagOrPC(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;
+
+ gPartyMenuUseExitCallback = FALSE;
+ mail = &gSaveBlock1Ptr->mail[gPlayerPcMenuManager.itemsAbove + 6 + gPlayerPcMenuManager.cursorPos];
+ if (GetMonData(mon, MON_DATA_HELD_ITEM) != ITEM_NONE)
+ {
+ DisplayPartyMenuMessage(gText_PkmnHoldingItemCantHoldMail, TRUE);
+ }
+ else
+ {
+ GiveMailToMon2(mon, mail);
+ ClearMailStruct(mail);
+ DisplayPartyMenuMessage(gText_MailTransferredFromMailbox, TRUE);
+ }
+ ScheduleBgCopyTilemapToVram(2);
+ gTasks[taskId].func = Task_UpdateHeldItemSpriteAndClosePartyMenu;
+}
+
+void InitChooseHalfPartyForBattle(u8 a1)
+{
+ ClearSelectedPartyOrder();
+ InitPartyMenu(PARTY_MENU_TYPE_CHOOSE_HALF, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_HandleChooseMonInput, gMain.savedCallback);
+ gPartyMenu.unk_8_6 = a1;
+ 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 species;
+ u16 i = 0;
+
+ if (GetMonData(mon, MON_DATA_IS_EGG))
+ return FALSE;
+ switch (gPartyMenu.unk_8_6)
+ {
+ default:
+ if (GetMonData(mon, MON_DATA_LEVEL) > 30)
+ return FALSE;
+ break;
+ case 0:
+ if (GetMonData(mon, MON_DATA_HP) == 0)
+ return FALSE;
+ break;
+ case 1:
+ if (gSaveBlock2Ptr->battleTower.battleTowerLevelType == 0 // level 50
+ && GetMonData(mon, MON_DATA_LEVEL) > 50)
+ return FALSE;
+ species = GetMonData(mon, MON_DATA_SPECIES);
+ for (; gBattleTowerBannedSpecies[i] != 0xFFFF; ++i)
+ if (gBattleTowerBannedSpecies[i] == species)
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+static u8 CheckBattleEntriesAndGetMessage(void)
+{
+ u8 i, j;
+ struct Pokemon *party = gPlayerParty;
+ u8 *order = gSelectedOrderFromParty;
+
+ switch (gPartyMenu.unk_8_6)
+ {
+ case 1:
+ if (order[2] == 0)
+ return PARTY_MSG_THREE_MONS_ARE_NEEDED;
+ for (i = 0; i < 2; ++i)
+ {
+ sPartyMenuInternal->data[15] = GetMonData(&party[order[i] - 1], MON_DATA_SPECIES);
+ sPartyMenuInternal->data[14] = GetMonData(&party[order[i] - 1], MON_DATA_HELD_ITEM);
+ for (j = i + 1; j < 3; ++j)
+ {
+ if (sPartyMenuInternal->data[15] == GetMonData(&party[order[j] - 1], MON_DATA_SPECIES))
+ return PARTY_MSG_MONS_CANT_BE_SAME;
+ if (sPartyMenuInternal->data[14] != ITEM_NONE && sPartyMenuInternal->data[14] == GetMonData(&party[order[j] - 1], MON_DATA_HELD_ITEM))
+ return PARTY_MSG_NO_SAME_HOLD_ITEMS;
+ }
+ }
+ break;
+ case 2:
+ if (order[1] == 0)
+ return PARTY_MSG_TWO_MONS_ARE_NEEDED;
+ break;
+ }
+ return 0xFF;
+}
+
+static bool8 HasPartySlotAlreadyBeenSelected(u8 slot)
+{
+ u8 i;
+
+ for (i = 0; i < NELEMS(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
+ {
+ if (gSelectedOrderFromParty[0] != 0)
+ {
+ PlaySE(SE_SELECT);
+ Task_ClosePartyMenu(taskId);
+ }
+ else
+ {
+ PlaySE(SE_HAZURE);
+ DisplayPartyMenuStdMessage(PARTY_MSG_NO_MON_FOR_BATTLE);
+ gTasks[taskId].func = Task_ContinueChoosingHalfParty;
+ }
+ }
+}
+
+static void Task_ContinueChoosingHalfParty(u8 taskId)
+{
+ if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
+ gTasks[taskId].func = Task_HandleChooseMonInput;
+ }
+}
+
+void sub_81277F4(u8 menuType, MainCallback callback)
+{
+ InitPartyMenu(menuType,
+ PARTY_LAYOUT_SINGLE,
+ PARTY_ACTION_CHOOSE_MON,
+ FALSE,
+ PARTY_MSG_CHOOSE_MON,
+ Task_HandleChooseMonInput,
+ callback);
+}
+
+void ChooseMonForMoveTutor(void)
+{
+ if (gSpecialVar_0x8005 < TUTOR_MOVE_COUNT)
+ {
+ InitPartyMenu(PARTY_MENU_TYPE_FIELD,
+ PARTY_LAYOUT_SINGLE,
+ PARTY_ACTION_MOVE_TUTOR,
+ FALSE,
+ PARTY_MSG_TEACH_WHICH_MON,
+ Task_HandleChooseMonInput,
+ CB2_ReturnToFieldContinueScriptPlayMapMusic);
+ }
+ else
+ {
+ InitPartyMenu(PARTY_MENU_TYPE_FIELD,
+ PARTY_LAYOUT_SINGLE,
+ PARTY_ACTION_MOVE_TUTOR,
+ FALSE,
+ PARTY_MSG_NONE,
+ TryTutorSelectedMon,
+ CB2_ReturnToFieldContinueScriptPlayMapMusic);
+ gPartyMenu.slotId = gSpecialVar_0x8007;
+ }
+}
+
+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 OpenPartyMenuInTutorialBattle(u8 partyAction)
+{
+ if (!sub_80EB2E0(8) && (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE))
+ {
+ InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE,
+ GetPartyLayoutFromBattleType(),
+ partyAction,
+ FALSE,
+ PARTY_MSG_NONE,
+ sub_8120C3C,
+ SetCB2ToReshowScreenAfterMenu);
+ sub_80EB2F4(8);
+ }
+ else
+ {
+ InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE,
+ GetPartyLayoutFromBattleType(),
+ partyAction,
+ FALSE,
+ PARTY_MSG_CHOOSE_MON,
+ Task_HandleChooseMonInput,
+ SetCB2ToReshowScreenAfterMenu);
+ }
+ nullsub_44();
+ UpdatePartyToBattleOrder();
+}
+
+void OpenPartyMenuInBattle(void)
+{
+ InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE, GetPartyLayoutFromBattleType(), PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, sub_8120EBC, SetCB2ToReshowScreenAfterMenu);
+ nullsub_44();
+ UpdatePartyToBattleOrder();
+}
+
+void ChooseMonForInBattleItem(void)
+{
+ InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE, GetPartyLayoutFromBattleType(), PARTY_ACTION_REUSABLE_ITEM, FALSE, PARTY_MSG_USE_ON_WHICH_MON, sub_8120FCC, sub_8107ECC);
+ nullsub_44();
+ UpdatePartyToBattleOrder();
+}
+
+void sub_81279E0(void)
+{
+ if (!sub_80EB2E0(8) && (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE))
+ {
+ InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE,
+ GetPartyLayoutFromBattleType(),
+ PARTY_ACTION_USE_ITEM,
+ FALSE,
+ PARTY_MSG_NONE,
+ sub_8120C3C,
+ sub_8107ECC);
+ sub_80EB2F4(8);
+ }
+ else
+ {
+ MainCallback callback;
+
+ if (GetPocketByItemId(gSpecialVar_ItemId) == POCKET_BERRY_POUCH)
+ callback = CB2_ReturnToBerryPouchMenu;
+ else
+ callback = sub_8107ECC;
+ InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE,
+ GetPartyLayoutFromBattleType(),
+ PARTY_ACTION_USE_ITEM,
+ FALSE,
+ PARTY_MSG_USE_ON_WHICH_MON,
+ Task_HandleChooseMonInput,
+ callback);
+ }
+ nullsub_44();
+ UpdatePartyToBattleOrder();
+}
+
+static u8 GetPartyMenuActionsTypeInBattle(struct Pokemon *mon)
+{
+ if (GetMonData(&gPlayerParty[1], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(mon, MON_DATA_IS_EGG))
+ return ACTIONS_SUMMARY_ONLY;
+ else if (gPartyMenu.action == PARTY_ACTION_SEND_OUT)
+ return ACTIONS_SEND_OUT;
+ else
+ return ACTIONS_SHIFT;
+}
+
+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[GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[currBattler])], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnCantSwitchOut);
+ return FALSE;
+ }
+ gSelectedMonPartyId = GetPartyIdFromBattleSlot(slot);
+ gPartyMenuUseExitCallback = TRUE;
+ newSlot = GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[gBattlerInMenuId]);
+ SwitchPartyMonSlots(newSlot, slot);
+ SwapPartyPokemon(&gPlayerParty[newSlot], &gPlayerParty[slot]);
+ return TRUE;
+}
+
+void BufferBattlePartyCurrentOrder(void)
+{
+ BufferBattlePartyOrder(gBattlePartyCurrentOrder, GetPlayerFlankId());
+}
+
+static void BufferBattlePartyOrder(u8 *partyBattleOrder, u8 flankId)
+{
+ u8 partyIds[PARTY_SIZE];
+ s32 i, j;
+
+ if (IsMultiBattle() == TRUE)
+ {
+ // Party ids are packed in 4 bits at a time
+ // i.e. the party id order below would be 0, 3, 5, 4, 2, 1, and the two parties would be 0,5,4 and 3,2,1
+ if (flankId != 0)
+ {
+ 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;
+ partyIds[0] = gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)];
+ for (i = 0; i < PARTY_SIZE; ++i)
+ {
+ if (i != partyIds[0])
+ {
+ partyIds[j] = i;
+ ++j;
+ }
+ }
+ }
+ else
+ {
+ j = 2;
+ partyIds[0] = gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)];
+ partyIds[1] = gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)];
+ for (i = 0; i < PARTY_SIZE; ++i)
+ {
+ if (i != partyIds[0] && i != partyIds[1])
+ {
+ partyIds[j] = i;
+ ++j;
+ }
+ }
+ }
+ for (i = 0; i < (s32)NELEMS(gBattlePartyCurrentOrder); ++i)
+ partyBattleOrder[i] = (partyIds[0 + (i * 2)] << 4) | partyIds[1 + (i * 2)];
+}
+
+void BufferBattlePartyCurrentOrderBySide(u8 battlerId, u8 flankId)
+{
+ BufferBattlePartyOrderBySide(gBattleStruct->field_60[battlerId], flankId, battlerId);
+}
+
+// when GetBattlerSide(battlerId) == B_SIDE_PLAYER, this function is identical the one above
+static void BufferBattlePartyOrderBySide(u8 *partyBattleOrder, u8 flankId, u8 battlerId)
+{
+ u8 partyIndexes[PARTY_SIZE];
+ s32 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 (flankId != 0)
+ {
+ 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[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)
+ partyBattleOrder[i] = (partyIndexes[0 + (i * 2)] << 4) | partyIndexes[1 + (i * 2)];
+}
+
+void SwitchPartyOrderLinkMulti(u8 battlerId, u8 slot, u8 slot2)
+{
+ u8 partyIds[PARTY_SIZE];
+ u8 tempSlot = 0;
+ s32 i, j;
+ u8 *partyBattleOrder;
+ u8 partyIdBuffer;
+
+ if (IsMultiBattle())
+ {
+ partyBattleOrder = gBattleStruct->field_60[battlerId];
+ for (i = j = 0; i < 3; ++j, ++i)
+ {
+ partyIds[j] = partyBattleOrder[i] >> 4;
+ ++j;
+ partyIds[j] = partyBattleOrder[i] & 0xF;
+ }
+ partyIdBuffer = partyIds[slot2];
+ for (i = 0; i < PARTY_SIZE; ++i)
+ {
+ if (partyIds[i] == slot)
+ {
+ tempSlot = partyIds[i];
+ partyIds[i] = partyIdBuffer;
+ break;
+ }
+ }
+ if (i != PARTY_SIZE)
+ {
+ partyIds[slot2] = tempSlot;
+ partyBattleOrder[0] = (partyIds[0] << 4) | partyIds[1];
+ partyBattleOrder[1] = (partyIds[2] << 4) | partyIds[3];
+ partyBattleOrder[2] = (partyIds[4] << 4) | partyIds[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);
+}
+
+u8 GetPartyIdFromBattlePartyId(u8 battlePartyId)
+{
+ u8 i, j;
+
+ for (j = i = 0; i < (s32)NELEMS(gBattlePartyCurrentOrder); ++j, ++i)
+ {
+ if ((gBattlePartyCurrentOrder[i] >> 4) != battlePartyId)
+ {
+ ++j;
+ if ((gBattlePartyCurrentOrder[i] & 0xF) == battlePartyId)
+ 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[GetPartyIdFromBattlePartyId(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);
+}
+
+// not used
+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)
+{
+ CB2_SetUpReshowBattleScreenAfterMenu();
+ SetMainCallback2(SetCB2ToReshowScreenAfterMenu);
+}
+
+void ShowPartyMenuToShowcaseMultiBattleParty(void)
+{
+ InitPartyMenu(PARTY_MENU_TYPE_MULTI_SHOWCASE, PARTY_LAYOUT_MULTI_SHOWCASE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_NONE, Task_InitMultiPartnerPartySlideIn, gMain.savedCallback);
+}
+
+#define tXPos data[0]
+
+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 - MULTI_PARTY_SIZE].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 - MULTI_PARTY_SIZE].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)
+{
+ gFieldCallback2 = CB2_FadeFromPartyMenu;
+ InitPartyMenu(PARTY_MENU_TYPE_DAYCARE, PARTY_LAYOUT_SINGLE, PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON_2, Task_HandleChooseMonInput, CB2_ReturnToField);
+}
+
+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 bool8 CB2_FadeFromPartyMenu(void)
+{
+ sub_807DC00();
+ CreateTask(Task_PartyMenuWaitForFade, 10);
+ return TRUE;
+}
+
+static void Task_PartyMenuWaitForFade(u8 taskId)
+{
+ if (IsWeatherNotFadingIn())
+ {
+ DestroyTask(taskId);
+ ScriptContext2_Disable();
+ EnableBothScriptContexts();
+ }
+}
diff --git a/src/player_pc.c b/src/player_pc.c
index f454cd07f..00d41abe6 100644
--- a/src/player_pc.c
+++ b/src/player_pc.c
@@ -38,7 +38,7 @@ static EWRAM_DATA const u8 *sItemOrder = NULL;
static EWRAM_DATA u8 sTopMenuItemCount = 0;
EWRAM_DATA struct PlayerPCItemPageStruct gPlayerPcMenuManager = {};
-#define SELECTED_MAIL (gSaveBlock1Ptr->mail[PC_MAIL_NUM(gPlayerPcMenuManager.scrollOffset) + gPlayerPcMenuManager.selectedRow])
+#define SELECTED_MAIL (gSaveBlock1Ptr->mail[PC_MAIL_NUM(gPlayerPcMenuManager.itemsAbove) + gPlayerPcMenuManager.cursorPos])
static void Task_DrawPlayerPcTopMenu(u8 taskId);
static void Task_TopMenuHandleInput(u8 taskId);
@@ -234,8 +234,8 @@ static void Task_PlayerPcMailbox(u8 taskId)
}
else
{
- gPlayerPcMenuManager.selectedRow = 0;
- gPlayerPcMenuManager.scrollOffset = 0;
+ gPlayerPcMenuManager.cursorPos = 0;
+ gPlayerPcMenuManager.itemsAbove = 0;
PCMailCompaction();
Task_SetPageItemVars(taskId);
if (gPlayerPcMenuManager.unk_9 == 0)
@@ -322,7 +322,7 @@ static void Task_DepositItem_WaitFadeAndGoToBag(u8 taskId)
if (!gPaletteFade.active)
{
CleanupOverworldWindowsAndTilemaps();
- sub_8107DB4(3, POCKET_ITEMS - 1, CB2_ReturnToField);
+ GoToBagMenu(3, POCKET_ITEMS - 1, CB2_ReturnToField);
gFieldCallback = CB2_ReturnFromDepositMenu;
DestroyTask(taskId);
}
@@ -336,7 +336,7 @@ static void Task_PlayerPcDepositItem(u8 taskId)
static void Task_ReturnToItemStorageSubmenu(u8 taskId)
{
- if (field_weather_is_fade_finished() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
gTasks[taskId].func = Task_TopMenu_ItemStorageSubmenu_HandleInput;
}
@@ -469,7 +469,7 @@ static void Task_MailboxPcHandleInput(u8 taskId)
if (!gPaletteFade.active)
{
input = ListMenu_ProcessInput(tListMenuTaskId);
- ListMenuGetScrollAndRow(tListMenuTaskId, &gPlayerPcMenuManager.scrollOffset, &gPlayerPcMenuManager.selectedRow);
+ ListMenuGetScrollAndRow(tListMenuTaskId, &gPlayerPcMenuManager.itemsAbove, &gPlayerPcMenuManager.cursorPos);
switch (input)
{
case -1:
@@ -483,7 +483,7 @@ static void Task_MailboxPcHandleInput(u8 taskId)
PlaySE(SE_SELECT);
MailboxPC_RemoveWindow(0);
MailboxPC_RemoveWindow(1);
- DestroyListMenuTask(tListMenuTaskId, &gPlayerPcMenuManager.scrollOffset, &gPlayerPcMenuManager.selectedRow);
+ DestroyListMenuTask(tListMenuTaskId, &gPlayerPcMenuManager.itemsAbove, &gPlayerPcMenuManager.cursorPos);
ScheduleBgCopyTilemapToVram(0);
RemoveScrollIndicatorArrowPair(gPlayerPcMenuManager.scrollIndicatorId);
gTasks[taskId].func = Task_PrintWhatToDoWithSelectedMail;
@@ -573,7 +573,7 @@ static void Task_WaitFadeAndReadSelectedMail(u8 taskId)
static void Task_WaitFadeAndReturnToMailboxPcInputHandler(u8 taskId)
{
- if (field_weather_is_fade_finished() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
gTasks[taskId].func = Task_MailboxPcHandleInput;
}
@@ -641,10 +641,10 @@ static void Task_TryPutMailInBag_DestroyMsgIfSuccessful(u8 taskId)
ClearMailStruct(mail);
PCMailCompaction();
gPlayerPcMenuManager.count--;
- if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.scrollOffset)
+ if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.itemsAbove)
{
- if (gPlayerPcMenuManager.scrollOffset != 0)
- gPlayerPcMenuManager.scrollOffset--;
+ if (gPlayerPcMenuManager.itemsAbove != 0)
+ gPlayerPcMenuManager.itemsAbove--;
}
Task_SetPageItemVars(taskId);
}
@@ -674,7 +674,7 @@ static void Task_WaitFadeAndGoToPartyMenu(u8 taskId)
{
MailboxPC_DestroyListMenuBuffer();
CleanupOverworldWindowsAndTilemaps();
- PartyMenuInit_FromPlayerPc();
+ ChooseMonToGiveMailFromMailbox();
DestroyTask(taskId);
}
}
@@ -693,10 +693,10 @@ static void CB2_ReturnToMailboxPc_UpdateScrollVariables(void)
PCMailCompaction();
if (count != gPlayerPcMenuManager.count)
{
- if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.scrollOffset)
+ if (gPlayerPcMenuManager.count < gPlayerPcMenuManager.pageItems + gPlayerPcMenuManager.itemsAbove)
{
- if (gPlayerPcMenuManager.scrollOffset != 0)
- gPlayerPcMenuManager.scrollOffset--;
+ if (gPlayerPcMenuManager.itemsAbove != 0)
+ gPlayerPcMenuManager.itemsAbove--;
}
}
Task_SetPageItemVars(taskId);
@@ -708,7 +708,7 @@ static void CB2_ReturnToMailboxPc_UpdateScrollVariables(void)
sub_807DC00();
}
-void CB2_PlayerPC_ReturnFromPartyMenu(void)
+void Mailbox_ReturnToMailListAfterDeposit(void)
{
gFieldCallback = CB2_ReturnToMailboxPc_UpdateScrollVariables;
SetMainCallback2(CB2_ReturnToField);
diff --git a/src/pokemon.c b/src/pokemon.c
index 9aaddc142..9f5a6967e 100644
--- a/src/pokemon.c
+++ b/src/pokemon.c
@@ -4117,7 +4117,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if (sp34 != 4)
{
gAbsentBattlerFlags &= ~gBitTable[sp34];
- CopyPlayerPartyMonToBattleData(sp34, pokemon_order_func(gBattlerPartyIndexes[sp34]));
+ CopyPlayerPartyMonToBattleData(sp34, GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[sp34]));
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
gBattleResults.numRevivesUsed++;
}
@@ -4405,7 +4405,7 @@ static bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask,
}
}
-bool8 PokemonUseItemEffects2(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex)
+bool8 PokemonItemUseNoEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex)
{
u32 data;
s32 tmp;
@@ -4796,9 +4796,9 @@ u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
static void sub_8042D50(int stat)
{
gBattlerTarget = gBattlerInMenuId;
- StringCopy(gBattleTextBuff1, gUnknown_83FD5D0[gUnknown_825DFF0[stat]]);
- StringCopy(gBattleTextBuff2, BattleText_Rose);
- BattleStringExpandPlaceholdersToDisplayedString(BattleText_UnknownString3);
+ StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_825DFF0[stat]]);
+ StringCopy(gBattleTextBuff2, gBattleText_Rose);
+ BattleStringExpandPlaceholdersToDisplayedString(gBattleText_UnknownString3);
}
const u8 *Battle_PrintStatBoosterEffectMessage(u16 itemId)
@@ -4837,7 +4837,7 @@ const u8 *Battle_PrintStatBoosterEffectMessage(u16 itemId)
else
{
gBattlerAttacker = gBattlerInMenuId;
- BattleStringExpandPlaceholdersToDisplayedString(BattleText_GetPumped);
+ BattleStringExpandPlaceholdersToDisplayedString(gBattleText_GetPumped);
}
}
}
@@ -4845,7 +4845,7 @@ const u8 *Battle_PrintStatBoosterEffectMessage(u16 itemId)
if (itemEffect[3] & 0x80)
{
gBattlerAttacker = gBattlerInMenuId;
- BattleStringExpandPlaceholdersToDisplayedString(BattleText_MistShroud);
+ BattleStringExpandPlaceholdersToDisplayedString(gBattleText_MistShroud);
}
return gDisplayedStringBattle;
@@ -5179,7 +5179,7 @@ void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies)
SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[newSpecies]);
}
-bool8 sub_80435E0(void)
+bool8 GetPlayerFlankId(void)
{
bool8 retVal = FALSE;
switch (gLinkPlayers[GetMultiplayerId()].id)
@@ -5813,11 +5813,11 @@ void SetMonPreventsSwitchingString(void)
gBattleTextBuff1[4] = B_BUFF_EOS;
if (GetBattlerSide(gBattleStruct->battlerPreventingSwitchout) == B_SIDE_PLAYER)
- gBattleTextBuff1[3] = pokemon_order_func(gBattlerPartyIndexes[gBattleStruct->battlerPreventingSwitchout]);
+ gBattleTextBuff1[3] = GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[gBattleStruct->battlerPreventingSwitchout]);
else
gBattleTextBuff1[3] = gBattlerPartyIndexes[gBattleStruct->battlerPreventingSwitchout];
- PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBattlerInMenuId, pokemon_order_func(gBattlerPartyIndexes[gBattlerInMenuId]))
+ PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBattlerInMenuId, GetPartyIdFromBattlePartyId(gBattlerPartyIndexes[gBattlerInMenuId]))
BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4);
}
diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c
index f3492593c..4c7681231 100644
--- a/src/pokemon_icon.c
+++ b/src/pokemon_icon.c
@@ -1276,7 +1276,7 @@ static void DestroyMonIconInternal(struct Sprite * sprite)
DestroySprite(sprite);
}
-void MonIcon_SetAnim(struct Sprite * sprite, u8 animNum)
+void SetPartyHPBarSprite(struct Sprite * sprite, u8 animNum)
{
sprite->animNum = animNum;
sprite->animDelayCounter = 0;
diff --git a/src/quest_log.c b/src/quest_log.c
index d7b544882..04369f1c2 100644
--- a/src/quest_log.c
+++ b/src/quest_log.c
@@ -987,7 +987,7 @@ void sub_8111708(void)
gSaveBlock1Ptr->mapDataId = VarGet(VAR_0x40AE);
if (gSaveBlock1Ptr->mapDataId == 0)
{
- sp0 = *get_mapheader_by_bank_and_number(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
+ sp0 = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
gSaveBlock1Ptr->mapDataId = sp0.mapDataId;
}
}
@@ -1363,7 +1363,7 @@ static void sub_8111FCC(u8 taskId)
{
if (gUnknown_203AE94.unk_0_6 != 1)
{
- sub_80C4DF8(gStringVar1, gMapHeader.regionMapSectionId);
+ GetMapNameGeneric(gStringVar1, gMapHeader.regionMapSectionId);
StringExpandPlaceholders(gStringVar4, gUnknown_841B073);
sub_8111D10();
}
@@ -1972,15 +1972,15 @@ void DestroyHelpMessageWindow(u8 a0)
}
#ifdef NONMATCHING
-void sub_8112F18(u8 a0)
+void sub_8112F18(u8 windowId)
{
- u8 width = GetWindowAttribute(a0, WINDOW_WIDTH);
- u8 height = GetWindowAttribute(a0, WINDOW_HEIGHT);
+ u8 width = GetWindowAttribute(windowId, WINDOW_WIDTH);
+ u8 height = GetWindowAttribute(windowId, WINDOW_HEIGHT);
u8 *buffer = Alloc(32 * width * height);
u8 i, j;
u8 k;
- if (buffer)
+ if (buffer != NULL)
{
for (i = 0; i < height; i++)
{
@@ -1999,13 +1999,13 @@ void sub_8112F18(u8 a0)
);
}
}
- CopyToWindowPixelBuffer(a0, buffer, width * height * 32, 0);
+ CopyToWindowPixelBuffer(windowId, buffer, width * height * 32, 0);
Free(buffer);
}
}
#else
NAKED
-void sub_8112F18(u8 a0)
+void sub_8112F18(u8 windowId)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r10\n"
@@ -3166,7 +3166,7 @@ static const u16 *sub_8113FBC(const u16 *a0)
StringCopy(gStringVar1, ItemId_GetName(r5[0]));
if (r5[0] == ITEM_ESCAPE_ROPE)
{
- sub_80C4DF8(gStringVar2, r5[2]);
+ GetMapNameGeneric(gStringVar2, r5[2]);
StringExpandPlaceholders(gStringVar4, gUnknown_841AFA6);
}
else if (r5[1] != 0xFFFF)
@@ -3814,7 +3814,7 @@ static const u16 *sub_8114D68(const u16 *a0)
a0 = sub_8113E88(30, a0);
r6 = (const u8 *)a0 + 6;
DynamicPlaceholderTextUtil_Reset();
- sub_80C4DF8(gStringVar1, r6[0]);
+ GetMapNameGeneric(gStringVar1, r6[0]);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gTrainers[a0[2]].trainerName);
QuestLog_AutoGetSpeciesName(a0[0], 0, 2);
@@ -3855,7 +3855,7 @@ static const u16 *sub_8114E68(const u16 *a0)
r6 = (const u8 *)a0 + 8;
DynamicPlaceholderTextUtil_Reset();
- sub_80C4DF8(gStringVar1, r6[2]);
+ GetMapNameGeneric(gStringVar1, r6[2]);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
QuestLog_AutoGetSpeciesName(a0[2], NULL, 1);
ConvertIntToDecimalStringN(gStringVar2, r6[0], STR_CONV_MODE_LEFT_ALIGN, 3);
@@ -3983,7 +3983,7 @@ static const u16 *sub_81151DC(const u16 *a0)
const u16 *r5 = sub_8113E88(34, a0);
const u8 *r6 = (const u8 *)r5 + 6;
DynamicPlaceholderTextUtil_Reset();
- sub_80C4DF8(gStringVar1, r6[0]);
+ GetMapNameGeneric(gStringVar1, r6[0]);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
if (
gTrainers[r5[2]].trainerClass == 0x51
@@ -4164,7 +4164,7 @@ static const u16 *sub_81152BC(const u16 *a0)
const u16 *r5 = sub_8113E88(35, a0);
const u8 *r5_2 = (const u8 *)r5 + 0;
r6 = r5_2[1];
- sub_80C4DF8(gStringVar1, r5_2[0]);
+ GetMapNameGeneric(gStringVar1, r5_2[0]);
StringCopy(gStringVar2, gUnknown_8456AF0[r6]);
if (gUnknown_8456BE4[r6] == 5)
{
@@ -4238,7 +4238,7 @@ static const u16 *sub_8115460(const u16 *a0)
const u8 *r5 = (const u8 *)r4 + 2;
QuestLog_AutoGetSpeciesName(r4[0], gStringVar1, 0);
if (r5[1] != 0xFF)
- sub_80C4DF8(gStringVar2, r5[1]);
+ GetMapNameGeneric(gStringVar2, r5[1]);
if (r5[0] == 7)
{
if (r5[1] == 0x58)
@@ -4270,7 +4270,7 @@ static const u16 *sub_8115518(const u16 *a0)
const u8 *r7 = (const u8 *)r4 + 8;
u32 r6 = (r4[2] << 16) + r4[3];
DynamicPlaceholderTextUtil_Reset();
- sub_80C4DF8(gStringVar1, r7[0]);
+ GetMapNameGeneric(gStringVar1, r7[0]);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, ItemId_GetName(r4[0]));
if (r4[1] < 2)
@@ -4303,7 +4303,7 @@ static const u16 *sub_81155E0(const u16 *a0) {
const u8 *r7 = (const u8 *) r5 + 8;
u32 r6 = (r5[2] << 16) + r5[3];
DynamicPlaceholderTextUtil_Reset();
- sub_80C4DF8(gStringVar1, r7[0]);
+ GetMapNameGeneric(gStringVar1, r7[0]);
if (r7[1] == 0) {
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gSaveBlock2Ptr->playerName);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gStringVar1);
@@ -4344,7 +4344,7 @@ static const u16 *sub_8115700(const u16 *a0)
{
const u16 *r4 = sub_8113E88(40, a0);
const u8 *r5 = (const u8 *)r4 + 2;
- sub_80C4DF8(gStringVar1, r5[0]);
+ GetMapNameGeneric(gStringVar1, r5[0]);
StringCopy(gStringVar2, ItemId_GetName(r4[0]));
StringExpandPlaceholders(gStringVar4, gUnknown_841B03F);
return (const u16 *)(r5 + 2);
@@ -4420,7 +4420,7 @@ static u16 *sub_81157DC(u16 *a0, const u16 *a1)
static const u16 *sub_8115800(const u16 *a0)
{
const u16 *r4 = sub_8113E88(42, a0);
- sub_80C4DF8(gStringVar1, r4[0]);
+ GetMapNameGeneric(gStringVar1, r4[0]);
StringExpandPlaceholders(gStringVar4, gUnknown_841B064);
return r4 + 1;
}
diff --git a/src/roamer.c b/src/roamer.c
index b42855644..b3cc67f85 100644
--- a/src/roamer.c
+++ b/src/roamer.c
@@ -236,5 +236,5 @@ u16 GetRoamerLocationMapSectionId(void)
struct Roamer *roamer = &saveRoamer;
if (!saveRoamer.active)
return MAPSEC_NONE;
- return get_mapheader_by_bank_and_number(sRoamerLocation[MAP_GRP], sRoamerLocation[MAP_NUM])->regionMapSectionId;
+ return Overworld_GetMapHeaderByGroupAndId(sRoamerLocation[MAP_GRP], sRoamerLocation[MAP_NUM])->regionMapSectionId;
}
diff --git a/src/save_menu_util.c b/src/save_menu_util.c
index 195b29b0c..54073785e 100644
--- a/src/save_menu_util.c
+++ b/src/save_menu_util.c
@@ -41,7 +41,7 @@ void SaveStatToString(u8 gameStatId, u8 *dest0, u8 color)
dest = ConvertIntToDecimalStringN(dest, gSaveBlock2Ptr->playTimeMinutes, STR_CONV_MODE_LEADING_ZEROS, 2);
break;
case SAVE_STAT_LOCATION:
- sub_80C4DF8(dest, gMapHeader.regionMapSectionId);
+ GetMapNameGeneric(dest, gMapHeader.regionMapSectionId);
break;
case SAVE_STAT_BADGES:
for (flagId = FLAG_BADGE01_GET, nBadges = 0; flagId < FLAG_BADGE01_GET + 8; flagId++)
diff --git a/src/sea_cottage_special_anim.c b/src/sea_cottage_special_anim.c
index 542329893..bd69a120a 100644
--- a/src/sea_cottage_special_anim.c
+++ b/src/sea_cottage_special_anim.c
@@ -12,7 +12,7 @@
#define tY data[5]
#define tListTaskId data[7]
-EWRAM_DATA u8 gUnknown_2039984 = 0;
+static EWRAM_DATA u8 gUnknown_2039984 = 0;
static void sub_809C1D8(u8 taskId, const u16* a1, u16 a2);
static void sub_809C334(u8 taskId);
diff --git a/src/shop.c b/src/shop.c
index a0a8b8eca..a8294fd72 100644
--- a/src/shop.c
+++ b/src/shop.c
@@ -95,15 +95,15 @@ struct MartHistory
/*0x17*/ u8 unk17;
}; /* size = 0x18 */
-EWRAM_DATA s16 sViewportMapObjects[MAP_OBJECTS_COUNT][4] = {0};
+static EWRAM_DATA s16 sViewportMapObjects[MAP_OBJECTS_COUNT][4] = {0};
EWRAM_DATA struct ShopData gShopData = {0};
-EWRAM_DATA u8 sShopMenuWindowId = 0;
+static EWRAM_DATA u8 sShopMenuWindowId = 0;
EWRAM_DATA u16 (*gShopTilemapBuffer1)[0x400] = {0};
EWRAM_DATA u16 (*gShopTilemapBuffer2)[0x400] = {0};
EWRAM_DATA u16 (*gShopTilemapBuffer3)[0x400] = {0};
EWRAM_DATA u16 (*gShopTilemapBuffer4)[0x400] = {0};
EWRAM_DATA struct ListMenuItem *sShopMenuListMenu = {0};
-EWRAM_DATA u8 (*sShopMenuItemStrings)[13] = {0};
+static EWRAM_DATA u8 (*sShopMenuItemStrings)[13] = {0};
EWRAM_DATA struct MartHistory gShopMenuHistory = {0};
//Function Declarations
@@ -163,9 +163,6 @@ static void nullsub_52(u8 taskId);
static void nullsub_53(void);
static void RecordQuestLogItemPurchase(void);
-extern u8 MapGridGetMetatileLayerTypeAt(s16 x, s16 y);
-extern u16 BagGetQuantityByItemId(u16 item);
-
static const struct MenuAction sShopMenuActions_BuySellQuit[] =
{
{gText_ShopBuy, {.void_u8 = Task_HandleShopMenuBuy}},
@@ -179,17 +176,15 @@ static const struct YesNoFuncTable sShopMenuActions_BuyQuit[] =
BuyMenuReturnToItemList
};
-static const struct WindowTemplate sShopMenuWindowTemplates[] =
+static const struct WindowTemplate sShopMenuWindowTemplate =
{
- {
- .bg = 0,
- .tilemapLeft = 2,
- .tilemapTop = 1,
- .width = 12,
- .height = 6,
- .paletteNum = 15,
- .baseBlock = 8
- }
+ .bg = 0,
+ .tilemapLeft = 2,
+ .tilemapTop = 1,
+ .width = 12,
+ .height = 6,
+ .paletteNum = 15,
+ .baseBlock = 8
};
static const struct BgTemplate sShopBuyMenuBgTemplates[4] =
@@ -237,12 +232,12 @@ static u8 CreateShopMenu(u8 a0)
{
gShopData.martType = GetMartTypeFromItemList(a0) & 0xF;
gShopData.selectedRow = 0;
- if (!(ContextNpcGetTextColor()))
+ if (ContextNpcGetTextColor() == 0)
gShopData.unk16_4 = 4;
else
gShopData.unk16_4 = 5;
- sShopMenuWindowId = AddWindow(sShopMenuWindowTemplates);
+ sShopMenuWindowId = AddWindow(&sShopMenuWindowTemplate);
SetStdWindowBorderStyle(sShopMenuWindowId, 0);
PrintTextArray(sShopMenuWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 16, 3, sShopMenuActions_BuySellQuit);
Menu_InitCursor(sShopMenuWindowId, 2, 0, 2, 16, 3, 0);
@@ -251,7 +246,7 @@ static u8 CreateShopMenu(u8 a0)
return CreateTask(Task_ShopMenu, 8);
}
-static u8 GetMartTypeFromItemList(u32 a0)
+static bool8 GetMartTypeFromItemList(bool32 a0)
{
u16 i;
@@ -294,7 +289,8 @@ static void SetShopItemsForSale(const u16 *items)
if (mart->itemList[0] == 0)
return;
- do {
+ do
+ {
++gShopData.itemCount;
} while (mart->itemList[gShopData.itemCount]);
}
@@ -338,7 +334,7 @@ static void Task_HandleShopMenuSell(u8 taskId)
static void CB2_GoToSellMenu(void)
{
- sub_8107DB4(2, POCKET_POKE_BALLS, CB2_ReturnToField);
+ GoToBagMenu(2, POCKET_POKE_BALLS, CB2_ReturnToField);
gFieldCallback = MapPostLoadHook_ReturnToShopMenu;
}
@@ -347,7 +343,7 @@ static void Task_HandleShopMenuQuit(u8 taskId)
ClearShopMenuWindow();
RecordQuestLogItemPurchase();
DestroyTask(taskId);
- if (gShopData.callback != 0)
+ if (gShopData.callback != NULL)
gShopData.callback();
}
@@ -375,7 +371,7 @@ static void MapPostLoadHook_ReturnToShopMenu(void)
static void Task_ReturnToShopMenu(u8 taskId)
{
- if (field_weather_is_fade_finished() != TRUE)
+ if (IsWeatherNotFadingIn() != TRUE)
return;
DisplayItemMessageOnField(taskId, GetMartUnk16_4(), gText_CanIHelpWithAnythingElse, ShowShopMenuAfterExitingBuyOrSellMenu);
@@ -454,19 +450,19 @@ static void CB2_InitBuyMenu(void)
static bool8 InitShopData(void)
{
gShopTilemapBuffer1 = Alloc(sizeof(*gShopTilemapBuffer1));
- if (gShopTilemapBuffer1 == 0)
+ if (gShopTilemapBuffer1 == NULL)
goto CANCEL;
gShopTilemapBuffer2 = Alloc(sizeof(*gShopTilemapBuffer2));
- if (gShopTilemapBuffer2 == 0)
+ if (gShopTilemapBuffer2 == NULL)
goto CANCEL;
gShopTilemapBuffer3 = Alloc(sizeof(*gShopTilemapBuffer3));
- if (gShopTilemapBuffer3 == 0)
+ if (gShopTilemapBuffer3 == NULL)
goto CANCEL;
gShopTilemapBuffer4 = Alloc(sizeof(*gShopTilemapBuffer4));
- if (gShopTilemapBuffer4 == 0)
+ if (gShopTilemapBuffer4 == NULL)
goto CANCEL;
return TRUE;
@@ -483,16 +479,16 @@ static void BuyMenuInitBgs(void)
SetBgTilemapBuffer(1, gShopTilemapBuffer2);
SetBgTilemapBuffer(2, gShopTilemapBuffer4);
SetBgTilemapBuffer(3, gShopTilemapBuffer3);
- SetGpuReg(0x10, 0);
- SetGpuReg(0x12, 0);
- SetGpuReg(0x14, 0);
- SetGpuReg(0x16, 0);
- SetGpuReg(0x18, 0);
- SetGpuReg(0x1A, 0);
- SetGpuReg(0x1C, 0);
- SetGpuReg(0x1E, 0);
- SetGpuReg(0x50, 0);
- SetGpuReg(0, 0x1040);
+ SetGpuReg(REG_OFFSET_BG0HOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG3HOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_BLDCNT, DISPCNT_MODE_0);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
ShowBg(2);
@@ -526,9 +522,9 @@ static void sub_809B10C(bool32 a0)
v = 6;
if ((gShopData.martType) != MART_TYPE_TMHM)
- SetBgRectPal(1, 0, 0xE, 0x1E, 6, v);
+ SetBgTilemapPalette(1, 0, 0xE, 0x1E, 6, v);
else
- SetBgRectPal(1, 0, 0xC, 0x1E, 8, v);
+ SetBgTilemapPalette(1, 0, 0xC, 0x1E, 8, v);
ScheduleBgCopyTilemapToVram(1);
}
@@ -551,11 +547,11 @@ static bool8 BuyMenuBuildListMenuTemplate(void)
struct ShopData *mart = &gShopData;
*list = Alloc((gShopData.itemCount + 1) * sizeof(*sShopMenuListMenu));
- if (sShopMenuListMenu == 0)
+ if (sShopMenuListMenu == NULL)
goto FREE_MEMORY;
sShopMenuItemStrings = Alloc((gShopData.itemCount + 1) * sizeof(*sShopMenuItemStrings));
- if (sShopMenuItemStrings == 0)
+ if (sShopMenuItemStrings == NULL)
{
FREE_MEMORY:
BuyMenuFreeMemory();
@@ -587,8 +583,8 @@ static bool8 BuyMenuBuildListMenuTemplate(void)
gMultiuseListMenuTemplate.upText_Y = 2;
gMultiuseListMenuTemplate.fontId = 2;
gMultiuseListMenuTemplate.fillValue = 0;
- gMultiuseListMenuTemplate.cursorPal = GetFontAttribute(2, 5);
- gMultiuseListMenuTemplate.cursorShadowPal = GetFontAttribute(2, 7);
+ gMultiuseListMenuTemplate.cursorPal = GetFontAttribute(2, FONTATTR_COLOR_FOREGROUND);
+ gMultiuseListMenuTemplate.cursorShadowPal = GetFontAttribute(2, FONTATTR_COLOR_SHADOW);
gMultiuseListMenuTemplate.moveCursorFunc = BuyMenuPrintItemDescriptionAndShowItemIcon;
gMultiuseListMenuTemplate.itemPrintFunc = BuyMenuPrintPriceInList;
gMultiuseListMenuTemplate.scrollMultiple = 0;
@@ -788,22 +784,22 @@ static void BuyMenuPrintCursorAtYPosition(u8 y, u8 a1)
static void BuyMenuFreeMemory(void)
{
- if (gShopTilemapBuffer1 != 0)
+ if (gShopTilemapBuffer1 != NULL)
Free(gShopTilemapBuffer1);
- if (gShopTilemapBuffer2 != 0)
+ if (gShopTilemapBuffer2 != NULL)
Free(gShopTilemapBuffer2);
- if (gShopTilemapBuffer3 != 0)
+ if (gShopTilemapBuffer3 != NULL)
Free(gShopTilemapBuffer3);
- if (gShopTilemapBuffer4 != 0)
+ if (gShopTilemapBuffer4 != NULL)
Free(gShopTilemapBuffer4);
- if (sShopMenuListMenu != 0)
+ if (sShopMenuListMenu != NULL)
Free(sShopMenuListMenu);
- if (sShopMenuItemStrings != 0)
+ if (sShopMenuItemStrings != NULL)
Free(sShopMenuItemStrings);
FreeAllWindowBuffers();
@@ -972,7 +968,7 @@ static void BuyMenuDrawEventObjects(void)
spriteId = AddPseudoEventObject(
gMapObjects[sViewportMapObjects[i][EVENT_OBJ_ID]].graphicsId,
SpriteCallbackDummy,
- (((u16)sViewportMapObjects[i][X_COORD] << 0x14) + 0xFFF80000) >> 0x10,
+ (u16)sViewportMapObjects[i][X_COORD] * 16 - 8,
(u16)sViewportMapObjects[i][Y_COORD] * 16 + 48 - graphicsInfo->height / 2,
2);
StartSpriteAnim(&gSprites[spriteId], sViewportMapObjects[i][ANIM_NUM]);
@@ -1058,7 +1054,7 @@ static void Task_BuyHowManyDialogueInit(u8 taskId)
ScheduleBgCopyTilemapToVram(0);
maxQuantity = GetMoney(&gSaveBlock1Ptr->money) / itemid_get_market_price(tItemId);
if (maxQuantity > 99)
- gShopData.maxQuantity = (u8)99;
+ gShopData.maxQuantity = 99;
else
gShopData.maxQuantity = (u8)maxQuantity;
diff --git a/src/start_menu.c b/src/start_menu.c
index 4a4fe52e3..2a1713902 100644
--- a/src/start_menu.c
+++ b/src/start_menu.c
@@ -504,7 +504,7 @@ static bool8 StartMenuPlayerCallback(void)
PlayRainStoppingSoundEffect();
DestroySafariZoneStatsWindow();
CleanupOverworldWindowsAndTilemaps();
- InitTrainerCard(CB2_ReturnToStartMenu);
+ InitTrainerCard(CB2_ReturnToFieldWithOpenMenu);
return TRUE;
}
return FALSE;
@@ -524,7 +524,7 @@ static bool8 StartMenuOptionCallback(void)
DestroySafariZoneStatsWindow();
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_OptionsMenuFromStartMenu);
- gMain.savedCallback = CB2_ReturnToStartMenu;
+ gMain.savedCallback = CB2_ReturnToFieldWithOpenMenu;
return TRUE;
}
return FALSE;
@@ -554,7 +554,7 @@ static bool8 StartMenuLinkPlayerCallback(void)
{
PlayRainStoppingSoundEffect();
CleanupOverworldWindowsAndTilemaps();
- InitLinkPartnerTrainerCard(gUnknown_300502C, CB2_ReturnToStartMenu);
+ InitLinkPartnerTrainerCard(gUnknown_300502C, CB2_ReturnToFieldWithOpenMenu);
return TRUE;
}
return FALSE;
diff --git a/src/tm_case.c b/src/tm_case.c
index 9e5d32db9..40509ed1b 100644
--- a/src/tm_case.c
+++ b/src/tm_case.c
@@ -595,7 +595,7 @@ static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex)
static void FillBG2RowWithPalette_2timesNplus1(s32 a0)
{
- SetBgRectPal(2, 0, 12, 30, 8, 2 * a0 + 1);
+ SetBgTilemapPalette(2, 0, 12, 30, 8, 2 * a0 + 1);
ScheduleBgCopyTilemapToVram(2);
}
@@ -848,8 +848,8 @@ static void TMHMContextMenuAction_Use(u8 taskId)
}
else
{
- gUnknown_3005E98 = sub_8125B40;
- sTMCaseDynamicResources->savedCallback = sub_8124C8C;
+ gItemUseCB = ItemUseCB_TMHM;
+ sTMCaseDynamicResources->savedCallback = CB2_ShowPartyMenuForItemUse;
Task_BeginFadeOutFromTMCase(taskId);
}
}
@@ -874,7 +874,7 @@ static void TMHMContextMenuAction_Give(u8 taskId)
}
else
{
- sTMCaseDynamicResources->savedCallback = sub_8126EDC;
+ sTMCaseDynamicResources->savedCallback = CB2_ChooseMonToGiveItem;
Task_BeginFadeOutFromTMCase(taskId);
}
}
@@ -945,7 +945,7 @@ static void Task_SelectTMAction_Type1(u8 taskId)
if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])))
{
- sTMCaseDynamicResources->savedCallback = c2_8123744;
+ sTMCaseDynamicResources->savedCallback = CB2_GiveHoldItem;
Task_BeginFadeOutFromTMCase(taskId);
}
else
@@ -1274,7 +1274,7 @@ static void Task_TMCaseDude_Playback(u8 taskId)
sTMCaseStaticResources.scrollOffset = sPokeDudePackBackup->unk_162;
Free(sPokeDudePackBackup);
CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
- sub_8108CF0();
+ CB2_SetUpReshowBattleScreenAfterMenu();
BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, 0);
data[8]++;
}
diff --git a/src/trade.c b/src/trade.c
index 5151ecedd..4921a1ba3 100644
--- a/src/trade.c
+++ b/src/trade.c
@@ -459,9 +459,9 @@ static const u8 *const sTradeErrorOrStatusMessagePtrs[] = {
gUnknown_8417094, // That's your only POKéMON for battle
gUnknown_841E199, // Waiting for your friend to finish
gUnknown_841E1C5, // Your friend wants to trade POKéMON
- gUnknown_84170BC, // That POKéMON can't be traded now
- gUnknown_84170E0, // An EGG can't be traded now
- gUnknown_84170FC // The other TRAINER's POKéMON can't be traded now
+ gText_PkmnCantBeTradedNow, // That POKéMON can't be traded now
+ gText_EggCantBeTradedNow, // An EGG can't be traded now
+ gText_OtherTrainersPkmnCantBeTraded // The other TRAINER's POKéMON can't be traded now
};
static const u8 gUnknown_8261F18[] = { 0, 1, 2 };
@@ -879,11 +879,11 @@ static void sub_804C728(void)
break;
case 8:
LoadHeldItemIcons();
- sub_812256C(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 0);
+ DrawHeldItemIconsForTrade(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 0);
gMain.state++;
break;
case 9:
- sub_812256C(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 1);
+ DrawHeldItemIconsForTrade(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 1);
gMain.state++;
break;
case 10:
@@ -1483,7 +1483,7 @@ static void sub_804C728(void)
"\tadds r0, 0x36\n"
"\tadds r1, 0x28\n"
"\tmovs r2, 0\n"
- "\tbl sub_812256C\n"
+ "\tbl DrawHeldItemIconsForTrade\n"
"\tldr r1, _0804CB74 @ =gMain\n"
"\tmovs r5, 0x87\n"
"\tlsls r5, 3\n"
@@ -1499,7 +1499,7 @@ static void sub_804C728(void)
"\tadds r0, 0x36\n"
"\tadds r1, 0x28\n"
"\tmovs r2, 0x1\n"
- "\tbl sub_812256C\n"
+ "\tbl DrawHeldItemIconsForTrade\n"
"\tldr r1, _0804CB98 @ =gMain\n"
"\tmovs r7, 0x87\n"
"\tlsls r7, 3\n"
@@ -1989,11 +1989,11 @@ void sub_804CF14(void)
break;
case 8:
LoadHeldItemIcons();
- sub_812256C(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 0);
+ DrawHeldItemIconsForTrade(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 0);
gMain.state++;
break;
case 9:
- sub_812256C(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 1);
+ DrawHeldItemIconsForTrade(sTradeMenuResourcesPtr->partyCounts, sTradeMenuResourcesPtr->partyIcons, 1);
gMain.state++;
break;
case 10:
@@ -2053,9 +2053,9 @@ void sub_804CF14(void)
}
if (sTradeMenuResourcesPtr->tradeMenuCursorPosition < 6)
- sTradeMenuResourcesPtr->tradeMenuCursorPosition = sub_8138B20();
+ sTradeMenuResourcesPtr->tradeMenuCursorPosition = GetLastViewedMonIndex();
else
- sTradeMenuResourcesPtr->tradeMenuCursorPosition = sub_8138B20() + 6;
+ sTradeMenuResourcesPtr->tradeMenuCursorPosition = GetLastViewedMonIndex() + 6;
sTradeMenuResourcesPtr->tradeMenuCursorSpriteIdx = CreateSprite(&sSpriteTemplate_TradeButtons, sTradeMonSpriteCoords[sTradeMenuResourcesPtr->tradeMenuCursorPosition][0] * 8 + 32, sTradeMonSpriteCoords[sTradeMenuResourcesPtr->tradeMenuCursorPosition][1] * 8, 2);
gMain.state = 16;
@@ -2365,7 +2365,7 @@ void sub_804CF14(void)
"\tadds r0, 0x36\n"
"\tadds r1, 0x28\n"
"\tmovs r2, 0\n"
- "\tbl sub_812256C\n"
+ "\tbl DrawHeldItemIconsForTrade\n"
"\tldr r1, _0804D174 @ =gMain\n"
"\tmovs r5, 0x87\n"
"\tlsls r5, 3\n"
@@ -2381,7 +2381,7 @@ void sub_804CF14(void)
"\tadds r0, 0x36\n"
"\tadds r1, 0x28\n"
"\tmovs r2, 0x1\n"
- "\tbl sub_812256C\n"
+ "\tbl DrawHeldItemIconsForTrade\n"
"\tldr r1, _0804D198 @ =gMain\n"
"\tmovs r7, 0x87\n"
"\tlsls r7, 3\n"
@@ -2633,14 +2633,14 @@ void sub_804CF14(void)
"\tldrb r0, [r0]\n"
"\tcmp r0, 0x5\n"
"\tbhi _0804D3B8\n"
- "\tbl sub_8138B20\n"
+ "\tbl GetLastViewedMonIndex\n"
"\tldr r1, [r4]\n"
"\tb _0804D3C0\n"
"\t.align 2, 0\n"
"_0804D3B0: .4byte sSpriteTemplate_Text\n"
"_0804D3B4: .4byte sTradeMenuResourcesPtr\n"
"_0804D3B8:\n"
- "\tbl sub_8138B20\n"
+ "\tbl GetLastViewedMonIndex\n"
"\tldr r1, [r4]\n"
"\tadds r0, 0x6\n"
"_0804D3C0:\n"
@@ -4243,7 +4243,7 @@ static void sub_804F964(void)
{
for (j = 0; j < sTradeMenuResourcesPtr->partyCounts[i]; j++)
{
- MonIcon_SetAnim(&gSprites[sTradeMenuResourcesPtr->partyIcons[i][j]], 4 - sTradeMenuResourcesPtr->unk_5D[i][j]);
+ SetPartyHPBarSprite(&gSprites[sTradeMenuResourcesPtr->partyIcons[i][j]], 4 - sTradeMenuResourcesPtr->unk_5D[i][j]);
}
}
}
@@ -4394,7 +4394,7 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isObedientBitSet)
return FALSE;
}
-int sub_804FBEC(struct UnkLinkRfuStruct_02022B14Substruct a0, struct UnkLinkRfuStruct_02022B14Substruct a1, u16 species1, u16 species2, u8 type, u16 species3, u8 isObedientBitSet)
+int GetUnionRoomTradeMessageId(struct UnkLinkRfuStruct_02022B14Substruct a0, struct UnkLinkRfuStruct_02022B14Substruct a1, u16 species1, u16 species2, u8 type, u16 species3, u8 isObedientBitSet)
{
u8 r9 = a0.unk_01_0;
u8 r4 = a0.unk_00_7;
@@ -4474,7 +4474,7 @@ int sub_804FBEC(struct UnkLinkRfuStruct_02022B14Substruct a0, struct UnkLinkRfuS
return 0;
}
-int Trade_CanTradeSelectedMon(struct UnkLinkRfuStruct_02022B14Substruct a0, u16 species, u16 a2, u8 a3)
+int CanRegisterMonForTradingBoard(struct UnkLinkRfuStruct_02022B14Substruct a0, u16 species, u16 a2, u8 a3)
{
u8 canTradeEggAndNational = a0.unk_01_0;
diff --git a/src/wild_pokemon_area.c b/src/wild_pokemon_area.c
index fc4df06ed..3c5afaf25 100644
--- a/src/wild_pokemon_area.c
+++ b/src/wild_pokemon_area.c
@@ -289,7 +289,7 @@ static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * info, s32 s
static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header)
{
- return get_mapheader_by_bank_and_number(header->mapGroup, header->mapNum)->regionMapSectionId;
+ return Overworld_GetMapHeaderByGroupAndId(header->mapGroup, header->mapNum)->regionMapSectionId;
}
static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p)